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

Increase latitude accuracy level #102

Merged

Conversation

hambsch
Copy link
Contributor

@hambsch hambsch commented Apr 12, 2024

with this code change, the buildings 3d story has global accuracy.
previously, when drawing buildings further away from the origin, the lat component got an offset.
here i calculate the mercator factor, which represents the scale difference between the vector unit and the mercator unit.
since the background map is in mercator, we need to adapt the change in this unit factor with increasing latitude.

the simple way is to have the mean factor between origin and point "(originFactor + pointFactor) / 2" . But this relation is not linear, so it does not scale well to larger distances.
To mitigate this, i calculate the factor for different steps on the latitude from origin towards the point and take an average of this list.
For performance reasons, there is a precalculated lookup list.
This step adds about 20% computational overhead to the draw of the buildings, but it makes the buildings match the background layers even if you are hundreds of kilometers away from the origin.

i also updated the earthRadius to the one maplibre uses, this further increases the accuracy of the placement.
https://github.com/maplibre/maplibre-gl-js/blob/8ea76118210dd18fa52fdb83f2cbdd1229807346/src/geo/lng_lat.ts#L8

Copy link

changeset-bot bot commented Apr 12, 2024

🦋 Changeset detected

Latest commit: 9dda40c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
react-three-map Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

codesandbox-ci bot commented Apr 12, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 9dda40c:

Sandbox Source
example-mapbox Configuration
example-maplibre Configuration
stories Configuration

Copy link
Owner

@RodrigoHamuy RodrigoHamuy left a comment

Choose a reason for hiding this comment

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

@hambsch thanks for the PR! I thing something may still be off as NearCoordinates doesn't seem to work as expected. In the following video, Coordinates and NearCoordinates should behave the same when the distances are not to far away from the real origin, but seems like the green block behaves differently with this PR.

near.mp4

@hambsch
Copy link
Contributor Author

hambsch commented Apr 15, 2024

It is fixed by increasing the steps by 1. in this example, the object was exactly at the origin and this did not work. Thanks for finding it. We only focused on the buildings part, because that is what we are using.

RodrigoHamuy
RodrigoHamuy previously approved these changes Apr 19, 2024
Copy link
Owner

@RodrigoHamuy RodrigoHamuy left a comment

Choose a reason for hiding this comment

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

This is amazing, thank you so much! I honestly don't know much about what's going on myself, so glad to see somebody who knows their stuff 🔥 .

I added a small change to the lookup so is calculated and cached on demand, so it should have ~zero initial cost now :)

Question: and I leave it to you to decide if that's something that you would like to tackle or we merge it as it is.

Position has now been corrected, but the scales are still off.

They were already off anyway, which is why NearCoordinates is only suggested at city scale in the docs, but with your fix positions now work even at world scale, but scaling will stay off.

I recorded a demostration:

Check the 3 blocks in blue, green and purple. Coordinates component is precise, but requires to render things separately, NearCoordinates is off at big distances, but can render under the same scene.

Originally, this is how wrong things where if you use NearCoordinates. 😄

r3m-prod.mp4

Now with your fix, positions seems to be spot on, but scaling is still off.

r3m-pr.mp4

Even if you don't know/don't have time to fix that, happy to merge this PR as it is, but wanted to know your thoughts on it 😄

Thanks again for this amazing PR!!

RodrigoHamuy and others added 2 commits April 19, 2024 21:52
this gave bad averageScales when the point and origin where on different sides of the equator.
@hambsch
Copy link
Contributor Author

hambsch commented Apr 22, 2024

thanks to your examples, I noticed that my calculations where still off when the origin and the point where not in the same hemisphere. removing the absolute values from the latitudes fixes this.

I'll look into the scaling problem, but I'm actually a python developer and not react/JavaScript, so sometimes its hard to understand the relations in the scripts.

@hambsch
Copy link
Contributor Author

hambsch commented Apr 22, 2024

The issue with the scale is also linked to the mercatorFactor it seems. I can fix the scale changing in nearCoordinates by using the scale using the mercatorFactor of the origin position (which is blue[1]) and then using this scale.
This does not work for coordinates, because they all use their own origin to calculate the scale.
By placing the origin (blue box) far to the north (lat 80) the effect is very big.

const scaleFactor = getMercatorScale(blue[1]); // blue[1] is the origin latitude const mercatorScale = scale / scaleFactor
return <StoryMap <MyBox scale={mercatorScale} position={[2, 0, 0]} color="blue"/> <CoordsControl longitude={green[0]} latitude={green[1]} > <MyBox scale={mercatorScale} position={[-2, 0, 0]} color="green"/> </CoordsControl> <CoordsControl longitude={purple[0]} latitude={purple[1]} > <MyBox scale={mercatorScale} color="purple"/> </CoordsControl> </StoryMap> }

without fix:
image
with fix:
image

fix breaks 'coordinates' option because every bar gets the scale from the blue bar:
image

To fix this i think the structure of the object has to be changed, so the mercator scale factor can be provided at a different point liek here:
{coords === CoordinatesType.Coordinates && <Coordinates {...props} />}
{coords === CoordinatesType.NearCoordinates && <NearCoordinates {...props} />}

@RodrigoHamuy
Copy link
Owner

Brilliant, I will check and release this in a bit! This is neat and clear as it is. Probably better to leave the scale for another PR.

@hambsch
Copy link
Contributor Author

hambsch commented Apr 23, 2024

yes, I think the scale needs some other reshuffling in de code to work, and is only somewhat related (same root cause).
ideally the scale parameter needs to be updated after the coordinates are set.

@RodrigoHamuy
Copy link
Owner

Sorry the delay (on vacations!). Updated the README.md files to reflect changes and will deploy now :).

In summary, this gives a much more accurate translation to coordsToVector3, which makes NearCoordinates better, although scale is still being ignored, so probably still not recommended for very long distances.

vector3ToCoords does not have this tweak, so it will still have the old inaccuracies at long distances.

But this tweak is perfect if for example you just want to create a mesh of lines at multi-country level distances.

RodrigoHamuy
RodrigoHamuy previously approved these changes Apr 27, 2024
RodrigoHamuy
RodrigoHamuy previously approved these changes Apr 27, 2024
@RodrigoHamuy RodrigoHamuy force-pushed the increase-latitude-accuracy-level branch from 4bba8e8 to 9dda40c Compare April 27, 2024 23:23
@RodrigoHamuy RodrigoHamuy merged commit 58c42d9 into RodrigoHamuy:main Apr 27, 2024
2 checks passed
@hambsch
Copy link
Contributor Author

hambsch commented Apr 29, 2024

this makes drawing buildings on larger areas better (they do not use scaling, but a fixed height).
Thanks for the merge.

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.

2 participants