private static void ExportMultiPointToJson(com.epl.geometry.MultiPoint mpt, com.epl.geometry.SpatialReference spatialReference, com.epl.geometry.JsonWriter jsonWriter, System.Collections.Generic.IDictionary <string, object> exportProperties)
        {
            bool bExportZs    = mpt.HasAttribute(com.epl.geometry.VertexDescription.Semantics.Z);
            bool bExportMs    = mpt.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("points");
            if (!mpt.IsEmpty())
            {
                com.epl.geometry.MultiPointImpl mpImpl = (com.epl.geometry.MultiPointImpl)mpt._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);
                }
                com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
                int n = mpt.GetPointCount();
                for (int i = 0; i < n; i++)
                {
                    mpt.GetXY(i, 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)
                    {
                        double z = zs.Get(i);
                        jsonWriter.AddValueDouble(z);
                    }
                    if (bExportMs)
                    {
                        double m = ms.Get(i);
                        jsonWriter.AddValueDouble(m);
                    }
                    jsonWriter.EndArray();
                }
            }
            jsonWriter.EndArray();
            if (spatialReference != null)
            {
                WriteSR(spatialReference, jsonWriter);
            }
            jsonWriter.EndObject();
        }
Пример #2
0
		internal virtual com.epl.geometry.Geometry TryFastIntersectPolylinePolygon_(com.epl.geometry.Polyline polyline, com.epl.geometry.Polygon polygon)
		{
			com.epl.geometry.MultiPathImpl polylineImpl = (com.epl.geometry.MultiPathImpl)polyline._getImpl();
			com.epl.geometry.MultiPathImpl polygonImpl = (com.epl.geometry.MultiPathImpl)polygon._getImpl();
			double tolerance = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(m_spatial_reference, polygon, false);
			com.epl.geometry.Envelope2D clipEnvelope = new com.epl.geometry.Envelope2D();
			{
				polygonImpl.QueryEnvelope2D(clipEnvelope);
				com.epl.geometry.Envelope2D env1 = new com.epl.geometry.Envelope2D();
				polylineImpl.QueryEnvelope2D(env1);
				env1.Inflate(2.0 * tolerance, 2.0 * tolerance);
				clipEnvelope.Intersect(env1);
				System.Diagnostics.Debug.Assert((!clipEnvelope.IsEmpty()));
			}
			clipEnvelope.Inflate(10 * tolerance, 10 * tolerance);
			if (true)
			{
				double tol = 0;
				com.epl.geometry.Geometry clippedPolyline = com.epl.geometry.Clipper.Clip(polyline, clipEnvelope, tol, 0.0);
				polyline = (com.epl.geometry.Polyline)clippedPolyline;
				polylineImpl = (com.epl.geometry.MultiPathImpl)polyline._getImpl();
			}
			com.epl.geometry.AttributeStreamOfInt32 clipResult = new com.epl.geometry.AttributeStreamOfInt32(0);
			int unresolvedSegments = -1;
			com.epl.geometry.GeometryAccelerators accel = polygonImpl._getAccelerators();
			if (accel != null)
			{
				com.epl.geometry.RasterizedGeometry2D rgeom = accel.GetRasterizedGeometry();
				if (rgeom != null)
				{
					unresolvedSegments = 0;
					clipResult.Reserve(polylineImpl.GetPointCount() + polylineImpl.GetPathCount());
					com.epl.geometry.Envelope2D seg_env = new com.epl.geometry.Envelope2D();
					com.epl.geometry.SegmentIteratorImpl iter = polylineImpl.QuerySegmentIterator();
					while (iter.NextPath())
					{
						while (iter.HasNextSegment())
						{
							com.epl.geometry.Segment seg = iter.NextSegment();
							seg.QueryEnvelope2D(seg_env);
							com.epl.geometry.RasterizedGeometry2D.HitType hit = rgeom.QueryEnvelopeInGeometry(seg_env);
							if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Inside)
							{
								clipResult.Add(1);
							}
							else
							{
								if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Outside)
								{
									clipResult.Add(0);
								}
								else
								{
									clipResult.Add(-1);
									unresolvedSegments++;
								}
							}
						}
					}
				}
			}
			if (polygon.GetPointCount() > 5)
			{
				double tol = 0;
				com.epl.geometry.Geometry clippedPolygon = com.epl.geometry.Clipper.Clip(polygon, clipEnvelope, tol, 0.0);
				polygon = (com.epl.geometry.Polygon)clippedPolygon;
				polygonImpl = (com.epl.geometry.MultiPathImpl)polygon._getImpl();
				accel = polygonImpl._getAccelerators();
			}
			//update accelerators
			if (unresolvedSegments < 0)
			{
				unresolvedSegments = polylineImpl.GetSegmentCount();
			}
			// Some heuristics to decide if it makes sense to go with fast intersect
			// vs going with the regular planesweep.
			double totalPoints = (double)(polylineImpl.GetPointCount() + polygonImpl.GetPointCount());
			double thisAlgorithmComplexity = ((double)unresolvedSegments * polygonImpl.GetPointCount());
			// assume the worst case.
			double planesweepComplexity = System.Math.Log(totalPoints) * totalPoints;
			double empiricConstantFactorPlaneSweep = 4;
			if (thisAlgorithmComplexity > planesweepComplexity * empiricConstantFactorPlaneSweep)
			{
				// Based on the number of input points, we deduced that the
				// plansweep performance should be better than the brute force
				// performance.
				return null;
			}
			// resort to planesweep if quadtree does not help
			com.epl.geometry.QuadTreeImpl polygonQuadTree = null;
			com.epl.geometry.SegmentIteratorImpl polygonIter = polygonImpl.QuerySegmentIterator();
			// Some logic to decide if it makes sense to build a quadtree on the
			// polygon segments
			if (accel != null && accel.GetQuadTree() != null)
			{
				polygonQuadTree = accel.GetQuadTree();
			}
			if (polygonQuadTree == null && polygonImpl.GetPointCount() > 20)
			{
				polygonQuadTree = com.epl.geometry.InternalUtils.BuildQuadTree(polygonImpl);
			}
			com.epl.geometry.Polyline result_polyline = (com.epl.geometry.Polyline)polyline.CreateInstance();
			com.epl.geometry.MultiPathImpl resultPolylineImpl = (com.epl.geometry.MultiPathImpl)result_polyline._getImpl();
			com.epl.geometry.QuadTreeImpl.QuadTreeIteratorImpl qIter = null;
			com.epl.geometry.SegmentIteratorImpl polylineIter = polylineImpl.QuerySegmentIterator();
			double[] @params = new double[9];
			com.epl.geometry.AttributeStreamOfDbl intersections = new com.epl.geometry.AttributeStreamOfDbl(0);
			com.epl.geometry.SegmentBuffer segmentBuffer = new com.epl.geometry.SegmentBuffer();
			int start_index = -1;
			int inCount = 0;
			int segIndex = 0;
			bool bOptimized = clipResult.Size() > 0;
			// The algorithm is like that:
			// Loop through all the segments of the polyline.
			// For each polyline segment, intersect it with each of the polygon
			// segments.
			// If no intersections found then,
			// If the polyline segment is completely inside, it is added to the
			// result polyline.
			// If it is outside, it is thrown out.
			// If it intersects, then cut the polyline segment to pieces and test
			// each part of the intersected result.
			// The cut pieces will either have one point inside, or one point
			// outside, or the middle point inside/outside.
			//
			int polylinePathIndex = -1;
			while (polylineIter.NextPath())
			{
				polylinePathIndex = polylineIter.GetPathIndex();
				int stateNewPath = 0;
				int stateAddSegment = 1;
				int stateManySegments = 2;
				int stateManySegmentsContinuePath = 2;
				int stateManySegmentsNewPath = 3;
				int state = stateNewPath;
				start_index = -1;
				inCount = 0;
				while (polylineIter.HasNextSegment())
				{
					int clipStatus = bOptimized ? (int)clipResult.Get(segIndex) : -1;
					segIndex++;
					com.epl.geometry.Segment polylineSeg = polylineIter.NextSegment();
					if (clipStatus < 0)
					{
						System.Diagnostics.Debug.Assert((clipStatus == -1));
						// Analyse polyline segment for intersection with the
						// polygon.
						if (polygonQuadTree != null)
						{
							if (qIter == null)
							{
								qIter = polygonQuadTree.GetIterator(polylineSeg, tolerance);
							}
							else
							{
								qIter.ResetIterator(polylineSeg, tolerance);
							}
							int path_index = -1;
							for (int ind = qIter.Next(); ind != -1; ind = qIter.Next())
							{
								polygonIter.ResetToVertex(polygonQuadTree.GetElement(ind));
								// path_index
								path_index = polygonIter.GetPathIndex();
								com.epl.geometry.Segment polygonSeg = polygonIter.NextSegment();
								// intersect polylineSeg and polygonSeg.
								int count = polylineSeg.Intersect(polygonSeg, null, @params, null, tolerance);
								for (int i = 0; i < count; i++)
								{
									intersections.Add(@params[i]);
								}
							}
						}
						else
						{
							// no quadtree built
							polygonIter.ResetToFirstPath();
							while (polygonIter.NextPath())
							{
								while (polygonIter.HasNextSegment())
								{
									com.epl.geometry.Segment polygonSeg = polygonIter.NextSegment();
									// intersect polylineSeg and polygonSeg.
									int count = polylineSeg.Intersect(polygonSeg, null, @params, null, tolerance);
									for (int i = 0; i < count; i++)
									{
										intersections.Add(@params[i]);
									}
								}
							}
						}
						if (intersections.Size() > 0)
						{
							// intersections detected.
							intersections.Sort(0, intersections.Size());
							// std::sort(intersections.begin(),
							// intersections.end());
							double t0 = 0;
							intersections.Add(1.0);
							int status = -1;
							for (int i = 0, n = intersections.Size(); i < n; i++)
							{
								double t = intersections.Get(i);
								if (t == t0)
								{
									continue;
								}
								bool bWholeSegment = false;
								com.epl.geometry.Segment resSeg;
								if (t0 != 0 || t != 1.0)
								{
									polylineSeg.Cut(t0, t, segmentBuffer);
									resSeg = segmentBuffer.Get();
								}
								else
								{
									resSeg = polylineSeg;
									bWholeSegment = true;
								}
								if (state >= stateManySegments)
								{
									resultPolylineImpl.AddSegmentsFromPath(polylineImpl, polylinePathIndex, start_index, inCount, state == stateManySegmentsNewPath);
									if (AnalyseClipSegment_(polygon, resSeg.GetStartXY(), tolerance) != 1)
									{
										if (AnalyseClipSegment_(polygon, resSeg, tolerance) != 1)
										{
											return null;
										}
									}
									//someting went wrong we'll falback to slower but robust planesweep code.
									resultPolylineImpl.AddSegment(resSeg, false);
									state = stateAddSegment;
									inCount = 0;
								}
								else
								{
									status = AnalyseClipSegment_(polygon, resSeg, tolerance);
									switch (status)
									{
										case 1:
										{
											if (!bWholeSegment)
											{
												resultPolylineImpl.AddSegment(resSeg, state == stateNewPath);
												state = stateAddSegment;
											}
											else
											{
												if (state < stateManySegments)
												{
													start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
													inCount = 1;
													if (state == stateNewPath)
													{
														state = stateManySegmentsNewPath;
													}
													else
													{
														System.Diagnostics.Debug.Assert((state == stateAddSegment));
														state = stateManySegmentsContinuePath;
													}
												}
												else
												{
													inCount++;
												}
											}
											break;
										}

										case 0:
										{
											state = stateNewPath;
											start_index = -1;
											inCount = 0;
											break;
										}

										default:
										{
											return null;
										}
									}
								}
								// may happen if a segment
								// coincides with the border.
								t0 = t;
							}
						}
						else
						{
							clipStatus = AnalyseClipSegment_(polygon, polylineSeg.GetStartXY(), tolerance);
							// simple
							// case
							// no
							// intersection.
							// Both
							// points
							// must
							// be
							// inside.
							if (clipStatus < 0)
							{
								System.Diagnostics.Debug.Assert((clipStatus >= 0));
								return null;
							}
							// something goes wrong, resort to
							// planesweep
							System.Diagnostics.Debug.Assert((AnalyseClipSegment_(polygon, polylineSeg.GetEndXY(), tolerance) == clipStatus));
							if (clipStatus == 1)
							{
								// the whole segment inside
								if (state < stateManySegments)
								{
									System.Diagnostics.Debug.Assert((inCount == 0));
									start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
									if (state == stateNewPath)
									{
										state = stateManySegmentsNewPath;
									}
									else
									{
										System.Diagnostics.Debug.Assert((state == stateAddSegment));
										state = stateManySegmentsContinuePath;
									}
								}
								inCount++;
							}
							else
							{
								System.Diagnostics.Debug.Assert((state < stateManySegments));
								start_index = -1;
								inCount = 0;
							}
						}
						intersections.Clear(false);
					}
					else
					{
						// clip status is determined by other means
						if (clipStatus == 0)
						{
							// outside
							System.Diagnostics.Debug.Assert((AnalyseClipSegment_(polygon, polylineSeg, tolerance) == 0));
							System.Diagnostics.Debug.Assert((start_index < 0));
							System.Diagnostics.Debug.Assert((inCount == 0));
							continue;
						}
						if (clipStatus == 1)
						{
							System.Diagnostics.Debug.Assert((AnalyseClipSegment_(polygon, polylineSeg, tolerance) == 1));
							if (state == stateNewPath)
							{
								state = stateManySegmentsNewPath;
								start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
							}
							else
							{
								if (state == stateAddSegment)
								{
									state = stateManySegmentsContinuePath;
									start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
								}
								else
								{
									System.Diagnostics.Debug.Assert((state >= stateManySegments));
								}
							}
							inCount++;
							continue;
						}
					}
				}
				if (state >= stateManySegments)
				{
					resultPolylineImpl.AddSegmentsFromPath(polylineImpl, polylinePathIndex, start_index, inCount, state == stateManySegmentsNewPath);
					start_index = -1;
				}
			}
			return result_polyline;
		}
        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();
        }