satprint 0.2.1__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.
- satprint-0.2.1/LICENSE +21 -0
- satprint-0.2.1/PKG-INFO +368 -0
- satprint-0.2.1/README.md +330 -0
- satprint-0.2.1/pyproject.toml +161 -0
- satprint-0.2.1/satprint/__init__.py +3 -0
- satprint-0.2.1/satprint/__main__.py +3 -0
- satprint-0.2.1/satprint/app.py +635 -0
- satprint-0.2.1/satprint/buildings.py +795 -0
- satprint-0.2.1/satprint/cli.py +294 -0
- satprint-0.2.1/satprint/landmarks.py +91 -0
- satprint-0.2.1/satprint/mesh.py +753 -0
- satprint-0.2.1/satprint/osm.py +433 -0
- satprint-0.2.1/satprint/overture.py +167 -0
- satprint-0.2.1/satprint/presets.py +115 -0
- satprint-0.2.1/satprint/static/app.js +398 -0
- satprint-0.2.1/satprint/static/index.html +141 -0
- satprint-0.2.1/satprint/static/satprint-mark.svg +30 -0
- satprint-0.2.1/satprint/static/style.css +72 -0
- satprint-0.2.1/satprint/terrain.py +579 -0
- satprint-0.2.1/satprint/water.py +142 -0
satprint-0.2.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Eric G. Suchanek, PhD
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
satprint-0.2.1/PKG-INFO
ADDED
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: satprint
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Satellite terrain to 3D-printable models: watertight STL, multi-color 3MF and textured GLB, with OpenStreetMap buildings
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: 3d-printing,terrain,digital-elevation-model,openstreetmap,stl,3mf,gltf,multi-material
|
|
8
|
+
Author: Eric G. Suchanek, PhD
|
|
9
|
+
Author-email: suchanek@flux-frontiers.com
|
|
10
|
+
Requires-Python: >=3.12,<3.14
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
16
|
+
Classifier: Framework :: FastAPI
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Provides-Extra: geotiff
|
|
21
|
+
Provides-Extra: overture
|
|
22
|
+
Requires-Dist: fastapi (>=0.110)
|
|
23
|
+
Requires-Dist: mapbox-vector-tile (>=2.0)
|
|
24
|
+
Requires-Dist: numpy (>=1.26)
|
|
25
|
+
Requires-Dist: overturemaps (>=1.0) ; extra == "overture"
|
|
26
|
+
Requires-Dist: pillow (>=10)
|
|
27
|
+
Requires-Dist: python-multipart (>=0.0.9)
|
|
28
|
+
Requires-Dist: rasterio (>=1.3) ; extra == "geotiff"
|
|
29
|
+
Requires-Dist: requests (>=2.31)
|
|
30
|
+
Requires-Dist: shapely (>=2.1)
|
|
31
|
+
Requires-Dist: uvicorn[standard] (>=0.27)
|
|
32
|
+
Project-URL: Documentation, https://suchanek.github.io/satprint/
|
|
33
|
+
Project-URL: Homepage, https://github.com/suchanek/satprint
|
|
34
|
+
Project-URL: Issues, https://github.com/suchanek/satprint/issues
|
|
35
|
+
Project-URL: Repository, https://github.com/suchanek/satprint
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<picture>
|
|
40
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/brand/satprint-logo-dark.svg">
|
|
41
|
+
<img src="https://raw.githubusercontent.com/suchanek/satprint/v0.2.1/docs/brand/satprint-logo.svg" alt="satprint" width="460">
|
|
42
|
+
</picture>
|
|
43
|
+
</p>
|
|
44
|
+
|
|
45
|
+
[](https://github.com/suchanek/satprint/actions/workflows/tests.yml)
|
|
46
|
+
[](https://suchanek.github.io/satprint/)
|
|
47
|
+
[](https://www.python.org/)
|
|
48
|
+
[](https://github.com/suchanek/satprint/blob/main/LICENSE)
|
|
49
|
+
[](https://github.com/suchanek/satprint/releases)
|
|
50
|
+
[](https://python-poetry.org/)
|
|
51
|
+
[](https://doi.org/10.5281/zenodo.23094151)
|
|
52
|
+
[](https://pre-commit.com/)
|
|
53
|
+
[](https://orcid.org/0009-0009-0891-1507)
|
|
54
|
+
|
|
55
|
+
# satprint -- Satellite Terrain to 3D-Printable Models
|
|
56
|
+
|
|
57
|
+
**Pick a place on a map. Get a watertight STL of its terrain and buildings, a multi-color 3MF ready for a multi-material printer, and a GLB with satellite imagery draped over it.**
|
|
58
|
+
|
|
59
|
+
satprint turns real elevation data into a solid relief model scaled to your
|
|
60
|
+
printer: the terrain on top, four walls and a flat base. Cities can carry their
|
|
61
|
+
OpenStreetMap buildings, and the multi-color 3MF splits the model into land,
|
|
62
|
+
water, buildings and a border frame, one filament each.
|
|
63
|
+
|
|
64
|
+
**Documentation: [suchanek.github.io/satprint](https://suchanek.github.io/satprint/)**
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
satellite elevation -> heightmap (meters) -> STL solid
|
|
68
|
+
AWS Terrain Tiles clamp sea, smooth, terrain + walls + base
|
|
69
|
+
(SRTM, ASTER, GMTED) scale to mm, exaggerate + OSM buildings
|
|
70
|
+
+ land/water/border 3MF
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+

|
|
74
|
+
|
|
75
|
+
Mount Fuji from real elevation tiles, 120 mm wide, 1.2x exaggeration:
|
|
76
|
+
|
|
77
|
+

|
|
78
|
+
|
|
79
|
+
## Features
|
|
80
|
+
|
|
81
|
+
- **Real elevation, no API key.** Elevation comes from the public
|
|
82
|
+
[AWS Terrain Tiles](https://registry.opendata.aws/terrain-tiles/) set
|
|
83
|
+
(SRTM, ASTER, GMTED and others), cached under `~/.cache/satprint/tiles`. You
|
|
84
|
+
can also upload a 16-bit PNG, TIFF or GeoTIFF heightmap, or use a procedural
|
|
85
|
+
demo terrain that needs no network.
|
|
86
|
+
- **Print-aware output.** True plan scale, vertical exaggeration or a fixed
|
|
87
|
+
relief height, base thickness, sea-level flattening, Gaussian smoothing and
|
|
88
|
+
grids up to 1024 columns. Each build reports model size, scale, triangle
|
|
89
|
+
count, volume and an estimated PLA weight.
|
|
90
|
+
- **Watertight by construction.** Every edge is shared by exactly two
|
|
91
|
+
outward-wound triangles, so slicers (Bambu Studio, PrusaSlicer, Cura,
|
|
92
|
+
Chitubox) load the STL without repair.
|
|
93
|
+
- **Buildings** from OpenStreetMap, as closed solids standing on the terrain.
|
|
94
|
+
Landmark towers keep their setbacks where OSM maps them as `building:part`
|
|
95
|
+
shapes, domes, onion domes, cones and pyramids get their roof shapes, and
|
|
96
|
+
overlapping footprints are merged so no two solids pass through each other.
|
|
97
|
+
A few landmarks, such as the Sphere in Las Vegas, get exact shapes. Heights
|
|
98
|
+
are in true proportion by default, with a multiplier. OpenFreeMap, Overpass
|
|
99
|
+
or Overture Maps.
|
|
100
|
+
- **Multi-color 3MF.** Land, water, buildings and an optional border frame are
|
|
101
|
+
separate parts of one object, already on filaments 1 to 4 in Bambu Studio.
|
|
102
|
+
Water is the OSM sea, rivers and lakes, plus the flattened sea.
|
|
103
|
+
- **Border frame.** A rectangular rim around the model, 1 mm above the base by
|
|
104
|
+
default, in the STL, GLB and 3MF.
|
|
105
|
+
- **Textured GLB.** Satellite imagery draped over the terrain and the roofs,
|
|
106
|
+
for viewing in Blender, macOS Quick Look or a web viewer. The web preview
|
|
107
|
+
shows it.
|
|
108
|
+
- **Search and presets.** Search any place by name, or pick one of 67 presets:
|
|
109
|
+
37 cities and landmarks, which turn buildings on, and 30 mountains and
|
|
110
|
+
landscapes.
|
|
111
|
+
- **Web app, CLI and REST API.** Builds run as background jobs, and the page
|
|
112
|
+
shows each stage with tile counts. Interactive API docs are at `/docs`.
|
|
113
|
+
|
|
114
|
+
## Install
|
|
115
|
+
|
|
116
|
+
satprint needs Python 3.12 or 3.13.
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
git clone https://github.com/suchanek/satprint.git
|
|
120
|
+
cd satprint
|
|
121
|
+
poetry install # add --extras geotiff for GeoTIFF georeferencing
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Without Poetry, `pip install -e .` in a virtual environment installs the app.
|
|
125
|
+
See [Installation](https://suchanek.github.io/satprint/install/) for Docker.
|
|
126
|
+
|
|
127
|
+
## Run the web app
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
satprint serve # http://127.0.0.1:7417
|
|
131
|
+
satprint serve --host 0.0.0.0 --port 7417
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
1. **Choose an area.** Search for a place, pick a preset, click **Draw
|
|
135
|
+
rectangle** and drag on the map, or type the bounds. The hint line shows the
|
|
136
|
+
real size of the area and the model it makes.
|
|
137
|
+
2. **Set the print.** Model width, base thickness, vertical exaggeration
|
|
138
|
+
(1.5x to 3x reads well for most landscapes; 1x is true scale) or a fixed
|
|
139
|
+
relief height. Resolution sets the grid columns: 256 is fine for FDM, 512
|
|
140
|
+
to 1024 for resin. Check **Add buildings** for a city, and **Multi-color
|
|
141
|
+
3MF** plus a **Border frame** width for a multi-material print.
|
|
142
|
+
3. **Generate.** The textured model appears in the 3D preview. Download the
|
|
143
|
+
STL to print in one color, the 3MF to print in several, or the GLB to view.
|
|
144
|
+
|
|
145
|
+
After you change the code, restart `satprint serve` to pick up the change.
|
|
146
|
+
|
|
147
|
+
## Print in several colors
|
|
148
|
+
|
|
149
|
+
The multi-color 3MF holds up to four parts, in this filament order:
|
|
150
|
+
|
|
151
|
+
| Filament | Part | Display color |
|
|
152
|
+
|---|---|---|
|
|
153
|
+
| 1 | `land` | green |
|
|
154
|
+
| 2 | `water` | blue |
|
|
155
|
+
| 3 | `buildings` | white |
|
|
156
|
+
| 4 | `border` | dark gray |
|
|
157
|
+
|
|
158
|
+
To print it on a Bambu printer with an AMS:
|
|
159
|
+
|
|
160
|
+
1. In Bambu Studio, set up four filaments in the left sidebar, or sync them
|
|
161
|
+
from the AMS.
|
|
162
|
+
2. Open the 3MF. Bambu Studio reports that it loads "geometry only", as it does
|
|
163
|
+
for any 3MF it did not write; the part names and filaments still come
|
|
164
|
+
through.
|
|
165
|
+
3. To check or change a part's filament, open the object list: in the left
|
|
166
|
+
sidebar, under **Process**, click **Objects** and expand the model.
|
|
167
|
+
4. Slice. The preview shows each part in its filament's color.
|
|
168
|
+
|
|
169
|
+
Other slicers open the same parts with every part on filament 1; assign the
|
|
170
|
+
filaments by hand.
|
|
171
|
+
|
|
172
|
+
## Command line
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# Matterhorn, 120 mm wide, 2x exaggeration
|
|
176
|
+
satprint build --bbox 45.93 7.58 46.02 7.72 --width 120 --exaggeration 2 -o matterhorn.stl
|
|
177
|
+
|
|
178
|
+
# Fixed 15 mm relief, smoothed, with a hillshade preview PNG
|
|
179
|
+
satprint build --bbox 36.02 -112.25 36.20 -111.95 --relief 15 --smoothing 1 \
|
|
180
|
+
--preview canyon.png -o grand-canyon.stl
|
|
181
|
+
|
|
182
|
+
# Midtown Manhattan with buildings, plus a textured GLB
|
|
183
|
+
satprint build --bbox 40.7414 -73.9997 40.7684 -73.9683 --width 150 \
|
|
184
|
+
--buildings --glb midtown.glb -o midtown.stl
|
|
185
|
+
|
|
186
|
+
# Venice as a four-color 3MF: land, water, buildings and a 5 mm border frame
|
|
187
|
+
satprint build --bbox 45.43 12.32 45.446 12.343 --buildings --frame 5 \
|
|
188
|
+
--3mf venice.3mf -o venice.stl
|
|
189
|
+
|
|
190
|
+
# From your own DEM in meters, 12 km across
|
|
191
|
+
satprint build --file dem.tif --ground-width 12000 -o dem.stl
|
|
192
|
+
|
|
193
|
+
# Offline demo terrain
|
|
194
|
+
satprint build --synthetic -o demo.stl
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Bounds are `SOUTH WEST NORTH EAST` in decimal degrees. The command prints a
|
|
198
|
+
JSON summary: elevation range, scale, triangle count, volume and a watertight
|
|
199
|
+
check. `satprint build --help` lists every option.
|
|
200
|
+
|
|
201
|
+
## REST API
|
|
202
|
+
|
|
203
|
+
| Method | Path | Purpose |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
| `GET` | `/api/presets` | Named example areas, grouped |
|
|
206
|
+
| `GET` | `/api/search?q=...` | Place search; each hit has a `bbox` |
|
|
207
|
+
| `POST` | `/api/upload` | Multipart heightmap upload; returns an `upload_id` |
|
|
208
|
+
| `POST` | `/api/model` | Build a model; returns stats, a preview PNG and download URLs |
|
|
209
|
+
| `POST` | `/api/jobs` | Same body as `/api/model`, built in the background; returns a `job_id` |
|
|
210
|
+
| `GET` | `/api/jobs/{id}` | Job `status`, current `stage` with `done` and `total`, and the `/api/model` response as `result` when done |
|
|
211
|
+
| `GET` | `/api/model/{id}/{name}.stl` | Binary STL |
|
|
212
|
+
| `GET` | `/api/model/{id}/{name}.glb` | Textured GLB, when `glb_url` is set |
|
|
213
|
+
| `GET` | `/api/model/{id}/{name}.3mf` | Multi-color 3MF, when `threemf_url` is set (`"multicolor": true`) |
|
|
214
|
+
| `GET` | `/api/model/{id}/heightmap.png` | Hillshade preview |
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
curl -s localhost:7417/api/model -H 'content-type: application/json' -d '{
|
|
218
|
+
"source": "terrarium",
|
|
219
|
+
"bbox": {"south": 35.28, "west": 138.65, "north": 35.45, "east": 138.82},
|
|
220
|
+
"width_mm": 150, "exaggeration": 1.2, "resolution": 512, "name": "fuji"
|
|
221
|
+
}' | python -c 'import json,sys; j=json.load(sys.stdin); print(j["stl_url"], j["info"]["height_mm"])'
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## How the scaling works
|
|
225
|
+
|
|
226
|
+
- **Plan scale** is `width_mm / ground_width_m`. The depth follows the true
|
|
227
|
+
aspect ratio of the area, from great-circle distances along the center lines
|
|
228
|
+
of the bounding box.
|
|
229
|
+
- **Vertical scale** is the plan scale times the exaggeration, so
|
|
230
|
+
`exaggeration = 1` is a true-scale model. With `relief_mm` set, the vertical
|
|
231
|
+
scale puts the highest point exactly that far above the base, and the
|
|
232
|
+
effective exaggeration is reported back.
|
|
233
|
+
- **Sea level.** Samples below 0 m (bathymetry in the source data) are clamped
|
|
234
|
+
to 0 by default, so coastlines print as a flat plane.
|
|
235
|
+
- **Buildings** use the plan scale for their heights, so `building_scale = 1`
|
|
236
|
+
keeps them in true proportion to the map.
|
|
237
|
+
|
|
238
|
+
## Data sources
|
|
239
|
+
|
|
240
|
+
| Data | Source | Cache |
|
|
241
|
+
|---|---|---|
|
|
242
|
+
| Elevation | [AWS Terrain Tiles](https://registry.opendata.aws/terrain-tiles/) | `~/.cache/satprint/tiles` |
|
|
243
|
+
| Imagery (GLB texture) | Esri World Imagery | `~/.cache/satprint/imagery` |
|
|
244
|
+
| Buildings and water | [OpenFreeMap](https://openfreemap.org) vector tiles, zoom 14, rebuilt from OSM about weekly | `~/.cache/satprint/vtiles` |
|
|
245
|
+
| Buildings, fallback; roof shapes | [Overpass API](https://wiki.openstreetmap.org/wiki/Overpass_API), 0.01° tiles | `~/.cache/satprint/osm` |
|
|
246
|
+
| Buildings, optional | [Overture Maps](https://overturemaps.org) GeoParquet on S3, per release | `~/.cache/satprint/overture` |
|
|
247
|
+
| Place search | [Nominatim](https://nominatim.org), one request per second | in memory |
|
|
248
|
+
|
|
249
|
+
- **Buildings.** A building with no `height` or `building:levels` tag gets 8 m.
|
|
250
|
+
Building parts are extruded from the ground, ignoring `min_height`, so
|
|
251
|
+
nothing floats. Buildings sink 0.3 mm into the terrain so they fuse with it
|
|
252
|
+
when sliced. Areas are limited to 40 km² with buildings on, and very small
|
|
253
|
+
footprints are dropped. A building that crosses a vector-tile edge arrives as
|
|
254
|
+
two solids that meet at the edge.
|
|
255
|
+
- **Roof shapes.** Roofs tagged `roof:shape` dome, onion, cone or pyramidal
|
|
256
|
+
get that shape, from `roof:height` or `roof:levels`, else a hemisphere-like
|
|
257
|
+
height from the footprint's size. Other roofs are flat. The vector tiles
|
|
258
|
+
carry no roof tags, so a small Overpass query adds them; if it fails, the
|
|
259
|
+
roofs are flat and the build says so. A shaped roof starts no lower than the
|
|
260
|
+
larger flat roofs around it, and smaller parts standing on it, such as a
|
|
261
|
+
lantern on a dome, stand in a hole cut in the roof, so the solids never pass
|
|
262
|
+
through each other.
|
|
263
|
+
- **Landmarks.** A few buildings that roof tags cannot describe are replaced by
|
|
264
|
+
exact shapes from published dimensions: so far the Sphere in Las Vegas, a
|
|
265
|
+
157 m sphere cut by the ground at 112 m.
|
|
266
|
+
- **Overture Maps.** Choose it with "Building data" or
|
|
267
|
+
`--building-source overture`. It merges OSM with Microsoft and Google
|
|
268
|
+
footprints, so it finds buildings OSM lacks, and keeps the roof tags. It
|
|
269
|
+
needs the `overture` extra (`pip install "satprint[overture]"`, about
|
|
270
|
+
190 MB with pyarrow; the Docker image has it).
|
|
271
|
+
- **Overpass.** Choose it with "Building data" in the web app or
|
|
272
|
+
`--building-source overpass` on the CLI, for the latest OSM edits. The
|
|
273
|
+
default "auto" uses it only if OpenFreeMap fails. Its tiles download two at a
|
|
274
|
+
time, busy answers are retried with backoff, and a server that times out is
|
|
275
|
+
skipped for 10 minutes. When some tiles fail, the rest stay cached, so
|
|
276
|
+
generating again fetches only the missing ones.
|
|
277
|
+
- **Imagery.** The texture is at most 2048 px on its longer side. Esri's terms
|
|
278
|
+
of use govern the imagery. Set `"texture": false` to skip it.
|
|
279
|
+
|
|
280
|
+
## Limits
|
|
281
|
+
|
|
282
|
+
- Source resolution is about 30 m (SRTM) over most land and about 10 m at zoom
|
|
283
|
+
14 where available, so areas smaller than about 2 km look blocky. Smoothing
|
|
284
|
+
helps.
|
|
285
|
+
- Elevation and imagery downloads are capped at 64 tiles per request. Shrink the
|
|
286
|
+
area or lower the resolution if you hit the cap.
|
|
287
|
+
- The multi-color split works one grid cell at a time, so a river narrower than
|
|
288
|
+
a cell does not show. Raise the resolution to keep it.
|
|
289
|
+
- The GLB is for viewing. FDM slicers ignore textures, so print the STL or the
|
|
290
|
+
3MF.
|
|
291
|
+
- Built models live in memory, the last 32. A download link is valid until the
|
|
292
|
+
server restarts.
|
|
293
|
+
|
|
294
|
+
## Layout
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
satprint/
|
|
298
|
+
terrain.py elevation sources (terrain tiles, synthetic, file), imagery, scaling, hillshade
|
|
299
|
+
mesh.py heightmap to watertight solid, land/water split, frame, STL, GLB and 3MF writers
|
|
300
|
+
buildings.py OSM buildings to closed solids on the terrain, roof shapes
|
|
301
|
+
landmarks.py exact shapes for a few landmarks
|
|
302
|
+
overture.py Overture Maps building source (overture extra)
|
|
303
|
+
water.py water map and the multi-color 3MF parts
|
|
304
|
+
osm.py OpenFreeMap, Overpass and Nominatim clients
|
|
305
|
+
presets.py named example areas
|
|
306
|
+
app.py FastAPI backend, background jobs, in-memory model store
|
|
307
|
+
cli.py satprint serve / satprint build
|
|
308
|
+
static/ web app: index.html, style.css, app.js (Leaflet and three.js from CDNs)
|
|
309
|
+
tests/ pytest suite, offline: every network client is faked
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Development
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
poetry install --with dev
|
|
316
|
+
pre-commit install
|
|
317
|
+
pytest -q
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
The pre-commit hooks run the standard file checks, ruff, detect-secrets, ty and
|
|
321
|
+
pytest. `pycodekg` and `dockg` index the repo for agents through `.mcp.json`;
|
|
322
|
+
they are global tools, not dependencies. To build the docs site locally, run
|
|
323
|
+
`poetry install --with docs` and `mkdocs serve`.
|
|
324
|
+
|
|
325
|
+
## Docker
|
|
326
|
+
|
|
327
|
+
A prebuilt image for `linux/amd64` and `linux/arm64` is on Docker Hub:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
docker run -d -p 7417:7417 -v satprint-tiles:/home/satprint/.cache/satprint egsuchanek/satprint
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Then open http://localhost:7417. See
|
|
334
|
+
[Installation](https://suchanek.github.io/satprint/install/#with-docker) to
|
|
335
|
+
build the image yourself.
|
|
336
|
+
|
|
337
|
+
## License
|
|
338
|
+
|
|
339
|
+
MIT. See [LICENSE](https://github.com/suchanek/satprint/blob/main/LICENSE).
|
|
340
|
+
|
|
341
|
+
Map data: Terrain Tiles © Mapzen and AWS Open Data (SRTM, ASTER GDEM, GMTED2010,
|
|
342
|
+
ETOPO1, NED, EU-DEM and others). Imagery © Esri, Maxar, Earthstar Geographics.
|
|
343
|
+
Street map, buildings, water and search © OpenStreetMap contributors, under the
|
|
344
|
+
ODbL. Overture buildings © Overture Maps Foundation and OpenStreetMap
|
|
345
|
+
contributors, under the ODbL.
|
|
346
|
+
|
|
347
|
+
## Citation
|
|
348
|
+
|
|
349
|
+
If you use satprint in your research or project, please cite it:
|
|
350
|
+
|
|
351
|
+
> Suchanek, E. G. (2026). *satprint: Satellite Terrain to 3D-Printable Models* (Version 0.2.1) [Software]. Flux-Frontiers. https://doi.org/10.5281/zenodo.23094151
|
|
352
|
+
|
|
353
|
+
```bibtex
|
|
354
|
+
@software{suchanek_satprint,
|
|
355
|
+
author = {Suchanek, Eric G.},
|
|
356
|
+
title = {{satprint}: Satellite Terrain to 3D-Printable Models},
|
|
357
|
+
version = {0.2.1},
|
|
358
|
+
year = {2026},
|
|
359
|
+
publisher = {Flux-Frontiers},
|
|
360
|
+
url = {https://github.com/suchanek/satprint},
|
|
361
|
+
doi = {10.5281/zenodo.23094151},
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
The DOI is the Zenodo concept DOI, which always resolves to the newest
|
|
366
|
+
archived release. The citation metadata is also in [CITATION.cff](https://github.com/suchanek/satprint/blob/main/CITATION.cff). See the
|
|
367
|
+
[changelog](https://github.com/suchanek/satprint/blob/main/CHANGELOG.md) for release history.
|
|
368
|
+
|