Open asmccormick opened 5 years ago
Hey @asmccormick! Great catch and thanks for all detailed data. height precision isn't easy and to be honest not something used/required regularly so I guess we looked over this. After a quick inspection, I think I found something.
if you check MapScalingAtWorldScaleStrategy
class you'll find this method.
original
public void SetUpScaling(AbstractMap map)
{
var scaleFactor = Mathf.Pow(2, (map.AbsoluteZoom - map.InitialZoom));
map.SetWorldRelativeScale(scaleFactor * Mathf.Cos(Mathf.Deg2Rad * (float)map.CenterLatitudeLongitude.x));
}
That calculation starting with mathf.Cos is actually a fix for the latitude in fixed size tiles since forcing tiles down to a certain size is a little more complex in y axis because of the mercator tile sizes (they shrink as latitude goes higher/lower).
But that is unnecessary in world scale because in that mode we're not scaling tiles at all! So I just commented that out and tested with Columbia Tower
which came very close to 286m using the exact method you used.
changed
public void SetUpScaling(AbstractMap map)
{
var scaleFactor = Mathf.Pow(2, (map.AbsoluteZoom - map.InitialZoom));
map.SetWorldRelativeScale(scaleFactor);
}
So if you can change that line as shown above and test in WorldScale
mode again, I think you will get much better results. I'm not creating a branch and PR as I would like to test a little bit more myself as well, but theoretically it makes sense and we probably just looked over the fact that it's not necessary in world scale mode while writing that class.
Hope that helps!
I couldn't resists so I created a PR; https://github.com/mapbox/mapbox-unity-sdk/pull/1384 we can test and talk there as well anyway. Thanks a lot again @asmccormick
@asmccormick Thanks for the detailed analysis and awesome ticket 🎉
Simplest fix is to set AbstractMap to World Scale and zoom to 16x. Then set y-scale of map gameObject like this
void FixMapScale ()
{
float verticalScale = 1 / Mathf.Cos(Mathf.Deg2Rad * (float)AbstractMapScript.CenterLatitudeLongitude.x);
MapTransform.localScale = new Vector3(1f, verticalScale, 1f);
}
Note that changing the scale of a Unity object may create some strange behaviors from physics, colldiers, raycasting, etc etc.
Confirmed, this fixes elevation for my application as well, across a range of latitudes.
Note that if you are also calling AbstractMap.QueryElevationInUnityUnitsAt()
, then you need to multiply the result by the same verticalScale
factor computed above, even if you scale the map transform, as done above.
However, if you scale the map transform and call AbstractMap.GeoToWorldPosition()
with the queryHeight
parameter, then don't scale the result, it already includes it, since it uses the Unity tile transform, and so picks up the map scale.
Really would love to see https://github.com/mapbox/mapbox-unity-sdk/pull/1384 fixed and pushed!
I can confirm that changing the mentioned line in MapScalingAtWorldScaleStrategy.SetUpScaling will fix this issue like you can see in the pictures below:
Test with 200m Cube (respecting WorldRelativeScale) vs. 200m real world tower
Before
After
Look's legit now :-)
I'm trying to use Mapbox to create an accurate environment for VR. For example, if a real skyscraper in NYC is 100m tall in real life, it should be 100m tall in VR. I've tried adjusting the zoom scale and changing World Scale to Custom, but no combination of these will make the buildings appear at their actual height.
In hopes of finding a Mapbox-to-Realworld ratio, I gathered some data points.
Here's my methodology:
From these 7 data points, I calculated an average ratio of 6.12. However, I'm not terribly confident in the accuracy of my method, nor do I have any idea what this number signifies.
Does anyone know what 6.12 refers to? Does anyone know of a precise zoom level where Mapbox creates buildings to their actual scale?