Show map on details page

Includes pin and polygon

Closes: #4
This commit is contained in:
Edward Betts 2023-11-03 10:32:18 +00:00
parent d24744bc29
commit a6286cb05f
4 changed files with 74 additions and 5 deletions

View file

@ -14,7 +14,7 @@ from sqlalchemy.types import Float, Integer, Numeric, String
from .database import session from .database import session
Base = declarative_base() Base = declarative_base()
Base.query = session.query_property() # type:ignore Base.query = session.query_property()
class Polygon(Base): class Polygon(Base):
@ -30,6 +30,9 @@ class Polygon(Base):
tags = Column(postgresql.HSTORE) tags = Column(postgresql.HSTORE)
way = Column(Geometry("GEOMETRY", srid=4326, spatial_index=True), nullable=False) way = Column(Geometry("GEOMETRY", srid=4326, spatial_index=True), nullable=False)
area = column_property(func.ST_Area(way, False)) area = column_property(func.ST_Area(way, False))
geojson_str = column_property(
func.ST_AsGeoJSON(way, maxdecimaldigits=6), deferred=True
)
@property @property
def osm_url(self) -> str: def osm_url(self) -> str:
@ -48,7 +51,7 @@ class Polygon(Base):
) -> sqlalchemy.orm.query.Query: # type: ignore ) -> sqlalchemy.orm.query.Query: # type: ignore
"""Polygons that contain given coordinates.""" """Polygons that contain given coordinates."""
point = func.ST_SetSRID(func.ST_MakePoint(lon, lat), 4326) point = func.ST_SetSRID(func.ST_MakePoint(lon, lat), 4326)
q = cls.query.filter( # type: ignore q = cls.query.filter(
or_( or_(
cls.boundary == "political", cls.boundary == "political",
and_( and_(

View file

@ -189,6 +189,7 @@ def build_dict(hit: Hit | None, lat: str | float, lon: str | float) -> WikidataD
"admin_level": hit.get("admin_level"), "admin_level": hit.get("admin_level"),
"wikidata": hit["wikidata"], "wikidata": hit["wikidata"],
"element": hit.get("element"), "element": hit.get("element"),
"geojson": hit.get("geojson"),
} }
if not commons_cat: if not commons_cat:
return ret return ret

View file

@ -105,6 +105,7 @@ def osm_lookup(
"commons_cat": commons, "commons_cat": commons,
"admin_level": admin_level, "admin_level": admin_level,
"element": e.osm_id, "element": e.osm_id,
"geojson": typing.cast(str, e.geojson_str),
} }
gss = tags.get("ref:gss") gss = tags.get("ref:gss")
if gss: if gss:
@ -112,6 +113,7 @@ def osm_lookup(
if ret: if ret:
ret["admin_level"] = admin_level ret["admin_level"] = admin_level
ret["element"] = e.osm_id ret["element"] = e.osm_id
ret["geojson"] = typing.cast(str, e.geojson_str)
return ret return ret
name = tags.get("name") name = tags.get("name")
@ -162,6 +164,7 @@ def index() -> str | Response:
if lat is not None and lon is not None: if lat is not None and lon is not None:
result = lat_lon_to_wikidata(lat, lon)["result"] result = lat_lon_to_wikidata(lat, lon)["result"]
result.pop("element", None) result.pop("element", None)
result.pop("geojson", None)
return jsonify(result) return jsonify(result)
samples = sorted(geocode.samples, key=lambda row: row[2]) samples = sorted(geocode.samples, key=lambda row: row[2])
@ -219,9 +222,16 @@ def detail_page() -> Response | str:
return render_template("query_error.html", lat=lat, lon=lon, query=query, r=r) return render_template("query_error.html", lat=lat, lon=lon, query=query, r=r)
element = reply["result"].pop("element", None) element = reply["result"].pop("element", None)
geojson = reply["result"].pop("geojson", None)
return render_template( return render_template(
"detail.html", lat=lat, lon=lon, str=str, element_id=element, **reply "detail.html",
lat=lat,
lon=lon,
str=str,
element_id=element,
geojson=geojson,
**reply
) )

View file

@ -2,8 +2,64 @@
{% block title %}Geocode to Commons{% endblock %} {% block title %}Geocode to Commons{% endblock %}
{% block link %}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""/>
{% endblock %}
{% block script %}
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""></script>
<script>
var map = L.map('map').setView([{{ lat }}, {{ lon }}], 13);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
var marker = L.marker([{{ lat }} , {{ lon }}]).addTo(map);
{% if geojson %}
L.geoJSON({{ geojson | safe }}).addTo(map);
{% endif %}
</script>
{% endblock %}
{% block style %}
<style>
/*
#map {
width: 600px;
height: 600px;
}
*/
/* Styles for the map */
#map {
position: fixed; /* This keeps the map in place when the page is scrolled */
top: 0; /* Starting from the top edge of the browser window */
right: 0; /* Positioned on the right side */
width: 50%; /* Half the screen width */
height: 100%; /* Full height of the browser window */
}
#main {
width: 48%
}
</style>
{% endblock %}
{% block content %} {% block content %}
<div class="m-3"> <div id="map"></div>
<div class="m-3" id="main">
<h1>Geocode coordinates to Commons Category</h1> <h1>Geocode coordinates to Commons Category</h1>
<p><a href="{{ url_for('index', lat=lat, lon=lon) }}">visit endpoint</a> <p><a href="{{ url_for('index', lat=lat, lon=lon) }}">visit endpoint</a>
@ -48,6 +104,5 @@
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
{% endblock %} {% endblock %}