fields: allow prefilling maps using coordinates (#49068)

This commit is contained in:
Frédéric Péters 2020-12-06 13:21:20 +01:00
parent 0db2491813
commit 652883b389
3 changed files with 37 additions and 11 deletions

View File

@ -4831,12 +4831,29 @@ def test_form_map_field_prefill_address(pub):
resp.form['f1'] = '169 rue du chateau, paris'
with mock.patch('wcs.wf.geolocate.http_get_page') as http_get_page:
http_get_page.return_value = (None, 200,
json.dumps([{'lat':'48.8337085','lon':'2.3233693'}]), None)
json.dumps([{'lat': '48.8337085', 'lon': '2.3233693'}]), None)
resp = resp.form.submit('submit')
assert resp.form['f3$latlng'].value == '48.8337085;2.3233693'
assert 'chateau' in http_get_page.call_args[0][0]
def test_form_map_field_prefill_coords(pub):
formdef = create_formdef()
formdef.fields = [
fields.PageField(id='0', label='1st page', type='page'),
fields.MapField(id='1', label='map', type='map', varname='map1'),
fields.PageField(id='2', label='2nd page', type='page'),
fields.MapField(id='3', label='map',
prefill={'type': 'string', 'value': '{{ form_var_map1 }}'}),
]
formdef.store()
resp = get_app(pub).get('/test/')
formdef.data_class().wipe()
resp.form['f1$latlng'] = '1.234;-1.234'
resp = resp.form.submit('submit')
assert resp.form['f3$latlng'].value == '1.234;-1.234'
def test_form_map_multi_page(pub):
formdef = create_formdef()
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),

View File

@ -2479,13 +2479,17 @@ class MapField(WidgetField):
def get_prefill_value(self, user=None, force_string=True):
if self.prefill.get('type') != 'string' or not self.prefill.get('value'):
return (None, False)
# string is actually interpreted as a template of a string that will be
# geocoded
# template string must produce lat;lon to be interpreted as coordinates,
# otherwise it will be interpreted as an address that will be geocoded.
prefill_value, explicit_lock = super().get_prefill_value()
if re.match(r'-?\d+(\.\d+)?;-?\d+(\.\d+)?$', prefill_value):
return (prefill_value, explicit_lock)
from wcs.wf.geolocate import GeolocateWorkflowStatusItem
geolocate = GeolocateWorkflowStatusItem()
geolocate.method = 'address_string'
geolocate.address_string = self.prefill.get('value')
coords = geolocate.geolocate_address_string(None)
geolocate.address_string = prefill_value
coords = geolocate.geolocate_address_string(None, compute_template=False)
if not coords:
return (None, False)
return ('%(lat)s;%(lon)s' % coords, False)

View File

@ -108,12 +108,17 @@ class GeolocateWorkflowStatusItem(WorkflowStatusItem):
formdata.geolocations[geolocation_point] = location
formdata.store()
def geolocate_address_string(self, formdata):
try:
address = self.compute(self.address_string, raises=True)
except Exception as e:
get_logger().error('error in template for address string [%r]', e)
return
def geolocate_address_string(self, formdata, compute_template=True):
if compute_template:
try:
address = self.compute(self.address_string, raises=True)
except Exception as e:
get_logger().error('error in template for address string [%r]', e)
return
else:
# this is when the action is being executed to prefill a map field;
# the template has already been rendered.
address = self.address_string
if not address:
get_logger().debug('error geolocating string (empty string)')