Turfjs / turf

A modular geospatial engine written in JavaScript and TypeScript
https://turfjs.org/
MIT License
9.31k stars 942 forks source link

Propose isParallel as new module #735

Closed DenisCarriere closed 7 years ago

DenisCarriere commented 7 years ago

Propose @turf/boolean-parallel module

To complement the boolean themed modules, this would only input (Multi)LineString geometry types and should be able to detect if the two inputs are parallel or not.

The majority of the code is already built in @turf/line-offset in isParallel() which was inspired by node-intersection.

The only trick with this module would be to support LineString inputs with more than 2 vertices, @turf/line-segment can help iterate over both inputs.

morganherlocker commented 7 years ago

This seems interesting. How would you define the concept of "parallel" in this context, since the correct-ish term is probably not accurate (2 lines are exactly parallel in 3d space).

DenisCarriere commented 7 years ago

I don't know if this definition is accurate or not, however I've seen this type of line parallel method in a few modules so far and it would be nice to extract that into a single boolean method (@psalaets's line-intersect is another library that has a 2-vertex parallel boolean method).

This would definitely be a bit trickier to support in 3D space and would most likely only be implemented in a 2D plane.

stebogit commented 7 years ago

@DenisCarriere couldn't we simply calculate the slope/bearing of the segments and check if they are equal? I believe that is a correct definition for parallel segments on a plane. This would also make easy calculation for a boolean-perpendicular (abs(bearing1 - bearing2) == 90), if of any interest. We could use @turf-bearing or @turf-rhumb-bearing, or give the user the option to chose between the two.

The definition of 'parallel' should be well defined for multi-segment lines, as it generally applies to straight lines or segments. Example: would you define these two multi-segment lines as parallel? screen shot 2017-06-11 at 10 55 53 pm

For more complex geometries, how would you define if two MultiLineStrings are parallel? All LineStrings should be parallel in pairs maybe? But how can/would you pair the lines though? I would restrict this module to LineString inputs, and leave the user to iterate through MultiLineStrings as he considers appropriate.

I'd be happy to try implementing this if you want.

DenisCarriere commented 7 years ago

👍 I agree that it might be best to restrict it to only LineString, it can get very messy to support MultiLineString.

dpmcmlxxvi commented 7 years ago

I'd recommend working up a definition for "parallel" for the various cases first:

Lots of things to think through. Would be interesting to see if there is an agreed upon definition for these types of geometries out there.

stebogit commented 7 years ago

@dpmcmlxxvi

For a segment using a constant distance seems like the easiest to implement using the available turf functions. I try to avoid angles and bearings if I can get away with distances.

What function would you use to calculate the distance? I can't think of one Why would you avoid angles, what kind of issues do you think might arise?

Additional thought, would two parallel rhumb-lines have always the same (rhumb, I guess) distance?

480px-loxodrome svg

What about Great-Circle lines? Maybe these can't be parallel...?

Would it be sequential segments that are parallel?

I'd say yes.

Does each sequential pair have to be of the same length?

To me this seems to be maybe too restrictive; two multi-segment LineString would be parallel only in case of a translation, as you pointed out. At this point comparing just the bearings makes it very convenient in my opinion.

For MultiLineString ...

I would leave to the user how to define how to compare complex geometries; I feel like it would be kind of a guessing and most of the time a waist of resources in trying a lot of different combinations. However we can implement this part at any later time if necessary.

dpmcmlxxvi commented 7 years ago

@stebogit

What function would you use to calculate the distance?

Turf has a @turf/distance for computing distances between points.

Why would you avoid angles, what kind of issues do you think might arise?

Distances are more reliable to compute and can't really go wrong. With angles you have to have to be careful with defining a reference direction, orientation, positive/negative values. It's easy to get them wrong and mixing/matching wrong angles. If there is a distance based definition for parallel I'd suggest using it.

To me this seems to be maybe too restrictive;

It may be, but it is the only one that makes sense to me for a LineString. Checking each segment is parallel doesn't seem to me to satisfy any meaningful geometric postulate or sense of "parallel-ness". Happy to hear other arguments for it.

I would leave to the user how to define how to compare complex geometries

I don't see much difference between LineString and MultiLineString in this regard.

stebogit commented 7 years ago

Implemented with #941