maps: delegate circle param to geojson service (#41993)
This commit is contained in:
parent
8aa3fa52fc
commit
87e9957f0b
|
@ -55,7 +55,7 @@ class MapLayerForm(forms.ModelForm):
|
|||
else:
|
||||
todelete_fields = [
|
||||
'geojson_url', 'marker_colour', 'icon', 'icon_colour', 'cache_duration',
|
||||
'include_user_identifier', 'properties', 'geojson_query_parameter']
|
||||
'include_user_identifier', 'properties', 'geojson_query_parameter', 'geojson_accepts_circle_param']
|
||||
for field in todelete_fields:
|
||||
if field in self.fields:
|
||||
del self.fields[field]
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('maps', '0013_geojson_query_parameter'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='maplayer',
|
||||
name='geojson_accepts_circle_param',
|
||||
field=models.BooleanField(default=False, verbose_name='GeoJSON URL accepts a "cirle" parameter'),
|
||||
),
|
||||
]
|
|
@ -136,6 +136,9 @@ class MapLayer(models.Model):
|
|||
max_length=100,
|
||||
blank=True,
|
||||
help_text=_('Name of the parameter to use for querying the GeoJSON layer (typically, q)'))
|
||||
geojson_accepts_circle_param = models.BooleanField(
|
||||
_('GeoJSON URL accepts a "cirle" parameter'),
|
||||
default=False)
|
||||
|
||||
class Meta:
|
||||
ordering = ('label',)
|
||||
|
@ -193,6 +196,19 @@ class MapLayer(models.Model):
|
|||
req.prepare_url(geojson_url, {'q': request.GET[query_parameter]})
|
||||
geojson_url = req.url
|
||||
|
||||
distance = center_lat = center_lng = None
|
||||
try:
|
||||
distance = float(request.GET['distance'])
|
||||
center_lat = float(request.GET['lat'])
|
||||
center_lng = float(request.GET['lng'])
|
||||
distance_params = True
|
||||
except (ValueError, KeyError):
|
||||
distance_params = False
|
||||
if request and self.geojson_accepts_circle_param and distance_params:
|
||||
req = PreparedRequest()
|
||||
req.prepare_url(geojson_url, {'circle': '%s,%s,%s' % (center_lng, center_lat, distance)})
|
||||
geojson_url = req.url
|
||||
|
||||
response = requests.get(
|
||||
geojson_url,
|
||||
remote_service='auto',
|
||||
|
@ -222,10 +238,7 @@ class MapLayer(models.Model):
|
|||
feature['properties'] = dict(
|
||||
[x for x in feature['properties'].items() if x[0] in properties])
|
||||
|
||||
if request and request.GET.get('distance'):
|
||||
distance = float(request.GET['distance'])
|
||||
center_lat = float(request.GET['lat'])
|
||||
center_lng = float(request.GET['lng'])
|
||||
if request and not self.geojson_accepts_circle_param and distance_params:
|
||||
geod = pyproj.Geod(ellps='WGS84')
|
||||
south_lat = geod.fwd(center_lng, center_lat, 180, distance)[1]
|
||||
north_lat = geod.fwd(center_lng, center_lat, 0, distance)[1]
|
||||
|
|
|
@ -8,7 +8,6 @@ from django.contrib.auth.models import User
|
|||
from django.contrib.auth.models import Group
|
||||
from django.urls import reverse
|
||||
from django.test.client import RequestFactory
|
||||
from django.utils.html import escape
|
||||
|
||||
from combo.data.models import Page
|
||||
from combo.apps.maps.models import MapLayer, Map, MapLayerOptions
|
||||
|
@ -363,6 +362,20 @@ def test_get_geojson(app, layer, user):
|
|||
resp = app.get(geojson_url + '?lng=2.54&lat=48.84&distance=100')
|
||||
assert len(json.loads(resp.text)['features']) == 0
|
||||
|
||||
# missing params
|
||||
resp = app.get(geojson_url + '?lat=48.84&distance=10')
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
resp = app.get(geojson_url + '?lng=2.54&distance=10')
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
|
||||
# bad params
|
||||
resp = app.get(geojson_url + '?lng=foo&lat=48.84&distance=10')
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
resp = app.get(geojson_url + '?lng=2.54&lat=foo&distance=10')
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
resp = app.get(geojson_url + '?lng=2.54&lat=48.84&distance=foo')
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
|
||||
# check on multiple words
|
||||
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as requests_get:
|
||||
requests_get.return_value = mock.Mock(
|
||||
|
@ -466,6 +479,64 @@ def test_get_geojson_query_parameter(app, layer, user):
|
|||
assert len(json.loads(resp.text)['features']) == 2
|
||||
|
||||
|
||||
def test_get_geojson_accepts_circle_param(app, layer, user):
|
||||
page = Page.objects.create(title='xxx', slug='new', template_name='standard')
|
||||
cell = Map.objects.create(page=page, placeholder='content', order=0, public=True)
|
||||
layer.geojson_url = 'http://example.org/geojson'
|
||||
layer.save()
|
||||
MapLayerOptions.objects.create(map_cell=cell, map_layer=layer)
|
||||
geojson_url = reverse('mapcell-geojson', kwargs={'cell_id': cell.pk, 'layer_slug': layer.slug})
|
||||
mock_get = mock.Mock(
|
||||
content=SAMPLE_GEOJSON_CONTENT,
|
||||
json=lambda: json.loads(SAMPLE_GEOJSON_CONTENT),
|
||||
status_code=200)
|
||||
|
||||
# circle param not accepted
|
||||
with mock.patch('combo.utils.requests.get', return_value=mock_get) as requests_get:
|
||||
resp = app.get(geojson_url)
|
||||
assert requests_get.call_args_list[0][0][0] == 'http://example.org/geojson'
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
with mock.patch('combo.utils.requests.get', return_value=mock_get) as requests_get:
|
||||
resp = app.get(geojson_url + '?lng=2.54&lat=48.84&distance=1000')
|
||||
assert len(json.loads(resp.text)['features']) == 1
|
||||
assert requests_get.call_args_list[0][0][0] == 'http://example.org/geojson'
|
||||
assert len(json.loads(resp.text)['features']) == 1
|
||||
|
||||
# circle param accepted
|
||||
layer.geojson_accepts_circle_param = True
|
||||
layer.save()
|
||||
with mock.patch('combo.utils.requests.get', return_value=mock_get) as requests_get:
|
||||
resp = app.get(geojson_url)
|
||||
assert requests_get.call_args_list[0][0][0] == 'http://example.org/geojson'
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
with mock.patch('combo.utils.requests.get', return_value=mock_get) as requests_get:
|
||||
resp = app.get(geojson_url + '?lng=2.54&lat=48.84&distance=1000')
|
||||
assert requests_get.call_args_list[0][0][0] == 'http://example.org/geojson?circle=2.54%2C48.84%2C1000.0'
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
# missing params
|
||||
with mock.patch('combo.utils.requests.get', return_value=mock_get) as requests_get:
|
||||
resp = app.get(geojson_url + '?lat=48.84&distance=1000')
|
||||
assert requests_get.call_args_list[0][0][0] == 'http://example.org/geojson'
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
with mock.patch('combo.utils.requests.get', return_value=mock_get) as requests_get:
|
||||
resp = app.get(geojson_url + '?lng=2.54&distance=1000')
|
||||
assert requests_get.call_args_list[0][0][0] == 'http://example.org/geojson'
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
# bad params
|
||||
with mock.patch('combo.utils.requests.get', return_value=mock_get) as requests_get:
|
||||
resp = app.get(geojson_url + '?lng=foo&lat=48.84&distance=1000')
|
||||
assert requests_get.call_args_list[0][0][0] == 'http://example.org/geojson'
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
with mock.patch('combo.utils.requests.get', return_value=mock_get) as requests_get:
|
||||
resp = app.get(geojson_url + '?lng=2.54&lat=foo&distance=1000')
|
||||
assert requests_get.call_args_list[0][0][0] == 'http://example.org/geojson'
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
with mock.patch('combo.utils.requests.get', return_value=mock_get) as requests_get:
|
||||
resp = app.get(geojson_url + '?lng=2.54&lat=48.84&distance=foo')
|
||||
assert requests_get.call_args_list[0][0][0] == 'http://example.org/geojson'
|
||||
assert len(json.loads(resp.text)['features']) == 2
|
||||
|
||||
|
||||
def test_get_geojson_properties(app, layer, user):
|
||||
page = Page(title='xxx', slug='new', template_name='standard')
|
||||
page.save()
|
||||
|
|
|
@ -68,6 +68,7 @@ def test_add_geojson_layer(app, admin_user):
|
|||
assert resp.form['icon_colour'].value == '#000000'
|
||||
resp.form['icon_colour'] = '#FFFFFF'
|
||||
resp.form['geojson_query_parameter'] = 'foobar'
|
||||
resp.form['geojson_accepts_circle_param'] = True
|
||||
resp = resp.forms[0].submit()
|
||||
assert resp.location.endswith('/manage/maps/')
|
||||
assert MapLayer.objects.count() == 1
|
||||
|
@ -75,6 +76,7 @@ def test_add_geojson_layer(app, admin_user):
|
|||
assert layer.label == 'Test'
|
||||
assert layer.slug == 'test'
|
||||
assert layer.geojson_query_parameter == 'foobar'
|
||||
assert layer.geojson_accepts_circle_param is True
|
||||
assert layer.kind == 'geojson'
|
||||
|
||||
|
||||
|
@ -91,6 +93,7 @@ def test_add_tiles_layer(app, admin_user):
|
|||
assert 'icon_colour' not in resp.context['form'].fields
|
||||
assert 'properties' not in resp.context['form'].fields
|
||||
assert 'geojson_query_parameter' not in resp.context['form'].fields
|
||||
assert 'geojson_accepts_circle_param' not in resp.context['form'].fields
|
||||
resp.forms[0]['label'] = 'Test'
|
||||
resp.forms[0]['tiles_template_url'] = 'http://somedomain.com/blabla/{z}/{x}/{y}{r}.png'
|
||||
resp.forms[0]['tiles_attribution'] = 'Foo bar'
|
||||
|
|
Loading…
Reference in New Issue