/// <summary> /// /// </summary> /// <param name="line0"></param> /// <param name="line1"></param> /// <param name="locGeom"></param> private void ComputeMinDistance(ILineString line0, ILineString line1, GeometryLocation[] locGeom) { if (line0.EnvelopeInternal.Distance(line1.EnvelopeInternal) > _minDistance) { return; } var coord0 = line0.Coordinates; var coord1 = line1.Coordinates; // brute force approach! for (int i = 0; i < coord0.Length - 1; i++) { for (int j = 0; j < coord1.Length - 1; j++) { double dist = DistanceComputer.SegmentToSegment( coord0[i], coord0[i + 1], coord1[j], coord1[j + 1]); if (dist < _minDistance) { _minDistance = dist; var seg0 = new LineSegment(coord0[i], coord0[i + 1]); var seg1 = new LineSegment(coord1[j], coord1[j + 1]); var closestPt = seg0.ClosestPoints(seg1); locGeom[0] = new GeometryLocation(line0, i, closestPt[0]); locGeom[1] = new GeometryLocation(line1, j, closestPt[1]); } if (_minDistance <= _terminateDistance) { return; } } } }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="pt"></param> /// <param name="locGeom"></param> private void ComputeMinDistance(ILineString line, IPoint pt, GeometryLocation[] locGeom) { if (line.EnvelopeInternal.Distance(pt.EnvelopeInternal) > _minDistance) { return; } var coord0 = line.Coordinates; var coord = pt.Coordinate; // brute force approach! for (int i = 0; i < coord0.Length - 1; i++) { double dist = DistanceComputer.PointToSegment(coord, coord0[i], coord0[i + 1]); if (dist < _minDistance) { _minDistance = dist; var seg = new LineSegment(coord0[i], coord0[i + 1]); var segClosestPoint = seg.ClosestPoint(coord); locGeom[0] = new GeometryLocation(line, i, segClosestPoint); locGeom[1] = new GeometryLocation(pt, 0, coord); } if (_minDistance <= _terminateDistance) { return; } } }
private void UpdateNearestLocationsPointLine(Coordinate pt, FacetSequence facetSeq, int i, Coordinate q0, Coordinate q1, GeometryLocation[] locs) { locs[0] = new GeometryLocation(_geom, _start, pt.Copy()); var seg = new LineSegment(q0, q1); var segClosestPoint = seg.ClosestPoint(pt); locs[1] = new GeometryLocation(facetSeq._geom, i, segClosestPoint.Copy()); }
private void UpdateNearestLocationsLineLine(int i, Coordinate p0, Coordinate p1, FacetSequence facetSeq, int j, Coordinate q0, Coordinate q1, GeometryLocation[] locs) { var seg0 = new LineSegment(p0, p1); var seg1 = new LineSegment(q0, q1); var closestPt = seg0.ClosestPoints(seg1); locs[0] = new GeometryLocation(_geom, i, closestPt[0].Copy()); locs[1] = new GeometryLocation(facetSeq._geom, j, closestPt[1].Copy()); }
/// <summary> /// /// </summary> private void ComputeContainmentDistance() { var locPtPoly = new GeometryLocation[2]; // test if either geometry has a vertex inside the other ComputeContainmentDistance(0, locPtPoly); if (_minDistance <= _terminateDistance) { return; } ComputeContainmentDistance(1, locPtPoly); }
private void ComputeContainmentDistance(GeometryLocation ptLoc, IPolygon poly, GeometryLocation[] locPtPoly) { var pt = ptLoc.Coordinate; // if pt is not in exterior, distance to geom is 0 if (Location.Exterior != _ptLocator.Locate(pt, poly)) { _minDistance = 0.0; locPtPoly[0] = ptLoc; locPtPoly[1] = new GeometryLocation(poly, pt); } }
private void ComputeContainmentDistance(IList <GeometryLocation> locs, ICollection <IGeometry> polys, GeometryLocation[] locPtPoly) { for (int i = 0; i < locs.Count; i++) { GeometryLocation loc = locs[i]; foreach (IPolygon t in polys) { ComputeContainmentDistance(loc, t, locPtPoly); if (_minDistance <= _terminateDistance) { return; } } } }
/// <summary> /// /// </summary> /// <param name="line0"></param> /// <param name="line1"></param> /// <param name="locGeom"></param> private void ComputeMinDistance(LineString line0, LineString line1, GeometryLocation[] locGeom) { if (line0.EnvelopeInternal.Distance(line1.EnvelopeInternal) > _minDistance) { return; } var coord0 = line0.Coordinates; var coord1 = line1.Coordinates; // brute force approach! for (int i = 0; i < coord0.Length - 1; i++) { // short-circuit if line segment is far from line var segEnv0 = new Envelope(coord0[i], coord0[i + 1]); if (segEnv0.Distance(line1.EnvelopeInternal) > _minDistance) { continue; } for (int j = 0; j < coord1.Length - 1; j++) { // short-circuit if line segments are far apart var segEnv1 = new Envelope(coord1[j], coord1[j + 1]); if (segEnv0.Distance(segEnv1) > _minDistance) { continue; } double dist = DistanceComputer.SegmentToSegment( coord0[i], coord0[i + 1], coord1[j], coord1[j + 1]); if (dist < _minDistance) { _minDistance = dist; var seg0 = new LineSegment(coord0[i], coord0[i + 1]); var seg1 = new LineSegment(coord1[j], coord1[j + 1]); var closestPt = seg0.ClosestPoints(seg1); locGeom[0] = new GeometryLocation(line0, i, closestPt[0]); locGeom[1] = new GeometryLocation(line1, j, closestPt[1]); } if (_minDistance <= _terminateDistance) { return; } } } }
/* * /// <summary> * /// * /// </summary> * /// <param name="locs"></param> * /// <param name="polys"></param> * /// <param name="locPtPoly"></param> * private void ComputeInside(IEnumerable<GeometryLocation> locs, IEnumerable<IPolygon> polys, GeometryLocation[] locPtPoly) * { * foreach (GeometryLocation loc in locs) * { * foreach (IPolygon poly in polys) * { * ComputeInside(loc, poly, locPtPoly); * if (_minDistance <= _terminateDistance) * return; * } * } * } * * /// <summary> * /// * /// </summary> * /// <param name="ptLoc"></param> * /// <param name="poly"></param> * /// <param name="locPtPoly"></param> * private void ComputeInside(GeometryLocation ptLoc, IPolygon poly, GeometryLocation[] locPtPoly) * { * Coordinate pt = ptLoc.Coordinate; * // if pt is not in exterior, distance to geom is 0 * if (Location.Exterior != _ptLocator.Locate(pt, poly)) * { * _minDistance = 0.0; * locPtPoly[0] = ptLoc; * GeometryLocation locPoly = new GeometryLocation(poly, pt); * locPtPoly[1] = locPoly; * return; * } * } * */ /// <summary> /// Computes distance between facets (lines and points) of input geometries. /// </summary> private void ComputeFacetDistance() { var locGeom = new GeometryLocation[2]; /* * Geometries are not wholely inside, so compute distance from lines and points * of one to lines and points of the other */ var lines0 = LinearComponentExtracter.GetLines(_geom[0]); var lines1 = LinearComponentExtracter.GetLines(_geom[1]); var pts0 = PointExtracter.GetPoints(_geom[0]); var pts1 = PointExtracter.GetPoints(_geom[1]); // exit whenever minDistance goes LE than terminateDistance ComputeMinDistanceLines(lines0, lines1, locGeom); UpdateMinDistance(locGeom, false); if (_minDistance <= _terminateDistance) { return; } locGeom[0] = null; locGeom[1] = null; ComputeMinDistanceLinesPoints(lines0, pts1, locGeom); UpdateMinDistance(locGeom, false); if (_minDistance <= _terminateDistance) { return; } locGeom[0] = null; locGeom[1] = null; ComputeMinDistanceLinesPoints(lines1, pts0, locGeom); UpdateMinDistance(locGeom, true); if (_minDistance <= _terminateDistance) { return; } locGeom[0] = null; locGeom[1] = null; ComputeMinDistancePoints(pts0, pts1, locGeom); UpdateMinDistance(locGeom, false); }
/// <summary> /// /// </summary> private void ComputeContainmentDistance() { var locPtPoly = new GeometryLocation[2]; ComputeContainmentDistance(0, locPtPoly); if (_minDistance <= _terminateDistance) { return; } ComputeContainmentDistance(1, locPtPoly); // test if either geometry has a vertex inside the other /* * IList<IPolygon> polys1 = PolygonExtracter.GetPolygons(_geom[1]); * if (polys1.Count > 0) * { * IList<GeometryLocation> insideLocs0 = ConnectedElementLocationFilter.GetLocations(_geom[0]); * ComputeInside(insideLocs0, polys1, locPtPoly); * if (_minDistance <= _terminateDistance) * { * _minDistanceLocation[0] = locPtPoly[0]; * _minDistanceLocation[1] = locPtPoly[1]; * return; * } * } * * IList<IPolygon> polys0 = PolygonExtracter.GetPolygons(_geom[0]); * if (polys0.Count > 0) * { * IList<GeometryLocation> insideLocs1 = ConnectedElementLocationFilter.GetLocations(_geom[1]); * ComputeInside(insideLocs1, polys0, locPtPoly); * if (_minDistance <= _terminateDistance) * { * // flip locations, since we are testing geom 1 VS geom 0 * _minDistanceLocation[0] = locPtPoly[1]; * _minDistanceLocation[1] = locPtPoly[0]; * return; * } * } */ }
/// <summary> /// /// </summary> /// <param name="points0"></param> /// <param name="points1"></param> /// <param name="locGeom"></param> private void ComputeMinDistancePoints(IEnumerable <IGeometry> points0, ICollection <IGeometry> points1, GeometryLocation[] locGeom) { foreach (IPoint pt0 in points0) { foreach (IPoint pt1 in points1) { double dist = pt0.Coordinate.Distance(pt1.Coordinate); if (dist < _minDistance) { _minDistance = dist; locGeom[0] = new GeometryLocation(pt0, 0, pt0.Coordinate); locGeom[1] = new GeometryLocation(pt1, 0, pt1.Coordinate); } if (_minDistance <= _terminateDistance) { return; } } } }
/// <summary> /// Computes the locations of the nearest points between this sequence /// and another sequence. /// The locations are presented in the same order as the input sequences. /// </summary> /// <returns>A pair of <see cref="GeometryLocation"/>s for the nearest points.</returns> public GeometryLocation[] NearestLocations(FacetSequence facetSeq) { bool isPoint = IsPoint; bool isPointOther = facetSeq.IsPoint; var locs = new GeometryLocation[2]; if (isPoint && isPointOther) { // DEVIATION (minor): JTS uses "new Coordinate(GetCoordinate(int))", which is worse // than "GetCoordinateCopy(int)" for two reasons: 1) doesn't copy M (or, in NTS, Z), // and 2) might allocate two Coordinate instances instead of one. var pt = _pts.GetCoordinateCopy(_start); var seqPt = facetSeq._pts.GetCoordinateCopy(facetSeq._start); locs[0] = new GeometryLocation(_geom, _start, pt); locs[1] = new GeometryLocation(facetSeq._geom, facetSeq._start, seqPt); } else if (isPoint) { var pt = _pts.GetCoordinateCopy(_start); ComputeDistancePointLine(pt, facetSeq, locs); } else if (isPointOther) { var seqPt = facetSeq._pts.GetCoordinateCopy(facetSeq._start); ComputeDistancePointLine(seqPt, this, locs); // unflip the locations (locs[0], locs[1]) = (locs[1], locs[0]); } else { ComputeDistanceLineLine(facetSeq, locs); } return(locs); }
/// <summary> /// /// </summary> /// <param name="locGeom"></param> /// <param name="flip"></param> private void UpdateMinDistance(GeometryLocation[] locGeom, bool flip) { // if not set then don't update if (locGeom[0] == null) return; if (flip) { _minDistanceLocation[0] = locGeom[1]; _minDistanceLocation[1] = locGeom[0]; } else { _minDistanceLocation[0] = locGeom[0]; _minDistanceLocation[1] = locGeom[1]; } }
/// <summary> /// /// </summary> /// <param name="points0"></param> /// <param name="points1"></param> /// <param name="locGeom"></param> private void ComputeMinDistancePoints(IEnumerable<IGeometry> points0, ICollection<IGeometry> points1, GeometryLocation[] locGeom) { foreach (IPoint pt0 in points0) { foreach (IPoint pt1 in points1) { var dist = pt0.Coordinate.Distance(pt1.Coordinate); if (dist < _minDistance) { _minDistance = dist; locGeom[0] = new GeometryLocation(pt0, 0, pt0.Coordinate); locGeom[1] = new GeometryLocation(pt1, 0, pt1.Coordinate); } if (_minDistance <= _terminateDistance) return; } } }
private void ComputeContainmentDistance(int polyGeomIndex, GeometryLocation[] locPtPoly) { int locationsIndex = 1 - polyGeomIndex; var polys = PolygonExtracter.GetPolygons(_geom[polyGeomIndex]); if (polys.Count > 0) { var insideLocs = ConnectedElementLocationFilter.GetLocations(_geom[locationsIndex]); ComputeContainmentDistance(insideLocs, polys, locPtPoly); if (_minDistance <= _terminateDistance) { // this assigment is determined by the order of the args in the computeInside call above _minDistanceLocation[locationsIndex] = locPtPoly[0]; _minDistanceLocation[polyGeomIndex] = locPtPoly[1]; } } }
/// <summary> /// /// </summary> /// <param name="lines0"></param> /// <param name="lines1"></param> /// <param name="locGeom"></param> private void ComputeMinDistanceLines(IEnumerable<IGeometry> lines0, ICollection<IGeometry> lines1, GeometryLocation[] locGeom) { foreach (ILineString line0 in lines0) { foreach (ILineString line1 in lines1) { ComputeMinDistance(line0, line1, locGeom); if (_minDistance <= _terminateDistance) return; } } }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="pt"></param> /// <param name="locGeom"></param> private void ComputeMinDistance(ILineString line, IPoint pt, GeometryLocation[] locGeom) { if (line.EnvelopeInternal.Distance(pt.EnvelopeInternal) > _minDistance) return; Coordinate[] coord0 = line.Coordinates; Coordinate coord = pt.Coordinate; // brute force approach! for (int i = 0; i < coord0.Length - 1; i++) { double dist = CGAlgorithms.DistancePointLine(coord, coord0[i], coord0[i + 1]); if (dist < _minDistance) { _minDistance = dist; LineSegment seg = new LineSegment(coord0[i], coord0[i + 1]); Coordinate segClosestPoint = seg.ClosestPoint(coord); locGeom[0] = new GeometryLocation(line, i, segClosestPoint); locGeom[1] = new GeometryLocation(pt, 0, coord); } if (_minDistance <= _terminateDistance) return; } }
/* /// <summary> /// /// </summary> /// <param name="locs"></param> /// <param name="polys"></param> /// <param name="locPtPoly"></param> private void ComputeInside(IEnumerable<GeometryLocation> locs, IEnumerable<IPolygon> polys, GeometryLocation[] locPtPoly) { foreach (GeometryLocation loc in locs) { foreach (IPolygon poly in polys) { ComputeInside(loc, poly, locPtPoly); if (_minDistance <= _terminateDistance) return; } } } /// <summary> /// /// </summary> /// <param name="ptLoc"></param> /// <param name="poly"></param> /// <param name="locPtPoly"></param> private void ComputeInside(GeometryLocation ptLoc, IPolygon poly, GeometryLocation[] locPtPoly) { Coordinate pt = ptLoc.Coordinate; // if pt is not in exterior, distance to geom is 0 if (Location.Exterior != _ptLocator.Locate(pt, poly)) { _minDistance = 0.0; locPtPoly[0] = ptLoc; GeometryLocation locPoly = new GeometryLocation(poly, pt); locPtPoly[1] = locPoly; return; } } */ /// <summary> /// Computes distance between facets (lines and points) of input geometries. /// </summary> private void ComputeFacetDistance() { var locGeom = new GeometryLocation[2]; /* * Geometries are not wholely inside, so compute distance from lines and points * of one to lines and points of the other */ var lines0 = LinearComponentExtracter.GetLines(_geom[0]); var lines1 = LinearComponentExtracter.GetLines(_geom[1]); var pts0 = PointExtracter.GetPoints(_geom[0]); var pts1 = PointExtracter.GetPoints(_geom[1]); // exit whenever minDistance goes LE than terminateDistance ComputeMinDistanceLines(lines0, lines1, locGeom); UpdateMinDistance(locGeom, false); if (_minDistance <= _terminateDistance) return; locGeom[0] = null; locGeom[1] = null; ComputeMinDistanceLinesPoints(lines0, pts1, locGeom); UpdateMinDistance(locGeom, false); if (_minDistance <= _terminateDistance) return; locGeom[0] = null; locGeom[1] = null; ComputeMinDistanceLinesPoints(lines1, pts0, locGeom); UpdateMinDistance(locGeom, true); if (_minDistance <= _terminateDistance) return; locGeom[0] = null; locGeom[1] = null; ComputeMinDistancePoints(pts0, pts1, locGeom); UpdateMinDistance(locGeom, false); }
private void ComputeContainmentDistance(GeometryLocation ptLoc, IPolygon poly, GeometryLocation[] locPtPoly) { var pt = ptLoc.Coordinate; // if pt is not in exterior, distance to geom is 0 if (Location.Exterior != _ptLocator.Locate(pt, poly)) { _minDistance = 0.0; locPtPoly[0] = ptLoc; locPtPoly[1] = new GeometryLocation(poly, pt); } }
private void ComputeContainmentDistance(IList<GeometryLocation> locs, ICollection<IGeometry> polys, GeometryLocation[] locPtPoly) { for (int i = 0; i < locs.Count; i++) { GeometryLocation loc = locs[i]; foreach (IPolygon t in polys) { ComputeContainmentDistance(loc, t, locPtPoly); if (_minDistance <= _terminateDistance) return; } } }
private void UpdateDistance(double dist, GeometryLocation loc0, GeometryLocation loc1, bool flip) { _minDistance = dist; var index = flip ? 1 : 0; _minDistanceLocation[index] = loc0; _minDistanceLocation[1 - index] = loc1; if (_minDistance < _terminateDistance) _isDone = true; }
/// <summary> /// /// </summary> /// <param name="lines"></param> /// <param name="points"></param> /// <param name="locGeom"></param> private void ComputeMinDistanceLinesPoints(IEnumerable<IGeometry> lines, ICollection<IGeometry> points, GeometryLocation[] locGeom) { foreach (ILineString line in lines) { foreach (IPoint pt in points) { ComputeMinDistance(line, pt, locGeom); if (_minDistance <= _terminateDistance) return; } } }
/// <summary> /// /// </summary> /// <param name="line0"></param> /// <param name="line1"></param> /// <param name="locGeom"></param> private void ComputeMinDistance(ILineString line0, ILineString line1, GeometryLocation[] locGeom) { if (line0.EnvelopeInternal.Distance(line1.EnvelopeInternal) > _minDistance) return; var coord0 = line0.Coordinates; var coord1 = line1.Coordinates; // brute force approach! for (var i = 0; i < coord0.Length - 1; i++) { for (var j = 0; j < coord1.Length - 1; j++) { var dist = CGAlgorithms.DistanceLineLine( coord0[i], coord0[i + 1], coord1[j], coord1[j + 1]); if (dist < _minDistance) { _minDistance = dist; var seg0 = new LineSegment(coord0[i], coord0[i + 1]); var seg1 = new LineSegment(coord1[j], coord1[j + 1]); var closestPt = seg0.ClosestPoints(seg1); locGeom[0] = new GeometryLocation(line0, i, closestPt[0]); locGeom[1] = new GeometryLocation(line1, j, closestPt[1]); } if (_minDistance <= _terminateDistance) return; } } }
/// <summary> /// /// </summary> private void ComputeContainmentDistance() { var locPtPoly = new GeometryLocation[2]; ComputeContainmentDistance(0, locPtPoly); if (_minDistance <= _terminateDistance) return; ComputeContainmentDistance(1, locPtPoly); // test if either geometry has a vertex inside the other /* IList<IPolygon> polys1 = PolygonExtracter.GetPolygons(_geom[1]); if (polys1.Count > 0) { IList<GeometryLocation> insideLocs0 = ConnectedElementLocationFilter.GetLocations(_geom[0]); ComputeInside(insideLocs0, polys1, locPtPoly); if (_minDistance <= _terminateDistance) { _minDistanceLocation[0] = locPtPoly[0]; _minDistanceLocation[1] = locPtPoly[1]; return; } } IList<IPolygon> polys0 = PolygonExtracter.GetPolygons(_geom[0]); if (polys0.Count > 0) { IList<GeometryLocation> insideLocs1 = ConnectedElementLocationFilter.GetLocations(_geom[1]); ComputeInside(insideLocs1, polys0, locPtPoly); if (_minDistance <= _terminateDistance) { // flip locations, since we are testing geom 1 VS geom 0 _minDistanceLocation[0] = locPtPoly[1]; _minDistanceLocation[1] = locPtPoly[0]; return; } } */ }