Skip to content

Commit 77722da

Browse files
Merge branch 'main' into patch/includes-excludes
2 parents 0739603 + 7859298 commit 77722da

File tree

5 files changed

+135
-83
lines changed

5 files changed

+135
-83
lines changed

CHANGES.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,18 @@ Note: Minor version `0.X.0` update might break the API, It's recommended to pin
88

99
## [unreleased]
1010

11+
### added
12+
1113
- add `py.typed` file
1214

15+
### fixed
16+
17+
- hide map element in HTML pages when collections/items do not have spatial component
18+
19+
### changed
20+
21+
- split endpoints registration for more customization
22+
1323
## [0.4.4] - 2023-10-03
1424

1525
### fixed

tipg/factory.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ def __post_init__(self):
219219
"""Post Init: register route and configure specific options."""
220220
self.register_routes()
221221
if self.with_common:
222-
self.register_common_routes()
222+
self._conformance_route()
223+
self._landing_route()
223224

224225
def url_for(self, request: Request, name: str, **path_params: Any) -> str:
225226
"""Return full url (with prefix) for a specific handler."""
@@ -269,8 +270,8 @@ def links(self, request: Request) -> List[model.Link]:
269270
"""Register factory Routes."""
270271
...
271272

272-
def register_common_routes(self):
273-
"""Register Landing (/) and Conformance (/conformance) routes."""
273+
def _conformance_route(self):
274+
"""Register Conformance (/conformance) route."""
274275

275276
@self.router.get(
276277
"/conformance",
@@ -303,6 +304,9 @@ def conformance(
303304

304305
return data
305306

307+
def _landing_route(self):
308+
"""Register Landing (/) and Conformance (/conformance) routes."""
309+
306310
@self.router.get(
307311
"/",
308312
response_model=model.Landing,
@@ -421,9 +425,15 @@ def links(self, request: Request) -> List[model.Link]:
421425
),
422426
]
423427

424-
def register_routes(self): # noqa: C901
428+
def register_routes(self):
425429
"""Register OGC Features endpoints."""
430+
self._collections_route()
431+
self._collection_route()
432+
self._queryables_route()
433+
self._items_route()
434+
self._item_route()
426435

436+
def _collections_route(self): # noqa: C901
427437
@self.router.get(
428438
"/collections",
429439
response_model=model.Collections,
@@ -603,6 +613,7 @@ def collections( # noqa: C901
603613

604614
return data
605615

616+
def _collection_route(self):
606617
@self.router.get(
607618
"/collections/{collectionId}",
608619
response_model=model.Collection,
@@ -688,6 +699,7 @@ def collection(
688699

689700
return data
690701

702+
def _queryables_route(self):
691703
@self.router.get(
692704
"/collections/{collectionId}/queryables",
693705
response_model=model.Queryables,
@@ -731,6 +743,7 @@ def queryables(
731743

732744
return data
733745

746+
def _items_route(self): # noqa: C901
734747
@self.router.get(
735748
"/collections/{collectionId}/items",
736749
response_class=GeoJSONResponse,
@@ -1005,6 +1018,7 @@ async def items( # noqa: C901
10051018
# Default to GeoJSON Response
10061019
return GeoJSONResponse(data)
10071020

1021+
def _item_route(self):
10081022
@self.router.get(
10091023
"/collections/{collectionId}/items/{itemId}",
10101024
response_class=GeoJSONResponse,
@@ -1247,7 +1261,13 @@ def links(self, request: Request) -> List[model.Link]:
12471261

12481262
def register_routes(self): # noqa: C901
12491263
"""Register OGC Tiles endpoints."""
1264+
self._tilematrixsets_routes()
1265+
self._tilesets_routes()
1266+
self._tile_routes()
1267+
self._tilejson_routes()
1268+
self._stylejson_routes()
12501269

1270+
def _tilematrixsets_routes(self):
12511271
@self.router.get(
12521272
r"/tileMatrixSets",
12531273
response_model=model.TileMatrixSetList,
@@ -1344,6 +1364,7 @@ async def tilematrixset(
13441364

13451365
return data
13461366

1367+
def _tilesets_routes(self):
13471368
@self.router.get(
13481369
"/collections/{collectionId}/tiles",
13491370
response_model=model.TileSetList,
@@ -1547,6 +1568,7 @@ async def collection_tileset(
15471568

15481569
return data
15491570

1571+
def _tile_routes(self):
15501572
@self.router.get(
15511573
"/collections/{collectionId}/tiles/{tileMatrixSetId}/{z}/{x}/{y}",
15521574
response_class=Response,
@@ -1620,6 +1642,8 @@ async def collection_get_tile(
16201642

16211643
return Response(bytes(tile), media_type=MediaType.mvt.value)
16221644

1645+
def _tilejson_routes(self):
1646+
16231647
############################################################################
16241648
# ADDITIONAL ENDPOINTS NOT IN OGC Tiles API (tilejson, style.json, viewer) #
16251649
############################################################################
@@ -1721,6 +1745,7 @@ async def collection_tilejson(
17211745

17221746
return tile_json
17231747

1748+
def _stylejson_routes(self):
17241749
@self.router.get(
17251750
"/collections/{collectionId}/{tileMatrixSetId}/style.json",
17261751
response_model=model.StyleJSON,

tipg/templates/collection.html

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,24 +47,30 @@ <h2>Links</h2>
4747

4848
<script>
4949
$(function() {
50-
var map = L.map('map').setView([0, 0], 1);
51-
map.addLayer(new L.TileLayer(
52-
'https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
53-
maxZoom: 18,
54-
attribution: 'Map data &copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
55-
}
56-
));
50+
var collection = {{ response|tojson }};
51+
if (collection.extent && collection.extent.spatial){
52+
var bbox = collection.extent.spatial.bbox[0]
53+
var bbox_polygon = L.polygon([
54+
[bbox[1], bbox[0]],
55+
[bbox[1], bbox[2]],
56+
[bbox[3], bbox[2]],
57+
[bbox[3], bbox[0]]
58+
]);
5759

58-
var bbox = {{ ('extent' in response and response.extent.spatial.bbox.0) or [-180,-90,180,90] }};
59-
var bbox_polygon = L.polygon([
60-
[bbox[1], bbox[0]],
61-
[bbox[1], bbox[2]],
62-
[bbox[3], bbox[2]],
63-
[bbox[3], bbox[0]]
64-
]);
60+
var map = L.map('map').setView([0, 0], 1);
61+
map.addLayer(new L.TileLayer(
62+
'https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
63+
maxZoom: 18,
64+
attribution: 'Map data &copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
65+
}
66+
));
67+
68+
map.addLayer(bbox_polygon);
69+
map.fitBounds(bbox_polygon.getBounds());
70+
} else {
71+
document.getElementById("map").style.display = "none";
72+
}
6573

66-
map.addLayer(bbox_polygon);
67-
map.fitBounds(bbox_polygon.getBounds());
6874
});
6975
</script>
7076

tipg/templates/item.html

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -32,60 +32,65 @@ <h2>Properties</h2>
3232

3333
<script>
3434
var geojson = {{ response|tojson }};
35-
var map = L.map('map').setView([0, 0], 1);
36-
map.addLayer(new L.TileLayer(
37-
'https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
38-
maxZoom: 18,
39-
attribution: 'Map data &copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
40-
}
41-
));
42-
43-
function displayValue(value) {
44-
switch (typeof value) {
45-
case 'string':
46-
return value;
47-
case 'number':
48-
return value.toString();
49-
case 'object':
50-
if (value instanceof Array) {
51-
return value.map(displayValue).join(', ');
52-
} else {
53-
return JSON.stringify(value);
54-
}
55-
default:
56-
return '';
35+
if (geojson.geometry) {
36+
var map = L.map('map').setView([0, 0], 1);
37+
map.addLayer(new L.TileLayer(
38+
'https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
39+
maxZoom: 18,
40+
attribution: 'Map data &copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
41+
}
42+
));
43+
44+
function displayValue(value) {
45+
switch (typeof value) {
46+
case 'string':
47+
return value;
48+
case 'number':
49+
return value.toString();
50+
case 'object':
51+
if (value instanceof Array) {
52+
return value.map(displayValue).join(', ');
53+
} else {
54+
return JSON.stringify(value);
55+
}
56+
default:
57+
return '';
58+
}
5759
}
58-
}
5960

60-
function addPopup(feature, layer) {
61-
if (feature.properties) {
62-
var popupElm = document.createElement('div');
63-
popupElm.style.overflowX = 'scroll';
61+
function addPopup(feature, layer) {
62+
if (feature.properties) {
63+
var popupElm = document.createElement('div');
64+
popupElm.style.overflowX = 'scroll';
6465

65-
Object.keys(geojson.properties).map(prop => {
66-
var propElm = document.createElement('div');
66+
Object.keys(geojson.properties).map(prop => {
67+
var propElm = document.createElement('div');
6768

68-
var bElm = document.createElement('b');
69-
bElm.innerText = prop;
70-
propElm.appendChild(bElm);
71-
var valueElm = document.createTextNode(` : ${displayValue(feature.properties[prop])}`);
72-
propElm.appendChild(valueElm);
69+
var bElm = document.createElement('b');
70+
bElm.innerText = prop;
71+
propElm.appendChild(bElm);
72+
var valueElm = document.createTextNode(` : ${displayValue(feature.properties[prop])}`);
73+
propElm.appendChild(valueElm);
7374

74-
var brElm = document.createElement('br');
75-
propElm.appendChild(brElm);
75+
var brElm = document.createElement('br');
76+
propElm.appendChild(brElm);
7677

77-
popupElm.appendChild(propElm);
78-
})
78+
popupElm.appendChild(propElm);
79+
})
7980

80-
layer.bindPopup(popupElm);
81+
layer.bindPopup(popupElm);
82+
}
8183
}
84+
85+
var features = L.geoJSON(geojson, {
86+
onEachFeature: addPopup
87+
}).addTo(map);
88+
89+
map.fitBounds(features.getBounds());
90+
} else {
91+
document.getElementById("map").style.display = "none";
8292
}
8393

84-
var features = L.geoJSON(geojson, {
85-
onEachFeature: addPopup
86-
}).addTo(map);
87-
88-
map.fitBounds(features.getBounds());
8994
</script>
9095

9196
{% include "footer.html" %}

tipg/templates/items.html

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,32 +84,38 @@ <h1>Collection Items: {{ response.title or response.id }}</h1>
8484
window.location.href = url;
8585
}
8686
$(function() {
87-
8887
//
8988
// mapping
9089
//
9190
var geojson = {{ response|tojson }};
92-
var map = L.map('map').setView([0, 0], 1);
93-
map.addLayer(new L.TileLayer(
94-
'https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
95-
maxZoom: 18,
96-
attribution: 'Map data &copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
91+
92+
var features = (geojson.features) ? geojson.features : [];
93+
var hasGeom = features.some(feat => feat.geometry);
94+
if (hasGeom) {
95+
var map = L.map('map').setView([0, 0], 1);
96+
map.addLayer(new L.TileLayer(
97+
'https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
98+
maxZoom: 18,
99+
attribution: 'Map data &copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>'
100+
}
101+
));
102+
103+
function addPopup(feature, layer) {
104+
var aElm = document.createElement('a');
105+
aElm.setAttribute('href', `${currentURL}/${feature.id}`);
106+
aElm.setAttribute('target', '_blank');
107+
aElm.innerText = feature.id;
108+
layer.bindPopup(aElm);
97109
}
98-
));
99-
100-
function addPopup(feature, layer) {
101-
var aElm = document.createElement('a');
102-
aElm.setAttribute('href', `${currentURL}/${feature.id}`);
103-
aElm.setAttribute('target', '_blank');
104-
aElm.innerText = feature.id;
105-
layer.bindPopup(aElm);
106-
}
107110

108-
var features = L.geoJSON(geojson, {
109-
onEachFeature: addPopup
110-
}).addTo(map);
111+
var features = L.geoJSON(geojson, {
112+
onEachFeature: addPopup
113+
}).addTo(map);
111114

112-
map.fitBounds(features.getBounds());
115+
map.fitBounds(features.getBounds());
116+
} else {
117+
document.getElementById("map").style.display = "none";
118+
}
113119

114120
//
115121
// paging

0 commit comments

Comments
 (0)