@@ -206,11 +206,43 @@ function makeOverpassQuery({
206206 ) ;
207207 }
208208
209+ /*
210+ A polygon may have an outer ring and (optional) inner rings (to exclude). We use the "stitched
211+ path" trick to exlude any inner rings. All rings get converted to`lat1 lng1 lat2 lng2..`, but
212+ we also repeat the first (outer) vertice before and after each inner ring.
213+
214+ Examples:
215+ - Simple polygon: `lat1 lng1 lat2 lng2...`
216+ - Polygon with two inner rings:
217+ ```
218+ outer-lat1 outer-lng1 outer-lat2 outer-lng2...
219+ outer-lat1 outer-lng1
220+ inner1-lat1 inner1-lng1 inner1-lat2 inner1-lng2...
221+ outer-lat1 outer-lng1
222+ inner2-lat1 inner2-lng1 inner2-lat2 inner2-lng2...
223+ outer-lat1 outer-lng1
224+ ```
225+ Note: the newlines wouldn't actually exist
226+ */
209227 spatialModifiers = areaSelection . feature . geometry . coordinates . map (
210- ( polygonCoordinates ) => {
211- const polyModifierValue = polygonCoordinates [ 0 ]
212- . map ( ( [ lng , lat ] ) => `${ lat } ${ lng } ` )
213- . join ( " " ) ;
228+ ( polygons ) => {
229+ let polyModifierValue = "" ;
230+ let firstLatLngPair : string | undefined ;
231+
232+ for ( let i = 0 ; i < polygons . length ; i ++ ) {
233+ const latLngPairs = polygons [ i ] . map ( ( [ lng , lat ] ) => `${ lat } ${ lng } ` ) ;
234+
235+ firstLatLngPair ??= latLngPairs [ 0 ] ;
236+ if ( i ) {
237+ latLngPairs . unshift ( firstLatLngPair ) ;
238+ }
239+ polyModifierValue += latLngPairs . join ( " " ) ;
240+ }
241+
242+ if ( polygons . length > 1 ) {
243+ polyModifierValue += firstLatLngPair ;
244+ }
245+
214246 return `(poly:"${ polyModifierValue } ")` ;
215247 } ,
216248 ) ;
0 commit comments