User Tools

Site Tools


source_code_wpfdesktopeditionsample_findshortestlineandsplittinglines_cs_140425.zip

Source Code WpfDesktopEditionSample FindShortestLineandSplittingLines CS 140425.zip

TestWindow.xaml

 <Window x:Class="CustomRotationProjection.TestWindow"  
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
     xmlns:my="clr-namespace:ThinkGeo.MapSuite.WpfDesktopEdition;assembly=WpfDesktopEdition"  
     Title="Find Shortest Line from Point and Split Line" Height="640" Width="800"  
         Loaded="Window_Loaded" >  
     <Grid Height="Auto">  
         <Grid.ColumnDefinitions>  
             <ColumnDefinition Width="778*" />  
         </Grid.ColumnDefinitions>  
         <my:WpfMap Name="wpfMap1" />  
         <Button Height="28" Margin="0,12,20,0" Name="btnCalculate" VerticalAlignment="Top" HorizontalAlignment="Right" Width="246"  
                 Click="btnCalculate_Click" Content="Find Shortest Line from Point and Split Line" DataContext="{Binding}"></Button>  
         <Button Height="28" HorizontalAlignment="Right" Margin="0,46,20,0" Name="btnClear" VerticalAlignment="Top" Width="246"  
                 Click="btnClear_Click" Content="Clear Results"></Button>  
         <Button Height="28" HorizontalAlignment="Right" Margin="0,80,20,0" Name="btnMovePoint" VerticalAlignment="Top" Width="246"  
                 Click="btnEdit_Click" Content="Edit Test Features" />  
     </Grid>  
 </Window>  
 

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  
     {  
 
         public TestWindow()  
         {  
             InitializeComponent();  
         }  
 
         private void Window_Loaded(object sender, RoutedEventArgs e)  
         {  
 
             //Add a base map (ThinkGeo's online World Map Kit).  
             wpfMap1.MapUnit = GeographyUnit.DecimalDegree;  
             WorldMapKitWmsWpfOverlay worldOverlay = new WorldMapKitWmsWpfOverlay();  
             wpfMap1.Overlays.Add("WMK", worldOverlay);  
 
             //Build up the test data.  
             InMemoryFeatureLayer testData = setupTestData();  
             //Make test line red in color.  
             testData.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.SimpleColors.Red, 6, false);  
             //Make test point dark green in color.  
             testData.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.DarkGreen, 12);  
             //Apply the above styles to all zoom levels.  
             testData.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
             //Create a MapShapeLayer that we can style individually and which will hold the results of the shortest line and split lines.  
             MapShapeLayer results = new MapShapeLayer();  
 
             //Add the test data and results layers to a new layer overlay so they will show on top of the base map.  
             LayerOverlay layerOverlay = new LayerOverlay();  
             layerOverlay.Layers.Add("TestData", testData);  
             layerOverlay.Layers.Add("Results", results);  
             wpfMap1.Overlays.Add("layerOverlay", layerOverlay);  
 
             //Zoom into the test data area.  
             wpfMap1.CurrentExtent = testData.GetBoundingBox();  
             wpfMap1.Refresh();  
         }  
 
         private void btnCalculate_Click(object sender, RoutedEventArgs e)  
         {  
 
             //Get a reference to the results MapShapeLayer and clear it so we can display our new results.  
             MapShapeLayer results = (MapShapeLayer)((LayerOverlay)wpfMap1.Overlays["layerOverlay"]).Layers["Results"];  
             results.MapShapes.Clear();  
 
             //Get a reference to the test data layer.  
             InMemoryFeatureLayer testDataLayer = (InMemoryFeatureLayer)((LayerOverlay)wpfMap1.Overlays["layerOverlay"]).Layers["TestData"];  
             //Check to see if the test data has been edited.  
             if (wpfMap1.EditOverlay.EditShapesLayer.InternalFeatures.Count > 0)  
             {  
                 //Loop through the edited test data and update the test data layer.  
                 testDataLayer.EditTools.BeginTransaction();  
                 foreach (Feature feature in wpfMap1.EditOverlay.EditShapesLayer.InternalFeatures)  
                 {  
                     testDataLayer.EditTools.Update(feature.CloneDeep());  
                 }  
                 testDataLayer.EditTools.CommitTransaction();  
                 //Clear out the EditOverlay since we are done editing.  
                 wpfMap1.EditOverlay.EditShapesLayer.InternalFeatures.Clear();  
                 //Since we are done editing, turn visibility back on the for the layer overlay so we can see our test data again.  
                 wpfMap1.Overlays["layerOverlay"].IsVisible = true;  
             }  
 
             //Get the test point feature from the test data layer.  
             Feature testPointFeature = testDataLayer.QueryTools.GetFeaturesByColumnValue("Name", "TestPoint", ReturningColumnsType.AllColumns)[0];  
             //Get the test line feature from the test data layer.  
             Feature testLineFeature = testDataLayer.QueryTools.GetFeaturesByColumnValue("Name", "TestLine", ReturningColumnsType.AllColumns)[0];  
             //Take the test line feature and create a line shape so we can use line-specific APIs for finding the shortest line and line-on-line.  
             LineShape testLine = new MultilineShape(testLineFeature.GetWellKnownText()).Lines[0];  
 
             //Calculate the shortest line between our test line and test point.  
             LineShape shortestLineResult = testLine.GetShortestLineTo(testPointFeature.GetShape(), GeographyUnit.DecimalDegree).Lines[0];  
             //Take the result and create a MapShape so we can display the shortest line on the map in a blue color.  
             MapShape shortestLine = new MapShape(new Feature(shortestLineResult));  
             shortestLine.ZoomLevels.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.SimpleColors.Blue, 4, false);  
             shortestLine.ZoomLevels.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
             results.MapShapes.Add("ShortestLine", shortestLine);  
             string message = "Length of Blue Line is: " + shortestLineResult.GetLength(GeographyUnit.DecimalDegree, DistanceUnit.Kilometer).ToString() + " KM" + '\n';  
 
             //Split the test line from the left side based on where the shortest line touches it.  
             LineBaseShape leftSideOfLineResult = testLine.GetLineOnALine(new PointShape(testLine.Vertices[0]), new PointShape(shortestLineResult.Vertices[0]));  
             //Make sure the split was valid and the closest point wasn't at the beginning or end of the line.  
             if (leftSideOfLineResult.Validate(ShapeValidationMode.Simple).IsValid)  
             {  
                 MapShape leftSideOfLine = new MapShape(new Feature(leftSideOfLineResult));  
                 leftSideOfLine.ZoomLevels.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Green, 2, false);  
                 leftSideOfLine.ZoomLevels.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
                 results.MapShapes.Add("LeftSideofLine", leftSideOfLine);  
                 message += "Length of Green Line is: " + leftSideOfLineResult.GetLength(GeographyUnit.DecimalDegree, DistanceUnit.Kilometer).ToString() + " KM" + '\n';  
             }  
 
             //Split the test line from the right side based on where the shortest line touches it.  
             LineBaseShape rightSideOfLineResult = testLine.GetLineOnALine(new PointShape(shortestLineResult.Vertices[0]), new PointShape(testLine.Vertices[testLine.Vertices.Count|- 1]));  
             //Make sure the split was valid and the closest point wasn't at the beginning or end of the line.  
             if (rightSideOfLineResult.Validate(ShapeValidationMode.Simple).IsValid)  
             {  
                 MapShape rightSideOfLine = new MapShape(new Feature(rightSideOfLineResult));  
                 rightSideOfLine.ZoomLevels.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.SimpleColors.Yellow, 2, false);  
                 rightSideOfLine.ZoomLevels.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
                 results.MapShapes.Add("RightSideofLine", rightSideOfLine);  
                 message += "Length of Yellow Line is: " + rightSideOfLineResult.GetLength(GeographyUnit.DecimalDegree, DistanceUnit.Kilometer).ToString() + " KM" + '\n';  
             }  
             //Display the length of each line in kilometers.  
             message += "Length of Red Line is: " + testLine.GetLength(GeographyUnit.DecimalDegree, DistanceUnit.Kilometer).ToString() + " KM";  
             wpfMap1.Refresh();  
             MessageBox.Show(message, "Results");  
         }  
 
         private void btnClear_Click(object sender, RoutedEventArgs e)  
         {  
             //Get a reference to our overlay that has the test data in it.  
             LayerOverlay layerOverlay = (LayerOverlay)wpfMap1.Overlays["layerOverlay"];  
             //Get a refrence to the results MapShapeLayer and clear out any prior results if they exist.  
             MapShapeLayer results = (MapShapeLayer)layerOverlay.Layers["Results"];  
             results.MapShapes.Clear();  
             wpfMap1.Refresh();  
         }  
 
         private void btnEdit_Click(object sender, RoutedEventArgs e)  
         {  
             //Check to make sure we haven't already added our test features to the EditShapesLayer.  
             if (wpfMap1.EditOverlay.EditShapesLayer.InternalFeatures.Count == 0)  
             {  
                 //Get a reference to the test data Layer.  
                 InMemoryFeatureLayer testData = ((InMemoryFeatureLayer)((LayerOverlay)wpfMap1.Overlays["layerOverlay"]).Layers["TestData"]);  
                 wpfMap1.EditOverlay.EditShapesLayer.Open();  
                 //Check to see if this the first time we have ever edited the features. If so, add a column so that our name is stored correctly.  
                 if (wpfMap1.EditOverlay.EditShapesLayer.Columns.Count == 0)  
                 {  
                     wpfMap1.EditOverlay.EditShapesLayer.Columns.Add(new FeatureSourceColumn("Name"));  
                 }  
 
                 //Loop through all of our test data and add it to the edit overlay so we can interact with the test data.  
                 foreach (Feature feature in testData.QueryTools.GetAllFeatures(ReturningColumnsType.AllColumns))  
                 {  
                     wpfMap1.EditOverlay.EditShapesLayer.InternalFeatures.Add(feature.CloneDeep());  
                 }  
                 wpfMap1.EditOverlay.CalculateAllControlPoints();  
                 //Turn off the LayerOverlay with our test data while we are editing it.  
                 wpfMap1.Overlays["layerOverlay"].IsVisible = false;  
                 //Refresh the map.  
                 wpfMap1.Refresh();  
             }  
         }  
 
         private InMemoryFeatureLayer setupTestData()  
         {  
             //Set up an in-memory layer with our test point and test line.  
             InMemoryFeatureLayer testData = new InMemoryFeatureLayer();  
             testData.Open();  
             //Create a column on the layer to hold the name of the test feature.  
             testData.Columns.Add(new FeatureSourceColumn("Name"));  
             //Begin adding the test features to the layer.  
             testData.EditTools.BeginTransaction();  
 
             //Create a test point based on an X and Y coordinate.  
             Feature testPoint = new Feature(-0.1353814, 51.55651);  
             //Set the name of the test feature to "TestPoint".  
             testPoint.ColumnValues["Name"] = "TestPoint";  
             //Add the test point to the layer.  
             testData.EditTools.Add(testPoint);  
 
             //Create a test line based on a well-known text string containing the coordinates of the line.  
             Feature testLine = new Feature("MULTILINESTRING((-0.395401840884043 51.4602079393573,-0.249570304960823 51.5620148606622,-0.0817264617284379 51.4588321701505,0.0352139208515025 51.5537602454212,0.168663533913317 51.4533290933232,0.27734930125232 51.5537602454212,0.392913914625438 51.4657110161846))");  
             //Set the name of the test feature to "TestLine".  
             testLine.ColumnValues["Name"] = "TestLine";  
             //Add the test line to the layer.  
             testData.EditTools.Add(testLine);  
             //Commit the changes.  
             testData.EditTools.CommitTransaction();  
 
             return testData;  
         }  
     }  
 }  
 
source_code_wpfdesktopeditionsample_findshortestlineandsplittinglines_cs_140425.zip.txt · Last modified: 2015/09/09 03:38 by admin