Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FDSNWS: Bug in query with radial geographic constraint (internal server error: "distance returned negative!") #109

Open
megies opened this issue Nov 2, 2020 · 2 comments

Comments

@megies
Copy link
Collaborator

megies commented Nov 2, 2020

Using a radial geographic constraint can somehow end up in negative distances being calculated internally during assembling the QuerySet, which leads to an exception being raised and the server not returning any results but rather giving a HTTP 500 "Internal server error".

Works without radial constraint:

$ wget -O - 'https://erde.geophysik.uni-muenchen.de/fdsnws/event/1/query?format=text&minmagnitude=1.0&maxmagnitude=1.0001&starttime=2002-09-29T23:31:27&endtime=2002-09-29T23:31:33'
--2020-11-02 13:59:59--  https://erde.geophysik.uni-muenchen.de/fdsnws/event/1/query?format=text&minmagnitude=1.0&maxmagnitude=1.0001&starttime=2002-09-29T23:31:27&endtime=2002-09-29T23:31:33
Resolving erde.geophysik.uni-muenchen.de (erde.geophysik.uni-muenchen.de)... 141.84.11.2
Connecting to erde.geophysik.uni-muenchen.de (erde.geophysik.uni-muenchen.de)|141.84.11.2|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text]
Saving to: ‘STDOUT’

-                                    [<=>                                                      ]       0  --.-KB/s               #EventID|Time|Latitude|Longitude|Depth/km|Author|Catalog|Contributor|ContributorID|MagType|Magnitude|MagAuthor|EventLocationName
smi:de.erdbeben-in-bayern/event/20020929233127|2002-09-29T23:31:27.750000Z|47.754833|12.768|-0.8|toni||||Ml|1.0||AUSTRIA
-                                    [ <=>                                                     ]     252  --.-KB/s    in 0s      

2020-11-02 13:59:59 (74.2 MB/s) - written to stdout [252]

Same query with an added radial constraint on top:

$ wget -O - 'https://erde.geophysik.uni-muenchen.de/fdsnws/event/1/query?format=text&minmagnitude=1.0&maxmagnitude=1.0001&starttime=2002-09-29T23:31:27&endtime=2002-09-29T23:31:33&latitude=48&longitude=12&maxradius=0.01'
--2020-11-02 14:08:13--  https://erde.geophysik.uni-muenchen.de/fdsnws/event/1/query?format=text&minmagnitude=1.0&maxmagnitude=1.0001&starttime=2002-09-29T23:31:27&endtime=2002-09-29T23:31:33&latitude=48&longitude=12&maxradius=0.01
Resolving erde.geophysik.uni-muenchen.de (erde.geophysik.uni-muenchen.de)... 141.84.11.2
Connecting to erde.geophysik.uni-muenchen.de (erde.geophysik.uni-muenchen.de)|141.84.11.2|:443... connected.
HTTP request sent, awaiting response... 500 Internal Server Error
2020-11-02 14:08:13 ERROR 500: Internal Server Error.

In the browser it shows "Exception Value: | distance returned negative!"

@krischer
Copy link
Owner

krischer commented Nov 2, 2020

I assume the tests run on that machine?

I wonder if it might be some kind of accuracy issue with a 0.01 degree radius. Does it work with larger radii?

Internally this is all handled by PostGIS and the logic seems okay to me:

def get_filtered_queryset_radial_distance(
self, document_type, central_latitude, central_longitude,
min_radius=None, max_radius=None, queryset=None, user=None):
"""
Filter a dataset to get all indices within a certain distance to a
point.
Useful for the radial queries at the FDSN station and event service.
:param document_type: The document type to query. Will be ignored if a
queryset is passed.
:param central_latitude: The latitude of the central point.
:param central_longitude: The longitude of the central point.
:param min_radius: The minimum radius from the central point in degree.
:param max_radius: The maximum radius from the central point in degree.
:param queryset: If no queryset is passed, a new one will be
created, otherwise an existing one will be used and filtered.
"""
# Only create if necessary.
if queryset is None:
queryset = DocumentIndex.objects
# filter by document type
res_type = get_object_or_404(DocumentType, name=document_type)
queryset = queryset.filter(document__document_type=res_type)
queryset = self.apply_retrieve_permission(document_type=res_type,
queryset=queryset,
user=user)
central_point = 'POINT({lng} {lat})'.format(lng=central_longitude,
lat=central_latitude)
if min_radius is not None:
queryset = queryset.filter(
geometry__distance_gt=(central_point,
Distance(km=deg2km(min_radius))))
if max_radius is not None:
queryset = queryset.filter(
geometry__distance_lt=(central_point,
Distance(km=deg2km(max_radius))))
return queryset

@megies
Copy link
Collaborator Author

megies commented Nov 12, 2020

It also doesn't work with larger radii (the above links to check are globally available)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants