topo_map_processor 0.1.13__tar.gz → 0.1.14__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topo_map_processor
3
- Version: 0.1.13
3
+ Version: 0.1.14
4
4
  Summary: Library for processing topographic maps
5
5
  Project-URL: homepage, https://github.com/ramSeraph/topo_map_processor
6
6
  Project-URL: repository, https://github.com/ramSeraph/topo_map_processor.git
@@ -239,11 +239,12 @@ The tool works in two stages. First, it calculates the full set of sheets that n
239
239
  In the second stage, it retiles the affected area. It uses the pull list to create a temporary virtual raster (`.vrt`), generates new base tiles for the affected region, and then reconstructs the upper-level tiles by pulling existing, unaffected tiles from the PMTiles source.
240
240
 
241
241
  ```bash
242
- retile --retile-list-file <file> --bounds-file <file> [--max-zoom <zoom>] [--tiffs-dir <dir>] [--tiles-dir <dir>] [--from-source <source>] [--sheets-to-pull-list-outfile <file>] [--num-parallel <processes>] [--tile-quality <quality>]
242
+ retile --retile-list-file <file> --bounds-file <file> [--dummy-bounds-file <file>] [--max-zoom <zoom>] [--tiffs-dir <dir>] [--tiles-dir <dir>] [--from-source <source>] [--sheets-to-pull-list-outfile <file>] [--num-parallel <processes>] [--tile-quality <quality>]
243
243
  ```
244
244
 
245
245
  - `--retile-list-file`: File containing the list of sheets to retile. (Required)
246
246
  - `--bounds-file`: GeoJSON file containing the list of available sheets and their geographic bounds. (Required)
247
+ - `--dummy-bounds-file`: GeoJSON file containing geographic bounds of areas that need to be updated. These areas might not have any new sheets. (Optional)
247
248
  - `--max-zoom`: Maximum zoom level to create tiles for. Defaults to the max zoom from the source if `--from-source` is provided, otherwise it is required.
248
249
  - `--tiffs-dir`: Directory where the GeoTIFFs are located. (Required if not in pull-list generation mode)
249
250
  - `--tiles-dir`: Directory where the tiles will be created. (Required if not in pull-list generation mode)
@@ -190,11 +190,12 @@ The tool works in two stages. First, it calculates the full set of sheets that n
190
190
  In the second stage, it retiles the affected area. It uses the pull list to create a temporary virtual raster (`.vrt`), generates new base tiles for the affected region, and then reconstructs the upper-level tiles by pulling existing, unaffected tiles from the PMTiles source.
191
191
 
192
192
  ```bash
193
- retile --retile-list-file <file> --bounds-file <file> [--max-zoom <zoom>] [--tiffs-dir <dir>] [--tiles-dir <dir>] [--from-source <source>] [--sheets-to-pull-list-outfile <file>] [--num-parallel <processes>] [--tile-quality <quality>]
193
+ retile --retile-list-file <file> --bounds-file <file> [--dummy-bounds-file <file>] [--max-zoom <zoom>] [--tiffs-dir <dir>] [--tiles-dir <dir>] [--from-source <source>] [--sheets-to-pull-list-outfile <file>] [--num-parallel <processes>] [--tile-quality <quality>]
194
194
  ```
195
195
 
196
196
  - `--retile-list-file`: File containing the list of sheets to retile. (Required)
197
197
  - `--bounds-file`: GeoJSON file containing the list of available sheets and their geographic bounds. (Required)
198
+ - `--dummy-bounds-file`: GeoJSON file containing geographic bounds of areas that need to be updated. These areas might not have any new sheets. (Optional)
198
199
  - `--max-zoom`: Maximum zoom level to create tiles for. Defaults to the max zoom from the source if `--from-source` is provided, otherwise it is required.
199
200
  - `--tiffs-dir`: Directory where the GeoTIFFs are located. (Required if not in pull-list generation mode)
200
201
  - `--tiles-dir`: Directory where the tiles will be created. (Required if not in pull-list generation mode)
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.1.13'
32
- __version_tuple__ = version_tuple = (0, 1, 13)
31
+ __version__ = version = '0.1.14'
32
+ __version_tuple__ = version_tuple = (0, 1, 14)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -4,6 +4,7 @@ import re
4
4
  import sys
5
5
  import json
6
6
  import argparse
7
+ import tempfile
7
8
 
8
9
  import time
9
10
  import subprocess
@@ -319,7 +320,7 @@ def check_sheets(sheets_to_pull, tiffs_dir):
319
320
  raise Exception(f'missing files {missing}')
320
321
 
321
322
 
322
- def get_sheet_data(bounds_fname):
323
+ def get_sheet_data(bounds_fname, dummy=False):
323
324
 
324
325
  index_file = Path(bounds_fname)
325
326
  if not index_file.exists():
@@ -327,9 +328,14 @@ def get_sheet_data(bounds_fname):
327
328
 
328
329
  index_data = json.loads(index_file.read_text())
329
330
 
331
+ dummy_count = 0
330
332
  sheets_to_box = {}
331
333
  for f in index_data['features']:
332
- sheet_no = f['properties']['id']
334
+ if not dummy:
335
+ sheet_no = f['properties']['id']
336
+ else:
337
+ sheet_no = f'dummy_{dummy_count}'
338
+ dummy_count += 1
333
339
  geom = shape(f['geometry'])
334
340
  xmin, ymin, xmax, ymax = geom.bounds
335
341
  box = mercantile.LngLatBbox(xmin, ymin, xmax, ymax)
@@ -354,33 +360,61 @@ def get_base_tile_sheet_mappings(sheets_to_box, base_zoom):
354
360
 
355
361
 
356
362
 
357
- def assess_sheet_requirements(retile_list_file, bounds_file, max_zoom):
363
+ def assess_sheet_requirements(retile_list_file, bounds_file, dummy_bounds_file, max_zoom):
358
364
 
359
365
  retile_sheets = retile_list_file.read_text().split('\n')
360
366
  retile_sheets = set([ r.strip().replace('.tif', '') for r in retile_sheets if r.strip() != '' ])
361
367
 
362
368
  print('getting base tiles to sheet mapping')
363
369
  sheets_to_box = get_sheet_data(bounds_file)
370
+ dummy_sheets_to_box = {}
371
+ if dummy_bounds_file:
372
+ dummy_sheets_to_box = get_sheet_data(dummy_bounds_file, dummy=True)
373
+ sheets_to_box.update(dummy_sheets_to_box)
374
+
364
375
  sheets_to_base_tiles, base_tiles_to_sheets = get_base_tile_sheet_mappings(sheets_to_box, max_zoom)
365
376
 
366
377
  print('calculating sheets to pull')
367
378
  affected_base_tiles = set()
368
379
  for sheet_no in retile_sheets:
369
380
  affected_base_tiles.update(sheets_to_base_tiles[sheet_no])
381
+ for sheet_no in dummy_sheets_to_box.keys():
382
+ affected_base_tiles.update(sheets_to_base_tiles[sheet_no])
370
383
 
371
384
  sheets_to_pull = set()
372
385
  for tile in affected_base_tiles:
373
386
  to_add = base_tiles_to_sheets[tile]
374
387
  for sheet in to_add:
375
- sheets_to_pull.add(sheet + '.tif')
388
+ if sheet not in dummy_sheets_to_box:
389
+ sheets_to_pull.add(sheet + '.tif')
376
390
 
377
391
  return sheets_to_pull, affected_base_tiles
378
392
 
393
+ def create_dummy_sheets(dummy_bounds_file, tiffs_dir):
394
+ print('creating dummy sheets')
395
+ dummy_sheets_to_box = get_sheet_data(dummy_bounds_file, dummy=True)
396
+
397
+ for sheet_no, box in dummy_sheets_to_box.items():
398
+ file = tiffs_dir.joinpath(f'{sheet_no}.tif')
399
+ if file.exists():
400
+ continue
401
+
402
+ west, south, east, north = box.west, box.south, box.east, box.north
403
+ temp_file = Path(tempfile.mktemp(suffix='.tif'))
404
+ cmd = f'gdal_create -of GTiff -a_srs EPSG:4326 -a_ullr {west} {north} {east} {south} -a_nodata 0 -ot Byte -co COMPRESS=LZW -bands 3 -burn 0 0 0 -outsize 256 256 {temp_file}'
405
+ run_external(cmd)
406
+ temp_file_1 = Path(tempfile.mktemp(suffix='.tif'))
407
+ cmd = f'gdalwarp -dstalpha -t_srs EPSG:3857 -co COMPRESS=LZW {temp_file} {temp_file_1}'
408
+ run_external(cmd)
409
+ cmd = f'gdal_translate -co TILING_SCHEME=GoogleMapsCompatible -co COMPRESS=JPEG -co QUALITY=100 --config GDAL_TIFF_INTERNAL_MASK YES -b 1 -b 2 -b 3 -mask 4 --config GDAL_CACHEMAX 512 -of COG {temp_file_1} {file}'
410
+ run_external(cmd)
411
+
379
412
  def retile_main(args):
380
413
 
381
414
  parser = argparse.ArgumentParser()
382
415
  parser.add_argument('--retile-list-file', required=True, help='File containing list of sheets to retile')
383
416
  parser.add_argument('--bounds-file', required=True, help='Geojson file containing list of available sheets and their georaphic bounds')
417
+ parser.add_argument('--dummy-bounds-file', required=False, help='Geojson file containing georaphic bounds of areas that need to be updated, these areas might not have any new sheets')
384
418
  parser.add_argument('--max-zoom', type=int, help='Maximum zoom level to create tiles for, needed only when --from-source is not provided')
385
419
  parser.add_argument('--sheets-to-pull-list-outfile', default=None,
386
420
  help='Output into which we write the list of sheet that need to be pulled, if set, the script ends after it created the list file')
@@ -400,6 +434,12 @@ def retile_main(args):
400
434
  if not bounds_file.exists():
401
435
  parser.error(f'Bounds file {args.bounds_file} does not exist')
402
436
 
437
+ dummy_bounds_file = None
438
+ if args.dummy_bounds_file:
439
+ dummy_bounds_file = Path(args.dummy_bounds_file)
440
+ if not dummy_bounds_file.exists():
441
+ parser.error(f'Dummy bounds file {args.dummy_bounds_file} does not exist')
442
+
403
443
 
404
444
  if not args.sheets_to_pull_list_outfile:
405
445
  missing = []
@@ -430,7 +470,7 @@ def retile_main(args):
430
470
  print(f'--max-zoom argument is ignored when --from-source is set, using max zoom from original source: {max_zoom}')
431
471
 
432
472
  # calculate the sheets to pull and affected base tiles
433
- sheets_to_pull, affected_base_tiles = assess_sheet_requirements(retile_list_file, bounds_file, max_zoom)
473
+ sheets_to_pull, affected_base_tiles = assess_sheet_requirements(retile_list_file, bounds_file, dummy_bounds_file, max_zoom)
434
474
 
435
475
  if args.sheets_to_pull_list_outfile is not None:
436
476
  Path(args.sheets_to_pull_list_outfile).write_text('\n'.join(sheets_to_pull) + '\n')
@@ -443,6 +483,9 @@ def retile_main(args):
443
483
  print('check the sheets availability')
444
484
  check_sheets(sheets_to_pull, tiffs_dir)
445
485
 
486
+ if dummy_bounds_file is not None:
487
+ create_dummy_sheets(dummy_bounds_file, tiffs_dir)
488
+
446
489
  metadata = orig_source.get_metadata()
447
490
  tile_extension = metadata['format']
448
491
  if tile_extension == 'jpg':