/// <inheritdoc cref="GeometryTransformer.TransformCoordinates(CoordinateSequence, Geometry)"/> protected override CoordinateSequence TransformCoordinates(CoordinateSequence coords, Geometry parent) { var inputPts = coords.ToCoordinateArray(); var newPts = inputPts.Length == 0 ? new Coordinate[0] : DouglasPeuckerLineSimplifier.Simplify(inputPts, _container.DistanceTolerance); return(Factory.CoordinateSequenceFactory.Create(newPts)); }
///<inheritdoc/> public RouteData Split(RouteData routeData, string routingType) { var allRoutePoints = routeData.segments.SelectMany(s => s.latlngs).ToList(); var coordinates = ToWgs84Coordinates(allRoutePoints); int maximumPoints = Math.Max(3, Math.Min((int)(new LineString(coordinates).Length / _options.MinimalSegmentLength), _options.MaxSegmentsNumber)); var currentTolerance = _options.MinimalSplitSimplificationTolerace; Coordinate[] simplifiedCoordinates; do { simplifiedCoordinates = DouglasPeuckerLineSimplifier.Simplify(coordinates, currentTolerance); currentTolerance *= 2; } while (simplifiedCoordinates.Length > maximumPoints); var manipulatedRouteData = new RouteData { segments = new List <RouteSegmentData> { new RouteSegmentData { routePoint = allRoutePoints.First(), latlngs = new List <LatLng> { allRoutePoints.First(), allRoutePoints.First() } } }, name = routeData.name }; for (int index = 1; index < simplifiedCoordinates.Length; index++) { var currentIndex = coordinates.ToList().IndexOf(simplifiedCoordinates[index]); coordinates = coordinates.Skip(currentIndex).ToArray(); var latLngs = allRoutePoints.Take(currentIndex + 1).ToList(); allRoutePoints = allRoutePoints.Skip(currentIndex).ToList(); manipulatedRouteData.segments.Add(new RouteSegmentData { latlngs = latLngs, routePoint = latLngs.Last(), routingType = routingType }); } return(manipulatedRouteData); }
/// <summary> /// Executes the DP line simplefy tool programaticaly /// Ping Yang Added it for external Testing /// </summary> /// <param name="input">The input polygon feature set</param> /// <param name="tolerance">The tolerance to use when simplefiying</param> /// <param name="output">The output polygon feature set</param> /// <returns></returns> public bool Execute(IFeatureSet input, double tolerance, IFeatureSet output) { // Validates the input and output data if (input == null || output == null) { return(false); } // We copy all the fields foreach (DataColumn inputColumn in input.DataTable.Columns) { output.DataTable.Columns.Add(new DataColumn(inputColumn.ColumnName, inputColumn.DataType)); } foreach (IFeature t in input.Features) { Geometry geom = t.BasicGeometry as Geometry; if (geom != null) { for (int part = 0; part < geom.NumGeometries; part++) { Geometry geomPart = (Geometry)geom.GetGeometryN(part); // do the simplification IList <Coordinate> oldCoords = geomPart.Coordinates; IList <Coordinate> newCoords = DouglasPeuckerLineSimplifier.Simplify( oldCoords, tolerance); // convert the coordinates back to a geometry Geometry newGeom = new LineString(newCoords); Feature newFeature = new Feature(newGeom, output); foreach (DataColumn colSource in input.DataTable.Columns) { newFeature.DataRow[colSource.ColumnName] = t.DataRow[colSource.ColumnName]; } } } } output.Save(); return(true); }
private void reductionWorkerDoWork(object sender, DoWorkEventArgs args) { var worker = sender as BackgroundWorker; var lineSimplify = new DouglasPeuckerLineSimplifier(CoordinateConvertor.LocationCollectionToCoordinates(Original)); for (int i = 21; i > 0; i--) { if (worker != null && worker.CancellationPending) { args.Cancel = true; break; } var simplificationDistance = (1 / (Math.Pow(2, i - 1))); lineSimplify.DistanceTolerance = simplificationDistance; Reduced.Add(i, CoordinateConvertor.CoordinatesToLocationCollection(lineSimplify.Simplify())); } Initalized = true; }
/// <summary> /// Executes the DP line simplefy tool programmatically /// </summary> /// <param name="input">The input polygon feature set</param> /// <param name="tolerance">The tolerance to use when simplefiying</param> /// <param name="output">The output polygon feature set</param> /// <param name="cancelProgressHandler">The progress handler</param> /// <returns>True, if executed successfully.</returns> public bool Execute(IFeatureSet input, double tolerance, IFeatureSet output, ICancelProgressHandler cancelProgressHandler) { // Validates the input and output data if (input == null || output == null) { return(false); } // We copy all the fields foreach (DataColumn inputColumn in input.DataTable.Columns) { output.DataTable.Columns.Add(new DataColumn(inputColumn.ColumnName, inputColumn.DataType)); } int numTotalOldPoints = 0; int numTotalNewPoints = 0; for (int j = 0; j < input.Features.Count; j++) { int numOldPoints = 0; int numNewPoints = 0; Geometry geom = input.Features[j].Geometry as Geometry; if (geom != null) { numOldPoints = geom.NumPoints; } numTotalOldPoints += numOldPoints; if (geom != null) { for (int part = 0; part < geom.NumGeometries; part++) { Geometry geomPart = (Geometry)geom.GetGeometryN(part); // do the simplification Coordinate[] oldCoords = geomPart.Coordinates; Coordinate[] newCoords = DouglasPeuckerLineSimplifier.Simplify(oldCoords, tolerance); // convert the coordinates back to a geometry Geometry newGeom = new LineString(newCoords); numNewPoints += newGeom.NumPoints; numTotalNewPoints += numNewPoints; Feature newFeature = new Feature(newGeom, output); foreach (DataColumn colSource in input.DataTable.Columns) { newFeature.DataRow[colSource.ColumnName] = input.Features[j].DataRow[colSource.ColumnName]; } } } // Status updates is done here, shows number of old / new points cancelProgressHandler.Progress(Convert.ToInt32((Convert.ToDouble(j) / Convert.ToDouble(input.Features.Count)) * 100), numOldPoints + "-->" + numNewPoints); if (cancelProgressHandler.Cancel) { return(false); } } cancelProgressHandler.Progress(100, TextStrings.Originalnumberofpoints + numTotalOldPoints + " " + TextStrings.Newnumberofpoints + numTotalNewPoints); output.Save(); return(true); }
public bool Execute( IFeatureSet input, double tolerance, IFeatureSet output, ICancelProgressHandler cancelProgressHandler) { if (input == null || output == null) { return(false); } // 复制表 foreach (DataColumn inputColumn in input.DataTable.Columns) { output.DataTable.Columns.Add(new DataColumn(inputColumn.ColumnName, inputColumn.DataType)); } int numTotalOldPoints = 0; int numTotalNewPoints = 0; for (int j = 0; j < input.Features.Count; j++) { int numOldPoints = 0; int numNewPoints = 0; Geometry geom = input.Features[j].BasicGeometry as Geometry; if (geom != null) { numOldPoints = geom.NumPoints; } numTotalOldPoints += numOldPoints; if (geom != null) { for (int part = 0; part < geom.NumGeometries; part++) { Geometry geomPart = (Geometry)geom.GetGeometryN(part); // 简化 IList <Coordinate> oldCoords = geomPart.Coordinates; IList <Coordinate> newCoords = DouglasPeuckerLineSimplifier.Simplify( oldCoords, tolerance); // coordinates -> geometry Geometry newGeom = new LineString(newCoords); numNewPoints += newGeom.NumPoints; numTotalNewPoints += numNewPoints; Feature newFeature = new Feature(newGeom, output); foreach (DataColumn colSource in input.DataTable.Columns) { newFeature.DataRow[colSource.ColumnName] = input.Features[j].DataRow[colSource.ColumnName]; } } } cancelProgressHandler.Progress( string.Empty, Convert.ToInt32((Convert.ToDouble(j) / Convert.ToDouble(input.Features.Count)) * 100), numOldPoints + "-->" + numNewPoints); if (cancelProgressHandler.Cancel) { return(false); } } cancelProgressHandler.Progress( string.Empty, 100, "Old / Processed number of points:" + numTotalOldPoints + "/" + numTotalNewPoints); output.Save(); return(true); }
/// <summary> /// Generalization of polyline /// shapefiles using the Douglas-Peucker line simplification /// algorithm. This method will output a line shapefile. /// </summary> /// <param name="inFileName">Input shapefile</param> /// <param name="outFileName">Output shapefile</param> /// <param name="tolerance">tolerance parameter - /// specfies the maximum allowed distance between original polyline /// and simplified polyline</param> /// <param name="cback">Use this parameter for reporting progress. Set to null if not needed</param> public static void Generalize(string inFileName, string outFileName, double tolerance, MapWinGIS.ICallback cback) { MapWinGIS.Shapefile oldSF = new MapWinGIS.Shapefile(); if (!oldSF.Open(inFileName, null)) { throw new ArgumentException(string.Format("Shapefile {0} could not be opened. Error: {1}", inFileName, oldSF.get_ErrorMsg(oldSF.LastErrorCode))); } //Check if it's a line shapefile if (!(oldSF.ShapefileType == MapWinGIS.ShpfileType.SHP_POLYLINE || oldSF.ShapefileType == MapWinGIS.ShpfileType.SHP_POLYLINEM || oldSF.ShapefileType == MapWinGIS.ShpfileType.SHP_POLYLINEZ)) { throw new ArgumentException(string.Format("Shapefile {0} must be a polyline shapefile.", inFileName)); } int numShapes = oldSF.NumShapes; int numFields = oldSF.NumFields; //create a new output shapefile MapWinGIS.Shapefile newSF = new MapWinGIS.Shapefile(); MapWinGIS.ShpfileType sftype = MapWinGIS.ShpfileType.SHP_POLYLINE; // if shapefile exists - open it and clear all shapes if (System.IO.File.Exists(outFileName)) { try { //TODO: ask for overwriting.. bool deleted = MapWinGeoProc.DataManagement.DeleteShapefile(ref outFileName); } finally { } } if (!newSF.CreateNew(outFileName, sftype)) { throw new InvalidOperationException ("Error creating shapefile " + outFileName + " " + newSF.get_ErrorMsg(newSF.LastErrorCode)); } newSF.StartEditingShapes(true, cback); //Copy all fields if (!Globals.CopyFields(ref oldSF, ref newSF)) { throw new InvalidOperationException(string.Format("Error copying fields from {0} to {1}", oldSF.Filename, newSF.Filename)); } int newShapeIndex = 0; for (int shpIdx = 0; shpIdx < numShapes; ++shpIdx) { MapWinGIS.Shape shp = oldSF.get_Shape(shpIdx); // convert each part of the polyline shape to a 'geometry' object Geometry geom = MapWinGeoProc.NTS_Adapter.ShapeToGeometry(shp); for (int partIdx = 0; partIdx < geom.NumGeometries; ++partIdx) { Geometry geomPart = (Geometry)geom.GetGeometryN(partIdx); //do the simplification ICoordinate[] oldCoords = geomPart.Coordinates; DouglasPeuckerLineSimplifier simplifier = new DouglasPeuckerLineSimplifier(oldCoords); simplifier.DistanceTolerance = tolerance; ICoordinate[] newCoords = simplifier.Simplify(); //convert the coordinates back to a geometry Geometry newGeom = new LineString(newCoords); //convert the geometry back to a shape MapWinGIS.Shape newShape = MapWinGeoProc.NTS_Adapter.GeometryToShape(newGeom); //add the shape to the new shapefile newShapeIndex = newSF.NumShapes; if (newSF.EditInsertShape(newShape, ref newShapeIndex) == false) { throw new InvalidOperationException("Error inserting shape: " + newSF.get_ErrorMsg(newSF.LastErrorCode)); } //add attribute values for (int fldIdx = 0; fldIdx < numFields; ++fldIdx) { object val = oldSF.get_CellValue(fldIdx, shpIdx); if (newSF.EditCellValue(fldIdx, newSF.NumShapes - 1, val) == false) { throw new InvalidOperationException("Error editing cell value: " + newSF.get_ErrorMsg(newSF.LastErrorCode)); } } } } //close the old shapefile oldSF.Close(); //stop editing and close the new shapefile newSF.StopEditingShapes(true, true, cback); newSF.Close(); }