odc-tools icon indicating copy to clipboard operation
odc-tools copied to clipboard

Issue displaying outlines with odc.ui.show_datasets at the anti-meridian

Open luigidifraia opened this issue 5 years ago • 4 comments

There is an issue with odc.ui.show_datasets displaying dataset outlines when datasets span the antimeridian (±180° longitude). Example below:

odc ui-antimeridian-issue

luigidifraia avatar Jul 04 '19 06:07 luigidifraia

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 avatar Feb 24 '20 21:02 luigidifraia

@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 avatar Feb 28 '20 03:02 Kirill888

@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).

luigidifraia avatar Feb 28 '20 10:02 luigidifraia

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.

luigidifraia avatar Feb 28 '20 11:02 luigidifraia