public bool SetBounds(MapProjection projection, Size viewportSize)
        {
            // bounds in tile pixels from viewport size
            //
            var bounds = projection.GetTileBounds(TileMatrix.Scale, TileMatrix.TopLeft, viewportSize);

            // tile column and row index bounds
            //
            var xMin = (int)Math.Floor(bounds.X / TileMatrix.TileWidth);
            var yMin = (int)Math.Floor(bounds.Y / TileMatrix.TileHeight);
            var xMax = (int)Math.Floor((bounds.X + bounds.Width) / TileMatrix.TileWidth);
            var yMax = (int)Math.Floor((bounds.Y + bounds.Height) / TileMatrix.TileHeight);

            xMin = Math.Max(xMin, 0);
            yMin = Math.Max(yMin, 0);
            xMax = Math.Min(Math.Max(xMax, 0), TileMatrix.MatrixWidth - 1);
            yMax = Math.Min(Math.Max(yMax, 0), TileMatrix.MatrixHeight - 1);

            if (XMin == xMin && YMin == yMin && XMax == xMax && YMax == yMax)
            {
                return(false);
            }

            XMin = xMin;
            YMin = yMin;
            XMax = xMax;
            YMax = yMax;

            return(true);
        }
示例#2
0
        /// <summary>
        /// Changes the Center property according to the specified map translation in viewport coordinates.
        /// </summary>
        public void TranslateMap(Point translation)
        {
            if (transformCenter != null)
            {
                ResetTransformCenter();
                UpdateTransform();
            }

            if (translation.X != 0d || translation.Y != 0d)
            {
                if (Heading != 0d)
                {
                    var cos = Math.Cos(Heading / 180d * Math.PI);
                    var sin = Math.Sin(Heading / 180d * Math.PI);

                    translation = new Point(
                        translation.X * cos + translation.Y * sin,
                        translation.Y * cos - translation.X * sin);
                }

                translation.X = -translation.X;
                translation.Y = -translation.Y;

                Center = MapProjection.TranslateLocation(Center, translation);
            }
        }
示例#3
0
        private void TargetCenterPropertyChanged(Location targetCenter)
        {
            if (!internalPropertyChange)
            {
                AdjustCenterProperty(TargetCenterProperty, ref targetCenter);

                if (!targetCenter.Equals(Center))
                {
                    if (centerAnimation != null)
                    {
                        centerAnimation.Completed -= CenterAnimationCompleted;
                    }

                    // animate private CenterPoint property by PointAnimation
                    centerAnimation = new PointAnimation
                    {
                        From = MapProjection.LocationToPoint(Center),
                        To   = MapProjection.LocationToPoint(new Location(
                                                                 targetCenter.Latitude,
                                                                 Location.NearestLongitude(targetCenter.Longitude, Center.Longitude))),
                        Duration       = AnimationDuration,
                        EasingFunction = AnimationEasingFunction
                    };

                    centerAnimation.Completed += CenterAnimationCompleted;
                    this.BeginAnimation(CenterPointProperty, centerAnimation);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Changes the Center, Heading and ZoomLevel properties according to the specified
        /// viewport coordinate translation, rotation and scale delta values. Rotation and scaling
        /// is performed relative to the specified center point in viewport coordinates.
        /// </summary>
        public void TransformMap(Point center, Vector translation, double rotation, double scale)
        {
            if (rotation != 0d || scale != 1d)
            {
                transformCenter = MapProjection.ViewportPointToLocation(center);
                viewportCenter  = center + translation;

                if (rotation != 0d)
                {
                    var heading = (((Heading + rotation) % 360d) + 360d) % 360d;
                    SetValueInternal(HeadingProperty, heading);
                    SetValueInternal(TargetHeadingProperty, heading);
                }

                if (scale != 1d)
                {
                    var zoomLevel = Math.Min(Math.Max(ZoomLevel + Math.Log(scale, 2d), MinZoomLevel), MaxZoomLevel);
                    SetValueInternal(ZoomLevelProperty, zoomLevel);
                    SetValueInternal(TargetZoomLevelProperty, zoomLevel);
                }

                UpdateTransform(true);
            }
            else
            {
                TranslateMap(translation); // more precise
            }
        }
        public void SetRenderTransform(MapProjection projection)
        {
            // tile grid origin in pixels
            //
            var tileGridOrigin = new Point(TileMatrix.TileWidth * XMin, TileMatrix.TileHeight * YMin);

            ((MatrixTransform)RenderTransform).Matrix =
                projection.CreateTileLayerTransform(TileMatrix.Scale, TileMatrix.TopLeft, tileGridOrigin);
        }
示例#6
0
        /// <summary>
        /// Sets the TargetZoomLevel and TargetCenter properties so that the specified bounding box
        /// fits into the current view. The TargetHeading property is set to zero.
        /// </summary>
        public void ZoomToBounds(BoundingBox boundingBox)
        {
            var rect   = MapProjection.BoundingBoxToRect(boundingBox);
            var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d);
            var scale  = Math.Min(RenderSize.Width / rect.Width, RenderSize.Height / rect.Height);

            TargetZoomLevel = ViewTransform.ScaleToZoomLevel(scale);
            TargetCenter    = MapProjection.MapToLocation(center);
            TargetHeading   = 0d;
        }
示例#7
0
        private void CenterPointPropertyChanged(Point centerPoint)
        {
            if (!internalPropertyChange)
            {
                var center = MapProjection.PointToLocation(centerPoint);
                center.Longitude = Location.NormalizeLongitude(center.Longitude);

                InternalSetValue(CenterProperty, center);
                UpdateTransform();
            }
        }
示例#8
0
        /// <summary>
        /// Sets the TargetZoomLevel and TargetCenter properties so that the specified bounding box
        /// fits into the current viewport. The TargetHeading property is set to zero.
        /// </summary>
        public void ZoomToBounds(BoundingBox boundingBox)
        {
            var rect   = MapProjection.BoundingBoxToRect(boundingBox);
            var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d);
            var scale  = Math.Min(RenderSize.Width / rect.Width, RenderSize.Height / rect.Height)
                         * MapProjection.TrueScale / MapProjection.PixelPerDegree;

            TargetZoomLevel = Math.Log(scale, 2d);
            TargetCenter    = MapProjection.PointToLocation(center);
            TargetHeading   = 0d;
        }
示例#9
0
        private void CenterAnimationCompleted(object sender, object e)
        {
            if (centerAnimation != null)
            {
                centerAnimation.Completed -= CenterAnimationCompleted;
                centerAnimation            = null;

                InternalSetValue(CenterProperty, TargetCenter);
                InternalSetValue(CenterPointProperty, MapProjection.LocationToPoint(TargetCenter));
                UpdateTransform();
            }
        }
示例#10
0
        private void DrawCylindricalGraticule(DrawingContext drawingContext, MapProjection projection, double lineDistance, string labelFormat)
        {
            var boundingBox = projection.ViewportRectToBoundingBox(new Rect(ParentMap.RenderSize));

            if (boundingBox.HasValidBounds)
            {
                var latLabelStart = Math.Ceiling(boundingBox.South / lineDistance) * lineDistance;
                var lonLabelStart = Math.Ceiling(boundingBox.West / lineDistance) * lineDistance;
                var latLabels     = new List <Label>((int)((boundingBox.North - latLabelStart) / lineDistance) + 1);
                var lonLabels     = new List <Label>((int)((boundingBox.East - lonLabelStart) / lineDistance) + 1);
                var typeface      = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
                var pixelsPerDpi  = VisualTreeHelper.GetDpi(this).PixelsPerDip;
                var pen           = CreatePen();

                for (var lat = latLabelStart; lat <= boundingBox.North; lat += lineDistance)
                {
                    latLabels.Add(new Label(lat, new FormattedText(
                                                GetLabelText(lat, labelFormat, "NS"),
                                                CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, FontSize, Foreground, pixelsPerDpi)));

                    drawingContext.DrawLine(pen,
                                            projection.LocationToViewportPoint(new Location(lat, boundingBox.West)),
                                            projection.LocationToViewportPoint(new Location(lat, boundingBox.East)));
                }

                for (var lon = lonLabelStart; lon <= boundingBox.East; lon += lineDistance)
                {
                    lonLabels.Add(new Label(lon, new FormattedText(
                                                GetLabelText(Location.NormalizeLongitude(lon), labelFormat, "EW"),
                                                CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeface, FontSize, Foreground, pixelsPerDpi)));

                    drawingContext.DrawLine(pen,
                                            projection.LocationToViewportPoint(new Location(boundingBox.South, lon)),
                                            projection.LocationToViewportPoint(new Location(boundingBox.North, lon)));
                }

                foreach (var latLabel in latLabels)
                {
                    foreach (var lonLabel in lonLabels)
                    {
                        var position = projection.LocationToViewportPoint(new Location(latLabel.Position, lonLabel.Position));

                        drawingContext.PushTransform(new RotateTransform(ParentMap.Heading, position.X, position.Y));
                        drawingContext.DrawText(latLabel.Text,
                                                new Point(position.X + StrokeThickness / 2d + 2d, position.Y - StrokeThickness / 2d - latLabel.Text.Height));
                        drawingContext.DrawText(lonLabel.Text,
                                                new Point(position.X + StrokeThickness / 2d + 2d, position.Y + StrokeThickness / 2d));
                        drawingContext.Pop();
                    }
                }
            }
        }
示例#11
0
        private void SetRenderTransform()
        {
            var tileScale  = (double)(1 << TileGrid.ZoomLevel);
            var scale      = Math.Pow(2d, parentMap.ZoomLevel) / tileScale;
            var tileCenter = new Point(tileScale * (0.5 + parentMap.Center.Longitude / 360d),
                                       tileScale * (0.5 - WebMercatorProjection.LatitudeToY(parentMap.Center.Latitude) / 360d));
            var tileOrigin = new Point(MapProjection.TileSize * (tileCenter.X - TileGrid.XMin),
                                       MapProjection.TileSize * (tileCenter.Y - TileGrid.YMin));
            var viewCenter = new Point(parentMap.RenderSize.Width / 2d, parentMap.RenderSize.Height / 2d);

            ((MatrixTransform)RenderTransform).Matrix =
                MapProjection.CreateTransformMatrix(tileOrigin, scale, parentMap.Heading, viewCenter);
        }
示例#12
0
        /// <summary>
        /// Changes the Center property according to the specified translation in viewport coordinates.
        /// </summary>
        public void TranslateMap(Vector translation)
        {
            if (transformCenter != null)
            {
                ResetTransformCenter();
                UpdateTransform();
            }

            if (translation.X != 0d || translation.Y != 0d)
            {
                Center = MapProjection.ViewportPointToLocation(viewportCenter - translation);
            }
        }
示例#13
0
        private void CenterPropertyChanged(Location center)
        {
            if (!internalPropertyChange)
            {
                AdjustCenterProperty(CenterProperty, ref center);
                UpdateTransform();

                if (centerAnimation == null)
                {
                    InternalSetValue(TargetCenterProperty, center);
                    InternalSetValue(CenterPointProperty, MapProjection.LocationToPoint(center));
                }
            }
        }
示例#14
0
        /// <summary>
        /// Transforms a Rect in view coordinates to a BoundingBox in geographic coordinates.
        /// </summary>
        public BoundingBox ViewRectToBoundingBox(Rect rect)
        {
            var p1 = ViewTransform.ViewToMap(new Point(rect.X, rect.Y));
            var p2 = ViewTransform.ViewToMap(new Point(rect.X, rect.Y + rect.Height));
            var p3 = ViewTransform.ViewToMap(new Point(rect.X + rect.Width, rect.Y));
            var p4 = ViewTransform.ViewToMap(new Point(rect.X + rect.Width, rect.Y + rect.Height));

            rect.X      = Math.Min(p1.X, Math.Min(p2.X, Math.Min(p3.X, p4.X)));
            rect.Y      = Math.Min(p1.Y, Math.Min(p2.Y, Math.Min(p3.Y, p4.Y)));
            rect.Width  = Math.Max(p1.X, Math.Max(p2.X, Math.Max(p3.X, p4.X))) - rect.X;
            rect.Height = Math.Max(p1.Y, Math.Max(p2.Y, Math.Max(p3.Y, p4.Y))) - rect.Y;

            return(MapProjection.RectToBoundingBox(rect));
        }
示例#15
0
        /// <summary>
        /// Sets the TargetZoomLevel and TargetCenter properties so that the specified bounding box
        /// fits into the current viewport. The TargetHeading property is set to zero.
        /// </summary>
        public void ZoomToBounds(BoundingBox boundingBox)
        {
            if (boundingBox != null && boundingBox.HasValidBounds)
            {
                var rect     = MapProjection.BoundingBoxToRect(boundingBox);
                var center   = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d);
                var scale0   = 1d / MapProjection.GetViewportScale(0d);
                var lonScale = scale0 * RenderSize.Width / rect.Width;
                var latScale = scale0 * RenderSize.Height / rect.Height;
                var lonZoom  = Math.Log(lonScale, 2d);
                var latZoom  = Math.Log(latScale, 2d);

                TargetZoomLevel = Math.Min(lonZoom, latZoom);
                TargetCenter    = MapProjection.PointToLocation(center);
                TargetHeading   = 0d;
            }
        }
示例#16
0
        private ImageSource GetImage(MapProjection projection, IEnumerable <IMapDrawingItem> items)
        {
            var scale     = ParentMap.ViewTransform.Scale;
            var rotation  = ParentMap.ViewTransform.Rotation;
            var mapRect   = projection.BoundingBoxToRect(BoundingBox);
            var imageRect = new Rect(0, 0, scale * mapRect.Width, scale * mapRect.Height);
            var drawings  = new DrawingGroup();

            foreach (var item in items)
            {
                var positions = item.Locations.Select(l => projection.LocationToMap(l)).ToList();

                if (positions.Any(p => mapRect.Contains(p)))
                {
                    for (int i = 0; i < positions.Count; i++)
                    {
                        positions[i] = new Point(scale * (positions[i].X - mapRect.X),
                                                 imageRect.Height - scale * (positions[i].Y - mapRect.Y));
                    }

                    drawings.Children.Add(item.GetDrawing(positions, scale, rotation));
                }
            }

            var drawingBrush = new DrawingBrush
            {
                Drawing      = drawings,
                ViewboxUnits = BrushMappingMode.Absolute,
                Viewbox      = imageRect,
            };

            var drawing = new GeometryDrawing
            {
                Geometry = new RectangleGeometry(imageRect),
                Brush    = drawingBrush
            };

            var image = new DrawingImage(drawing);

            image.Freeze();

            return(image);
        }
示例#17
0
        private TileGrid GetTileGrid()
        {
            var tileZoomLevel = Math.Max(0, (int)Math.Round(parentMap.ZoomLevel + ZoomLevelOffset));
            var tileScale     = (double)(1 << tileZoomLevel);
            var scale         = tileScale / (Math.Pow(2d, parentMap.ZoomLevel) * MapProjection.TileSize);
            var tileCenter    = new Point(tileScale * (0.5 + parentMap.Center.Longitude / 360d),
                                          tileScale * (0.5 - WebMercatorProjection.LatitudeToY(parentMap.Center.Latitude) / 360d));
            var viewCenter = new Point(parentMap.RenderSize.Width / 2d, parentMap.RenderSize.Height / 2d);

            var transform = new MatrixTransform
            {
                Matrix = MapProjection.CreateTransformMatrix(viewCenter, scale, -parentMap.Heading, tileCenter)
            };

            var bounds = transform.TransformBounds(new Rect(0d, 0d, parentMap.RenderSize.Width, parentMap.RenderSize.Height));

            return(new TileGrid(tileZoomLevel,
                                (int)Math.Floor(bounds.X), (int)Math.Floor(bounds.Y),
                                (int)Math.Floor(bounds.X + bounds.Width), (int)Math.Floor(bounds.Y + bounds.Height)));
        }
示例#18
0
        private double GetLineDistance()
        {
            var minDistance = MinLineDistance / MapProjection.DegreesToViewportScale(ParentMap.ZoomLevel);
            var scale       = 1d;

            if (minDistance < 1d)
            {
                scale        = minDistance < 1d / 60d ? 3600d : 60d;
                minDistance *= scale;
            }

            var lineDistances = new double[] { 1d, 2d, 5d, 10d, 15d, 30d, 60d };
            var i             = 0;

            while (i < lineDistances.Length - 1 && lineDistances[i] < minDistance)
            {
                i++;
            }

            return(lineDistances[i] / scale);
        }
示例#19
0
 /// <summary>
 /// Sets a temporary center point in viewport coordinates for scaling and rotation transformations.
 /// This center point is automatically reset when the Center property is set by application code.
 /// </summary>
 public void SetTransformCenter(Point center)
 {
     transformCenter = MapProjection.ViewportPointToLocation(center);
     viewportCenter  = center;
 }
示例#20
0
 /// <summary>
 /// Transforms a Point in viewport coordinates to a Location in geographic coordinates.
 /// </summary>
 public Location ViewportPointToLocation(Point point)
 {
     return(MapProjection.ViewportPointToLocation(point));
 }
示例#21
0
 /// <summary>
 /// Transforms a Location in geographic coordinates to a Point in viewport coordinates.
 /// </summary>
 public Point LocationToViewportPoint(Location location)
 {
     return(MapProjection.LocationToViewportPoint(location));
 }
示例#22
0
 /// <summary>
 /// Transforms a Location in geographic coordinates to a Point in view coordinates.
 /// </summary>
 public Point LocationToView(Location location)
 {
     return(ViewTransform.MapToView(MapProjection.LocationToMap(location)));
 }
示例#23
0
 /// <summary>
 /// Transforms a Point in view coordinates to a Location in geographic coordinates.
 /// </summary>
 public Location ViewToLocation(Point point)
 {
     return(MapProjection.MapToLocation(ViewTransform.ViewToMap(point)));
 }
 protected virtual string GetBboxParam(MapProjection projection, Rect mapRect)
 {
     return("BBOX=" + projection.GetBboxValue(mapRect));
 }
 protected virtual string GetCrsParam(MapProjection projection)
 {
     return("CRS=" + projection.GetCrsValue());
 }
示例#26
0
        /// <summary>
        /// Gets the horizontal and vertical scaling factors from cartesian map coordinates to view
        /// coordinates at the specified location, i.e. pixels per meter.
        /// </summary>
        public Vector GetScale(Location location)
        {
            var projectionScale = MapProjection.GetRelativeScale(location);

            return(ViewTransform.Scale * projectionScale);
        }
示例#27
0
 /// <summary>
 /// Gets the horizontal and vertical scaling factors from cartesian map coordinates to view
 /// coordinates at the specified location, i.e. pixels per meter.
 /// </summary>
 public Vector GetScale(Location location)
 {
     return(ViewTransform.Scale * MapProjection.GetRelativeScale(location));
 }