Table of Contents

Source Code ServicesEditionSample SnapGpsToStreet CS 100108.zip

Program.cs

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Windows.Forms;  
 
 namespace DisplayingOneWayStreets  
 {  
     static class Program  
     {  
         /// <summary>  
         /// The main entry point for the application.  
         /// </summary>  
         [STAThread]  
         static void Main()  
         {  
             Application.EnableVisualStyles();  
             Application.SetCompatibleTextRenderingDefault(false);  
             Application.Run(new TestForm());  
         }  
     }  
 }  
 

TestForm.cs

 using System;  
 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Drawing;  
 using System.Windows.Forms;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace DisplayingOneWayStreets  
 {  
     public partial class TestForm : Form  
     {  
         private MapEngine mapEngine = new MapEngine();  
         private Bitmap bitmap = null;  
 
         public TestForm()  
         {  
             InitializeComponent();  
         }  
 
         private void TestForm_Load(object sender, EventArgs e)  
         {  
             // Set the extent and the background color  
             mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-97.77, 30.30, -97.75, 30.29), Map.Width, Map.Height);  
             mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 237, 234, 226));  
 
             //Adds the street Layer for Austin  
             ShapeFileFeatureLayer austinStreetsShapeLayer = new ShapeFileFeatureLayer(@"..\..\Data\AustinWithOneWayRoad.shp");  
             austinStreetsShapeLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
             //Adds the first LineStyle for displaying the streets  
             austinStreetsShapeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(LineStyles.LocalRoad1);  
 
             // Add the label layer to show the street names  
             ShapeFileFeatureLayer austinStreetsLabelLayer = new ShapeFileFeatureLayer(@"..\..\Data\AustinWithOneWayRoad.shp");  
             austinStreetsLabelLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(TextStyles.LocalRoad1("FENAME"));  
             austinStreetsLabelLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
             // Add a point layer that will display the snapped point  
             InMemoryFeatureLayer gpsPointLayer = new InMemoryFeatureLayer();  
             gpsPointLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.Red, 10);  
             gpsPointLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
             // Add all the layers to the map  
             mapEngine.StaticLayers.Add("StreetLayer", austinStreetsShapeLayer);  
             mapEngine.StaticLayers.Add("StreetLayerLabel", austinStreetsLabelLayer);  
             mapEngine.StaticLayers.Add("PointLayer", gpsPointLayer);  
 
             DrawImage();  
 
             MessageBox.Show("Click near a street and we will snap the point to the nearest street if it is within 50 meters.");  
         }  
 
         private void Map_Click(object sender, EventArgs e)  
         {  
             // Get the location the user clicked and convert that to world coordinates  
             MouseEventArgs mouseEventArgs = (MouseEventArgs)e;  
             PointShape worldPointShape = ExtentHelper.ToWorldCoordinate(mapEngine.CurrentExtent, mouseEventArgs.X, mouseEventArgs.Y, Map.Width, Map.Height);  
 
             // Get the street layer that we want to snap too  
             FeatureLayer streetLayer = (FeatureLayer)mapEngine.StaticLayers["StreetLayer"];  
 
             // This method gets the closes point on the closest feature.  The result my be null if there is not  
             // a feature within your tolerance  
             PointShape closestPoint = SnapToFeature(new Collection<FeatureLayer> { streetLayer }, worldPointShape, GeographyUnit.DecimalDegree, 50, DistanceUnit.Meter);  
 
             //  Clear the point off the screen and if we have a point returned then place it on the map  
             InMemoryFeatureLayer pointLayer = (InMemoryFeatureLayer)mapEngine.StaticLayers["PointLayer"];  
             pointLayer.InternalFeatures.Clear();  
 
             if (closestPoint != null)  
             {  
                 pointLayer.InternalFeatures.Add(closestPoint.GetFeature());  
             }  
 
             // Refresh the screen  
             DrawImage();  
         }  
 
         private PointShape SnapToFeature(IEnumerable<FeatureLayer> snapToLayers, PointShape pointToSnap, GeographyUnit unitOfSnapToPoint, double maxDistance, DistanceUnit unitOfMaxDistance)  
         {  
             PointShape closestPoint = null;  
             double closestDistance = double.MaxValue;  
 
             // Loop through each layer to see which on have the closest point  
             foreach (FeatureLayer featureLayer in snapToLayers)  
             {  
                 // Make sure the layer is open  
                 featureLayer.Open();  
 
                 // Get all the features within our tolerance  
                 Collection<Feature> closeStreets = featureLayer.QueryTools.GetFeaturesInsideBoundingBox(new EllipseShape(pointToSnap, maxDistance, unitOfSnapToPoint, unitOfMaxDistance).GetBoundingBox(), ReturningColumnsType.NoColumns);  
 
                 // Loop through each feature in our tolerance  
                 foreach (Feature feature in closeStreets)  
                 {  
                     // Find out the distance to the closest point on the feature  
                     double snapDistance = pointToSnap.GetDistanceTo(feature.GetShape(), unitOfSnapToPoint, unitOfMaxDistance);  
 
                     // If the distance is closer than the previous closest distance  
                     // then this is the new winner so far  
                     if (snapDistance < closestDistance)  
                     {  
                         // Make sure the distance is within our tolerance  
                         if (snapDistance < maxDistance)  
                         {  
                             closestDistance = snapDistance;  
                             closestPoint = feature.GetShape().GetClosestPointTo(pointToSnap, unitOfSnapToPoint);  
                         }  
                     }  
                 }  
             }  
 
             // return the closest point on the closes feature.  Note that this may return null  
             // if there are no features within the tolerance  
             return closestPoint;  
         }  
 
         private void DrawImage()  
         {  
             if (bitmap != null) { bitmap.Dispose(); }  
             bitmap = new Bitmap(Map.Width, Map.Height);  
             mapEngine.OpenAllLayers();  
             mapEngine.DrawStaticLayers(bitmap, GeographyUnit.DecimalDegree);  
             mapEngine.DrawDynamicLayers(bitmap, GeographyUnit.DecimalDegree);  
             mapEngine.CloseAllLayers();  
 
             Map.Image = bitmap;  
         }  
 
         private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)  
         {  
             switch (e.Button.Tag.ToString())  
             {  
                 case "Zoom In":  
                     mapEngine.CurrentExtent.ScaleDown(50);  
                     break;  
                 case "Zoom Out":  
                     mapEngine.CurrentExtent.ScaleUp(50);  
                     break;  
                 case "Full Extent":  
                     mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-180.0, 83.0, 180.0, -90.0), Map.Width, Map.Height);  
                     break;  
                 case "Pan Left":  
                     mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Left, 20);  
                     break;  
                 case "Pan Right":  
                     mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Right, 20);  
                     break;  
                 case "Pan Up":  
                     mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Up, 20);  
                     break;  
                 case "Pan Down":  
                     mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Down, 20);  
                     break;  
                 default:  
                     break;  
             }  
             DrawImage();  
         }  
 
         private void btnClose_Click(object sender, EventArgs e)  
         {  
             this.Close();  
         }  
 
         private void Map_MouseMove(object sender, MouseEventArgs e)  
         {  
             //Displays the X and Y in screen coordinates.  
             statusStrip1.Items["toolStripStatusLabelScreen"].Text = "X:" + e.X + " Y:" + e.Y;  
 
             //Gets the PointShape in world coordinates from screen coordinates.  
             PointShape pointShape = ExtentHelper.ToWorldCoordinate(mapEngine.CurrentExtent, new ScreenPointF(e.X, e.Y), Map.Width, Map.Height);  
 
             //Displays world coordinates.  
             statusStrip1.Items["toolStripStatusLabelWorld"].Text = "(world) X:" + Math.Round(pointShape.X, 4) + " Y:" + Math.Round(pointShape.Y, 4);  
         }  
     }  
 }