Back to Devexpress

ProjectionBase Class

wpf-devexpress-dot-xpf-dot-map-252a3372.md

latest12.8 KB
Original Source

ProjectionBase Class

The base class for all projections used in the MapControl.

Namespace : DevExpress.Xpf.Map

Assembly : DevExpress.Xpf.Map.v25.2.dll

NuGet Package : DevExpress.Wpf.Map

Declaration

csharp
public abstract class ProjectionBase :
    IProjectionCore
vb
Public MustInherit Class ProjectionBase
    Implements IProjectionCore

The following members return ProjectionBase objects:

Example

To create a custom projection, inherit the ProjectionBase class and override the following methods of the base class.

View Example

vb
Imports DevExpress.Xpf.Map
Imports System
Imports System.Windows

Namespace CustomProjection
    Friend Class HammerAitoffProjection
        Inherits ProjectionBase

        Public Overrides Property OffsetX() As Double
            Get
                Return 0.5
            End Get
            Set(value As Double)
            End Set
        End Property
        Public Overrides Property OffsetY() As Double
            Get
                Return 0.5
            End Get
            Set(value As Double)
            End Set
        End Property
        Public Overrides Property ScaleX() As Double
            Get
                Return 0.5
            End Get
            Set(value As Double)
            End Set
        End Property
        Public Overrides Property ScaleY() As Double
            Get
                Return -0.25
            End Get
            Set(value As Double)
            End Set
        End Property

        Private Const minLatitude As Double = -90.0
        Private Const maxLatitude As Double = 90.0
        Private Const minLongitude As Double = -180.0
        Private Const maxLongitude As Double = 180.0

        Private Shared Function RadianToDegree(ByVal value As Double) As Double
            Return value * 180.0 / Math.PI
        End Function

        Private Shared Function DegreeToRadian(ByVal value As Double) As Double
            Return value * Math.PI / 180.0
        End Function

        Private Function IsValidPoint(ByVal x As Double, ByVal y As Double) As Boolean
            If Math.Pow(x, 2) + Math.Pow(y, 2) > 1 Then
                Return False
            End If

            Return True
        End Function

        Public Overrides Function GeoPointToMapUnit(ByVal geoPoint As GeoPoint) As MapUnit
            Dim lonInRadian As Double = DegreeToRadian(Math.Min(maxLongitude, Math.Max(minLongitude, geoPoint.Longitude)))
            Dim latInRadian As Double = DegreeToRadian(Math.Min(maxLatitude, Math.Max(minLatitude, geoPoint.Latitude)))
            Dim z As Double = Math.Sqrt(1 + Math.Cos(latInRadian) * Math.Cos(lonInRadian / 2))
            Dim x As Double = Math.Cos(latInRadian) * Math.Sin(lonInRadian / 2) / z
            Dim y As Double = Math.Sin(latInRadian) / z

            Return New MapUnit(x * ScaleX + OffsetX, y * ScaleY + OffsetY)
        End Function

        Public Overrides Function MapUnitToGeoPoint(ByVal mapUnit As MapUnit) As GeoPoint
            Dim x As Double = (mapUnit.X - OffsetX) / ScaleX
            Dim y As Double = Math.Min(1, Math.Max(-1, (mapUnit.Y - OffsetY) / ScaleY))

            If IsValidPoint(x, y) Then
                Dim z As Double = Math.Sqrt(1 - 0.5 * Math.Pow(x, 2) - 0.5 * Math.Pow(y, 2))
                Dim c As Double = Math.Sqrt(2) * z * x / (2 * Math.Pow(z, 2) - 1)
                Dim lon As Double = 2 * Math.Atan(c)
                Dim lat As Double = Math.Asin(Math.Min(Math.Max(Math.Sqrt(2) * z * y, -1), 1))
                Dim latInDegree As Double = lat * maxLongitude / Math.PI
                Dim lonInDegree As Double = lon * maxLongitude / Math.PI

                Return New GeoPoint(Math.Min(maxLatitude, Math.Max(minLatitude, RadianToDegree(lat))), Math.Min(maxLongitude, Math.Max(minLongitude, RadianToDegree(lon))))
            Else
                Dim signX As Integer = If(x < 0, -1, 1)
                Dim signY As Integer = If(y < 0, -1, 1)
                Return New GeoPoint(maxLatitude * signY, maxLongitude * signX)
            End If
        End Function

        Public Overrides Function GeoToKilometersSize(ByVal anchorPoint As GeoPoint, ByVal size As Size) As Size
            Return New Size(size.Width * LonToKilometersRatio * Math.Cos(DegreeToRadian(anchorPoint.Latitude)), size.Height * LatToKilometersRatio)
        End Function

        Public Overrides Function KilometersToGeoSize(ByVal anchorPoint As GeoPoint, ByVal size As Size) As Size
            Return New Size(size.Width / LonToKilometersRatio / Math.Cos(DegreeToRadian(anchorPoint.Latitude)), size.Height / LatToKilometersRatio)
        End Function
    End Class
End Namespace
xaml
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CustomProjection"
        xmlns:dxm="http://schemas.devexpress.com/winfx/2008/xaml/map" 
        x:Class="CustomProjection.MainWindow"
        Title="MainWindow" Height="549" Width="526">
    <Grid>
        <dxm:MapControl>
            <dxm:MapControl.CoordinateSystem>
                <dxm:GeoMapCoordinateSystem>
                    <dxm:GeoMapCoordinateSystem.Projection>
                        <local:HammerAitoffProjection/>
                    </dxm:GeoMapCoordinateSystem.Projection>
                </dxm:GeoMapCoordinateSystem>
            </dxm:MapControl.CoordinateSystem>
            <dxm:VectorLayer>
                <dxm:ShapefileDataAdapter FileUri="Data/Countries.shp" />
            </dxm:VectorLayer>
        </dxm:MapControl>
    </Grid>
</Window>
xaml
<Application x:Class="CustomProjection.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>

    </Application.Resources>
</Application>
csharp
using DevExpress.Xpf.Map;
using System;
using System.Windows;

namespace CustomProjection {
    class HammerAitoffProjection : ProjectionBase {
        override public double OffsetX { get { return 0.5; } }
        override public double OffsetY { get { return 0.5; } }
        override public double ScaleX { get { return 0.5; } }
        override public double ScaleY { get { return -0.25; } }

        const double minLatitude = -90.0;
        const double maxLatitude = 90.0;
        const double minLongitude = -180.0;
        const double maxLongitude = 180.0;

        static double RadianToDegree(double value) {
            return value * 180.0 / Math.PI;
        }

        static double DegreeToRadian(double value) {
            return value * Math.PI / 180.0;
        }

        bool IsValidPoint(double x, double y) {
            if (Math.Pow(x, 2) + Math.Pow(y, 2) > 1)
                return false;

            return true;
        }

        public override MapUnit GeoPointToMapUnit(GeoPoint geoPoint) {
            double lonInRadian = DegreeToRadian(
                Math.Min(
                    maxLongitude,
                    Math.Max(minLongitude, geoPoint.Longitude)
                )
            );
            double latInRadian = DegreeToRadian(
                Math.Min(
                    maxLatitude,
                    Math.Max(minLatitude, geoPoint.Latitude)
                )
            );
            double z = Math.Sqrt(1 + Math.Cos(latInRadian) * Math.Cos(lonInRadian / 2));
            double x = Math.Cos(latInRadian) * Math.Sin(lonInRadian / 2) / z;
            double y = Math.Sin(latInRadian) / z;

            return new MapUnit(x * ScaleX + OffsetX, y * ScaleY + OffsetY);
        }

        public override GeoPoint MapUnitToGeoPoint(MapUnit mapUnit) {
            double x = (mapUnit.X - OffsetX) / ScaleX;
            double y = Math.Min(1, Math.Max(-1, (mapUnit.Y - OffsetY) / ScaleY));

            if (IsValidPoint(x, y)) {
                double z = Math.Sqrt(1 - 0.5 * Math.Pow(x, 2) - 0.5 * Math.Pow(y, 2));
                double c = Math.Sqrt(2) * z * x / (2 * Math.Pow(z, 2) - 1);
                double lon = 2 * Math.Atan(c);
                double lat = Math.Asin(Math.Min(Math.Max(Math.Sqrt(2) * z * y, -1), 1));
                double latInDegree = lat * maxLongitude / Math.PI;
                double lonInDegree = lon * maxLongitude / Math.PI;

                return new GeoPoint(
                    Math.Min(
                        maxLatitude,
                        Math.Max(minLatitude, RadianToDegree(lat))
                    ),
                    Math.Min(
                        maxLongitude,
                        Math.Max(minLongitude, RadianToDegree(lon))
                    )
                );
            }
            else {
                int signX = (x < 0) ? -1 : 1;
                int signY = (y < 0) ? -1 : 1;
                return new GeoPoint(maxLatitude * signY, maxLongitude * signX);
            }
        }

        public override Size GeoToKilometersSize(GeoPoint anchorPoint, Size size) {
            return new Size(
                size.Width * LonToKilometersRatio * Math.Cos(DegreeToRadian(anchorPoint.Latitude)),
                size.Height * LatToKilometersRatio
            );
        }

        public override Size KilometersToGeoSize(GeoPoint anchorPoint, Size size) {
            return new Size(
                size.Width / LonToKilometersRatio / Math.Cos(DegreeToRadian(anchorPoint.Latitude)),
                size.Height / LatToKilometersRatio
            );
        }
    }
}

Inheritance

Show 15 items

Object ProjectionBase EqualAreaProjection

EquidistantProjection

EquirectangularProjection

Etrs89LambertAzimuthalEqualAreaProjection

BraunStereographicProjection

KavrayskiyProjection

LambertAzimuthalEqualAreaProjectionBase

LambertCylindricalEqualAreaProjection

MillerProjection

EllipticalMercatorProjection

EPSG4326Projection

SinusoidalProjection

SphericalMercatorProjection

See Also

ProjectionBase Members

DevExpress.Xpf.Map Namespace