/// <summary> /// Removes the shorts segments of the specified featureVertexInfo unless they are protected /// by the specified featureVertexInfo's CrackPoints. The minimum of the featureVertexInfo must /// be set. /// </summary> /// <param name="fromPolycurve"></param> /// <param name="featureVertexInfo"></param> /// <param name="use2DLengthOnly"></param> /// <param name="inPerimeter"></param> /// <returns></returns> private static void RemoveShortSegments( [NotNull] IPolycurve fromPolycurve, [NotNull] FeatureVertexInfo featureVertexInfo, bool use2DLengthOnly, [CanBeNull] IGeometry inPerimeter) { Assert.ArgumentNotNull(fromPolycurve, nameof(fromPolycurve)); Assert.ArgumentNotNull(featureVertexInfo, nameof(featureVertexInfo)); Assert.ArgumentCondition(featureVertexInfo.ShortSegments != null, "featureVertexInfo's ShortSegments is null"); Assert.ArgumentCondition(featureVertexInfo.MinimumSegmentLength != null, "featureVertexInfo's MinimumSegmentLength is null"); var notifications = new NotificationCollection(); Assert.NotNull(featureVertexInfo.MinimumSegmentLength, "Minimum segment length not set."); var minimumSegmentLength = (double)featureVertexInfo.MinimumSegmentLength; IList <esriSegmentInfo> shortSegments = featureVertexInfo.ShortSegments; SegmentReplacementUtils.RemoveShortSegments(fromPolycurve, shortSegments, minimumSegmentLength, use2DLengthOnly, featureVertexInfo.CrackPointCollection, inPerimeter, notifications); if (notifications.Count > 0) { _msg.WarnFormat("Feature {0}: {1}", GdbObjectUtils.ToString(featureVertexInfo.Feature), notifications.Concatenate(" ")); } }
/// <summary> /// Gets the segments from the provided ring that run along the provided alongPath. /// </summary> /// <param name="targetRing"></param> /// <param name="alongPath"></param> /// <returns></returns> private static IGeometry GetRingSubcurveAlong([NotNull] IRing targetRing, [NotNull] IPath alongPath) { IGeometry result = SegmentReplacementUtils.GetSegmentsBetween( alongPath.FromPoint, alongPath.ToPoint, targetRing); IGeometry highLevelResult = GeometryUtils.GetHighLevelGeometry(alongPath, true); IGeometry highLevelTarget = GeometryUtils.GetHighLevelGeometry(result, true); if (!GeometryUtils.InteriorIntersects(highLevelResult, highLevelTarget)) { // try the other side of the ring result = SegmentReplacementUtils.GetSegmentsBetween( alongPath.ToPoint, alongPath.FromPoint, targetRing); } Marshal.ReleaseComObject(highLevelResult); Marshal.ReleaseComObject(highLevelTarget); return(result); }
public void CanReplaceSegmentsWithNonZAwareReplacement() { ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95); IPolyline originalPolyline = GeometryFactory.CreatePolyline( GeometryFactory.CreatePath( GeometryFactory.CreatePoint(2600000, 1200000, 400, double.NaN, lv95), GeometryFactory.CreatePoint(2600010, 1200000, 410, double.NaN, lv95), GeometryFactory.CreatePoint(2600020, 1200000, 410, double.NaN, lv95), GeometryFactory.CreatePoint(2600030, 1200000, 420, double.NaN, lv95))); IPath replacement = GeometryFactory.CreatePath( GeometryFactory.CreatePoint(2600010, 1200000, 0, double.NaN, lv95), GeometryFactory.CreatePoint(2600015, 1200010, 500, double.NaN, lv95), GeometryFactory.CreatePoint(2600020, 1200000, 900, double.NaN, lv95)); // NOTE: The Z value of the first point of the replacement is used, however, the envelope of the resulting pathToReshape is not updated! // Hence it is crucial to insert the exact replacement end points into the geometry to reshape! IPolyline polyline = GeometryFactory.Clone(originalPolyline); var pathToReshape = (ISegmentCollection)((IGeometryCollection)polyline).Geometry[0]; GeometryUtils.MakeNonZAware(replacement); SegmentReplacementUtils.ReplaceSegments((IPath)pathToReshape, replacement, replacement.FromPoint, replacement.ToPoint); Assert.AreEqual(410, ((IPointCollection)pathToReshape).Point[1].Z); Assert.AreEqual(400, polyline.Envelope.ZMin, "Envelope is not inconsistent any more after segment replacment!"); // Now connect within a segment: IPoint firstPoint = replacement.FromPoint; firstPoint.X = 2600007; ((IPointCollection)replacement).UpdatePoint(0, firstPoint); polyline = GeometryFactory.Clone(originalPolyline); pathToReshape = (ISegmentCollection)((IGeometryCollection)polyline).Geometry[0]; GeometryUtils.MakeNonZAware(replacement); SegmentReplacementUtils.ReplaceSegments((IPath)pathToReshape, replacement, replacement.FromPoint, replacement.ToPoint); Assert.AreEqual(407, ((IPointCollection)pathToReshape).Point[1].Z); Assert.AreEqual(400, polyline.Envelope.ZMin, "Envelope is not inconsistent any more after segment replacment!"); }
private static ISegment GetConnectSegment([NotNull] IPath ofPath, [NotNull] IPoint sourceConnectPoint, double tolerance) { // Always gets the previous segment in case of To-Point (even for the 0th) int partIndex; int segmentIndex = SegmentReplacementUtils.GetSegmentIndex( ofPath, sourceConnectPoint, tolerance, out partIndex); ISegment sourceSegment = ((ISegmentCollection)ofPath).Segment[segmentIndex]; return(sourceSegment); }
private static void RemoveShortSegments(IGeometry geometry, double minimumLength, IPolygon scope) { Assert.ArgumentNotNaN(minimumLength, nameof(minimumLength)); Assert.ArgumentCondition(minimumLength > 0, "Minimum segment length must be larger than 0"); var polycurve = geometry as IPolycurve; Assert.ArgumentCondition(polycurve != null, "Geometry is null or not a polycurve"); SegmentReplacementUtils.RemoveShortSegments( polycurve, minimumLength, scope, null); }
private static void AssertCanJoin(IPolyline line1, IPolyline line2) { var path1 = (IPath)((IGeometryCollection)line1).get_Geometry(0); double totalLength = path1.Length + line2.Length; IPolyline resultPolyline = GeometryFactory.Clone(line2); var resultPath = (IPath)((IGeometryCollection)resultPolyline).get_Geometry(0); SegmentReplacementUtils.JoinConnectedPaths(path1, resultPath); GeometryUtils.Simplify(resultPolyline, true, true); Assert.AreEqual(totalLength, resultPath.Length); Assert.AreEqual(1, ((IGeometryCollection)resultPolyline).GeometryCount); }
private static ISegment GetConnectSegment([NotNull] IPath sourceReplacementPath, [NotNull] ICurve curveToReshape, [NotNull] IPoint sourceConnectPoint, double tolerance) { // Always gets the previous segment in case of To-Point (even for the 0th) int partIndex; int segmentIndex = SegmentReplacementUtils.GetSegmentIndex( curveToReshape, sourceConnectPoint, tolerance, out partIndex); ISegment sourceSegment = ((ISegmentCollection)curveToReshape).Segment[segmentIndex]; IGeometry highLevelSourceSegment = GeometryUtils.GetHighLevelGeometry( sourceSegment, true); // if the reshape line connects in the segment's interior, it should be always used bool sourceConnectPointIsSegmentToPoint = GeometryUtils.Touches(highLevelSourceSegment, sourceConnectPoint); IGeometry highLevelSourceReplacement = GeometryUtils.GetHighLevelGeometry(sourceReplacementPath, true); // however, if the reshape line connects in the segment's to-point, the segment that // is not part of the source replacement should be used -> it's part of the shared boundary if (sourceConnectPointIsSegmentToPoint && GeometryUtils.InteriorIntersects( highLevelSourceReplacement, highLevelSourceSegment)) { if (segmentIndex == ((ISegmentCollection)curveToReshape).SegmentCount - 1) { segmentIndex = 0; } else { segmentIndex++; } } sourceSegment = ((ISegmentCollection)curveToReshape).Segment[segmentIndex]; Marshal.ReleaseComObject(highLevelSourceSegment); Marshal.ReleaseComObject(highLevelSourceReplacement); return(sourceSegment); }
public void LearningTest_ReplaceSegmentsWithNonIdenticalConnectPointsZs() { ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95); IPolyline originalPolyline = GeometryFactory.CreatePolyline( GeometryFactory.CreatePath( GeometryFactory.CreatePoint(2600000, 1200000, 400, double.NaN, lv95), GeometryFactory.CreatePoint(2600010, 1200000, 405, double.NaN, lv95), GeometryFactory.CreatePoint(2600020, 1200000, 410, double.NaN, lv95), GeometryFactory.CreatePoint(2600030, 1200000, 420, double.NaN, lv95))); IPath replacement = GeometryFactory.CreatePath( GeometryFactory.CreatePoint(2600010, 1200000, 0, double.NaN, lv95), GeometryFactory.CreatePoint(2600015, 1200010, 500, double.NaN, lv95), GeometryFactory.CreatePoint(2600020, 1200000, 900, double.NaN, lv95)); // NOTE: The Z value of the first point of the replacement is used, however, the envelope of the resulting pathToReshape is not updated! // Hence it is crucial to insert the exact replacement end points into the geometry to reshape! IPolyline polyline = GeometryFactory.Clone(originalPolyline); var pathToReshape = (ISegmentCollection)((IGeometryCollection)polyline).Geometry[0]; pathToReshape.ReplaceSegmentCollection(1, 2, (ISegmentCollection)replacement); // This makes no difference: //pathToReshape.SegmentsChanged(); Assert.AreEqual(0, ((IPointCollection)pathToReshape).Point[1].Z); Assert.AreEqual(400, polyline.Envelope.ZMin, "Envelope is not inconsistent any more after ArcObjects segment replacment!"); // Make sure this does not happen in SegmentReplacementUtils polyline = GeometryFactory.Clone(originalPolyline); pathToReshape = (ISegmentCollection)((IGeometryCollection)polyline).Geometry[0]; SegmentReplacementUtils.ReplaceSegments((IPath)pathToReshape, replacement, replacement.FromPoint, replacement.ToPoint); Assert.AreEqual(0, ((IPointCollection)pathToReshape).Point[1].Z); Assert.AreEqual(0, polyline.Envelope.ZMin, "Envelope is inconsistent after SegmentReplacementUtils.ReplaceSegments!"); }
public void CanGetSegmentIndexRing() { const double xyTolerance = 0.0125; IPolygon poly = GeometryFactory.CreatePolygon(1000, 2000, 1500, 2500); poly.SpatialReference = CreateSpatialReference(xyTolerance, 0.0125); var ring = (IRing)((IGeometryCollection)poly).get_Geometry(0); IPoint searchPoint = new PointClass(); searchPoint.PutCoords(234, 34675); int partIndex; int?resultIndex = SegmentReplacementUtils.GetSegmentIndex( ring, searchPoint, xyTolerance, out partIndex, true, true); Assert.IsNull(resultIndex, "Point is not on geometry but segment index returned."); searchPoint.PutCoords(1000, 2000); resultIndex = SegmentReplacementUtils.GetSegmentIndex( ring, searchPoint, xyTolerance, out partIndex, true, true); Assert.IsNotNull(resultIndex, "Point is on geometry but segment index not found."); Assert.AreEqual(0, resultIndex); resultIndex = SegmentReplacementUtils.GetSegmentIndex( ring, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(3, resultIndex); searchPoint.PutCoords(1000, 2500); resultIndex = SegmentReplacementUtils.GetSegmentIndex( ring, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(1, resultIndex); searchPoint.PutCoords(1500, 2000); resultIndex = SegmentReplacementUtils.GetSegmentIndex( ring, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(3, resultIndex); }
public void CanGetPathSegmentsBetweenPoints() { const string xmlPath = @"<Path xsi:type='typens:Path' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:typens='http://www.esri.com/schemas/ArcGIS/10.1'><PointArray xsi:type='typens:ArrayOfPoint'><Point xsi:type='typens:PointN'><X>2744261.7537500001</X><Y>1201884.120000001</Y><SpatialReference xsi:type='typens:ProjectedCoordinateSystem'><WKT>PROJCS["CH1903+_LV95",GEOGCS["GCS_CH1903+",DATUM["D_CH1903+",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["False_Easting",2600000.0],PARAMETER["False_Northing",1200000.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Azimuth",90.0],PARAMETER["Longitude_Of_Center",7.439583333333333],PARAMETER["Latitude_Of_Center",46.95240555555556],UNIT["Meter",1.0],AUTHORITY["EPSG",2056]]</WKT><XOrigin>-27386400</XOrigin><YOrigin>-32067900</YOrigin><XYScale>140996569.55187955</XYScale><ZOrigin>-100000</ZOrigin><ZScale>800</ZScale><MOrigin>-100000</MOrigin><MScale>10000</MScale><XYTolerance>0.0025000000000000001</XYTolerance><ZTolerance>0.012500000000000001</ZTolerance><MTolerance>0.001</MTolerance><HighPrecision>true</HighPrecision><WKID>2056</WKID><LatestWKID>2056</LatestWKID></SpatialReference></Point><Point xsi:type='typens:PointN'><X>2744255.8000000007</X><Y>1201848.4012500048</Y><SpatialReference xsi:type='typens:ProjectedCoordinateSystem'><WKT>PROJCS["CH1903+_LV95",GEOGCS["GCS_CH1903+",DATUM["D_CH1903+",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["False_Easting",2600000.0],PARAMETER["False_Northing",1200000.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Azimuth",90.0],PARAMETER["Longitude_Of_Center",7.439583333333333],PARAMETER["Latitude_Of_Center",46.95240555555556],UNIT["Meter",1.0],AUTHORITY["EPSG",2056]]</WKT><XOrigin>-27386400</XOrigin><YOrigin>-32067900</YOrigin><XYScale>140996569.55187955</XYScale><ZOrigin>-100000</ZOrigin><ZScale>800</ZScale><MOrigin>-100000</MOrigin><MScale>10000</MScale><XYTolerance>0.0025000000000000001</XYTolerance><ZTolerance>0.012500000000000001</ZTolerance><MTolerance>0.001</MTolerance><HighPrecision>true</HighPrecision><WKID>2056</WKID><LatestWKID>2056</LatestWKID></SpatialReference></Point></PointArray></Path>"; var path = (IPath)GeometryUtils.FromXmlString(xmlPath); IPoint startPoint = path.FromPoint; IPoint endPoint = new PointClass(); path.QueryPoint(esriSegmentExtension.esriNoExtension, 2.1881204836952222, false, endPoint); // Not Z aware: Assert.IsFalse(GeometryUtils.IsZAware(path)); ICurve result = SegmentReplacementUtils.GetCurveBetween(startPoint, endPoint, path); Assert.IsFalse(GeometryUtils.IsZAware(result)); // Z-aware but not simple: // The input must be Z-aware and Z-simple GeometryUtils.MakeZAware(path); Assert.IsTrue(((IZAware)path).ZAware); Assert.IsFalse(((IZAware)path).ZSimple); result = SegmentReplacementUtils.GetCurveBetween(startPoint, endPoint, path); // result is also Z-aware and not Z-simple: Assert.IsTrue(GeometryUtils.IsZAware(result)); Assert.IsFalse(((IZAware)result).ZSimple); // Z aware and simple: GeometryUtils.SimplifyZ(path); Assert.IsTrue(((IZAware)path).ZAware); Assert.IsTrue(((IZAware)path).ZSimple); result = SegmentReplacementUtils.GetCurveBetween(startPoint, endPoint, path); // result is also Z-aware and Z-simple: Assert.IsTrue(GeometryUtils.IsZAware(result)); Assert.IsTrue(((IZAware)result).ZSimple); }
private static IPolyline TryGetAdjacentSegmentsAsPolyline( [NotNull] IPolygon polygon, [NotNull] IPoint startingAt) { double xyTolerance = GeometryUtils.GetXyTolerance(startingAt); int partIdx; const bool allowNoMatch = true; IList <int> adjacentSegments = SegmentReplacementUtils.GetAdjacentSegmentIndexes( polygon, startingAt, xyTolerance, out partIdx, allowNoMatch); if (adjacentSegments.Count == 0) { return(null); } var segmentList = new List <ISegment>(); foreach (int segmentIdx in adjacentSegments) { ISegment segment = GeometryUtils.GetSegment((ISegmentCollection)polygon, partIdx, segmentIdx); segmentList.Add(GeometryFactory.Clone(segment)); } if (segmentList.Count == 0) { return(null); } ISegment[] segments = segmentList.ToArray(); // create a polyline IPolyline result = GeometryFactory.CreateEmptyPolyline(polygon); GeometryUtils.GeometryBridge.AddSegments((ISegmentCollection)result, ref segments); GeometryUtils.Simplify(result); return(result); }
public void CanInsertVertexIntoPolyline() { IPolyline polyline = GeometryFactory.CreatePolyline(1000, 2000, 1500, 2500); ISpatialReference lv95 = CreateSpatialReference(0.0125, 0.0125); polyline.SpatialReference = lv95; IPoint newPoint = GeometryFactory.CreatePoint(1250, 2250, lv95); SegmentReplacementUtils.InsertVertex(newPoint, 0, 0, (ISegmentCollection)polyline); Assert.AreEqual(2, ((ISegmentCollection)polyline).SegmentCount); newPoint = GeometryFactory.CreatePoint(1400, 2400, lv95); SegmentReplacementUtils.InsertVertex(newPoint, 1, 0, (ISegmentCollection)polyline); Assert.AreEqual(3, ((ISegmentCollection)polyline).SegmentCount); }
private void RemoveStitchPoints(IEnumerable <IGeometry> geometriesToReshape) { // TODO: maintain the stitch points by geometry to reshape if (_stitchPoints == null) { return; } foreach (IGeometry geometry in geometriesToReshape) { foreach (KeyValuePair <IPoint, ISegment> keyValuePair in _stitchPoints) { IPoint stitchPoint = keyValuePair.Key; ISegment replacementSegment = keyValuePair.Value; SegmentReplacementUtils.TryReplaceSegments((IPolycurve)geometry, stitchPoint, replacementSegment); } } }
private IPath GetReplacedSegmentsForOtherGeometry( [NotNull] IGeometry geometryToReshape, [NotNull] IPoint betweenSourceIntersectionPoint, [NotNull] IPoint andTargetIntersectionPoint) { Assert.NotNull(_individualReshapes); foreach ( KeyValuePair <IGeometry, IList <ReshapeInfo> > individualReshape in _individualReshapes) { if (individualReshape.Key == geometryToReshape) { continue; } foreach (ReshapeInfo reshapeInfo in individualReshape.Value) { IPath replacedSegments = reshapeInfo.ReplacedSegments; if (replacedSegments != null) { IGeometry highLevelReplacedSegments = GeometryUtils.GetHighLevelGeometry(replacedSegments, true); if ( GeometryUtils.Intersects(highLevelReplacedSegments, betweenSourceIntersectionPoint) && GeometryUtils.Intersects(highLevelReplacedSegments, andTargetIntersectionPoint)) { return(SegmentReplacementUtils.GetSegmentsBetween( betweenSourceIntersectionPoint, andTargetIntersectionPoint, replacedSegments)); } } } } return(null); }
private IPath CalculateSourceTargetPointsConnectLine(IPoint sourceConnectPoint, IPoint targetConnectPoint) { IPath result; var unionReplacedPolyline = (IPolyline)GeometryUtils.GetHighLevelGeometry(_unionReshapeInfo.ReplacedSegments); if (GeometryUtils.Intersects(targetConnectPoint, unionReplacedPolyline)) { // use the connection along the replaced segments result = SegmentReplacementUtils.GetSegmentsBetween( sourceConnectPoint, targetConnectPoint, _unionReshapeInfo.ReplacedSegments); } else { result = GeometryFactory.CreatePath(sourceConnectPoint, targetConnectPoint); } return(result); }
private static IPath GetChangedSegments(ReshapeInfo reshapeInfo, RingReshapeSideOfLine proposedSide) { IPath replacedSegments; if (reshapeInfo.ReplacedSegments == null) { var ringToReshape = (IRing)reshapeInfo.GetGeometryPartToReshape(); IPath cutReshapePath = Assert.NotNull(reshapeInfo.CutReshapePath).Path; replacedSegments = SegmentReplacementUtils.GetSegmentsToReplace( ringToReshape, cutReshapePath.FromPoint, cutReshapePath.ToPoint, proposedSide); } else { replacedSegments = reshapeInfo.ReplacedSegments; } return(replacedSegments); }
public void CanInsertVertexIntoPolygon() { ISpatialReference lv95 = CreateSpatialReference(0.0125, 0.0125); IPolygon polygon = GeometryFactory.CreatePolygon(1000, 2000, 1500, 2500, lv95); GeometryUtils.Simplify(polygon, false); Assert.AreEqual(4, ((ISegmentCollection)polygon).SegmentCount); IPoint newPoint = GeometryFactory.CreatePoint(1250, 2000, lv95); SegmentReplacementUtils.InsertVertex(newPoint, 3, 0, (ISegmentCollection)polygon); Assert.AreEqual(5, ((ISegmentCollection)polygon).SegmentCount); newPoint = GeometryFactory.CreatePoint(1000, 2250, lv95); SegmentReplacementUtils.InsertVertex(newPoint, 0, 0, (ISegmentCollection)polygon); Assert.AreEqual(6, ((ISegmentCollection)polygon).SegmentCount); }
public void CanGetSegmentIndexMultipartPolygon() { const double xyTolerance = 0.0125; IPolygon poly = GeometryFactory.CreatePolygon(1000, 2000, 1500, 2500); IGeometry hole = GeometryFactory.CreatePolygon(1100, 2100, 1400, 2400); ((IGeometryCollection)poly).AddGeometryCollection((IGeometryCollection)hole); poly.SpatialReference = CreateSpatialReference(xyTolerance, 0.0125); GeometryUtils.Simplify(poly); IPoint searchPoint = new PointClass(); searchPoint.PutCoords(234, 34675); int partIndex; int?resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, true, true); Assert.IsNull(resultIndex, "Point is not on geometry but segment index returned."); // 1. point, segment from-point searchPoint.PutCoords(1000, 2000); resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, true, true); Assert.IsNotNull(resultIndex, "Point is on geometry but segment index not found."); Assert.AreEqual(0, resultIndex); Assert.AreEqual(0, partIndex); // 1. point, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(3, resultIndex); Assert.AreEqual(0, partIndex); // 2. point, segment from-point searchPoint.PutCoords(1000, 2500); resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(1, resultIndex); Assert.AreEqual(0, partIndex); // 2. point, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(0, resultIndex); Assert.AreEqual(0, partIndex); // 3. point, segment from-point searchPoint.PutCoords(1500, 2500); resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(2, resultIndex); Assert.AreEqual(0, partIndex); // 3. point, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(1, resultIndex); Assert.AreEqual(0, partIndex); // 4. point, segment from-point searchPoint.PutCoords(1500, 2000); resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(3, resultIndex); Assert.AreEqual(0, partIndex); // 4. point, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(2, resultIndex); Assert.AreEqual(0, partIndex); // 1. point of inner ring, segment from-point searchPoint.PutCoords(1100, 2100); resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(0, resultIndex); Assert.AreEqual(1, partIndex); // 1. point of inner ring, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(3, resultIndex); Assert.AreEqual(1, partIndex); // 2. point of inner ring, segment from-point searchPoint.PutCoords(1400, 2100); resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(1, resultIndex); Assert.AreEqual(1, partIndex); // 2. point of inner ring, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(0, resultIndex); Assert.AreEqual(1, partIndex); // 3. point of inner ring, segment from-point searchPoint.PutCoords(1400, 2400); resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(2, resultIndex); Assert.AreEqual(1, partIndex); // 3. point of inner ring, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(1, resultIndex); Assert.AreEqual(1, partIndex); // 4. point of inner ring, segment from-point searchPoint.PutCoords(1100, 2400); resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(3, resultIndex); Assert.AreEqual(1, partIndex); // 4. point of inner ring, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( poly, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(2, resultIndex); Assert.AreEqual(1, partIndex); }
private static IPolyline GetTargetSegmentsAlong( [NotNull] IPolyline targetPolyline, [NotNull] IPolyline alongPolyline, double originalTolerance) { // NOTE: The targetPolyline must be simplified i.e. the adjacent parts should be merged. var exactDifferences = (IGeometryCollection)GeometryFactory.CreateEmptyGeometry(alongPolyline); foreach (IPath differencePath in GeometryUtils.GetPaths(alongPolyline)) { IPath targetPath = GetUniqueTargetPathRunningAlong( targetPolyline, differencePath, originalTolerance); // NOTE: Sometimes, especially with non-linear segments and non-micro-resolution, this logic does not work because // the difference between non-linear geometries can look extremely weird (i.e. incorrect multiparts) // See CanReshapeAlongNonLinearSegmentsPolygonCircleWithMinimumTolerance() in GeometryReshaperTest if (targetPath == null) { _msg.DebugFormat( "Unable to use exact target geometry, because no unique target path found running along {0}. The standard difference (using minimum tolerance) is used instead.", GeometryUtils.ToString(differencePath)); return(alongPolyline); } Assert.NotNull(targetPath, "No target part found when searching with the difference part"); IGeometry exactDifferencePart; if (targetPath.IsClosed) { if (differencePath.IsClosed) { exactDifferencePart = GeometryFactory.Clone(targetPath); } else { IRing targetRing = GeometryFactory.CreateRing(targetPath); exactDifferencePart = GetRingSubcurveAlong(targetRing, differencePath); } } else { exactDifferencePart = SegmentReplacementUtils.GetSegmentsBetween( differencePath.FromPoint, differencePath.ToPoint, targetPath); } exactDifferences.AddGeometry(exactDifferencePart); } var result = (IPolyline)exactDifferences; GeometryUtils.Simplify(result, true, true); return(result); }
public void CanGetSegmentIndexMultipartPolyline() { const double xyTolerance = 0.0125; IPolyline polyline = GeometryFactory.CreatePolyline(1000, 2000, 1500, 2500); ISpatialReference lv95 = CreateSpatialReference(0.0125, 0.0125); polyline.SpatialReference = lv95; object missing = Type.Missing; ((IPointCollection)polyline).AddPoint( GeometryFactory.CreatePoint(2000, 3000), ref missing, ref missing); IGeometry secondLine = GeometryFactory.CreatePolyline(5000, 8000, 5500, 8500); ((IPointCollection)secondLine).AddPoint( GeometryFactory.CreatePoint(6000, 9000), ref missing, ref missing); ((IGeometryCollection)polyline).AddGeometryCollection( (IGeometryCollection)secondLine); GeometryUtils.Simplify(polyline); IPoint searchPoint = new PointClass(); searchPoint.PutCoords(234, 34675); int partIndex; int?resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, true, true); Assert.IsNull(resultIndex, "Point is not on geometry but non-null segment index returned."); // 1. point, segment from-point searchPoint.PutCoords(1000, 2000); resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, true, true); Assert.IsNotNull(resultIndex, "Point is on geometry but segment index not found."); Assert.AreEqual(0, resultIndex); Assert.AreEqual(0, partIndex); // 1. point, segment to-point (actually incorrect parameter combination) resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(0, resultIndex); Assert.AreEqual(0, partIndex); // 2. point, segment from-point searchPoint.PutCoords(1500, 2500); resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(1, resultIndex); Assert.AreEqual(0, partIndex); // 2. point, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(0, resultIndex); Assert.AreEqual(0, partIndex); // 3. point, segment from-point (actually incorrect parameter combination) searchPoint.PutCoords(2000, 3000); resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(1, resultIndex); Assert.AreEqual(0, partIndex); // 3. point, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(1, resultIndex); Assert.AreEqual(0, partIndex); // 1. point of second, segment from-point searchPoint.PutCoords(5000, 8000); resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(0, resultIndex); Assert.AreEqual(1, partIndex); // 1. point of inner ring, segment to-point (incorrect parameter combination) resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(0, resultIndex); Assert.AreEqual(1, partIndex); // 2. point of inner ring, segment from-point searchPoint.PutCoords(5500, 8500); resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(1, resultIndex); Assert.AreEqual(1, partIndex); // 2. point of inner ring, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(0, resultIndex); Assert.AreEqual(1, partIndex); // 3. point of inner ring, segment from-point (actually incorrect parameter combination) searchPoint.PutCoords(6000, 9000); resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, true, true); Assert.AreEqual(1, resultIndex); Assert.AreEqual(1, partIndex); // 3. point of inner ring, segment to-point resultIndex = SegmentReplacementUtils.GetSegmentIndex( polyline, searchPoint, xyTolerance, out partIndex, false, true); Assert.AreEqual(1, resultIndex); Assert.AreEqual(1, partIndex); }