@@ -2,8 +2,10 @@ import { Effect, Options } from "./types.ts";
22import { toWKT } from "./wktGeometries.ts" ;
33import {
44 ESRI_SYMBOLS_FONT ,
5+ ESRI_SPECIAL_FONT ,
56 OFFSET_FACTOR ,
67 POLYGON_FILL_RESIZE_FACTOR ,
8+ ESRI_SPECIAL_FONT_RESIZE_FACTOR ,
79 ptToPx ,
810} from "./constants.ts" ;
911import {
@@ -76,15 +78,15 @@ const processSymbolLayerWithSubSymbol = (
7678 options : Options ,
7779 maxX : number | null = null ,
7880 maxY : number | null = null ,
81+ respectFrame : boolean = true ,
7982) : Symbolizer [ ] => {
8083 const symbolizers : Symbolizer [ ] = [ ] ;
8184 if ( symbol . type === "CIMPolygonSymbol" ) {
8285 const markerPlacement = layer . markerPlacement || { } ;
8386 const polygonSymbolizer = formatPolygonSymbolizer (
8487 symbolizer as MarkSymbolizer ,
8588 markerPlacement ,
86- maxX ,
87- maxY ,
89+ respectFrame ,
8890 ) ;
8991 if ( polygonSymbolizer ) {
9092 symbolizers . push ( polygonSymbolizer ) ;
@@ -219,16 +221,14 @@ const processMarkerPlacementAlongLine = (
219221const formatPolygonSymbolizer = (
220222 symbolizer : MarkSymbolizer ,
221223 markerPlacement : CIMMarkerPlacement ,
222- maxX : number | null = null ,
223- maxY : number | null = null ,
224+ respectFrame : boolean ,
224225) : FillSymbolizer | LineSymbolizer | null => {
225226 const markerPlacementType = markerPlacement . type ;
226227 if ( markerPlacementType === "CIMMarkerPlacementInsidePolygon" ) {
227228 const padding = processMarkerPlacementInsidePolygon (
228229 symbolizer ,
229230 markerPlacement ,
230- maxX ,
231- maxY ,
231+ respectFrame ,
232232 ) ;
233233 return {
234234 kind : "Fill" ,
@@ -333,57 +333,43 @@ const processOrientedMarkerAtEndOfLine = (
333333const processMarkerPlacementInsidePolygon = (
334334 symbolizer : MarkSymbolizer ,
335335 markerPlacement : CIMMarkerPlacement ,
336- symMaxX : number | null = null ,
337- symMaxY : number | null = null ,
336+ respectFrame : boolean = true
338337) : [
339338 Expression < number > ,
340339 Expression < number > ,
341340 Expression < number > ,
342341 Expression < number > ,
343342] => {
343+ const isSpecialFont = ESRI_SPECIAL_FONT . some ( font => symbolizer ?. wellKnownName ?. startsWith ( font ) ) ;
344344 // In case of markers in a polygon fill, it seems ArcGIS does some undocumented resizing of the marker.
345- // We use an empirical factor to account for this, which works in most cases (but not all)
346- const resizeFactor = symbolizer ?. wellKnownName ?. startsWith ( "wkt://POLYGON" )
347- ? 1
348- : POLYGON_FILL_RESIZE_FACTOR ;
349-
350- const radius = typeof symbolizer . radius === "number" ? symbolizer . radius : 0 ;
351-
352- // Size is already in pixel.
353- // Avoid null values and force them to 1 px
354- const size = Math . round ( radius * resizeFactor ) || 1 ;
355- symbolizer . radius = size ;
356-
357- // We use SLD graphic-margin as top, right, bottom, left to mimic the combination of
358- // ArcGIS stepX, stepY, offsetX, offsetY
359- let maxX = size / 2 ;
360- let maxY = size / 2 ;
361-
362- symMaxX = symMaxX ?? maxX ;
363- symMaxY = symMaxY ?? maxY ;
364- if ( symMaxX && symMaxY ) {
365- maxX = Math . floor ( symMaxX * resizeFactor ) || 1 ;
366- maxY = Math . floor ( symMaxY * resizeFactor ) || 1 ;
345+ // We use an empirical factor to account for this, which works in most cases. For special Fonts we need to
346+ // use another empirical factor when respectFrame is set to false.
347+ let resizeFactor : number ;
348+ if ( respectFrame ) {
349+ resizeFactor = isSpecialFont ? 1 : POLYGON_FILL_RESIZE_FACTOR ;
350+ } else {
351+ resizeFactor = isSpecialFont ? ESRI_SPECIAL_FONT_RESIZE_FACTOR : 1 ;
367352 }
368353
369354 let stepX = ptToPxProp ( markerPlacement , "stepX" , 0 ) ;
370355 let stepY = ptToPxProp ( markerPlacement , "stepY" , 0 ) ;
371356
372- if ( stepX < maxX ) {
373- stepX += maxX * 2 ;
374- }
357+ const radius = typeof symbolizer . radius === "number" ? symbolizer . radius : 0 ;
358+ const size = Math . round ( radius * 2 * resizeFactor ) || 1 ;
359+ symbolizer . radius = size / 2 ;
375360
376- if ( stepY < maxY ) {
377- stepY += maxY * 2 ;
361+ if ( stepX < size ) {
362+ stepX = size ;
378363 }
379364
380- const offsetX = ptToPxProp ( markerPlacement , "offsetX" , 0 ) ;
381- const offsetY = ptToPxProp ( markerPlacement , "offsetY" , 0 ) ;
365+ if ( stepY < size ) {
366+ stepY = size ;
367+ }
382368
383- const right = Math . round ( stepX / 2 - maxX - offsetX ) ;
384- const left = Math . round ( stepX / 2 - maxX + offsetX ) ;
385- const top = Math . round ( stepY / 2 - maxY - offsetY ) ;
386- const bottom = Math . round ( stepY / 2 - maxY + offsetY ) ;
369+ const right = Math . round ( stepX / 2 - size / 2 ) ;
370+ const left = Math . round ( stepX / 2 - size / 2 ) ;
371+ const top = Math . round ( stepY / 2 - size / 2 ) ;
372+ const bottom = Math . round ( stepY / 2 - size / 2 ) ;
387373
388374 return [ top , right , bottom , left ] ;
389375} ;
@@ -503,6 +489,7 @@ const processSymbolCharacterMarker = (
503489 let strokeColor = "#000000" ;
504490 let strokeWidth = 0 ;
505491 let strokeOpacity = 0 ;
492+ let respectFrame = layer . respectFrame ;
506493 const symbolLayers = layer . symbol . symbolLayers ;
507494 if ( symbolLayers ) {
508495 fillColor = extractFillColor ( symbolLayers ) ;
@@ -522,13 +509,17 @@ const processSymbolCharacterMarker = (
522509 color : fillColor ,
523510 wellKnownName : name ,
524511 radius : size / 2 ,
512+ respectFrame : respectFrame ,
525513 } as Symbolizer ;
526514
527515 const symbolizerWithSubSymbolizer = processSymbolLayerWithSubSymbol (
528516 symbol ,
529517 layer ,
530518 symbolCharacterMaker ,
531519 options ,
520+ undefined ,
521+ undefined ,
522+ respectFrame ,
532523 ) ;
533524 if ( symbolizerWithSubSymbolizer . length ) {
534525 return symbolizerWithSubSymbolizer ;
0 commit comments