Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SnapRoundingNoder to use tolerance in noding #802

Merged
merged 1 commit into from
Nov 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,33 +43,21 @@
*/
public class SnapRoundingIntersectionAdder
implements SegmentIntersector
{
/**
* The division factor used to determine
* nearness distance tolerance for interior intersection detection.
*/
private static final int NEARNESS_FACTOR = 100;

{
private final LineIntersector li;
private final List<Coordinate> intersections;
private final PrecisionModel precModel;
private final double nearnessTol;


/**
* Creates an intersector which finds all snapped interior intersections,
* and adds them as nodes.
*
* @param pm the precision mode to use
* @param nearnessTol the intersection distance tolerance
*/
public SnapRoundingIntersectionAdder(PrecisionModel pm)
public SnapRoundingIntersectionAdder(double nearnessTol)
{
precModel = pm;
/**
* Nearness distance tolerance is a small fraction of the snap grid size
*/
double snapGridSize = 1.0 / precModel.getScale();
nearnessTol = snapGridSize / NEARNESS_FACTOR;
this.nearnessTol = nearnessTol;

/**
* Intersections are detected and computed using full precision.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@
public class SnapRoundingNoder
implements Noder
{
/**
* The division factor used to determine
* nearness distance tolerance for intersection detection.
*/
private static final int NEARNESS_FACTOR = 100;

private final PrecisionModel pm;
private final HotPixelIndex pixelIndex;

Expand Down Expand Up @@ -111,9 +117,14 @@ private List<NodedSegmentString> snapRound(Collection<NodedSegmentString> segStr
*/
private void addIntersectionPixels(Collection<NodedSegmentString> segStrings)
{
SnapRoundingIntersectionAdder intAdder = new SnapRoundingIntersectionAdder(pm);
MCIndexNoder noder = new MCIndexNoder();
noder.setSegmentIntersector(intAdder);
/**
* nearness tolerance is a small fraction of the grid size.
*/
double snapGridSize = 1.0 / pm.getScale();
double nearnessTol = snapGridSize / NEARNESS_FACTOR;

SnapRoundingIntersectionAdder intAdder = new SnapRoundingIntersectionAdder(nearnessTol);
MCIndexNoder noder = new MCIndexNoder(intAdder, nearnessTol);
noder.computeNodes(segStrings);
List<Coordinate> intPts = intAdder.getIntersections();
pixelIndex.addNodes(intPts);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,16 @@ public void testVertexNearHorizSegNotNoded() {
checkRounding(wkt, 1000000, expected);
}

/**
* Tests that MCIndexNoder tolerance is set correctly.
* See https://trac.osgeo.org/geos/ticket/1127 and https://github.com/libgeos/geos/pull/504
*/
public void testMCIndexNoderTolerance() {
String wkt = "LINESTRING (3670939.6336634574 3396937.3777869204, 3670995.4715200397 3396926.0316904164, 3671077.280213823 3396905.4302639295, 3671203.8838707027 3396908.120176068, 3671334.962571111 3396904.8310892633, 3670037.299066126 3396904.8310892633, 3670037.299066126 3398075.9808747065, 3670939.6336634574 3396937.3777869204)";
String expected = "MULTILINESTRING ((3670776.0631373483 3397212.0584320477, 3670776.0631373483 3396600.058421521), (3670776.0631373483 3396600.058421521, 3671388.063147875 3396600.058421521), (3671388.063147875 3396600.058421521, 3671388.063147875 3397212.0584320477), (3671388.063147875 3397212.0584320477, 3671388.063147875 3396600.058421521), (3671388.063147875 3396600.058421521, 3671388.063147875 3397212.0584320477), (3671388.063147875 3397212.0584320477, 3671388.063147875 3396600.058421521), (3671388.063147875 3396600.058421521, 3670776.0631373483 3396600.058421521), (3670776.0631373483 3396600.058421521, 3670164.063126822 3396600.058421521, 3670164.063126822 3397824.058442574, 3670776.0631373483 3397212.0584320477))";
checkRounding(wkt, 0.0016339869, expected);
}

void checkRounding(String wkt, double scale, String expectedWKT)
{
Geometry geom = read(wkt);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,19 @@ public void testKeepCollapsedMultiPolygon()
"POLYGON ((2 2, 2 1, 1 1, 1 2, 2 2))");
}

//-------------------------------------------------

/**
* Test issue showing bug in SnapRoundingNoder not passing tolerance to MCIndexNoder.
*
* See https://trac.osgeo.org/geos/ticket/1127
*/
public void testLargeGridsizeFail()
{
checkReduce(1.0/612, "POLYGON((3670939.6336634574 3396937.3777869204, 3670995.4715200397 3396926.0316904164, 3671077.280213823 3396905.4302639295, 3671203.8838707027 3396908.120176068, 3671334.962571111 3396904.8310892633, 3670037.299066126 3396904.8310892633, 3670037.299066126 3398075.9808747065, 3670939.6336634574 3396937.3777869204))",
"POLYGON ((3670164 3396600, 3670164 3397824, 3670776 3397212, 3670776 3396600, 3670164 3396600))");
}

//=======================================

private void checkReduce(
Expand Down