normalize geographic coordinates into -90..90/-180..180 (#20364)
This commit is contained in:
parent
06ef78bb9e
commit
c54766c4e3
|
@ -15,7 +15,7 @@ import wcs.api # workaround against circular dependencies :/
|
|||
from wcs.qommon.form import FileSizeWidget, PicklableUpload
|
||||
from wcs.qommon.humantime import humanduration2seconds, seconds2humanduration
|
||||
from wcs.qommon.misc import (simplify, json_loads, parse_isotime, format_time,
|
||||
date_format, get_as_datetime)
|
||||
date_format, get_as_datetime, normalize_geolocation)
|
||||
from wcs.admin.settings import FileTypesDirectory
|
||||
from wcs.scripts import Script
|
||||
from wcs.qommon import evalutils
|
||||
|
@ -399,3 +399,22 @@ def test_email_plain_and_html_with_attachments(emails):
|
|||
def test_cache():
|
||||
cache.set('hello', 'world')
|
||||
assert cache.get('hello') == 'world'
|
||||
|
||||
def test_normalize_geolocation():
|
||||
assert normalize_geolocation({'lat': 10.0, 'lon': 0.0}) == {'lat': 10.0, 'lon': 0.0}
|
||||
assert normalize_geolocation({'lat': -10.0, 'lon': 0.0}) == {'lat': -10.0, 'lon': 0.0}
|
||||
assert normalize_geolocation({'lat': 100.0, 'lon': 0.0}) == {'lat': -80.0, 'lon': 0.0}
|
||||
assert normalize_geolocation({'lat': -100.0, 'lon': 0.0}) == {'lat': 80.0, 'lon': 0.0}
|
||||
assert normalize_geolocation({'lat': 180.0, 'lon': 0.0}) == {'lat': 0.0, 'lon': 0.0}
|
||||
assert normalize_geolocation({'lat': -180.0, 'lon': 0.0}) == {'lat': 0.0, 'lon': 0.0}
|
||||
assert normalize_geolocation({'lat': 200.0, 'lon': 0.0}) == {'lat': 20.0, 'lon': 0.0}
|
||||
assert normalize_geolocation({'lat': -200.0, 'lon': 0.0}) == {'lat': -20.0, 'lon': 0.0}
|
||||
|
||||
assert normalize_geolocation({'lat': 0.0, 'lon': 10.0}) == {'lat': 0.0, 'lon': 10.0}
|
||||
assert normalize_geolocation({'lat': 0.0, 'lon': -10.0}) == {'lat': 0.0, 'lon': -10.0}
|
||||
assert normalize_geolocation({'lat': 0.0, 'lon': 200.0}) == {'lat': 0.0, 'lon': -160.0}
|
||||
assert normalize_geolocation({'lat': 0.0, 'lon': -200.0}) == {'lat': 0.0, 'lon': 160.0}
|
||||
assert normalize_geolocation({'lat': 0.0, 'lon': 360.0}) == {'lat': 0.0, 'lon': 0.0}
|
||||
assert normalize_geolocation({'lat': 0.0, 'lon': -360.0}) == {'lat': 0.0, 'lon': 0.0}
|
||||
assert normalize_geolocation({'lat': 0.0, 'lon': 400.0}) == {'lat': 0.0, 'lon': 40.0}
|
||||
assert normalize_geolocation({'lat': 0.0, 'lon': -400.0}) == {'lat': 0.0, 'lon': -40.0}
|
||||
|
|
|
@ -69,7 +69,7 @@ def geojson_formdatas(formdatas, geoloc_key='base', fields=None):
|
|||
for formdata in formdatas:
|
||||
if not formdata.geolocations or not geoloc_key in formdata.geolocations:
|
||||
continue
|
||||
coords = formdata.geolocations[geoloc_key]
|
||||
coords = misc.normalize_geolocation(formdata.geolocations[geoloc_key])
|
||||
status = formdata.get_status()
|
||||
try:
|
||||
status_colour = status.colour
|
||||
|
|
|
@ -2183,6 +2183,9 @@ class MapWidget(CompositeWidget):
|
|||
def _parse(self, request):
|
||||
CompositeWidget._parse(self, request)
|
||||
self.value = self.get('latlng')
|
||||
lat, lon = self.value.split(';')
|
||||
lat_lon = misc.normalize_geolocation({'lat': lat, 'lon': lon})
|
||||
self.value = '%s;%s' % (lat_lon['lat'], lat_lon['lon'])
|
||||
|
||||
|
||||
class HiddenErrorWidget(HiddenWidget):
|
||||
|
|
|
@ -559,3 +559,15 @@ def get_thumbnail(fp):
|
|||
fp.seek(0)
|
||||
raise ThumbnailError()
|
||||
return image_thumb_fp.getvalue()
|
||||
|
||||
|
||||
def normalize_geolocation(lat_lon):
|
||||
'''Fit lat into -90/90 and lon into -180/180'''
|
||||
def wrap(x, mini, maxi):
|
||||
diff = maxi - mini
|
||||
return ((x - mini) % diff + diff) % diff + mini
|
||||
lat = decimal.Decimal(lat_lon['lat'])
|
||||
lon = decimal.Decimal(lat_lon['lon'])
|
||||
lat = wrap(lat, decimal.Decimal('-90.0'), decimal.Decimal('90.0'))
|
||||
lon = wrap(lon, decimal.Decimal('-180.0'), decimal.Decimal('180.0'))
|
||||
return {'lat': float(lat), 'lon': float(lon)}
|
||||
|
|
|
@ -29,7 +29,7 @@ from quixote import get_publisher
|
|||
from qommon import _
|
||||
from qommon import get_logger
|
||||
from qommon.form import RadiobuttonsWidget, ComputedExpressionWidget, CheckboxWidget
|
||||
from qommon.misc import http_get_page
|
||||
from qommon.misc import http_get_page, normalize_geolocation
|
||||
from wcs.workflows import WorkflowStatusItem, register_item_class
|
||||
|
||||
class GeolocateWorkflowStatusItem(WorkflowStatusItem):
|
||||
|
@ -130,7 +130,7 @@ class GeolocateWorkflowStatusItem(WorkflowStatusItem):
|
|||
get_logger().info('error finding location')
|
||||
return
|
||||
coords = data[0]
|
||||
return {'lon': float(coords['lon']), 'lat': float(coords['lat'])}
|
||||
return normalize_geolocation({'lon': coords['lon'], 'lat': coords['lat']})
|
||||
|
||||
def geolocate_map_variable(self, formdata):
|
||||
value = self.compute(self.map_variable)
|
||||
|
@ -138,12 +138,13 @@ class GeolocateWorkflowStatusItem(WorkflowStatusItem):
|
|||
return
|
||||
|
||||
try:
|
||||
lat, lon = map(float, value.split(';'))
|
||||
lat, lon = value.split(';')
|
||||
lat_lon = normalize_geolocation({'lon': lon, 'lat': lat})
|
||||
except Exception, e:
|
||||
get_logger().error('error geolocating from map variable [%r]', e)
|
||||
return
|
||||
|
||||
return {'lon': lon, 'lat': lat}
|
||||
return lat_lon
|
||||
|
||||
def geolocate_photo_variable(self, formdata):
|
||||
if Image is None:
|
||||
|
@ -192,7 +193,7 @@ class GeolocateWorkflowStatusItem(WorkflowStatusItem):
|
|||
lat = -lat
|
||||
if lon_ref == 'W':
|
||||
lon = -lon
|
||||
return {'lon': lon, 'lat': lat}
|
||||
return normalize_geolocation({'lon': lon, 'lat': lat})
|
||||
return
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue