Match on boundary=political
This commit is contained in:
parent
41a34856b8
commit
6e6a31298a
|
@ -1,8 +1,9 @@
|
||||||
"""Database model."""
|
"""Database model."""
|
||||||
|
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
|
import sqlalchemy.orm.query
|
||||||
from geoalchemy2 import Geometry
|
from geoalchemy2 import Geometry
|
||||||
from sqlalchemy import cast, func
|
from sqlalchemy import and_, cast, func, or_
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.ext.hybrid import hybrid_property
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
|
@ -13,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()
|
Base.query = session.query_property() # type:ignore
|
||||||
|
|
||||||
|
|
||||||
class Polygon(Base):
|
class Polygon(Base):
|
||||||
|
@ -23,6 +24,7 @@ class Polygon(Base):
|
||||||
|
|
||||||
osm_id = Column(Integer, primary_key=True, autoincrement=False)
|
osm_id = Column(Integer, primary_key=True, autoincrement=False)
|
||||||
admin_level = Column(String)
|
admin_level = Column(String)
|
||||||
|
boundary = Column(String)
|
||||||
|
|
||||||
way_area = Column(Float)
|
way_area = Column(Float)
|
||||||
tags = Column(postgresql.HSTORE)
|
tags = Column(postgresql.HSTORE)
|
||||||
|
@ -43,15 +45,20 @@ class Polygon(Base):
|
||||||
@classmethod
|
@classmethod
|
||||||
def coords_within(
|
def coords_within(
|
||||||
cls, lat: str | float, lon: str | float
|
cls, lat: str | float, lon: str | float
|
||||||
) -> sqlalchemy.orm.query.Query["Polygon"]:
|
) -> 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: sqlalchemy.orm.query.Query["Polygon"] = cls.query.filter(
|
q = cls.query.filter( # type: ignore
|
||||||
cls.admin_level.isnot(None),
|
or_(
|
||||||
cls.admin_level.regexp_match("^\d+$"),
|
cls.boundary == "political",
|
||||||
|
and_(
|
||||||
|
cls.admin_level.isnot(None), # type: ignore
|
||||||
|
cls.admin_level.regexp_match(r"^\d+$"), # type: ignore
|
||||||
|
),
|
||||||
|
),
|
||||||
func.ST_Within(point, cls.way),
|
func.ST_Within(point, cls.way),
|
||||||
).order_by(cls.area, cast(cls.admin_level, Integer).desc())
|
).order_by(cls.area, cast(cls.admin_level, Integer).desc())
|
||||||
return q
|
return q # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class Scotland(Base):
|
class Scotland(Base):
|
||||||
|
|
|
@ -107,6 +107,7 @@ def geosearch(lat: str | float, lon: str | float) -> Row | None:
|
||||||
"Q5084": 1, # hamlet
|
"Q5084": 1, # hamlet
|
||||||
"Q515": 2, # city
|
"Q515": 2, # city
|
||||||
"Q1549591": 3, # big city
|
"Q1549591": 3, # big city
|
||||||
|
"Q589282": 2, # ward or electoral division of the United Kingdom
|
||||||
}
|
}
|
||||||
for row in rows:
|
for row in rows:
|
||||||
isa = wd_uri_to_qid(row["isa"]["value"])
|
isa = wd_uri_to_qid(row["isa"]["value"])
|
||||||
|
|
|
@ -66,7 +66,6 @@ def lat_lon_to_wikidata(lat: str | float, lon: str | float) -> dict[str, typing.
|
||||||
return {"elements": elements, "result": result}
|
return {"elements": elements, "result": result}
|
||||||
|
|
||||||
admin_level = result.get("admin_level")
|
admin_level = result.get("admin_level")
|
||||||
assert isinstance(admin_level, int)
|
|
||||||
|
|
||||||
if not admin_level or admin_level >= 7:
|
if not admin_level or admin_level >= 7:
|
||||||
return {"elements": elements, "result": result}
|
return {"elements": elements, "result": result}
|
||||||
|
|
Loading…
Reference in a new issue