Exemple #1
0
        internal void AddMapPin(MapPin mapPinToAdd)
        {
            mapPinToAdd.LocationChanged += MapPinLocationChanged;
            var latLon = mapPinToAdd.Location;

            // Insert into max LOD.
            TileId maxLodTileId;

            {
                var lodIndex = _maxLod.Value - 1;
                maxLodTileId = new TileId(latLon, _maxLod);
                if (!_tiledSpatialIndex[lodIndex].TryGetValue(maxLodTileId.Value, out TileData maxLodTileData))
                {
                    maxLodTileData =
                        new TileData
                    {
                        MapPins = new List <MapPin> {
                            mapPinToAdd
                        }
                    };
                    _tiledSpatialIndex[lodIndex].Add(maxLodTileId.Value, maxLodTileData);
                }
                else
                {
                    maxLodTileData.MapPins.Add(mapPinToAdd);
                }

                maxLodTileData.MapPinCount++;
                maxLodTileData.TotalLat += latLon.LatitudeInDegrees;
                maxLodTileData.TotalLon += latLon.LongitudeInDegrees;
            }

            // Bubble up tile into parent LODs.
            maxLodTileId.TryGetParent(out var parentTileId);
            var parentLodIndex = parentTileId.CalculateLevelOfDetail().Value - 1;

            while (parentLodIndex >= 0)
            {
                if (!_tiledSpatialIndex[parentLodIndex].TryGetValue(parentTileId.Value, out var parentTileData))
                {
                    // This is a new tile. Create and add a new TileData for this LOD.
                    parentTileData =
                        new TileData
                    {
                        MapPins = new List <MapPin> {
                            mapPinToAdd
                        },
                        MapPinCount = 1,
                        TotalLat    = latLon.LatitudeInDegrees,
                        TotalLon    = latLon.LongitudeInDegrees
                    };
                    _tiledSpatialIndex[parentLodIndex].Add(parentTileId.Value, parentTileData);
                }
                else
                {
                    // We already have a tile with points or clusters.

                    // In either case, track the LatLong.
                    parentTileData.MapPinCount++;
                    parentTileData.TotalLat += latLon.LatitudeInDegrees;
                    parentTileData.TotalLon += latLon.LongitudeInDegrees;

                    var isCluster = _isClusteringEnabled && parentTileData.MapPinCount > ClusterThreshold;
                    if (isCluster)
                    {
                        parentTileData.MapPins = null;
                    }
                    else
                    {
                        parentTileData.MapPins.Add(mapPinToAdd);
                    }
                }

                parentLodIndex--;
                parentTileId.TryGetParent(out parentTileId);
            }
        }
Exemple #2
0
        private void RemoveMapPin(MapPin mapPinToRemove, LatLon locationOverride)
        {
            // Find the MapPin in the spatial index at the max LOD.
            var lodIndex     = _maxLod.Value - 1;
            var maxLodTileId = new TileId(locationOverride, _maxLod);
            var indexChanged = false;

            if (_tiledSpatialIndex[lodIndex].TryGetValue(maxLodTileId.Value, out TileData maxLodTileData))
            {
                if (maxLodTileData.MapPins.Remove(mapPinToRemove))
                {
                    indexChanged = true;

                    mapPinToRemove.LocationChanged -= MapPinLocationChanged;

                    maxLodTileData.MapPinCount--;
                    if (maxLodTileData.MapPinCount == 0)
                    {
                        // Remove tile if now empty.
                        _tiledSpatialIndex[lodIndex].Remove(maxLodTileId.Value);
                    }
                    else
                    {
                        maxLodTileData.TotalLat -= locationOverride.LatitudeInDegrees;
                        maxLodTileData.TotalLon -= locationOverride.LongitudeInDegrees;
                    }
                }
            }

            // Bubble up change to parent tiles.
            if (indexChanged)
            {
                maxLodTileId.TryGetParent(out var parentTileId);
                var parentLodIndex = parentTileId.CalculateLevelOfDetail().Value - 1;
                while (parentLodIndex >= 0)
                {
                    _tiledSpatialIndex[parentLodIndex].TryGetValue(parentTileId.Value, out var parentTileData);
                    parentTileData.MapPinCount--;

                    if (parentTileData.MapPinCount == 0)
                    {
                        // No more pins left in this tile. Remove it from the spatial index.
                        _tiledSpatialIndex[parentLodIndex].Remove(parentTileId.Value);

#if DEBUG
                        // It shouldn't be clustered.
                        Assert.IsTrue(parentTileData.ClusterMapPin == null);
#endif
                    }
                    else
                    {
                        parentTileData.TotalLat -= locationOverride.LatitudeInDegrees;
                        parentTileData.TotalLon -= locationOverride.LongitudeInDegrees;

                        var isCluster = _isClusteringEnabled && parentTileData.MapPinCount > ClusterThreshold;
                        if (!isCluster)
                        {
                            if (parentTileData.MapPins != null)
                            {
                                parentTileData.MapPins.Remove(mapPinToRemove);
                            }
                            else
                            {
                                // When we remove the MapPin, this tile will fall under the cluster threshold so we will need to repopulate
                                // the children list.
                                parentTileData.MapPins = GatherChildren(parentTileId);

                                // Destroy the ClusterMapPin game object if it exists.
                                if (parentTileData.ClusterMapPin != null)
                                {
                                    _clusterMapPins.Remove(parentTileData.ClusterMapPin);
                                    UnityEngine.Object.Destroy(parentTileData.ClusterMapPin.gameObject);
                                    parentTileData.ClusterMapPin = null;
                                }
                            }
                        }
                    }

                    parentLodIndex--;
                    parentTileId.TryGetParent(out parentTileId);
                }
            }
        }
Exemple #3
0
 private void MapPinLocationChanged(MapPin mapPinToUpdate, LatLon oldLocation)
 {
     RemoveMapPin(mapPinToUpdate, oldLocation);
     AddMapPin(mapPinToUpdate);
 }
Exemple #4
0
 internal void RemoveMapPin(MapPin mapPinToRemove)
 {
     RemoveMapPin(mapPinToRemove, mapPinToRemove.Location);
 }