public HeightSegment(SegmentProxy segment) { _segment = segment; double z0 = segment.GetStart(true)[2]; double z1 = segment.GetStart(true)[2]; _height = (z0 + z1) / 2.0; }
protected override bool GetNextSegment(out double length, out double dz, out int partIndex, out int segmentIndex) { if (!_enumSegments.MoveNext()) { length = double.NaN; dz = double.NaN; partIndex = -1; segmentIndex = -1; return(false); } SegmentProxy segment = Assert.NotNull(_enumSegments.Current); partIndex = segment.PartIndex; segmentIndex = segment.SegmentIndex; length = segment.Length; double z0 = segment.GetStart(true)[2]; double z1 = segment.GetEnd(true)[2]; dz = z1 - z0; return(true); }
public override Pnt GetNearestVertex() { double fraction = Fraction; Pnt vertex = fraction < 0.5 ? _segmentProxy.GetStart(as3D: true) : _segmentProxy.GetEnd(as3D: true); return(vertex); }
private static double GetOffset([NotNull] Pnt pnt, [NotNull] SegmentProxy segmentProxy, out double fraction, out bool?onRightSide) { double?offset; fraction = SegmentUtils.GetClosestPointFraction( segmentProxy, pnt, out offset, out onRightSide, as3D: false); double distance2; if (fraction < 0) { distance2 = pnt.Dist2(segmentProxy.GetStart(as3D: false)); onRightSide = null; } else if (fraction > 1) { distance2 = pnt.Dist2(segmentProxy.GetEnd(as3D: false)); onRightSide = null; } else { if (!offset.HasValue) { Pnt s = segmentProxy.GetStart(as3D: false); Pnt e = segmentProxy.GetEnd(as3D: false); double vectorProd = (pnt - s).VectorProduct(s - e); onRightSide = vectorProd < 0; distance2 = pnt.Dist2(segmentProxy.GetPointAt(fraction, as3D: false)); } else { distance2 = 0; // offset has value and will be used as distance } } double distance = offset ?? Math.Sqrt(distance2); return(distance); }
private static double GetDistanceToVertices([NotNull] IPoint point, [NotNull] IFeature neighbourFeature, [NotNull] IPoint nearestPoint, double maxNeededDistance) { double minDistance2 = double.MaxValue; SegmentProxy nearestSegment = null; var isEndNearest = false; Pnt qaPoint = QaGeometryUtils.CreatePoint3D(point); IEnumerable <SegmentProxy> segments = EnumSegments(qaPoint, neighbourFeature, maxNeededDistance); foreach (SegmentProxy segment in segments) { if (GetNearest(qaPoint, segment.GetStart(false), ref minDistance2)) { nearestSegment = segment; isEndNearest = false; } if (GetNearest(qaPoint, segment.GetEnd(false), ref minDistance2)) { nearestSegment = segment; isEndNearest = true; } } double minDistance; if (nearestSegment != null) { minDistance = Math.Sqrt(minDistance2); if (minDistance <= maxNeededDistance) { Pnt nearest = !isEndNearest ? nearestSegment.GetStart(true) : nearestSegment.GetEnd(true); nearestPoint.PutCoords(nearest.X, nearest.Y); nearestPoint.Z = nearest[2]; } } else { minDistance = double.MaxValue; } return(minDistance); }
private bool IsHorizontal([NotNull] SegmentProxy segment) { double length = segment.Length; if (Math.Abs(length) < double.Epsilon) { return(false); } double z0 = segment.GetStart(true)[2]; double z1 = segment.GetEnd(true)[2]; double slopeAngle = Math.Atan2(Math.Abs(z1 - z0), length); bool isHorizontal = slopeAngle <= _horizontalToleranceRad; return(isHorizontal); }
public AzimuthSegment([NotNull] SegmentProxy segment, double xyResolution) { Segment = segment; _xyResolution = xyResolution; Pnt start = Segment.GetStart(false); Pnt end = Segment.GetEnd(false); double dx = end.X - start.X; double dy = end.Y - start.Y; Azimuth = Math.Atan2(dx, dy); // Azimuth is the angle to north if (Azimuth < 0) // the orientation must be ignored { Azimuth += Math.PI; } }
private static double GetDistanceToCurve( [NotNull] IPoint point, [NotNull] IFeature neighbourFeature, [NotNull] IPoint nearestPoint, double maxNeededDistance, out bool onRightSide) { var neighborCurve = (ICurve)neighbourFeature.Shape; if (UseQueryPointAndDistance) { const bool asRatio = false; double along = 0; double distance = 0; var rightSide = false; // TLMQA-292 (EBG - BB): most time spent here (> 90%) neighborCurve.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, point, asRatio, nearestPoint, ref along, ref distance, ref rightSide); onRightSide = rightSide; return(distance); } { double nearestDistance = maxNeededDistance * 1.01; bool? nearestOnRightSide = null; SegmentProxy nearestSegment = null; double nearestFraction = 0; double x; double y; point.QueryCoords(out x, out y); Pnt qaPoint = new Pnt2D(x, y); foreach (SegmentProxy segmentProxy in EnumSegments(qaPoint, neighbourFeature, maxNeededDistance)) { bool? onSegmentRightSide; double alongFraction; double offset = GetOffset(qaPoint, segmentProxy, out alongFraction, out onSegmentRightSide); if (offset <= nearestDistance) { if (!onSegmentRightSide.HasValue && !nearestOnRightSide.HasValue && nearestSegment != null) { nearestOnRightSide = GetOnRightSide( nearestSegment, nearestFraction, segmentProxy, alongFraction, neighborCurve); } else if (offset < nearestDistance) { nearestOnRightSide = onSegmentRightSide; } nearestDistance = offset; nearestSegment = segmentProxy; nearestFraction = alongFraction; } } if (nearestSegment != null) { double f = Math.Min(1, Math.Max(0, nearestFraction)); IPnt p = nearestSegment.GetPointAt(f, as3D: true); nearestPoint.PutCoords(p.X, p.Y); nearestPoint.Z = p[2]; if (!nearestOnRightSide.HasValue) { // Extend segment lineary to determine right side Pnt s = nearestSegment.GetStart(as3D: false); Pnt e = nearestSegment.GetEnd(as3D: false); if (nearestFraction >= 1) { nearestOnRightSide = (e - s).VectorProduct(e - qaPoint) > 0; } else if (nearestFraction <= 0) { nearestOnRightSide = (e - s).VectorProduct(s - qaPoint) > 0; } } } onRightSide = nearestOnRightSide ?? false; return(nearestDistance); } }
private void Initialize() { _indexedMultipatch = GetAdaptedMultiPatch(); IMultiPatch multiPatch = _indexedMultipatch.BaseGeometry; _verticalFaceSegments = new List <SegmentProxy>(); var patches = (IGeometryCollection)multiPatch; var verticalPatchParts = new Dictionary <int, List <int> >(); int patchCount = patches.GeometryCount; for (int patchIndex = 0; patchIndex < patchCount; patchIndex++) { List <int> partIndexes = _indexedMultipatch.GetPartIndexes(patchIndex); foreach (int partIndex in partIndexes) { int partSegmentCount = _indexedMultipatch.GetPartSegmentCount(partIndex); var segments = new List <SegmentProxy>(partSegmentCount); for (int segmentIndex = 0; segmentIndex < partSegmentCount; segmentIndex++) { segments.Add( _indexedMultipatch.GetSegment(partIndex, segmentIndex)); } Plane plane = QaGeometryUtils.CreatePlane( (IEnumerable <SegmentProxy>)segments); if (Math.Abs(plane.GetNormalVector().Z) < double.Epsilon) { List <int> verticalParts; if (!verticalPatchParts.TryGetValue( patchIndex, out verticalParts)) { verticalParts = new List <int>(); verticalPatchParts.Add(patchIndex, verticalParts); } verticalParts.Add(partIndex); _verticalFaceSegments.AddRange(segments); } } } if (verticalPatchParts.Count > 0) { object missing = Type.Missing; IMultiPatch nonVerticalMultiPatch = new MultiPatchClass { SpatialReference = multiPatch.SpatialReference }; for (int patchIndex = 0; patchIndex < patchCount; patchIndex++) { List <int> verticalParts; IGeometry patch = ((IGeometryCollection)multiPatch).Geometry[patchIndex]; if (!verticalPatchParts.TryGetValue( patchIndex, out verticalParts)) { IGeometry clone = GeometryFactory.Clone(patch); ((IGeometryCollection)nonVerticalMultiPatch).AddGeometry( clone, ref missing, ref missing); var ring = patch as IRing; if (ring != null) { bool isBeginning = false; esriMultiPatchRingType ringType = multiPatch.GetRingType(ring, ref isBeginning); nonVerticalMultiPatch.PutRingType( (IRing)clone, ringType); } } else { if (patch is IRing) { continue; } List <int> partIndexes = _indexedMultipatch.GetPartIndexes(patchIndex); foreach (int partIndex in partIndexes) { if (verticalParts.Contains(partIndex)) { continue; } int partSegmentCount = _indexedMultipatch.GetPartSegmentCount(partIndex); var points = new List <WKSPointZ>(3); for (int segmentIndex = 0; segmentIndex < partSegmentCount; segmentIndex++) { SegmentProxy segment = _indexedMultipatch.GetSegment( partIndex, segmentIndex); const bool as3D = true; Pnt p = segment.GetStart(as3D); points.Add( WKSPointZUtils.CreatePoint(p.X, p.Y, p[2])); } IRing ring = CreateRing(points); ((IGeometryCollection)nonVerticalMultiPatch).AddGeometry( ring, ref missing, ref missing); } } } _nonVerticalMultipatch = nonVerticalMultiPatch; } else { _nonVerticalMultipatch = multiPatch; } }