private void OnGUI()
        {
            if (GUI.Button(new Rect(5, 5, 100, 30), "Calc"))
            {
                // Calculate the distance in km between locations.
                float distance = OnlineMapsUtils.DistanceBetweenPoints(userCoordinares, markerCoordinates).magnitude;

                Debug.Log("Distance: " + distance);

                int zoom = 15;
                int maxX = 1 << zoom;

                // Calculate the tile position of locations.
                Vector2 userTile   = OnlineMapsUtils.LatLongToTilef(userCoordinares, zoom);
                Vector2 markerTile = OnlineMapsUtils.LatLongToTilef(markerCoordinates, zoom);

                // Calculate the angle between locations.
                float angle = OnlineMapsUtils.Angle2D(userTile, markerTile);
                if (Mathf.Abs(userTile.x - markerTile.x) > maxX / 2)
                {
                    angle = 360 - angle;
                }

                Debug.Log("Angle: " + angle);

                // Calculate relative angle between locations.
                float relativeAngle = angle - compassTrueHeading;
                Debug.Log("Relative angle: " + relativeAngle);
            }
        }
示例#2
0
    /// <summary>
    /// Determines if the marker at the specified coordinates.
    /// </summary>
    /// <param name="positionLatLng">
    /// Position.
    /// </param>
    /// <param name="zoom">
    /// The zoom.
    /// </param>
    /// <returns>
    /// True if the marker in position, false if not.
    /// </returns>
    public bool HitTest(Vector2 positionLatLng, int zoom)
    {
        if (OnlineMapsControlBase.instance is OnlineMapsTileSetControl)
        {
            OnlineMapsVector2i pos = OnlineMapsUtils.LatLongToTilef(position, zoom) * OnlineMapsUtils.tileSize;
            float w = width * scale;
            float h = height * scale;

            pos = GetAlignedPosition(pos);
            Vector2 mPos = OnlineMapsUtils.LatLongToTilef(positionLatLng, zoom) * OnlineMapsUtils.tileSize;

            return(mPos.x >= pos.x + w * (markerColliderRect.x + 0.5f) && mPos.x <= pos.x + w * (markerColliderRect.xMax + 0.5f) && mPos.y >= pos.y + w * (markerColliderRect.y + 0.5f) && mPos.y <= pos.y + h * (markerColliderRect.yMax + 0.5f));
        }
        else
        {
            OnlineMapsVector2i pos = OnlineMapsUtils.LatLongToTilef(position, zoom) * OnlineMapsUtils.tileSize;
            int w = width;
            int h = height;

            pos = GetAlignedPosition(pos);
            Vector2 mPos = OnlineMapsUtils.LatLongToTilef(positionLatLng, zoom) * OnlineMapsUtils.tileSize;

            return(mPos.x >= pos.x + w * (markerColliderRect.x + 0.5f) && mPos.x <= pos.x + w * (markerColliderRect.xMax + 0.5f) && mPos.y >= pos.y + w * (markerColliderRect.y + 0.5f) && mPos.y <= pos.y + h * (markerColliderRect.yMax + 0.5f));
        }
    }
    private Vector2 GetCoords2D(Vector2 position)
    {
        RaycastHit2D hit = Physics2D.GetRayIntersection(Camera.main.ScreenPointToRay(position), Mathf.Infinity);

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

        Vector3 size = (cl2D.bounds.max - new Vector3(hit.point.x, hit.point.y));

        size.x = size.x / cl2D.bounds.size.x;
        size.y = size.y / cl2D.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;

        Vector2 p = OnlineMapsUtils.LatLongToTilef(api.position, api.zoom);

        p.x -= countX * r.x;
        p.y += countY * r.y;

        return(OnlineMapsUtils.TileToLatLong(p, api.zoom));
    }
示例#4
0
        private void OnGUI()
        {
            // On click button, starts movement
            if (GUI.Button(new Rect(5, 5, 100, 30), "Goto marker"))
            {
                // from current map position
                fromPosition = OnlineMaps.instance.position;

                // to GPS position;
                toPosition = OnlineMaps.instance.GetComponent <OnlineMapsLocationService>().position;

                // calculates tile positions
                Vector2 fromTile = OnlineMapsUtils.LatLongToTilef(fromPosition, OnlineMaps.instance.zoom);
                Vector2 toTile   = OnlineMapsUtils.LatLongToTilef(toPosition, OnlineMaps.instance.zoom);

                // if tile offset < 4, then start smooth movement
                if ((fromTile - toTile).magnitude < 4)
                {
                    // set relative position 0
                    angle = 0;

                    // start movement
                    isMovement = true;
                }
                else // too far
                {
                    OnlineMaps.instance.position = toPosition;
                }
            }
        }
示例#5
0
 public void Add(OnlineMapsMarker marker)
 {
     markers.Add(marker);
     center            = markers.Aggregate(Vector2.zero, (current, m) => current + m.position) / markers.Count;
     instance.position = center;
     tilePosition      = OnlineMapsUtils.LatLongToTilef(center, zoom);
     instance.label    = "Group. Count: " + markers.Count;
 }
示例#6
0
    private Rect GetMarkerRect(OnlineMapsMarker marker)
    {
        const int s = OnlineMapsUtils.tileSize;
        Vector2   p = OnlineMapsUtils.LatLongToTilef(marker.position, bufferZoom);

        p.x -= bufferPosition.x;
        p.y -= bufferPosition.y;
        OnlineMapsVector2i ip = marker.GetAlignedPosition(new OnlineMapsVector2i((int)(p.x * s), (int)(p.y * s)));

        return(new Rect(ip.x, ip.y, marker.width, marker.height));
    }
示例#7
0
        private void GroupMarkers()
        {
            List <MarkerGroup> groups = new List <MarkerGroup>();

            for (int zoom = 20; zoom >= 3; zoom--)
            {
                List <OnlineMapsMarker> ms = markers.Select(m => m).ToList();

                for (int j = 0; j < ms.Count - 1; j++)
                {
                    OnlineMapsMarker marker = ms[j];
                    MarkerGroup      group  = null;
                    Vector2          pos    = OnlineMapsUtils.LatLongToTilef(marker.position, zoom);

                    int k = j + 1;

                    while (k < ms.Count)
                    {
                        OnlineMapsMarker marker2 = ms[k];
                        Vector2          pos2    = OnlineMapsUtils.LatLongToTilef(marker2.position, zoom);
                        if ((pos - pos2).magnitude < distance)
                        {
                            if (group == null)
                            {
                                group = new MarkerGroup(zoom, groupTexture);
                                groups.Add(group);
                                group.Add(marker);
                                if (marker.range.min == 3)
                                {
                                    marker.range.min = zoom + 1;
                                }
                            }
                            group.Add(marker2);
                            if (marker2.range.min == 3)
                            {
                                marker2.range.min = zoom + 1;
                            }
                            ms.RemoveAt(k);
                            pos = group.tilePosition;
                        }
                        else
                        {
                            k++;
                        }
                    }
                }
            }

            foreach (MarkerGroup g in groups)
            {
                g.Apply(font);
            }
        }
    /// <summary>
    /// Converts geographical coordinate to position in the scene relative to the top-left corner of the map in map space.
    /// </summary>
    /// <param name="coords">Geographical coordinate</param>
    /// <returns>Scene position (in map space)</returns>
    public virtual Vector2 GetPosition(Vector2 coords)
    {
        Vector2 pos     = OnlineMapsUtils.LatLongToTilef(coords, api.zoom);
        Vector2 topLeft = OnlineMapsUtils.LatLongToTilef(api.topLeftPosition, api.zoom);

        pos -= topLeft;
        int maxX = 1 << api.zoom;

        if (pos.x < -maxX / 2)
        {
            pos.x += maxX;
        }
        return(new Vector2(pos.x * OnlineMapsUtils.tileSize, pos.y * OnlineMapsUtils.tileSize));
    }
示例#9
0
        private void UpdateMesh()
        {
            _bufferPosition = null;
            _alpha          = alpha;

            int w1 = api.tilesetWidth / OnlineMapsUtils.tileSize;
            int h1 = api.tilesetHeight / OnlineMapsUtils.tileSize;

            int subMeshVX = 1;
            int subMeshVZ = 1;

            Vector2 subMeshSize = new Vector2(api.tilesetSize.x / w1, api.tilesetSize.y / h1);

            Vector2 topLeftPosition     = api.topLeftPosition;
            Vector2 bottomRightPosition = api.bottomRightPosition;

            Vector2 tlPos = OnlineMapsUtils.LatLongToTilef(topLeftPosition, api.zoom);
            Vector2 pos   = tlPos - bufferPosition;

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

            if (pos.x >= maxX)
            {
                pos.x -= maxX;
            }

            Vector3 startPos = new Vector3(subMeshSize.x * pos.x, 0, -subMeshSize.y * pos.y);

            int w = w1 + 2;
            int h = h1 + 2;

            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    UpdateMapSubMesh(x, y, w, h, subMeshSize, subMeshVX, subMeshVZ, startPos, 0, topLeftPosition,
                                     bottomRightPosition);
                }
            }

            overlayMesh.vertices = vertices;
            overlayMesh.uv       = uv;

            for (int i = 0; i < overlayMesh.subMeshCount; i++)
            {
                overlayMesh.SetTriangles(overlayMesh.GetTriangles(i), i);
            }

            overlayMesh.RecalculateBounds();
        }
    protected static List <Vector3> GetLocalPoints(List <OnlineMapsOSMNode> nodes)
    {
        OnlineMaps api          = OnlineMaps.instance;
        Vector2    startTilePos = OnlineMapsUtils.LatLongToTilef(api.topLeftPosition, api.buffer.apiZoom);

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

        float sw = OnlineMapsUtils.tileSize * api.tilesetSize.x / api.tilesetWidth;
        float sh = OnlineMapsUtils.tileSize * api.tilesetSize.y / api.tilesetHeight;

        for (int i = 0; i < nodes.Count; i++)
        {
            Vector2 p = OnlineMapsUtils.LatLongToTilef(nodes[i], api.buffer.apiZoom) - startTilePos;
            localPoints.Add(new Vector3(-p.x * sw, 0, p.y * sh));
        }
        return(localPoints);
    }
        private bool HasWater(float lat, float lng)
        {
            // Convert geo coordinates to tile coordinates
            Vector2 tilef = OnlineMapsUtils.LatLongToTilef(lng, lat, 3);

            const int countTileRowCol = 8;

            // Convert tile coordinates to texture coordinates (UV)
            tilef.x /= countTileRowCol;
            tilef.y /= countTileRowCol;

            // Check pixel color
            Color color = mapForDetectWater.GetPixelBilinear(tilef.x, 1 - tilef.y);

            Debug.Log(tilef);

            /*Debug.Log ("pixel color = " + color);
             *      Debug.Log ("water color = " + waterColor);*/
            return(color == waterColor);
        }
示例#12
0
    private Rect GetRect()
    {
        OnlineMaps api         = OnlineMaps.instance;
        Rect       controlRect = api.control.GetRect();
        Rect       uvRect      = api.control.uvRect;

        controlRect.width  /= uvRect.width;
        controlRect.height /= uvRect.height;
        controlRect.x      -= controlRect.width * uvRect.x;
        controlRect.y      -= controlRect.height * uvRect.y;
        Vector2 topLeft = OnlineMapsUtils.LatLongToTilef(api.buffer.topLeftPosition, api.buffer.apiZoom) * OnlineMapsUtils.tileSize;
        Vector2 pos     = GetAlignedPosition(OnlineMapsUtils.LatLongToTilef(position, api.buffer.apiZoom) * OnlineMapsUtils.tileSize);
        float   scaleX  = (controlRect.width / api.width);
        float   scaleY  = (controlRect.height / api.height);

        pos  -= topLeft;
        pos.x = Mathf.RoundToInt(pos.x * scaleX + controlRect.x);
        pos.y = Mathf.RoundToInt(controlRect.yMax - (pos.y + height) * scaleY);

        return(new Rect(pos.x, pos.y, width * scaleX, height * scaleY));
    }
    /// <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);
        }
    }
示例#14
0
    private void SetMarkerToBuffer(OnlineMapsMarker marker, Vector2 startPos, Vector2 endPos)
    {
        const int s  = OnlineMapsUtils.tileSize;
        float     mx = marker.position.x;

        if (!(((mx > startPos.x && mx < endPos.x) || (mx + 360 > startPos.x && mx + 360 < endPos.x) ||
               (mx - 360 > startPos.x && mx - 360 < endPos.x)) &&
              marker.position.y < startPos.y && marker.position.y > endPos.y))
        {
            return;
        }

#if !UNITY_WEBGL
        int maxCount = 20;
        while (marker.locked && maxCount > 0)
        {
            Thread.Sleep(1);
            maxCount--;
        }
#endif

        marker.locked = true;
        Vector2 p = OnlineMapsUtils.LatLongToTilef(marker.position, bufferZoom);
        p -= bufferPosition;

        int maxX = 1 << bufferZoom;

        if (p.x < 0)
        {
            p.x += maxX;
        }
        else if (p.x > maxX)
        {
            p.x -= maxX;
        }

        OnlineMapsVector2i ip = marker.GetAlignedPosition(new OnlineMapsVector2i((int)(p.x * s), (int)(p.y * s)));

        Color[] markerColors = marker.colors;
        if (markerColors == null || markerColors.Length == 0)
        {
            return;
        }

        int markerWidth  = marker.width;
        int markerHeight = marker.height;

        for (int y = 0; y < marker.height; y++)
        {
            if (ip.y + y < 0 || ip.y + y >= height)
            {
                continue;
            }

            int my = (markerHeight - y - 1) * markerWidth;

            for (int x = 0; x < marker.width; x++)
            {
                if (ip.x + x < 0 || ip.x + x >= width)
                {
                    continue;
                }

                try
                {
                    SetColorToBuffer(markerColors[my + x], ip, y, x);
                }
                catch
                {
                }
            }
        }

        marker.locked = false;
    }
示例#15
0
        private void UpdateMesh()
        {
            OnlineMapsTileSetControl control = OnlineMapsTileSetControl.instance;

            if (tilesetCollider == null)
            {
                tilesetCollider = control.GetComponent <Collider>();
            }
            Bounds bounds = tilesetCollider.bounds;

            // Clear overlay mesh
            overlayMesh.Clear(true);

            // Init verticles and normals
            float y = bounds.max.y + 0.5f;

            overlayMesh.vertices = new[]
            {
                new Vector3(bounds.min.x, y, bounds.min.z),
                new Vector3(bounds.min.x, y, bounds.max.z),
                new Vector3(bounds.max.x, y, bounds.max.z),
                new Vector3(bounds.max.x, y, bounds.min.z)
            };

            overlayMesh.normals = new[]
            {
                Vector3.up,
                Vector3.up,
                Vector3.up,
                Vector3.up
            };

            // Init overlay UV
            OnlineMaps api                 = OnlineMaps.instance;
            Vector2    topLeftPosition     = api.topLeftPosition;
            Vector2    bottomRightPosition = api.bottomRightPosition;

            Vector2 topLeftTile     = OnlineMapsUtils.LatLongToTilef(topLeftPosition, api.zoom);
            Vector2 bottomRightTile = OnlineMapsUtils.LatLongToTilef(bottomRightPosition, api.zoom);

            int maxTileCount = 1 << api.zoom;

            float uvX1 = topLeftTile.x / maxTileCount;
            float uvX2 = bottomRightTile.x / maxTileCount;

            if (uvX1 > uvX2)
            {
                uvX2 += 1;
            }

            float uvY1 = 1 - topLeftTile.y / maxTileCount;
            float uvY2 = 1 - bottomRightTile.y / maxTileCount;

            overlayMesh.uv = new[]
            {
                new Vector2(uvX2, uvY1),
                new Vector2(uvX2, uvY2),
                new Vector2(uvX1, uvY2),
                new Vector2(uvX1, uvY1)
            };

            // Init triangles
            overlayMesh.SetTriangles(new[]
            {
                0, 1, 2,
                0, 2, 3
            }, 0);

            overlayMesh.RecalculateBounds();
            overlayMesh.RecalculateNormals();
        }
    protected void FillPoly(Color[] buffer, OnlineMapsVector2i bufferPosition, int bufferWidth, int bufferHeight,
                            int zoom, List <Vector2> points, Color color)
    {
        if (color.a == 0)
        {
            return;
        }

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

        float minX = float.MaxValue;
        float maxX = float.MinValue;
        float minY = float.MaxValue;
        float maxY = float.MinValue;

        foreach (Vector2 point in points)
        {
            Vector2 bufferPoint = (OnlineMapsUtils.LatLongToTilef(point, zoom) - bufferPosition) * OnlineMapsUtils.tileSize;

            if (bufferPoint.x < minX)
            {
                minX = bufferPoint.x;
            }
            if (bufferPoint.x > maxX)
            {
                maxX = bufferPoint.x;
            }
            if (bufferPoint.y < minY)
            {
                minY = bufferPoint.y;
            }
            if (bufferPoint.y > maxY)
            {
                maxY = bufferPoint.y;
            }

            bufferPoints.Add(bufferPoint);
        }

        float stY  = Mathf.Clamp(minY, 0, bufferHeight);
        float stX  = Mathf.Clamp(minX, 0, bufferWidth);
        float endY = Mathf.Clamp(maxY, 0, bufferHeight);
        float endX = Mathf.Clamp(maxX, 0, bufferWidth);

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

        Color clr = new Color(color.r, color.g, color.b, 1);

        for (int y = 0; y < lengthY; y++)
        {
            float bufferY = y + start.y;
            for (int x = 0; x < lengthX; x++)
            {
                float bufferX = x + start.x;
                if (OnlineMapsUtils.IsPointInPolygon(bufferPoints, bufferX, bufferY))
                {
                    int bufferIndex = (int)bufferY * bufferWidth + (int)bufferX;
                    if (color.a == 1)
                    {
                        buffer[bufferIndex] = color;
                    }
                    else
                    {
                        buffer[bufferIndex] = Color.Lerp(buffer[bufferIndex], clr, color.a);
                    }
                }
            }
        }
    }
示例#17
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;
        }
    }