maps: add option to specify properties to include in geojson (#25094)

This commit is contained in:
Frédéric Péters 2018-07-06 14:17:06 +02:00
parent d30920adfc
commit 934b13922d
4 changed files with 146 additions and 4 deletions

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.12 on 2018-07-06 11:45
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('maps', '0006_auto_20180627_0841'),
]
operations = [
migrations.AddField(
model_name='maplayer',
name='properties',
field=models.CharField(blank=True, help_text='List of properties to include, separated by commas', max_length=500, verbose_name='Properties'),
),
]

View File

@ -102,6 +102,8 @@ class MapLayer(models.Model):
include_user_identifier = models.BooleanField(
_('Include user identifier in request'),
default=True)
properties = models.CharField(_('Properties'), max_length=500, blank=True,
help_text=_('List of properties to include, separated by commas'))
class Meta:
ordering = ('label',)
@ -165,6 +167,20 @@ class MapLayer(models.Model):
else:
features = data
properties = []
if self.properties:
properties = [x.strip() for x in self.properties.split(',')]
for feature in features:
if 'display_fields' in feature['properties']:
# w.c.s. content, filter fields on varnames
feature['properties']['display_fields'] = [
x for x in feature['properties']['display_fields']
if x.get('varname') in properties]
else:
# classic geojson, filter properties
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'])
@ -202,7 +218,8 @@ class MapLayer(models.Model):
'icon_colour': self.icon_colour,
'label': self.label,
'icon': self.icon,
'identifier': self.slug
'identifier': self.slug,
'properties': properties,
}
return features

View File

@ -32,8 +32,12 @@ $(function() {
popup += $popup_field.html();
});
} else {
var ordered_keys = feature.properties.layer.properties;
if (! ordered_keys) {
ordered_keys = Object.keys(properties).sort();
}
var properties = feature.properties;
$.each(Object.keys(properties).sort(), function(idx, field) {
$.each(ordered_keys, function(idx, field) {
// exclude object type properties
if (typeof(properties[field]) !== 'object') {
var $popup_field = $('<div><div class="popup-field property-' + field + '"></span><span class="field-value"></span></div></div>');

View File

@ -22,7 +22,8 @@ SAMPLE_GEOJSON_CONTENT = '''{
{
"type": "Feature",
"properties": {
"name": "Foo"
"name": "Foo",
"extra": "Baz"
},
"geometry": {
"type": "Point",
@ -35,7 +36,8 @@ SAMPLE_GEOJSON_CONTENT = '''{
{
"type": "Feature",
"properties": {
"name": "Bar"
"name": "Bar",
"extra": "Baz"
},
"geometry": {
"type": "Point",
@ -48,6 +50,43 @@ SAMPLE_GEOJSON_CONTENT = '''{
]
}'''
SAMPLE_WCS_GEOJSON_CONTENT = '''{
"type": "FeatureCollection",
"features": [
{
"type" : "Feature",
"geometry" : {
"type" : "Point",
"coordinates" : [
6.175303,
48.684512
]
},
"properties" : {
"name" : "Test - n°144-4",
"view_label" : "Voir",
"status_name" : "Foo",
"display_fields" : [
{
"varname" : "id",
"html_value" : "144-4",
"value" : "144-4",
"label" : "Numéro"
},
{
"varname" : null,
"html_value" : "toto",
"value" : "toto",
"label" : "toto"
}
]
}
}
]
}'''
@pytest.fixture
def user():
try:
@ -243,3 +282,65 @@ def test_get_geojson(layer, user):
resp = client.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}) + '?lng=2.54&lat=48.84&distance=100')
assert len(json.loads(resp.content)['features']) == 0
def test_get_geojson_properties(layer, user):
page = Page(title='xxx', slug='new', template_name='standard')
page.save()
cell = Map(page=page, placeholder='content', order=0, public=True)
cell.title = 'Map'
cell.save()
layer.save()
cell.layers.add(layer)
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as requests_get:
layer.geojson_url = 'http://example.org/geojson?t1'
layer.save()
requests_get.return_value = mock.Mock(
content=SAMPLE_GEOJSON_CONTENT,
json=lambda: json.loads(SAMPLE_GEOJSON_CONTENT),
status_code=200)
resp = client.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}))
features = json.loads(resp.content)['features']
assert 'name' in features[0]['properties']
assert 'extra' in features[0]['properties']
assert features[0]['properties']['layer']['properties'] == []
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as requests_get:
layer.geojson_url = 'http://example.org/geojson?t2'
layer.properties = 'name, hop'
layer.save()
requests_get.return_value = mock.Mock(
content=SAMPLE_GEOJSON_CONTENT,
json=lambda: json.loads(SAMPLE_GEOJSON_CONTENT),
status_code=200)
resp = client.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}))
features = json.loads(resp.content)['features']
assert 'name' in features[0]['properties']
assert 'extra' not in features[0]['properties']
assert features[0]['properties']['layer']['properties'] == ['name', 'hop']
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as requests_get:
layer.geojson_url = 'http://example.org/geojson?t3'
layer.properties = ''
layer.save()
requests_get.return_value = mock.Mock(
content=SAMPLE_WCS_GEOJSON_CONTENT,
json=lambda: json.loads(SAMPLE_WCS_GEOJSON_CONTENT),
status_code=200)
resp = client.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}))
features = json.loads(resp.content)['features']
assert len(features[0]['properties']['display_fields']) == 2
assert features[0]['properties']['layer']['properties'] == []
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as requests_get:
layer.geojson_url = 'http://example.org/geojson?t4'
layer.properties = 'id'
layer.save()
requests_get.return_value = mock.Mock(
content=SAMPLE_WCS_GEOJSON_CONTENT,
json=lambda: json.loads(SAMPLE_WCS_GEOJSON_CONTENT),
status_code=200)
resp = client.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}))
features = json.loads(resp.content)['features']
assert len(features[0]['properties']['display_fields']) == 1
assert features[0]['properties']['layer']['properties'] == ['id']