Skip to content

Commit 555a38f

Browse files
committed
Created demo static notebook
1 parent 57c9b00 commit 555a38f

File tree

3 files changed

+879
-0
lines changed

3 files changed

+879
-0
lines changed

docs/tiling_demo.md

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
# MicroJSON Tiling Demo
2+
3+
This notebook demonstrates how to use the MicroJSON tiling functionality to create vector tiles from MicroJSON data. Vector tiles are a way to efficiently store and serve geospatial data for web mapping applications.
4+
5+
## Overview
6+
7+
In this demo, we will:
8+
1. Generate sample polygon data (or use existing MicroJSON data)
9+
2. Create a TileJSON specification
10+
3. Generate vector tiles from the MicroJSON data
11+
4. Save the tiles and metadata for use in web mapping applications
12+
13+
## Import Required Libraries
14+
15+
First, let's import the necessary libraries for tiling MicroJSON data.
16+
17+
18+
```python
19+
from microjson.tilewriter import (
20+
TileWriter,
21+
getbounds,
22+
extract_fields_ranges_enums
23+
)
24+
from pathlib import Path
25+
from microjson.tilemodel import TileJSON, TileModel, TileLayer
26+
import os
27+
from microjson.polygen import generate_polygons
28+
import json
29+
```
30+
31+
## Option 1: Generate Sample Polygon Data
32+
33+
If you don't have existing MicroJSON data, we can generate sample polygon data using the `generate_polygons` function.
34+
35+
36+
```python
37+
# Parameters for generating polygons
38+
GRID_SIZE = 10000 # Size of the grid
39+
CELL_SIZE = 100 # Size of each cell in the grid
40+
MIN_VERTICES = 10 # Minimum number of vertices per polygon
41+
MAX_VERTICES = 100 # Maximum number of vertices per polygon
42+
43+
# Metadata types and options
44+
meta_types = {
45+
"num_vertices": "int",
46+
}
47+
meta_values_options = {
48+
"polytype": ["Type1", "Type2", "Type3", "Type4"]
49+
}
50+
51+
# Output file path
52+
microjson_data_path = "example_generated.json"
53+
54+
# Generate polygons
55+
generate_polygons(
56+
GRID_SIZE,
57+
CELL_SIZE,
58+
MIN_VERTICES,
59+
MAX_VERTICES,
60+
meta_types,
61+
meta_values_options,
62+
microjson_data_path
63+
)
64+
65+
print(f"Generated polygon data saved to {microjson_data_path}")
66+
```
67+
68+
Generated polygon data saved to example_generated.json
69+
70+
71+
## Option 2: Use Existing MicroJSON Data
72+
73+
Alternatively, you can use existing MicroJSON data. Uncomment and modify the following cell to use your own data.
74+
75+
76+
```python
77+
# microjson_data_path = "path/to/your/data.json"
78+
# print(f"Using existing MicroJSON data from {microjson_data_path}")
79+
```
80+
81+
## Visualize the MicroJSON Data
82+
83+
Let's take a look at the structure of our MicroJSON data.
84+
85+
86+
```python
87+
# Load and display the first few features of the MicroJSON data
88+
with open(microjson_data_path, 'r') as f:
89+
data = json.load(f)
90+
91+
# Display basic information about the data
92+
print(f"Number of features: {len(data.get('features', []))}")
93+
94+
# Display the first feature (truncated for readability)
95+
if 'features' in data and len(data['features']) > 0:
96+
first_feature = data['features'][0]
97+
print("\nSample feature:")
98+
print(json.dumps(first_feature, indent=2)[:500] + "...")
99+
```
100+
101+
Number of features: 10000
102+
103+
Sample feature:
104+
{
105+
"type": "Feature",
106+
"geometry": {
107+
"type": "Polygon",
108+
"coordinates": [
109+
[
110+
[
111+
62.7619624272948,
112+
9.7445327252005
113+
],
114+
[
115+
66.55786998050925,
116+
10.453250162004622
117+
],
118+
[
119+
86.82803641255592,
120+
51.64994084555056
121+
],
122+
[
123+
77.93853896392383,
124+
68.85236038607228
125+
],
126+
[
127+
67.57602296868663,
128+
78.79357410969412
129+
],
130+
[
131+
4...
132+
133+
134+
## Extract Fields, Ranges, and Enums
135+
136+
For existing MicroJSON data, we can extract field information, value ranges, and enumeration values.
137+
138+
139+
```python
140+
# Extract fields, ranges, and enums from the MicroJSON data
141+
field_names, field_ranges, field_enums = extract_fields_ranges_enums(microjson_data_path)
142+
143+
print("Extracted field names:")
144+
print(field_names)
145+
146+
print("\nExtracted field ranges:")
147+
print(field_ranges)
148+
149+
print("\nExtracted field enums:")
150+
print(field_enums)
151+
```
152+
153+
Extracted field names:
154+
{'num_vertices': 'Number', 'polytype': 'String'}
155+
156+
Extracted field ranges:
157+
{'num_vertices': [10, 24]}
158+
159+
Extracted field enums:
160+
{'polytype': {'Type3', 'Type2', 'Type1', 'Type4'}}
161+
162+
163+
## Define Vector Layers
164+
165+
Now, let's define the vector layers for our tiles. We'll use the extracted field information.
166+
167+
168+
```python
169+
# Create a TileLayer using the extracted fields
170+
vector_layers = [
171+
TileLayer(
172+
id="polygon-layer",
173+
fields=field_names,
174+
minzoom=0,
175+
maxzoom=10,
176+
description="Layer containing polygon data",
177+
fieldranges=field_ranges,
178+
fieldenums=field_enums,
179+
)
180+
]
181+
182+
print("Vector layer defined with the following properties:")
183+
print(f"ID: {vector_layers[0].id}")
184+
print(f"Fields: {vector_layers[0].fields}")
185+
print(f"Zoom range: {vector_layers[0].minzoom} - {vector_layers[0].maxzoom}")
186+
```
187+
188+
Vector layer defined with the following properties:
189+
ID: polygon-layer
190+
Fields: {'num_vertices': 'Number', 'polytype': 'String'}
191+
Zoom range: 0 - 10
192+
193+
194+
## Get Bounds and Center
195+
196+
Next, we'll calculate the bounds of our data to properly configure the tile model.
197+
198+
199+
```python
200+
# Get bounds of the data (square=True ensures the bounds form a square)
201+
maxbounds = getbounds(microjson_data_path, square=True)
202+
print(f"Bounds: {maxbounds}")
203+
204+
# Calculate the center of the bounds
205+
center = [0, (maxbounds[0] + maxbounds[2]) / 2, (maxbounds[1] + maxbounds[3]) / 2]
206+
print(f"Center: {center}")
207+
```
208+
209+
Bounds: [5.352408515784582, 5.049442955279417, 9995.190828709661, 9994.887863149157]
210+
Center: [0, 5000.271618612723, 4999.9686530522185]
211+
212+
213+
## Create the Tile Model
214+
215+
Now, let's create the TileModel that will define our tile set.
216+
217+
218+
```python
219+
# Create output directory for tiles
220+
os.makedirs("tiles", exist_ok=True)
221+
222+
# Instantiate TileModel with our settings
223+
tile_model = TileModel(
224+
tilejson="3.0.0",
225+
tiles=[Path("tiles/{z}/{x}/{y}.pbf")], # Local path or URL
226+
name="Example Tile Layer",
227+
description="A TileJSON example incorporating MicroJSON data",
228+
version="1.0.0",
229+
attribution="Polus AI",
230+
minzoom=0,
231+
maxzoom=7,
232+
bounds=maxbounds,
233+
center=center,
234+
vector_layers=vector_layers
235+
)
236+
237+
# Create the root model with our TileModel instance
238+
tileobj = TileJSON(root=tile_model)
239+
240+
# Display the TileJSON specification
241+
print("TileJSON specification:")
242+
print(tileobj.model_dump_json(indent=2))
243+
```
244+
245+
TileJSON specification:
246+
{
247+
"tilejson": "3.0.0",
248+
"tiles": [
249+
"tiles/{z}/{x}/{y}.pbf"
250+
],
251+
"name": "Example Tile Layer",
252+
"description": "A TileJSON example incorporating MicroJSON data",
253+
"version": "1.0.0",
254+
"attribution": "Polus AI",
255+
"template": null,
256+
"legend": null,
257+
"scheme": null,
258+
"grids": null,
259+
"data": null,
260+
"minzoom": 0,
261+
"maxzoom": 7,
262+
"bounds": [
263+
5.352408515784582,
264+
5.049442955279417,
265+
9995.190828709661,
266+
9994.887863149157
267+
],
268+
"center": [
269+
0.0,
270+
5000.271618612723,
271+
4999.9686530522185
272+
],
273+
"fillzoom": null,
274+
"vector_layers": [
275+
{
276+
"id": "polygon-layer",
277+
"fields": {
278+
"num_vertices": "Number",
279+
"polytype": "String"
280+
},
281+
"minzoom": 0,
282+
"maxzoom": 10,
283+
"description": "Layer containing polygon data",
284+
"fieldranges": {
285+
"num_vertices": [
286+
10,
287+
24
288+
]
289+
},
290+
"fieldenums": {
291+
"polytype": [
292+
"Type3",
293+
"Type2",
294+
"Type1",
295+
"Type4"
296+
]
297+
},
298+
"fielddescriptions": null
299+
}
300+
],
301+
"multiscale": null,
302+
"scale_factor": null
303+
}
304+
305+
306+
## Export TileJSON Metadata
307+
308+
Let's export the TileJSON metadata to a file.
309+
310+
311+
```python
312+
# Export to tilejson
313+
with open("tiles/metadata.json", "w") as f:
314+
f.write(tileobj.model_dump_json(indent=2))
315+
316+
print("TileJSON metadata exported to tiles/metadata.json")
317+
```
318+
319+
TileJSON metadata exported to tiles/metadata.json
320+
321+
322+
## Generate Vector Tiles
323+
324+
Finally, let's generate the vector tiles from our MicroJSON data.
325+
326+
327+
```python
328+
# Initialize the TileWriter
329+
handler = TileWriter(tile_model, pbf=True)
330+
331+
# Convert MicroJSON to tiles
332+
handler.microjson2tiles(microjson_data_path, validate=False)
333+
334+
print("Vector tiles generated successfully!")
335+
336+
# List the generated tile directories to verify
337+
tile_dirs = [d for d in os.listdir("tiles") if os.path.isdir(os.path.join("tiles", d))]
338+
print(f"Generated tile zoom levels: {tile_dirs}")
339+
```
340+
341+
Vector tiles generated successfully!
342+
Generated tile zoom levels: ['7', '2', '0', 'tiled_example', '1', '5', '3', '4', '6']
343+
344+
345+
## Conclusion
346+
347+
In this notebook, we've demonstrated how to:
348+
349+
1. Generate or use existing MicroJSON data
350+
2. Extract field information from the data
351+
3. Define vector layers for our tiles
352+
4. Calculate bounds and center for our tile set
353+
5. Create a TileJSON specification
354+
6. Generate vector tiles from MicroJSON data
355+
356+
These vector tiles can now be used in web mapping applications like Mapbox GL JS, Leaflet, or OpenLayers to display the data interactively.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ nav:
4747
- Extensions:
4848
- Provenance in MicroJSON: 'provenance.md'
4949
- MicroJSON tiling: 'tiling.md'
50+
- Tiling Demo (Notebook): 'tiling_demo.md'
5051
- About:
5152
- About MicroJSON: 'about.md'
5253
- License: 'license.md'

0 commit comments

Comments
 (0)