topo_map_processor 0.1.10__tar.gz → 0.1.12__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.
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/PKG-INFO +9 -45
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/README.md +7 -43
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/pyproject.toml +1 -9
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/_version.py +16 -3
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/processor.py +9 -4
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/tools/retile.py +7 -12
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/tools/retile_e2e.py +2 -1
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/tools/tile.py +18 -1
- topo_map_processor-0.1.12/topo_map_processor/tools/utils.py +31 -0
- topo_map_processor-0.1.10/topo_map_processor/bash_scripts/generate_lists.sh +0 -33
- topo_map_processor-0.1.10/topo_map_processor/bash_scripts/upload_to_release.sh +0 -148
- topo_map_processor-0.1.10/topo_map_processor/tools/__init__.py +0 -0
- topo_map_processor-0.1.10/topo_map_processor/tools/download_mosaic.py +0 -375
- topo_map_processor-0.1.10/topo_map_processor/tools/execute_bash.py +0 -59
- topo_map_processor-0.1.10/topo_map_processor/tools/partition.py +0 -604
- topo_map_processor-0.1.10/topo_map_processor/tools/partition_basic.py +0 -514
- topo_map_processor-0.1.10/topo_map_processor/tools/tile_sources.py +0 -470
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/.gitignore +0 -0
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/LICENSE +0 -0
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/__init__.py +0 -0
- {topo_map_processor-0.1.10/topo_map_processor/bash_scripts → topo_map_processor-0.1.12/topo_map_processor/tools}/__init__.py +0 -0
- {topo_map_processor-0.1.10 → topo_map_processor-0.1.12}/topo_map_processor/tools/collect_bounds.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: topo_map_processor
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12
|
|
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
|
|
@@ -32,7 +32,7 @@ License: This is free and unencumbered software released into the public domain.
|
|
|
32
32
|
License-File: LICENSE
|
|
33
33
|
Requires-Python: >=3.12
|
|
34
34
|
Requires-Dist: mercantile>=1.2.1
|
|
35
|
-
Requires-Dist: pmtiles
|
|
35
|
+
Requires-Dist: pmtiles-mosaic>=0.1.0
|
|
36
36
|
Requires-Dist: requests>=2.32.4
|
|
37
37
|
Requires-Dist: shapely>=2.1.1
|
|
38
38
|
Provides-Extra: easyocr
|
|
@@ -184,7 +184,13 @@ The `get_intersection_point` method is the most critical part to customize for a
|
|
|
184
184
|
3. Identifying the point closest to the expected corner position, while also matching an expected angle and distance from an anchor point.
|
|
185
185
|
|
|
186
186
|

|
|
187
|
-
- **`get_4way_intersection_point`**: This is a more robust version for crosshair-style corners. It
|
|
187
|
+
- **`get_4way_intersection_point`**: This is a more robust version for crosshair-style corners. It works by:
|
|
188
|
+
1. Isolating lines based on their color.
|
|
189
|
+
2. Optionally removing any text that might interfere with line detection.
|
|
190
|
+
3. Ignoring the edges of the corner image patch to avoid spurious intersections with the border.
|
|
191
|
+
4. Detecting all horizontal and vertical lines and finding their intersection points.
|
|
192
|
+
5. Validating each intersection by checking for the presence of lines extending in all four directions (up, down, left, right) from the intersection point. This ensures it's a true 4-way "crosshair" intersection.
|
|
193
|
+
6. It is designed to be very specific and will fail if it doesn't find exactly one 4-way intersection.
|
|
188
194
|
|
|
189
195
|

|
|
190
196
|
- **`get_biggest_contour_corner`**: This strategy is designed for corners that are marked by a solid shape or a filled area (e.g., a colored square or circle). It works by:
|
|
@@ -208,15 +214,6 @@ Similar to corner detection, the `locate_grid_lines` method can be implemented u
|
|
|
208
214
|
|
|
209
215
|
- **`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.
|
|
210
216
|
|
|
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
|
-
|
|
220
217
|
### Command-Line Tools
|
|
221
218
|
|
|
222
219
|
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.
|
|
@@ -233,39 +230,6 @@ collect-bounds --bounds-dir <directory> --output-file <file> [--preexisting-file
|
|
|
233
230
|
- `--output-file`: Output GeoJSON file path. (Required)
|
|
234
231
|
- `--preexisting-file`: Pre existing GeoJSON file path. (Optional)
|
|
235
232
|
|
|
236
|
-
#### `download-mosaic`
|
|
237
|
-
|
|
238
|
-
Downloads a PMTiles mosaic and converts it to a single MBTiles or PMTiles file. A mosaic is a JSON file that lists multiple PMTiles files.
|
|
239
|
-
|
|
240
|
-
```bash
|
|
241
|
-
download-mosaic --mosaic-url <url> [--output-file <file>] [--archive-type <type>] [--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/PMTiles file name. The format is inferred from the extension (`.mbtiles` or `.pmtiles`). If not specified, it is derived from the mosaic URL. (Optional)
|
|
246
|
-
- `--archive-type`: Type of archive to create (`mbtiles` or `pmtiles`). Required if `--output-file` is not provided or its extension is not recognized.
|
|
247
|
-
- `--request-timeout-secs`, `-t`: Timeout for HTTP requests in seconds (default: 60).
|
|
248
|
-
- `--num-http-retries`, `-r`: Number of retries for HTTP requests (default: 3).
|
|
249
|
-
|
|
250
|
-
#### `partition`
|
|
251
|
-
|
|
252
|
-
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.
|
|
253
|
-
|
|
254
|
-
```bash
|
|
255
|
-
partition --from-source <source> [--from-source <source> ...] --to-pmtiles <file> [--size-limit <limit>]
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
- `--from-source`: Path to a source file or directory. Can be repeated. Supported sources:
|
|
259
|
-
- `.mbtiles` file: e.g., `path/to/file.mbtiles`
|
|
260
|
-
- `.pmtiles` file (supports glob patterns): e.g., `path/to/*.pmtiles`
|
|
261
|
-
- Directory containing tiles: e.g., `path/to/tiles_dir`
|
|
262
|
-
- `--to-pmtiles`: Output PMTiles file. The prefix for partitioned files will be derived from this argument.
|
|
263
|
-
- `--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:
|
|
264
|
-
- `github_release`: 2GB limit
|
|
265
|
-
- `github_file`: 100MB limit
|
|
266
|
-
- `cloudflare_object`: 512MB limit
|
|
267
|
-
The overhead (delta) is scaled proportionally based on the `github_release` preset (2GB with 5MB overhead). Defaults to `github_release`.
|
|
268
|
-
|
|
269
233
|
#### `retile`
|
|
270
234
|
|
|
271
235
|
Retiles a specific list of sheets (GeoTIFFs) and updates the corresponding tiles in an existing tile set. It can determine which other sheets are affected and need to be pulled in to correctly retile the area.
|
|
@@ -135,7 +135,13 @@ The `get_intersection_point` method is the most critical part to customize for a
|
|
|
135
135
|
3. Identifying the point closest to the expected corner position, while also matching an expected angle and distance from an anchor point.
|
|
136
136
|
|
|
137
137
|

|
|
138
|
-
- **`get_4way_intersection_point`**: This is a more robust version for crosshair-style corners. It
|
|
138
|
+
- **`get_4way_intersection_point`**: This is a more robust version for crosshair-style corners. It works by:
|
|
139
|
+
1. Isolating lines based on their color.
|
|
140
|
+
2. Optionally removing any text that might interfere with line detection.
|
|
141
|
+
3. Ignoring the edges of the corner image patch to avoid spurious intersections with the border.
|
|
142
|
+
4. Detecting all horizontal and vertical lines and finding their intersection points.
|
|
143
|
+
5. Validating each intersection by checking for the presence of lines extending in all four directions (up, down, left, right) from the intersection point. This ensures it's a true 4-way "crosshair" intersection.
|
|
144
|
+
6. It is designed to be very specific and will fail if it doesn't find exactly one 4-way intersection.
|
|
139
145
|
|
|
140
146
|

|
|
141
147
|
- **`get_biggest_contour_corner`**: This strategy is designed for corners that are marked by a solid shape or a filled area (e.g., a colored square or circle). It works by:
|
|
@@ -159,15 +165,6 @@ Similar to corner detection, the `locate_grid_lines` method can be implemented u
|
|
|
159
165
|
|
|
160
166
|
- **`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
167
|
|
|
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
|
-
|
|
171
168
|
### Command-Line Tools
|
|
172
169
|
|
|
173
170
|
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.
|
|
@@ -184,39 +181,6 @@ collect-bounds --bounds-dir <directory> --output-file <file> [--preexisting-file
|
|
|
184
181
|
- `--output-file`: Output GeoJSON file path. (Required)
|
|
185
182
|
- `--preexisting-file`: Pre existing GeoJSON file path. (Optional)
|
|
186
183
|
|
|
187
|
-
#### `download-mosaic`
|
|
188
|
-
|
|
189
|
-
Downloads a PMTiles mosaic and converts it to a single MBTiles or PMTiles file. A mosaic is a JSON file that lists multiple PMTiles files.
|
|
190
|
-
|
|
191
|
-
```bash
|
|
192
|
-
download-mosaic --mosaic-url <url> [--output-file <file>] [--archive-type <type>] [--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/PMTiles file name. The format is inferred from the extension (`.mbtiles` or `.pmtiles`). If not specified, it is derived from the mosaic URL. (Optional)
|
|
197
|
-
- `--archive-type`: Type of archive to create (`mbtiles` or `pmtiles`). Required if `--output-file` is not provided or its extension is not recognized.
|
|
198
|
-
- `--request-timeout-secs`, `-t`: Timeout for HTTP requests in seconds (default: 60).
|
|
199
|
-
- `--num-http-retries`, `-r`: Number of retries for HTTP requests (default: 3).
|
|
200
|
-
|
|
201
|
-
#### `partition`
|
|
202
|
-
|
|
203
|
-
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.
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
partition --from-source <source> [--from-source <source> ...] --to-pmtiles <file> [--size-limit <limit>]
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
- `--from-source`: Path to a source file or directory. Can be repeated. Supported sources:
|
|
210
|
-
- `.mbtiles` file: e.g., `path/to/file.mbtiles`
|
|
211
|
-
- `.pmtiles` file (supports glob patterns): e.g., `path/to/*.pmtiles`
|
|
212
|
-
- Directory containing tiles: e.g., `path/to/tiles_dir`
|
|
213
|
-
- `--to-pmtiles`: Output PMTiles file. The prefix for partitioned files will be derived from this argument.
|
|
214
|
-
- `--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:
|
|
215
|
-
- `github_release`: 2GB limit
|
|
216
|
-
- `github_file`: 100MB limit
|
|
217
|
-
- `cloudflare_object`: 512MB limit
|
|
218
|
-
The overhead (delta) is scaled proportionally based on the `github_release` preset (2GB with 5MB overhead). Defaults to `github_release`.
|
|
219
|
-
|
|
220
184
|
#### `retile`
|
|
221
185
|
|
|
222
186
|
Retiles a specific list of sheets (GeoTIFFs) and updates the corresponding tiles in an existing tile set. It can determine which other sheets are affected and need to be pulled in to correctly retile the area.
|
|
@@ -9,7 +9,7 @@ authors = [
|
|
|
9
9
|
]
|
|
10
10
|
dependencies = [
|
|
11
11
|
"mercantile>=1.2.1",
|
|
12
|
-
"pmtiles
|
|
12
|
+
"pmtiles-mosaic>=0.1.0",
|
|
13
13
|
"requests>=2.32.4",
|
|
14
14
|
"shapely>=2.1.1",
|
|
15
15
|
]
|
|
@@ -38,16 +38,10 @@ repository = "https://github.com/ramSeraph/topo_map_processor.git"
|
|
|
38
38
|
|
|
39
39
|
[project.scripts]
|
|
40
40
|
collect-bounds = "topo_map_processor.tools.collect_bounds:cli"
|
|
41
|
-
download-mosaic = "topo_map_processor.tools.download_mosaic:cli"
|
|
42
|
-
partition = "topo_map_processor.tools.partition:cli"
|
|
43
|
-
partition-basic = "topo_map_processor.tools.partition_basic:cli"
|
|
44
41
|
retile = "topo_map_processor.tools.retile:cli"
|
|
45
42
|
tile = "topo_map_processor.tools.tile:cli"
|
|
46
|
-
generate-lists = "topo_map_processor.tools.execute_bash:generate_lists"
|
|
47
|
-
upload-to-release = "topo_map_processor.tools.execute_bash:upload_to_release"
|
|
48
43
|
retile-e2e = "topo_map_processor.tools.retile_e2e:cli"
|
|
49
44
|
|
|
50
|
-
|
|
51
45
|
[build-system]
|
|
52
46
|
requires = [
|
|
53
47
|
"hatchling",
|
|
@@ -64,12 +58,10 @@ version-file = "topo_map_processor/_version.py"
|
|
|
64
58
|
[tool.hatch.build.targets.sdist]
|
|
65
59
|
include = [
|
|
66
60
|
"topo_map_processor",
|
|
67
|
-
"topo_map_processor/bash_scripts/**",
|
|
68
61
|
]
|
|
69
62
|
|
|
70
63
|
[tool.hatch.build.targets.wheel]
|
|
71
64
|
include = [
|
|
72
65
|
"topo_map_processor",
|
|
73
|
-
"topo_map_processor/bash_scripts/**",
|
|
74
66
|
]
|
|
75
67
|
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
5
12
|
|
|
6
13
|
TYPE_CHECKING = False
|
|
7
14
|
if TYPE_CHECKING:
|
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
|
9
16
|
from typing import Union
|
|
10
17
|
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
12
20
|
else:
|
|
13
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
14
23
|
|
|
15
24
|
version: str
|
|
16
25
|
__version__: str
|
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
|
18
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
19
30
|
|
|
20
|
-
__version__ = version = '0.1.
|
|
21
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.12'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 12)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
@@ -1074,12 +1074,16 @@ class TopoMapProcessor:
|
|
|
1074
1074
|
|
|
1075
1075
|
return ip
|
|
1076
1076
|
|
|
1077
|
-
def get_4way_intersection_point(self, img, line_color,
|
|
1077
|
+
def get_4way_intersection_point(self, img, line_color, remove_text,
|
|
1078
1078
|
find_line_scale, find_line_iter,
|
|
1079
|
-
cwidth, ext_thresh
|
|
1079
|
+
cwidth, ext_thresh, direction,
|
|
1080
|
+
remove_corner_edges_ratio):
|
|
1080
1081
|
img_mask = self.get_color_mask(img, line_color)
|
|
1081
1082
|
|
|
1082
|
-
|
|
1083
|
+
if remove_text:
|
|
1084
|
+
self.remove_text(img_mask)
|
|
1085
|
+
|
|
1086
|
+
self.remove_corner_edges(img_mask, direction, remove_corner_edges_ratio)
|
|
1083
1087
|
|
|
1084
1088
|
h, w = img_mask.shape[:2]
|
|
1085
1089
|
self.show_image(img_mask)
|
|
@@ -1106,7 +1110,8 @@ class TopoMapProcessor:
|
|
|
1106
1110
|
if len(four_corner_ips) > 1:
|
|
1107
1111
|
continue
|
|
1108
1112
|
|
|
1109
|
-
|
|
1113
|
+
self.show_points(four_corner_ips, img_mask, [0, 255, 0])
|
|
1114
|
+
|
|
1110
1115
|
if len(four_corner_ips) > 1:
|
|
1111
1116
|
raise Exception(f'multiple intersection points found - {len(four_corner_ips)}')
|
|
1112
1117
|
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
# /// script
|
|
2
|
-
# requires-python = ">=3.12"
|
|
3
|
-
# dependencies = [
|
|
4
|
-
# "mercantile",
|
|
5
|
-
# "pmtiles",
|
|
6
|
-
# "shapely",
|
|
7
|
-
# ]
|
|
8
|
-
# ///
|
|
9
1
|
|
|
10
2
|
import os
|
|
11
3
|
import re
|
|
12
4
|
import sys
|
|
13
|
-
import glob
|
|
14
5
|
import json
|
|
15
6
|
import argparse
|
|
16
7
|
|
|
@@ -33,7 +24,9 @@ from osgeo_utils.gdal2tiles import (
|
|
|
33
24
|
DividedCache,
|
|
34
25
|
)
|
|
35
26
|
|
|
36
|
-
from .tile_sources import create_source_from_paths, MissingTileError
|
|
27
|
+
from pmtiles_mosaic.tile_sources import create_source_from_paths, MissingTileError
|
|
28
|
+
|
|
29
|
+
from .utils import relax_open_file_limit
|
|
37
30
|
|
|
38
31
|
def run_external(cmd):
|
|
39
32
|
print(f'running cmd - {cmd}')
|
|
@@ -309,8 +302,8 @@ class Tiler:
|
|
|
309
302
|
prev_affected_tiles = curr_affected_tiles
|
|
310
303
|
|
|
311
304
|
metadata = self.orig_tile_source.get_metadata()
|
|
312
|
-
metadata['minzoom'] =
|
|
313
|
-
metadata['maxzoom'] =
|
|
305
|
+
metadata['minzoom'] = min_zoom
|
|
306
|
+
metadata['maxzoom'] = max_zoom
|
|
314
307
|
self.disk_handler.save_metadata(metadata)
|
|
315
308
|
print('All Done!!!')
|
|
316
309
|
|
|
@@ -454,6 +447,8 @@ def retile_main(args):
|
|
|
454
447
|
if tile_extension == 'jpg':
|
|
455
448
|
tile_extension = 'jpeg'
|
|
456
449
|
|
|
450
|
+
relax_open_file_limit()
|
|
451
|
+
|
|
457
452
|
os.environ['GDAL_CACHEMAX'] = '2048'
|
|
458
453
|
os.environ['GDAL_MAX_DATASET_POOL_SIZE'] = '5000'
|
|
459
454
|
os.environ['GDAL_DISABLE_READDIR_ON_OPEN'] = 'TRUE'
|
|
@@ -9,9 +9,12 @@ import subprocess
|
|
|
9
9
|
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from multiprocessing import set_start_method, cpu_count
|
|
12
|
+
from pprint import pprint
|
|
12
13
|
|
|
13
14
|
from osgeo_utils.gdal2tiles import submain as gdal2tiles_main
|
|
14
15
|
|
|
16
|
+
from .utils import relax_open_file_limit
|
|
17
|
+
|
|
15
18
|
SUPPORTED_FORMATS = ['webp', 'jpeg', 'png']
|
|
16
19
|
|
|
17
20
|
def run_external(cmd):
|
|
@@ -56,6 +59,14 @@ def get_tiler_cmd_params(tile_extension, tile_quality):
|
|
|
56
59
|
|
|
57
60
|
raise ValueError(f'Unsupported tile extension: {tile_extension}, {SUPPORTED_FORMATS=}')
|
|
58
61
|
|
|
62
|
+
def get_format(tile_extension):
|
|
63
|
+
if tile_extension == 'webp':
|
|
64
|
+
return 'webp'
|
|
65
|
+
if tile_extension == 'jpeg':
|
|
66
|
+
return 'jpeg'
|
|
67
|
+
if tile_extension == 'png':
|
|
68
|
+
return 'png'
|
|
69
|
+
raise ValueError(f'Unsupported tile extension: {tile_extension}, {SUPPORTED_FORMATS=}')
|
|
59
70
|
|
|
60
71
|
|
|
61
72
|
def cli():
|
|
@@ -86,6 +97,7 @@ def cli():
|
|
|
86
97
|
else:
|
|
87
98
|
attribution_text = args.attribution
|
|
88
99
|
|
|
100
|
+
relax_open_file_limit()
|
|
89
101
|
|
|
90
102
|
tiles_dir = Path(args.tiles_dir)
|
|
91
103
|
tiles_dir.mkdir(parents=True, exist_ok=True)
|
|
@@ -131,10 +143,12 @@ def cli():
|
|
|
131
143
|
|
|
132
144
|
metadata_file = tiles_dir / 'tiles.json'
|
|
133
145
|
|
|
146
|
+
fmt = get_format(args.tile_extension)
|
|
147
|
+
|
|
134
148
|
# it is not really a proper tilejson spec.. it is the basic things needed to populate a pmtiles metadata
|
|
135
149
|
metadata = {
|
|
136
150
|
'type': 'baselayer',
|
|
137
|
-
'format':
|
|
151
|
+
'format': fmt,
|
|
138
152
|
'attribution': attribution_text,
|
|
139
153
|
'description': args.description,
|
|
140
154
|
'name': args.name,
|
|
@@ -142,6 +156,9 @@ def cli():
|
|
|
142
156
|
'maxzoom': args.max_zoom,
|
|
143
157
|
'minzoom': args.min_zoom,
|
|
144
158
|
}
|
|
159
|
+
|
|
160
|
+
print(f'writing metadata to {metadata_file}')
|
|
161
|
+
pprint(metadata)
|
|
145
162
|
metadata_file.write_text(json.dumps(metadata, indent=2))
|
|
146
163
|
|
|
147
164
|
print('All Done!!')
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
import resource
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def relax_open_file_limit():
|
|
6
|
+
|
|
7
|
+
# Get the current soft and hard limits for open files
|
|
8
|
+
current_soft, current_hard = resource.getrlimit(resource.RLIMIT_NOFILE)
|
|
9
|
+
print(f"Current open file limits: Soft={current_soft}, Hard={current_hard}")
|
|
10
|
+
|
|
11
|
+
# Set new soft and hard limits for open files
|
|
12
|
+
new_soft = resource.RLIM_INFINITY # Set to unlimited
|
|
13
|
+
new_hard = resource.RLIM_INFINITY # Set to unlimited
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft, new_hard))
|
|
17
|
+
print(f"New open file limits set: Soft={new_soft}, Hard={new_hard}")
|
|
18
|
+
except Exception as e:
|
|
19
|
+
print(f"Error setting resource limit to unlimited: {e}")
|
|
20
|
+
print('Increasing soft limit to match the hard limit instead')
|
|
21
|
+
new_soft = current_hard
|
|
22
|
+
new_hard = current_hard
|
|
23
|
+
try:
|
|
24
|
+
resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft, new_hard))
|
|
25
|
+
print(f"New open file limits set: Soft={new_soft}, Hard={new_hard}")
|
|
26
|
+
except Exception as e:
|
|
27
|
+
print(f"Error setting soft resource limit to match hard limit: {e}")
|
|
28
|
+
|
|
29
|
+
# Verify the new limits
|
|
30
|
+
updated_soft, updated_hard = resource.getrlimit(resource.RLIMIT_NOFILE)
|
|
31
|
+
print(f"Verified open file limits: Soft={updated_soft}, Hard={updated_hard}")
|
|
@@ -1,33 +0,0 @@
|
|
|
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
|
-
|
|
@@ -1,148 +0,0 @@
|
|
|
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
|
-
# Determine available releases and their current asset counts
|
|
85
|
-
AVAILABLE_RELEASES=()
|
|
86
|
-
AVAILABLE_ASSET_COUNTS=()
|
|
87
|
-
for release in $RELEASES_TO_PROCESS; do
|
|
88
|
-
count=$(gh release view "$release" --json assets -q '.assets | length' 2>/dev/null || echo "0")
|
|
89
|
-
|
|
90
|
-
MAX_ASSETS=998
|
|
91
|
-
if [ "$release" == "$TAG" ]; then
|
|
92
|
-
MAX_ASSETS=988
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
if [ "$count" -lt "$MAX_ASSETS" ]; then
|
|
96
|
-
AVAILABLE_RELEASES+=("$release")
|
|
97
|
-
AVAILABLE_ASSET_COUNTS+=("$count")
|
|
98
|
-
fi
|
|
99
|
-
done
|
|
100
|
-
|
|
101
|
-
echo "Starting upload process from folder '$FOLDER'..."
|
|
102
|
-
|
|
103
|
-
# Find all files in the folder that are not yet in any release and loop through them.
|
|
104
|
-
find "${FOLDER}" -type f | grep "^.*\.${EXT}$" | while read -r FILE_PATH; do
|
|
105
|
-
FILENAME=$(basename "$FILE_PATH")
|
|
106
|
-
echo "Processing file: $FILENAME"
|
|
107
|
-
|
|
108
|
-
set +o pipefail
|
|
109
|
-
RELEASE_FOR_ASSET=$(echo -n "$EXISTING_ASSETS_WITH_RELEASES" | grep "^${FILENAME} " | head -n 1 | awk '{print $2}')
|
|
110
|
-
set -o pipefail
|
|
111
|
-
|
|
112
|
-
if [ -n "$RELEASE_FOR_ASSET" ]; then
|
|
113
|
-
# Asset exists
|
|
114
|
-
if [ "$ALLOW_OVERWRITE" -eq 1 ]; then
|
|
115
|
-
echo " -> Overwriting '$FILENAME' in release '$RELEASE_FOR_ASSET'..."
|
|
116
|
-
gh release upload "$RELEASE_FOR_ASSET" "$FILE_PATH" --clobber
|
|
117
|
-
else
|
|
118
|
-
echo " -> Skipping '$FILENAME', it already exists in release '$RELEASE_FOR_ASSET'."
|
|
119
|
-
fi
|
|
120
|
-
continue
|
|
121
|
-
fi
|
|
122
|
-
|
|
123
|
-
# Find a release to upload to for a new asset
|
|
124
|
-
if [ ${#AVAILABLE_RELEASES[@]} -eq 0 ]; then
|
|
125
|
-
echo "Error: All existing releases are full. No space to upload '$FILENAME'." >&2
|
|
126
|
-
exit 1
|
|
127
|
-
fi
|
|
128
|
-
|
|
129
|
-
UPLOAD_TARGET=${AVAILABLE_RELEASES[0]}
|
|
130
|
-
|
|
131
|
-
echo " -> Uploading '$FILENAME' to '$UPLOAD_TARGET'..."
|
|
132
|
-
gh release upload "$UPLOAD_TARGET" "$FILE_PATH"
|
|
133
|
-
|
|
134
|
-
# Update asset count and remove release from available list if full
|
|
135
|
-
AVAILABLE_ASSET_COUNTS[0]=$((${AVAILABLE_ASSET_COUNTS[0]} + 1))
|
|
136
|
-
|
|
137
|
-
MAX_ASSETS=998
|
|
138
|
-
if [ "$UPLOAD_TARGET" == "$TAG" ]; then
|
|
139
|
-
MAX_ASSETS=988
|
|
140
|
-
fi
|
|
141
|
-
|
|
142
|
-
if [ "${AVAILABLE_ASSET_COUNTS[0]}" -ge "$MAX_ASSETS" ]; then
|
|
143
|
-
AVAILABLE_RELEASES=("${AVAILABLE_RELEASES[@]:1}")
|
|
144
|
-
AVAILABLE_ASSET_COUNTS=("${AVAILABLE_ASSET_COUNTS[@]:1}")
|
|
145
|
-
fi
|
|
146
|
-
done
|
|
147
|
-
|
|
148
|
-
echo "Upload process complete."
|
|
File without changes
|