public AreaStatistics(Geometry <Point> geometry) { this.NumberOfPoints = geometry.TotalNumberOfPoints; this.Areas = SpatialUtility.GetPrimitiveAreas(geometry); }
// ref: https://www.tandfonline.com/doi/abs/10.1179/000870493786962263 public static List <T> SimplifyByVisvalingam <T>(List <T> pointList, SimplificationParamters parameters, bool isRing /*, double threshold, bool isRing, bool retain3Points = false*/) where T : IPoint { if (pointList == null || pointList.Count <= 3) { return(pointList); } var areas = SpatialUtility.GetPrimitiveAreas(pointList, isRing); List <T> pList = pointList.ToList(); //var areas2 = SpatialUtility.GetPrimitiveAreas(pointList, isRing); //List<T> pList2 = pointList.ToList(); while (areas.Count > 0) { //if (!areas.SequenceEqual(areas2)) //{ //} //if (!pList.SequenceEqual(pList2)) //{ //} var minArea = Statistics.Statistics.GetMin(areas); if (minArea > parameters.AreaThreshold) { break; } var pointCount = pList.Count; var areaCount = areas.Count; //double a1=0, a2=0; //remove min areas for (int i = areas.Count - 1; i >= 0; i--) { if (areas[i] == minArea) { if (isRing || i > 0) { // (i-1, i, i+2): i+2 is used insted of i+1 because i+1 is going to be removed var firstIndex = i - 1 < 0 ? pointCount - 1 : i - 1; areas[firstIndex] = SpatialUtility.GetUnsignedTriangleArea(pList[firstIndex], pList[i], pList[(i + 2) % pointCount]); //a1 = areas[firstIndex]; } if (isRing || i < areas.Count - 1) { // (i, i+2, i+3): i is used insted of i+1 because i+1 is going to be removed areas[(i + 1) % areaCount] = SpatialUtility.GetUnsignedTriangleArea(pList[i], pList[(i + 2) % pointCount], pList[(i + 3) % pointCount]); //a2 = areas[(i + 1) % areaCount]; } ////recalculate adjacent areas //if (i > 0) //{ // areas[i - 1] = SpatialUtility.GetUnsignedTriangleArea(pList[i - 1], pList[i], pList[i + 2]); //} //if (i < areas.Count - 1) //{ // areas[i] = SpatialUtility.GetUnsignedTriangleArea(pList[i], pList[i + 1], pList[i + 2]); //} pList.RemoveAt((i + 1) % pointCount); areas.RemoveAt(i); break; } } //for (int i = areas2.Count - 1; i >= 0; i--) //{ // if (areas2[i] == minArea) // { // pList2.RemoveAt((i + 1)); // areas2.RemoveAt(i); // ////recalculate adjacent areas // if (i > 0) // { // areas2[i - 1] = SpatialUtility.GetUnsignedTriangleArea(pList2[i - 1], pList2[i], pList2[i + 1]); // if (areas2[i - 1] != a1) // { // } // } // if (i < areas2.Count - 1) // { // areas2[i] = SpatialUtility.GetUnsignedTriangleArea(pList2[i], pList2[i + 1], pList2[i + 2]); // if (areas2[i] != a2) // { // } // } // break; // } //} } if (parameters.Retain3Points && pList.Count == 2) { pList.Insert(1, pointList[pointList.Count() / 2]); } return(pList.ToList()); }
public AreaStatistics(List <Geometry <Point> > geometries) { this.NumberOfPoints = geometries.Sum(g => g.TotalNumberOfPoints); this.Areas = SpatialUtility.GetPrimitiveAreas(geometries); }