Topic: Range Around Transform

We are seeking to migrate from Mapbox to Online Maps, and there is a functionality from thr Mapbox Unity SDK that I would love very much to be implemented in Online Maps.

It's Range Around Transform. Basically, the map will update its extents when a transform of another GameObject moves. I have attached a GIF of the feature in action. This feature is essential to our visualisation product, basically positioning objects in world scale, and allowing freestyle camera movement in 3D space as well. The idea is that everything is in world scale (1 unit is 1 meter), including the map plane.

I'm new to Online Maps, and I haven't been able to replicate this functionality. As I understand, the Online Maps map plane is stationary, and the camera control locks the camera in place to allow for user control. Is Range Around Transform functionality implemented in Online Maps already? If not, it would be really nice to have this in the plugin.

Post's attachments

Attachment icon 2019-01-07_15-09-19.gif 1.76 mb, file has never been downloaded. 

Re: Range Around Transform

Hello.

Something like that:

using UnityEngine;

public class FollowGameObject : MonoBehaviour
{
    public GameObject target;
    private Vector3 lastPosition;
    protected internal OnlineMaps map;
    protected internal OnlineMapsTileSetControl control;

    private double tx, ty;

    private void Start()
    {
        map = OnlineMaps.instance;
        control = OnlineMapsTileSetControl.instance;

        control.allowUserControl = false;
        control.allowZoom = false;

        UpdateMap(true);
    }

    private void Update()
    {
        if (target.transform.position != lastPosition) UpdateMap();
    }

    private void UpdateMap(bool initial = false)
    {
        lastPosition = target.transform.position;

        Vector3 center = new Vector3(map.tilesetSize.x / -2, 0, map.tilesetSize.y / 2);
        Vector3 offset = lastPosition - map.transform.position - center;
        offset.x = offset.x / OnlineMapsUtils.tileSize * map.tilesetSize.x / map.tilesetWidth;
        offset.z = offset.z / OnlineMapsUtils.tileSize * map.tilesetSize.y / map.tilesetHeight;

        if (initial) map.GetTilePosition(out tx, out ty);
        tx -= offset.x;
        ty += offset.z;

        double lng, lat;
        map.projection.TileToCoordinates(tx, ty, map.zoom, out lng, out lat);
        map.SetPosition(lng, lat);

        map.transform.position = lastPosition - center;
    }
}

Video:
https://www.dropbox.com/s/y1fzwbxxcfed0 … 1.mp4?dl=0

Kind Regards,
Infinity Code Team

Re: Range Around Transform

Thanks a lot, Alex! That works perfectly!

Re: Range Around Transform

Hi Alex,

I'm trying to replicate Mapbox's behaviour, and the next behaviour is that when compared to Mapbox, the map is flipped 180 degrees on the Y axis. That is, to get the same orientation as the Mapbox map, I need to rotate OnlineMaps 180 degrees on the Y axis.

I have uploaded some screenshots (don't know how to add multiple attachments to the post, so I uploaded them to imgur.com: https://imgur.com/a/r061anA

The first is Mapbox compared to OnlineMaps in their original transforms (I dragged OnlineMaps to the right for comparison). The second is adding the Y rotation, which because of OnlineMaps' pivot, is putting it way down to the bottom right. The 3rd is me trying to use your provided code (thanks again!), which the pivot being on the bottom right is now putting it way down there.

Basically what I'm trying to do is to have the same Range Around Transform functionality, with the orientation corrected to Mapbox. I have not been able to achieve this tinkering with the code you provided sad This is where I am at right now after a day, but it's not working. Can you have a look and give me some directions?

Re: Range Around Transform

Can't add the code in the previous post because it doesn't allow more than 2 tags? Posting it here.

using UnityEngine;

/// <summary>
/// From Alex Vertax of Infinity Code.
/// http://forum.infinity-code.com/viewtopic.php?pid=4462
/// </summary>
public class RangeAroundTransform : MonoBehaviour 
{
    public GameObject target;
    private Vector3 lastPosition;
    protected internal OnlineMaps map;
    protected internal OnlineMapsTileSetControl control;

    private double tx, ty;

    private void Start()
    {
        map = OnlineMaps.instance;
        control = OnlineMapsTileSetControl.instance;

        control.allowUserControl = false;
        control.allowZoom = false;

        UpdateMap(true);
    }

    private void Update()
    {
        if (target.transform.position != lastPosition) UpdateMap();
    }

    private void UpdateMap(bool initial = false)
    {
        lastPosition = target.transform.position;

        // Change: lock map Y to 0 instead of target y
        lastPosition.y = 0;
        // End change

        Vector3 center = new Vector3(map.tilesetSize.x / -2, 0, map.tilesetSize.y / 2);
        Vector3 offset = lastPosition - map.transform.position - center;
        offset.x = offset.x / OnlineMapsUtils.tileSize * map.tilesetSize.x / map.tilesetWidth;
        offset.z = offset.z / OnlineMapsUtils.tileSize * map.tilesetSize.y / map.tilesetHeight;

        if (initial) map.GetTilePosition(out tx, out ty);
        tx -= offset.x;
        ty += offset.z;

        double lng, lat;
        map.projection.TileToCoordinates(tx, ty, map.zoom, out lng, out lat);
        map.SetPosition(lng, lat);

        map.transform.position = lastPosition - center;

        // Change: Flipping: 180 Y rotation
        map.transform.rotation = Quaternion.Euler(new Vector3(0, 180, 0));
        var x = map.transform.position.x;
        var z = map.transform.position.z;
        map.transform.position = new Vector3(z, 0, x);
        // End change
    }
}

Re: Range Around Transform

1. Set Transform.Rotation - (0, 180, 0) of the map GameObject using the inspector.

2. Modify the script lines:

Vector3 center = new Vector3(map.tilesetSize.x / 2, 0, map.tilesetSize.y / -2);

...

tx += offset.x;
ty -= offset.z;
Kind Regards,
Infinity Code Team

Re: Range Around Transform

Thanks, Alex! That works smile

Re: Range Around Transform

Hi Alex,

We are getting really close! The mechanics and offsets are now working, and the next piece is that the map projection is off.

I have again uploaded some GIFs to imgur.com https://imgur.com/a/v8SzcAK
The 1st gif shows the the expected behavior from Mapbox: when I move around, the map itself should be in place; the map is to world scale, so moving 1 unit will be like 1 meter. When panning around (moving the camera), the objects stay where it is supposed to on the map. In Unity space, the objects and the map does not move at all.

The 2nd gif is from Online Maps. When moving around (the camera, to which the Range Around Transform script above is attached), while the objects themselves stayed, the Online Maps own plane is moving, and the map inside is itself also moving. This causes the objects to appear to be floating when the camera moves.

The 3rd gif is the Mapbox plane, from a higher angle. When the camera moves, the plane itself stays in place, and it relocates itself and reloads the map smoothly.

The 4th gif is Online Maps. Notice that both the plane and the map inside moves, so it does not maintain the same projection with Unity space.

The idea is to have the map physically laid over Unity space, and moving around in Unity space should reveal sections of the map physically correctly (1 Unity unit = 1 real world meter). (I hope this makes sense)

Re: Range Around Transform

Video:
https://www.dropbox.com/s/va7l7ljxemze0 … 1.mp4?dl=0

I just put the box over the building, and as you can see it is always displayed correctly.

In your gif, I see that the map is not positioned correctly.
Most likely this happens because you use Transform Scale != (1, 1, 1). I'm right?
If so, use Size (in scene) to make the desired map size, or include scale into the calculation of the center point and offset.

Kind Regards,
Infinity Code Team

Re: Range Around Transform

Oh you are right! I didn't use the Transform Scale, but used both Width and Height in Pixels and Size in Scene settings. The Width and height were double that of the Size. Now I set the Width and Height to the same value as Size in scene, and the drifting is gone!

I think this is the main problem I have been facing with Online Maps. Thanks for solving it for us!

Another question (sorry for having so many!). I have signed up for a Google Maps API Key, but I don't see where to enter it in the Online Maps component. Right now I just copied the string from SnazzyMaps, and it works, but I don't know if it's legal?

Re: Range Around Transform

Fix:

offset.x = offset.x / OnlineMapsUtils.tileSize / map.tilesetSize.x * map.tilesetWidth;
offset.z = offset.z / OnlineMapsUtils.tileSize / map.tilesetSize.y * map.tilesetHeight;

100% legal way:
https://developers.google.com/maps/documentation/tile/

Some time ago I noticed that URL of requests for Google Maps tiles may contain API key.
I have not yet seen any official information about this.
So, most likely some changes will be announced soon (perhaps on Google I/O).

Kind Regards,
Infinity Code Team

Re: Range Around Transform

Right now I'm following the set up guide to set up Online Maps, using the SnazzyMaps method. I kept the &key=[snazzy's API] part and replaced it with our own key. I noticed that the OnlineMaps component however will strip that key parameter if I use the wizard. It does work without the key parameter, but I'm unsure if it's legal

For the Tile API, it's not public. Do you know if it's legal to keep using the SnazzyMaps/JavaScript method adding the Key parameter?

Re: Range Around Transform

Most likely not, it is not legal.

Kind Regards,
Infinity Code Team

Re: Range Around Transform

OK, thank you.