[#40] Address search #89
2 changed files with 55 additions and 3 deletions
|
@ -8,7 +8,7 @@ from right_tree.api.models import Habitat, HabitatImage, Plant, EcologicalDistri
|
||||||
from right_tree.api.serializers import HabitatImageSerializer, HabitatSerializer, PlantSerializer, SoilOrderSerializer, EcologicalDistrictLayerSerializer, AddressSerializer, ZoneSerializer
|
from right_tree.api.serializers import HabitatImageSerializer, HabitatSerializer, PlantSerializer, SoilOrderSerializer, EcologicalDistrictLayerSerializer, AddressSerializer, ZoneSerializer
|
||||||
|
|
||||||
from .filters import *
|
from .filters import *
|
||||||
from .wms_utils import get_address_from_coordinates
|
from .wms_utils import get_address_from_coordinates, search_address
|
||||||
from .resource_generation_utils import create_plant_csv_file, get_plant_resource_filepath, create_planting_guide_pdf, PLANTING_GUIDE_PDF_FILENAME
|
from .resource_generation_utils import create_plant_csv_file, get_plant_resource_filepath, create_planting_guide_pdf, PLANTING_GUIDE_PDF_FILENAME
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,12 +61,17 @@ class LINZPropertyViewSet(viewsets.ViewSet):
|
||||||
|
|
||||||
def list(self, request):
|
def list(self, request):
|
||||||
coordinates = self.request.query_params.get('coordinates')
|
coordinates = self.request.query_params.get('coordinates')
|
||||||
if coordinates is not None:
|
address = self.request.query_params.get('search')
|
||||||
|
|
||||||
|
if address is not None:
|
||||||
|
results = search_address(address)
|
||||||
|
return Response(results)
|
||||||
|
elif coordinates is not None:
|
||||||
address_data = get_address_from_coordinates(coordinates)
|
address_data = get_address_from_coordinates(coordinates)
|
||||||
serializer = AddressSerializer(address_data)
|
serializer = AddressSerializer(address_data)
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
else:
|
else:
|
||||||
return HttpResponseBadRequest("No coordinate given.")
|
return HttpResponseBadRequest("No parameters given.")
|
||||||
|
|
||||||
class AuckCHCHRegionInformation(viewsets.ViewSet):
|
class AuckCHCHRegionInformation(viewsets.ViewSet):
|
||||||
""" Filtered viewset defining if coordinate falls inside auckland and chch regions.
|
""" Filtered viewset defining if coordinate falls inside auckland and chch regions.
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import requests
|
import requests
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
from unicodedata import normalize
|
||||||
|
|
||||||
from django.contrib.gis.geos import Point, GEOSGeometry
|
from django.contrib.gis.geos import Point, GEOSGeometry
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -12,6 +14,10 @@ PROPERTY_TILE_LAYER = "layer-50804"
|
||||||
PROPERTY_INFO_LAYER = "layer-53353"
|
PROPERTY_INFO_LAYER = "layer-53353"
|
||||||
|
|
||||||
|
|
||||||
|
search_num = re.compile(r'((?<!\S)\d+)')
|
||||||
|
search_str = re.compile(r'((?<!\S)[a-zA-Z\-]+)')
|
||||||
|
|
||||||
|
|
||||||
class WFSError(Exception):
|
class WFSError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -85,3 +91,44 @@ def get_address_from_coordinates(coordinates):
|
||||||
if propertyPolygon is not None:
|
if propertyPolygon is not None:
|
||||||
prop_geom = GEOSGeometry(json.dumps(propertyPolygon['geometry']))
|
prop_geom = GEOSGeometry(json.dumps(propertyPolygon['geometry']))
|
||||||
return get_address(prop_geom)
|
return get_address(prop_geom)
|
||||||
|
|
||||||
|
|
||||||
|
def search_address(address):
|
||||||
|
|
||||||
|
# normalize accent characters etc.
|
||||||
|
address = normalize(
|
||||||
|
"NFKD",
|
||||||
|
address.strip().lower(),
|
||||||
|
).encode("ascii", "ignore").decode()
|
||||||
|
|
||||||
|
nums = search_num.findall(address)
|
||||||
|
strings = search_str.findall(address)
|
||||||
|
|
||||||
|
num_terms = [f"address_number = {n}" for n in nums]
|
||||||
|
string_terms = []
|
||||||
|
|
||||||
|
for s in strings:
|
||||||
|
string_terms += [
|
||||||
|
f"full_road_name_ascii ILIKE '{s}%'",
|
||||||
|
f"town_city_ascii ILIKE '{s}%'",
|
||||||
|
f"suburb_locality_ascii ILIKE '{s}%'",
|
||||||
|
]
|
||||||
|
|
||||||
|
num_expr = " OR ".join(f"({term})" for term in num_terms)
|
||||||
|
string_expr = " OR ".join(f"({term})" for term in string_terms)
|
||||||
|
|
||||||
|
cql_filter = f"({num_expr}) AND ({string_expr})"
|
||||||
|
|
||||||
|
resp = linz_wfs_getfeature(
|
||||||
|
typeNames=PROPERTY_INFO_LAYER,
|
||||||
|
cql_filter=cql_filter,
|
||||||
|
count=10,
|
||||||
|
)
|
||||||
|
features = resp.get("features", [])
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'coordinates': feature['geometry']['coordinates'],
|
||||||
|
'address': feature['properties']['full_address'],
|
||||||
|
} for feature in features
|
||||||
|
]
|
||||||
|
|
Loading…
Reference in a new issue