public override Vector2 GetCoords(Vector2 position)
    {
        if (!RectTransformUtility.RectangleContainsScreenPoint(image.rectTransform, position, worldCamera))
        {
            return(Vector2.zero);
        }

        Vector2 point;

        RectTransformUtility.ScreenPointToLocalPointInRectangle(image.rectTransform, position, worldCamera, out point);

        Rect rect = image.GetPixelAdjustedRect();

        Vector2 size = (rect.max - point);

        size.x = size.x / rect.size.x;
        size.y = size.y / rect.size.y;

        Vector2 r = new Vector2((size.x - .5f), (size.y - .5f));

        int countX = api.width / OnlineMapsUtils.tileSize;
        int countY = api.height / OnlineMapsUtils.tileSize;

        double px, py;

        api.GetPosition(out px, out py);
        OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py);

        px -= countX * r.x;
        py += countY * r.y;

        OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out px, out py);
        return(new Vector2((float)px, (float)py));
    }
    public override bool GetCoords(out double lng, out double lat, Vector2 position)
    {
        RaycastHit hit;

        lng = lat = 0;
        if (!Physics.Raycast(Camera.main.ScreenPointToRay(position), out hit))
        {
            return(false);
        }

        if (hit.collider.gameObject != gameObject)
        {
            return(false);
        }

        Vector3 size = (cl.bounds.max - hit.point);

        size.x = size.x / cl.bounds.size.x;
        size.y = size.y / cl.bounds.size.y;

        Vector2 r = new Vector3((size.x - .5f), (size.y - .5f));

        int countX = api.width / OnlineMapsUtils.tileSize;
        int countY = api.height / OnlineMapsUtils.tileSize;

        double px, py;

        api.GetPosition(out px, out py);
        OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py);
        px -= countX * r.x;
        py += countY * r.y;

        OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out lng, out lat);
        return(true);
    }
    private Vector2 GetCoords3D(Vector2 position)
    {
        RaycastHit hit;

        if (!Physics.Raycast(Camera.main.ScreenPointToRay(position), out hit))
        {
            return(Vector2.zero);
        }

        if (hit.collider.gameObject != gameObject)
        {
            return(Vector2.zero);
        }

        Vector3 size = (cl.bounds.max - hit.point);

        size.x = size.x / cl.bounds.size.x;
        size.y = size.y / cl.bounds.size.y;

        Vector2 r = new Vector3((size.x - .5f), (size.y - .5f));

        int countX = api.width / OnlineMapsUtils.tileSize;
        int countY = api.height / OnlineMapsUtils.tileSize;

        double px, py;

        api.GetPosition(out px, out py);
        OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py);
        px -= countX * r.x;
        py += countY * r.y;

        OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out px, out py);
        return(new Vector2((float)px, (float)py));
    }
예제 #4
0
    private OnlineMapsVector2i GetBackBufferPosition(double px, double py, OnlineMapsVector2i _bufferPosition, int zoom, int apiWidth, int apiHeight)
    {
        OnlineMapsUtils.LatLongToTiled(px, py, zoom, out px, out py);

        int countX = apiWidth / OnlineMapsUtils.tileSize + 2;
        int countY = apiHeight / OnlineMapsUtils.tileSize + 2;

        px -= countX / 2f + _bufferPosition.x - 1;
        py -= countY / 2f + _bufferPosition.y - 1;

        int ix = (int)((px / countX) * width);
        int iy = (int)((py / countY) * height);

        return(new OnlineMapsVector2i(ix, iy));
    }
    public override bool GetCoords(out double lng, out double lat, Vector2 position)
    {
        Rect   rect = screenRect;
        int    countX = api.texture.width / OnlineMapsUtils.tileSize;
        int    countY = api.texture.height / OnlineMapsUtils.tileSize;
        double px, py;

        api.GetPosition(out px, out py);
        OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py);
        double rx = (rect.center.x - position.x) / rect.width * 2;
        double ry = (rect.center.y - position.y) / rect.height * 2;

        px -= countX / 2f * rx;
        py += countY / 2f * ry;
        OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out lng, out lat);
        return(true);
    }
    public override Vector2 GetCoords(Vector2 position)
    {
        Rect   rect = screenRect;
        int    countX = api.texture.width / OnlineMapsUtils.tileSize;
        int    countY = api.texture.height / OnlineMapsUtils.tileSize;
        double px, py;

        api.GetPosition(out px, out py);
        OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py);
        float rx = (rect.center.x - position.x) / rect.width * 2;
        float ry = (rect.center.y - position.y) / rect.height * 2;

        px -= countX / 2f * rx;
        py += countY / 2f * ry;
        OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out px, out py);
        return(new Vector2((float)px, (float)py));
    }
예제 #7
0
    /// <summary>
    /// Converts geographical coordinate to position in the scene relative to the top-left corner of the map in map space.
    /// </summary>
    /// <param name="lng">Longitude</param>
    /// <param name="lat">Latitude</param>
    /// <param name="px">Relative position X</param>
    /// <param name="py">Relative position Y</param>
    public virtual void GetPosition(double lng, double lat, out double px, out double py)
    {
        double tx, ty;
        double dx, dy, dtx, dty;

        OnlineMapsUtils.LatLongToTiled(lng, lat, api.zoom, out dx, out dy);
        api.GetTopLeftPosition(out tx, out ty);
        OnlineMapsUtils.LatLongToTiled(tx, ty, api.zoom, out dtx, out dty);
        dx -= dtx;
        dy -= dty;
        int maxX = 1 << api.zoom;

        if (dx < -maxX / 2)
        {
            dx += maxX;
        }
        px = dx * OnlineMapsUtils.tileSize;
        py = dy * OnlineMapsUtils.tileSize;
    }
예제 #8
0
    public override bool GetCoords(out double lng, out double lat, Vector2 position)
    {
        RaycastHit hit;

        lng = lat = 0;
        if (!Physics.Raycast(activeCamera.ScreenPointToRay(position), out hit))
        {
            return(false);
        }

        if (hit.collider.gameObject != gameObject)
        {
            return(false);
        }

        Renderer     render       = hit.collider.GetComponent <Renderer>();
        MeshCollider meshCollider = hit.collider as MeshCollider;

        if (render == null || render.sharedMaterial == null || render.sharedMaterial.mainTexture == null || meshCollider == null)
        {
            return(false);
        }

        Vector2 r = hit.textureCoord;

        r.x = r.x - 0.5f;
        r.y = r.y - 0.5f;

        int countX = api.width / OnlineMapsUtils.tileSize;
        int countY = api.height / OnlineMapsUtils.tileSize;

        double px, py;

        api.GetPosition(out px, out py);
        OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py);

        px += countX * r.x;
        py -= countY * r.y;
        OnlineMapsUtils.TileToLatLong(px, py, api.zoom, out lng, out lat);
        return(true);
    }
예제 #9
0
    /// <summary>
    /// Updates billboard markers.
    /// </summary>
    protected void UpdateMarkersBillboard()
    {
        if (markersGameObject == null)
        {
            InitMarkersMesh();
        }
        if (markerBillboards == null)
        {
            markerBillboards = new Dictionary <int, OnlineMapsMarkerBillboard>();
        }

        double tlx, tly, brx, bry;

        api.GetTopLeftPosition(out tlx, out tly);
        api.GetBottomRightPosition(out brx, out bry);
        if (brx < tlx)
        {
            brx += 360;
        }

        int maxX = (2 << api.buffer.apiZoom) / 2;

        double px, py;

        OnlineMapsUtils.LatLongToTiled(tlx, tly, api.zoom, out px, out py);

        float yScale = GetBestElevationYScale(tlx, tly, brx, bry);

        Bounds  mapBounds      = cl.bounds;
        Vector3 positionOffset = transform.position - mapBounds.min;
        Vector3 size           = mapBounds.size;

        size = transform.rotation * size;
        if (api.target == OnlineMapsTarget.tileset)
        {
            positionOffset.x -= size.x;
        }

        foreach (KeyValuePair <int, OnlineMapsMarkerBillboard> billboard in markerBillboards)
        {
            billboard.Value.used = false;
        }

        foreach (OnlineMapsMarker marker in api.markers)
        {
            if (!marker.enabled || !marker.range.InRange(api.zoom))
            {
                continue;
            }
            float mx = marker.position.x;
            if (!(((mx > tlx && mx < brx) || (mx + 360 > tlx && mx + 360 < brx) ||
                   (mx - 360 > tlx && mx - 360 < brx)) &&
                  marker.position.y < tly && marker.position.y > bry))
            {
                continue;
            }

            int markerHashCode = marker.GetHashCode();
            OnlineMapsMarkerBillboard markerBillboard = null;

            if (!markerBillboards.ContainsKey(markerHashCode))
            {
                markerBillboard = OnlineMapsMarkerBillboard.Create(marker);
                markerBillboard.transform.parent = markersGameObject.transform;

                markerBillboards.Add(markerHashCode, markerBillboard);
            }
            else
            {
                markerBillboard = markerBillboards[markerHashCode];
            }

            float sx = size.x / api.width * marker2DSize * marker.scale;
            float sz = size.z / api.height * marker2DSize * marker.scale;
            float s  = Mathf.Max(sx, sz);
            markerBillboard.transform.localScale = new Vector3(-s, s, s);

            Vector2 p = OnlineMapsUtils.LatLongToTilef(marker.position, api.buffer.apiZoom);

            p.x  = Mathf.Repeat(p.x - (float)px, maxX);
            p.y -= (float)py;

            float x = -p.x / api.width * OnlineMapsUtils.tileSize * size.x + positionOffset.x;
            float z = p.y / api.height * OnlineMapsUtils.tileSize * size.z - positionOffset.z;

            float y = GetElevationValue(x, z, yScale, tlx, tly, brx, bry);

            markerBillboard.transform.localPosition = transform.rotation * new Vector3(x, y, z);
            markerBillboard.used = true;
        }

        List <int> keysForRemove = new List <int>();

        foreach (KeyValuePair <int, OnlineMapsMarkerBillboard> billboard in markerBillboards)
        {
            if (!billboard.Value.used)
            {
                billboard.Value.Dispose();
                keysForRemove.Add(billboard.Key);
            }
        }

        foreach (int key in keysForRemove)
        {
            markerBillboards.Remove(key);
        }
    }
예제 #10
0
    public override void Update(double tlx, double tly, double brx, double bry, int zoom)
    {
        if (instance == null)
        {
            Debug.Log("No instance");
            return;
        }

        if (!range.InRange(zoom))
        {
            enabled = false;
        }
        else if (position.y > tly || position.y < bry)
        {
            enabled = false;
        }
        else if (tlx < brx && (position.x < tlx || position.x > brx))
        {
            enabled = false;
        }
        else if (tlx > brx && position.x < tlx && position.x > brx)
        {
            enabled = false;
        }
        else
        {
            enabled = true;
        }

        if (!enabled)
        {
            return;
        }

        if (_prefab != prefab)
        {
            Reinit(tlx, tly, brx, bry, zoom);
        }

        double mx, my;

        OnlineMapsUtils.LatLongToTiled(position.x, position.y, zoom, out mx, out my);

        double ttlx, ttly, tbrx, tbry;

        OnlineMapsUtils.LatLongToTiled(tlx, tly, zoom, out ttlx, out ttly);
        OnlineMapsUtils.LatLongToTiled(brx, bry, zoom, out tbrx, out tbry);

        int maxX = (2 << zoom) / 2;

        OnlineMaps api    = OnlineMaps.instance;
        Bounds     bounds = api.GetComponent <Collider>().bounds;

        double sx = tbrx - ttlx;

        if (sx < 0)
        {
            sx += maxX;
        }

        double mpx = mx - ttlx;

        if (mpx < 0)
        {
            mpx += maxX;
        }

        double px = mpx / sx;
        double pz = (ttly - my) / (ttly - tbry);

        _relativePosition = new Vector3((float)px, 0, (float)pz);

        if (OnlineMapsControlBase.instance is OnlineMapsTileSetControl)
        {
            px = -api.tilesetSize.x / 2 - (px - 0.5) * api.tilesetSize.x;
            pz = api.tilesetSize.y / 2 + (pz - 0.5) * api.tilesetSize.y;
        }
        else
        {
            Vector3 center = bounds.center;
            Vector3 size   = bounds.size;
            px = center.x - (px - 0.5) * size.x - api.transform.position.x;
            pz = center.z + (pz - 0.5) * size.z - api.transform.position.z;
        }

        Vector3 oldPosition = instance.transform.localPosition;
        float   y           = 0;

        if (OnlineMapsControlBase.instance is OnlineMapsTileSetControl)
        {
            OnlineMapsTileSetControl control = OnlineMapsTileSetControl.instance;
            y = control.GetElevationValue((float)px, (float)pz, control.GetBestElevationYScale(tlx, tly, brx, bry), tlx, tly, brx, bry);
        }

        Vector3 newPosition = new Vector3((float)px, y, (float)pz);

        instance.transform.localPosition = newPosition;
        if (oldPosition != newPosition && OnPositionChanged != null)
        {
            OnPositionChanged(this);
        }
    }
예제 #11
0
    protected List <Vector2> GetLocalPoints(List <Vector2> points, bool closed = false)
    {
        double sx, sy;

        OnlineMapsUtils.LatLongToTiled(tlx, tly, api.buffer.apiZoom, out sx, out sy);

        int maxX = 1 << api.zoom;

        int off = closed ? 1 : 0;

        List <Vector2> localPoints = new List <Vector2>();

        double ppx = 0;

        for (int i = 0; i < points.Count + off; i++)
        {
            int ci = i;
            if (ci >= points.Count)
            {
                ci -= points.Count;
            }
            double px, py;
            OnlineMapsUtils.LatLongToTiled(points[ci].x, points[ci].y, api.buffer.apiZoom, out px, out py);

            px -= sx;
            py -= sy;

            if (i == 0)
            {
                if (px < maxX * -0.25)
                {
                    px += maxX;
                }
                else if (px > maxX * 0.75)
                {
                    px -= maxX;
                }
            }
            else
            {
                double gpx = px + maxX;
                double lpx = px - maxX;

                if (Math.Abs(ppx - gpx) < Math.Abs(ppx - px))
                {
                    px = gpx;
                }
                else if (Math.Abs(ppx - lpx) < Math.Abs(ppx - px))
                {
                    px = lpx;
                }
            }

            ppx = px;

            double rx1 = (px * OnlineMapsUtils.tileSize) / api.tilesetWidth * api.tilesetSize.x;
            double ry1 = (py * OnlineMapsUtils.tileSize) / api.tilesetHeight * api.tilesetSize.y;

            Vector2 np = new Vector2((float)rx1, (float)ry1);
            localPoints.Add(np);
        }
        return(localPoints);
    }
예제 #12
0
    protected void DrawLineToBuffer(Color[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight,
                                    int zoom, List <Vector2> points, Color color, float weight, bool closed)
    {
        if (color.a == 0)
        {
            return;
        }

        double sx, sy;

        OnlineMapsUtils.LatLongToTiled(tlx, tly, zoom, out sx, out sy);

        int maxX = 1 << zoom;

        int off = closed ? 1 : 0;

        List <Vector2> localPoints = new List <Vector2>();

        double ppx = 0;

        for (int i = 0; i < points.Count + off; i++)
        {
            int ci = i;
            if (ci >= points.Count)
            {
                ci -= points.Count;
            }
            double px, py;
            OnlineMapsUtils.LatLongToTiled(points[ci].x, points[ci].y, zoom, out px, out py);

            px -= sx;
            py -= sy;

            if (i == 0)
            {
                if (px < maxX * -0.25)
                {
                    px += maxX;
                }
                else if (px > maxX * 0.75)
                {
                    px -= maxX;
                }
            }
            else
            {
                double gpx = px + maxX;
                double lpx = px - maxX;

                if (Math.Abs(ppx - gpx) < Math.Abs(ppx - px))
                {
                    px = gpx;
                }
                else if (Math.Abs(ppx - lpx) < Math.Abs(ppx - px))
                {
                    px = lpx;
                }
            }

            ppx = px;

            double rx1 = px + sx;
            double ry1 = py + sy;

            Vector2 np = new Vector2((float)rx1, (float)ry1);
            localPoints.Add(np);
        }

        int w = Mathf.RoundToInt(weight);

        for (int j = 0; j < localPoints.Count - 1; j++)
        {
            Vector2 p1 = localPoints[j] - bufferPosition;
            Vector2 p2 = localPoints[j + 1] - bufferPosition;

            if (p1.x > maxX && p2.x > maxX)
            {
                p1.x -= maxX;
                p2.x -= maxX;
            }

            Vector2 from = p1 * OnlineMapsUtils.tileSize;
            Vector2 to   = p2 * OnlineMapsUtils.tileSize;

            float stY          = Mathf.Clamp(Mathf.Min(from.y, to.y) - w, 0, bufferHeight);
            float stX          = Mathf.Clamp(Mathf.Min(from.x, to.x) - w, 0, bufferWidth);
            float endY         = Mathf.Clamp(Mathf.Max(from.y, to.y) + w, 0, bufferHeight);
            float endX         = Mathf.Clamp(Mathf.Max(from.x, to.x) + w, 0, bufferWidth);
            int   strokeOuter2 = w * w;

            int sqrW = w * w;

            int     lengthX = Mathf.RoundToInt(endX - stX);
            int     lengthY = Mathf.RoundToInt(endY - stY);
            Vector2 start   = new Vector2(stX, stY);

            for (int y = 0; y < lengthY; y++)
            {
                for (int x = 0; x < lengthX; x++)
                {
                    Vector2 p      = new Vector2(x, y) + start;
                    Vector2 center = p + halfVector;
                    float   dist   = (center - center.NearestPointStrict(from, to)).sqrMagnitude;

                    if (dist <= strokeOuter2)
                    {
                        Color c = Color.black;

                        Vector2[] samples =
                        {
                            p + sampleV1,
                            p + sampleV2,
                            p + sampleV3,
                            p + sampleV4
                        };
                        int   bufferIndex = (int)p.y * bufferWidth + (int)p.x;
                        Color pc          = buffer[bufferIndex];
                        for (int i = 0; i < 4; i++)
                        {
                            dist = (samples[i] - samples[i].NearestPointStrict(from, to)).sqrMagnitude;
                            if (dist < sqrW)
                            {
                                c += Color.Lerp(pc, color, color.a);
                            }
                            else
                            {
                                c += pc;
                            }
                        }
                        c /= 4;
                        buffer[bufferIndex] = c;
                    }
                }
            }
        }
    }
예제 #13
0
    private void UpdateBuildingsPosition()
    {
        Bounds  bounds              = new Bounds();
        Vector2 topLeftPosition     = OnlineMaps.instance.topLeftPosition;
        Vector2 bottomRightPosition = OnlineMaps.instance.bottomRightPosition;

        bounds.min = new Vector3(topLeftPosition.x, bottomRightPosition.y);
        bounds.max = new Vector3(bottomRightPosition.x, topLeftPosition.y);

        List <string> unusedKeys = new List <string>();

        bool useElevation = OnlineMapsTileSetControl.instance.useElevation;

        foreach (KeyValuePair <string, OnlineMapsBuildingBase> building in buildings)
        {
            if (!bounds.Intersects(building.Value.boundsCoords))
            {
                unusedKeys.Add(building.Key);
            }
            else
            {
                if (useElevation)
                {
                    Vector3 newPosition = OnlineMapsTileSetControl.instance.GetWorldPositionWithElevation(building.Value.centerCoordinates, topLeftPosition, bottomRightPosition);
                    building.Value.transform.position = newPosition;
                }
                else
                {
                    Vector3 newPosition = OnlineMapsTileSetControl.instance.GetWorldPosition(building.Value.centerCoordinates);
                    building.Value.transform.position = newPosition;
                }
            }
        }

        List <string> usedKeys    = new List <string>();
        List <string> destroyKeys = new List <string>();

        double px, py;

        api.GetPosition(out px, out py);
        OnlineMapsUtils.LatLongToTiled(px, py, api.zoom, out px, out py);

        float maxDistance = Mathf.Sqrt(Mathf.Pow(api.width / 2 / OnlineMapsUtils.tileSize, 2) + Mathf.Pow(api.height / 2 / OnlineMapsUtils.tileSize, 2)) * 2;

        foreach (KeyValuePair <string, OnlineMapsBuildingBase> building in unusedBuildings)
        {
            OnlineMapsBuildingBase value = building.Value;
            if (bounds.Intersects(value.boundsCoords))
            {
                usedKeys.Add(building.Key);
                Vector3 newPosition = OnlineMapsTileSetControl.instance.GetWorldPosition(value.centerCoordinates);
                value.transform.position = newPosition;
            }
            else
            {
                Vector2 buildingTilePos = OnlineMapsUtils.LatLongToTilef(value.centerCoordinates, api.zoom);
                if ((buildingTilePos - new Vector2((float)px, (float)py)).magnitude > maxDistance)
                {
                    destroyKeys.Add(building.Key);
                }
            }
        }

        foreach (string key in unusedKeys)
        {
            OnlineMapsBuildingBase value = buildings[key];
            value.gameObject.SetActive(false);
            unusedBuildings.Add(key, value);
            buildings.Remove(key);
        }

        foreach (string key in usedKeys)
        {
            OnlineMapsBuildingBase value = unusedBuildings[key];
            if (maxActiveBuildings > 0 && buildings.Count >= maxActiveBuildings)
            {
                break;
            }
            if (OnShowBuilding != null && !OnShowBuilding(value))
            {
                continue;
            }
            value.gameObject.SetActive(true);
            buildings.Add(key, value);
            unusedBuildings.Remove(key);
        }

        foreach (string key in destroyKeys)
        {
            OnlineMapsBuildingBase value = unusedBuildings[key];
            if (OnBuildingDispose != null)
            {
                OnBuildingDispose(value);
            }
            DestroyImmediate(value.gameObject);
            unusedBuildings.Remove(key);
        }

        if (destroyKeys.Count > 0)
        {
            OnlineMaps.instance.needGC = true;
        }
    }