public virtual void TestBufferPoint()
        {
            com.epl.geometry.SpatialReference sr        = com.epl.geometry.SpatialReference.Create(4326);
            com.epl.geometry.Point            inputGeom = new com.epl.geometry.Point(12, 120);
            com.epl.geometry.OperatorBuffer   buffer    = (com.epl.geometry.OperatorBuffer)com.epl.geometry.OperatorFactoryLocal.GetInstance().GetOperator(com.epl.geometry.Operator.Type.Buffer);
            com.epl.geometry.OperatorSimplify simplify  = (com.epl.geometry.OperatorSimplify)com.epl.geometry.OperatorFactoryLocal.GetInstance().GetOperator(com.epl.geometry.Operator.Type.Simplify);
            com.epl.geometry.Geometry         result    = buffer.Execute(inputGeom, sr, 40.0, null);
            NUnit.Framework.Assert.IsTrue(result.GetType().Value() == com.epl.geometry.Geometry.GeometryType.Polygon);
            com.epl.geometry.Polygon poly = (com.epl.geometry.Polygon)result;
            int pathCount = poly.GetPathCount();

            NUnit.Framework.Assert.IsTrue(pathCount == 1);
            int pointCount = poly.GetPointCount();

            NUnit.Framework.Assert.IsTrue(System.Math.Abs(pointCount - 100.0) < 10);
            com.epl.geometry.Envelope2D env2D = new com.epl.geometry.Envelope2D();
            result.QueryEnvelope2D(env2D);
            NUnit.Framework.Assert.IsTrue(System.Math.Abs(env2D.GetWidth() - 80) < 0.01 && System.Math.Abs(env2D.GetHeight() - 80) < 0.01);
            NUnit.Framework.Assert.IsTrue(System.Math.Abs(env2D.GetCenterX() - 12) < 0.001 && System.Math.Abs(env2D.GetCenterY() - 120) < 0.001);
            com.epl.geometry.NonSimpleResult nsr = new com.epl.geometry.NonSimpleResult();
            bool is_simple = simplify.IsSimpleAsFeature(result, sr, true, nsr, null);

            NUnit.Framework.Assert.IsTrue(is_simple);
            {
                result = buffer.Execute(inputGeom, sr, 0, null);
                NUnit.Framework.Assert.IsTrue(result.GetType().Value() == com.epl.geometry.Geometry.GeometryType.Polygon);
                NUnit.Framework.Assert.IsTrue(result.IsEmpty());
            }
            {
                result = buffer.Execute(inputGeom, sr, -1, null);
                NUnit.Framework.Assert.IsTrue(result.GetType().Value() == com.epl.geometry.Geometry.GeometryType.Polygon);
                NUnit.Framework.Assert.IsTrue(result.IsEmpty());
            }
        }
Example #2
0
 internal virtual int ErrorCoincident()
 {
     // two segments coincide.
     m_b_intersection_detected = true;
     System.Diagnostics.Debug.Assert((m_b_is_simple));
     com.epl.geometry.NonSimpleResult.Reason reason = com.epl.geometry.NonSimpleResult.Reason.CrossOver;
     m_non_simple_result = new com.epl.geometry.NonSimpleResult(reason, m_vertex_1, m_vertex_2);
     return(-1);
 }
Example #3
0
 internal virtual int ErrorCracking()
 {
     // cracking error
     m_b_intersection_detected = true;
     if (m_b_is_simple)
     {
         // only report the reason in IsSimple. Do not do
         // that for regular cracking.
         com.epl.geometry.NonSimpleResult.Reason reason = com.epl.geometry.NonSimpleResult.Reason.Cracking;
         m_non_simple_result = new com.epl.geometry.NonSimpleResult(reason, m_vertex_1, m_vertex_2);
     }
     else
     {
         // reset cached data after detected intersection
         m_prev_1   = -1;
         m_prev_2   = -1;
         m_vertex_1 = -1;
         m_vertex_2 = -1;
     }
     return(-1);
 }
        // Reviewed vs. Feb 8 2011
        public override bool IsSimpleAsFeature(com.epl.geometry.Geometry geom, com.epl.geometry.SpatialReference spatialRef, bool bForceTest, com.epl.geometry.NonSimpleResult result, com.epl.geometry.ProgressTracker progressTracker)
        {
            int res = com.epl.geometry.OperatorSimplifyLocalHelper.IsSimpleAsFeature(geom, spatialRef, bForceTest, result, progressTracker);

            return(res > 0);
        }
 /// <summary>Tests if the Geometry is simple.</summary>
 /// <param name="geom">The Geometry to be tested.</param>
 /// <param name="spatialRef">
 /// Spatial reference from which the tolerance is obtained. Can be null, then a
 /// very small tolerance value is derived from the geometry bounds.
 /// </param>
 /// <param name="bForceTest">When True, the Geometry will be tested regardless of the internal IsKnownSimple flag.</param>
 /// <param name="result">if not null, will contain the results of the check.</param>
 /// <param name="progressTracker">Allows cancellation of a long operation. Can be null.</param>
 public abstract bool IsSimpleAsFeature(com.epl.geometry.Geometry geom, com.epl.geometry.SpatialReference spatialRef, bool bForceTest, com.epl.geometry.NonSimpleResult result, com.epl.geometry.ProgressTracker progressTracker);
Example #6
0
 internal virtual void Assign(com.epl.geometry.NonSimpleResult src)
 {
     m_reason       = src.m_reason;
     m_vertexIndex1 = src.m_vertexIndex1;
     m_vertexIndex2 = src.m_vertexIndex2;
 }
Example #7
0
        // Used for IsSimple.
        internal static bool NeedsCracking(bool allowCoincident, com.epl.geometry.EditShape shape, double tolerance, com.epl.geometry.NonSimpleResult result, com.epl.geometry.ProgressTracker progress_tracker)
        {
            if (!CanBeCracked(shape))
            {
                return(false);
            }
            com.epl.geometry.Cracker cracker = new com.epl.geometry.Cracker(progress_tracker);
            cracker.m_shape            = shape;
            cracker.m_tolerance        = tolerance;
            cracker.m_bAllowCoincident = allowCoincident;
            if (cracker.NeedsCrackingImpl_())
            {
                if (result != null)
                {
                    result.Assign(cracker.m_non_simple_result);
                }
                return(true);
            }
            // Now swap the coordinates to catch horizontal cases.
            com.epl.geometry.Transformation2D transform = new com.epl.geometry.Transformation2D();
            transform.SetSwapCoordinates();
            shape.ApplyTransformation(transform);
            cracker                    = new com.epl.geometry.Cracker(progress_tracker);
            cracker.m_shape            = shape;
            cracker.m_tolerance        = tolerance;
            cracker.m_bAllowCoincident = allowCoincident;
            bool b_res = cracker.NeedsCrackingImpl_();

            transform.SetSwapCoordinates();
            shape.ApplyTransformation(transform);
            // restore shape
            if (b_res)
            {
                if (result != null)
                {
                    result.Assign(cracker.m_non_simple_result);
                }
                return(true);
            }
            return(false);
        }
Example #8
0
        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);
        }