topo_map_processor 0.1.5__tar.gz → 0.1.6__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.5 → topo_map_processor-0.1.6}/PKG-INFO +11 -9
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/README.md +10 -8
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/topo_map_processor/__init__.py +10 -9
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/topo_map_processor/_version.py +2 -2
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/.github/workflows/publish.yml +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/.gitignore +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/.python-version +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/LICENSE +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/pyproject.toml +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/samples/corner1.png +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/samples/corner2.png +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/samples/corner3.png +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/topo_map_processor/tools/__init__.py +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/topo_map_processor/tools/collect_bounds.py +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/topo_map_processor/tools/partition.py +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/topo_map_processor/tools/retile.py +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/topo_map_processor/tools/tile.py +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/topo_map_processor/tools/tile_sources.py +0 -0
- {topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/uv.lock +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.6
|
|
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
|
|
@@ -51,7 +51,7 @@ A Python utility for processing topographic maps.
|
|
|
51
51
|
|
|
52
52
|
## Description
|
|
53
53
|
|
|
54
|
-
This project provides a collection of command-line tools and a Python library to process,
|
|
54
|
+
This project provides a collection of command-line tools and a Python library to process, georeference, and export topographic map data in raster form, specifically for creating web-mappable tiles from GeoTIFF files. The tools allow you to create tiles, partition large tile sets, and update existing tile sets efficiently.
|
|
55
55
|
|
|
56
56
|
## Installation
|
|
57
57
|
|
|
@@ -106,7 +106,7 @@ The main steps, executed by the `processor.process()` method, are as follows:
|
|
|
106
106
|
1. **Image Preparation (`rotate`):** To minimize computation, the processor first creates a smaller, shrunken version of the full-resolution map. On this small image, it locates the main contour of the map's frame (the border area). By calculating the angle of this contour's minimum bounding box, it determines the skew of the map. The full-resolution image is then rotated using this angle to make the frame perfectly horizontal, correcting for any tilt introduced during scanning.
|
|
107
107
|
2. **Corner Detection (`get_corners`):** Once the image is straightened, the processor uses the same map frame contour to identify the four corner regions. By narrowing the search to these smaller areas, it can apply more precise logic to find the exact pixel coordinates of the map's neatline corners. This is a critical step that often requires custom implementation in a subclass (`get_intersection_point`) to handle the specific visual features of the map's corners (e.g., crosses, specific colors, patterns).
|
|
108
108
|
3. **Grid Line Removal (`remove_grid_lines`):** If configured, the processor can detect and remove grid lines (graticules) from the map image. This is achieved by implementing the `locate_grid_lines` method. The removal helps create a cleaner final map by inpainting the areas where the lines were.
|
|
109
|
-
4. **Georeferencing (`georeference`):** Using the detected corner coordinates and the corresponding real-world geographic coordinates (provided via the `
|
|
109
|
+
4. **Georeferencing (`georeference`):** Using the detected corner coordinates and the corresponding real-world geographic coordinates (provided via the `index_box`), the tool creates Ground Control Points (GCPs). It then uses `gdal_translate` to create an initial georeferenced GeoTIFF.
|
|
110
110
|
5. **Warping and Cutting (`warp`):** The georeferenced image is then warped into the standard `EPSG:3857` projection used by most web maps. During this step, it's also precisely cropped to the map's boundary (neatline) using a cutline derived from the corner points. The output is a clean, map-only image, correctly projected.
|
|
111
111
|
6. **Exporting (`export`):** The final warped image is converted into a Cloud-Optimized GeoTIFF (COG), which is highly efficient for web-based tiling. A corresponding bounds file (`.geojsonl`) is also created, defining the geographic extent of the map sheet.
|
|
112
112
|
|
|
@@ -116,15 +116,15 @@ The output of this library workflow—a directory of COG `.tif` files and a dire
|
|
|
116
116
|
|
|
117
117
|
The `TopoMapProcessor` class provides a framework for processing individual map sheets. To use it, you need to create a subclass and implement the required methods.
|
|
118
118
|
|
|
119
|
-
Here's an example of how to use the `TopoMapProcessor` class
|
|
119
|
+
Here's an example of how to use the `TopoMapProcessor` class.
|
|
120
120
|
|
|
121
121
|
```python
|
|
122
122
|
from topo_map_processor import TopoMapProcessor, LineRemovalParams
|
|
123
123
|
|
|
124
124
|
class SampleProcessor(TopoMapProcessor):
|
|
125
125
|
|
|
126
|
-
def __init__(self, filepath, extra,
|
|
127
|
-
super().__init__(filepath, extra,
|
|
126
|
+
def __init__(self, filepath, extra, index_box, index_props):
|
|
127
|
+
super().__init__(filepath, extra, index_box, index_props)
|
|
128
128
|
# ... (additional initialization)
|
|
129
129
|
|
|
130
130
|
def get_inter_dir(self):
|
|
@@ -155,14 +155,16 @@ def process_files():
|
|
|
155
155
|
# ... (load image files and special cases)
|
|
156
156
|
for filepath in image_files:
|
|
157
157
|
extra = special_cases.get(filepath.name, {})
|
|
158
|
-
|
|
159
|
-
processor = SampleProcessor(filepath, extra,
|
|
158
|
+
index_box, index_props = get_index_data(filepath.name) # This should return the corresponding index box and properties for the file
|
|
159
|
+
processor = SampleProcessor(filepath, extra, index_box, index_props)
|
|
160
160
|
processor.process()
|
|
161
161
|
```
|
|
162
162
|
|
|
163
163
|
The library is configurable and most parameters can be overridden at a per sheet level using the `extra` dictionary.
|
|
164
164
|
|
|
165
|
-
The `
|
|
165
|
+
The `index_box` is used to provide the coordinates of the corners of the sheet. This information is used to create the bounds file and georeference the sheet. This is expected to be a list of coordinates in counter clockwise order starting at the top left corner of the map sheet.
|
|
166
|
+
|
|
167
|
+
The optional `index_properties` dictionary can contain additional metadata about the sheet, such as its name, description, and other properties which end up in the generated bounds files.
|
|
166
168
|
|
|
167
169
|
The end result is a Cloud optimized GeoTIFF file, a bounds file in GeoJSON format from which the tiles can be generated, using the `tile` command-line tool, and a set of tiles in the specified directory.
|
|
168
170
|
|
|
@@ -5,7 +5,7 @@ A Python utility for processing topographic maps.
|
|
|
5
5
|
|
|
6
6
|
## Description
|
|
7
7
|
|
|
8
|
-
This project provides a collection of command-line tools and a Python library to process,
|
|
8
|
+
This project provides a collection of command-line tools and a Python library to process, georeference, and export topographic map data in raster form, specifically for creating web-mappable tiles from GeoTIFF files. The tools allow you to create tiles, partition large tile sets, and update existing tile sets efficiently.
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
@@ -60,7 +60,7 @@ The main steps, executed by the `processor.process()` method, are as follows:
|
|
|
60
60
|
1. **Image Preparation (`rotate`):** To minimize computation, the processor first creates a smaller, shrunken version of the full-resolution map. On this small image, it locates the main contour of the map's frame (the border area). By calculating the angle of this contour's minimum bounding box, it determines the skew of the map. The full-resolution image is then rotated using this angle to make the frame perfectly horizontal, correcting for any tilt introduced during scanning.
|
|
61
61
|
2. **Corner Detection (`get_corners`):** Once the image is straightened, the processor uses the same map frame contour to identify the four corner regions. By narrowing the search to these smaller areas, it can apply more precise logic to find the exact pixel coordinates of the map's neatline corners. This is a critical step that often requires custom implementation in a subclass (`get_intersection_point`) to handle the specific visual features of the map's corners (e.g., crosses, specific colors, patterns).
|
|
62
62
|
3. **Grid Line Removal (`remove_grid_lines`):** If configured, the processor can detect and remove grid lines (graticules) from the map image. This is achieved by implementing the `locate_grid_lines` method. The removal helps create a cleaner final map by inpainting the areas where the lines were.
|
|
63
|
-
4. **Georeferencing (`georeference`):** Using the detected corner coordinates and the corresponding real-world geographic coordinates (provided via the `
|
|
63
|
+
4. **Georeferencing (`georeference`):** Using the detected corner coordinates and the corresponding real-world geographic coordinates (provided via the `index_box`), the tool creates Ground Control Points (GCPs). It then uses `gdal_translate` to create an initial georeferenced GeoTIFF.
|
|
64
64
|
5. **Warping and Cutting (`warp`):** The georeferenced image is then warped into the standard `EPSG:3857` projection used by most web maps. During this step, it's also precisely cropped to the map's boundary (neatline) using a cutline derived from the corner points. The output is a clean, map-only image, correctly projected.
|
|
65
65
|
6. **Exporting (`export`):** The final warped image is converted into a Cloud-Optimized GeoTIFF (COG), which is highly efficient for web-based tiling. A corresponding bounds file (`.geojsonl`) is also created, defining the geographic extent of the map sheet.
|
|
66
66
|
|
|
@@ -70,15 +70,15 @@ The output of this library workflow—a directory of COG `.tif` files and a dire
|
|
|
70
70
|
|
|
71
71
|
The `TopoMapProcessor` class provides a framework for processing individual map sheets. To use it, you need to create a subclass and implement the required methods.
|
|
72
72
|
|
|
73
|
-
Here's an example of how to use the `TopoMapProcessor` class
|
|
73
|
+
Here's an example of how to use the `TopoMapProcessor` class.
|
|
74
74
|
|
|
75
75
|
```python
|
|
76
76
|
from topo_map_processor import TopoMapProcessor, LineRemovalParams
|
|
77
77
|
|
|
78
78
|
class SampleProcessor(TopoMapProcessor):
|
|
79
79
|
|
|
80
|
-
def __init__(self, filepath, extra,
|
|
81
|
-
super().__init__(filepath, extra,
|
|
80
|
+
def __init__(self, filepath, extra, index_box, index_props):
|
|
81
|
+
super().__init__(filepath, extra, index_box, index_props)
|
|
82
82
|
# ... (additional initialization)
|
|
83
83
|
|
|
84
84
|
def get_inter_dir(self):
|
|
@@ -109,14 +109,16 @@ def process_files():
|
|
|
109
109
|
# ... (load image files and special cases)
|
|
110
110
|
for filepath in image_files:
|
|
111
111
|
extra = special_cases.get(filepath.name, {})
|
|
112
|
-
|
|
113
|
-
processor = SampleProcessor(filepath, extra,
|
|
112
|
+
index_box, index_props = get_index_data(filepath.name) # This should return the corresponding index box and properties for the file
|
|
113
|
+
processor = SampleProcessor(filepath, extra, index_box, index_props)
|
|
114
114
|
processor.process()
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
The library is configurable and most parameters can be overridden at a per sheet level using the `extra` dictionary.
|
|
118
118
|
|
|
119
|
-
The `
|
|
119
|
+
The `index_box` is used to provide the coordinates of the corners of the sheet. This information is used to create the bounds file and georeference the sheet. This is expected to be a list of coordinates in counter clockwise order starting at the top left corner of the map sheet.
|
|
120
|
+
|
|
121
|
+
The optional `index_properties` dictionary can contain additional metadata about the sheet, such as its name, description, and other properties which end up in the generated bounds files.
|
|
120
122
|
|
|
121
123
|
The end result is a Cloud optimized GeoTIFF file, a bounds file in GeoJSON format from which the tiles can be generated, using the `tile` command-line tool, and a set of tiles in the specified directory.
|
|
122
124
|
|
|
@@ -70,9 +70,10 @@ class GCPBasedTransformer:
|
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
class TopoMapProcessor:
|
|
73
|
-
def __init__(self, filepath, extra,
|
|
73
|
+
def __init__(self, filepath, extra, index_box, index_properties={}):
|
|
74
74
|
self.filepath = filepath
|
|
75
|
-
self.
|
|
75
|
+
self.index_box = index_box
|
|
76
|
+
self.index_properties = index_properties
|
|
76
77
|
|
|
77
78
|
self.SHOW_IMG = os.getenv('SHOW_IMG', '0') == '1'
|
|
78
79
|
self.INSPECT = os.getenv('INSPECT', '0') == '1'
|
|
@@ -141,11 +142,8 @@ class TopoMapProcessor:
|
|
|
141
142
|
ext = self.filepath.suffix
|
|
142
143
|
return self.filepath.name.replace(ext, '')
|
|
143
144
|
|
|
144
|
-
def get_sheet_ibox(self
|
|
145
|
-
|
|
146
|
-
sheet_id = self.get_id()
|
|
147
|
-
|
|
148
|
-
return self.index_map[sheet_id]
|
|
145
|
+
def get_sheet_ibox(self):
|
|
146
|
+
return self.index_box
|
|
149
147
|
|
|
150
148
|
def get_data_dir(self):
|
|
151
149
|
return Path('data')
|
|
@@ -1607,12 +1605,15 @@ class TopoMapProcessor:
|
|
|
1607
1605
|
def get_cutline_props(self):
|
|
1608
1606
|
crs_proj = self.get_crs_proj()
|
|
1609
1607
|
|
|
1610
|
-
props = {
|
|
1608
|
+
props = {}
|
|
1609
|
+
props.update(self.index_properties)
|
|
1610
|
+
|
|
1611
|
+
props.update({
|
|
1611
1612
|
'id': self.get_id(),
|
|
1612
1613
|
'crs': crs_proj,
|
|
1613
1614
|
'gcps': self.get_gcps(pre_rotated=True),
|
|
1614
1615
|
'pixel_cutline': self.get_full_pixel_cutline(pre_rotated=True),
|
|
1615
|
-
}
|
|
1616
|
+
})
|
|
1616
1617
|
return props
|
|
1617
1618
|
|
|
1618
1619
|
def create_cutline(self, ibox, file):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/topo_map_processor/tools/collect_bounds.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{topo_map_processor-0.1.5 → topo_map_processor-0.1.6}/topo_map_processor/tools/tile_sources.py
RENAMED
|
File without changes
|
|
File without changes
|