GeoPakTile 2.1.0__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.
- geopaktile-2.1.0/LICENSE.md +9 -0
- geopaktile-2.1.0/PKG-INFO +121 -0
- geopaktile-2.1.0/README.md +94 -0
- geopaktile-2.1.0/pyproject.toml +50 -0
- geopaktile-2.1.0/src/geopaktile/__init__.py +8 -0
- geopaktile-2.1.0/src/geopaktile/__main__.py +4 -0
- geopaktile-2.1.0/src/geopaktile/geopaktile.py +463 -0
- geopaktile-2.1.0/src/geopaktile/gpkg_to_cog.py +508 -0
- geopaktile-2.1.0/src/geopaktile/xml_parser.py +191 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alex Webber
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: GeoPakTile
|
|
3
|
+
Version: 2.1.0
|
|
4
|
+
Summary: Create a Geopackage XYZ Tile layer.
|
|
5
|
+
Keywords: GIS,Geopackage,Tiles,XYZ,gpkg
|
|
6
|
+
Author: apwebber
|
|
7
|
+
Author-email: apwebber <39490780+apwebber@users.noreply.github.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE.md
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Requires-Dist: typing-extensions>=4.0 ; python_full_version < '3.11'
|
|
17
|
+
Requires-Dist: morecantile>=6.2.0
|
|
18
|
+
Requires-Dist: numpy>=2.2.6
|
|
19
|
+
Requires-Dist: requests>=2.34.2
|
|
20
|
+
Requires-Dist: pillow>=12.3.0
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Project-URL: Homepage, https://github.com/apwebber/GeoPakTile
|
|
23
|
+
Project-URL: Documentation, https://github.com/apwebber/GeoPakTile
|
|
24
|
+
Project-URL: Repository, https://github.com/apwebber/GeoPakTile.git
|
|
25
|
+
Project-URL: Issues, https://github.com/apwebber/GeoPakTile/issues
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# GeoPakTile
|
|
29
|
+
|
|
30
|
+
For writing geopackage XYZ raster tile layers, with support for using arbitrary grid systems, and for converting them to Cloud Optimized GeoTIFFs (COGs).
|
|
31
|
+
|
|
32
|
+
Geopackage XYZ files can use any tile grid system, this is often defined by a server's GetCapabilities response where a TileMatrixSet defines the data co-ordinate system, the extent, the number of rows and columns in each zoom lever, and the corner co-ordinates for each zoom level. This package contains a tool for parsing the GetCapabilities XML into a [morecantile](https://github.com/developmentseed/morecantile) `TileMatrixSet`, and then for writing tiles to a new or existing geopackage.
|
|
33
|
+
|
|
34
|
+
## Examples
|
|
35
|
+
|
|
36
|
+
Write tiles to a new geopackage using web mercator (similar to mbtiles), where tiles is a list of (z, x, y, bytes). `tms` is a morecantile `TileMatrixSet` - the standard web mercator can be obtained with `morecantile.tms.get('WebMercatorQuad')`
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from geopaktile import GeoPakTile
|
|
40
|
+
|
|
41
|
+
# Here, a list of tiles are read from a local path, the bytes and co-ordinates are stored as tuples in a list:
|
|
42
|
+
# You might get these tiles from a tile server or anywhere else. Adjust accordingly.
|
|
43
|
+
|
|
44
|
+
tiles = [
|
|
45
|
+
(z, x, y, path.read_bytes()),
|
|
46
|
+
(z2, x2, y2, path2.read_bytes()),
|
|
47
|
+
(z3, x3, y3, path3.read_bytes()),
|
|
48
|
+
...
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
with GeoPakTile(test_gpkg, tms=morecantile.tms.get('WebMercatorQuad'), mode='rwc') as gpkg:
|
|
52
|
+
gpkg.add_tiles(tiles)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Open a geopackage in read only mode and see if it contains certain tiles. A TileMatrixSet isn't required for read-only mode.
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from geopaktile import GeoPakTile
|
|
59
|
+
|
|
60
|
+
with GeoPakTile(test_gpkg, mode='ro') as gpkg:
|
|
61
|
+
assert gpkg.has_tile(z, x, y)
|
|
62
|
+
result = gpkg.has_tiles([(z, x, y), (z1, x1, y1)])
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
Parse a GetCapabilties xml to provide the TileMatrixSet for writing a geopackage:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from geopaktile import parse_capabilities
|
|
70
|
+
|
|
71
|
+
tms_set = parse_capabilities(xml)
|
|
72
|
+
tms = tms_set[0] # you'll need to know which one you want, or use:
|
|
73
|
+
|
|
74
|
+
tms = get_tile_matrix_set(xml, identifier = '1km') # an identifier that you know is defined in the xml
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
Convert a geopackage tile layer to a Cloud Optimized GeoTIFF. The highest zoom level becomes the full resolution image, and the lower zoom levels become the COG's overviews:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from geopaktile import gpkg_tiles_to_cog
|
|
82
|
+
|
|
83
|
+
gpkg_tiles_to_cog("tiles.gpkg", "tiles.tif")
|
|
84
|
+
|
|
85
|
+
# Clip to a bounding box, given here in longitude/latitude
|
|
86
|
+
gpkg_tiles_to_cog(
|
|
87
|
+
"tiles.gpkg",
|
|
88
|
+
"clipped.tif",
|
|
89
|
+
bbox=(-0.1, 51.45, 0.05, 51.52),
|
|
90
|
+
bbox_crs="EPSG:4326",
|
|
91
|
+
)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### TileMatrixSet models
|
|
95
|
+
|
|
96
|
+
Tile Matrix definitions use the [morecantile](https://github.com/developmentseed/morecantile) package (`morecantile.TileMatrixSet`, `TileMatrix`, etc.) so any morecantile TileMatrixSet (built-in or custom-loaded) can be passed to `GeoPakTile`. The XML parser returns morecantile `TileMatrixSet` objects.
|
|
97
|
+
|
|
98
|
+
### XML Parser
|
|
99
|
+
|
|
100
|
+
The xml parser has been tested on NASA GetCapabilties XML and some others, if you come across any that doesn't work then please raise an issue or fix and pull request.
|
|
101
|
+
|
|
102
|
+
### Converting to COG
|
|
103
|
+
|
|
104
|
+
`gpkg_tiles_to_cog` copies each zoom level's own pixels into the COG as an overview, rather than letting GDAL resample new overviews from the full resolution image, so every overview keeps the scale of the zoom level it came from. It works with any tile grid where each zoom level halves the pixel size of the one below, such as `WebMercatorQuad` and most grids from GetCapabilities documents.
|
|
105
|
+
|
|
106
|
+
The output extent defaults to the tiles present at the highest zoom level, or can be set with `bbox` (in the layer's CRS, or in `bbox_crs` if given). The extent is expanded slightly so that it lines up with whole pixels at the zoom levels used as overviews.
|
|
107
|
+
|
|
108
|
+
A zoom level can only be copied directly if its pixel grid lines up with the output extent. For small extents, the coarsest zoom levels often don't line up, and are left out by default. Pass `resample_unaligned=True` to include them by resampling them onto the extent, down to an overview 1 pixel across. A warning lists any zoom levels that were resampled. The method is set with `resampling` (`"bilinear"` by default; any [rasterio Resampling](https://rasterio.readthedocs.io/en/stable/api/rasterio.enums.html#rasterio.enums.Resampling) name such as `"nearest"` or `"average"` works).
|
|
109
|
+
|
|
110
|
+
Other options:
|
|
111
|
+
|
|
112
|
+
| Argument | Default | Description |
|
|
113
|
+
| --- | --- | --- |
|
|
114
|
+
| `table` | the only tile table | Tile table to convert, needed if the geopackage has more than one. |
|
|
115
|
+
| `min_zoom`, `max_zoom` | all zoom levels with tiles | Zoom levels to include. `max_zoom` sets the full resolution. Without `resample_unaligned`, setting `min_zoom` expands the extent to line up with that zoom level's pixels, which can make the output much larger. |
|
|
116
|
+
| `bands` | `"RGBA"` | `"RGBA"` makes missing tiles transparent. `"RGB"` makes them black, and is required for JPEG compression. |
|
|
117
|
+
| `compress` | `"DEFLATE"` | Any GDAL COG compression, such as `"ZSTD"`, `"LZW"`, `"WEBP"` or `"JPEG"`. |
|
|
118
|
+
| `blocksize` | the geopackage tile width | Internal tile size of the COG. |
|
|
119
|
+
| `overwrite` | `False` | Replace an existing output file. |
|
|
120
|
+
|
|
121
|
+
COG conversion requires [rasterio](https://rasterio.readthedocs.io/), which includes GDAL's COG driver in its wheels.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# GeoPakTile
|
|
2
|
+
|
|
3
|
+
For writing geopackage XYZ raster tile layers, with support for using arbitrary grid systems, and for converting them to Cloud Optimized GeoTIFFs (COGs).
|
|
4
|
+
|
|
5
|
+
Geopackage XYZ files can use any tile grid system, this is often defined by a server's GetCapabilities response where a TileMatrixSet defines the data co-ordinate system, the extent, the number of rows and columns in each zoom lever, and the corner co-ordinates for each zoom level. This package contains a tool for parsing the GetCapabilities XML into a [morecantile](https://github.com/developmentseed/morecantile) `TileMatrixSet`, and then for writing tiles to a new or existing geopackage.
|
|
6
|
+
|
|
7
|
+
## Examples
|
|
8
|
+
|
|
9
|
+
Write tiles to a new geopackage using web mercator (similar to mbtiles), where tiles is a list of (z, x, y, bytes). `tms` is a morecantile `TileMatrixSet` - the standard web mercator can be obtained with `morecantile.tms.get('WebMercatorQuad')`
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from geopaktile import GeoPakTile
|
|
13
|
+
|
|
14
|
+
# Here, a list of tiles are read from a local path, the bytes and co-ordinates are stored as tuples in a list:
|
|
15
|
+
# You might get these tiles from a tile server or anywhere else. Adjust accordingly.
|
|
16
|
+
|
|
17
|
+
tiles = [
|
|
18
|
+
(z, x, y, path.read_bytes()),
|
|
19
|
+
(z2, x2, y2, path2.read_bytes()),
|
|
20
|
+
(z3, x3, y3, path3.read_bytes()),
|
|
21
|
+
...
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
with GeoPakTile(test_gpkg, tms=morecantile.tms.get('WebMercatorQuad'), mode='rwc') as gpkg:
|
|
25
|
+
gpkg.add_tiles(tiles)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Open a geopackage in read only mode and see if it contains certain tiles. A TileMatrixSet isn't required for read-only mode.
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from geopaktile import GeoPakTile
|
|
32
|
+
|
|
33
|
+
with GeoPakTile(test_gpkg, mode='ro') as gpkg:
|
|
34
|
+
assert gpkg.has_tile(z, x, y)
|
|
35
|
+
result = gpkg.has_tiles([(z, x, y), (z1, x1, y1)])
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
Parse a GetCapabilties xml to provide the TileMatrixSet for writing a geopackage:
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from geopaktile import parse_capabilities
|
|
43
|
+
|
|
44
|
+
tms_set = parse_capabilities(xml)
|
|
45
|
+
tms = tms_set[0] # you'll need to know which one you want, or use:
|
|
46
|
+
|
|
47
|
+
tms = get_tile_matrix_set(xml, identifier = '1km') # an identifier that you know is defined in the xml
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
Convert a geopackage tile layer to a Cloud Optimized GeoTIFF. The highest zoom level becomes the full resolution image, and the lower zoom levels become the COG's overviews:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from geopaktile import gpkg_tiles_to_cog
|
|
55
|
+
|
|
56
|
+
gpkg_tiles_to_cog("tiles.gpkg", "tiles.tif")
|
|
57
|
+
|
|
58
|
+
# Clip to a bounding box, given here in longitude/latitude
|
|
59
|
+
gpkg_tiles_to_cog(
|
|
60
|
+
"tiles.gpkg",
|
|
61
|
+
"clipped.tif",
|
|
62
|
+
bbox=(-0.1, 51.45, 0.05, 51.52),
|
|
63
|
+
bbox_crs="EPSG:4326",
|
|
64
|
+
)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### TileMatrixSet models
|
|
68
|
+
|
|
69
|
+
Tile Matrix definitions use the [morecantile](https://github.com/developmentseed/morecantile) package (`morecantile.TileMatrixSet`, `TileMatrix`, etc.) so any morecantile TileMatrixSet (built-in or custom-loaded) can be passed to `GeoPakTile`. The XML parser returns morecantile `TileMatrixSet` objects.
|
|
70
|
+
|
|
71
|
+
### XML Parser
|
|
72
|
+
|
|
73
|
+
The xml parser has been tested on NASA GetCapabilties XML and some others, if you come across any that doesn't work then please raise an issue or fix and pull request.
|
|
74
|
+
|
|
75
|
+
### Converting to COG
|
|
76
|
+
|
|
77
|
+
`gpkg_tiles_to_cog` copies each zoom level's own pixels into the COG as an overview, rather than letting GDAL resample new overviews from the full resolution image, so every overview keeps the scale of the zoom level it came from. It works with any tile grid where each zoom level halves the pixel size of the one below, such as `WebMercatorQuad` and most grids from GetCapabilities documents.
|
|
78
|
+
|
|
79
|
+
The output extent defaults to the tiles present at the highest zoom level, or can be set with `bbox` (in the layer's CRS, or in `bbox_crs` if given). The extent is expanded slightly so that it lines up with whole pixels at the zoom levels used as overviews.
|
|
80
|
+
|
|
81
|
+
A zoom level can only be copied directly if its pixel grid lines up with the output extent. For small extents, the coarsest zoom levels often don't line up, and are left out by default. Pass `resample_unaligned=True` to include them by resampling them onto the extent, down to an overview 1 pixel across. A warning lists any zoom levels that were resampled. The method is set with `resampling` (`"bilinear"` by default; any [rasterio Resampling](https://rasterio.readthedocs.io/en/stable/api/rasterio.enums.html#rasterio.enums.Resampling) name such as `"nearest"` or `"average"` works).
|
|
82
|
+
|
|
83
|
+
Other options:
|
|
84
|
+
|
|
85
|
+
| Argument | Default | Description |
|
|
86
|
+
| --- | --- | --- |
|
|
87
|
+
| `table` | the only tile table | Tile table to convert, needed if the geopackage has more than one. |
|
|
88
|
+
| `min_zoom`, `max_zoom` | all zoom levels with tiles | Zoom levels to include. `max_zoom` sets the full resolution. Without `resample_unaligned`, setting `min_zoom` expands the extent to line up with that zoom level's pixels, which can make the output much larger. |
|
|
89
|
+
| `bands` | `"RGBA"` | `"RGBA"` makes missing tiles transparent. `"RGB"` makes them black, and is required for JPEG compression. |
|
|
90
|
+
| `compress` | `"DEFLATE"` | Any GDAL COG compression, such as `"ZSTD"`, `"LZW"`, `"WEBP"` or `"JPEG"`. |
|
|
91
|
+
| `blocksize` | the geopackage tile width | Internal tile size of the COG. |
|
|
92
|
+
| `overwrite` | `False` | Replace an existing output file. |
|
|
93
|
+
|
|
94
|
+
COG conversion requires [rasterio](https://rasterio.readthedocs.io/), which includes GDAL's COG driver in its wheels.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "GeoPakTile"
|
|
3
|
+
version = "2.1.0"
|
|
4
|
+
description = "Create a Geopackage XYZ Tile layer."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "apwebber", email = "39490780+apwebber@users.noreply.github.com" }
|
|
8
|
+
]
|
|
9
|
+
license = "MIT"
|
|
10
|
+
license-files = ["LICENSE.md"]
|
|
11
|
+
keywords = ["GIS", "Geopackage", "Tiles", "XYZ", "gpkg"]
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 4 - Beta",
|
|
15
|
+
|
|
16
|
+
# Specify the Python versions you support here.
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"typing_extensions>=4.0; python_version < '3.11'",
|
|
25
|
+
"morecantile>=6.2.0",
|
|
26
|
+
"numpy>=2.2.6",
|
|
27
|
+
"requests>=2.34.2",
|
|
28
|
+
"pillow>=12.3.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/apwebber/GeoPakTile"
|
|
33
|
+
Documentation = "https://github.com/apwebber/GeoPakTile"
|
|
34
|
+
Repository = "https://github.com/apwebber/GeoPakTile.git"
|
|
35
|
+
Issues = "https://github.com/apwebber/GeoPakTile/issues"
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
geopaktile = "geopaktile:main"
|
|
39
|
+
|
|
40
|
+
[build-system]
|
|
41
|
+
requires = ["uv_build>=0.11.2,<0.12.0"]
|
|
42
|
+
build-backend = "uv_build"
|
|
43
|
+
|
|
44
|
+
[dependency-groups]
|
|
45
|
+
dev = [
|
|
46
|
+
"pytest",
|
|
47
|
+
"diskcache",
|
|
48
|
+
"rasterio",
|
|
49
|
+
"rio-cogeo>=6.0.0",
|
|
50
|
+
]
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from geopaktile.geopaktile import GeoPakTile as GeoPakTile
|
|
2
|
+
from geopaktile.gpkg_to_cog import gpkg_tiles_to_cog as gpkg_tiles_to_cog
|
|
3
|
+
from geopaktile.xml_parser import get_tile_matrix_set as get_tile_matrix_set
|
|
4
|
+
from geopaktile.xml_parser import parse_capabilities as parse_capabilities
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main():
|
|
8
|
+
print("Command line usage has not been implemented.")
|