make reverse geocoding nominatim compatible (#7349)
* convert input WGS84 coords to Lambert93 * nominatim like url schema and output Tests for streets prefixes and splitting
This commit is contained in:
parent
986135e8bf
commit
9c51b590dd
|
@ -9,7 +9,7 @@ Standards-Version: 3.9.1
|
|||
|
||||
Package: python-passerelle-montpellier-sig
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, ${python:Depends}
|
||||
Depends: ${misc:Depends}, ${python:Depends}, python-pyproj
|
||||
Description: Passerelle extension for Montpellier's GIS
|
||||
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ Service URL : {{ object.service_url }}
|
|||
<a href="{% url 'montpellier-sig-voiecommune' slug=object.slug nom_rue='montp' %}">{{ site_base_uri }}{% url 'montpellier-sig-view' slug=object.slug %}voiecommune/<i><montp></i></a>
|
||||
</li>
|
||||
<li>{% trans 'Get address by geographical position:' %}
|
||||
<a href="{% url 'montpellier-sig-adresse' slug=object.slug lat='771933.239730606' long='6279155.419609674' %}">{{ site_base_uri }}{% url 'montpellier-sig-adresse' slug=object.slug lat='771933.239730606' long='6279155.419609674' %}</a>
|
||||
<a href="{% url 'montpellier-sig-adresse' slug=object.slug %}?lat=52.5487429714954&lon=-1.81602098644987">{{ site_base_uri }}{% url 'montpellier-sig-adresse' slug=object.slug %}?lat=52.5487429714954&lon=-1.81602098644987</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
import json
|
||||
|
||||
from django.test import TestCase
|
||||
from django.test.client import Client
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from passerelle_montpellier_sig.models import MontpellierSig
|
||||
from passerelle_montpellier_sig.views import prefix_cleanup, split_street
|
||||
|
||||
|
||||
class PrefixCleanupTestCase(TestCase):
|
||||
|
||||
def test_prefix_alle(self):
|
||||
self.assertEqual(prefix_cleanup('ALL DE LA PAIX'), 'ALLEE DE LA PAIX')
|
||||
|
||||
def test_prefix_viaduc(self):
|
||||
self.assertEqual(prefix_cleanup('VIAD ALPHONSE LOUBAT'), 'VIADUC ALPHONSE LOUBAT')
|
||||
|
||||
def test_prefix_voie(self):
|
||||
self.assertEqual(prefix_cleanup('VOI DOMITIENNE'), 'VOIE DOMITIENNE')
|
||||
|
||||
def test_prefix_square(self):
|
||||
self.assertEqual(prefix_cleanup('SQ SAINT FIACRE'), 'SQUARE SAINT FIACRE')
|
||||
|
||||
def test_prefix_terasse(self):
|
||||
self.assertEqual(prefix_cleanup('TSSE TERRASSE DES ALLEES DU BOIS'), 'TERRASSE DES ALLEES DU BOIS')
|
||||
|
||||
def test_prefix_route(self):
|
||||
self.assertEqual(prefix_cleanup('RTE DE LODEVE'), 'ROUTE DE LODEVE')
|
||||
|
||||
def test_prefix_rondpoint(self):
|
||||
self.assertEqual(prefix_cleanup('RPT RENE CHAR'), 'ROND-POINT RENE CHAR')
|
||||
|
||||
def test_prefix_rue(self):
|
||||
self.assertEqual(prefix_cleanup('R WILLIAM ET CATHERINE BOOTH'), 'RUE WILLIAM ET CATHERINE BOOTH')
|
||||
|
||||
def test_prefix_place(self):
|
||||
self.assertEqual(prefix_cleanup('PL PABLO PICASSO'), 'PLACE PABLO PICASSO')
|
||||
|
||||
def test_prefix_passage(self):
|
||||
self.assertEqual(prefix_cleanup('PAS HANS CHRISTIAN ANDERSEN'), 'PASSAGE HANS CHRISTIAN ANDERSEN')
|
||||
|
||||
def test_prefix_jardin(self):
|
||||
self.assertEqual(prefix_cleanup('JARD LES JARDINS DU CORUM'), 'JARDIN LES JARDINS DU CORUM')
|
||||
|
||||
def test_prefix_impasse(self):
|
||||
self.assertEqual(prefix_cleanup('IMP VILLEHARDOUIN'), 'IMPASSE VILLEHARDOUIN')
|
||||
|
||||
def test_prefix_esplanade(self):
|
||||
self.assertEqual(prefix_cleanup('ESP DE LA MUSIQUE'), 'ESPLANADE DE LA MUSIQUE')
|
||||
|
||||
def test_prefix_chausse(self):
|
||||
self.assertEqual(prefix_cleanup('CHE DES GRENADIERS'), 'CHAUSSEE DES GRENADIERS')
|
||||
|
||||
def test_prefix_boulevard(self):
|
||||
self.assertEqual(prefix_cleanup('BD RENOUVIER'), 'BOULEVARD RENOUVIER')
|
||||
|
||||
def test_prefix_avenue(self):
|
||||
self.assertEqual(prefix_cleanup('AV RAYMOND DUGRAND'), 'AVENUE RAYMOND DUGRAND')
|
||||
|
||||
|
||||
class ReverseGeolocTest(TestCase):
|
||||
|
||||
def test_get_rue(self):
|
||||
self.assertEqual(split_street('17 bis R WILLIAM ET CATHERINE BOOTH'), ('17 bis', 'RUE WILLIAM ET CATHERINE BOOTH'))
|
||||
|
||||
def test_split_impasse(self):
|
||||
self.assertEqual(split_street(' 5 IMP VILLEHARDOUIN'), ('5', 'IMPASSE VILLEHARDOUIN'))
|
||||
|
||||
def test_split_avenue(self):
|
||||
self.assertEqual(split_street('42 AV RAYMOND DUGRAND '), ('42', 'AVENUE RAYMOND DUGRAND'))
|
|
@ -13,7 +13,7 @@ public_urlpatterns = patterns('',
|
|||
url(r'^(?P<slug>[\w,-]+)/voies/(?P<insee>\d+)$', VoiesView.as_view(), name='montpellier-sig-voies'),
|
||||
url(r'^(?P<slug>[\w,-]+)/voies/(?P<insee>\d+)/(?P<nom_rue>[\w ]+)/numero$', VoiesCommuneView.as_view(), name='montpellier-voies-commune'),
|
||||
url(r'^(?P<slug>[\w,-]+)/voiecommune/(?P<nom_rue>[\w ]+)$', VoieCommuneView.as_view(), name='montpellier-sig-voiecommune'),
|
||||
url(r'^(?P<slug>[\w,-]+)/adresse/(?P<lat>[^/]+)/(?P<long>[^/]+)$', AdresseView.as_view(), name='montpellier-sig-adresse')
|
||||
url(r'^(?P<slug>[\w,-]+)/reverse$', AdresseView.as_view(), name='montpellier-sig-adresse')
|
||||
)
|
||||
|
||||
management_urlpatterns = patterns('',
|
||||
|
|
|
@ -1,16 +1,72 @@
|
|||
import requests
|
||||
import unicodedata
|
||||
import pyproj
|
||||
|
||||
from django.views.generic.detail import SingleObjectMixin, DetailView
|
||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
||||
from django.views.generic.base import View, RedirectView
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponseBadRequest
|
||||
|
||||
from passerelle import utils
|
||||
|
||||
from .models import MontpellierSig
|
||||
from .forms import MontpellierSigForm
|
||||
|
||||
prefix_map = {
|
||||
'ALL': 'ALLEE',
|
||||
'AUTO': 'AUTOROUTE',
|
||||
'AV': 'AVENUE',
|
||||
'BASS': 'BASSIN',
|
||||
'BD': 'BOULEVARD',
|
||||
'CAR': 'CARREFOUR',
|
||||
'CHE': 'CHAUSSEE',
|
||||
'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):
|
||||
name = name.strip()
|
||||
for prefix, full in prefix_map.items():
|
||||
if name.startswith(prefix + ' '):
|
||||
name = (full + name[len(prefix):]).strip()
|
||||
return name
|
||||
|
||||
def split_street(name):
|
||||
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 SigCreateView(CreateView):
|
||||
model = MontpellierSig
|
||||
|
@ -55,51 +111,11 @@ class VoiesView(View, SingleObjectMixin):
|
|||
|
||||
def get(self, request, *args, **kwargs):
|
||||
insee = kwargs['insee']
|
||||
prefix_map = {
|
||||
'ALL': 'ALLEE',
|
||||
'AUTO': 'AUTOROUTE',
|
||||
'AV': 'AVENUE',
|
||||
'BASS': 'BASSIN',
|
||||
'BD': 'BOULEVARD',
|
||||
'CAR': 'CARREFOUR',
|
||||
'CHE': 'CHAUSSEE',
|
||||
'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',
|
||||
}
|
||||
result = self.get_object().sig_request('commune/' + insee + '/voie')
|
||||
voies = []
|
||||
for i in result:
|
||||
voie = i['attributes']['nom_voie']
|
||||
for prefix, full in prefix_map.items():
|
||||
if voie.startswith(prefix + ' '):
|
||||
voie = (full + voie[len(prefix):]).strip()
|
||||
voies.append({'id': i['attributes']['nom_voie'],
|
||||
'text': voie})
|
||||
voies.append({'id': voie, 'text': prefix_cleanup(voie)})
|
||||
|
||||
if 'q' in request.GET and request.GET['q']:
|
||||
q = request.GET['q'].upper()
|
||||
|
@ -152,5 +168,24 @@ class AdresseView(View, SingleObjectMixin):
|
|||
model = MontpellierSig
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
result = self.get_object().sig_request('adresse/' + kwargs['lat'] + '/' + kwargs['long'])
|
||||
return utils.response_for_json(request, {'data': result})
|
||||
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_lat, l_lon = pyproj.transform(wgs84, lambert93, lat, lon)
|
||||
except TypeError:
|
||||
return HttpResponseBadRequest()
|
||||
result = self.get_object().sig_request('adresse/%s/%s' %(l_lat, l_lon))
|
||||
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})
|
||||
|
|
Loading…
Reference in New Issue