misc: add distance template tag (#32262)

This commit is contained in:
Frédéric Péters 2019-04-13 16:49:49 +02:00
parent 96b02e1f3d
commit 7f8c246f87
6 changed files with 73 additions and 0 deletions

1
debian/control vendored
View File

@ -17,6 +17,7 @@ Depends: ${misc:Depends}, ${python:Depends},
python-django-ckeditor,
python-feedparser,
python-imaging,
python-pyproj,
python-requests,
python-vobject,
python-xstatic-leaflet,

View File

@ -110,6 +110,7 @@ setup(
'gadjo>=0.53',
'django-ckeditor<4.5.3',
'XStatic-Leaflet',
'pyproj',
],
package_dir = { 'wcs': 'wcs' },
packages = find_packages(),

View File

@ -833,6 +833,15 @@ def test_lazy_map_variable(pub, variable_test_data):
assert WorkflowStatusItem.compute('=form_var_map_lon', raises=True) == 4
assert WorkflowStatusItem.compute('{{ form_var_map_lon }}', raises=True) == '4.0'
assert WorkflowStatusItem.compute('{{ form_var_map|distance:form_var_map|floatformat }}', raises=True) == '0'
assert WorkflowStatusItem.compute('{{ form_var_map|distance:"2.1;4.1"|floatformat }}', raises=True) == '15685.4'
assert WorkflowStatusItem.compute('{{ "2.1;4.1"|distance:form_var_map|floatformat }}', raises=True) == '15685.4'
assert WorkflowStatusItem.compute('{{ form|distance:"1;2"|floatformat }}', raises=True) == '0'
assert WorkflowStatusItem.compute('{{ form|distance:"1.1;2.1"|floatformat }}', raises=True) == '15689.1'
assert WorkflowStatusItem.compute('{{ "1.1;2.1"|distance:form|floatformat }}', raises=True) == '15689.1'
assert WorkflowStatusItem.compute('{{ form|distance:form_var_map|floatformat }}', raises=True) == '248515.5'
assert WorkflowStatusItem.compute('{{ form_var_map|distance:form|floatformat }}', raises=True) == '248515.5'
formdata.data['7'] = None
formdata.store()
pub.substitutions.reset()
@ -843,6 +852,8 @@ def test_lazy_map_variable(pub, variable_test_data):
pub.substitutions.feed(formdef)
with pub.substitutions.temporary_feed(formdata, force_mode=mode):
assert WorkflowStatusItem.compute('=form_var_map', raises=True) is None
assert WorkflowStatusItem.compute('{{ form_var_map|distance:"1;2"|floatformat }}', raises=True) == ''
assert WorkflowStatusItem.compute('{{ "1;2"|distance:form_var_map|floatformat }}', raises=True) == ''
def test_lazy_conditions(pub, variable_test_data):
condition = Condition({'type': 'django', 'value': 'form_var_foo_foo == "bar"'})

View File

@ -7,6 +7,7 @@ import string
from quixote import cleanup
from qommon.template import Template, TemplateError
from wcs.conditions import Condition
from wcs.variables import LazyFormData
from utilities import create_temporary_pub, clean_temporary_pub
@ -459,3 +460,32 @@ def test_token_alphanum():
assert not any(set(token) & set('01IiOo') for token in tokens)
t = Template('{% if token1|token_check:token2 %}ok{% endif %}')
assert t.render({'token1': tokens[0] + ' ', 'token2': tokens[0].lower()}) == 'ok'
def test_distance():
t = Template('{{ "48;2"|distance:"48.1;2.1"|floatformat }}',)
assert t.render() == '13387.2'
t = Template('{{ coords|distance:"48.1;2.1"|floatformat }}',)
assert t.render({'coords': '48;2'}) == '13387.2'
t = Template('{{ "48;2"|distance:coords|floatformat }}',)
assert t.render({'coords': '48.1;2.1'}) == '13387.2'
t = Template('{{ c1|distance:c2|floatformat }}',)
assert t.render({'c1': '48;2', 'c2': '48.1;2.1'}) == '13387.2'
class MockFormData(object):
formdef = None
geolocations = {'base': {'lat': 48, 'lon': 2}}
lazy_formdata = LazyFormData(MockFormData())
for tpl in ('{{ formdata|distance:coords|floatformat }}',
'{{ coords|distance:formdata|floatformat }}'):
t = Template(tpl,)
assert t.render({'formdata': lazy_formdata, 'coords': '48.1;2.1'}) == '13387.2'
assert t.render({'formdata': lazy_formdata, 'coords': '49.1;3.1'}) == '146821.9'
assert t.render({'formdata': lazy_formdata, 'coords': 'abc;def'}) == ''
assert t.render({'formdata': lazy_formdata, 'coords': '42'}) == ''
assert t.render({'formdata': lazy_formdata, 'coords': ''}) == ''
MockFormData.geolocations = {}
for tpl in ('{{ formdata|distance:coords|floatformat }}',
'{{ coords|distance:formdata|floatformat }}'):
t = Template(tpl,)
assert t.render({'formdata': lazy_formdata, 'coords': '49.1;3.1'}) == ''

View File

@ -30,6 +30,7 @@ deps =
python-dateutil
pillow
feedparser
pyproj
commands =
./getlasso.sh
pickle: py.test --without-postgresql-tests {env:COVERAGE:} {posargs:tests}

View File

@ -23,6 +23,8 @@ import math
import string
import random
from pyproj import Geod
from django import template
from django.template import defaultfilters
from django.utils import dateparse
@ -300,3 +302,30 @@ def token_alphanum(length=4):
@register.filter
def token_check(token1, token2):
return token1.strip().upper() == token2.strip().upper()
def get_latlon(obj):
if getattr(obj, 'geoloc', None):
if 'base' in obj.geoloc:
return obj.geoloc['base']['lat'], obj.geoloc['base']['lon']
return None, None
if hasattr(obj, 'get_value'):
obj = obj.get_value() # unlazy
if not obj or not isinstance(obj, basestring) or ';' not in obj:
return None, None
try:
return float(obj.split(';')[0]), float(obj.split(';')[1])
except ValueError:
return None, None
@register.filter
def distance(obj1, obj2):
lat1, lon1 = get_latlon(obj1)
if lat1 is None or lon1 is None:
return None
lat2, lon2 = get_latlon(obj2)
if lat2 is None or lon2 is None:
return None
geod = Geod(ellps='WGS84')
distance = geod.inv(lon1, lat1, lon2, lat2)[2]
return distance