private Shapefile CreateCarShapefile(CarService service) { var sf = new Shapefile(); sf.CreateNew("", ShpfileType.SHP_POINT); sf.DefaultDrawingOptions.AlignPictureByBottom = false; var ct = sf.Categories.Add("Police"); var opt = ct.DrawingOptions; opt.PointType = tkPointSymbolType.ptSymbolPicture; opt.Picture = IconManager.GetIcon(CarType.Police); ct = sf.Categories.Add("Taxi"); opt = ct.DrawingOptions; opt.PointType = tkPointSymbolType.ptSymbolPicture; opt.Picture = IconManager.GetIcon(CarType.Taxi); ct = sf.Categories.Add("Ambulance"); opt = ct.DrawingOptions; opt.PointType = tkPointSymbolType.ptSymbolPicture; opt.Picture = IconManager.GetIcon(CarType.Ambulance); // general settings for labels should be applied before creating categories sf.Labels.FrameVisible = true; sf.Labels.TextRenderingHint = tkTextRenderingHint.ClearTypeGridFit; var utils = new Utils(); var lb = sf.Labels.AddCategory("Busy"); lb.FrameBackColor = utils.ColorByName(tkMapColor.Yellow); lb = sf.Labels.AddCategory("Available"); lb.FrameBackColor = utils.ColorByName(tkMapColor.Green); lb = sf.Labels.AddCategory("OutOfService"); lb.FrameBackColor = utils.ColorByName(tkMapColor.Gray); Debug.Print("Num categories: " + sf.Labels.NumCategories); for (int i = 0; i < service.Cars.Count; i++) { var car = service.Cars[i]; var shp = new Shape(); shp.Create(ShpfileType.SHP_POINT); shp.AddPoint(car.X, car.Y); sf.EditAddShape(shp); sf.ShapeCategory[i] = (int)car.CarType; sf.Labels.AddLabel(car.ToString(), car.X, car.Y); sf.Labels.Label[i, 0].Category = (int)(car.State); } return(sf); }
// <summary> // Loads the layers, registers event handlers // </summary> public void Tracking(AxMap axMap1, string dataPath) { axMap1.Projection = tkMapProjection.PROJECTION_NONE; axMap1.GrabProjectionFromData = true; axMap1.DisableWaitCursor = true; string filename1 = dataPath + "buildings.shp"; string filename2 = dataPath + "roads.shp"; string filename3 = dataPath + "path.shp"; if (!File.Exists(filename1) || !File.Exists(filename2) || !File.Exists(filename3)) { MessageBox.Show("Couldn't find the files (buildings.shp, roads.shp, path.shp): " + dataPath); } else { Shapefile sf = new Shapefile(); sf.Open(filename1, null); axMap1.AddLayer(sf, true); sf = new Shapefile(); sf.Open(filename2, null); sf.Labels.Generate("[Name]", tkLabelPositioning.lpLongestSegement, false); Utils utils = new Utils(); LinePattern pattern = new LinePattern(); pattern.AddLine(utils.ColorByName(tkMapColor.Brown), 10.0f, tkDashStyle.dsSolid); pattern.AddLine(utils.ColorByName(tkMapColor.Yellow), 9.0f, tkDashStyle.dsSolid); sf.DefaultDrawingOptions.LinePattern = pattern; sf.DefaultDrawingOptions.UseLinePattern = true; axMap1.AddLayer(sf, true); sf = new Shapefile(); sf.Open(filename3, null); m_path = sf.Shape[0]; axMap1.MapUnits = tkUnitsOfMeasure.umMeters; axMap1.CurrentScale = 5000.0; m_timer.Interval = 250; m_timer.Tick += TimerTick; m_timer.Start(); } }
// <summary> // Creates and displayes custom line patterns // </summary> public void LinePattern(AxMap axMap1, string iconPath) { axMap1.Projection = tkMapProjection.PROJECTION_NONE; var sf = this.CreateLines(); axMap1.AddLayer(sf, true); var utils = new Utils(); // railroad pattern LinePattern pattern = new LinePattern(); pattern.AddLine(utils.ColorByName(tkMapColor.Black), 6.0f, tkDashStyle.dsSolid); pattern.AddLine(utils.ColorByName(tkMapColor.White), 5.0f, tkDashStyle.dsDot); ShapefileCategory ct = sf.Categories.Add("Railroad"); ct.DrawingOptions.LinePattern = pattern; ct.DrawingOptions.UseLinePattern = true; sf.set_ShapeCategory(0, 0); // river pattern pattern = new LinePattern(); pattern.AddLine(utils.ColorByName(tkMapColor.DarkBlue), 6.0f, tkDashStyle.dsSolid); pattern.AddLine(utils.ColorByName(tkMapColor.LightBlue), 4.0f, tkDashStyle.dsSolid); ct = sf.Categories.Add("River"); ct.DrawingOptions.LinePattern = pattern; ct.DrawingOptions.UseLinePattern = true; sf.set_ShapeCategory(1, 1); // road with direction pattern = new LinePattern(); pattern.AddLine(utils.ColorByName(tkMapColor.Gray), 8.0f, tkDashStyle.dsSolid); pattern.AddLine(utils.ColorByName(tkMapColor.Yellow), 7.0f, tkDashStyle.dsSolid); LineSegment segm = pattern.AddMarker(tkDefaultPointSymbol.dpsArrowRight); segm.Color = utils.ColorByName(tkMapColor.Orange); segm.MarkerSize = 10; segm.MarkerInterval = 32; ct = sf.Categories.Add("Direction"); ct.DrawingOptions.LinePattern = pattern; ct.DrawingOptions.UseLinePattern = true; sf.set_ShapeCategory(2, 2); }
// <summary> // Build a list of unique values of the given field and imlement zooming to them from the context menu // </summary> public void LabelSelection(AxMap axMap1, string dataPath) { axMap1.Projection = tkMapProjection.PROJECTION_GOOGLE_MERCATOR; string filename = dataPath + "buildings.shp"; if (!File.Exists(filename)) { System.Windows.Forms.MessageBox.Show("Couldn't file the file: " + filename); return; } Shapefile sf = new Shapefile(); sf.Open(filename, null); m_layerHandle = axMap1.AddLayer(sf, true); sf = axMap1.get_Shapefile(m_layerHandle); // in case a copy of shapefile was created by GlobalSettings.ReprojectLayersOnAdding // let's add labels consisting of Name and type of building on a separate lines sf.Labels.Generate("[Type]", tkLabelPositioning.lpCenter, false); sf.Labels.FrameVisible = true; sf.Labels.FrameType = tkLabelFrameType.lfRectangle; // now let's add categories Utils utils = new Utils(); // to specify colors LabelCategory ct = sf.Labels.AddCategory("Selected"); ct.FrameBackColor = utils.ColorByName(tkMapColor.Yellow); ct = sf.Labels.AddCategory("Hidden"); ct.Visible = false; axMap1.SendSelectBoxFinal = true; axMap1.SendMouseDown = true; axMap1.CursorMode = tkCursorMode.cmSelection; MapEvents.SelectBoxFinal += AxMap1SelectBoxFinal2; }
// <summary> // Calculates a minimal distance from each building to the river. // </summary> public void MinimalDistance(AxMap axMap1, string dataPath, ToolStripStatusLabel label) { axMap1.Projection = tkMapProjection.PROJECTION_NONE; axMap1.GrabProjectionFromData = true; string filename1 = dataPath + "waterways.shp"; string filename2 = dataPath + "buildings.shp"; if (!File.Exists(filename1) || !File.Exists(filename2)) { MessageBox.Show("The necessary files (waterways.shp, building.shp) are missing: " + dataPath); } else { Shapefile sfRivers = new Shapefile(); sfRivers.Open(filename1, null); Utils utils = new Utils(); sfRivers.DefaultDrawingOptions.LineColor = utils.ColorByName(tkMapColor.Blue); sfRivers.DefaultDrawingOptions.LineWidth = 5.0f; Shapefile sfBuildings = new Shapefile(); sfBuildings.Open(filename2, null); // adds a field in the table Field field = new Field(); field.Name = "RiverDist"; field.Type = FieldType.DOUBLE_FIELD; field.Precision = 10; int fieldIndex = sfBuildings.NumFields; sfBuildings.StartEditingShapes(true, null); sfBuildings.EditInsertField(field, ref fieldIndex, null); ShapefileCategory ct = sfBuildings.Categories.Add("Named buildings"); ct.Expression = "[Name] <> \"\""; sfBuildings.Categories.ApplyExpressions(); sfRivers.StartEditingShapes(false, null); for (int i = 0; i < sfBuildings.NumShapes; i++) { if (sfBuildings.ShapeCategory[i] == 0) { label.Text = "Processing building: " + (i + 1) + " / " + sfBuildings.NumShapes; Application.DoEvents(); Shape shp = sfBuildings.Shape[i]; double minDist = Double.MaxValue; for (int j = 0; j < sfRivers.NumShapes; j++) { Shape shp2 = sfRivers.Shape[j]; double distance = shp.Distance(shp2); if (distance < minDist) { minDist = distance; } } if (minDist != Double.MaxValue) { sfBuildings.EditCellValue(fieldIndex, i, minDist); } } else { sfBuildings.EditCellValue(fieldIndex, i, 0.0); } } sfRivers.StopEditingShapes(false, true, null); sfBuildings.Categories.Generate(fieldIndex, tkClassificationType.ctNaturalBreaks, 8); ColorScheme scheme = new ColorScheme(); scheme.SetColors2(tkMapColor.Blue, tkMapColor.Yellow); sfBuildings.Categories.ApplyColorScheme(tkColorSchemeType.ctSchemeGraduated, scheme); sfBuildings.Labels.Generate("[Name] + \"\n\" + [RiverDist] + \" m\"", tkLabelPositioning.lpCentroid, true); sfBuildings.Labels.TextRenderingHint = tkTextRenderingHint.SystemDefault; sfBuildings.VisibilityExpression = "[Name] <> \"\""; axMap1.AddLayer(sfRivers, true); axMap1.AddLayer(sfBuildings, true); label.Text = ""; } }
// <summary> // Calculates area of polygons and sets 3 range of categories with different symbology // </summary> public void AddCategoryRange(AxMap axMap, string dataPath) { axMap.Projection = tkMapProjection.PROJECTION_GOOGLE_MERCATOR; string filename = dataPath + "landuse.shp"; if (File.Exists(filename) == false) { MessageBox.Show(@"Failed to open file: " + filename); return; } Shapefile sf = new Shapefile(); if (!sf.Open(filename)) { return; } if (!sf.StartEditingTable()) { MessageBox.Show(@"Failed to open editing mode."); return; } int fieldIndex = sf.Table.FieldIndexByName["Area"]; if (fieldIndex == -1) { fieldIndex = sf.EditAddField("Area", FieldType.DOUBLE_FIELD, 15, 18); } for (int i = 0; i < sf.NumShapes; i++) { double area = sf.Shape[i].Area * 100000.0; sf.EditCellValue(fieldIndex, i, area); } // adding to map int handle = axMap.AddLayer(sf, true); sf = axMap.get_Shapefile(handle); // in case a copy of shapefile was created by GlobalSettings.ReprojectLayersOnAdding double mean = sf.Table.MeanValue[fieldIndex]; double stDev = sf.Table.StandardDeviation[fieldIndex]; double min = (double)sf.Table.MinValue[fieldIndex]; double max = (double)sf.Table.MaxValue[fieldIndex]; var scheme = new ColorScheme(); // 1. the first range [min; mean - stDev] Utils utils = new Utils(); sf.DefaultDrawingOptions.FillType = tkFillType.ftHatch; sf.DefaultDrawingOptions.FillHatchStyle = tkGDIPlusHatchStyle.hsDiagonalBrick; sf.Categories.AddRange(fieldIndex, tkClassificationType.ctNaturalBreaks, 5, min, mean); scheme.SetColors2(tkMapColor.Red, tkMapColor.Yellow); // apply colors 0 and 4 are indices of categories, since 5 categories were added - from 0 to 4 sf.Categories.ApplyColorScheme3(tkColorSchemeType.ctSchemeRandom, scheme, tkShapeElements.shElementFill, 0, 4); // 2. the second range [mean - stDev; mean + stDev] // the default drawing options will be copied to the new categories sf.DefaultDrawingOptions.FillType = tkFillType.ftHatch; sf.DefaultDrawingOptions.FillHatchStyle = tkGDIPlusHatchStyle.hsCross; sf.Categories.AddRange(fieldIndex, tkClassificationType.ctEqualIntervals, 5, mean, mean + stDev); scheme.SetColors2(tkMapColor.Green, tkMapColor.Blue); sf.Categories.ApplyColorScheme3(tkColorSchemeType.ctSchemeGraduated, scheme, tkShapeElements.shElementFill, 5, 9); // 3. the third range [mean + stDev; max] // the default drawing options will be copied to the new categories sf.DefaultDrawingOptions.FillType = tkFillType.ftGradient; sf.DefaultDrawingOptions.FillColor2 = utils.ColorByName(tkMapColor.Gray); sf.Categories.AddRange(fieldIndex, tkClassificationType.ctEqualIntervals, 5, mean + stDev, max); scheme.SetColors2(tkMapColor.Pink, tkMapColor.Violet); sf.Categories.ApplyColorScheme3(tkColorSchemeType.ctSchemeGraduated, scheme, tkShapeElements.shElementFill, 10, 14); // apply expresions should be called exlicitly sf.Categories.ApplyExpressions(); axMap.Redraw(); // saving options to see categories desription in XML axMap.SaveLayerOptions(handle, "categories_sample", true, ""); }
// <summary> // Creates several buffers around the waterways. // </summary> public void CreateBuffer(AxMap axMap1, string dataPath, System.Windows.Forms.ToolStripStatusLabel label) { axMap1.Projection = tkMapProjection.PROJECTION_GOOGLE_MERCATOR; string filename = dataPath + "waterways.shp"; if (!File.Exists(filename)) { MessageBox.Show("The shapefile with rivers wasn't found: " + filename); } else { var callback = new Callback(label); var sf = new Shapefile(); if (!sf.Open(filename, callback)) { MessageBox.Show(sf.ErrorMsg[sf.LastErrorCode]); } else { int layerHandle = axMap1.AddLayer(sf, true); sf = axMap1.get_Shapefile(layerHandle); // in case a copy of shapefile was created by GlobalSettings.ReprojectLayersOnAdding var utils = new Utils(); sf.DefaultDrawingOptions.LineWidth = 3.0f; sf.DefaultDrawingOptions.LineColor = utils.ColorByName(tkMapColor.Blue); const double distance = 150; // meters var buffers = new List <Shapefile>(); for (int i = 1; i < 5; i++) { Shapefile sfBuffer = sf.BufferByDistance(distance * i, 30, false, true); if (sfBuffer == null) { MessageBox.Show("Failed to calculate the buffer: " + sf.ErrorMsg[sf.LastErrorCode]); return; } else { sfBuffer.GlobalCallback = callback; buffers.Add(sfBuffer); } } // now subtract smaller buffers from larger ones for (int i = buffers.Count - 1; i > 0; i--) { Shapefile sfDiff = buffers[i].Difference(false, buffers[i - 1], false); if (sfDiff == null) { MessageBox.Show("Failed to calculate the difference: " + sf.ErrorMsg[sf.LastErrorCode]); return; } else { buffers[i] = sfDiff; } } // pass all the resulting shapes to a single shapefile and mark their distance Shapefile sfResult = buffers[0].Clone(); sfResult.GlobalCallback = callback; int fieldIndex = sfResult.EditAddField("Distance", FieldType.DOUBLE_FIELD, 10, 12); for (int i = 0; i < buffers.Count; i++) { Shapefile sfBuffer = buffers[i]; for (int j = 0; j < sfBuffer.NumShapes; j++) { int index = sfResult.NumShapes; sfResult.EditInsertShape(sfBuffer.Shape[j].Clone(), ref index); sfResult.EditCellValue(fieldIndex, index, distance * (i + 1)); } } // create visualization categories sfResult.DefaultDrawingOptions.FillType = tkFillType.ftStandard; sfResult.Categories.Generate(fieldIndex, tkClassificationType.ctUniqueValues, 0); sfResult.Categories.ApplyExpressions(); // apply color scheme var scheme = new ColorScheme(); scheme.SetColors2(tkMapColor.LightBlue, tkMapColor.LightYellow); sfResult.Categories.ApplyColorScheme(tkColorSchemeType.ctSchemeGraduated, scheme); layerHandle = axMap1.AddLayer(sfResult, true); axMap1.Redraw(); //sfResult.SaveAs(@"c:\buffers.shp", null); } } }
// <summary> // Selects buildings which lie within specified distance from the parks. // </summary> public void SelectByDistance(AxMap axMap1, string dataPath) { axMap1.Projection = tkMapProjection.PROJECTION_NONE; axMap1.GrabProjectionFromData = true; string filename1 = dataPath + "buildings.shp"; string filename2 = dataPath + "natural.shp"; if (!File.Exists(filename1) || !File.Exists(filename2)) { MessageBox.Show("Failed to open shapefile (natural.shp, buildings.shp): " + dataPath); return; } var sfBuildings = new Shapefile(); sfBuildings.Open(filename1, null); var sfParks = new Shapefile(); sfParks.Open(filename2, null); ShapefileCategory ct = sfParks.Categories.Add("Parks"); // choose parks and make them green ct.Expression = "[Type] = \"Park\""; var utils = new Utils(); ct.DrawingOptions.FillColor = utils.ColorByName(tkMapColor.Green); sfParks.Categories.ApplyExpression(0); // hide the rest types of objects on the layer sfParks.DefaultDrawingOptions.Visible = false; double maxDistance = 150.0; // in meters bool editing = sfBuildings.StartEditingShapes(true, null); sfBuildings.UseQTree = true; // this will build a spatial index to speed up selection for (int i = 0; i < sfParks.NumShapes; i++) { int index = sfParks.ShapeCategory[i]; if (index == 0) { object result = null; Shape shp = sfParks.Shape[i]; if (sfBuildings.SelectShapes(shp.Extents, maxDistance, SelectMode.INTERSECTION, ref result)) { int[] shapes = result as int[]; if (shapes == null) { return; } for (int j = 0; j < shapes.Length; j++) { if (!sfBuildings.ShapeSelected[shapes[j]]) { Shape shp2 = sfBuildings.Shape[shapes[j]]; double dist = shp.Distance(shp2); if (dist < maxDistance) { sfBuildings.set_ShapeSelected(shapes[j], true); } } } } } } axMap1.AddLayer(sfParks, true); axMap1.AddLayer(sfBuildings, true); axMap1.ZoomToMaxExtents(); }
// <summary> // Calculates the length of intersection of rivers and land parcels // </summary> public void IntersectionLength(AxMap axMap1, ToolStripStatusLabel label, string dataPath) { axMap1.Projection = tkMapProjection.PROJECTION_NONE; axMap1.GrabProjectionFromData = true; string filename1 = dataPath + "landuse.shp"; string filename2 = dataPath + "waterways.shp"; if (!File.Exists(filename1) || !File.Exists(filename2)) { MessageBox.Show("The necessary files (waterways.shp, building.shp) are missing: " + dataPath); } else { Shapefile sfParcels = new Shapefile(); sfParcels.Open(filename1, null); sfParcels.StartEditingShapes(true, null); Field field = new Field { Name = "Length", Type = FieldType.DOUBLE_FIELD, Precision = 10 }; int fieldIndex = sfParcels.NumShapes; sfParcels.EditInsertField(field, ref fieldIndex, null); Shapefile sfRivers = new Shapefile(); sfRivers.Open(filename2, null); sfRivers.StartEditingShapes(true, null); Utils utils = new Utils(); sfRivers.DefaultDrawingOptions.LineWidth = 2; sfRivers.DefaultDrawingOptions.LineColor = utils.ColorByName(tkMapColor.Blue); Shapefile sfNew = sfRivers.Clone(); ShapeDrawingOptions options = sfNew.DefaultDrawingOptions; LinePattern pattern = new LinePattern(); pattern.AddLine(utils.ColorByName(tkMapColor.Blue), 8, tkDashStyle.dsSolid); pattern.AddLine(utils.ColorByName(tkMapColor.LightBlue), 4, tkDashStyle.dsSolid); options.LinePattern = pattern; options.UseLinePattern = true; for (int i = 0; i < sfParcels.NumShapes; i++) { Shape shp1 = sfParcels.Shape[i]; double length = 0.0; // the length of intersection for (int j = 0; j < sfRivers.NumShapes; j++) { Shape shp2 = sfRivers.Shape[j]; if (shp1.Intersects(shp2)) { Shape result = shp1.Clip(shp2, tkClipOperation.clIntersection); if (result != null) { int index = sfNew.EditAddShape(result); length += result.Length; } } } sfParcels.EditCellValue(fieldIndex, i, length); label.Text = string.Format("Parcel: {0}/{1}", i + 1, sfParcels.NumShapes); Application.DoEvents(); } // generating charts var chartField = new ChartField(); chartField.Name = "Length"; chartField.Color = utils.ColorByName(tkMapColor.LightBlue); chartField.Index = fieldIndex; sfParcels.Charts.AddField(chartField); sfParcels.Charts.Generate(tkLabelPositioning.lpInteriorPoint); sfParcels.Charts.ChartType = tkChartType.chtBarChart; sfParcels.Charts.BarHeight = 100; sfParcels.Charts.ValuesVisible = true; sfParcels.Charts.Visible = true; axMap1.AddLayer(sfParcels, true); axMap1.AddLayer(sfRivers, true); axMap1.AddLayer(sfNew, true); axMap1.ZoomToMaxExtents(); } }