コード例 #1
0
        private static void UpdateCurrentLocation(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var map = d as Map;
            var currentGeoCoordinate = e.NewValue as GeoCoordinate;

            if (currentGeoCoordinate != null && map != null)
            {
                DataTemplate currentLocationPushpinTemplate = GetCurrentLocationPushpinTemplate(d);

                map.Dispatcher.BeginInvoke(
                    () =>
                {
                    // Remove layer which hosts pushpins
                    var removeLayer = map.Layers.FirstOrDefault(x => x.All(y => y.Content is UserLocationMarker));
                    map.Layers.Remove(removeLayer);

                    // Create new layer with current location pin
                    var layer = new MapLayer
                    {
                        new MapOverlay
                        {
                            GeoCoordinate   = currentGeoCoordinate,
                            Content         = new UserLocationMarker(currentGeoCoordinate),
                            ContentTemplate = currentLocationPushpinTemplate,
                            PositionOrigin  = new System.Windows.Point(0.5, 0.5)
                        }
                    };

                    if (layer.Any())
                    {
                        map.Layers.Insert(CurrentLocationLayerIndex, layer);
                    }
                });
            }
        }
コード例 #2
0
        private static void UpdateItemsSource(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var map = d as Map;
            var newPushPinCollection = e.NewValue as IEnumerable <IClusteredGeoObject>;

            if (newPushPinCollection != null && newPushPinCollection.Any() && map != null)
            {
                // Read dependency properties
                var pushpinTemplate        = GetPushpinTemplate(d);
                var clusterPushpinTemplate = GetClusterTemplate(d);
                ////var clusteringDistance = GetClusteringDistance(d);

                // Perform clustering
                var visibleAreaTopLeft     = map.ConvertViewportPointToGeoCoordinate(new Point(0, 0));
                var visibleAreaBottomRight = map.ConvertViewportPointToGeoCoordinate(new Point(map.ActualWidth, map.ActualHeight));
                var boundingRectangle      = LocationRect.CreateLocationRect(visibleAreaTopLeft.ToPosition(), visibleAreaBottomRight.ToPosition());

                //var clusterer = new SectorClusterer<IClusteredGeoObject>();
                var clusterer = new RectangularClusterer <IClusteredGeoObject>();

                //var stopwatch = new Stopwatch();
                //stopwatch.Start();
                IEnumerable <IClusteredLocation <IClusteredGeoObject> > clusteredLocations = clusterer.Cluster(newPushPinCollection, boundingRectangle, map.ZoomLevel);
                if (map.ZoomLevel >= 18)
                {
                    clusteredLocations = clusteredLocations.SelectMany(x => x.ClusteredItems).Select(
                        clusteredGeoObject =>
                    {
                        var rect = new ClusteredLocationRect <IClusteredGeoObject>(boundingRectangle);
                        rect.Add(clusteredGeoObject);
                        return(rect);
                    }).ToList();
                }

                //stopwatch.Stop();
                //Console.WriteLine("UPDATED CLUSTER IN {0}ms", stopwatch.ElapsedMilliseconds);

                // Update map on UI
                map.Dispatcher.BeginInvoke(
                    () =>
                {
                    // Remove layer which hosts pushpins
                    var clusteredPushpinLayer = map.Layers.FirstOrDefault(x => x.All(y => y.Content is IClusteredLocation <IClusteredGeoObject>));
                    map.Layers.Remove(clusteredPushpinLayer);

                    // Create new layer
                    var layer = new MapLayer();

                    // The descending-by-latitude ordering makes sure the pins are not overlapping eachother
                    Position lastGeoCoordinate = Position.Unknown;
                    foreach (var pushPinModel in clusteredLocations.OrderByDescending(p => p.Location.Latitude))
                    {
                        var mapOverlay = new MapOverlay
                        {
                            GeoCoordinate = new GeoCoordinate(pushPinModel.Location.Latitude, pushPinModel.Location.Longitude),
                            Content       = pushPinModel
                        };

                        if (pushPinModel.IsClustered)
                        {
                            mapOverlay.ContentTemplate = clusterPushpinTemplate;
                            mapOverlay.PositionOrigin  = new System.Windows.Point(0.5, 0.5);
                        }
                        else
                        {
                            mapOverlay.ContentTemplate = pushpinTemplate;

                            // In case two/more pins have the same GPS position, we add a random offset to longitude/latitude.
                            if (Math.Abs(pushPinModel.Location.Latitude - lastGeoCoordinate.Latitude) < 0.00005 &&
                                Math.Abs(pushPinModel.Location.Longitude - lastGeoCoordinate.Longitude) < 0.00005)
                            {
                                mapOverlay.GeoCoordinate = lastGeoCoordinate.WithRandomOffset().ToGeoCoordinate();
                            }
                            lastGeoCoordinate = pushPinModel.Location;
                        }

                        layer.Add(mapOverlay);
                    }

                    // Finally, add all items (pushpins, clusters and current location) to the map.
                    if (layer.Any())
                    {
                        map.Layers.Insert(ItemsSourceLayerIndex, layer);
                    }
                });
            }
        }