ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
using System; using System.Globalization; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.Routing; namespace ThinkGeo.MapSuite.RoutingExamples { public class RouteDirectionModel { private static string directionImageUriTemplate = "../../Image/Directions/{0}"; private string roadNameColumnName; private string directionImageUriString; private Feature roadFeature; private DistanceUnit lengthUnit; private RouteSegment roadSegment; private Feature roadSegmentFeature; private GeographyUnit geographyUnit; public RouteDirectionModel() : this(null, null, null) { } public RouteDirectionModel(RouteSegment roadSegment, Feature roadFeature, string roadNameColumnName) : this(roadSegment, roadFeature, roadNameColumnName, GeographyUnit.DecimalDegree, DistanceUnit.Meter) { } public RouteDirectionModel(RouteSegment roadSegment, Feature roadFeature, string roadNameColumnName, GeographyUnit geographyUnit, DistanceUnit lengthUnit) { this.roadSegment = roadSegment; this.roadFeature = roadFeature; this.roadNameColumnName = roadNameColumnName; this.geographyUnit = geographyUnit; this.lengthUnit = lengthUnit; } public DrivingDirection Direction { get { return roadSegment != null ? roadSegment.DrivingDirection : DrivingDirection.Back; } } public GeographyUnit GeographyUnit { get { return geographyUnit; } set { geographyUnit = value; } } public DistanceUnit LengthUnit { get { return lengthUnit; } set { lengthUnit = value; } } public Feature RoadFeature { get { return roadFeature; } set { roadFeature = value; } } public string RoadNameColumnName { get { return roadNameColumnName; } set { roadNameColumnName = value; } } public RouteSegment RoadSegment { get { return roadSegment; } set { roadSegment = value; } } public Feature RoadSegmentFeature { get { return roadSegmentFeature; } set { roadSegmentFeature = value; } } public string Length { get { double value = Math.Round(((LineBaseShape)RoadFeature.GetShape()).GetLength(GeographyUnit, lengthUnit), 2); return string.Format(CultureInfo.InvariantCulture, "{0} {1}", value, lengthUnit == DistanceUnit.Mile ? "mi" : "km"); } } public string RoadName { get { string roadName = string.Empty; if (!string.IsNullOrEmpty(RoadNameColumnName)) { roadName = roadFeature.ColumnValues[RoadNameColumnName]; } return roadName; } } public Uri DirectionImageUri { get { switch (Direction) { case DrivingDirection.Back: directionImageUriString = "back.png"; break; case DrivingDirection.Forward: directionImageUriString = "Forward.png"; break; case DrivingDirection.Invalid: directionImageUriString = "Invalid.png"; break; case DrivingDirection.LeftForward: directionImageUriString = "LeftForward.png"; break; case DrivingDirection.Right: directionImageUriString = "Right.png"; break; case DrivingDirection.RightBack: directionImageUriString = "RightBack.png"; break; case DrivingDirection.RightForward: directionImageUriString = "RightForward.png"; break; case DrivingDirection.LeftBack: directionImageUriString = "LeftBack.png"; break; case DrivingDirection.Left: directionImageUriString = "Left.png"; break; } return new Uri(string.Format(CultureInfo.InvariantCulture, directionImageUriTemplate, directionImageUriString), UriKind.RelativeOrAbsolute); } } } }
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.Routing; namespace ThinkGeo.MapSuite.RoutingExamples { public class RoutePathAndDirection { private readonly IEnumerable<PointShape> stopPoints; private readonly IEnumerable<string> avoidableFeatureIds; private PointShape endPoint; private PointShape startPoint; private RoutingEngine routingEngine; private FeatureSource barrierFeatureSource; public RoutePathAndDirection() { } public RoutePathAndDirection(RoutingEngine routingEngine, PointShape startPoint, PointShape endPoint) : this(routingEngine, startPoint, endPoint, null) { } public RoutePathAndDirection(RoutingEngine routingEngine, PointShape startPoint, PointShape endPoint, FeatureSource barrierFeatureSource) : this(routingEngine, startPoint, endPoint, barrierFeatureSource, new string[] { }) { } public RoutePathAndDirection(RoutingEngine routingEngine, PointShape startPoint, PointShape endPoint, FeatureSource barrierFeatureSource, IEnumerable<string> avoidableFeatureIds) : this(routingEngine, startPoint, endPoint, barrierFeatureSource, avoidableFeatureIds, new PointShape[] { }) { } public RoutePathAndDirection(RoutingEngine routingEngine, PointShape startPoint, PointShape endPoint, FeatureSource barrierFeatureSource, IEnumerable<PointShape> stopPoints) : this(routingEngine, startPoint, endPoint, barrierFeatureSource, new string[] { }, stopPoints) { } public RoutePathAndDirection(RoutingEngine routingEngine, PointShape startPoint, PointShape endPoint, FeatureSource barrierFeatureSource, IEnumerable<string> avoidableFeatureIds, IEnumerable<PointShape> stopPoints) { this.stopPoints = stopPoints; this.avoidableFeatureIds = avoidableFeatureIds; this.barrierFeatureSource = barrierFeatureSource; this.routingEngine = routingEngine; this.startPoint = startPoint; this.endPoint = endPoint; routingEngine.RoutingAlgorithm.FindingRoute += RoutingAlgorithm_FindingRoute; } public PointShape StartPoint { get { return startPoint; } set { startPoint = value; } } public PointShape EndPoint { get { return endPoint; } set { endPoint = value; } } public IEnumerable<PointShape> StopPoints { get { return stopPoints; } } public RoutingEngine RoutingEngine { get { return routingEngine; } set { routingEngine = value; } } public FeatureSource BarrierFeatureSource { get { return barrierFeatureSource; } set { barrierFeatureSource = value; } } public RoutingResult GetRoute() { if (stopPoints != null && !stopPoints.Any()) { RoutingResult result = routingEngine.GetRoute(startPoint, endPoint); return result; } else { Collection<PointShape> points = new Collection<PointShape>(); points.Add(startPoint); foreach (PointShape stopPoint in stopPoints) { points.Add(stopPoint); } points.Add(endPoint); // Filter the invalid point. Collection<PointShape> availablePoint = FilterInvalidPoints(points); RoutingResult result = null; for (int i = 0; i < availablePoint.Count - 1; i++) { RoutingResult tempResult = routingEngine.GetRoute(availablePoint[i], availablePoint[i|+ 1]); result = CombineRoutingResult(result, tempResult); } return result; } } private Collection<PointShape> FilterInvalidPoints(IEnumerable<PointShape> points) { Collection<PointShape> result = new Collection<PointShape>(); barrierFeatureSource.Open(); Collection<Feature> barrierFeatures = barrierFeatureSource.GetAllFeatures(ReturningColumnsType.NoColumns); foreach (PointShape point in points) { bool inBarrier = barrierFeatures.Any(a => a.Contains(new Feature(point))); if (!inBarrier) result.Add(point); } return result; } private RoutingResult CombineRoutingResult(RoutingResult baseResult, RoutingResult additionalResult) { if (baseResult == null) { baseResult = new RoutingResult(); baseResult.Distance = additionalResult.Distance; baseResult.Weight = additionalResult.Weight; baseResult.Route = additionalResult.Route; additionalResult.Features.ForEach(a => baseResult.Features.Add(a)); additionalResult.OrderedStops.ForEach(a => baseResult.OrderedStops.Add(a)); additionalResult.RouteSegments.ForEach(a => baseResult.RouteSegments.Add(a)); } else { baseResult.Distance += additionalResult.Distance; baseResult.Weight += additionalResult.Weight; Collection<Vertex> vertexes = new Collection<Vertex>(); baseResult.Route.Vertices.ForEach(vertexes.Add); additionalResult.Route.Vertices.ForEach(vertexes.Add); baseResult.Route = new LineShape(vertexes); additionalResult.Features.ForEach(a => baseResult.Features.Add(a)); additionalResult.OrderedStops.ForEach(a => baseResult.OrderedStops.Add(a)); additionalResult.RouteSegments.ForEach(a => baseResult.RouteSegments.Add(a)); } return baseResult; } private void RoutingAlgorithm_FindingRoute(object sender, FindingRouteRoutingAlgorithmEventArgs e) { Collection<string> beContainedFeatureIds = new Collection<string>(); barrierFeatureSource.Open(); Collection<string> startPointAdjacentIds = e.RouteSegment.StartPointAdjacentIds; Collection<string> endPointAdjacentIds = e.RouteSegment.EndPointAdjacentIds; foreach (string id in startPointAdjacentIds.Where(id => avoidableFeatureIds.Contains(id))) { beContainedFeatureIds.Add(id); } foreach (string id in endPointAdjacentIds.Where(id => avoidableFeatureIds.Contains(id))) { beContainedFeatureIds.Add(id); } // Remove the ones that be contained in the avoidable area foreach (string id in beContainedFeatureIds) { if (e.RouteSegment.StartPointAdjacentIds.Contains(id)) { e.RouteSegment.StartPointAdjacentIds.Remove(id); } if (e.RouteSegment.EndPointAdjacentIds.Contains(id)) { e.RouteSegment.EndPointAdjacentIds.Remove(id); } } } } }
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; namespace ThinkGeo.MapSuite.RoutingExamples { public static class MapSuiteExampleHelper { public static GraphicsPath CreateRoundPath(Rectangle rect, int arcRadius) { GraphicsPath path = new GraphicsPath(); if (rect.Width == 0 || rect.Height == 0) return path; if (arcRadius > 0) { path.AddArc(rect.Left, rect.Top, arcRadius, arcRadius, 180, 90); path.AddArc(rect.Right - arcRadius, rect.Top, arcRadius, arcRadius, -90, 90); path.AddArc(rect.Right - arcRadius, rect.Bottom - arcRadius, arcRadius, arcRadius, 0, 90); path.AddArc(rect.Left, rect.Bottom - arcRadius, arcRadius, arcRadius, 90, 90); } path.CloseFigure(); return path; } public static void ForEach<T>(this IEnumerable<T> items, Action<T> action) { foreach (var item in items) { if (action != null) action(item); } } } }
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Globalization; using System.Windows.Forms; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.DesktopEdition; using ThinkGeo.MapSuite.Routing; namespace ThinkGeo.MapSuite.RoutingExamples { public partial class MainForm : Form { private static readonly string roadColumnName = "FULL_STREE"; private static readonly string rtgFastestFile = @"..\..\App_Data\austin_streets_fastest.rtg"; private static readonly string rtgShortestFile = @"..\..\App_Data\austin_streets_shortest.rtg"; private static readonly string austinStreetShapeFile = @"..\..\App_Data\austin_streets.shp"; private readonly int endTextBox; private readonly int pictureBox2Top; private readonly int flowLayoutPanelTop; private MultipolygonShape restrictedPolygon; private RoutingLayer routingLayer; private LayerOverlay routingOverlay; private PointShape clickedMouseWorldPoint; private InMemoryFeatureLayer barrierLayer; private Collection<string> avoidableFeatureIds; private ShapeFileFeatureLayer routingFeatureLayer; public MainForm() { InitializeComponent(); InitializeBackground(); InitializeMap(); InitializeToolTips(); flowLayoutPanelTop = flowLayoutPanel1.Top; endTextBox = txtEnd.Top; pictureBox2Top = pictureBox2.Top; } private InMemoryFeatureLayer TrackShapeLayer { get { return mapControl.TrackOverlay.TrackShapeLayer; } } private void InitializeToolTips() { ToolTip toolTip = new ToolTip(); toolTip.SetToolTip(rbtnPan, "Pan the map"); toolTip.SetToolTip(rbtnDrawPolygon, "Draw areas to avoid traveling through"); toolTip.SetToolTip(rbtnUndo, "Undo last area drawn"); toolTip.SetToolTip(rbtnClearAll, "Delete all areas"); toolTip.SetToolTip(btnSwitch, "Switch start and end search point"); } private void MainForm_Load(object sender, EventArgs e) { avoidableFeatureIds = new Collection<string>(); routingFeatureLayer = new ShapeFileFeatureLayer(austinStreetShapeFile); cmbDistance.SelectedIndex = 0; MenuItem startItem = new MenuItem("Direction from here"); MenuItem endItem = new MenuItem("Direction to here"); MenuItem stopItem = new MenuItem("Add a waypoint here"); startItem.Click += AddStartPointMenuItem_Click; endItem.Click += AddEndPointMenuItem_Click; stopItem.Click += AddStopMenuItem_Click; ContextMenu menuOnMap = new ContextMenu(); menuOnMap.MenuItems.Add(startItem); menuOnMap.MenuItems.Add(endItem); menuOnMap.MenuItems.Add(stopItem); mapControl.ContextMenu = menuOnMap; mapControl.CurrentExtent = new RectangleShape(-97.803553154785, 30.352039937378, -97.700175654785, 30.259261310914); mapControl.Refresh(); } private void TrackOverlay_TrackEnded(object sender, TrackEndedTrackInteractiveOverlayEventArgs e) { if (TrackShapeLayer.InternalFeatures.Count > 0) { PolygonShape trackedPolygonShape = TrackShapeLayer.InternalFeatures[0].GetShape() as PolygonShape; if (trackedPolygonShape != null) { if (trackedPolygonShape.IsWithin(restrictedPolygon)) { barrierLayer.InternalFeatures.Add(TrackShapeLayer.InternalFeatures[0]); } else { MessageBox.Show("Please note that this sample map is only able to analyze service areas within the Austin city limits, which are indicated by a dashed red line. Click inside that boundary for best results.", "Draw Area"); } TrackShapeLayer.InternalFeatures.Clear(); UpdateAvoidFeatureIds(); mapControl.Refresh(routingOverlay); } } } private void Map_MouseMove(object sender, MouseEventArgs e) { PointShape mouseLocation = ExtentHelper.ToWorldCoordinate(mapControl.CurrentExtent, new ScreenPointF(e.X, e.Y), mapControl.Width, mapControl.Height); lblFooterLocationX.Text = string.Format(CultureInfo.InvariantCulture, "X : {0:N6}", mouseLocation.X); lblFooterLocationY.Text = string.Format(CultureInfo.InvariantCulture, "Y : {0:N6}", mouseLocation.Y); stpFooter.Refresh(); } private void Map_MouseDown(object sender, MouseEventArgs e) { clickedMouseWorldPoint = ExtentHelper.ToWorldCoordinate(mapControl.CurrentExtent, new ScreenPointF(e.Location.X, e.Location.Y), mapControl.Width, mapControl.Height); } private void AddStopMenuItem_Click(object sender, EventArgs e) { routingLayer.StopPoints.Add(clickedMouseWorldPoint); mapControl.Refresh(routingOverlay); RefreshStopList(); } private void RefreshStopList() { StopItemsPanel.Controls.Clear(); btnSwitch.Visible = !(routingLayer.StopPoints.Count > 0); int stopItemsPanelHeight = 0; for (int i = 0; i < routingLayer.StopPoints.Count; i++) { PointShape locationItem = routingLayer.StopPoints[i]; if (locationItem != null) { StopItemUserControl stopControl = new StopItemUserControl(locationItem, i + 1); stopControl.btnRemove.Click += BtnRemove_Click; stopItemsPanelHeight += stopControl.Height; StopItemsPanel.Controls.Add(stopControl); } } if (routingLayer.StopPoints.Count > 0) { if (routingLayer.StopPoints.Count >= 8) { flowLayoutPanel1.VerticalScroll.Enabled = true; flowLayoutPanel1.VerticalScroll.Visible = true; } else { stopItemsPanelHeight += routingLayer.StopPoints.Count * 7; StopItemsPanel.Height = stopItemsPanelHeight; flowLayoutPanel1.Top = flowLayoutPanelTop + stopItemsPanelHeight; txtEnd.Top = endTextBox + stopItemsPanelHeight; pictureBox2.Top = pictureBox2Top + stopItemsPanelHeight; } } else { StopItemsPanel.Height = stopItemsPanelHeight; flowLayoutPanel1.Top = flowLayoutPanelTop; txtEnd.Top = endTextBox; pictureBox2.Top = pictureBox2Top; } flowLayoutPanel1.Refresh(); } private void BtnRemove_Click(object sender, EventArgs e) { Button button = (Button)sender; StopItemUserControl stopItem = (StopItemUserControl)button.Parent; PointShape selectStopItem = routingLayer.StopPoints[StopItemsPanel.Controls.IndexOf(stopItem)]; routingLayer.StopPoints.Remove(selectStopItem); routingLayer.Routes.Clear(); mapControl.Refresh(routingOverlay); RefreshStopList(); } private void AddEndPointMenuItem_Click(object sender, EventArgs e) { txtEnd.Text = string.Format(CultureInfo.InvariantCulture, "{0}, {1}", clickedMouseWorldPoint.X.ToString("N8"), clickedMouseWorldPoint.Y.ToString("N8")); routingLayer.EndPoint = clickedMouseWorldPoint; routingLayer.Routes.Clear(); mapControl.Refresh(routingOverlay); } private void AddStartPointMenuItem_Click(object sender, EventArgs e) { txtStart.Text = string.Format(CultureInfo.InvariantCulture, "{0}, {1}", clickedMouseWorldPoint.X.ToString("N8"), clickedMouseWorldPoint.Y.ToString("N8")); routingLayer.StartPoint = clickedMouseWorldPoint; routingLayer.Routes.Clear(); mapControl.Refresh(routingOverlay); } private void GetDirectionButton_Click(object sender, EventArgs e) { if (routingLayer.StartPoint == null || routingLayer.EndPoint == null) return; DistanceUnit distanceUnit = cmbDistance.SelectedIndex == 1 ? DistanceUnit.Kilometer : DistanceUnit.Mile; string rtgFilePathName = rbtnShortest.Checked ? rtgShortestFile : rtgFastestFile; RoutingEngine routingEngine = new RoutingEngine(new RtgRoutingSource(rtgFilePathName), routingFeatureLayer.FeatureSource); RoutePathAndDirection routePathAndDirection = new RoutePathAndDirection(routingEngine, routingLayer.StartPoint, routingLayer.EndPoint, barrierLayer.FeatureSource, avoidableFeatureIds, routingLayer.StopPoints); RoutingResult result = routePathAndDirection.GetRoute(); routingLayer.Routes.Clear(); routingLayer.Routes.Add(result.Route); Collection<RouteDirectionModel> models = new Collection<RouteDirectionModel>(); for (int i = 0; i < result.RouteSegments.Count; i++) { RouteDirectionModel routeDirection = new RouteDirectionModel(result.RouteSegments[i], result.Features[i], roadColumnName, mapControl.MapUnit, distanceUnit); models.Add(routeDirection); } UpdateResultGrid(models); mapControl.Refresh(routingOverlay); } private void UpdateResultGrid(IEnumerable<RouteDirectionModel> items) { dgvQueryResultItems.Rows.Clear(); foreach (var item in items) { DataGridViewRow newRow = new DataGridViewRow(); Image image = Image.FromFile(item.DirectionImageUri.OriginalString); Image image1 = image.GetThumbnailImage(23, 23, null, IntPtr.Zero); newRow.Cells.Add(new DataGridViewImageCell { Value = image1 }); newRow.Cells.Add(new DataGridViewTextBoxCell { Value = item.RoadName }); newRow.Cells.Add(new DataGridViewTextBoxCell { Value = item.Length }); dgvQueryResultItems.Rows.Add(newRow); } dgvQueryResultItems.Visible = true; } private void RadioButton_CheckedChanged(object sender, EventArgs e) { RadioButton rbtn = sender as RadioButton; if (rbtn != null) { rbtn.FlatAppearance.BorderColor = rbtn.Checked ? Color.FromArgb(136, 136, 136) : Color.White; if (rbtn.Equals(rbtnPan)) { mapControl.TrackOverlay.TrackMode = TrackMode.None; } else if (rbtn.Equals(rbtnDrawPolygon)) { mapControl.TrackOverlay.TrackMode = TrackMode.Polygon; } } } private void Clear() { barrierLayer.InternalFeatures.Clear(); mapControl.Refresh(routingOverlay); TrackShapeLayer.InternalFeatures.Clear(); } private void UndoTrack() { if (barrierLayer.InternalFeatures.Count > 0) { barrierLayer.InternalFeatures.RemoveAt(barrierLayer.InternalFeatures.Count - 1); UpdateAvoidFeatureIds(); mapControl.Refresh(routingOverlay); } } private void btnSwitch_Click(object sender, EventArgs e) { PointShape end = routingLayer.StartPoint; routingLayer.StartPoint = routingLayer.EndPoint; routingLayer.EndPoint = end; string endString = txtStart.Text; txtStart.Text = txtEnd.Text; txtEnd.Text = endString; mapControl.Refresh(routingOverlay); } private void ClearAllButton_Click(object sender, EventArgs e) { txtEnd.Text = string.Empty; txtStart.Text = string.Empty; routingLayer.StopPoints.Clear(); RefreshStopList(); routingLayer.StartPoint = null; routingLayer.EndPoint = null; routingLayer.Routes.Clear(); mapControl.Refresh(routingOverlay); } private void LeftSideBarPanel_PanelCollapseButtonClick(object sender, EventArgs e) { mapControl.Width = Width - collapsiblePanel.Width - 15; mapControl.Left = collapsiblePanel.Width; } private void UpdateAvoidFeatureIds() { routingFeatureLayer.Open(); avoidableFeatureIds.Clear(); foreach (Feature feature in barrierLayer.InternalFeatures) { Collection<Feature> features = routingFeatureLayer.FeatureSource.GetFeaturesWithinDistanceOf(feature, mapControl.MapUnit, DistanceUnit.Meter, 1, ReturningColumnsType.NoColumns); foreach (Feature avoidableFeature in features) avoidableFeatureIds.Add(avoidableFeature.Id); } } private void InitializeMap() { mapControl.AdornmentOverlay.ShowLogo = false; mapControl.MapUnit = GeographyUnit.DecimalDegree; mapControl.TrackOverlay.TrackEnded += TrackOverlay_TrackEnded; mapControl.Overlays.Add("World Map Kit", new WorldMapKitWmsDesktopOverlay()); InitRoutingOverlays(); InitRestrictedOverlay(); } private void InitRoutingOverlays() { routingOverlay = new LayerOverlay(); mapControl.Overlays.Add("RoutingOverlay", routingOverlay); routingLayer = new RoutingLayer(); routingLayer.StartPointStyle = new PointStyle(new GeoImage(@"..\..\Image\start.png")); routingLayer.EndPointStyle = new PointStyle(new GeoImage(@"..\..\Image\end.png")); routingLayer.StopPointStyle = new PointStyle(new GeoImage(@"..\..\Image\stop.png")) { YOffsetInPixel = -10 }; routingLayer.StopTextStyle.TextSolidBrush.Color = GeoColor.StandardColors.White; routingLayer.StopTextStyle.Font = new GeoFont("Arial", 10); routingLayer.XOffsetInPixelOfStopOrder = -3; routingLayer.YOffsetInPixelOfStopOrder = 14; routingOverlay.Layers.Add("RoutingLayer", routingLayer); barrierLayer = new InMemoryFeatureLayer(); barrierLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.FromArgb(100, GeoColor.SimpleColors.Red), GeoColor.SimpleColors.Red, 1); barrierLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; routingOverlay.Layers.Add("BarrierLayer", barrierLayer); } private void InitRestrictedOverlay() { LayerOverlay restrictedOverlay = new LayerOverlay(); mapControl.Overlays.Add("RestrictedOverlay", restrictedOverlay); const string austinCountyShapeFile = @"..\..\App_Data\AustinBorder.shp"; ShapeFileFeatureLayer restrictedLayer = new ShapeFileFeatureLayer(austinCountyShapeFile); restrictedLayer.Open(); restrictedPolygon = (MultipolygonShape)restrictedLayer.QueryTools.GetAllFeatures(ReturningColumnsType.AllColumns)[0].GetShape(); AreaStyle extentStyle = new AreaStyle(); extentStyle.CustomAreaStyles.Add(new AreaStyle(new GeoSolidBrush(GeoColor.SimpleColors.Transparent)) { OutlinePen = new GeoPen(GeoColor.SimpleColors.White, 5.5f) }); extentStyle.CustomAreaStyles.Add(new AreaStyle(new GeoSolidBrush(GeoColor.SimpleColors.Transparent)) { OutlinePen = new GeoPen(GeoColor.SimpleColors.Red, 1.5f) { DashStyle = LineDashStyle.Dash } }); restrictedLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = extentStyle; restrictedLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; restrictedOverlay.Layers.Add("RestrictedLayer", restrictedLayer); } private void InitializeBackground() { Bitmap queryToolBitmap = new Bitmap(pnlQueryTool.Width - 1, pnlQueryTool.Height - 1); using (Graphics g = Graphics.FromImage(queryToolBitmap)) { g.SmoothingMode = SmoothingMode.HighQuality; Rectangle drawingRectangle = new Rectangle(0, 0, queryToolBitmap.Width, queryToolBitmap.Height); GraphicsPath path = MapSuiteExampleHelper.CreateRoundPath(drawingRectangle, 10); g.DrawPath(new Pen(Color.LightGray, 1), path); } pnlQueryTool.BackgroundImage = queryToolBitmap; } private void UndoButton_Click(object sender, EventArgs e) { UndoTrack(); } private void ClearPolygons_Click(object sender, EventArgs e) { Clear(); } } }