topo_map_processor 0.1.6__tar.gz → 0.1.8__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.
Files changed (29) hide show
  1. {topo_map_processor-0.1.6 → topo_map_processor-0.1.8}/.gitignore +1 -0
  2. {topo_map_processor-0.1.6 → topo_map_processor-0.1.8}/PKG-INFO +64 -31
  3. {topo_map_processor-0.1.6 → topo_map_processor-0.1.8}/README.md +52 -22
  4. {topo_map_processor-0.1.6 → topo_map_processor-0.1.8}/pyproject.toml +29 -10
  5. {topo_map_processor-0.1.6 → topo_map_processor-0.1.8}/topo_map_processor/_version.py +2 -2
  6. topo_map_processor-0.1.8/topo_map_processor/bash_scripts/__init__.py +0 -0
  7. topo_map_processor-0.1.8/topo_map_processor/bash_scripts/generate_lists.sh +33 -0
  8. topo_map_processor-0.1.8/topo_map_processor/bash_scripts/upload_to_release.sh +149 -0
  9. topo_map_processor-0.1.6/topo_map_processor/__init__.py → topo_map_processor-0.1.8/topo_map_processor/processor.py +1 -1
  10. topo_map_processor-0.1.8/topo_map_processor/tools/__init__.py +0 -0
  11. topo_map_processor-0.1.8/topo_map_processor/tools/download_mosaic.py +254 -0
  12. topo_map_processor-0.1.8/topo_map_processor/tools/execute_bash.py +57 -0
  13. topo_map_processor-0.1.8/topo_map_processor/tools/partition.py +433 -0
  14. topo_map_processor-0.1.8/topo_map_processor/tools/retile.py +474 -0
  15. topo_map_processor-0.1.8/topo_map_processor/tools/tile.py +153 -0
  16. topo_map_processor-0.1.8/topo_map_processor/tools/tile_sources.py +417 -0
  17. topo_map_processor-0.1.6/.github/workflows/publish.yml +0 -56
  18. topo_map_processor-0.1.6/.python-version +0 -1
  19. topo_map_processor-0.1.6/samples/corner1.png +0 -0
  20. topo_map_processor-0.1.6/samples/corner2.png +0 -0
  21. topo_map_processor-0.1.6/samples/corner3.png +0 -0
  22. topo_map_processor-0.1.6/topo_map_processor/tools/partition.py +0 -394
  23. topo_map_processor-0.1.6/topo_map_processor/tools/retile.py +0 -333
  24. topo_map_processor-0.1.6/topo_map_processor/tools/tile.py +0 -86
  25. topo_map_processor-0.1.6/topo_map_processor/tools/tile_sources.py +0 -286
  26. topo_map_processor-0.1.6/uv.lock +0 -940
  27. {topo_map_processor-0.1.6 → topo_map_processor-0.1.8}/LICENSE +0 -0
  28. {topo_map_processor-0.1.6/topo_map_processor/tools → topo_map_processor-0.1.8/topo_map_processor}/__init__.py +0 -0
  29. {topo_map_processor-0.1.6 → topo_map_processor-0.1.8}/topo_map_processor/tools/collect_bounds.py +0 -0
@@ -1,5 +1,6 @@
1
1
  # Python-generated files
2
2
  __pycache__/
3
+ topo_map_processor/_version.py
3
4
  *.py[oc]
4
5
  build/
5
6
  dist/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topo_map_processor
3
- Version: 0.1.6
3
+ Version: 0.1.8
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
@@ -31,17 +31,20 @@ License: This is free and unencumbered software released into the public domain.
31
31
  For more information, please refer to <https://unlicense.org>
32
32
  License-File: LICENSE
33
33
  Requires-Python: >=3.12
34
- Requires-Dist: easyocr>=1.7.2
35
- Requires-Dist: imgcat>=0.6.0
36
34
  Requires-Dist: mercantile>=1.2.1
37
- Requires-Dist: numpy>=2.3.1
38
- Requires-Dist: opencv-python-headless>=4.11.0.86
39
- Requires-Dist: pillow>=11.3.0
40
35
  Requires-Dist: pmtiles>=3.4.1
41
- Requires-Dist: pyproj>=3.7.1
42
- Requires-Dist: pytesseract>=0.3.13
43
- Requires-Dist: rasterio>=1.4.3
36
+ Requires-Dist: requests>=2.32.4
44
37
  Requires-Dist: shapely>=2.1.1
38
+ Provides-Extra: easyocr
39
+ Requires-Dist: easyocr>=1.7.2; extra == 'easyocr'
40
+ Provides-Extra: parse
41
+ Requires-Dist: imgcat>=0.6.0; extra == 'parse'
42
+ Requires-Dist: numpy>=2.3.1; extra == 'parse'
43
+ Requires-Dist: opencv-python-headless>=4.11.0.86; extra == 'parse'
44
+ Requires-Dist: pillow>=11.3.0; extra == 'parse'
45
+ Requires-Dist: pyproj>=3.7.1; extra == 'parse'
46
+ Requires-Dist: pytesseract>=0.3.13; extra == 'parse'
47
+ Requires-Dist: rasterio>=1.4.3; extra == 'parse'
45
48
  Description-Content-Type: text/markdown
46
49
 
47
50
  # Topo Map Processor [![PyPI - Latest Version](https://img.shields.io/pypi/v/topo_map_processor)](https://pypi.org/project/topo_map_processor/) [![GitHub Tag](https://img.shields.io/github/v/tag/ramSeraph/topo_map_processor?filter=v*)](https://github.com/ramSeraph/topo_map_processor/releases/latest)
@@ -119,7 +122,7 @@ The `TopoMapProcessor` class provides a framework for processing individual map
119
122
  Here's an example of how to use the `TopoMapProcessor` class.
120
123
 
121
124
  ```python
122
- from topo_map_processor import TopoMapProcessor, LineRemovalParams
125
+ from topo_map_processor.processor import TopoMapProcessor, LineRemovalParams
123
126
 
124
127
  class SampleProcessor(TopoMapProcessor):
125
128
 
@@ -205,6 +208,15 @@ Similar to corner detection, the `locate_grid_lines` method can be implemented u
205
208
 
206
209
  - **`get_grid_line_corrections`**: This method serves as a refinement step to improve accuracy. While the transformer provides a very close estimate, this function can correct for minor printing or scanning inaccuracies. For each projected grid intersection, it searches a small area in the actual image for the *true* intersection of printed lines, adjusting the point to match the visual data. This ensures that the lines targeted for removal are precisely the ones printed on the map.
207
210
 
211
+ ### Tile Sources
212
+
213
+ The `topo_map_processor.tools.tile_sources` module provides classes for reading tiles from different sources.
214
+
215
+ - `DiskTilesSource`: Reads tiles from a directory on the local disk.
216
+ - `MBTilesSource`: Reads tiles from an MBTiles file.
217
+ - `PMTilesSource`: Reads tiles from a PMTiles file.
218
+ - `StackedTileSource`: Combines multiple tile sources (Disk, MBTiles, PMTiles) into a single logical source, allowing for seamless access across different storage types.
219
+
208
220
  ### Command-Line Tools
209
221
 
210
222
  This project provides several command-line tools to work with topographic maps. These tools are dynamically loaded, and you can get the most up-to-date usage information by running the tool with the `--help` flag.
@@ -221,24 +233,37 @@ collect-bounds --bounds-dir <directory> --output-file <file> [--preexisting-file
221
233
  - `--output-file`: Output GeoJSON file path. (Required)
222
234
  - `--preexisting-file`: Pre existing GeoJSON file path. (Optional)
223
235
 
236
+ #### `download-mosaic`
237
+
238
+ Downloads a PMTiles mosaic and converts it to a single MBTiles file. A mosaic is a JSON file that lists multiple PMTiles files.
239
+
240
+ ```bash
241
+ download-mosaic --mosaic_url <url> [--output_file <file>] [--request-timeout-secs <seconds>] [--num-http-retries <retries>]
242
+ ```
243
+
244
+ - `--mosaic_url`, `-u`: URL of the mosaic JSON file. (Required)
245
+ - `--output_file`, `-o`: Output MBTiles file name. If not specified, it is derived from the mosaic URL. (Optional)
246
+ - `--request-timeout-secs`, `-t`: Timeout for HTTP requests in seconds (default: 60).
247
+ - `--num-http-retries`, `-r`: Number of retries for HTTP requests (default: 3).
248
+
224
249
  #### `partition`
225
250
 
226
- Partitions a large set of tiles into smaller PMTiles files. This is useful for managing large datasets, for example, to stay within file size limits for services like GitHub Releases. When run with `--only-disk`, it creates a new partitioned `pmtiles` fileset from a directory of tiles. When run without, it can be used to re-partition an existing `pmtiles` fileset, for example after having retiled some of the sheets.
251
+ Partitions a large set of tiles into smaller PMTiles files. This is useful for managing large datasets, for example, to stay within file size limits for services like GitHub Releases. It creates a mosaic file if the output is partitioned into multiple files.
227
252
 
228
253
  ```bash
229
- partition --to-pmtiles-prefix <prefix> --from-tiles-dir <dir> [--from-pmtiles-prefix <prefix>] [--name <name>] [--description <desc>] [--max-zoom <zoom>] [--min-zoom <zoom>] [--only-disk] (--attribution <text> | --attribution-file <file>)
254
+ partition --from-source <source> [--from-source <source> ...] --to-pmtiles <file> [--size-limit <limit>]
230
255
  ```
231
256
 
232
- - `--to-pmtiles-prefix`: Prefix for the output PMTiles files. (Required)
233
- - `--from-tiles-dir`: Directory containing the input tiles. (Required)
234
- - `--from-pmtiles-prefix`: Prefix for input PMTiles files (required if not using `--only-disk`).
235
- - `--name`: Name of the mosaic. (Required if using `--only-disk`)
236
- - `--description`: Description of the mosaic. (Required if using `--only-disk`)
237
- - `--max-zoom`: Maximum zoom level for the mosaic. (Defaults to the max zoom found in the source)
238
- - `--min-zoom`: Minimum zoom level for the mosaic (default: 0).
239
- - `--only-disk`: Only read tiles from the local disk.
240
- - `--attribution`: Attribution text for the mosaic. (Required if using `--only-disk`)
241
- - `--attribution-file`: File containing attribution text. (Required if using `--only-disk`)
257
+ - `--from-source`: Path to a source file or directory. Can be repeated. Supported sources:
258
+ - `.mbtiles` file: e.g., `path/to/file.mbtiles`
259
+ - `.pmtiles` file (supports glob patterns): e.g., `path/to/*.pmtiles`
260
+ - Directory containing tiles: e.g., `path/to/tiles_dir`
261
+ - `--to-pmtiles`: Output PMTiles file. The prefix for partitioned files will be derived from this argument.
262
+ - `--size-limit`: Maximum size of each partition. Can be a number in bytes (e.g., `100000000`), or with units (e.g., `100M`, `2G`), or a preset:
263
+ - `github_release`: 2GB limit
264
+ - `github_file`: 100MB limit
265
+ - `cloudflare_object`: 512MB limit
266
+ The overhead (delta) is scaled proportionally based on the `github_release` preset (2GB with 5MB overhead). Defaults to `github_release`.
242
267
 
243
268
  #### `retile`
244
269
 
@@ -249,30 +274,38 @@ The tool works in two stages. First, it calculates the full set of sheets that n
249
274
  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.
250
275
 
251
276
  ```bash
252
- retile --retile-list-file <file> --bounds-file <file> [--max-zoom <zoom>] [--min-zoom <zoom>] [--tiffs-dir <dir>] [--tiles-dir <dir>] [--from-pmtiles-prefix <prefix>] [--sheets-to-pull-list-outfile <file>]
277
+ 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>]
253
278
  ```
254
279
 
255
280
  - `--retile-list-file`: File containing the list of sheets to retile. (Required)
256
281
  - `--bounds-file`: GeoJSON file containing the list of available sheets and their geographic bounds. (Required)
257
- - `--max-zoom`: Maximum zoom level to create tiles for. (Defaults to the max zoom from the PMTiles source)
258
- - `--min-zoom`: Minimum zoom level to create tiles for. (Defaults to the min zoom from the PMTiles source)
282
+ - `--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.
259
283
  - `--tiffs-dir`: Directory where the GeoTIFFs are located. (Required if not in pull-list generation mode)
260
284
  - `--tiles-dir`: Directory where the tiles will be created. (Required if not in pull-list generation mode)
261
- - `--from-pmtiles-prefix`: Prefix for the PMTiles source from which to pull existing tiles. (Required if not in pull-list generation mode)
285
+ - `--from-source`: Location of the source from which to pull existing tiles. Can be a glob pattern to match a group of pmtiles. Required if not in pull-list generation mode.
262
286
  - `--sheets-to-pull-list-outfile`: If provided, the script will only calculate the full list of sheets that need to be processed (including adjacent ones) and write it to this file, then exit.
287
+ - `--num-parallel`: Number of parallel processes to use for tiling (default: number of CPU cores).
288
+ - `--tile-quality`: Quality of compression for webp and jpg (default: 75).
263
289
 
264
290
  #### `tile`
265
291
 
266
292
  Creates web map tiles from a directory of GeoTIFF files. It combines them into a virtual raster (`.vrt`) for efficient processing.
267
293
 
268
294
  ```bash
269
- tile <tiles-dir> <tiffs-dir> <max-zoom> [<min-zoom>]
295
+ tile --tiles-dir <dir> --tiffs-dir <dir> --max-zoom <zoom> --name <name> --description <desc> (--attribution <text> | --attribution-file <file>) [--min-zoom <zoom>] [--tile-extension <ext>] [--tile-quality <quality>] [--num-parallel <processes>]
270
296
  ```
271
297
 
272
- - `<tiles-dir>`: Directory to store the output tiles. (Required)
273
- - `<tiffs-dir>`: Directory containing the input GeoTIFF files. (Required)
274
- - `<max-zoom>`: Maximum zoom level for tiling. (Required)
275
- - `<min-zoom>`: Minimum zoom level for tiling (default: 0).
298
+ - `--tiles-dir`: Directory to store the output tiles. (Required)
299
+ - `--tiffs-dir`: Directory containing the input GeoTIFF files. (Required)
300
+ - `--max-zoom`: Maximum zoom level for tiling. (Required)
301
+ - `--name`: Name of the mosaic. (Required)
302
+ - `--description`: Description of the mosaic. (Required)
303
+ - `--attribution`: Attribution text for the mosaic. Required if `--attribution-file` is not used.
304
+ - `--attribution-file`: File containing attribution text for the mosaic. Required if `--attribution` is not used.
305
+ - `--min-zoom`: Minimum zoom level for tiling (default: 0).
306
+ - `--tile-extension`: Tile file extension (default: webp). Choices: `webp`, `jpg`, `jpeg`, `png`.
307
+ - `--tile-quality`: Compression quality of the tiles for `webp` and `jpg` (default: 75).
308
+ - `--num-parallel`: Number of parallel processes to use for tiling (default: number of CPU cores).
276
309
 
277
310
  ### Running Tools Directly with `uvx`
278
311
 
@@ -73,7 +73,7 @@ The `TopoMapProcessor` class provides a framework for processing individual map
73
73
  Here's an example of how to use the `TopoMapProcessor` class.
74
74
 
75
75
  ```python
76
- from topo_map_processor import TopoMapProcessor, LineRemovalParams
76
+ from topo_map_processor.processor import TopoMapProcessor, LineRemovalParams
77
77
 
78
78
  class SampleProcessor(TopoMapProcessor):
79
79
 
@@ -159,6 +159,15 @@ Similar to corner detection, the `locate_grid_lines` method can be implemented u
159
159
 
160
160
  - **`get_grid_line_corrections`**: This method serves as a refinement step to improve accuracy. While the transformer provides a very close estimate, this function can correct for minor printing or scanning inaccuracies. For each projected grid intersection, it searches a small area in the actual image for the *true* intersection of printed lines, adjusting the point to match the visual data. This ensures that the lines targeted for removal are precisely the ones printed on the map.
161
161
 
162
+ ### Tile Sources
163
+
164
+ The `topo_map_processor.tools.tile_sources` module provides classes for reading tiles from different sources.
165
+
166
+ - `DiskTilesSource`: Reads tiles from a directory on the local disk.
167
+ - `MBTilesSource`: Reads tiles from an MBTiles file.
168
+ - `PMTilesSource`: Reads tiles from a PMTiles file.
169
+ - `StackedTileSource`: Combines multiple tile sources (Disk, MBTiles, PMTiles) into a single logical source, allowing for seamless access across different storage types.
170
+
162
171
  ### Command-Line Tools
163
172
 
164
173
  This project provides several command-line tools to work with topographic maps. These tools are dynamically loaded, and you can get the most up-to-date usage information by running the tool with the `--help` flag.
@@ -175,24 +184,37 @@ collect-bounds --bounds-dir <directory> --output-file <file> [--preexisting-file
175
184
  - `--output-file`: Output GeoJSON file path. (Required)
176
185
  - `--preexisting-file`: Pre existing GeoJSON file path. (Optional)
177
186
 
187
+ #### `download-mosaic`
188
+
189
+ Downloads a PMTiles mosaic and converts it to a single MBTiles file. A mosaic is a JSON file that lists multiple PMTiles files.
190
+
191
+ ```bash
192
+ download-mosaic --mosaic_url <url> [--output_file <file>] [--request-timeout-secs <seconds>] [--num-http-retries <retries>]
193
+ ```
194
+
195
+ - `--mosaic_url`, `-u`: URL of the mosaic JSON file. (Required)
196
+ - `--output_file`, `-o`: Output MBTiles file name. If not specified, it is derived from the mosaic URL. (Optional)
197
+ - `--request-timeout-secs`, `-t`: Timeout for HTTP requests in seconds (default: 60).
198
+ - `--num-http-retries`, `-r`: Number of retries for HTTP requests (default: 3).
199
+
178
200
  #### `partition`
179
201
 
180
- Partitions a large set of tiles into smaller PMTiles files. This is useful for managing large datasets, for example, to stay within file size limits for services like GitHub Releases. When run with `--only-disk`, it creates a new partitioned `pmtiles` fileset from a directory of tiles. When run without, it can be used to re-partition an existing `pmtiles` fileset, for example after having retiled some of the sheets.
202
+ Partitions a large set of tiles into smaller PMTiles files. This is useful for managing large datasets, for example, to stay within file size limits for services like GitHub Releases. It creates a mosaic file if the output is partitioned into multiple files.
181
203
 
182
204
  ```bash
183
- partition --to-pmtiles-prefix <prefix> --from-tiles-dir <dir> [--from-pmtiles-prefix <prefix>] [--name <name>] [--description <desc>] [--max-zoom <zoom>] [--min-zoom <zoom>] [--only-disk] (--attribution <text> | --attribution-file <file>)
205
+ partition --from-source <source> [--from-source <source> ...] --to-pmtiles <file> [--size-limit <limit>]
184
206
  ```
185
207
 
186
- - `--to-pmtiles-prefix`: Prefix for the output PMTiles files. (Required)
187
- - `--from-tiles-dir`: Directory containing the input tiles. (Required)
188
- - `--from-pmtiles-prefix`: Prefix for input PMTiles files (required if not using `--only-disk`).
189
- - `--name`: Name of the mosaic. (Required if using `--only-disk`)
190
- - `--description`: Description of the mosaic. (Required if using `--only-disk`)
191
- - `--max-zoom`: Maximum zoom level for the mosaic. (Defaults to the max zoom found in the source)
192
- - `--min-zoom`: Minimum zoom level for the mosaic (default: 0).
193
- - `--only-disk`: Only read tiles from the local disk.
194
- - `--attribution`: Attribution text for the mosaic. (Required if using `--only-disk`)
195
- - `--attribution-file`: File containing attribution text. (Required if using `--only-disk`)
208
+ - `--from-source`: Path to a source file or directory. Can be repeated. Supported sources:
209
+ - `.mbtiles` file: e.g., `path/to/file.mbtiles`
210
+ - `.pmtiles` file (supports glob patterns): e.g., `path/to/*.pmtiles`
211
+ - Directory containing tiles: e.g., `path/to/tiles_dir`
212
+ - `--to-pmtiles`: Output PMTiles file. The prefix for partitioned files will be derived from this argument.
213
+ - `--size-limit`: Maximum size of each partition. Can be a number in bytes (e.g., `100000000`), or with units (e.g., `100M`, `2G`), or a preset:
214
+ - `github_release`: 2GB limit
215
+ - `github_file`: 100MB limit
216
+ - `cloudflare_object`: 512MB limit
217
+ The overhead (delta) is scaled proportionally based on the `github_release` preset (2GB with 5MB overhead). Defaults to `github_release`.
196
218
 
197
219
  #### `retile`
198
220
 
@@ -203,30 +225,38 @@ The tool works in two stages. First, it calculates the full set of sheets that n
203
225
  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.
204
226
 
205
227
  ```bash
206
- retile --retile-list-file <file> --bounds-file <file> [--max-zoom <zoom>] [--min-zoom <zoom>] [--tiffs-dir <dir>] [--tiles-dir <dir>] [--from-pmtiles-prefix <prefix>] [--sheets-to-pull-list-outfile <file>]
228
+ 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>]
207
229
  ```
208
230
 
209
231
  - `--retile-list-file`: File containing the list of sheets to retile. (Required)
210
232
  - `--bounds-file`: GeoJSON file containing the list of available sheets and their geographic bounds. (Required)
211
- - `--max-zoom`: Maximum zoom level to create tiles for. (Defaults to the max zoom from the PMTiles source)
212
- - `--min-zoom`: Minimum zoom level to create tiles for. (Defaults to the min zoom from the PMTiles source)
233
+ - `--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.
213
234
  - `--tiffs-dir`: Directory where the GeoTIFFs are located. (Required if not in pull-list generation mode)
214
235
  - `--tiles-dir`: Directory where the tiles will be created. (Required if not in pull-list generation mode)
215
- - `--from-pmtiles-prefix`: Prefix for the PMTiles source from which to pull existing tiles. (Required if not in pull-list generation mode)
236
+ - `--from-source`: Location of the source from which to pull existing tiles. Can be a glob pattern to match a group of pmtiles. Required if not in pull-list generation mode.
216
237
  - `--sheets-to-pull-list-outfile`: If provided, the script will only calculate the full list of sheets that need to be processed (including adjacent ones) and write it to this file, then exit.
238
+ - `--num-parallel`: Number of parallel processes to use for tiling (default: number of CPU cores).
239
+ - `--tile-quality`: Quality of compression for webp and jpg (default: 75).
217
240
 
218
241
  #### `tile`
219
242
 
220
243
  Creates web map tiles from a directory of GeoTIFF files. It combines them into a virtual raster (`.vrt`) for efficient processing.
221
244
 
222
245
  ```bash
223
- tile <tiles-dir> <tiffs-dir> <max-zoom> [<min-zoom>]
246
+ tile --tiles-dir <dir> --tiffs-dir <dir> --max-zoom <zoom> --name <name> --description <desc> (--attribution <text> | --attribution-file <file>) [--min-zoom <zoom>] [--tile-extension <ext>] [--tile-quality <quality>] [--num-parallel <processes>]
224
247
  ```
225
248
 
226
- - `<tiles-dir>`: Directory to store the output tiles. (Required)
227
- - `<tiffs-dir>`: Directory containing the input GeoTIFF files. (Required)
228
- - `<max-zoom>`: Maximum zoom level for tiling. (Required)
229
- - `<min-zoom>`: Minimum zoom level for tiling (default: 0).
249
+ - `--tiles-dir`: Directory to store the output tiles. (Required)
250
+ - `--tiffs-dir`: Directory containing the input GeoTIFF files. (Required)
251
+ - `--max-zoom`: Maximum zoom level for tiling. (Required)
252
+ - `--name`: Name of the mosaic. (Required)
253
+ - `--description`: Description of the mosaic. (Required)
254
+ - `--attribution`: Attribution text for the mosaic. Required if `--attribution-file` is not used.
255
+ - `--attribution-file`: File containing attribution text for the mosaic. Required if `--attribution` is not used.
256
+ - `--min-zoom`: Minimum zoom level for tiling (default: 0).
257
+ - `--tile-extension`: Tile file extension (default: webp). Choices: `webp`, `jpg`, `jpeg`, `png`.
258
+ - `--tile-quality`: Compression quality of the tiles for `webp` and `jpg` (default: 75).
259
+ - `--num-parallel`: Number of parallel processes to use for tiling (default: number of CPU cores).
230
260
 
231
261
  ### Running Tools Directly with `uvx`
232
262
 
@@ -8,22 +8,29 @@ authors = [
8
8
  { name = "Sreeram Kandimalla", email = "kandimalla.sreeram@gmail.com" },
9
9
  ]
10
10
  dependencies = [
11
- "easyocr>=1.7.2",
12
- "imgcat>=0.6.0",
13
11
  "mercantile>=1.2.1",
14
- "numpy>=2.3.1",
15
- "opencv-python-headless>=4.11.0.86",
16
- "pillow>=11.3.0",
17
12
  "pmtiles>=3.4.1",
18
- "pyproj>=3.7.1",
19
- "pytesseract>=0.3.13",
20
- "rasterio>=1.4.3",
13
+ "requests>=2.32.4",
21
14
  "shapely>=2.1.1",
22
15
  ]
23
16
  dynamic = [
24
17
  "version"
25
18
  ]
26
19
 
20
+ [project.optional-dependencies]
21
+ easyocr = [
22
+ "easyocr>=1.7.2",
23
+ ]
24
+ parse = [
25
+ "numpy>=2.3.1",
26
+ "pillow>=11.3.0",
27
+ "imgcat>=0.6.0",
28
+ "opencv-python-headless>=4.11.0.86",
29
+ "pyproj>=3.7.1",
30
+ "pytesseract>=0.3.13",
31
+ "rasterio>=1.4.3",
32
+ ]
33
+
27
34
  [project.urls]
28
35
  homepage = "https://github.com/ramSeraph/topo_map_processor"
29
36
  repository = "https://github.com/ramSeraph/topo_map_processor.git"
@@ -31,9 +38,12 @@ repository = "https://github.com/ramSeraph/topo_map_processor.git"
31
38
 
32
39
  [project.scripts]
33
40
  collect-bounds = "topo_map_processor.tools.collect_bounds:cli"
41
+ download-mosaic = "topo_map_processor.tools.download_mosaic:cli"
34
42
  partition = "topo_map_processor.tools.partition:cli"
35
43
  retile = "topo_map_processor.tools.retile:cli"
36
44
  tile = "topo_map_processor.tools.tile:cli"
45
+ generate-lists = "topo_map_processor.tools.execute_bash:generate_lists"
46
+ upload-to-release = "topo_map_processor.tools.execute_bash:upload_to_release"
37
47
 
38
48
 
39
49
  [build-system]
@@ -49,6 +59,15 @@ source = "vcs"
49
59
  [tool.hatch.build.hooks.vcs]
50
60
  version-file = "topo_map_processor/_version.py"
51
61
 
52
- tool.hatch.build.targets.sdist.include = [
53
- "topo_map_processor"
62
+ [tool.hatch.build.targets.sdist]
63
+ include = [
64
+ "topo_map_processor",
65
+ "topo_map_processor/bash_scripts/**",
54
66
  ]
67
+
68
+ [tool.hatch.build.targets.wheel]
69
+ include = [
70
+ "topo_map_processor",
71
+ "topo_map_processor/bash_scripts/**",
72
+ ]
73
+
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.1.6'
21
- __version_tuple__ = version_tuple = (0, 1, 6)
20
+ __version__ = version = '0.1.8'
21
+ __version_tuple__ = version_tuple = (0, 1, 8)
@@ -0,0 +1,33 @@
1
+ #!/bin/bash
2
+
3
+ prog_name=${COMMNAND_NAME:-$(basename "$0")}
4
+ release_base=$1
5
+ ext=$2
6
+
7
+ if [ -z "$release_base" ] || [ -z "$ext" ]; then
8
+ echo "Usage: $prog_name <release_base> <extension>"
9
+ exit 1
10
+ fi
11
+
12
+ #owner=$(gh repo view --json owner -q .owner.login)
13
+ #name=$(gh repo view --json name -q .name)
14
+ #repo="$owner/$name"
15
+
16
+ echo "getting file list"
17
+ echo "name,size,url" > listing_files.csv
18
+
19
+ # Get all releases, then filter for the base release and any -extra releases.
20
+ releases_to_process=$(gh release list --repo "$repo" --json tagName -q '.[].tagName' | grep -E "^${release_base}(-extra[0-9]+)?$")
21
+ releases_to_process=$(echo "$releases_to_process" | sort -u)
22
+
23
+ echo "Will process releases: $releases_to_process"
24
+
25
+ for release in $releases_to_process; do
26
+ echo "Processing release: $release"
27
+ gh release view "$release" --json assets -q ".assets[] | select(.name | endswith(\"$ext\")) | \"\\(.name),\\(.size),\\(.url)\"" >> listing_files.csv
28
+ done
29
+
30
+ gh release upload "$release_base" listing_files.csv --clobber
31
+
32
+ rm listing_files.csv
33
+
@@ -0,0 +1,149 @@
1
+ #!/bin/bash
2
+
3
+ # A script to upload files from a folder to a GitHub release,
4
+ # skipping files that already exist in the release.
5
+ # If the fourth argument is 'yes', it will overwrite existing assets.
6
+
7
+ set -e
8
+ set -o pipefail
9
+
10
+ # --- Configuration ---
11
+ # TAG: The git tag of the release to upload to.
12
+ # FOLDER: The local folder containing the files to upload.
13
+ # OVERWRITE: Optional. Set to 'yes' to allow overwriting existing assets.
14
+ prog_name=${COMMNAND_NAME:-$(basename "$0")}
15
+
16
+ if [ "$#" -lt 3 ] || [ "$#" -gt 4 ]; then
17
+ echo "Usage: $prog_name <tag> <folder> <extension_without_the_leading_dot> [yes_to_overwrite]"
18
+ exit 1
19
+ fi
20
+
21
+ TAG="$1"
22
+ FOLDER="$2"
23
+ EXT="$3"
24
+ OVERWRITE_FLAG=${4:-no}
25
+
26
+ # --- Pre-flight Checks ---
27
+
28
+ # Check if gh is installed
29
+ if ! command -v gh &> /dev/null; then
30
+ echo "Error: gh command-line tool is not installed. Please install it to continue."
31
+ exit 1
32
+ fi
33
+
34
+ if [ -z "$TAG" ]; then
35
+ echo "Error: Release tag is not specified."
36
+ exit 1
37
+ fi
38
+
39
+ if [ ! -d "$FOLDER" ]; then
40
+ echo "Error: Folder '$FOLDER' not found."
41
+ exit 1
42
+ fi
43
+
44
+ if [ -z "$EXT" ]; then
45
+ echo "Error: Extension '$EXT' is not specified."
46
+ exit 1
47
+ fi
48
+
49
+ ALLOW_OVERWRITE=0
50
+ if [ "$OVERWRITE_FLAG" == "yes" ]; then
51
+ ALLOW_OVERWRITE=1
52
+ echo "Overwrite flag is set. Existing assets will be overwritten."
53
+ fi
54
+
55
+ # --- Main Logic ---
56
+
57
+ echo "Fetching existing assets for releases matching pattern '${TAG}(-extra[0-9]+)?'..."
58
+
59
+ # Get all releases, then filter for the base release and any -extra releases, and sort them
60
+ RELEASES_TO_PROCESS=$(gh release list --json tagName -q '.[].tagName' | grep -E "^${TAG}(-extra[0-9]+)?$" | sort -V)
61
+
62
+ if [ -z "$RELEASES_TO_PROCESS" ]; then
63
+ echo "Error: No releases found matching pattern '${TAG}(-extra[0-9]+)?'." >&2
64
+ exit 1
65
+ fi
66
+
67
+ echo "Found releases: $RELEASES_TO_PROCESS"
68
+
69
+ # Store assets with their release tags. Format: "asset_name release_tag"
70
+ EXISTING_ASSETS_WITH_RELEASES=""
71
+ for release in $RELEASES_TO_PROCESS; do
72
+ echo "Fetching assets from release: $release"
73
+ assets=$(gh release view "$release" --json assets -q '.assets[].name' 2>/dev/null || echo "")
74
+ if [ -n "$assets" ]; then
75
+ while IFS= read -r asset_name; do
76
+ if [ -n "$asset_name" ]; then
77
+ EXISTING_ASSETS_WITH_RELEASES="${EXISTING_ASSETS_WITH_RELEASES}${asset_name} ${release}"$'
78
+ '
79
+ fi
80
+ done <<< "$assets"
81
+ fi
82
+ done
83
+
84
+ if [ -z "$EXISTING_ASSETS_WITH_RELEASES" ]; then
85
+ echo "Could not fetch any assets. This could mean the releases do not have assets, or you lack permissions."
86
+ fi
87
+
88
+ # Determine available releases and their current asset counts
89
+ AVAILABLE_RELEASES=()
90
+ AVAILABLE_ASSET_COUNTS=()
91
+ for release in $RELEASES_TO_PROCESS; do
92
+ count=$(gh release view "$release" --json assets -q '.assets | length' 2>/dev/null || echo "0")
93
+
94
+ MAX_ASSETS=998
95
+ if [ "$release" == "$TAG" ]; then
96
+ MAX_ASSETS=988
97
+ fi
98
+
99
+ if [ "$count" -lt "$MAX_ASSETS" ]; then
100
+ AVAILABLE_RELEASES+=("$release")
101
+ AVAILABLE_ASSET_COUNTS+=("$count")
102
+ fi
103
+ done
104
+
105
+ echo "Starting upload process from folder '$FOLDER'..."
106
+
107
+ # Find all files in the folder that are not yet in any release and loop through them.
108
+ find "${FOLDER}" -type f | grep "^.*\.${EXT}$" | while read -r FILE_PATH; do
109
+ FILENAME=$(basename "$FILE_PATH")
110
+
111
+ RELEASE_FOR_ASSET=$(echo -n "$EXISTING_ASSETS_WITH_RELEASES" | grep "^${FILENAME} " | head -n 1 | awk '{print $2}')
112
+
113
+ if [ -n "$RELEASE_FOR_ASSET" ]; then
114
+ # Asset exists
115
+ if [ "$ALLOW_OVERWRITE" -eq 1 ]; then
116
+ echo " -> Overwriting '$FILENAME' in release '$RELEASE_FOR_ASSET'..."
117
+ gh release upload "$RELEASE_FOR_ASSET" "$FILE_PATH" --clobber
118
+ else
119
+ echo " -> Skipping '$FILENAME', it already exists in release '$RELEASE_FOR_ASSET'."
120
+ fi
121
+ continue
122
+ fi
123
+
124
+ # Find a release to upload to for a new asset
125
+ if [ ${#AVAILABLE_RELEASES[@]} -eq 0 ]; then
126
+ echo "Error: All existing releases are full. No space to upload '$FILENAME'." >&2
127
+ exit 1
128
+ fi
129
+
130
+ UPLOAD_TARGET=${AVAILABLE_RELEASES[0]}
131
+
132
+ echo " -> Uploading '$FILENAME' to '$UPLOAD_TARGET'..."
133
+ gh release upload "$UPLOAD_TARGET" "$FILE_PATH"
134
+
135
+ # Update asset count and remove release from available list if full
136
+ AVAILABLE_ASSET_COUNTS[0]=$((${AVAILABLE_ASSET_COUNTS[0]} + 1))
137
+
138
+ MAX_ASSETS=998
139
+ if [ "$UPLOAD_TARGET" == "$TAG" ]; then
140
+ MAX_ASSETS=988
141
+ fi
142
+
143
+ if [ "${AVAILABLE_ASSET_COUNTS[0]}" -ge "$MAX_ASSETS" ]; then
144
+ AVAILABLE_RELEASES=("${AVAILABLE_RELEASES[@]:1}")
145
+ AVAILABLE_ASSET_COUNTS=("${AVAILABLE_ASSET_COUNTS[@]:1}")
146
+ fi
147
+ done
148
+
149
+ echo "Upload process complete."
@@ -14,7 +14,6 @@ import cv2
14
14
  import numpy as np
15
15
 
16
16
  import pytesseract
17
- import easyocr
18
17
  from PIL import Image
19
18
  from imgcat import imgcat
20
19
 
@@ -551,6 +550,7 @@ class TopoMapProcessor:
551
550
  global easy_ocr_reader
552
551
 
553
552
  if easy_ocr_reader is None:
553
+ import easyocr
554
554
  easy_ocr_reader = easyocr.Reader(['en'], gpu=False)
555
555
 
556
556
  mask = np.zeros(img.shape[:2], dtype=np.uint8)