// Tests if Ring1 is inside Ring2.
        // We assume here that the Polygon is Weak Simple. That is if one point of
        // Ring1 is found to be inside of Ring2, then
        // we assume that all of Ring1 is inside Ring2.
        internal static bool _isRingInRing2D(com.epl.geometry.MultiPath polygon, int iRing1, int iRing2, double tolerance, com.epl.geometry.QuadTree quadTree)
        {
            com.epl.geometry.MultiPathImpl       polygonImpl = (com.epl.geometry.MultiPathImpl)polygon._getImpl();
            com.epl.geometry.SegmentIteratorImpl segIter     = polygonImpl.QuerySegmentIterator();
            segIter.ResetToPath(iRing1);
            if (!segIter.NextPath() || !segIter.HasNextSegment())
            {
                throw new com.epl.geometry.GeometryException("corrupted geometry");
            }
            int res = 2;

            while (res == 2 && segIter.HasNextSegment())
            {
                com.epl.geometry.Segment segment = segIter.NextSegment();
                com.epl.geometry.Point2D point   = segment.GetCoord2D(0.5);
                res = com.epl.geometry.PointInPolygonHelper.IsPointInRing(polygonImpl, iRing2, point, tolerance, quadTree);
            }
            if (res == 2)
            {
                throw com.epl.geometry.GeometryException.GeometryInternalError();
            }
            if (res == 1)
            {
                return(true);
            }
            return(false);
        }
 private com.epl.geometry.Geometry Generalize(com.epl.geometry.Geometry geom)
 {
     com.epl.geometry.Geometry.Type gt = geom.GetType();
     if (com.epl.geometry.Geometry.IsPoint(gt.Value()))
     {
         return(geom);
     }
     if (gt == com.epl.geometry.Geometry.Type.Envelope)
     {
         com.epl.geometry.Polygon poly = new com.epl.geometry.Polygon(geom.GetDescription());
         poly.AddEnvelope((com.epl.geometry.Envelope)geom, false);
         return(Generalize(poly));
     }
     if (geom.IsEmpty())
     {
         return(geom);
     }
     com.epl.geometry.MultiPath mp    = (com.epl.geometry.MultiPath)geom;
     com.epl.geometry.MultiPath dstmp = (com.epl.geometry.MultiPath)geom.CreateInstance();
     com.epl.geometry.Line      line  = new com.epl.geometry.Line();
     for (int ipath = 0, npath = mp.GetPathCount(); ipath < npath; ipath++)
     {
         GeneralizePath((com.epl.geometry.MultiPathImpl)mp._getImpl(), ipath, (com.epl.geometry.MultiPathImpl)dstmp._getImpl(), line);
     }
     return(dstmp);
 }
 public OGCLinearRing(com.epl.geometry.MultiPath mp, int pathIndex, com.epl.geometry.SpatialReference sr, bool reversed)
     : base(mp, pathIndex, sr, reversed)
 {
     if (!mp.IsClosedPath(0))
     {
         throw new System.ArgumentException("LinearRing path must be closed");
     }
 }
 public OGCLineString(com.epl.geometry.MultiPath mp, int pathIndex, com.epl.geometry.SpatialReference sr, bool reversed)
 {
     multiPath = new com.epl.geometry.Polyline();
     if (!mp.IsEmpty())
     {
         multiPath.AddPath(mp, pathIndex, !reversed);
     }
     esriSR = sr;
 }
        public static com.epl.geometry.Point[] PointsFromMultiPath(com.epl.geometry.MultiPath geom)
        {
            int numberOfPoints = geom.GetPointCount();

            com.epl.geometry.Point[] points = new com.epl.geometry.Point[numberOfPoints];
            for (int i = 0; i < geom.GetPointCount(); i++)
            {
                points[i] = geom.GetPoint(i);
            }
            return(points);
        }
 public virtual bool IsClosed()
 {
     com.epl.geometry.MultiPath mp = (com.epl.geometry.MultiPath)GetEsriGeometry();
     for (int i = 0, n = mp.GetPathCount(); i < n; i++)
     {
         if (!mp.IsClosedPathInXYPlane(i))
         {
             return(false);
         }
     }
     return(true);
 }
        internal void ShiftPath(com.epl.geometry.MultiPath inputGeom, int iPath, double shift)
        {
            com.epl.geometry.MultiVertexGeometryImpl vertexGeometryImpl = (com.epl.geometry.MultiVertexGeometryImpl)inputGeom._getImpl();
            com.epl.geometry.AttributeStreamOfDbl    xyStream           = (com.epl.geometry.AttributeStreamOfDbl)vertexGeometryImpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION);
            int i1 = inputGeom.GetPathStart(iPath);
            int i2 = inputGeom.GetPathEnd(iPath);

            com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
            while (i1 < i2)
            {
                xyStream.Read(i1, pt);
                pt.x += shift;
                xyStream.Write(i1, pt);
                i1++;
            }
        }
        public static com.epl.geometry.QuadTree BuildQuadTree(com.epl.geometry.MultiPath multipath)
        {
            com.epl.geometry.Envelope2D extent = new com.epl.geometry.Envelope2D();
            multipath.QueryEnvelope2D(extent);
            com.epl.geometry.QuadTree quadTree = new com.epl.geometry.QuadTree(extent, 8);
            int hint_index = -1;

            com.epl.geometry.SegmentIterator seg_iter = multipath.QuerySegmentIterator();
            while (seg_iter.NextPath())
            {
                while (seg_iter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = seg_iter.NextSegment();
                    int index = seg_iter.GetStartPointIndex();
                    com.epl.geometry.Envelope2D boundingbox = new com.epl.geometry.Envelope2D();
                    segment.QueryEnvelope2D(boundingbox);
                    hint_index = quadTree.Insert(index, boundingbox, hint_index);
                }
            }
            return(quadTree);
        }
 private com.epl.geometry.Geometry DensifyMultiPath(com.epl.geometry.MultiPath geom)
 {
     com.epl.geometry.MultiPath       densifiedPoly = (com.epl.geometry.MultiPath)geom.CreateInstance();
     com.epl.geometry.SegmentIterator iter          = geom.QuerySegmentIterator();
     while (iter.NextPath())
     {
         bool bStartNewPath = true;
         while (iter.HasNextSegment())
         {
             com.epl.geometry.Segment seg = iter.NextSegment();
             if (seg.GetType().Value() != com.epl.geometry.Geometry.GeometryType.Line)
             {
                 throw new com.epl.geometry.GeometryException("not implemented");
             }
             bool   bIsClosing = iter.IsClosingSegment();
             double len        = seg.CalculateLength2D();
             if (len > m_maxLength)
             {
                 // need to split
                 double dcount = System.Math.Ceiling(len / m_maxLength);
                 com.epl.geometry.Point point = new com.epl.geometry.Point(geom.GetDescription());
                 // LOCALREFCLASS1(Point,
                 // VertexDescription,
                 // point,
                 // geom.getDescription());
                 if (bStartNewPath)
                 {
                     bStartNewPath = false;
                     seg.QueryStart(point);
                     densifiedPoly.StartPath(point);
                 }
                 double dt = 1.0 / dcount;
                 double t  = dt;
                 for (int i = 0, n = (int)dcount - 1; i < n; i++)
                 {
                     seg.QueryCoord(t, point);
                     densifiedPoly.LineTo(point);
                     t += dt;
                 }
                 if (!bIsClosing)
                 {
                     seg.QueryEnd(point);
                     densifiedPoly.LineTo(point);
                 }
                 else
                 {
                     densifiedPoly.ClosePathWithLine();
                 }
                 bStartNewPath = false;
             }
             else
             {
                 if (!bIsClosing)
                 {
                     densifiedPoly.AddSegment(seg, bStartNewPath);
                 }
                 else
                 {
                     densifiedPoly.ClosePathWithLine();
                 }
                 bStartNewPath = false;
             }
         }
     }
     return((com.epl.geometry.Geometry)densifiedPoly);
 }
Example #10
0
 /// <summary>Appends all paths from another multipath.</summary>
 /// <param name="src">The multipath to append to this multipath.</param>
 /// <param name="bReversePaths">
 /// TRUE if the multipath is added should be added with its paths
 /// reversed.
 /// </param>
 public virtual void Add(com.epl.geometry.MultiPath src, bool bReversePaths)
 {
     m_impl.Add((com.epl.geometry.MultiPathImpl)src._getImpl(), bReversePaths);
 }
Example #11
0
        internal virtual bool RgHelper(com.epl.geometry.RasterizedGeometry2D rg, com.epl.geometry.MultiPath mp)
        {
            com.epl.geometry.SegmentIterator iter = mp.QuerySegmentIterator();
            while (iter.NextPath())
            {
                while (iter.HasNextSegment())
                {
                    com.epl.geometry.Segment seg = iter.NextSegment();
                    int count = 20;
                    for (int i = 0; i < count; i++)
                    {
                        double t = (1.0 * i / count);
                        com.epl.geometry.Point2D pt = seg.GetCoord2D(t);
                        com.epl.geometry.RasterizedGeometry2D.HitType hit = rg.QueryPointInGeometry(pt.x, pt.y);
                        if (hit != com.epl.geometry.RasterizedGeometry2D.HitType.Border)
                        {
                            return(false);
                        }
                    }
                }
            }
            if (mp.GetType() != com.epl.geometry.Geometry.Type.Polygon)
            {
                return(true);
            }
            com.epl.geometry.Polygon    poly = (com.epl.geometry.Polygon)mp;
            com.epl.geometry.Envelope2D env  = new com.epl.geometry.Envelope2D();
            poly.QueryEnvelope2D(env);
            int count_1 = 100;

            for (int iy = 0; iy < count_1; iy++)
            {
                double ty = 1.0 * iy / count_1;
                double y  = env.ymin * (1.0 - ty) + ty * env.ymax;
                for (int ix = 0; ix < count_1; ix++)
                {
                    double tx = 1.0 * ix / count_1;
                    double x  = env.xmin * (1.0 - tx) + tx * env.xmax;
                    com.epl.geometry.RasterizedGeometry2D.HitType hit = rg.QueryPointInGeometry(x, y);
                    com.epl.geometry.PolygonUtils.PiPResult       res = com.epl.geometry.PolygonUtils.IsPointInPolygon2D(poly, new com.epl.geometry.Point2D(x, y), 0);
                    if (res == com.epl.geometry.PolygonUtils.PiPResult.PiPInside)
                    {
                        bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border || hit == com.epl.geometry.RasterizedGeometry2D.HitType.Inside);
                        if (!bgood)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (res == com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
                        {
                            bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border || hit == com.epl.geometry.RasterizedGeometry2D.HitType.Outside);
                            if (!bgood)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border);
                            if (!bgood)
                            {
                                return(false);
                            }
                        }
                    }
                }
            }
            return(true);
        }
        /// <summary>Returns true if the given path of the input MultiPath is convex.</summary>
        /// <remarks>
        /// Returns true if the given path of the input MultiPath is convex. Returns false otherwise.
        /// \param multi_path The MultiPath to check if the path is convex.
        /// \param path_index The path of the MultiPath to check if its convex.
        /// </remarks>
        internal static bool IsPathConvex(com.epl.geometry.MultiPath multi_path, int path_index, com.epl.geometry.ProgressTracker progress_tracker)
        {
            com.epl.geometry.MultiPathImpl mimpl = (com.epl.geometry.MultiPathImpl)multi_path._getImpl();
            int  path_start = mimpl.GetPathStart(path_index);
            int  path_end   = mimpl.GetPathEnd(path_index);
            bool bxyclosed  = !mimpl.IsClosedPath(path_index) && mimpl.IsClosedPathInXYPlane(path_index);

            com.epl.geometry.AttributeStreamOfDbl position = (com.epl.geometry.AttributeStreamOfDbl)(mimpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION));
            int position_start = 2 * path_start;
            int position_end   = 2 * path_end;

            if (bxyclosed)
            {
                position_end -= 2;
            }
            if (position_end - position_start < 6)
            {
                return(true);
            }
            // This matches the logic for case 1 of the tree hull algorithm. The idea is inductive. We assume we have a convex hull pt_0,...,pt_m, and we see if
            // a new point (pt_pivot) is among the transitive tournament for pt_0, knowing that pt_pivot comes after pt_m.
            // We check three conditions:
            // 1) pt_m->pt_pivot->pt_0 is clockwise (closure across the boundary is convex)
            // 2) pt_1->pt_pivot->pt_0 is clockwise (the first step forward is convex)  (pt_1 is the next point after pt_0)
            // 3) pt_m->pt_pivot->pt_m_prev is clockwise (the first step backwards is convex)  (pt_m_prev is the previous point before pt_m)
            // If all three of the above conditions are clockwise, then pt_pivot is among the transitive tournament for pt_0, and therefore the polygon pt_0, ..., pt_m, pt_pivot is convex.
            com.epl.geometry.Point2D pt_0     = new com.epl.geometry.Point2D();
            com.epl.geometry.Point2D pt_m     = new com.epl.geometry.Point2D();
            com.epl.geometry.Point2D pt_pivot = new com.epl.geometry.Point2D();
            position.Read(position_start, pt_0);
            position.Read(position_start + 2, pt_m);
            position.Read(position_start + 4, pt_pivot);
            // Initial inductive step
            com.epl.geometry.ECoordinate det_ec = Determinant_(pt_m, pt_pivot, pt_0);
            if (det_ec.IsFuzzyZero() || !IsClockwise_(det_ec.Value()))
            {
                return(false);
            }
            com.epl.geometry.Point2D pt_1      = new com.epl.geometry.Point2D(pt_m.x, pt_m.y);
            com.epl.geometry.Point2D pt_m_prev = new com.epl.geometry.Point2D();
            // Assume that pt_0,...,pt_m is convex. Check if the next point, pt_pivot, maintains the convex invariant.
            for (int i = position_start + 6; i < position_end; i += 2)
            {
                pt_m_prev.SetCoords(pt_m);
                pt_m.SetCoords(pt_pivot);
                position.Read(i, pt_pivot);
                det_ec = Determinant_(pt_m, pt_pivot, pt_0);
                if (det_ec.IsFuzzyZero() || !IsClockwise_(det_ec.Value()))
                {
                    return(false);
                }
                det_ec = Determinant_(pt_1, pt_pivot, pt_0);
                if (det_ec.IsFuzzyZero() || !IsClockwise_(det_ec.Value()))
                {
                    return(false);
                }
                det_ec = Determinant_(pt_m, pt_pivot, pt_m_prev);
                if (det_ec.IsFuzzyZero() || !IsClockwise_(det_ec.Value()))
                {
                    return(false);
                }
            }
            return(true);
        }
        private static int ExportMultiPathToESRIShape(bool bPolygon, int exportFlags, com.epl.geometry.MultiPath multipath, System.IO.BinaryWriter shapeBuffer)
        {
            com.epl.geometry.MultiPathImpl multipathImpl = (com.epl.geometry.MultiPathImpl)multipath._getImpl();
            bool bExportZs    = multipathImpl.HasAttribute(com.epl.geometry.VertexDescription.Semantics.Z) && (exportFlags & com.epl.geometry.ShapeExportFlags.ShapeExportStripZs) == 0;
            bool bExportMs    = multipathImpl.HasAttribute(com.epl.geometry.VertexDescription.Semantics.M) && (exportFlags & com.epl.geometry.ShapeExportFlags.ShapeExportStripMs) == 0;
            bool bExportIDs   = multipathImpl.HasAttribute(com.epl.geometry.VertexDescription.Semantics.ID) && (exportFlags & com.epl.geometry.ShapeExportFlags.ShapeExportStripIDs) == 0;
            bool bHasCurves   = multipathImpl.HasNonLinearSegments();
            bool bArcViewNaNs = (exportFlags & com.epl.geometry.ShapeExportFlags.ShapeExportTrueNaNs) == 0;
            int  partCount    = multipathImpl.GetPathCount();
            int  pointCount   = multipathImpl.GetPointCount();

            if (!bPolygon)
            {
                for (int ipart = 0; ipart < partCount; ipart++)
                {
                    if (multipath.IsClosedPath(ipart))
                    {
                        pointCount++;
                    }
                }
            }
            else
            {
                pointCount += partCount;
            }
            int size = (4) + (4 * 8) + (4) + (4) + (partCount * 4) + pointCount * 2 * 8;

            /* type */
            /* envelope */
            /* part count */
            /* point count */
            /* start indices */
            /* xy coordinates */
            if (bExportZs)
            {
                size += (2 * 8) + (pointCount * 8);
            }
            /* min max */
            /* zs */
            if (bExportMs)
            {
                size += (2 * 8) + (pointCount * 8);
            }
            /* min max */
            /* ms */
            if (bExportIDs)
            {
                size += pointCount * 4;
            }
            /* ids */
            if (bHasCurves)
            {
            }
            // to-do: curves
            if (size >= com.epl.geometry.NumberUtils.IntMax())
            {
                throw new com.epl.geometry.GeometryException("invalid call");
            }
            if (shapeBuffer == null)
            {
                return(size);
            }
            else
            {
                if (((System.IO.MemoryStream)shapeBuffer.BaseStream).Capacity < size)
                {
                    throw new com.epl.geometry.GeometryException("buffer is too small");
                }
            }
            int offset = 0;
            // Determine the shape type
            int type;

            if (!bExportZs && !bExportMs)
            {
                if (bExportIDs || bHasCurves)
                {
                    type = bPolygon ? com.epl.geometry.ShapeType.ShapeGeneralPolygon : com.epl.geometry.ShapeType.ShapeGeneralPolyline;
                    if (bExportIDs)
                    {
                        type |= com.epl.geometry.ShapeModifiers.ShapeHasIDs;
                    }
                    if (bHasCurves)
                    {
                        type |= com.epl.geometry.ShapeModifiers.ShapeHasCurves;
                    }
                }
                else
                {
                    type = bPolygon ? com.epl.geometry.ShapeType.ShapePolygon : com.epl.geometry.ShapeType.ShapePolyline;
                }
            }
            else
            {
                if (bExportZs && !bExportMs)
                {
                    if (bExportIDs || bHasCurves)
                    {
                        type  = bPolygon ? com.epl.geometry.ShapeType.ShapeGeneralPolygon : com.epl.geometry.ShapeType.ShapeGeneralPolyline;
                        type |= com.epl.geometry.ShapeModifiers.ShapeHasZs;
                        if (bExportIDs)
                        {
                            type |= com.epl.geometry.ShapeModifiers.ShapeHasIDs;
                        }
                        if (bHasCurves)
                        {
                            type |= com.epl.geometry.ShapeModifiers.ShapeHasCurves;
                        }
                    }
                    else
                    {
                        type = bPolygon ? com.epl.geometry.ShapeType.ShapePolygonZ : com.epl.geometry.ShapeType.ShapePolylineZ;
                    }
                }
                else
                {
                    if (bExportMs && !bExportZs)
                    {
                        if (bExportIDs || bHasCurves)
                        {
                            type  = bPolygon ? com.epl.geometry.ShapeType.ShapeGeneralPolygon : com.epl.geometry.ShapeType.ShapeGeneralPolyline;
                            type |= com.epl.geometry.ShapeModifiers.ShapeHasMs;
                            if (bExportIDs)
                            {
                                type |= com.epl.geometry.ShapeModifiers.ShapeHasIDs;
                            }
                            if (bHasCurves)
                            {
                                type |= com.epl.geometry.ShapeModifiers.ShapeHasCurves;
                            }
                        }
                        else
                        {
                            type = bPolygon ? com.epl.geometry.ShapeType.ShapePolygonM : com.epl.geometry.ShapeType.ShapePolylineM;
                        }
                    }
                    else
                    {
                        if (bExportIDs || bHasCurves)
                        {
                            type  = bPolygon ? com.epl.geometry.ShapeType.ShapeGeneralPolygon : com.epl.geometry.ShapeType.ShapeGeneralPolyline;
                            type |= com.epl.geometry.ShapeModifiers.ShapeHasZs | com.epl.geometry.ShapeModifiers.ShapeHasMs;
                            if (bExportIDs)
                            {
                                type |= com.epl.geometry.ShapeModifiers.ShapeHasIDs;
                            }
                            if (bHasCurves)
                            {
                                type |= com.epl.geometry.ShapeModifiers.ShapeHasCurves;
                            }
                        }
                        else
                        {
                            type = bPolygon ? com.epl.geometry.ShapeType.ShapePolygonZM : com.epl.geometry.ShapeType.ShapePolylineZM;
                        }
                    }
                }
            }
            // write type
            shapeBuffer.Write(type);
            offset += 4;
            // write Envelope
            com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
            multipathImpl.QueryEnvelope2D(env);
            // calls _VerifyAllStreams
            shapeBuffer.Write(env.xmin);
            offset += 8;
            shapeBuffer.Write(env.ymin);
            offset += 8;
            shapeBuffer.Write(env.xmax);
            offset += 8;
            shapeBuffer.Write(env.ymax);
            offset += 8;
            // write part count
            shapeBuffer.Write(partCount);
            offset += 4;
            // to-do: return error if larger than 2^32 - 1
            // write pointCount
            shapeBuffer.Write(pointCount);
            offset += 4;
            // write start indices for each part
            int pointIndexDelta = 0;

            for (int ipart = 0; ipart < partCount; ipart++)
            {
                int istart = multipathImpl.GetPathStart(ipart) + pointIndexDelta;
                shapeBuffer.Write(istart);
                offset += 4;
                if (bPolygon || multipathImpl.IsClosedPath(ipart))
                {
                    pointIndexDelta++;
                }
            }
            if (pointCount > 0)
            {
                // write xy coordinates
                com.epl.geometry.AttributeStreamBase  positionStream = multipathImpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION);
                com.epl.geometry.AttributeStreamOfDbl position       = (com.epl.geometry.AttributeStreamOfDbl)positionStream;
                for (int ipart = 0; ipart < partCount; ipart++)
                {
                    int partStart = multipathImpl.GetPathStart(ipart);
                    int partEnd   = multipathImpl.GetPathEnd(ipart);
                    for (int i = partStart; i < partEnd; i++)
                    {
                        double x = position.Read(2 * i);
                        double y = position.Read(2 * i + 1);
                        shapeBuffer.Write(x);
                        offset += 8;
                        shapeBuffer.Write(y);
                        offset += 8;
                    }
                    // If the part is closed, then we need to duplicate the start
                    // point
                    if (bPolygon || multipathImpl.IsClosedPath(ipart))
                    {
                        double x = position.Read(2 * partStart);
                        double y = position.Read(2 * partStart + 1);
                        shapeBuffer.Write(x);
                        offset += 8;
                        shapeBuffer.Write(y);
                        offset += 8;
                    }
                }
            }
            // write Zs
            if (bExportZs)
            {
                com.epl.geometry.Envelope1D zInterval = multipathImpl.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0);
                shapeBuffer.Write(bArcViewNaNs ? com.epl.geometry.Interop.TranslateToAVNaN(zInterval.vmin) : zInterval.vmin);
                offset += 8;
                shapeBuffer.Write(bArcViewNaNs ? com.epl.geometry.Interop.TranslateToAVNaN(zInterval.vmax) : zInterval.vmax);
                offset += 8;
                if (pointCount > 0)
                {
                    if (multipathImpl._attributeStreamIsAllocated(com.epl.geometry.VertexDescription.Semantics.Z))
                    {
                        com.epl.geometry.AttributeStreamOfDbl zs = (com.epl.geometry.AttributeStreamOfDbl)multipathImpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.Z);
                        for (int ipart = 0; ipart < partCount; ipart++)
                        {
                            int partStart = multipathImpl.GetPathStart(ipart);
                            int partEnd   = multipathImpl.GetPathEnd(ipart);
                            for (int i = partStart; i < partEnd; i++)
                            {
                                double z = zs.Read(i);
                                shapeBuffer.Write(bArcViewNaNs ? com.epl.geometry.Interop.TranslateToAVNaN(z) : z);
                                offset += 8;
                            }
                            // If the part is closed, then we need to duplicate the
                            // start z
                            if (bPolygon || multipathImpl.IsClosedPath(ipart))
                            {
                                double z = zs.Read(partStart);
                                shapeBuffer.Write(z);
                                offset += 8;
                            }
                        }
                    }
                    else
                    {
                        double z = com.epl.geometry.VertexDescription.GetDefaultValue(com.epl.geometry.VertexDescription.Semantics.Z);
                        if (bArcViewNaNs)
                        {
                            z = com.epl.geometry.Interop.TranslateToAVNaN(z);
                        }
                        for (int i = 0; i < pointCount; i++)
                        {
                            shapeBuffer.Write(z);
                        }
                        offset += 8;
                    }
                }
            }
            // write Ms
            if (bExportMs)
            {
                com.epl.geometry.Envelope1D mInterval = multipathImpl.QueryInterval(com.epl.geometry.VertexDescription.Semantics.M, 0);
                shapeBuffer.Write(bArcViewNaNs ? com.epl.geometry.Interop.TranslateToAVNaN(mInterval.vmin) : mInterval.vmin);
                offset += 8;
                shapeBuffer.Write(bArcViewNaNs ? com.epl.geometry.Interop.TranslateToAVNaN(mInterval.vmax) : mInterval.vmax);
                offset += 8;
                if (pointCount > 0)
                {
                    if (multipathImpl._attributeStreamIsAllocated(com.epl.geometry.VertexDescription.Semantics.M))
                    {
                        com.epl.geometry.AttributeStreamOfDbl ms = (com.epl.geometry.AttributeStreamOfDbl)multipathImpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.M);
                        for (int ipart = 0; ipart < partCount; ipart++)
                        {
                            int partStart = multipathImpl.GetPathStart(ipart);
                            int partEnd   = multipathImpl.GetPathEnd(ipart);
                            for (int i = partStart; i < partEnd; i++)
                            {
                                double m = ms.Read(i);
                                shapeBuffer.Write(bArcViewNaNs ? com.epl.geometry.Interop.TranslateToAVNaN(m) : m);
                                offset += 8;
                            }
                            // If the part is closed, then we need to duplicate the
                            // start m
                            if (bPolygon || multipathImpl.IsClosedPath(ipart))
                            {
                                double m = ms.Read(partStart);
                                shapeBuffer.Write(m);
                                offset += 8;
                            }
                        }
                    }
                    else
                    {
                        double m = com.epl.geometry.VertexDescription.GetDefaultValue(com.epl.geometry.VertexDescription.Semantics.M);
                        if (bArcViewNaNs)
                        {
                            m = com.epl.geometry.Interop.TranslateToAVNaN(m);
                        }
                        for (int i = 0; i < pointCount; i++)
                        {
                            shapeBuffer.Write(m);
                        }
                        offset += 8;
                    }
                }
            }
            // write Curves
            if (bHasCurves)
            {
            }
            // to-do: We'll finish this later
            // write IDs
            if (bExportIDs)
            {
                if (pointCount > 0)
                {
                    if (multipathImpl._attributeStreamIsAllocated(com.epl.geometry.VertexDescription.Semantics.ID))
                    {
                        com.epl.geometry.AttributeStreamOfInt32 ids = (com.epl.geometry.AttributeStreamOfInt32)multipathImpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.ID);
                        for (int ipart = 0; ipart < partCount; ipart++)
                        {
                            int partStart = multipathImpl.GetPathStart(ipart);
                            int partEnd   = multipathImpl.GetPathEnd(ipart);
                            for (int i = partStart; i < partEnd; i++)
                            {
                                int id = ids.Read(i);
                                shapeBuffer.Write(id);
                                offset += 4;
                            }
                            // If the part is closed, then we need to duplicate the
                            // start id
                            if (bPolygon || multipathImpl.IsClosedPath(ipart))
                            {
                                int id = ids.Read(partStart);
                                shapeBuffer.Write(id);
                                offset += 4;
                            }
                        }
                    }
                    else
                    {
                        int id = (int)com.epl.geometry.VertexDescription.GetDefaultValue(com.epl.geometry.VertexDescription.Semantics.ID);
                        for (int i = 0; i < pointCount; i++)
                        {
                            shapeBuffer.Write(id);
                        }
                        offset += 4;
                    }
                }
            }
            return(offset);
        }
 public override int NumGeometries()
 {
     com.epl.geometry.MultiPath mp = (com.epl.geometry.MultiPath)GetEsriGeometry();
     return(mp.GetPathCount());
 }
Example #15
0
        internal virtual com.epl.geometry.Proximity2DResult MultiPathGetNearestCoordinate(com.epl.geometry.MultiPath geom, com.epl.geometry.Point2D inputPoint, bool bTestPolygonInterior, bool bCalculateLeftRightSide)
        {
            if (geom.GetType() == com.epl.geometry.Geometry.Type.Polygon && bTestPolygonInterior)
            {
                com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                geom.QueryEnvelope2D(env);
                double tolerance = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(null, env, false);
                com.epl.geometry.PolygonUtils.PiPResult pipResult;
                if (bCalculateLeftRightSide)
                {
                    pipResult = com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geom, inputPoint, 0.0);
                }
                else
                {
                    pipResult = com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geom, inputPoint, tolerance);
                }
                if (pipResult != com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
                {
                    com.epl.geometry.Proximity2DResult result = new com.epl.geometry.Proximity2DResult(inputPoint, 0, 0.0);
                    if (bCalculateLeftRightSide)
                    {
                        result.SetRightSide(true);
                    }
                    return(result);
                }
            }
            com.epl.geometry.SegmentIterator segIter = geom.QuerySegmentIterator();
            com.epl.geometry.Point2D         closest = new com.epl.geometry.Point2D();
            int    closestVertexIndex = -1;
            int    closestPathIndex   = -1;
            double closestDistanceSq  = com.epl.geometry.NumberUtils.DoubleMax();
            bool   bRight             = false;
            int    num_candidates     = 0;

            while (segIter.NextPath())
            {
                while (segIter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = segIter.NextSegment();
                    double t = segment.GetClosestCoordinate(inputPoint, false);
                    com.epl.geometry.Point2D point = segment.GetCoord2D(t);
                    double distanceSq = com.epl.geometry.Point2D.SqrDistance(point, inputPoint);
                    if (distanceSq < closestDistanceSq)
                    {
                        num_candidates     = 1;
                        closest            = point;
                        closestVertexIndex = segIter.GetStartPointIndex();
                        closestPathIndex   = segIter.GetPathIndex();
                        closestDistanceSq  = distanceSq;
                    }
                    else
                    {
                        if (distanceSq == closestDistanceSq)
                        {
                            num_candidates++;
                        }
                    }
                }
            }
            com.epl.geometry.Proximity2DResult result_1 = new com.epl.geometry.Proximity2DResult(closest, closestVertexIndex, System.Math.Sqrt(closestDistanceSq));
            if (bCalculateLeftRightSide)
            {
                segIter.ResetToVertex(closestVertexIndex, closestPathIndex);
                com.epl.geometry.Segment segment = segIter.NextSegment();
                bRight = (com.epl.geometry.Point2D.OrientationRobust(inputPoint, segment.GetStartXY(), segment.GetEndXY()) < 0);
                if (num_candidates > 1)
                {
                    com.epl.geometry.OperatorProximity2DLocal.Side_helper sideHelper = new com.epl.geometry.OperatorProximity2DLocal.Side_helper(this);
                    sideHelper.Reset();
                    bRight = sideHelper.Calc_side(inputPoint, bRight, geom, closestVertexIndex, closestPathIndex);
                }
                result_1.SetRightSide(bRight);
            }
            return(result_1);
        }
Example #16
0
            private double BruteForceMultiPathMultiPath_(com.epl.geometry.MultiPath geometryA, com.epl.geometry.MultiPath geometryB, bool geometriesAreDisjoint)
            {
                /* const */
                /* const */
                // It may be beneficial to have the geometry with less vertices
                // always be geometryA.
                com.epl.geometry.SegmentIterator segIterA      = geometryA.QuerySegmentIterator();
                com.epl.geometry.SegmentIterator segIterB      = geometryB.QuerySegmentIterator();
                com.epl.geometry.Envelope2D      env2DSegmentA = new com.epl.geometry.Envelope2D();
                com.epl.geometry.Envelope2D      env2DSegmentB = new com.epl.geometry.Envelope2D();
                double minSqrDistance = com.epl.geometry.NumberUtils.DoubleMax();

                if (!geometriesAreDisjoint)
                {
                    // Geometries might be non-disjoint. Check if they intersect
                    // using point-in-polygon tests
                    if (this.WeakIntersectionTest_(geometryA, geometryB, segIterA, segIterB))
                    {
                        return(0.0);
                    }
                }
                // if geometries are known disjoint, don't bother to do any tests
                // for polygon containment
                // nested while-loop insanity
                while (segIterA.NextPath())
                {
                    while (segIterA.HasNextSegment())
                    {
                        /* const */
                        com.epl.geometry.Segment segmentA = segIterA.NextSegment();
                        segmentA.QueryEnvelope2D(env2DSegmentA);
                        if (env2DSegmentA.SqrDistance(this.m_env2DgeometryB) > minSqrDistance)
                        {
                            continue;
                        }
                        while (segIterB.NextPath())
                        {
                            while (segIterB.HasNextSegment())
                            {
                                /* const */
                                com.epl.geometry.Segment segmentB = segIterB.NextSegment();
                                segmentB.QueryEnvelope2D(env2DSegmentB);
                                if (env2DSegmentA.SqrDistance(env2DSegmentB) < minSqrDistance)
                                {
                                    // get distance between segments
                                    double sqrDistance = segmentA.Distance(segmentB, geometriesAreDisjoint);
                                    sqrDistance *= sqrDistance;
                                    if (sqrDistance < minSqrDistance)
                                    {
                                        if (sqrDistance == 0.0)
                                        {
                                            return(0.0);
                                        }
                                        minSqrDistance = sqrDistance;
                                    }
                                }
                            }
                        }
                        segIterB.ResetToFirstPath();
                    }
                }
                return(System.Math.Sqrt(minSqrDistance));
            }
Example #17
0
 /// <summary>Inserts a path from another multipath.</summary>
 /// <param name="pathIndex">The start index of the multipath to insert.</param>
 /// <param name="src">
 /// The multipath to insert into this multipath. Can be the same
 /// as the multipath being modified.
 /// </param>
 /// <param name="srcPathIndex">The start index to insert the path into the multipath.</param>
 /// <param name="bForward">When FALSE, the points are inserted in reverse order.</param>
 public virtual void InsertPath(int pathIndex, com.epl.geometry.MultiPath src, int srcPathIndex, bool bForward)
 {
     m_impl.InsertPath(pathIndex, (com.epl.geometry.MultiPathImpl)src._getImpl(), srcPathIndex, bForward);
 }
Example #18
0
 /// <summary>Copies a path from another multipath.</summary>
 /// <param name="src">The multipath to copy from.</param>
 /// <param name="srcPathIndex">The index of the path in the the source MultiPath.</param>
 /// <param name="bForward">When FALSE, the points are inserted in reverse order.</param>
 public virtual void AddPath(com.epl.geometry.MultiPath src, int srcPathIndex, bool bForward)
 {
     m_impl.AddPath((com.epl.geometry.MultiPathImpl)src._getImpl(), srcPathIndex, bForward);
 }
Example #19
0
            private double BruteForceMultiPathMultiPoint_(com.epl.geometry.MultiPath geometryA, com.epl.geometry.MultiPoint geometryB, bool geometriesAreDisjoint)
            {
                /* const */
                /* const */
                com.epl.geometry.SegmentIterator segIterA      = geometryA.QuerySegmentIterator();
                com.epl.geometry.Envelope2D      env2DSegmentA = new com.epl.geometry.Envelope2D();
                double minSqrDistance = com.epl.geometry.NumberUtils.DoubleMax();

                com.epl.geometry.Point2D inputPoint = new com.epl.geometry.Point2D();
                double t           = -1;
                double sqrDistance = minSqrDistance;

                /* const */
                com.epl.geometry.MultiPointImpl multiPointImplB = (com.epl.geometry.MultiPointImpl)geometryB._getImpl();
                int  pointCountB = multiPointImplB.GetPointCount();
                bool bDoPiPTest  = !geometriesAreDisjoint && (geometryA.GetType() == com.epl.geometry.Geometry.Type.Polygon);

                while (segIterA.NextPath())
                {
                    while (segIterA.HasNextSegment())
                    {
                        /* const */
                        com.epl.geometry.Segment segmentA = segIterA.NextSegment();
                        segmentA.QueryEnvelope2D(env2DSegmentA);
                        // if multipointB has only 1 vertex then it is faster to not
                        // test for
                        // env2DSegmentA.distance(env2DgeometryB)
                        if (pointCountB > 1 && env2DSegmentA.SqrDistance(this.m_env2DgeometryB) > minSqrDistance)
                        {
                            continue;
                        }
                        for (int i = 0; i < pointCountB; i++)
                        {
                            multiPointImplB.GetXY(i, inputPoint);
                            if (bDoPiPTest)
                            {
                                // Test for polygon containment. This takes the
                                // place of a more general intersection test at the
                                // beginning of the operator
                                if (com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geometryA, inputPoint, 0) != com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
                                {
                                    return(0.0);
                                }
                            }
                            t = segmentA.GetClosestCoordinate(inputPoint, false);
                            inputPoint.Sub(segmentA.GetCoord2D(t));
                            sqrDistance = inputPoint.SqrLength();
                            if (sqrDistance < minSqrDistance)
                            {
                                if (sqrDistance == 0.0)
                                {
                                    return(0.0);
                                }
                                minSqrDistance = sqrDistance;
                            }
                        }
                        // No need to do point-in-polygon anymore (if it is a
                        // polygon vs polyline)
                        bDoPiPTest = false;
                    }
                }
                return(System.Math.Sqrt(minSqrDistance));
            }
Example #20
0
 /// <summary>Adds segments from a source multipath to this MultiPath.</summary>
 /// <param name="src">The source MultiPath to add segments from.</param>
 /// <param name="srcPathIndex">The index of the path in the the source MultiPath.</param>
 /// <param name="srcSegmentFrom">
 /// The index of first segment in the path to start adding from.
 /// The value has to be between 0 and
 /// src.getSegmentCount(srcPathIndex) - 1.
 /// </param>
 /// <param name="srcSegmentCount">
 /// The number of segments to add. If 0, the function does
 /// nothing.
 /// </param>
 /// <param name="bStartNewPath">
 /// When true, a new path is added and segments are added to it.
 /// Otherwise the segments are added to the last path of this
 /// MultiPath.
 /// If bStartNewPath false, the first point of the first source
 /// segment is not added. This is done to ensure proper connection
 /// to existing segments. When the source path is closed, and the
 /// closing segment is among those to be added, it is added also
 /// as a closing segment, not as a real segment. Use add_segment
 /// instead if you do not like that behavior.
 /// This MultiPath obtains all missing attributes from the src
 /// MultiPath.
 /// </param>
 public virtual void AddSegmentsFromPath(com.epl.geometry.MultiPath src, int srcPathIndex, int srcSegmentFrom, int srcSegmentCount, bool bStartNewPath)
 {
     m_impl.AddSegmentsFromPath((com.epl.geometry.MultiPathImpl)src._getImpl(), srcPathIndex, srcSegmentFrom, srcSegmentCount, bStartNewPath);
 }
Example #21
0
 // Try to find two segements that are not degenerate
 internal virtual bool Calc_side(com.epl.geometry.Point2D inputPoint, bool bRight, com.epl.geometry.MultiPath multipath, int vertexIndex, int pathIndex)
 {
     com.epl.geometry.SegmentIterator segIter = multipath.QuerySegmentIterator();
     this.Find_analysis_pair_from_index(inputPoint, segIter, vertexIndex, pathIndex);
     if (this.m_i1 != -1 && this.m_i2 == -1)
     {
         // could not find a pair of segments
         return(this.m_bRight1);
     }
     if (this.m_i1 != -1 && this.m_i2 != -1)
     {
         if (this.m_bRight1 == this.m_bRight2)
         {
             return(this.m_bRight1);
         }
         else
         {
             // no conflicting result for the side
             // the conflicting result, that we are trying to resolve,
             // happens in the obtuse (outer) side of the turn only.
             segIter.ResetToVertex(this.m_i1, -1);
             com.epl.geometry.Segment segment1 = segIter.NextSegment();
             com.epl.geometry.Point2D tang1    = segment1._getTangent(1.0);
             segIter.ResetToVertex(this.m_i2, -1);
             com.epl.geometry.Segment segment2 = segIter.NextSegment();
             com.epl.geometry.Point2D tang2    = segment2._getTangent(0.0);
             double cross = tang1.CrossProduct(tang2);
             if (cross >= 0)
             {
                 // the obtuse angle is on the right side
                 return(true);
             }
             else
             {
                 // the obtuse angle is on the right side
                 return(false);
             }
         }
     }
     else
     {
         System.Diagnostics.Debug.Assert((this.m_i1 == -1 && this.m_i2 == -1));
         return(bRight);
     }
 }
Example #22
0
 /// <summary>Inserts vertices from the given multipath into this multipath.</summary>
 /// <remarks>
 /// Inserts vertices from the given multipath into this multipath. All added
 /// vertices are connected by linear segments with each other and with the
 /// existing vertices.
 /// </remarks>
 /// <param name="pathIndex">
 /// The path index in this multipath to insert points to. Must
 /// correspond to an existing path.
 /// </param>
 /// <param name="beforePointIndex">
 /// The point index before all other vertices to insert in the
 /// given path of this multipath. This value must be between 0 and
 /// GetPathSize(pathIndex), or -1 to insert points at the end of
 /// the given path.
 /// </param>
 /// <param name="src">The source multipath.</param>
 /// <param name="srcPathIndex">The source path index to copy points from.</param>
 /// <param name="srcPointIndexFrom">The start point in the source path to start copying from.</param>
 /// <param name="srcPointCount">The count of points to add.</param>
 /// <param name="bForward">When FALSE, the points are inserted in reverse order.</param>
 public virtual void InsertPoints(int pathIndex, int beforePointIndex, com.epl.geometry.MultiPath src, int srcPathIndex, int srcPointIndexFrom, int srcPointCount, bool bForward)
 {
     m_impl.InsertPoints(pathIndex, beforePointIndex, (com.epl.geometry.MultiPathImpl)src._getImpl(), srcPathIndex, srcPointIndexFrom, srcPointCount, bForward);
 }
        private static void ExportPolypathToJson(com.epl.geometry.MultiPath pp, string name, com.epl.geometry.SpatialReference spatialReference, com.epl.geometry.JsonWriter jsonWriter, System.Collections.Generic.IDictionary <string, object> exportProperties)
        {
            bool bExportZs    = pp.HasAttribute(com.epl.geometry.VertexDescription.Semantics.Z);
            bool bExportMs    = pp.HasAttribute(com.epl.geometry.VertexDescription.Semantics.M);
            bool bPositionAsF = false;
            int  decimals     = 17;

            if (exportProperties != null)
            {
                object numberOfDecimalsXY = exportProperties["numberOfDecimalsXY"];
                if (numberOfDecimalsXY != null && numberOfDecimalsXY is java.lang.Number)
                {
                    bPositionAsF = true;
                    decimals     = ((java.lang.Number)numberOfDecimalsXY);
                }
            }
            jsonWriter.StartObject();
            if (bExportZs)
            {
                jsonWriter.AddPairBoolean("hasZ", true);
            }
            if (bExportMs)
            {
                jsonWriter.AddPairBoolean("hasM", true);
            }
            jsonWriter.AddPairArray(name);
            if (!pp.IsEmpty())
            {
                int n = pp.GetPathCount();
                // rings or paths
                com.epl.geometry.MultiPathImpl mpImpl = (com.epl.geometry.MultiPathImpl)pp._getImpl();
                // get impl for
                // faster
                // access
                com.epl.geometry.AttributeStreamOfDbl zs = null;
                com.epl.geometry.AttributeStreamOfDbl ms = null;
                if (bExportZs)
                {
                    zs = (com.epl.geometry.AttributeStreamOfDbl)mpImpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.Z);
                }
                if (bExportMs)
                {
                    ms = (com.epl.geometry.AttributeStreamOfDbl)mpImpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.M);
                }
                bool bPolygon = pp is com.epl.geometry.Polygon;
                com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
                for (int i = 0; i < n; i++)
                {
                    jsonWriter.AddValueArray();
                    int    startindex  = pp.GetPathStart(i);
                    int    numVertices = pp.GetPathSize(i);
                    double startx      = 0.0;
                    double starty      = 0.0;
                    double startz      = com.epl.geometry.NumberUtils.NaN();
                    double startm      = com.epl.geometry.NumberUtils.NaN();
                    double z           = com.epl.geometry.NumberUtils.NaN();
                    double m           = com.epl.geometry.NumberUtils.NaN();
                    bool   bClosed     = pp.IsClosedPath(i);
                    for (int j = startindex; j < startindex + numVertices; j++)
                    {
                        pp.GetXY(j, pt);
                        jsonWriter.AddValueArray();
                        if (bPositionAsF)
                        {
                            jsonWriter.AddValueDouble(pt.x, decimals, true);
                            jsonWriter.AddValueDouble(pt.y, decimals, true);
                        }
                        else
                        {
                            jsonWriter.AddValueDouble(pt.x);
                            jsonWriter.AddValueDouble(pt.y);
                        }
                        if (bExportZs)
                        {
                            z = zs.Get(j);
                            jsonWriter.AddValueDouble(z);
                        }
                        if (bExportMs)
                        {
                            m = ms.Get(j);
                            jsonWriter.AddValueDouble(m);
                        }
                        if (j == startindex && bClosed)
                        {
                            startx = pt.x;
                            starty = pt.y;
                            startz = z;
                            startm = m;
                        }
                        jsonWriter.EndArray();
                    }
                    // Close the Path/Ring by writing the Point at the start index
                    if (bClosed && (startx != pt.x || starty != pt.y || (bExportZs && !(com.epl.geometry.NumberUtils.IsNaN(startz) && com.epl.geometry.NumberUtils.IsNaN(z)) && startz != z) || (bExportMs && !(com.epl.geometry.NumberUtils.IsNaN(startm) && com.epl.geometry.NumberUtils.IsNaN(m)) && startm
                                                                                                                                                                                                 != m)))
                    {
                        pp.GetXY(startindex, pt);
                        // getPoint(startindex);
                        jsonWriter.AddValueArray();
                        if (bPositionAsF)
                        {
                            jsonWriter.AddValueDouble(pt.x, decimals, true);
                            jsonWriter.AddValueDouble(pt.y, decimals, true);
                        }
                        else
                        {
                            jsonWriter.AddValueDouble(pt.x);
                            jsonWriter.AddValueDouble(pt.y);
                        }
                        if (bExportZs)
                        {
                            z = zs.Get(startindex);
                            jsonWriter.AddValueDouble(z);
                        }
                        if (bExportMs)
                        {
                            m = ms.Get(startindex);
                            jsonWriter.AddValueDouble(m);
                        }
                        jsonWriter.EndArray();
                    }
                    jsonWriter.EndArray();
                }
            }
            jsonWriter.EndArray();
            if (spatialReference != null)
            {
                WriteSR(spatialReference, jsonWriter);
            }
            jsonWriter.EndObject();
        }