@@ -149,11 +149,57 @@ function geojsonToOsmGeometry(
149
149
return [ relation ] ;
150
150
}
151
151
152
- // TODO: support other geometries
152
+ // this logic is based on what RapiD uses:
153
+ // https://github.com/facebookincubator/Rapid/blob/8a58b2/modules/services/esri_data.js#L103-L134
153
154
case 'Polygon' :
154
155
case 'MultiPolygon' : {
155
- return undefined ;
156
+ const nodes : OsmNode [ ] = [ ] ;
157
+ const ways : { way : OsmWay ; role : string } [ ] = [ ] ;
158
+
159
+ const groups =
160
+ geom . type === 'Polygon' ? [ geom . coordinates ] : geom . coordinates ;
161
+
162
+ for ( const rings of groups ) {
163
+ for ( const [ index , ring ] of rings . entries ( ) ) {
164
+ const ringNodes = ring . map ( coordToNode ) ;
165
+ if ( ringNodes . length < 3 ) return [ ] ;
166
+
167
+ const first = ringNodes [ 0 ] ;
168
+ const last = ringNodes . at ( - 1 ) ;
169
+ if ( first !== last ) ringNodes . push ( first ) ; // sanity check, ensure rings are closed
170
+
171
+ const way : OsmWay = {
172
+ ...TEMPLATE_OSM_FEATURE ,
173
+ type : 'way' ,
174
+ id : nextId . way -- ,
175
+ nodes : ringNodes . map ( ( n ) => n . id ) ,
176
+ } ;
177
+ nodes . push ( ...ringNodes ) ;
178
+ ways . push ( { way, role : index === 0 ? 'outer' : 'inner' } ) ;
179
+ }
180
+
181
+ if ( groups . length === 1 && rings . length === 1 ) {
182
+ // special case: only 1 ring, so we don't need a multipolygon,
183
+ // we can just create a simple way and abort early.
184
+ const way : OsmWay = { ...baseFeature , ...ways [ 0 ] . way } ;
185
+ return [ way , ...nodes ] ;
186
+ }
187
+ }
188
+
189
+ const relation : OsmRelation = {
190
+ ...baseFeature ,
191
+ tags : { type : 'multipolygon' , ...baseFeature . tags } ,
192
+ type : 'relation' ,
193
+ id : nextId . relation -- ,
194
+ members : ways . map ( ( { way, role } ) => ( {
195
+ type : 'way' ,
196
+ ref : way . id ,
197
+ role,
198
+ } ) ) ,
199
+ } ;
200
+ return [ relation , ...ways . map ( ( w ) => w . way ) , ...nodes ] ;
156
201
}
202
+
157
203
default : {
158
204
return undefined ;
159
205
}
0 commit comments