Topic: Let Map contains all Drawing element

Hi, I am working on adding some lines on OnlineMapsTileset. 
This time I want to see the whole drawing element( ie. PolyLine, ... ) that Map focus.
Like Google Maps Api V3 's fitbounds(), but somehow OnlineMaps.instance.positionRange not do that tricks.

As a result, I run through all points in PolyLine and generate a Bounding Box ( bound by lat, lng ).
If I get the best fit zoom, I will solve this problem as I can setPositionAndZoom by center of BoundingBox and b-f zoom.

So, the question is, if there is a solution to let map focus on specific area(latlng bound)?
if not, how can I get best fit zoom by bounding box?

thanks a lot!!!!

Re: Let Map contains all Drawing element

Hello.

OnlineMapsUtils.GetCenterPointAndZoom
http://infinity-code.com/doxygen/online … cc18081dc8

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: Let Map contains all Drawing element

Wow!!  That's something I need!!
Thanks you, Alex!

Re: Let Map contains all Drawing element

Hello ,

There are some weird behavior.
If my PolyLine cross the International Date Line(180 lat), the center will be place at (0 lat).

I am looking forward to some solution to solve this, thanks again!

Re: Let Map contains all Drawing element

Fixed.
Next update will contain this fix:

public static void GetCenterPointAndZoom(OnlineMapsMarkerBase[] markers, out Vector2 center, out int zoom)
{
    center = new Vector2();
    zoom = 3;
    if (markers == null || markers.Length == 0) return;

    OnlineMaps api = OnlineMaps.instance;
    OnlineMapsProjection projection = api.projection;

    double mx, my;
    markers[0].GetPosition(out mx, out my);
    double minX = mx;
    double minY = my;
    double maxX = mx;
    double maxY = my;

    for (int i = 1; i < markers.Length; i++)
    {
        OnlineMapsMarkerBase marker = markers[i];
        marker.GetPosition(out mx, out my);

        double rx = mx - minX;
        if (rx > 180) mx -= 360;
        else if (rx < -180) mx += 360;

        if (mx < minX) minX = mx;
        if (mx > maxX) maxX = mx;

        if (my < minY) minY = my;
        if (my > maxY) maxY = my;
    }

    double sx = maxX - minX;
    double sy = maxY - minY;

    center = new Vector2((float)(sx / 2 + minX), (float)(sy / 2 + minY));

    if (center.x < -180) center.x += 360;
    else if (center.x > 180) center.x -= 360;

    int width = api.width;
    int height = api.height;

    float countX = width / (float)tileSize / 2;
    float countY = height / (float)tileSize / 2;

    bool useZoomMin = false;

    for (int z = 20; z > 4; z--)
    {
        bool success = true;

        double bx, by;
        projection.CoordinatesToTile(center.x, center.y, z, out bx, out by);
        int _mx = 1 << z;
        int hx = 1 << (z - 1);

        foreach (OnlineMapsMarkerBase marker in markers)
        {
            marker.GetPosition(out mx, out my);

            double px, py;
            projection.CoordinatesToTile(mx, my, z, out px, out py);

            if (px - bx < -hx) px += _mx;
            else if (px - bx > hx) px -= _mx;

            px -= bx - countX;
            py -= by - countY;

            if (marker is OnlineMapsMarker)
            {
                useZoomMin = true;
                OnlineMapsMarker m = marker as OnlineMapsMarker;
                OnlineMapsVector2i ip = m.GetAlignedPosition(new OnlineMapsVector2i((int)(px * tileSize), (int)(py * tileSize)));
                if (ip.x < 0 || ip.y < 0 || ip.x + m.width > width || ip.y + m.height > height)
                {
                    success = false;
                    break;
                }
            }
            else if (marker is OnlineMapsMarker3D)
            {
                if (px < 0 || py < 0 || px > width || py > height)
                {
                    success = false;
                    break;
                }
            }
            else
            {
                throw new Exception("Wrong marker type");
            }
        }
        if (success)
        {
            zoom = z;
            if (useZoomMin) zoom -= 1;
            return;
        }
    }

    zoom = 3;
}

public static void GetCenterPointAndZoom(Vector2[] positions, out Vector2 center, out int zoom)
{
    center = new Vector2();
    zoom = 3;
    if (positions == null || positions.Length == 0) return;

    OnlineMaps api = OnlineMaps.instance;
    OnlineMapsProjection projection = api.projection;

    Vector2 p = positions[0];
    float minX = p.x;
    float minY = p.y;
    float maxX = p.x;
    float maxY = p.y;

    for (int i = 1; i < positions.Length; i++)
    {
        p = positions[i];
        float px = p.x;

        float rx = px - minX;
        if (rx > 180) px -= 360;
        else if (rx < -180) px += 360;

        if (px < minX) minX = px;
        if (px > maxX) maxX = px;

        if (p.y < minY) minY = p.y;
        if (p.y > maxY) maxY = p.y;
    }

    float sx = maxX - minX;
    float sy = maxY - minY;

    center = new Vector2(sx / 2 + minX, sy / 2 + minY);

    if (center.x < -180) center.x += 360;
    else if (center.x > 180) center.x -= 360;

    int width = api.width;
    int height = api.height;

    float countX = width / (float)tileSize / 2;
    float countY = height / (float)tileSize / 2;

    for (int z = 20; z > 4; z--)
    {
        bool success = true;

        int mx = 1 << z;
        int hx = 1 << (z - 1);
        double cx, cy;
        projection.CoordinatesToTile(center.x, center.y, z, out cx, out cy);

        foreach (Vector2 pos in positions)
        {
            double px, py;
            projection.CoordinatesToTile(pos.x, pos.y, z, out px, out py);

            if (px - cx < -hx) px += mx;
            else if (px - cx > hx) px -= mx;

            px -= cx - countX;
            py -= cy - countY;

            if (px < 0 || py < 0 || px > width || py > height)
            {
                success = false;
                break;
            }
        }
        if (success)
        {
            zoom = z;
            return;
        }
    }

    zoom = 3;
}
Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: Let Map contains all Drawing element

Hi, Alex

It works!!!  Thanks for your amazing fixed!