internal JsonStringWriter() { m_jsonString = new System.Text.StringBuilder(); m_functionStack = new com.epl.geometry.AttributeStreamOfInt32(0); m_functionStack.Add(com.epl.geometry.JsonWriter.State.accept); m_functionStack.Add(com.epl.geometry.JsonWriter.State.start); }
internal int NewEdge(int vertex) { if (m_first_free != -1) { int index = m_first_free; m_first_free = m_end_1_nodes.Get(index); m_end_1_nodes.Set(index, vertex); m_end_2_nodes.Set(index, m_shape.GetNextVertex(vertex)); return(index); } else { if (m_end_1_nodes == null) { m_end_1_nodes = new com.epl.geometry.AttributeStreamOfInt32(0); m_end_2_nodes = new com.epl.geometry.AttributeStreamOfInt32(0); } } int index_1 = m_end_1_nodes.Size(); m_end_1_nodes.Add(vertex); m_end_2_nodes.Add(m_shape.GetNextVertex(vertex)); return(index_1); }
private bool _simplify() { if (m_shape.GetGeometryType(m_geometry) == com.epl.geometry.Geometry.Type.Polygon.Value() && m_shape.GetFillRule(m_geometry) == com.epl.geometry.Polygon.FillRule.enumFillRuleWinding) { com.epl.geometry.TopologicalOperations ops = new com.epl.geometry.TopologicalOperations(); ops.PlanarSimplifyNoCrackingAndCluster(m_fixSelfTangency, m_shape, m_geometry, m_progressTracker); System.Diagnostics.Debug.Assert((m_shape.GetFillRule(m_geometry) == com.epl.geometry.Polygon.FillRule.enumFillRuleOddEven)); } bool bChanged = false; bool bNeedWindingRepeat = true; bool bWinding = false; m_userIndexSortedIndexToVertex = -1; m_userIndexSortedAngleIndexToVertex = -1; int pointCount = m_shape.GetPointCount(m_geometry); // Sort vertices lexicographically // Firstly copy allvertices to an array. com.epl.geometry.AttributeStreamOfInt32 verticesSorter = new com.epl.geometry.AttributeStreamOfInt32(0); verticesSorter.Reserve(pointCount); for (int path = m_shape.GetFirstPath(m_geometry); path != -1; path = m_shape.GetNextPath(path)) { int vertex = m_shape.GetFirstVertex(path); for (int index = 0, n = m_shape.GetPathSize(path); index < n; index++) { verticesSorter.Add(vertex); vertex = m_shape.GetNextVertex(vertex); } } // Sort verticesSorter.Sort(0, pointCount, new com.epl.geometry.Simplificator.SimplificatorVertexComparer(this)); // SORTDYNAMICARRAYEX(verticesSorter, int, 0, pointCount, // SimplificatorVertexComparer, this); // Copy sorted vertices to the m_sortedVertices list. Make a mapping // from the edit shape vertices to the sorted vertices. m_userIndexSortedIndexToVertex = m_shape.CreateUserIndex(); // this index // is used // to map // from edit // shape // vertex to // the // m_sortedVertices // list m_sortedVertices = new com.epl.geometry.IndexMultiDCList(); m_sortedVerticesListIndex = m_sortedVertices.CreateList(0); for (int i = 0; i < pointCount; i++) { int vertex = verticesSorter.Get(i); { // debug com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D(); m_shape.GetXY(vertex, pt); // for debugging double y = pt.x; } int vertexlistIndex = m_sortedVertices.AddElement(m_sortedVerticesListIndex, vertex); m_shape.SetUserIndex(vertex, m_userIndexSortedIndexToVertex, vertexlistIndex); } // remember the sorted list element on the // vertex. // When we remove a vertex, we also remove associated sorted list // element. m_userIndexSortedAngleIndexToVertex = m_shape.CreateUserIndex(); // create // additional // list // to // store // angular // sort // mapping. m_nextVertexToProcess = -1; if (_cleanupSpikes()) { // cleanup any spikes on the polygon. bChanged = true; } // External iteration loop for the simplificator. // ST. I am not sure if it actually needs this loop. TODO: figure this // out. while (bNeedWindingRepeat) { bNeedWindingRepeat = false; int max_iter = m_shape.GetPointCount(m_geometry) + 10 > 30 ? 1000 : (m_shape.GetPointCount(m_geometry) + 10) * (m_shape.GetPointCount(m_geometry) + 10); // Simplify polygon int iRepeatNum = 0; bool bNeedRepeat = false; do { // Internal iteration loop for the simplificator. // ST. I am not sure if it actually needs this loop. TODO: figure // this out. // while (bNeedRepeat); bNeedRepeat = false; bool bVertexRecheck = false; m_firstCoincidentVertex = -1; int coincidentCount = 0; com.epl.geometry.Point2D ptFirst = new com.epl.geometry.Point2D(); com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D(); // Main loop of the simplificator. Go through the vertices and // for those that have same coordinates, for (int vlistindex = m_sortedVertices.GetFirst(m_sortedVerticesListIndex); vlistindex != com.epl.geometry.IndexMultiDCList.NullNode();) { int vertex = m_sortedVertices.GetData(vlistindex); { // debug // Point2D pt = new Point2D(); m_shape.GetXY(vertex, pt); double d = pt.x; } if (m_firstCoincidentVertex != -1) { // Point2D pt = new Point2D(); m_shape.GetXY(vertex, pt); if (ptFirst.IsEqual(pt)) { coincidentCount++; } else { ptFirst.SetCoords(pt); m_nextVertexToProcess = vlistindex; // we remeber the // next index in // the member // variable to // allow it to // be updated if // a vertex is // removed // inside of the // _ProcessBunch. if (coincidentCount > 0) { bool result = _processBunch(); // process a // bunch of // coinciding // vertices if (result) { // something has changed. // Note that ProcessBunch may // change m_nextVertexToProcess // and m_firstCoincidentVertex. bNeedRepeat = true; if (m_nextVertexToProcess != com.epl.geometry.IndexMultiDCList.NullNode()) { int v = m_sortedVertices.GetData(m_nextVertexToProcess); m_shape.GetXY(v, ptFirst); } } } vlistindex = m_nextVertexToProcess; m_firstCoincidentVertex = vlistindex; coincidentCount = 0; } } else { m_firstCoincidentVertex = vlistindex; m_shape.GetXY(m_sortedVertices.GetData(vlistindex), ptFirst); coincidentCount = 0; } if (vlistindex != -1) { //vlistindex can be set to -1 after ProcessBunch call above vlistindex = m_sortedVertices.GetNext(vlistindex); } } m_nextVertexToProcess = -1; if (coincidentCount > 0) { bool result = _processBunch(); if (result) { bNeedRepeat = true; } } if (iRepeatNum++ > 10) { throw com.epl.geometry.GeometryException.GeometryInternalError(); } if (bNeedRepeat) { _fixOrphanVertices(); } // fix broken structure of the shape if (_cleanupSpikes()) { bNeedRepeat = true; } bNeedWindingRepeat |= bNeedRepeat && bWinding; bChanged |= bNeedRepeat; }while (bNeedRepeat); } // while (bNeedWindingRepeat) // Now process rings. Fix ring orientation and determine rings that need // to be deleted. m_shape.RemoveUserIndex(m_userIndexSortedIndexToVertex); m_shape.RemoveUserIndex(m_userIndexSortedAngleIndexToVertex); bChanged |= com.epl.geometry.RingOrientationFixer.Execute(m_shape, m_geometry, m_sortedVertices, m_fixSelfTangency); return(bChanged); }
private bool _processBunch() { bool bModified = false; int iter = 0; com.epl.geometry.Point2D ptCenter = new com.epl.geometry.Point2D(); while (true) { m_dbgCounter++; // only for debugging iter++; // _ASSERT(iter < 10); if (m_bunchEdgeEndPoints == null) { m_bunchEdgeEndPoints = new com.epl.geometry.AttributeStreamOfInt32(0); m_bunchEdgeCenterPoints = new com.epl.geometry.AttributeStreamOfInt32(0); m_bunchEdgeIndices = new com.epl.geometry.AttributeStreamOfInt32(0); } else { m_bunchEdgeEndPoints.Clear(false); m_bunchEdgeCenterPoints.Clear(false); m_bunchEdgeIndices.Clear(false); } int currentVertex = m_firstCoincidentVertex; int index = 0; bool bFirst = true; while (currentVertex != m_nextVertexToProcess) { int v = m_sortedVertices.GetData(currentVertex); { // debug com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D(); m_shape.GetXY(v, pt); double y = pt.x; } if (bFirst) { m_shape.GetXY(v, ptCenter); bFirst = false; } int vertP = m_shape.GetPrevVertex(v); int vertN = m_shape.GetNextVertex(v); // _ASSERT(vertP != vertN || m_shape.getPrevVertex(vertN) == v // && m_shape.getNextVertex(vertP) == v); int id = m_shape.GetUserIndex(vertP, m_userIndexSortedAngleIndexToVertex); if (id != unchecked ((int)(0xdeadbeef))) { // avoid adding a point twice // _ASSERT(id == -1); m_bunchEdgeEndPoints.Add(vertP); m_shape.SetUserIndex(vertP, m_userIndexSortedAngleIndexToVertex, unchecked ((int)(0xdeadbeef))); // mark // that // it // has // been // already // added m_bunchEdgeCenterPoints.Add(v); m_bunchEdgeIndices.Add(index++); } int id2 = m_shape.GetUserIndex(vertN, m_userIndexSortedAngleIndexToVertex); if (id2 != unchecked ((int)(0xdeadbeef))) { // avoid adding a point twice // _ASSERT(id2 == -1); m_bunchEdgeEndPoints.Add(vertN); m_shape.SetUserIndex(vertN, m_userIndexSortedAngleIndexToVertex, unchecked ((int)(0xdeadbeef))); // mark // that // it // has // been // already // added m_bunchEdgeCenterPoints.Add(v); m_bunchEdgeIndices.Add(index++); } currentVertex = m_sortedVertices.GetNext(currentVertex); } if (m_bunchEdgeEndPoints.Size() < 2) { break; } // Sort the bunch edpoints by angle (angle between the axis x and // the edge, connecting the endpoint with the bunch center) m_bunchEdgeIndices.Sort(0, m_bunchEdgeIndices.Size(), new com.epl.geometry.Simplificator.SimplificatorAngleComparer(this)); // SORTDYNAMICARRAYEX(m_bunchEdgeIndices, int, 0, // m_bunchEdgeIndices.size(), SimplificatorAngleComparer, this); for (int i = 0, n = m_bunchEdgeIndices.Size(); i < n; i++) { int indexL = m_bunchEdgeIndices.Get(i); int vertex = m_bunchEdgeEndPoints.Get(indexL); m_shape.SetUserIndex(vertex, m_userIndexSortedAngleIndexToVertex, i); { // rember the // sort by angle // order // debug com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D(); m_shape.GetXY(vertex, pt); double y = pt.x; } } bool bCrossOverResolved = _processCrossOvers(ptCenter); // see of // there // are // crossing // over // edges. for (int i_1 = 0, n = m_bunchEdgeIndices.Size(); i_1 < n; i_1++) { int indexL = m_bunchEdgeIndices.Get(i_1); if (indexL == -1) { continue; } int vertex = m_bunchEdgeEndPoints.Get(indexL); m_shape.SetUserIndex(vertex, m_userIndexSortedAngleIndexToVertex, -1); } // remove // mapping if (bCrossOverResolved) { bModified = true; continue; } break; } return(bModified); }
internal bool NeedsCrackingImpl_() { bool b_needs_cracking = false; if (m_sweep_structure == null) { m_sweep_structure = new com.epl.geometry.Treap(); } com.epl.geometry.AttributeStreamOfInt32 event_q = new com.epl.geometry.AttributeStreamOfInt32(0); event_q.Reserve(m_shape.GetTotalPointCount() + 1); com.epl.geometry.EditShape.VertexIterator iter = m_shape.QueryVertexIterator(); for (int vert = iter.Next(); vert != -1; vert = iter.Next()) { event_q.Add(vert); } System.Diagnostics.Debug.Assert((m_shape.GetTotalPointCount() == event_q.Size())); m_shape.SortVerticesSimpleByY_(event_q, 0, event_q.Size()); event_q.Add(-1); // for termination; // create user indices to store edges that end at vertices. int edge_index_1 = m_shape.CreateUserIndex(); int edge_index_2 = m_shape.CreateUserIndex(); m_sweep_comparator = new com.epl.geometry.SweepComparator(m_shape, m_tolerance, !m_bAllowCoincident); m_sweep_structure.SetComparator(m_sweep_comparator); com.epl.geometry.AttributeStreamOfInt32 swept_edges_to_delete = new com.epl.geometry.AttributeStreamOfInt32(0); com.epl.geometry.AttributeStreamOfInt32 edges_to_insert = new com.epl.geometry.AttributeStreamOfInt32(0); // Go throught the sorted vertices int event_q_index = 0; com.epl.geometry.Point2D cluster_pt = new com.epl.geometry.Point2D(); // sweep-line algorithm: for (int vertex = event_q.Get(event_q_index++); vertex != -1;) { m_shape.GetXY(vertex, cluster_pt); do { int next_vertex = m_shape.GetNextVertex(vertex); int prev_vertex = m_shape.GetPrevVertex(vertex); if (next_vertex != -1 && m_shape.CompareVerticesSimpleY_(vertex, next_vertex) < 0) { edges_to_insert.Add(vertex); edges_to_insert.Add(next_vertex); } if (prev_vertex != -1 && m_shape.CompareVerticesSimpleY_(vertex, prev_vertex) < 0) { edges_to_insert.Add(prev_vertex); edges_to_insert.Add(prev_vertex); } // Continue accumulating current cluster int attached_edge_1 = m_shape.GetUserIndex(vertex, edge_index_1); if (attached_edge_1 != -1) { swept_edges_to_delete.Add(attached_edge_1); m_shape.SetUserIndex(vertex, edge_index_1, -1); } int attached_edge_2 = m_shape.GetUserIndex(vertex, edge_index_2); if (attached_edge_2 != -1) { swept_edges_to_delete.Add(attached_edge_2); m_shape.SetUserIndex(vertex, edge_index_2, -1); } vertex = event_q.Get(event_q_index++); }while (vertex != -1 && m_shape.IsEqualXY(vertex, cluster_pt)); bool b_continuing_segment_chain_optimization = swept_edges_to_delete.Size() == 1 && edges_to_insert.Size() == 2; int new_left = -1; int new_right = -1; // Process the cluster for (int i = 0, n = swept_edges_to_delete.Size(); i < n; i++) { // Find left and right neighbour of the edges that terminate at // the cluster (there will be atmost only one left and one // right). int edge = swept_edges_to_delete.Get(i); int left = m_sweep_structure.GetPrev(edge); if (left != -1 && !swept_edges_to_delete.HasElement(left)) { // Note: // for // some // heavy // cases, // it // could // be // better // to // use // binary // search. System.Diagnostics.Debug.Assert((new_left == -1)); new_left = left; } int right = m_sweep_structure.GetNext(edge); if (right != -1 && !swept_edges_to_delete.HasElement(right)) { System.Diagnostics.Debug.Assert((new_right == -1)); new_right = right; } //#ifdef NDEBUG if (new_left != -1 && new_right != -1) { break; } } //#endif System.Diagnostics.Debug.Assert((new_left == -1 || new_left != new_right)); m_sweep_comparator.SetSweepY(cluster_pt.y, cluster_pt.x); // Delete the edges that terminate at the cluster. for (int i_1 = 0, n = swept_edges_to_delete.Size(); i_1 < n; i_1++) { int edge = swept_edges_to_delete.Get(i_1); m_sweep_structure.DeleteNode(edge, -1); } swept_edges_to_delete.Clear(false); if (!b_continuing_segment_chain_optimization && new_left != -1 && new_right != -1) { if (CheckForIntersections_(new_left, new_right)) { b_needs_cracking = true; m_non_simple_result = m_sweep_comparator.GetResult(); break; } } for (int i_2 = 0, n = edges_to_insert.Size(); i_2 < n; i_2 += 2) { int v = edges_to_insert.Get(i_2); int otherv = edges_to_insert.Get(i_2 + 1); int new_edge_1 = -1; if (b_continuing_segment_chain_optimization) { new_edge_1 = m_sweep_structure.AddElementAtPosition(new_left, new_right, v, true, true, -1); b_continuing_segment_chain_optimization = false; } else { new_edge_1 = m_sweep_structure.AddElement(v, -1); } // the // sweep // structure // consist // of // the // origin // vertices // for // edges. // One // can // always // get // the // other // endpoint // as // the // next // vertex. if (m_sweep_comparator.IntersectionDetected()) { m_non_simple_result = m_sweep_comparator.GetResult(); b_needs_cracking = true; break; } int e_1 = m_shape.GetUserIndex(otherv, edge_index_1); if (e_1 == -1) { m_shape.SetUserIndex(otherv, edge_index_1, new_edge_1); } else { System.Diagnostics.Debug.Assert((m_shape.GetUserIndex(otherv, edge_index_2) == -1)); m_shape.SetUserIndex(otherv, edge_index_2, new_edge_1); } } if (b_needs_cracking) { break; } // Start accumulating new cluster edges_to_insert.ResizePreserveCapacity(0); } m_shape.RemoveUserIndex(edge_index_1); m_shape.RemoveUserIndex(edge_index_2); return(b_needs_cracking); }
internal static int LineStringText(bool b_ring, com.epl.geometry.AttributeStreamOfDbl zs, com.epl.geometry.AttributeStreamOfDbl ms, com.epl.geometry.AttributeStreamOfDbl position, com.epl.geometry.AttributeStreamOfInt32 paths, com.epl.geometry.AttributeStreamOfInt8 path_flags , com.epl.geometry.WktParser wkt_parser) { // At start of LineStringText int current_token = wkt_parser.CurrentToken(); int point_count = 0; if (current_token == com.epl.geometry.WktParser.WktToken.empty) { return(point_count); } bool b_start_path = true; double startx = com.epl.geometry.NumberUtils.TheNaN; double starty = com.epl.geometry.NumberUtils.TheNaN; double startz = com.epl.geometry.NumberUtils.TheNaN; double startm = com.epl.geometry.NumberUtils.TheNaN; current_token = wkt_parser.NextToken(); while (current_token != com.epl.geometry.WktParser.WktToken.right_paren) { // At start of x double x = wkt_parser.CurrentNumericLiteral(); wkt_parser.NextToken(); double y = wkt_parser.CurrentNumericLiteral(); wkt_parser.NextToken(); double z = com.epl.geometry.NumberUtils.TheNaN; double m = com.epl.geometry.NumberUtils.TheNaN; if (wkt_parser.HasZs()) { z = wkt_parser.CurrentNumericLiteral(); wkt_parser.NextToken(); } if (wkt_parser.HasMs()) { m = wkt_parser.CurrentNumericLiteral(); wkt_parser.NextToken(); } current_token = wkt_parser.CurrentToken(); bool b_add_point = true; if (b_ring && point_count >= 2 && current_token == com.epl.geometry.WktParser.WktToken.right_paren) { // If the last point in the ring is not equal to the start // point, then let's add it. if ((startx == x || (com.epl.geometry.NumberUtils.IsNaN(startx) && com.epl.geometry.NumberUtils.IsNaN(x))) && (starty == y || (com.epl.geometry.NumberUtils.IsNaN(starty) && com.epl.geometry.NumberUtils.IsNaN(y))) && (!wkt_parser.HasZs() || startz == z || (com.epl.geometry.NumberUtils .IsNaN(startz) && com.epl.geometry.NumberUtils.IsNaN(z))) && (!wkt_parser.HasMs() || startm == m || (com.epl.geometry.NumberUtils.IsNaN(startm) && com.epl.geometry.NumberUtils.IsNaN(m)))) { b_add_point = false; } } if (b_add_point) { if (b_start_path) { b_start_path = false; startx = x; starty = y; startz = z; startm = m; } point_count++; AddToStreams(zs, ms, position, x, y, z, m); } } if (point_count == 1) { point_count++; AddToStreams(zs, ms, position, startx, starty, startz, startm); } paths.Add(position.Size() / 2); path_flags.Add(unchecked ((byte)0)); return(point_count); }
public static void Test_perf_quad_tree() { com.epl.geometry.Envelope extent1 = new com.epl.geometry.Envelope(); extent1.SetCoords(-1000, -1000, 1000, 1000); com.epl.geometry.RandomCoordinateGenerator generator1 = new com.epl.geometry.RandomCoordinateGenerator(1000, extent1, 0.001); //HiResTimer timer; for (int N = 16; N <= 1024; N *= 2) { //timer.StartMeasurement(); com.epl.geometry.Envelope2D extent = new com.epl.geometry.Envelope2D(); extent.SetCoords(-1000, -1000, 1000, 1000); System.Collections.Generic.Dictionary <int, com.epl.geometry.Envelope2D> data = new System.Collections.Generic.Dictionary <int, com.epl.geometry.Envelope2D>(0); com.epl.geometry.QuadTree qt = new com.epl.geometry.QuadTree(extent, 10); for (int i = 0; i < N; i++) { com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D(); com.epl.geometry.Point2D center = generator1.GetRandomCoord().GetXY(); double w = 10; env.SetCoords(center, w, w); env.Intersect(extent); if (env.IsEmpty()) { continue; } int h = qt.Insert(i, env); data[h] = env; } int ecount = 0; com.epl.geometry.AttributeStreamOfInt32 handles = new com.epl.geometry.AttributeStreamOfInt32(0); com.epl.geometry.QuadTree.QuadTreeIterator iter = qt.GetIterator(); System.Collections.Generic.IEnumerator <System.Collections.Generic.KeyValuePair <int, com.epl.geometry.Envelope2D> > pairs = data.GetEnumerator(); while (pairs.MoveNext()) { System.Collections.Generic.KeyValuePair <int, com.epl.geometry.Envelope2D> entry = pairs.Current; iter.ResetIterator((com.epl.geometry.Envelope2D)entry.Value, 0.001); bool remove_self = false; for (int h = iter.Next(); h != -1; h = iter.Next()) { if (h != entry.Key) { handles.Add(h); } else { remove_self = true; } ecount++; } for (int i_1 = 0; i_1 < handles.Size(); i_1++) { qt.RemoveElement(handles.Get(i_1)); } //remove elements that were selected. if (remove_self) { qt.RemoveElement(entry.Key); } handles.Resize(0); } } }
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); }
internal virtual bool FixRingSelfTangency_() { com.epl.geometry.AttributeStreamOfInt32 self_tangent_paths = new com.epl.geometry.AttributeStreamOfInt32(0); com.epl.geometry.AttributeStreamOfInt32 self_tangency_clusters = new com.epl.geometry.AttributeStreamOfInt32(0); int tangent_path_first_vertex_index = -1; int tangent_vertex_cluster_index = -1; com.epl.geometry.Point2D pt_prev = new com.epl.geometry.Point2D(); pt_prev.SetNaN(); int prev_vertex = -1; int old_path = -1; int current_cluster = -1; com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D(); for (int ivertex = m_sorted_vertices.GetFirst(m_sorted_vertices.GetFirstList()); ivertex != -1; ivertex = m_sorted_vertices.GetNext(ivertex)) { int vertex = m_sorted_vertices.GetData(ivertex); m_shape.GetXY(vertex, pt); int path = m_shape.GetPathFromVertex(vertex); if (pt_prev.IsEqual(pt) && old_path == path) { if (tangent_vertex_cluster_index == -1) { tangent_path_first_vertex_index = m_shape.CreatePathUserIndex(); tangent_vertex_cluster_index = m_shape.CreateUserIndex(); } if (current_cluster == -1) { current_cluster = self_tangency_clusters.Size(); m_shape.SetUserIndex(prev_vertex, tangent_vertex_cluster_index, current_cluster); self_tangency_clusters.Add(1); int p = m_shape.GetPathUserIndex(path, tangent_path_first_vertex_index); if (p == -1) { m_shape.SetPathUserIndex(path, tangent_path_first_vertex_index, prev_vertex); self_tangent_paths.Add(path); } } m_shape.SetUserIndex(vertex, tangent_vertex_cluster_index, current_cluster); self_tangency_clusters.SetLast(self_tangency_clusters.GetLast() + 1); } else { current_cluster = -1; pt_prev.SetCoords(pt); } prev_vertex = vertex; old_path = path; } if (self_tangent_paths.Size() == 0) { return(false); } // Now self_tangent_paths contains list of clusters of tangency for each // path. // The clusters contains list of clusters and for each cluster it // contains a list of vertices. com.epl.geometry.AttributeStreamOfInt32 vertex_stack = new com.epl.geometry.AttributeStreamOfInt32(0); com.epl.geometry.AttributeStreamOfInt32 cluster_stack = new com.epl.geometry.AttributeStreamOfInt32(0); for (int ipath = 0, npath = self_tangent_paths.Size(); ipath < npath; ipath++) { int path = self_tangent_paths.Get(ipath); int first_vertex = m_shape.GetPathUserIndex(path, tangent_path_first_vertex_index); int cluster = m_shape.GetUserIndex(first_vertex, tangent_vertex_cluster_index); vertex_stack.Clear(false); cluster_stack.Clear(false); vertex_stack.Add(first_vertex); cluster_stack.Add(cluster); for (int vertex = m_shape.GetNextVertex(first_vertex); vertex != first_vertex; vertex = m_shape.GetNextVertex(vertex)) { int vertex_to = vertex; int cluster_to = m_shape.GetUserIndex(vertex_to, tangent_vertex_cluster_index); if (cluster_to != -1) { if (cluster_stack.Size() == 0) { cluster_stack.Add(cluster_to); vertex_stack.Add(vertex_to); continue; } if (cluster_stack.GetLast() == cluster_to) { int vertex_from = vertex_stack.GetLast(); // peel the loop from path int from_next = m_shape.GetNextVertex(vertex_from); int from_prev = m_shape.GetPrevVertex(vertex_from); int to_next = m_shape.GetNextVertex(vertex_to); int to_prev = m_shape.GetPrevVertex(vertex_to); m_shape.SetNextVertex_(vertex_from, to_next); m_shape.SetPrevVertex_(to_next, vertex_from); m_shape.SetNextVertex_(vertex_to, from_next); m_shape.SetPrevVertex_(from_next, vertex_to); // vertex_from is left in the path we are processing, // while the vertex_to is in the loop being teared off. bool[] first_vertex_correction_requied = new bool[] { false }; int new_path = m_shape.InsertClosedPath_(m_geometry, -1, from_next, m_shape.GetFirstVertex(path), first_vertex_correction_requied); m_shape.SetUserIndex(vertex, tangent_vertex_cluster_index, -1); // Fix the path after peeling if the peeled loop had the // first path vertex in it if (first_vertex_correction_requied[0]) { m_shape.SetFirstVertex_(path, to_next); } int path_size = m_shape.GetPathSize(path); int new_path_size = m_shape.GetPathSize(new_path); path_size -= new_path_size; System.Diagnostics.Debug.Assert((path_size >= 3)); m_shape.SetPathSize_(path, path_size); self_tangency_clusters.Set(cluster_to, self_tangency_clusters.Get(cluster_to) - 1); if (self_tangency_clusters.Get(cluster_to) == 1) { self_tangency_clusters.Set(cluster_to, 0); cluster_stack.RemoveLast(); vertex_stack.RemoveLast(); } // this cluster has more than two vertices in it. first_vertex = vertex_from; // reset the counter to // ensure we find all loops. vertex = vertex_from; } else { vertex_stack.Add(vertex); cluster_stack.Add(cluster_to); } } } } m_shape.RemovePathUserIndex(tangent_path_first_vertex_index); m_shape.RemoveUserIndex(tangent_vertex_cluster_index); return(true); }
internal virtual bool InsertEdge_(int vertex, int reused_node) { com.epl.geometry.Point2D pt_1 = new com.epl.geometry.Point2D(); com.epl.geometry.Point2D pt_2 = new com.epl.geometry.Point2D(); m_shape.GetXY(vertex, pt_1); int next = m_shape.GetNextVertex(vertex); m_shape.GetXY(next, pt_2); bool b_res = false; if (pt_1.y < pt_2.y) { b_res = true; int edge = m_edges.NewEdge(vertex); int aetNode; if (reused_node == -1) { aetNode = m_AET.AddElement(edge, -1); } else { aetNode = reused_node; m_AET.SetElement(aetNode, edge); } int node = m_shape.GetUserIndex(next, m_node_1_user_index); if (node == -1) { m_shape.SetUserIndex(next, m_node_1_user_index, aetNode); } else { m_shape.SetUserIndex(next, m_node_2_user_index, aetNode); } int path = m_shape.GetPathFromVertex(vertex); if (m_shape.GetPathUserIndex(path, m_path_orientation_index) == 0) { m_unknown_nodes.Add(aetNode); } } int prev = m_shape.GetPrevVertex(vertex); m_shape.GetXY(prev, pt_2); if (pt_1.y < pt_2.y) { b_res = true; int edge = m_edges.NewEdge(prev); int aetNode; if (reused_node == -1) { aetNode = m_AET.AddElement(edge, -1); } else { aetNode = reused_node; m_AET.SetElement(aetNode, edge); } int node = m_shape.GetUserIndex(prev, m_node_1_user_index); if (node == -1) { m_shape.SetUserIndex(prev, m_node_1_user_index, aetNode); } else { m_shape.SetUserIndex(prev, m_node_2_user_index, aetNode); } int path = m_shape.GetPathFromVertex(vertex); if (m_shape.GetPathUserIndex(path, m_path_orientation_index) == 0) { m_unknown_nodes.Add(aetNode); } } return(b_res); }
internal virtual bool FixRingOrientation_() { bool bFound = false; if (m_fixSelfTangency) { bFound = FixRingSelfTangency_(); } if (m_shape.GetPathCount(m_geometry) == 1) { int path = m_shape.GetFirstPath(m_geometry); double area = m_shape.GetRingArea(path); m_shape.SetExterior(path, true); if (area < 0) { int first = m_shape.GetFirstVertex(path); m_shape.ReverseRingInternal_(first); m_shape.SetLastVertex_(path, m_shape.GetPrevVertex(first)); // fix // last // after // the // reverse return(true); } return(false); } m_path_orientation_index = m_shape.CreatePathUserIndex(); // used to // store // discovered // orientation // (3 - // extrior, // 2 - // interior) m_path_parentage_index = m_shape.CreatePathUserIndex(); // used to // resolve OGC // order for (int path_1 = m_shape.GetFirstPath(m_geometry); path_1 != -1; path_1 = m_shape.GetNextPath(path_1)) { m_shape.SetPathUserIndex(path_1, m_path_orientation_index, 0); m_shape.SetPathUserIndex(path_1, m_path_parentage_index, -1); } com.epl.geometry.AttributeStreamOfInt32 bunch = new com.epl.geometry.AttributeStreamOfInt32(0); m_y_scanline = com.epl.geometry.NumberUtils.TheNaN; com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D(); m_unknown_ring_orientation_count = m_shape.GetPathCount(m_geometry); m_node_1_user_index = m_shape.CreateUserIndex(); m_node_2_user_index = m_shape.CreateUserIndex(); for (int ivertex = m_sorted_vertices.GetFirst(m_sorted_vertices.GetFirstList()); ivertex != -1; ivertex = m_sorted_vertices.GetNext(ivertex)) { int vertex = m_sorted_vertices.GetData(ivertex); m_shape.GetXY(vertex, pt); if (pt.y != m_y_scanline && bunch.Size() != 0) { bFound |= ProcessBunchForRingOrientationTest_(bunch); m_sweep_comparator.Reset(); bunch.Clear(false); } bunch.Add(vertex); // all vertices that have same y are added to the // bunch m_y_scanline = pt.y; if (m_unknown_ring_orientation_count == 0) { break; } } if (m_unknown_ring_orientation_count > 0) { bFound |= ProcessBunchForRingOrientationTest_(bunch); bunch.Clear(false); } m_shape.RemoveUserIndex(m_node_1_user_index); m_shape.RemoveUserIndex(m_node_2_user_index); // dbg_verify_ring_orientation_();//debug for (int path_2 = m_shape.GetFirstPath(m_geometry); path_2 != -1;) { if (m_shape.GetPathUserIndex(path_2, m_path_orientation_index) == 3) { // exterior m_shape.SetExterior(path_2, true); int afterPath = path_2; for (int nextHole = m_shape.GetPathUserIndex(path_2, m_path_parentage_index); nextHole != -1;) { int p = m_shape.GetPathUserIndex(nextHole, m_path_parentage_index); m_shape.MovePath(m_geometry, m_shape.GetNextPath(afterPath), nextHole); afterPath = nextHole; nextHole = p; } path_2 = m_shape.GetNextPath(afterPath); } else { m_shape.SetExterior(path_2, false); path_2 = m_shape.GetNextPath(path_2); } } m_shape.RemovePathUserIndex(m_path_orientation_index); m_shape.RemovePathUserIndex(m_path_parentage_index); return(bFound); }
/// <exception cref="System.Exception"/> private static com.epl.geometry.Geometry ImportFromJsonMultiPath(bool b_polygon, com.epl.geometry.JsonReader parser, com.epl.geometry.AttributeStreamOfDbl @as, com.epl.geometry.AttributeStreamOfDbl bs) { if (parser.CurrentToken() != com.epl.geometry.JsonReader.Token.START_ARRAY) { throw new com.epl.geometry.GeometryException("failed to parse multipath: array of array of vertices is expected"); } com.epl.geometry.MultiPath multipath; if (b_polygon) { multipath = new com.epl.geometry.Polygon(); } else { multipath = new com.epl.geometry.Polyline(); } com.epl.geometry.AttributeStreamOfInt32 parts = (com.epl.geometry.AttributeStreamOfInt32)com.epl.geometry.AttributeStreamBase.CreateIndexStream(0); com.epl.geometry.AttributeStreamOfDbl position = (com.epl.geometry.AttributeStreamOfDbl)com.epl.geometry.AttributeStreamBase.CreateDoubleStream(2, 0); com.epl.geometry.AttributeStreamOfInt8 pathFlags = (com.epl.geometry.AttributeStreamOfInt8)com.epl.geometry.AttributeStreamBase.CreateByteStream(0); // set up min max variables double[] buf = new double[4]; double[] start = new double[4]; int point_count = 0; int path_count = 0; byte pathFlag = b_polygon ? unchecked ((byte)com.epl.geometry.PathFlags.enumClosed) : 0; int requiredSize = b_polygon ? 3 : 2; // At start of rings while (parser.NextToken() != com.epl.geometry.JsonReader.Token.END_ARRAY) { if (parser.CurrentToken() != com.epl.geometry.JsonReader.Token.START_ARRAY) { throw new com.epl.geometry.GeometryException("failed to parse multipath: ring/path array is expected"); } int pathPointCount = 0; bool b_first = true; int sz = 0; int szstart = 0; parser.NextToken(); while (parser.CurrentToken() != com.epl.geometry.JsonReader.Token.END_ARRAY) { if (parser.CurrentToken() != com.epl.geometry.JsonReader.Token.START_ARRAY) { throw new com.epl.geometry.GeometryException("failed to parse multipath: array is expected, rings/paths vertices consist of arrays of cooridinates"); } sz = 0; while (parser.NextToken() != com.epl.geometry.JsonReader.Token.END_ARRAY) { buf[sz++] = ReadDouble(parser); } if (sz < 2) { throw new com.epl.geometry.GeometryException("failed to parse multipath: each vertex array has to have at least 2 elements"); } parser.NextToken(); do { if (position.Size() == point_count * 2) { int c = point_count * 3; if (c % 2 != 0) { c++; } // have to be even if (c < 8) { c = 8; } else { if (c < 32) { c = 32; } } position.Resize(c); } position.Write(2 * point_count, buf[0]); position.Write(2 * point_count + 1, buf[1]); if (@as.Size() == point_count) { int c = (point_count * 3) / 2; // have to be even if (c < 4) { c = 4; } else { if (c < 16) { c = 16; } } @as.Resize(c); } if (sz > 2) { @as.Write(point_count, buf[2]); } else { @as.Write(point_count, com.epl.geometry.NumberUtils.NaN()); } if (bs.Size() == point_count) { int c = (point_count * 3) / 2; // have to be even if (c < 4) { c = 4; } else { if (c < 16) { c = 16; } } bs.Resize(c); } if (sz > 3) { bs.Write(point_count, buf[3]); } else { bs.Write(point_count, com.epl.geometry.NumberUtils.NaN()); } if (b_first) { path_count++; parts.Add(point_count); pathFlags.Add(pathFlag); b_first = false; szstart = sz; start[0] = buf[0]; start[1] = buf[1]; start[2] = buf[2]; start[3] = buf[3]; } point_count++; pathPointCount++; }while (pathPointCount < requiredSize && parser.CurrentToken() == com.epl.geometry.JsonReader.Token.END_ARRAY); } if (b_polygon && pathPointCount > requiredSize && sz == szstart && start[0] == buf[0] && start[1] == buf[1] && start[2] == buf[2] && start[3] == buf[3]) { // remove the end point that is equal to the start point. point_count--; pathPointCount--; } if (pathPointCount == 0) { continue; } } // skip empty paths if (point_count != 0) { parts.Resize(path_count); pathFlags.Resize(path_count); if (point_count > 0) { parts.Add(point_count); pathFlags.Add(unchecked ((byte)0)); } com.epl.geometry.MultiPathImpl mp_impl = (com.epl.geometry.MultiPathImpl)multipath._getImpl(); mp_impl.SetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION, position); mp_impl.SetPathFlagsStreamRef(pathFlags); mp_impl.SetPathStreamRef(parts); } return(multipath); }
private void AddValueObject_() { m_jsonString.Append('{'); m_functionStack.Add(com.epl.geometry.JsonWriter.State.objectStart); }
public static void TestEditShape__() { { // Single part polygon com.epl.geometry.Polygon poly = new com.epl.geometry.Polygon(); poly.StartPath(10, 10); poly.LineTo(10, 12); poly.LineTo(14, 15); poly.LineTo(10, 11); com.epl.geometry.EditShape editShape = new com.epl.geometry.EditShape(); int geom = editShape.AddGeometry(poly); com.epl.geometry.Polygon poly2 = (com.epl.geometry.Polygon)editShape.GetGeometry(geom); NUnit.Framework.Assert.IsTrue(poly.Equals(poly2)); } { // Two part poly com.epl.geometry.Polygon poly = new com.epl.geometry.Polygon(); poly.StartPath(10, 10); poly.LineTo(10, 12); poly.LineTo(14, 15); poly.LineTo(10, 11); poly.StartPath(100, 10); poly.LineTo(100, 12); poly.LineTo(14, 150); poly.LineTo(10, 101); poly.LineTo(100, 11); com.epl.geometry.EditShape editShape = new com.epl.geometry.EditShape(); int geom = editShape.AddGeometry(poly); com.epl.geometry.Polygon poly2 = (com.epl.geometry.Polygon)editShape.GetGeometry(geom); NUnit.Framework.Assert.IsTrue(poly.Equals(poly2)); } { // Single part polyline com.epl.geometry.Polyline poly = new com.epl.geometry.Polyline(); poly.StartPath(10, 10); poly.LineTo(10, 12); poly.LineTo(14, 15); poly.LineTo(10, 11); com.epl.geometry.EditShape editShape = new com.epl.geometry.EditShape(); int geom = editShape.AddGeometry(poly); com.epl.geometry.Polyline poly2 = (com.epl.geometry.Polyline)editShape.GetGeometry(geom); NUnit.Framework.Assert.IsTrue(poly.Equals(poly2)); } { // Two part poly com.epl.geometry.Polyline poly = new com.epl.geometry.Polyline(); poly.StartPath(10, 10); poly.LineTo(10, 12); poly.LineTo(14, 15); poly.LineTo(10, 11); poly.StartPath(100, 10); poly.LineTo(100, 12); poly.LineTo(14, 150); poly.LineTo(10, 101); poly.LineTo(100, 11); com.epl.geometry.EditShape editShape = new com.epl.geometry.EditShape(); int geom = editShape.AddGeometry(poly); com.epl.geometry.Polyline poly2 = (com.epl.geometry.Polyline)editShape.GetGeometry(geom); NUnit.Framework.Assert.IsTrue(poly.Equals(poly2)); } { // Five part poly. Close one of parts to test if it works. com.epl.geometry.Polyline poly = new com.epl.geometry.Polyline(); poly.StartPath(10, 10); poly.LineTo(10, 12); poly.LineTo(14, 15); poly.LineTo(10, 11); poly.StartPath(100, 10); poly.LineTo(100, 12); poly.LineTo(14, 150); poly.LineTo(10, 101); poly.LineTo(100, 11); poly.StartPath(1100, 101); poly.LineTo(1300, 132); poly.LineTo(144, 150); poly.LineTo(106, 1051); poly.LineTo(1600, 161); poly.StartPath(100, 190); poly.LineTo(1800, 192); poly.LineTo(184, 8150); poly.LineTo(1080, 181); poly.StartPath(1030, 10); poly.LineTo(1300, 132); poly.LineTo(314, 3150); poly.LineTo(310, 1301); poly.LineTo(3100, 311); com.epl.geometry.EditShape editShape = new com.epl.geometry.EditShape(); int geom = editShape.AddGeometry(poly); editShape.SetClosedPath(editShape.GetNextPath(editShape.GetFirstPath(geom)), true); ((com.epl.geometry.MultiPathImpl)poly._getImpl()).ClosePathWithLine(1); com.epl.geometry.Polyline poly2 = (com.epl.geometry.Polyline)editShape.GetGeometry(geom); NUnit.Framework.Assert.IsTrue(poly.Equals(poly2)); } { // Test erase com.epl.geometry.Polyline poly = new com.epl.geometry.Polyline(); poly.StartPath(10, 10); poly.LineTo(10, 12); poly.LineTo(314, 3150); poly.LineTo(310, 1301); poly.LineTo(3100, 311); com.epl.geometry.EditShape editShape = new com.epl.geometry.EditShape(); int geom = editShape.AddGeometry(poly); int vertex = editShape.GetFirstVertex(editShape.GetFirstPath(geom)); vertex = editShape.RemoveVertex(vertex, true); vertex = editShape.GetNextVertex(vertex); editShape.RemoveVertex(vertex, true); com.epl.geometry.Polyline poly2 = (com.epl.geometry.Polyline)editShape.GetGeometry(geom); poly.SetEmpty(); poly.StartPath(10, 12); poly.LineTo(310, 1301); poly.LineTo(3100, 311); NUnit.Framework.Assert.IsTrue(poly.Equals(poly2)); } { // Test erase com.epl.geometry.Polygon poly = new com.epl.geometry.Polygon(); poly.StartPath(10, 10); poly.LineTo(10, 12); poly.LineTo(314, 3150); poly.LineTo(310, 1301); poly.LineTo(3100, 311); com.epl.geometry.EditShape editShape = new com.epl.geometry.EditShape(); int geom = editShape.AddGeometry(poly); int vertex = editShape.GetFirstVertex(editShape.GetFirstPath(geom)); vertex = editShape.RemoveVertex(vertex, true); vertex = editShape.GetNextVertex(vertex); editShape.RemoveVertex(vertex, true); com.epl.geometry.Polygon poly2 = (com.epl.geometry.Polygon)editShape.GetGeometry(geom); poly.SetEmpty(); poly.StartPath(10, 12); poly.LineTo(310, 1301); poly.LineTo(3100, 311); NUnit.Framework.Assert.IsTrue(poly.Equals(poly2)); } { // Test Filter Close Points com.epl.geometry.Polygon poly = new com.epl.geometry.Polygon(); poly.StartPath(10, 10); poly.LineTo(10, 10.001); poly.LineTo(10.001, 10); com.epl.geometry.EditShape editShape = new com.epl.geometry.EditShape(); int geom = editShape.AddGeometry(poly); editShape.FilterClosePoints(0.002, true, false); com.epl.geometry.Polygon poly2 = (com.epl.geometry.Polygon)editShape.GetGeometry(geom); NUnit.Framework.Assert.IsTrue(poly2.IsEmpty()); } { // Test Filter Close Points com.epl.geometry.Polygon poly = new com.epl.geometry.Polygon(); poly.StartPath(10, 10); poly.LineTo(10, 10.0025); poly.LineTo(11.0, 10); com.epl.geometry.EditShape editShape = new com.epl.geometry.EditShape(); int geom = editShape.AddGeometry(poly); editShape.FilterClosePoints(0.002, true, false); com.epl.geometry.Polygon poly2 = (com.epl.geometry.Polygon)editShape.GetGeometry(geom); NUnit.Framework.Assert.IsTrue(!poly2.IsEmpty()); } { // Test Filter Close Points com.epl.geometry.Polygon poly = new com.epl.geometry.Polygon(); poly.StartPath(10, 10); poly.LineTo(10, 10.001); poly.LineTo(11.0, 10); com.epl.geometry.EditShape editShape = new com.epl.geometry.EditShape(); int geom = editShape.AddGeometry(poly); editShape.FilterClosePoints(0.002, true, false); com.epl.geometry.Polygon poly2 = (com.epl.geometry.Polygon)editShape.GetGeometry(geom); NUnit.Framework.Assert.IsTrue(poly2.IsEmpty()); } { // Test attribute splitting 1 com.epl.geometry.Polyline polyline = new com.epl.geometry.Polyline(); polyline.StartPath(0, 0); polyline.LineTo(1, 1); polyline.LineTo(2, 2); polyline.LineTo(3, 3); polyline.LineTo(4, 4); polyline.StartPath(5, 5); polyline.LineTo(6, 6); polyline.LineTo(7, 7); polyline.LineTo(8, 8); polyline.LineTo(9, 9); polyline.AddAttribute(com.epl.geometry.VertexDescription.Semantics.Z); polyline.SetAttribute(com.epl.geometry.VertexDescription.Semantics.Z, 0, 0, 4); polyline.SetAttribute(com.epl.geometry.VertexDescription.Semantics.Z, 1, 0, 8); polyline.SetAttribute(com.epl.geometry.VertexDescription.Semantics.Z, 2, 0, 12); polyline.SetAttribute(com.epl.geometry.VertexDescription.Semantics.Z, 3, 0, 16); polyline.SetAttribute(com.epl.geometry.VertexDescription.Semantics.Z, 4, 0, 20); polyline.SetAttribute(com.epl.geometry.VertexDescription.Semantics.Z, 5, 0, 22); polyline.SetAttribute(com.epl.geometry.VertexDescription.Semantics.Z, 6, 0, 26); polyline.SetAttribute(com.epl.geometry.VertexDescription.Semantics.Z, 7, 0, 30); polyline.SetAttribute(com.epl.geometry.VertexDescription.Semantics.Z, 8, 0, 34); polyline.SetAttribute(com.epl.geometry.VertexDescription.Semantics.Z, 9, 0, 38); com.epl.geometry.EditShape shape = new com.epl.geometry.EditShape(); int geometry = shape.AddGeometry(polyline); com.epl.geometry.AttributeStreamOfInt32 vertex_handles = new com.epl.geometry.AttributeStreamOfInt32(0); for (int path = shape.GetFirstPath(geometry); path != -1; path = shape.GetNextPath(path)) { for (int vertex = shape.GetFirstVertex(path); vertex != -1; vertex = shape.GetNextVertex(vertex)) { if (vertex != shape.GetLastVertex(path)) { vertex_handles.Add(vertex); } } } double[] t = new double[1]; for (int i = 0; i < vertex_handles.Size(); i++) { int vertex = vertex_handles.Read(i); t[0] = 0.5; shape.SplitSegment(vertex, t, 1); } com.epl.geometry.Polyline chopped_polyline = (com.epl.geometry.Polyline)shape.GetGeometry(geometry); NUnit.Framework.Assert.IsTrue(chopped_polyline.GetPointCount() == 18); double att_ = 4; for (int i_1 = 0; i_1 < 18; i_1++) { double att = chopped_polyline.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.Z, i_1, 0); NUnit.Framework.Assert.IsTrue(att == att_); att_ += 2; } } { // Test attribute splitting 2 com.epl.geometry.Polyline line1 = new com.epl.geometry.Polyline(); com.epl.geometry.Polyline line2 = new com.epl.geometry.Polyline(); line1.AddAttribute(com.epl.geometry.VertexDescription.Semantics.M); line2.AddAttribute(com.epl.geometry.VertexDescription.Semantics.M); line1.StartPath(0, 0); line1.LineTo(10, 10); line2.StartPath(10, 0); line2.LineTo(0, 10); line1.SetAttribute(com.epl.geometry.VertexDescription.Semantics.M, 0, 0, 7); line1.SetAttribute(com.epl.geometry.VertexDescription.Semantics.M, 1, 0, 17); line2.SetAttribute(com.epl.geometry.VertexDescription.Semantics.M, 0, 0, 5); line2.SetAttribute(com.epl.geometry.VertexDescription.Semantics.M, 1, 0, 15); com.epl.geometry.EditShape shape = new com.epl.geometry.EditShape(); int g1 = shape.AddGeometry(line1); int g2 = shape.AddGeometry(line2); com.epl.geometry.CrackAndCluster.Execute(shape, 0.001, null, true); com.epl.geometry.Polyline chopped_line1 = (com.epl.geometry.Polyline)shape.GetGeometry(g1); com.epl.geometry.Polyline chopped_line2 = (com.epl.geometry.Polyline)shape.GetGeometry(g2); double att1 = chopped_line1.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.M, 1, 0); double att2 = chopped_line2.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.M, 1, 0); NUnit.Framework.Assert.IsTrue(att1 == 12); NUnit.Framework.Assert.IsTrue(att2 == 10); } { // Test attribute splitting 3 com.epl.geometry.Polygon polygon = new com.epl.geometry.Polygon(); polygon.AddAttribute(com.epl.geometry.VertexDescription.Semantics.M); polygon.StartPath(0, 0); polygon.LineTo(0, 10); polygon.LineTo(10, 10); polygon.LineTo(10, 0); polygon.SetAttribute(com.epl.geometry.VertexDescription.Semantics.M, 0, 0, 7); polygon.SetAttribute(com.epl.geometry.VertexDescription.Semantics.M, 1, 0, 17); polygon.SetAttribute(com.epl.geometry.VertexDescription.Semantics.M, 2, 0, 23); polygon.SetAttribute(com.epl.geometry.VertexDescription.Semantics.M, 3, 0, 43); com.epl.geometry.EditShape shape = new com.epl.geometry.EditShape(); int geometry = shape.AddGeometry(polygon); com.epl.geometry.AttributeStreamOfInt32 vertex_handles = new com.epl.geometry.AttributeStreamOfInt32(0); int start_v = shape.GetFirstVertex(shape.GetFirstPath(geometry)); int v = start_v; do { vertex_handles.Add(v); v = shape.GetNextVertex(v); }while (v != start_v); double[] t = new double[1]; for (int i = 0; i < vertex_handles.Size(); i++) { int v1 = vertex_handles.Read(i); t[0] = 0.5; shape.SplitSegment(v1, t, 1); } com.epl.geometry.Polygon cut_polygon = (com.epl.geometry.Polygon)shape.GetGeometry(geometry); NUnit.Framework.Assert.IsTrue(cut_polygon.GetPointCount() == 8); com.epl.geometry.Point2D pt0 = cut_polygon.GetXY(0); double a0 = cut_polygon.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.M, 0, 0); NUnit.Framework.Assert.IsTrue(a0 == 25); com.epl.geometry.Point2D pt1 = cut_polygon.GetXY(1); double a1 = cut_polygon.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.M, 1, 0); NUnit.Framework.Assert.IsTrue(a1 == 7); com.epl.geometry.Point2D pt2 = cut_polygon.GetXY(2); double a2 = cut_polygon.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.M, 2, 0); NUnit.Framework.Assert.IsTrue(a2 == 12); com.epl.geometry.Point2D pt3 = cut_polygon.GetXY(3); double a3 = cut_polygon.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.M, 3, 0); NUnit.Framework.Assert.IsTrue(a3 == 17); com.epl.geometry.Point2D pt4 = cut_polygon.GetXY(4); double a4 = cut_polygon.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.M, 4, 0); NUnit.Framework.Assert.IsTrue(a4 == 20); com.epl.geometry.Point2D pt5 = cut_polygon.GetXY(5); double a5 = cut_polygon.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.M, 5, 0); NUnit.Framework.Assert.IsTrue(a5 == 23); com.epl.geometry.Point2D pt6 = cut_polygon.GetXY(6); double a6 = cut_polygon.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.M, 6, 0); NUnit.Framework.Assert.IsTrue(a6 == 33); com.epl.geometry.Point2D pt7 = cut_polygon.GetXY(7); double a7 = cut_polygon.GetAttributeAsDbl(com.epl.geometry.VertexDescription.Semantics.M, 7, 0); NUnit.Framework.Assert.IsTrue(a7 == 43); } }