private void GeneralizePath(com.epl.geometry.MultiPathImpl mpsrc, int ipath, com.epl.geometry.MultiPathImpl mpdst, com.epl.geometry.Line lineHelper) { if (mpsrc.GetPathSize(ipath) < 2) { return; } int start = mpsrc.GetPathStart(ipath); int end = mpsrc.GetPathEnd(ipath) - 1; com.epl.geometry.AttributeStreamOfDbl xy = (com.epl.geometry.AttributeStreamOfDbl)mpsrc.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION); bool bClosed = mpsrc.IsClosedPath(ipath); com.epl.geometry.AttributeStreamOfInt32 stack = new com.epl.geometry.AttributeStreamOfInt32(0); stack.Reserve(mpsrc.GetPathSize(ipath) + 1); com.epl.geometry.AttributeStreamOfInt32 resultStack = new com.epl.geometry.AttributeStreamOfInt32(0); resultStack.Reserve(mpsrc.GetPathSize(ipath) + 1); stack.Add(bClosed ? start : end); stack.Add(start); com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D(); while (stack.Size() > 1) { int i1 = stack.GetLast(); stack.RemoveLast(); int i2 = stack.GetLast(); mpsrc.GetXY(i1, pt); lineHelper.SetStartXY(pt); mpsrc.GetXY(i2, pt); lineHelper.SetEndXY(pt); int mid = FindGreatestDistance(lineHelper, pt, xy, i1, i2, end); if (mid >= 0) { stack.Add(mid); stack.Add(i1); } else { resultStack.Add(i1); } } if (!bClosed) { resultStack.Add(stack.Get(0)); } int rs_size = resultStack.Size(); int path_size = mpsrc.GetPathSize(ipath); if (rs_size == path_size && rs_size == stack.Size()) { mpdst.AddPath(mpsrc, ipath, true); } else { if (resultStack.Size() > 0) { if (m_bRemoveDegenerateParts && resultStack.Size() <= 2) { if (bClosed || resultStack.Size() == 1) { return; } double d = com.epl.geometry.Point2D.Distance(mpsrc.GetXY(resultStack.Get(0)), mpsrc.GetXY(resultStack.Get(1))); if (d <= m_maxDeviation) { return; } } com.epl.geometry.Point point = new com.epl.geometry.Point(); for (int i = 0, n = resultStack.Size(); i < n; i++) { mpsrc.GetPointByVal(resultStack.Get(i), point); if (i == 0) { mpdst.StartPath(point); } else { mpdst.LineTo(point); } } if (bClosed) { for (int i_1 = resultStack.Size(); i_1 < 3; i_1++) { mpdst.LineTo(point); } mpdst.ClosePathWithLine(); } } } }
public override void GetPointByVal(int index, com.epl.geometry.Point outPoint) { m_impl.GetPointByVal(index, outPoint); }
internal static com.epl.geometry.MultiPoint CalculatePolylineBoundary_(object impl, com.epl.geometry.ProgressTracker progress_tracker, bool only_check_non_empty_boundary, bool[] not_empty) { if (not_empty != null) { not_empty[0] = false; } com.epl.geometry.MultiPathImpl mpImpl = (com.epl.geometry.MultiPathImpl)impl; com.epl.geometry.MultiPoint dst = null; if (!only_check_non_empty_boundary) { dst = new com.epl.geometry.MultiPoint(mpImpl.GetDescription()); } if (!mpImpl.IsEmpty()) { com.epl.geometry.AttributeStreamOfInt32 indices = new com.epl.geometry.AttributeStreamOfInt32(0); indices.Reserve(mpImpl.GetPathCount() * 2); for (int ipath = 0, nPathCount = mpImpl.GetPathCount(); ipath < nPathCount; ipath++) { int path_size = mpImpl.GetPathSize(ipath); if (path_size > 0 && !mpImpl.IsClosedPathInXYPlane(ipath)) { // closed // paths // of // polyline // do // not // contribute // to // the // boundary. int start = mpImpl.GetPathStart(ipath); indices.Add(start); int end = mpImpl.GetPathEnd(ipath) - 1; indices.Add(end); } } if (indices.Size() > 0) { com.epl.geometry.BucketSort sorter = new com.epl.geometry.BucketSort(); com.epl.geometry.AttributeStreamOfDbl xy = (com.epl.geometry.AttributeStreamOfDbl)(mpImpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION)); sorter.Sort(indices, 0, indices.Size(), new com.epl.geometry.Boundary.MultiPathImplBoundarySorter(xy)); com.epl.geometry.Point2D ptPrev = new com.epl.geometry.Point2D(); xy.Read(2 * indices.Get(0), ptPrev); int ind = 0; int counter = 1; com.epl.geometry.Point point = new com.epl.geometry.Point(); com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D(); for (int i = 1, n = indices.Size(); i < n; i++) { xy.Read(2 * indices.Get(i), pt); if (pt.IsEqual(ptPrev)) { if (indices.Get(ind) > indices.Get(i)) { // remove duplicate point indices.Set(ind, com.epl.geometry.NumberUtils.IntMax()); ind = i; } else { // just for the heck of it, have the first // point in the order to be added to the // boundary. indices.Set(i, com.epl.geometry.NumberUtils.IntMax()); } counter++; } else { if ((counter & 1) == 0) { // remove boundary point indices.Set(ind, com.epl.geometry.NumberUtils.IntMax()); } else { if (only_check_non_empty_boundary) { if (not_empty != null) { not_empty[0] = true; } return(null); } } ptPrev.SetCoords(pt); ind = i; counter = 1; } } if ((counter & 1) == 0) { // remove the point indices.Set(ind, com.epl.geometry.NumberUtils.IntMax()); } else { if (only_check_non_empty_boundary) { if (not_empty != null) { not_empty[0] = true; } return(null); } } if (!only_check_non_empty_boundary) { indices.Sort(0, indices.Size()); for (int i_1 = 0, n = indices.Size(); i_1 < n; i_1++) { if (indices.Get(i_1) == com.epl.geometry.NumberUtils.IntMax()) { break; } mpImpl.GetPointByVal(indices.Get(i_1), point); dst.Add(point); } } } } if (only_check_non_empty_boundary) { return(null); } return(dst); }