|
|
|
@@ -9,16 +9,14 @@ import json
|
|
|
|
|
from json import JSONDecodeError
|
|
|
|
|
|
|
|
|
|
import requests
|
|
|
|
|
from django.contrib.gis import gdal
|
|
|
|
|
from django.contrib.gis.geos import GEOSGeometry
|
|
|
|
|
|
|
|
|
|
from konova.sub_settings import schneider_settings
|
|
|
|
|
from konova.sub_settings.lanis_settings import DEFAULT_SRID
|
|
|
|
|
from konova.sub_settings.proxy_settings import PROXIES
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ParcelFetcher:
|
|
|
|
|
base_url = schneider_settings.base_url
|
|
|
|
|
auth_header = schneider_settings.auth_header
|
|
|
|
|
auth_header_token = schneider_settings.auth_header_token
|
|
|
|
|
|
|
|
|
|
geometry = None
|
|
|
|
@@ -30,30 +28,47 @@ class ParcelFetcher:
|
|
|
|
|
raise AssertionError("Geometry must not be none")
|
|
|
|
|
self.geometry = geometry
|
|
|
|
|
|
|
|
|
|
# Reduce size of geometry to avoid "intersections" because of exact border matching
|
|
|
|
|
buffer_threshold = 0.001
|
|
|
|
|
geom = geometry.geom.buffer(-buffer_threshold)
|
|
|
|
|
if geom.area < buffer_threshold:
|
|
|
|
|
# Fallback for malicious geometries which are way too small and would disappear on negative buffering
|
|
|
|
|
geom = geometry.geom
|
|
|
|
|
try:
|
|
|
|
|
geom.transform(DEFAULT_SRID)
|
|
|
|
|
except gdal.GDALException as e:
|
|
|
|
|
raise ValueError(f"{str(e)}\nCould not transform geometry (id: {geometry.id}) to {DEFAULT_SRID}:\n {geom.geojson}")
|
|
|
|
|
self.geojson = geom.ewkt
|
|
|
|
|
geom = self._shrink_geometry(geometry.geom)
|
|
|
|
|
|
|
|
|
|
self.geojson = geom.geojson
|
|
|
|
|
self.results = []
|
|
|
|
|
|
|
|
|
|
def get_parcels(self, url: str = None):
|
|
|
|
|
post_url = url
|
|
|
|
|
if post_url is None:
|
|
|
|
|
post_url = f"{self.base_url}/parcel/intersect/"
|
|
|
|
|
def _shrink_geometry(self, geometry: GEOSGeometry) -> GEOSGeometry:
|
|
|
|
|
""" Shrink geometry by a minimal factor to avoid intersections with neighboring features due to
|
|
|
|
|
exact outline match.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
geometry (GEOSGeometry): geometry to shrink
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
geom (GEOSGeometry): Shrinked geometry
|
|
|
|
|
"""
|
|
|
|
|
# Reduce size of geometry to avoid "intersections" because of exact border matching
|
|
|
|
|
buffer_threshold = 0.001
|
|
|
|
|
return_geom = geometry.buffer(-buffer_threshold)
|
|
|
|
|
if return_geom.area < buffer_threshold:
|
|
|
|
|
# Fallback for malicious geometries which are way too small and would disappear on negative buffering
|
|
|
|
|
return_geom = geometry
|
|
|
|
|
return return_geom
|
|
|
|
|
|
|
|
|
|
def get_parcels(self, url: str = None) -> list:
|
|
|
|
|
""" Perform parcel fetching
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
url (None|str): (optional) Provide an alternative url for fetching parcels. Default will be used if None
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
results (list): List of fetched parcels
|
|
|
|
|
"""
|
|
|
|
|
if url is None:
|
|
|
|
|
url = f"{self.base_url}/parcel/intersect/"
|
|
|
|
|
|
|
|
|
|
response = requests.post(
|
|
|
|
|
url=post_url,
|
|
|
|
|
url=url,
|
|
|
|
|
proxies=PROXIES,
|
|
|
|
|
data=self.geojson,
|
|
|
|
|
headers={
|
|
|
|
|
self.auth_header: self.auth_header_token
|
|
|
|
|
"Authorization": f"Bearer {self.auth_header_token}"
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|