293 lines
9.5 KiB
Python
293 lines
9.5 KiB
Python
import unicodedata
|
|
|
|
import pyproj
|
|
import requests
|
|
from django.http import HttpResponseBadRequest
|
|
from django.shortcuts import redirect
|
|
from django.utils.encoding import force_text
|
|
from django.views.generic.base import RedirectView, View
|
|
from django.views.generic.detail import DetailView, SingleObjectMixin
|
|
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
|
from passerelle import utils
|
|
|
|
from .forms import MontpellierSigForm
|
|
from .models import MontpellierSig
|
|
|
|
prefix_map = {
|
|
'ALL': 'ALLEE',
|
|
'AUTO': 'AUTOROUTE',
|
|
'AV': 'AVENUE',
|
|
'BASS': 'BASSIN',
|
|
'BD': 'BOULEVARD',
|
|
'CAR': 'CARREFOUR',
|
|
'CHE': 'CHEMIN',
|
|
'COUR': 'COUR',
|
|
'CRS': 'COURS',
|
|
'DESC': 'DESCENTE',
|
|
'DOM': 'DOMAINE',
|
|
'ENCL': 'ENCLOS',
|
|
'ESP': 'ESPLANADE',
|
|
'ESPA': 'ESPACE',
|
|
'GR': '', # "GR GRAND-RUE JEAN MOULIN"
|
|
'IMP': 'IMPASSE',
|
|
'JARD': 'JARDIN',
|
|
'MAIL': '', # "MAIL LE GRAND MAIL"
|
|
'PARC': 'PARC',
|
|
'PARV': '', # "PARV PARVIS DE LA LEGION D HONNEUR"
|
|
'PAS': 'PASSAGE',
|
|
'PL': 'PLACE',
|
|
'PLAN': 'PLAN',
|
|
'PONT': 'PONT',
|
|
'QUA': 'QUAI',
|
|
'R': 'RUE',
|
|
'RAMB': '', # "RAMB RAMBLA DES CALISSONS"
|
|
'RPT': 'ROND-POINT',
|
|
'RTE': 'ROUTE',
|
|
'SQ': 'SQUARE',
|
|
'TSSE': '', # "TSSE TERRASSE DES ALLEES DU BOIS"
|
|
'TUN': 'TUNNEL',
|
|
'VIAD': 'VIADUC',
|
|
'VOI': 'VOIE',
|
|
}
|
|
|
|
|
|
def prefix_cleanup(name):
|
|
if not name:
|
|
return ''
|
|
name = name.strip()
|
|
for prefix, full in prefix_map.items():
|
|
if name.startswith(prefix + ' '):
|
|
name = (full + name[len(prefix) :]).strip()
|
|
return name
|
|
|
|
|
|
def get_original_prefix(name):
|
|
if not name:
|
|
return ''
|
|
name = name.strip()
|
|
for prefix, full in prefix_map.items():
|
|
if name.startswith(full + ' '):
|
|
name = (prefix + name[len(full) :]).strip()
|
|
return name.upper()
|
|
|
|
|
|
def split_street(name):
|
|
if not name:
|
|
return '', ''
|
|
name = name.strip()
|
|
for prefix, full in prefix_map.items():
|
|
prefix += ' '
|
|
if prefix in name:
|
|
index, name = name.split(prefix)
|
|
index = index.strip()
|
|
name = prefix_cleanup(prefix + name)
|
|
return index, name
|
|
|
|
|
|
class SigDetailView(DetailView):
|
|
model = MontpellierSig
|
|
|
|
|
|
COMMUNES = [
|
|
('34022', 'BAILLARGUES'),
|
|
('34027', 'BEAULIEU'),
|
|
('34057', 'CASTELNAU LE LEZ'),
|
|
('34058', 'CASTRIES'),
|
|
('34077', 'CLAPIERS'),
|
|
('34087', 'COURNONSEC'),
|
|
('34088', 'COURNONTERRAL'),
|
|
('34090', 'LE CRES'),
|
|
('34095', 'FABREGUES'),
|
|
('34116', 'GRABELS'),
|
|
('34120', 'JACOU'),
|
|
('34123', 'JUVIGNAC'),
|
|
('34129', 'LATTES'),
|
|
('34134', 'LAVERUNE'),
|
|
('34164', 'MONTAUD'),
|
|
('34169', 'MONTFERRIER-SUR-LEZ'),
|
|
('34172', 'MONTPELLIER'),
|
|
('34179', 'MURVIEL-LES-MONTPELLIER'),
|
|
('34198', 'PEROLS'),
|
|
('34202', 'PIGNAN'),
|
|
('34217', 'PRADES-LE-LEZ'),
|
|
('34227', 'RESTINCLIERES'),
|
|
('34244', 'SAINT-BRES'),
|
|
('34249', 'SAINT-DREZERY'),
|
|
('34256', 'SAINT-GENIES-DES-MOURGUES'),
|
|
('34259', 'SAINT GEORGES D ORQUES'),
|
|
('34270', 'SAINT-JEAN-DE-VEDAS'),
|
|
('34295', 'SAUSSAN'),
|
|
('34307', 'SUSSARGUES'),
|
|
('34327', 'VENDARGUES'),
|
|
('34337', 'VILLENEUVE-LES-MAGUELONE'),
|
|
]
|
|
|
|
|
|
class CommunesView(View, SingleObjectMixin):
|
|
model = MontpellierSig
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
communes = COMMUNES
|
|
if 'q' in request.GET:
|
|
communes = [x for x in communes if request.GET['q'].upper() in x[1]]
|
|
communes = [{'id': x[0], 'text': x[1]} for x in communes]
|
|
return utils.response_for_json(request, {'data': communes})
|
|
|
|
|
|
class VoiesView(View, SingleObjectMixin):
|
|
model = MontpellierSig
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
insee = kwargs['insee']
|
|
result = self.get_object().sig_request('commune/' + insee + '/voie')
|
|
voies = []
|
|
if isinstance(result, dict) and result.get('error'):
|
|
return utils.response_for_json(request, {'data': voies})
|
|
for i in result:
|
|
voie = i['attributes']['nom_voie']
|
|
if 'id' in request.GET and voie != request.GET['id']:
|
|
continue
|
|
voies.append({'id': voie, 'text': prefix_cleanup(voie)})
|
|
|
|
if 'q' in request.GET and request.GET['q']:
|
|
q = request.GET['q'].upper()
|
|
q = q.replace("'", ' ')
|
|
q = unicodedata.normalize('NFKD', q).encode('ascii', 'ignore')
|
|
q = force_text(q)
|
|
voies = [v for v in voies if q in v['text']]
|
|
|
|
voies.sort(key=lambda x: x['id'])
|
|
return utils.response_for_json(request, {'data': voies})
|
|
|
|
|
|
class VoiesCommuneView(View, SingleObjectMixin):
|
|
"""
|
|
Called service
|
|
$ curl .../adresse/rest/commune/34057/voie/ALL DES CONDAMINES/numero
|
|
Expected result when called with no street number:
|
|
[{"attributes": {"nom_voie": "ALL DES CONDAMINES", "numero": 8}, ...]
|
|
When called with street number:
|
|
$ curl .../adresse/rest/commune/34057/voie/ALL DES CONDAMINES/numero/8
|
|
Expected result:
|
|
[{"geometry": {"y": 6281724.800000001, "x": 773304.5},
|
|
"attributes": {"numero": 8, "nom_voie": "ALL DES CONDAMINES"}},
|
|
...]
|
|
"""
|
|
|
|
model = MontpellierSig
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
insee = kwargs['insee']
|
|
nom_rue = get_original_prefix(kwargs['nom_rue'])
|
|
if 'q' in request.GET:
|
|
result = self.get_object().sig_request(
|
|
'commune/' + insee + '/voie/' + nom_rue + '/numero/' + request.GET['q']
|
|
)
|
|
else:
|
|
result = self.get_object().sig_request('commune/' + insee + '/voie/' + nom_rue + '/numero')
|
|
voies_communes = []
|
|
if isinstance(result, dict) and result.get('error'):
|
|
return utils.response_for_json(request, {'data': voies_communes})
|
|
for i in result:
|
|
attrs = i['attributes']
|
|
voie = {'id': '%(numero)s %(nom_voie)s' % attrs, 'text': '%(numero)s %(nom_voie)s' % attrs}
|
|
if i.get('geometry'):
|
|
voie.update({'x': i['geometry'].get('x'), 'y': i['geometry'].get('y')})
|
|
voies_communes.append(voie)
|
|
voies_communes.sort(key=lambda x: x['id'])
|
|
return utils.response_for_json(request, {'data': voies_communes})
|
|
|
|
|
|
class VoieCommuneView(View, SingleObjectMixin):
|
|
model = MontpellierSig
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
result = self.get_object().sig_request('voiecommune/' + kwargs['nom_rue'])
|
|
voies_communes = []
|
|
if isinstance(result, dict) and result.get('error'):
|
|
return utils.response_for_json(request, {'data': voies_communes})
|
|
for i in result:
|
|
attrs = i['attributes']
|
|
voies_communes.append(
|
|
{
|
|
'id': '%(nom_voie)s' % attrs,
|
|
'text': '%(nom_voie)s' % attrs,
|
|
'commune': attrs['commune'],
|
|
'insee': attrs['code_insee'],
|
|
}
|
|
)
|
|
voies_communes.sort(key=lambda x: x['insee'])
|
|
return utils.response_for_json(request, {'data': voies_communes})
|
|
|
|
|
|
class AdresseView(View, SingleObjectMixin):
|
|
model = MontpellierSig
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
lat = request.GET.get('lat')
|
|
lon = request.GET.get('lon')
|
|
# WGS84: epsg:4326
|
|
wgs84 = pyproj.Proj(init='epsg:4326')
|
|
# Lambert93: epsg:2154
|
|
lambert93 = pyproj.Proj(init='epsg:2154')
|
|
try:
|
|
l_lon, l_lat = pyproj.transform(wgs84, lambert93, lon, lat)
|
|
except TypeError:
|
|
return HttpResponseBadRequest()
|
|
result = self.get_object().sig_request('adresse/%s/%s' % (l_lon, l_lat))
|
|
house_number, road = split_street(result.get('voie'))
|
|
address = {
|
|
'road': road,
|
|
'house_number': house_number,
|
|
'city': result.get('commune'),
|
|
'neighbourhood': result.get('sousquartier'),
|
|
'postcode': result.get('codepostal'),
|
|
'suburb': result.get('quartier'),
|
|
'country': 'France',
|
|
}
|
|
return utils.response_for_json(request, {'address': address})
|
|
|
|
|
|
class DistrictView(View, SingleObjectMixin):
|
|
model = MontpellierSig
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
insee = kwargs['insee']
|
|
nom_rue = get_original_prefix(kwargs['nom_rue'])
|
|
numero = kwargs['numero']
|
|
|
|
uri = 'commune/%s/voie/%s/numero/%s' % (insee, nom_rue, numero)
|
|
result = self.get_object().sig_request(uri)
|
|
if isinstance(result, dict) and result.get('error'):
|
|
return utils.response_for_json(request, {'data': []})
|
|
if result:
|
|
r = result[0]
|
|
data = self.get_object().sig_request(
|
|
'adresse/%s/%s' % (r['geometry'].get('x'), r['geometry'].get('y'))
|
|
)
|
|
return utils.response_for_json(request, {'data': data})
|
|
return utils.response_for_json(request, {'data': []})
|
|
|
|
|
|
class ViewerUrlView(View, SingleObjectMixin):
|
|
model = MontpellierSig
|
|
permanent = False
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
lat = request.GET.get('lat')
|
|
lon = request.GET.get('lon')
|
|
# WGS84: epsg:4326
|
|
wgs84 = pyproj.Proj(init='epsg:4326')
|
|
# Lambert93: epsg:2154
|
|
lambert93 = pyproj.Proj(init='epsg:2154')
|
|
|
|
try:
|
|
l_lon, l_lat = pyproj.transform(wgs84, lambert93, lon, lat)
|
|
except TypeError:
|
|
return HttpResponseBadRequest()
|
|
|
|
area = l_lon - 50, l_lat - 50, l_lon + 50, l_lat + 50
|
|
return redirect(
|
|
'http://sig.montpellier-agglo.com/WebVilleServer/resources/index.html#extent:%s;%s;%s;%s' % area
|
|
)
|