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

@turf/booleanCrosses #796

Merged
merged 6 commits into from
Jun 19, 2017
Merged

@turf/booleanCrosses #796

merged 6 commits into from
Jun 19, 2017

Conversation

rowanwins
Copy link
Member

  • Use a meaningful title for the pull request. Include the name of the package modified.
  • Have read How To Contribute.
  • Run npm test at the sub modules where changes have occurred.
  • Run npm run lint to ensure code style at the turf module level.
  • Overview description of proposed module.
  • Include JSDocs with a basic example.
  • Execute ./scripts/generate-readmes to create README.md.
  • Add yourself to contributors in package.json using "Full Name <@github Username>".

Gday @DenisCarriere

Well I think this is hopefully almost done.

  • There are 20+ tests (although realistically I think we could still do more!)
  • I've run the tests against shapely and confirmed the same results
    The benchmark results are looking not too bad although I think our line intersections algorithm could be improved
  • I suggest we make the name booleanCrosses, as 'crosses' (rather than cross) is the name of the predicate everywhere else
 * Benchmark Results
 * LineDoesNotCrossButTouches x 71,945 ops/sec ±2.04% (71 runs sampled)
 * LineDoesNotCrossLine x 88,084 ops/sec ±2.56% (70 runs sampled)
 * LineDoesNotCrossPolygon x 86,024 ops/sec ±2.80% (71 runs sampled)
 * MultiPointNotCrossLine x 11,976,750 ops/sec ±1.61% (93 runs sampled)
 * MultiPointNotCrossLineEnd x 10,191,949 ops/sec ±3.51% (85 runs sampled)
 * LineCrossesLine x 68,764 ops/sec ±2.53% (72 runs sampled)
 * LineCrossesPolygon x 49,268 ops/sec ±2.70% (80 runs sampled)
 * LineCrossesPolygonPartial x 63,313 ops/sec ±2.87% (71 runs sampled)

}
throw new Error('feature2 ' + type2 + ' geometry not supported');
default:
throw new Error('feature1 ' + type1 + ' geometry not supported');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type1 cannot be Point/Polygon/MultiLineString? or you are still working on this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Crosses only supports a very limited set of types, see this link. So as far as I'm concerned I think they're all covered off

@DenisCarriere
Copy link
Member

DenisCarriere commented Jun 17, 2017

👍 that's great that we've got Shapely validation, do you have that code on GitHub anywhere?

Found it: https://gist.github.com/rowanwins/e23208be1c5b27c1af2abdffab546444

if (i2 === 0 || i2 === lineString.coordinates.length - 2) {
incEndVertices = false;
}
if (isPointOnLineSegment(lineString.coordinates[i2], lineString.coordinates[i2 + 1], multiPoint.coordinates[i], incEndVertices)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this excluding both end points of both end segments? Shouldn't it just be the actual LineString end points?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ooo yeah that is a good pickup, a slight modification is needed on the isPointOnLineSegment function

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually now I remember why I did this, I worked out that this didn't matter as the actual 2nd vertex get's picked up in the second segment.

if (i2 === 0 || i2 === lineString2.coordinates.length - 2) {
incEndVertices = false;
}
if (isPointOnLineSegment(lineString1.coordinates[i], lineString1.coordinates[i + 1], lineString2.coordinates[i2], incEndVertices)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you checking that the line segment 1 end points fall on line segment 2? cross only requires that they share some but not all interior points and that the intersections be points. They don't have to be the vertex points.

Copy link
Member Author

@rowanwins rowanwins Jun 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah ok so I think here Im just checking that the point of intersection (or one of them) occurs somewhere other than the very end of the line.

@rowanwins
Copy link
Member Author

Gday @dpmcmlxxvi

Thanks for the review. Perhaps the best thing to do is if you've got a concern is perhaps add some more test cases and we'll see how they come out.

@dpmcmlxxvi
Copy link
Collaborator

dpmcmlxxvi commented Jun 18, 2017

@rowanwins Will do. It maybe a little bit before I get some time to work on it but will work on putting some tests together.

@DenisCarriere
Copy link
Member

DenisCarriere commented Jun 18, 2017

@rowanwins @dpmcmlxxvi As for the types, shouldn't the opposite input types also be valid?

Feature1 => Feature2

  • LineString => Polygon
  • Polygon => LineString (Currently throws an error)
  • MultiPoint => Polygon
  • Polygon => MultiPoint (Currently throws an error)
  • LineString => Polygon
  • Polygon => LineString (Currently throws an error)
  • Other combinations

ST_Crosses returns 1 or t (TRUE) if the intersection results in a geometry that has a dimension that is one less than the maximum dimension of the two source geometries and the intersection set is interior to both source geometries. ST_Crosses returns 1 or t (TRUE) for only ST_MultiPoint/ST_Polygon, ST_MultiPoint/ST_LineString, ST_Linestring/ST_LineString, ST_LineString/ST_Polygon, and ST_LineString/ST_MultiPolygon comparisons.

Question: Shouldn't we return False instead of throwing an Error?

@dpmcmlxxvi
Copy link
Collaborator

Agreed that the opposite input types are valid and should be allowed. Should be easy enough to implement. Use same functions just flip the geom# arguments.

On the return value. I can go either way. I do think there is some value to the way @rowanwins has it now. It might be helpful to make a distinction between having valid vs. invalid inputs. Returning False for DE-9IM functions that are not defined for certain inputs types might be misleading.

@DenisCarriere
Copy link
Member

I think if we include the reverse inputs we will have very little "invalid" input types.

Ex: Point => Point - should be invalid since two points cannot cross each other.

@DenisCarriere
Copy link
Member

@rowanwins FYI: Going to include your shapely script into /scripts

@rowanwins
Copy link
Member Author

Gday @DenisCarriere

Good thinking, it looks like the inverse can be covered in crosses ( I guess crosses is a bit different from of the other booleans in that regard), I'll include those in.

@DenisCarriere
Copy link
Member

@rowanwins Wow, this actually worked, I was able to include the shapely tests directly in the Tape tests.

glob.sync(path.join(__dirname, 'test', 'true', '*.geojson')).forEach(filepath => {
    const {name} = path.parse(filepath);
    const geojson = load.sync(filepath);
    const [feature1, feature2] = geojson.features;
    if (process.env.SHAPELY) shapely('crosses', feature1, feature2).then(result => t.true(result, '[true] shapely - ' + name));
    t.true(crosses(feature1, feature2), '[true] ' + name);
});

Just make sure you define your environment variable as SHAPELY=true and you have Python + shapely installed.

@DenisCarriere DenisCarriere added this to the 4.5.0 milestone Jun 19, 2017
Copy link
Member

@DenisCarriere DenisCarriere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks good

@DenisCarriere
Copy link
Member

Merging, all the tests pass (including Shapely results).

We can always improve this library by adding more test fixtures, so far it looks good to me.

@DenisCarriere DenisCarriere merged commit 28f6dcd into master Jun 19, 2017
@DenisCarriere DenisCarriere deleted the boolean-crosses branch June 19, 2017 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants