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);
}
}
}