Skip to content

Commit a90522c

Browse files
committed
Loading geojson when called
1 parent 8858812 commit a90522c

File tree

2 files changed

+181
-142
lines changed

2 files changed

+181
-142
lines changed

application/routers/entity.py

+117-107
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from fastapi.responses import HTMLResponse, RedirectResponse
1010
from fastapi.exceptions import RequestValidationError
1111
from sqlalchemy.orm import Session
12-
1312
from application.core.models import GeoJSON, EntityModel
1413
from application.data_access.digital_land_queries import (
1514
get_datasets,
@@ -70,6 +69,120 @@ def _get_entity_json(data: List[EntityModel], include: Optional[Set] = None):
7069
return entities
7170

7271

72+
def handle_gone_entity(
73+
request: Request, entity: int, extension: Optional[SuffixEntity]
74+
):
75+
if extension:
76+
raise HTTPException(
77+
detail=f"Entity {entity} has been removed",
78+
status_code=410,
79+
)
80+
return templates.TemplateResponse(
81+
"entity-gone.html",
82+
{"request": request, "entity": str(entity)},
83+
status_code=410,
84+
)
85+
86+
87+
def handle_moved_entity(
88+
entity: int, new_entity_id: int, extension: Optional[SuffixEntity]
89+
):
90+
if extension:
91+
return RedirectResponse(f"/entity/{new_entity_id}.{extension}", status_code=301)
92+
return RedirectResponse(f"/entity/{new_entity_id}", status_code=301)
93+
94+
95+
def prepare_geojson(e):
96+
if e.geojson is not None:
97+
geojson = e.geojson
98+
if geojson:
99+
properties = e.dict(exclude={"geojson", "geometry", "point"}, by_alias=True)
100+
geojson.properties = properties
101+
return geojson
102+
return None
103+
104+
105+
def handle_entity_response(
106+
request: Request, e, extension: Optional[SuffixEntity], session: Session
107+
):
108+
if extension is not None and extension.value == "json":
109+
return e.dict(by_alias=True, exclude={"geojson"})
110+
111+
geojson = None
112+
113+
if extension is not None and extension.value == "geojson":
114+
geojson = prepare_geojson(e)
115+
if geojson:
116+
return geojson
117+
else:
118+
raise HTTPException(
119+
status_code=406, detail="geojson for entity not available"
120+
)
121+
122+
e_dict = e.dict(by_alias=True, exclude={"geojson"})
123+
e_dict_sorted = {
124+
key: e_dict[key] for key in sorted(e_dict.keys(), key=entity_attribute_sort_key)
125+
}
126+
127+
# need to remove any dependency on facts this should be changed when fields added to postgis
128+
fields = None
129+
# get field specifications and convert to dictionary to easily access
130+
# fields = get_field_specifications(e_dict_sorted.keys())
131+
# if fields:
132+
# fields = [field.dict(by_alias=True) for field in fields]
133+
# fields = {field["field"]: field for field in fields}
134+
135+
# get dictionary of fields which have linked datasets
136+
dataset_fields = get_datasets(session, datasets=e_dict_sorted.keys())
137+
dataset_fields = [
138+
dataset_field.dict(by_alias=True) for dataset_field in dataset_fields
139+
]
140+
dataset_fields = [dataset_field["dataset"] for dataset_field in dataset_fields]
141+
142+
dataset = get_dataset_query(session, e.dataset)
143+
organisation_entity, _, _ = get_entity_query(session, e.organisation_entity)
144+
145+
entityLinkFields = [
146+
"article-4-direction",
147+
"permitted-development-rights",
148+
"tree-preservation-order",
149+
]
150+
151+
linked_entities = {}
152+
153+
# for each entityLinkField, if that key exists in the entity dict, then
154+
# lookup the entity and add it to the linked_entities dict
155+
for field in entityLinkFields:
156+
if field in e_dict_sorted:
157+
linked_entity = lookup_entity_link(
158+
session, e_dict_sorted[field], field, e_dict_sorted["dataset"]
159+
)
160+
if linked_entity is not None:
161+
linked_entities[field] = linked_entity
162+
163+
return templates.TemplateResponse(
164+
"entity.html",
165+
{
166+
"request": request,
167+
"row": e_dict_sorted,
168+
"linked_entities": linked_entities,
169+
"entity": e,
170+
"pipeline_name": e.dataset,
171+
"references": [],
172+
"breadcrumb": [],
173+
"schema": None,
174+
"typology": e.typology,
175+
"entity_prefix": "",
176+
"geojson_features": e.geojson if e.geojson is not None else None,
177+
"geojson": geojson.dict() if geojson else None,
178+
"fields": fields,
179+
"dataset_fields": dataset_fields,
180+
"dataset": dataset,
181+
"organisation_entity": organisation_entity,
182+
},
183+
)
184+
185+
73186
def get_entity(
74187
request: Request,
75188
entity: int = Path(default=Required, description="Entity id"),
@@ -79,114 +192,11 @@ def get_entity(
79192
e, old_entity_status, new_entity_id = get_entity_query(session, entity)
80193

81194
if old_entity_status == 410:
82-
if extension:
83-
raise HTTPException(
84-
detail=f"Entity {entity} has been removed",
85-
status_code=410,
86-
)
87-
else:
88-
return templates.TemplateResponse(
89-
"entity-gone.html",
90-
{
91-
"request": request,
92-
"entity": str(entity),
93-
},
94-
status_code=410,
95-
)
195+
return handle_gone_entity(request, entity, extension)
96196
elif old_entity_status == 301:
97-
if extension:
98-
return RedirectResponse(
99-
f"/entity/{new_entity_id}.{extension}", status_code=301
100-
)
101-
else:
102-
return RedirectResponse(f"/entity/{new_entity_id}", status_code=301)
197+
return handle_moved_entity(entity, new_entity_id, extension)
103198
elif e is not None:
104-
if extension is not None and extension.value == "json":
105-
return e.dict(by_alias=True, exclude={"geojson"})
106-
107-
if e.geojson is not None:
108-
geojson = e.geojson
109-
properties = e.dict(exclude={"geojson", "geometry", "point"}, by_alias=True)
110-
geojson.properties = properties
111-
else:
112-
geojson = None
113-
114-
if extension is not None and extension.value == "geojson":
115-
if geojson is not None:
116-
return geojson
117-
else:
118-
raise HTTPException(
119-
status_code=406, detail="geojson for entity not available"
120-
)
121-
122-
e_dict = e.dict(by_alias=True, exclude={"geojson"})
123-
e_dict_sorted = {
124-
key: e_dict[key]
125-
for key in sorted(e_dict.keys(), key=entity_attribute_sort_key)
126-
}
127-
128-
if geojson is not None:
129-
geojson_dict = dict(geojson)
130-
else:
131-
geojson_dict = None
132-
133-
# need to remove any dependency on facts this should be changed when fields added to postgis
134-
fields = None
135-
# get field specifications and convert to dictionary to easily access
136-
# fields = get_field_specifications(e_dict_sorted.keys())
137-
# if fields:
138-
# fields = [field.dict(by_alias=True) for field in fields]
139-
# fields = {field["field"]: field for field in fields}
140-
141-
# get dictionary of fields which have linked datasets
142-
dataset_fields = get_datasets(session, datasets=e_dict_sorted.keys())
143-
dataset_fields = [
144-
dataset_field.dict(by_alias=True) for dataset_field in dataset_fields
145-
]
146-
dataset_fields = [dataset_field["dataset"] for dataset_field in dataset_fields]
147-
148-
dataset = get_dataset_query(session, e.dataset)
149-
organisation_entity, _, _ = get_entity_query(session, e.organisation_entity)
150-
151-
entityLinkFields = [
152-
"article-4-direction",
153-
"permitted-development-rights",
154-
"tree-preservation-order",
155-
]
156-
157-
linked_entities = {}
158-
159-
# for each entityLinkField, if that key exists in the entity dict, then
160-
# lookup the entity and add it to the linked_entities dict
161-
for field in entityLinkFields:
162-
if field in e_dict_sorted:
163-
linked_entity = lookup_entity_link(
164-
session, e_dict_sorted[field], field, e_dict_sorted["dataset"]
165-
)
166-
if linked_entity is not None:
167-
linked_entities[field] = linked_entity
168-
169-
return templates.TemplateResponse(
170-
"entity.html",
171-
{
172-
"request": request,
173-
"row": e_dict_sorted,
174-
"linked_entities": linked_entities,
175-
"entity": e,
176-
"pipeline_name": e.dataset,
177-
"references": [],
178-
"breadcrumb": [],
179-
"schema": None,
180-
"typology": e.typology,
181-
"entity_prefix": "",
182-
"geojson_features": e.geojson if e.geojson is not None else None,
183-
"geojson": geojson_dict,
184-
"fields": fields,
185-
"dataset_fields": dataset_fields,
186-
"dataset": dataset,
187-
"organisation_entity": organisation_entity,
188-
},
189-
)
199+
return handle_entity_response(request, e, extension, session)
190200
else:
191201
raise HTTPException(status_code=404, detail="entity not found")
192202

application/templates/entity.html

+64-35
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,26 @@ <h1 class="govuk-heading-xl">{{ row_name }}</h1>
6363
<tbody class="govuk-table__body">
6464
{% for field in row.keys() %}
6565
{% if field != 'entity' %}
66-
{%- if field not in ["geometry","point","organisation-entity","json"] or row[field] is not none %}
66+
{%- if field not in ["organisation-entity", "json"] %}
6767
<tr class="govuk-table__row">
6868
<th scope="row" class="app-table__header app-table__header--row">
69-
{{ entityField(field,fields,dataset_fields) }}
69+
{{ entityField(field, fields, dataset_fields) }}
7070
</th>
7171
<td class="govuk-table__cell app-table__cell">
72-
{{ entityValue(field,row[field],fields,dataset_fields,organisation_entity,linked_entities)}}
72+
{% if field == 'geometry' %}
73+
<div id="geometry-content">
74+
{{ row[field][:200] }}{% if row[field]|length > 200 %}...<a href="javascript:void(0);" onclick="expandGeometry()">Load More</a>{% endif %}
75+
</div>
76+
<div id="geometry-full-content" style="display: none;">
77+
{{ row[field] }}
78+
</div>
79+
{% else %}
80+
{{ entityValue(field, row[field], fields, dataset_fields, organisation_entity, linked_entities) }}
81+
{% endif %}
7382
</td>
74-
{% if field is not in['dataset','organisation-entity','start-date','end-date','typology'] %}
83+
{% if field not in ['dataset', 'organisation-entity', 'start-date', 'end-date', 'typology'] %}
7584
<td class="govuk-table__cell govuk-!-font-size-14 govuk-!-text-align-right">
76-
<a href="/fact?dataset={{row['dataset']}}&entity={{row['entity']}}&field={{field}}" class="govuk-link">Facts</a>
85+
<a href="/fact?dataset={{ row['dataset'] }}&entity={{ row['entity'] }}&field={{ field }}" class="govuk-link">Facts</a>
7786
</td>
7887
{% else %}
7988
<td class="govuk-table__cell govuk-!-font-size-14 govuk-!-text-align-right"><span class='govuk-visually-hidden'>no fact link</span></td>
@@ -83,45 +92,41 @@ <h1 class="govuk-heading-xl">{{ row_name }}</h1>
8392
{% endif %}
8493
{% endfor %}
8594
</tbody>
95+
96+
<script>
97+
function expandGeometry() {
98+
document.getElementById('geometry-content').style.display = 'none';
99+
document.getElementById('geometry-full-content').style.display = 'block';
100+
}
101+
</script>
102+
86103
</table>
87104
{% endcall %}
88105

89106
{% set jsonHTML %}
90107
<pre class="govuk-!-margin-0"><code class="language-json app-code-block app-code-block-overflow" tabindex="0">{{row|digital_land_to_json}}</code></pre>
91108
{% endset %}
92109
{% set geojsonHTML %}
93-
<pre class="govuk-!-margin-0"><code class="language-json app-code-block app-code-block-overflow" tabindex="0">{{geojson|digital_land_to_json}}</code></pre>
94-
{% endset %}
95-
96-
{% if geojson %}
97-
{% set params = {
98-
"title":"Available Code Snippets:",
99-
"items":[
100-
{
101-
"label":"JSON","id":"json","panel":{
102-
"html":jsonHTML
103-
}
104-
},
105-
{
106-
"label":"GeoJSON","id":"geojson","panel":{
107-
"html":geojsonHTML
108-
}
110+
<pre class="govuk-!-margin-0"><code class="language-json app-code-block app-code-block-overflow" id="geojson-content" tabindex="0">Loading...</code></pre>
111+
<button id="load-more-button" class="govuk-button" style="display:none;">Load More</button>
112+
{% endset %}
113+
114+
{% set params = {
115+
"title":"Available Code Snippets:",
116+
"items":[
117+
{
118+
"label":"JSON","id":"json","panel":{
119+
"html":jsonHTML
109120
}
110-
],
111-
"classes": "govuk-tabs--entity govuk-!-margin-bottom-0"
112-
} %}
113-
{% else %}
114-
{% set params = {
115-
"items":[
116-
{
117-
"label":"JSON","id":"json","panel":{
118-
"html":jsonHTML
119-
}
121+
},
122+
{
123+
"label":"GeoJSON","id":"geojson","panel":{
124+
"html":geojsonHTML
120125
}
121-
],
122-
"classes": "govuk-tabs--entity govuk-!-margin-bottom-0"
123-
} %}
124-
{% endif %}
126+
}
127+
],
128+
"classes": "govuk-tabs--entity govuk-!-margin-bottom-0"
129+
} %}
125130
{{ govukTabs(params) }}
126131

127132
{% if dataset %}
@@ -215,4 +220,28 @@ <h3 class="govuk-heading-s">{{ type|capitalize }}</h3>
215220

216221
{%- block pageScripts %}
217222

223+
{% set geojson_url = "/entity/" + row["entity"] | string + "?extension=geojson" %}
224+
{% set geojson_string = geojson|digital_land_to_json %}
225+
<script>
226+
document.addEventListener('DOMContentLoaded', function () {
227+
document.querySelector('#tab_geojson').addEventListener('click', function () {
228+
// Check if the content is already loaded
229+
const geojsonContentElement = document.getElementById('geojson-content');
230+
if (geojsonContentElement && geojsonContentElement.textContent === 'Loading...') {
231+
// Fetch the GeoJSON content
232+
fetch('{{ geometry_url }}')
233+
.then(response => {
234+
return response.text();
235+
})
236+
.then(data => {
237+
geojsonContentElement.textContent = data
238+
})
239+
.catch(error => {
240+
console.error('Error loading GeoJSON:', error);
241+
geojsonContentElement.textContent = 'Error loading GeoJSON content';
242+
});
243+
}
244+
});
245+
});
246+
</script>
218247
{%- endblock %}

0 commit comments

Comments
 (0)