odc-tools
odc-tools copied to clipboard
Issue displaying outlines with odc.ui.show_datasets at the anti-meridian
There is an issue with odc.ui.show_datasets displaying dataset outlines when datasets span the antimeridian (±180° longitude). Example below:
A workaround that leverages the fact leaflet deals with longitude values >= 180 degrees (although it works with GeoJSON's coordinate system, EPSG:4326) can be found in this utility. It's by no means supposed to be a reference design or an optimized solution: it is just provided to illustrate how one can leverage the above-mentioned feature in leaflet, which is what has been done over and over by leaflet users to deal with issues around the anti-meridian. Here's an example of the results it produces.
@luigidifraia thanks I thought offsetting by 360 should work.
I can't say I understand how it works though, particularly find_safe_latitude
. I guess there is always an ambiguity when dealing with modulo numbers, did you mean -179->179
or 179->179+2
, both are valid inputs, just one is more likely than the other.
@Kirill888 I think the confusion arises from the fact the function name should have been find_safe_longitude()
- this was now corrected in my repo.
Offsetting by 360 degrees alone is not going to solve the problem entirely. What find_safe_longitude()
does, instead, is to find the first (in a given range) longitude value, L, for which the circle of constant longitude L doesn't cut trough any dataset's bounding box (at this stage you also have to be careful when you test the crossing of bounding boxes that span the anti-meridian!). Once such longitude value L is found, the discontinuity is moved there so usual math operations (e.g. differences, comparisons, hence max, min) can be used without incurring into issues around the anti-meridian any longer.
In practice, the code "moves the discontinuity" from the anti-meridian to L in this way: for any point with longitude < L it simply adds 360 degrees to the longitude value. The condition on "longitude < L" is essential to avoid that one simply moves the discontinuity without solving the underlying issue for good.
Now when you cross L from West to East, and the other way around, you have a 360 degree jump/a discontinuity but you haven't got a discontinuity at the anti-meridian any longer. This is a coordinate system abuse, but Leaflet is internally consistent with the abuse (see Medium post linked in my earlier reply).
Take Fiji, as example, whose WGS84 bounds are:
176.81 -20.81
-178.15 -12.42
Rewritten bounds according to the above (assume L was found to be 176.7 degrees E):
176.81 -20.81
181.85 -12.42
Feed these into Leaflet and you will see the bounding box spanning across the anti-meridian correctly displayed. Simple math calculations including max/min will also still be meaningful when you iterate through multiple bounding boxes to e.g. find their "bbox union", so that you can then find its center and estimate a suitable zoom level to display all bounding boxes at once.
By limiting the range in which L is searched, you can also keep clusters of datasets across different countries (e.g. Fiji and Vanuatu) on the same side of the discontinuity, hence on the same region of a Leaflet map, instead of them ending up on either edge of it (it happens if one cluster was shifted by 360 degrees and a nearby one wasn't simply because L was set to a longitude value in between these clusters). A more detailed example is part of the code, but the gist is that being Vanuatu's Northern Islands WGS84 bounds as per below:
166.47 -17.32
168.71 -14.57
Setting L to 176.7 degrees E as before would result in Vanuatu's coordinates rewritten as:
526.47 -17.32
528.71 -14.57
This would result in the calculation of distances and of the "bbox union", center point, and best zoom level for both countries at once being wrong. A better value for L would be 166.3 degrees E, which keeps both countries on the same side of the discontinuity. Therefore you might want to limit the range in which L is searched in the first instance. Again, when working in the Pacific, a suitable range would be around the Prime meridian. Obviously, one could automate the narrowing of such search range too, based on dataset density and location. I would naturally look for the widest range of longitudes where there are no datasets and expect to choose L so that it slices the range in half.