[#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 .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
|
||||
|
||||
|
||||
|
@ -61,12 +61,17 @@ class LINZPropertyViewSet(viewsets.ViewSet):
|
|||
|
||||
def list(self, request):
|
||||
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)
|
||||
serializer = AddressSerializer(address_data)
|
||||
return Response(serializer.data)
|
||||
else:
|
||||
return HttpResponseBadRequest("No coordinate given.")
|
||||
return HttpResponseBadRequest("No parameters given.")
|
||||
|
||||
class AuckCHCHRegionInformation(viewsets.ViewSet):
|
||||
""" Filtered viewset defining if coordinate falls inside auckland and chch regions.
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import json
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
from urllib.parse import urlencode
|
||||
from unicodedata import normalize
|
||||
|
||||
from django.contrib.gis.geos import Point, GEOSGeometry
|
||||
from django.conf import settings
|
||||
|
@ -12,6 +14,10 @@ PROPERTY_TILE_LAYER = "layer-50804"
|
|||
PROPERTY_INFO_LAYER = "layer-53353"
|
||||
|
||||
|
||||
search_num = re.compile(r'((?<!\S)\d+)')
|
||||
search_str = re.compile(r'((?<!\S)[a-zA-Z\-]+)')
|
||||
|
||||
|
||||
class WFSError(Exception):
|
||||
pass
|
||||
|
||||
|
@ -85,3 +91,44 @@ def get_address_from_coordinates(coordinates):
|
|||
if propertyPolygon is not None:
|
||||
prop_geom = GEOSGeometry(json.dumps(propertyPolygon['geometry']))
|
||||
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