Example #1
0
        // private AttributeStreamOfInt32 m_orphanVertices;
        private void _beforeRemoveVertex(int vertex, bool bChangePathFirst)
        {
            int vertexlistIndex = m_shape.GetUserIndex(vertex, m_userIndexSortedIndexToVertex);

            if (m_nextVertexToProcess == vertexlistIndex)
            {
                m_nextVertexToProcess = m_sortedVertices.GetNext(m_nextVertexToProcess);
            }
            if (m_firstCoincidentVertex == vertexlistIndex)
            {
                m_firstCoincidentVertex = m_sortedVertices.GetNext(m_firstCoincidentVertex);
            }
            m_sortedVertices.DeleteElement(m_sortedVerticesListIndex, vertexlistIndex);
            _removeAngleSortInfo(vertex);
            if (bChangePathFirst)
            {
                int path = m_shape.GetPathFromVertex(vertex);
                if (path != -1)
                {
                    int first = m_shape.GetFirstVertex(path);
                    if (first == vertex)
                    {
                        int next = m_shape.GetNextVertex(vertex);
                        if (next != vertex)
                        {
                            int p = m_shape.GetPathFromVertex(next);
                            if (p == path)
                            {
                                m_shape.SetFirstVertex_(path, next);
                                return;
                            }
                            else
                            {
                                int prev = m_shape.GetPrevVertex(vertex);
                                if (prev != vertex)
                                {
                                    p = m_shape.GetPathFromVertex(prev);
                                    if (p == path)
                                    {
                                        m_shape.SetFirstVertex_(path, prev);
                                        return;
                                    }
                                }
                            }
                        }
                        m_shape.SetFirstVertex_(path, -1);
                        m_shape.SetLastVertex_(path, -1);
                    }
                }
            }
        }
        internal bool ClusterNonReciprocal_()
        {
            int point_count = m_shape.GetTotalPointCount();

            com.epl.geometry.Envelope2D env = m_shape.GetEnvelope2D();
            m_origin = env.GetLowerLeft();
            double dim     = System.Math.Max(env.GetHeight(), env.GetWidth());
            double mincell = dim / (com.epl.geometry.NumberUtils.IntMax() - 1);

            if (m_cell_size < mincell)
            {
                m_cell_size     = mincell;
                m_inv_cell_size = 1.0 / m_cell_size;
            }
            // This holds clusters.
            m_clusters = new com.epl.geometry.IndexMultiList();
            m_clusters.ReserveLists(m_shape.GetTotalPointCount() / 3 + 1);
            m_clusters.ReserveNodes(m_shape.GetTotalPointCount() / 3 + 1);
            m_hash_values  = m_shape.CreateUserIndex();
            m_new_clusters = m_shape.CreateUserIndex();
            // Make the hash table. It serves a purpose of fine grain grid.
            // Make it 25% larger than the 4 times point count to reduce the chance
            // of collision.
            // The 4 times comes from the fact that we check four neighbouring cells
            // in the grid for each point.
            m_hash_function = new com.epl.geometry.Clusterer.ClusterHashFunction(this, m_shape, m_origin, m_sqr_tolerance, m_inv_cell_size, m_hash_values);
            m_hash_table    = new com.epl.geometry.IndexHashTable(4 * point_count / 3, m_hash_function);
            m_hash_table.ReserveElements(m_shape.GetTotalPointCount());
            bool b_clustered = false;

            // Go through all vertices stored in the m_shape and put the handles of
            // the vertices into the clusters and the hash table.
            for (int geometry = m_shape.GetFirstGeometry(); geometry != -1; geometry = m_shape.GetNextGeometry(geometry))
            {
                for (int path = m_shape.GetFirstPath(geometry); path != -1; path = m_shape.GetNextPath(path))
                {
                    int vertex = m_shape.GetFirstVertex(path);
                    for (int index = 0, nindex = m_shape.GetPathSize(path); index < nindex; index++)
                    {
                        System.Diagnostics.Debug.Assert((vertex != -1));
                        int hash = m_hash_function.Calculate_hash_from_vertex(vertex);
                        m_shape.SetUserIndex(vertex, m_hash_values, hash);
                        m_hash_table.AddElement(vertex, hash);
                        // add cluster to the
                        // hash table
                        System.Diagnostics.Debug.Assert((m_shape.GetUserIndex(vertex, m_new_clusters) == -1));
                        vertex = m_shape.GetNextVertex(vertex);
                    }
                }
            }
            {
                // m_hash_table->dbg_print_bucket_histogram_();
                // scope for candidates array
                com.epl.geometry.AttributeStreamOfInt32 candidates = new com.epl.geometry.AttributeStreamOfInt32(0);
                candidates.Reserve(10);
                for (int geometry_1 = m_shape.GetFirstGeometry(); geometry_1 != -1; geometry_1 = m_shape.GetNextGeometry(geometry_1))
                {
                    for (int path = m_shape.GetFirstPath(geometry_1); path != -1; path = m_shape.GetNextPath(path))
                    {
                        int vertex = m_shape.GetFirstVertex(path);
                        for (int index = 0, nindex = m_shape.GetPathSize(path); index < nindex; index++)
                        {
                            if (m_shape.GetUserIndex(vertex, m_new_clusters) == com.epl.geometry.StridedIndexTypeCollection.ImpossibleIndex2())
                            {
                                vertex = m_shape.GetNextVertex(vertex);
                                continue;
                            }
                            // this vertex was merged with another
                            // cluster. It also was removed from the
                            // hash table.
                            int hash = m_shape.GetUserIndex(vertex, m_hash_values);
                            m_hash_table.DeleteElement(vertex, hash);
                            while (true)
                            {
                                CollectClusterCandidates_(vertex, candidates);
                                if (candidates.Size() == 0)
                                {
                                    // no candidate for
                                    // clustering has
                                    // been found for
                                    // the cluster_1.
                                    break;
                                }
                                bool clustered = false;
                                for (int candidate_index = 0, ncandidates = candidates.Size(); candidate_index < ncandidates; candidate_index++)
                                {
                                    int cluster_node = candidates.Get(candidate_index);
                                    int other_vertex = m_hash_table.GetElement(cluster_node);
                                    m_hash_table.DeleteNode(cluster_node);
                                    clustered |= MergeClusters_(vertex, other_vertex, candidate_index + 1 == ncandidates);
                                }
                                b_clustered |= clustered;
                                candidates.Clear(false);
                                // repeat search for the cluster candidates for
                                // cluster_1
                                if (!clustered)
                                {
                                    break;
                                }
                            }
                            // positions did not change
                            // m_shape->set_user_index(vertex, m_new_clusters,
                            // Strided_index_type_collection::impossible_index_2());
                            vertex = m_shape.GetNextVertex(vertex);
                        }
                    }
                }
            }
            if (b_clustered)
            {
                ApplyClusterPositions_();
            }
            m_hash_table    = null;
            m_hash_function = null;
            m_shape.RemoveUserIndex(m_hash_values);
            m_shape.RemoveUserIndex(m_new_clusters);
            // output_debug_printf("total: %d\n",m_shape->get_total_point_count());
            // output_debug_printf("clustered: %d\n",m_dbg_candidate_check_count);
            return(b_clustered);
        }
Example #3
0
        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);
        }
Example #4
0
 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);
     }
 }