private void UpdateBuildingsPosition()
    {
        OnlineMapsTileSetControl control = OnlineMapsTileSetControl.instance;

        Bounds bounds = new Bounds();

        double tlx, tly, brx, bry;

        map.GetCorners(out tlx, out tly, out brx, out bry);

        bounds.min = new Vector3((float)tlx, (float)bry);
        bounds.max = new Vector3((float)brx, (float)tly);

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

        bool useElevation = control.useElevation;

        foreach (KeyValuePair <string, OnlineMapsBuildingBase> building in buildings)
        {
            if (!bounds.Intersects(building.Value.boundsCoords))
            {
                unusedKeys.Add(building.Key);
            }
            else
            {
                if (useElevation)
                {
                    Vector3 newPosition = control.GetWorldPositionWithElevation(building.Value.centerCoordinates.x, building.Value.centerCoordinates.y, tlx, tly, brx, bry);
                    building.Value.transform.position = newPosition;
                }
                else
                {
                    Vector3 newPosition = control.GetWorldPosition(building.Value.centerCoordinates.x, building.Value.centerCoordinates.y);
                    building.Value.transform.position = newPosition;
                }
            }
        }

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

        double px, py;

        map.GetTilePosition(out px, out py);

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

        foreach (KeyValuePair <string, OnlineMapsBuildingBase> building in unusedBuildings)
        {
            OnlineMapsBuildingBase value = building.Value;
            if (bounds.Intersects(value.boundsCoords))
            {
                usedKeys.Add(building.Key);
                if (useElevation)
                {
                    Vector3 newPosition = control.GetWorldPositionWithElevation(building.Value.centerCoordinates, tlx, tly, brx, bry);
                    building.Value.transform.position = newPosition;
                }
                else
                {
                    Vector3 newPosition = control.GetWorldPosition(building.Value.centerCoordinates.x, building.Value.centerCoordinates.y);
                    building.Value.transform.position = newPosition;
                }
            }
            else
            {
                double bx, by;
                map.projection.CoordinatesToTile(value.centerCoordinates.x, value.centerCoordinates.y, map.zoom, out bx, out by);
                if (OnlineMapsUtils.SqrMagnitude(0, 0, bx - px, by - py) > maxDistance)
                {
                    destroyKeys.Add(building.Key);
                }
            }
        }

        for (int i = 0; i < unusedKeys.Count; i++)
        {
            string key = unusedKeys[i];
            OnlineMapsBuildingBase value = buildings[key];
            value.gameObject.SetActive(false);
            unusedBuildings.Add(key, value);
            buildings.Remove(key);
        }

        for (int i = 0; i < usedKeys.Count; i++)
        {
            if (maxActiveBuildings > 0 && buildings.Count >= maxActiveBuildings)
            {
                break;
            }

            string key = usedKeys[i];
            OnlineMapsBuildingBase value = unusedBuildings[key];

            if (OnShowBuilding != null && !OnShowBuilding(value))
            {
                continue;
            }
            value.gameObject.SetActive(true);
            buildings.Add(key, value);
            unusedBuildings.Remove(key);
        }

        for (int i = 0; i < destroyKeys.Count; i++)
        {
            string key = destroyKeys[i];
            OnlineMapsBuildingBase value = unusedBuildings[key];
            if (OnBuildingDispose != null)
            {
                OnBuildingDispose(value);
            }
            value.Dispose();
            OnlineMapsUtils.DestroyImmediate(value.gameObject);
            unusedBuildings.Remove(key);
        }
    }