27
27
help = 'the input file containning the geometry as kml, shp or geojson' )
28
28
parser .add_argument ('-t' , '--tileserver' , nargs = '?' , default = 'bing' ,
29
29
choices = ['bing' , 'digital_globe' , 'google' , 'custom' ])
30
- parser .add_argument ('-z' , '--zoomlevel' , required = False , default = None , type = int ,
30
+ parser .add_argument ('-z' , '--zoomlevel' , required = False , default = 18 , type = int ,
31
31
help = 'the zoom level.' )
32
32
parser .add_argument ('-p' , '--project_id' , required = False , default = None , type = int ,
33
33
help = 'the project id.' )
@@ -228,23 +228,31 @@ def get_horizontal_slice(extent, geomcol, zoom):
228
228
229
229
230
230
def get_vertical_slice (geomcol , zoom ):
231
- # the width threshold defines how "long" the grous are
231
+ # this functions slices the horizontal stripes vertically
232
+ # each stripe has a height of three tiles
233
+ # the width depends on the width threshold set below
234
+ # the final group polygon is calculated from TileX_min, TileX_max, TileY_min, TileY_max
235
+
236
+ # the width threshold defines how "long" the groups are
232
237
width_threshold = 70
238
+ # create an empty dict for the group ids and TileY_min, TileY_may, TileX_min, TileX_max
239
+ raw_groups = {}
240
+ group_id = 100
233
241
234
- slice_collection = ogr .Geometry (ogr .wkbGeometryCollection )
242
+ # add these variables to test, if groups are created correctly
243
+ TileY_top = - 1
235
244
236
245
# process each polygon individually
237
246
for p in range (0 , geomcol .GetGeometryCount ()):
238
- polygon_to_slice = geomcol .GetGeometryRef (p )
247
+ horizontal_slice = geomcol .GetGeometryRef (p )
239
248
240
249
# sometimes we get really really small polygones, skip these
241
- if polygon_to_slice .GetArea () < 0.0000001 :
250
+ if horizontal_slice .GetArea () < 0.0000001 :
242
251
continue
243
- logging .info ('polygon area: %s' % polygon_to_slice .GetArea ())
252
+ logging .info ('polygon area: %s' % horizontal_slice .GetArea ())
244
253
logging .info ('skipped this polygon' )
245
254
246
- #print(polygon_to_slice)
247
- extent = polygon_to_slice .GetEnvelope ()
255
+ extent = horizontal_slice .GetEnvelope ()
248
256
xmin = extent [0 ]
249
257
xmax = extent [1 ]
250
258
ymin = extent [2 ]
@@ -254,25 +262,35 @@ def get_vertical_slice(geomcol, zoom):
254
262
pixel = lat_long_zoom_to_pixel_coords (ymax , xmin , zoom )
255
263
tile = pixel_coords_to_tile_address (pixel .x , pixel .y )
256
264
TileX_left = tile .x
257
- TileY_top = tile .y
265
+
266
+ # this is a fix for incorrect groups height
267
+ # this is caused by a wrong calculation of the tile coordinates, probably because of float precision
268
+ # previously we started with tile x and tiley -->
269
+ # then calculated correspondinglat, lon -->
270
+ # finally we calculated corresponding tilex and tile y again,
271
+ # however in some rare occassion the tileY from the beginning and from the end were different
272
+ # thats why we now don't calculate tile.y coordinates from lat, lon but use the coordinates of the upper group
273
+ # this assumes that horizontal slices are ordered north to south
274
+ if TileY_top < 0 :
275
+ TileY_top = tile .y
276
+ TileY_bottom = TileY_top + 3
277
+ else :
278
+ TileY_top += 3
279
+ TileY_bottom += 3
258
280
259
281
# get lower right tile coordinates
260
282
pixel = lat_long_zoom_to_pixel_coords (ymin , xmax , zoom )
261
283
tile = pixel_coords_to_tile_address (pixel .x , pixel .y )
262
284
TileX_right = tile .x
263
- TileY_bottom = tile .y
264
-
265
285
266
286
TileWidth = abs (TileX_right - TileX_left )
267
287
TileHeight = abs (TileY_top - TileY_bottom )
268
288
269
- TileY = TileY_top
270
289
TileX = TileX_left
271
290
272
291
# get rows
273
292
rows = int (ceil (TileHeight / 3 ))
274
293
275
-
276
294
# get columns
277
295
cols = int (ceil (TileWidth / width_threshold ))
278
296
# how wide should the group be, calculate from total width and do equally for all slices
@@ -301,20 +319,24 @@ def get_vertical_slice(geomcol, zoom):
301
319
ring .AddPoint (lon_right , lat_bottom )
302
320
ring .AddPoint (lon_left , lat_bottom )
303
321
ring .AddPoint (lon_left , lat_top )
304
- poly = ogr .Geometry (ogr .wkbPolygon )
305
- poly .AddGeometry (ring )
306
-
307
- # sliced_poly = poly.Intersection(polygon_to_slice)
308
- if poly .GetGeometryName () == 'POLYGON' :
309
- slice_collection .AddGeometry (poly )
310
- else :
311
- pass
322
+ group_poly = ogr .Geometry (ogr .wkbPolygon )
323
+ group_poly .AddGeometry (ring )
324
+
325
+ # add info to groups_dict
326
+ group_id += 1
327
+ raw_groups [group_id ] = {
328
+ "xMin" : str (TileX ),
329
+ "xMax" : str (TileX + step_size - 1 ),
330
+ "yMin" : str (TileY_top ),
331
+ "yMax" : str (TileY_bottom - 1 ),
332
+ "group_polygon" : group_poly
333
+ }
312
334
313
335
#####################
314
336
TileX = TileX + step_size
315
337
316
338
logging .warning ('created vertical_slice' )
317
- return slice_collection
339
+ return raw_groups
318
340
319
341
320
342
def save_geom_as_geojson (geomcol , outfile ):
@@ -430,11 +452,9 @@ def create_tasks(xmin, xmax, ymin, ymax, config):
430
452
return tasks
431
453
432
454
433
- def create_groups (geomcol , config ):
455
+ def create_groups (groups , config ):
434
456
# this function will create a json file to upload in firebase groups table
435
457
436
- groups = {}
437
-
438
458
# Create the output Driver
439
459
outDriver = ogr .GetDriverByName ('GeoJSON' )
440
460
# Create the output GeoJSON
@@ -449,41 +469,23 @@ def create_groups(geomcol, config):
449
469
outLayer .CreateField (ogr .FieldDefn ('ymin' , ogr .OFTInteger ))
450
470
outLayer .CreateField (ogr .FieldDefn ('ymax' , ogr .OFTInteger ))
451
471
452
- for p in range ( 0 , geomcol . GetGeometryCount () ):
472
+ for group_id , group in groups . items ( ):
453
473
454
- group_geometry = geomcol .GetGeometryRef (p )
474
+ group_geometry = group ['group_polygon' ]
475
+ del group ['group_polygon' ]
455
476
456
- group = {}
457
477
group ['zoomLevel' ] = config ['zoom' ]
458
478
group ['projectId' ] = str (config ['project_id' ])
459
479
group ['distributedCount' ] = 0
460
480
group ['completedCount' ] = 0
461
481
group ['reportCount' ] = 0
462
- group ['id' ] = 100 + p
463
-
464
- extent = group_geometry .GetEnvelope ()
465
- xmin , xmax , ymin , ymax = extent
466
-
467
- # get upper left left tile coordinates
468
- pixel = lat_long_zoom_to_pixel_coords (ymax , xmin , config ['zoom' ])
469
- tile = pixel_coords_to_tile_address (pixel .x , pixel .y )
470
- group ['xMin' ] = str (tile .x )
471
- group ['yMin' ] = str (tile .y )
472
-
473
- # get lower right tile coordinates
474
- pixel = lat_long_zoom_to_pixel_coords (ymin , xmax , config ['zoom' ])
475
- tile = pixel_coords_to_tile_address (pixel .x , pixel .y )
476
- # we have to reduce this by 1
477
- group ['xMax' ] = str (tile .x - 1 )
478
- group ['yMax' ] = str (tile .y - 1 )
482
+ group ['id' ] = group_id
479
483
480
484
# get tasks for this group
481
485
group ['tasks' ] = create_tasks (
482
486
group ['xMin' ], group ['xMax' ], group ['yMin' ], group ['yMax' ], config )
483
487
484
488
group ['count' ] = len (group ['tasks' ])
485
- # add information to groups dict
486
- groups [group ['id' ]] = group
487
489
488
490
# write to geojson file
489
491
featureDefn = outLayer .GetLayerDefn ()
@@ -532,14 +534,12 @@ def run_create_groups(input_file, project_id, tileserver, custom_tileserver_url,
532
534
extent , geomcol = get_geometry_from_file (input_file )
533
535
534
536
horizontal_slice = get_horizontal_slice (extent , geomcol , config ['zoom' ])
535
- # outfile = 'horizontally_sliced_groups_{}.geojson'.format(config["project_id"])
536
- # save_geom_as_geojson(horizontal_slice, outfile)
537
+ #outfile = 'data/ horizontally_sliced_groups_{}.geojson'.format(config["project_id"])
538
+ #save_geom_as_geojson(horizontal_slice, outfile)
537
539
538
- vertical_slice = get_vertical_slice (horizontal_slice , config ['zoom' ])
539
- # outfile = 'vertically_sliced_groups_{}.geojson'.format(config["project_id"])
540
- # save_geom_as_geojson(vertical_slice, outfile)
540
+ raw_groups = get_vertical_slice (horizontal_slice , config ['zoom' ])
541
541
542
- groups = create_groups (vertical_slice , config )
542
+ groups = create_groups (raw_groups , config )
543
543
outfile = 'data/groups_{}.json' .format (config ["project_id" ])
544
544
# save groups as json file
545
545
with open (outfile , 'w' ) as fp :
0 commit comments