User Tools

Site Tools


source_code_wpfdesktopeditionsample_customrotationprojection_cs_110127.zip

Source Code WpfDesktopEditionSample CustomRotationProjection CS 110127.zip

App.xaml.cs

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
namespace CustomRotationProjection
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
    }
}

CustomRotationProjection.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ThinkGeo.MapSuite.Core;
namespace Projections
{
    //This projection class allows to project and rotate at the same time.
    class CustomRotationProjection : Projection, IDisposable
    {
        private ManagedProj4Projection proj4 = new ManagedProj4Projection();
        private RotationProjection rotateProjection = new RotationProjection();
        private double angle;
        private Vertex pivotVertex;
        public CustomRotationProjection()
            : base()
        {
        }
        public CustomRotationProjection( String InternalProjectionString, String ExternalProjectionString)
            : base()
        {
            proj4.InternalProjectionParametersString = InternalProjectionString;
            proj4.ExternalProjectionParametersString = ExternalProjectionString;
        }
        public string InternalProjectionString
        {
            get
            {
                return proj4.InternalProjectionParametersString;
            }
            set
            {
                proj4.InternalProjectionParametersString = value;
            }
        }
        public string ExternalProjectionString
        {
            get
            {
                return proj4.ExternalProjectionParametersString;
            }
            set
            {
                proj4.ExternalProjectionParametersString = value;
            }
        }
        public double Angle
        {
            get
            {
                return angle;
            }
            set
            {
                angle = value;
                rotateProjection.Angle = angle;
            }
        }
        public Vertex PivotVertex
        {
            get
            {
                return pivotVertex;
            }
            set
            {
                pivotVertex = value;
            }
        }
        protected override Vertex[] ConvertToExternalProjectionCore(double[] x, double[] y)
        {
            //First, converts to the external projection
            Vertex[] projVertices = new Vertex[x.Length];
            proj4.Open();
            for (int i = 0; i < projVertices.Length; i++)
            {
                projVertices[i] = proj4.ConvertToExternalProjection(x[i], y[i]);
            }
            proj4.Close();
            Vertex[] rotateVertices = new Vertex[x.Length];
            //Second, rotates based on angle and pivot point.
            for (int i = 0; i < rotateVertices.Length; i++)
            {
                rotateVertices[i] = RotateVertex(projVertices[i].X, projVertices[i].Y, angle);
            }
            return rotateVertices;
    }
        private Vertex RotateVertex(double x, double y, double angle)
        {
            Vertex rotatedVertex = new Vertex(x, y);
            if ((angle % 360) != 0)
            {
                double rotatedX = x;
                double rotatedY = y;
                double distanceToPivot = Math.Sqrt(Math.Pow((x - pivotVertex.X), 2) + Math.Pow((y - pivotVertex.Y), 2));
                if (distanceToPivot != 0)
                {
                    double beta = Math.Atan((y - pivotVertex.Y) / (x - pivotVertex.X));
                    if ((beta <= 0 | y < pivotVertex.Y) && x < pivotVertex.X)
                    {
                        beta = Math.PI + beta;
                    }
                    double radiantAngle = angle * Math.PI / 180;
                    rotatedX = (distanceToPivot * Math.Cos(radiantAngle + beta)) + pivotVertex.X;
                    rotatedY = (distanceToPivot * Math.Sin(radiantAngle + beta)) + pivotVertex.Y;
                }
                rotatedVertex = new Vertex(rotatedX, rotatedY);
            }
            return rotatedVertex;
        }
        protected override Vertex[] ConvertToInternalProjectionCore(double[] x, double[] y)
        {
            //Converts back to internal projection with the rotation.
            Vertex[] vertices = new Vertex[x.Length];
            proj4.Open();
            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = proj4.ConvertToInternalProjection(x[i], y[i]);
            }
            proj4.Close();
            return vertices;
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        private void Dispose(bool disposing)
        {
            Close();
        }
    }
}

TestWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.WpfDesktopEdition;
 
namespace CustomRotationProjection
{
    /// <summary>
    /// Interaction logic for TestWindow.xaml
    /// </summary>
    public partial class TestWindow : Window
    {
        private Projections.CustomRotationProjection customRotationProjection;
        public TestWindow()
        {
            InitializeComponent();
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //Sets the correct map unit and the extent of the map.
            wpfMap1.MapUnit = GeographyUnit.Meter;
            wpfMap1.CurrentExtent = new RectangleShape(-10782920,3912077,-10779783,3910188);
            wpfMap1.Background = new SolidColorBrush(Color.FromRgb(148, 196, 243));
            GoogleMapsOverlay googleMapsOverlay = new GoogleMapsOverlay();
            wpfMap1.Overlays.Add(googleMapsOverlay);
            //Custom projection that will allow to project from State Plane Central North Texas to Spherical Mercator while applying a rotation.
            customRotationProjection = new Projections.CustomRotationProjection(ManagedProj4Projection.GetEsriParametersString(102738),
                ManagedProj4Projection.GetGoogleMapParametersString());
            ShapeFileFeatureLayer streetLayer = new ShapeFileFeatureLayer(@"../../data/Streets_subset.shp");
            streetLayer.DrawingMarginPercentage = 100;
            streetLayer.FeatureSource.Projection = customRotationProjection;
            streetLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle
                (GeoColor.StandardColors.Red, 3, GeoColor.FromArgb(255, GeoColor.StandardColors.Black), 5, true);
            streetLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            LayerOverlay layerOverlay = new LayerOverlay();
            layerOverlay.Layers.Add("StreetLayer", streetLayer);
            wpfMap1.Overlays.Add("StreetOverlay", layerOverlay);
            //Sets the pivot point to be the center of the layer.
            streetLayer.Open();
            customRotationProjection.PivotVertex = new Vertex(streetLayer.GetBoundingBox().GetCenterPoint());
            streetLayer.Close();
            customRotationProjection.Angle = 20;
            wpfMap1.Refresh();
        }
        private void btnRotateClockWise_Click(object sender, RoutedEventArgs e)
        {
            LayerOverlay streetLayerOverlay = (LayerOverlay)wpfMap1.Overlays["StreetOverlay"];
            ShapeFileFeatureLayer streetLayer = (ShapeFileFeatureLayer)streetLayerOverlay.Layers["StreetLayer"];
            //Set the Angle property of RotationProjection. Substract 5 to go clockwise.
            streetLayer.Open();
            customRotationProjection.Angle = customRotationProjection.Angle - 5;
            streetLayer.Close();
            wpfMap1.Refresh(streetLayerOverlay);
        }
        private void btnRotateCounterClockWise_Click(object sender, RoutedEventArgs e)
        {
            LayerOverlay streetLayerOverlay = (LayerOverlay)wpfMap1.Overlays["StreetOverlay"];
            ShapeFileFeatureLayer streetLayer = (ShapeFileFeatureLayer)streetLayerOverlay.Layers["StreetLayer"];
            //Set the Angle property of RotationProjection. Adds 5 to go clockwise.
            streetLayer.Open();
            customRotationProjection.Angle = customRotationProjection.Angle + 5;
            streetLayer.Close();
            wpfMap1.Refresh(streetLayerOverlay);
        }
 
        private void wpfMap1_MouseMove(object sender, MouseEventArgs e)
        {
            //Gets the PointShape in world coordinates from screen coordinates.
            Point point = e.MouseDevice.GetPosition(null);
            ScreenPointF screenPointF = new ScreenPointF((float)point.X, (float)point.Y);
            PointShape pointShape = ExtentHelper.ToWorldCoordinate(wpfMap1.CurrentExtent, screenPointF, (float)wpfMap1.Width, (float)wpfMap1.Height);
            textBox1.Text = "X: " + Math.Round(pointShape.X) +
                          "  Y: " + Math.Round(pointShape.Y);
           }
      }
}
source_code_wpfdesktopeditionsample_customrotationprojection_cs_110127.zip.txt · Last modified: 2015/09/09 03:38 by admin