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

Make repeated WGS84-Mercator conversion stable #897

Merged
merged 2 commits into from
Oct 27, 2023
Merged

Conversation

abyrd
Copy link
Member

@abyrd abyrd commented Oct 19, 2023

This PR supersedes #892, which has been split into multiple PRs. This is a more minimal changeset than originally proposed, to facilitate review and contain any risk from changing heavily used math functions.

As recently discussed: regional request bounds are specified in WGS84 coordinates, which are converted to web Mercator extents when regional tasks are processed. Repeating a regional analysis with the same bounds as an existing one requires the the UI to look at the web Mercator bounds of an existing analysis, then convert them to WGS84 to create the new regional analysis request. This creates a feedback loop between WGS84 and web Mercator where WGS84 bounding boxes lie exactly on the edges of Mercator pixels, creating a literal edge case for the function WebMercatorExtents#forWgsEnvelope and populateTask.

This PR revises the way web Mercator extents are created to handle this edge case. This change is reinforced with additional factory methods that should handle any numerical instability or lack of precision in the repeated conversions.

The eventual real fix for this is #893.

This PR includes a test of repeated conversions, which fails without these changes and passes with these changes.
Javadoc was also added and updated.

Includes test which passes with these changes in place.
Also added and updated Javadoc.
This is a more minimal changeset than originally proposed, to facilitate
review and contain risk from changing heavily used math functions.
Comment on lines +139 to +141
// Find width and height in whole pixels, handling the case where the right envelope edge is on a pixel edge.
int height = (int) Math.ceil(latToFractionalPixel(wgsEnvelope.getMinY(), zoom) - north);
int width = (int) Math.ceil(lonToFractionalPixel(wgsEnvelope.getMaxX(), zoom) - west);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is a key part of the PR, using ceil() to handle the case where the projected value already lies exactly on a pixel boundary.

Copy link
Member

@ansoncfit ansoncfit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes look good to me.

@abyrd
Copy link
Member Author

abyrd commented Oct 25, 2023

A corresponding or related UI PR is https://github.com/conveyal/ui/pull/1985, where I made some comments about coordinating behavior between the two sides.

Copy link
Member

@trevorgerhardt trevorgerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@abyrd abyrd enabled auto-merge October 27, 2023 12:34
@abyrd abyrd merged commit 4397ac7 into dev Oct 27, 2023
2 checks passed
@abyrd abyrd deleted the wgs-mercator-minimal branch October 27, 2023 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants