/// <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 = 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; } Coordinate[] coord0 = line.Coordinates; Coordinate 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; 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; } } }
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="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) { 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; } } } }