-
Notifications
You must be signed in to change notification settings - Fork 946
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
lineSplit doesn't split correctly #1232
Comments
Hey @andersfalk Thanks for a great first bug report, test cases like you provided are always super helpful! When I've got a computer turned on i'll take a look into things and report back. |
@andersfalk In your example it looks like you swapped the coordinates of the line and the polygon. I found another case today, where lineSplit does not split correctly: it('should split the line in three parts', () => {
const poly = polygon([[
[10.41993839, 50.0301184],
[10.42587086, 50.02630702],
[10.41993839, 50.02249594],
[10.41400592, 50.02630702],
[10.41993839, 50.0301184],
]]);
const line = lineString([
[10.424716, 50.024888],
[10.417643, 50.029512],
]);
expect(lineSplit(line, poly).features.length).toBe(3);
}); In the result the lineString inside the polygon is missing. |
@sroettering My example has one polyline and one polygon where the polyline is much larger than the polygon. I think the example is ok. |
I would be very interested in your code, if you could post it somewhere. |
This is the code. It can probably be cleaned up. @rowanwins, if this code in any way helps you with your implementation of lineSplit, please feel free to use any part.
|
Another example where line-split doesn't seem to work as intended:
|
The solution here seems to work as expected https://github.com/Turfjs/turf-line-slice-at-intersection/blob/master/index.js#L109 |
Another example where it fails, this seems pretty common: const result = lineSplit(
{
type: "Feature",
properties: {
index: 0,
stroke: "#ff00c8",
"stroke-width": 2,
"stroke-opacity": 1,
intersectingIndex: 2
},
geometry: {
type: "LineString",
coordinates: [
[-9.284582069501932, 38.68554008224343],
[-9.286108016967773, 38.66594353859579],
[-9.264135360717773, 38.6648042445158],
[-9.263504188862719, 38.678904253099795]
]
}
},
{
type: "Feature",
properties: {
index: 4,
stroke: "#1e00ff",
"stroke-width": 2,
"stroke-opacity": 1
},
geometry: {
type: "LineString",
coordinates: [
[-9.255123138427734, 38.65716380410655],
[-9.289369583129883, 38.68772067467188]
]
}
}
); Result is: {
"features": [
{
"geometry": {
"coordinates": [
-9.28473432383367,
38.683584799558915
],
"type": "Point"
},
"properties": {},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
-9.264118106633084,
38.66518969063523
],
"type": "Point"
},
"properties": {},
"type": "Feature"
}
],
"type": "FeatureCollection"
} While it should be made of 3 segments... But for the record, |
I had to modify @andersfalk code to make it work: export const lineSplit = (line, splitter) => {
const splitOwn = featureCollection([lineString(line.geometry.coordinates)]);
// dispatch all intersections
const intersections = lineIntersect(line, splitter).features;
for (let i = 0; i < intersections.length; i++) {
let point = intersections[i];
// check if intersection is on line
for (let j = 0; j < splitOwn.features.length; j++) {
const lineString = splitOwn.features[j];
if (!point) {
break;
}
if (pointToLineDistance(point, lineString) > 0.00001) {
// Too far, this point is not on this segment
continue;
}
// split line into two
splitOwn.features.splice(j, 1);
const pointStart = turfPoint(lineString.geometry.coordinates[0]);
const pointStop = turfPoint(
lineString.geometry.coordinates[
lineString.geometry.coordinates.length - 1
]
);
splitOwn.features.push(lineSlice(pointStart, point, line));
splitOwn.features.push(lineSlice(point, pointStop, line));
point = null;
}
}
// remove short splits
for (let i = splitOwn.features.length - 1; i >= 0; i--) {
if (length(splitOwn.features[i]) < 0.00001) splitOwn.features.splice(i, 1);
}
return splitOwn;
}; |
Related issue: #2023 The function above uses lineSlice, but lineSlice is super imprecise |
I've found the cause of this issue, but don't have a solution yet. The line split algorithm is missing segments to split as they aren't being found by the For more detail, the line split algorithm seems to work like this:
EDIT: Actually, it's due to the bbox of linesegments being calculated with turf-square, which will in many cases make a bbox that is smaller than the input bbox. This is due to how it calculates the aspect ratio in real distance, but then applies the square-ing in WGS-84. This makes it an easy fix, remove the |
Thanks for finding the root cause @hanneshdc. Do you know of an existing issue describing that problem in turf-square? Does #1727 cover it? |
No problem, I'm glad it's a reasonably simple fix. Yes, #1727 describes the same issue, and fixing that will likely fix this as well. Though, I haven't tested that. |
Time for me to pile on.
The fix proposed by @hanneshdc within PR #2460 solves the issue for us in this case. As they call out, this is possibly better achieved via #1727. Is there any follow up on this issue? Or hope of it getting merged into an upcoming release? |
Another case. Removing bbox proposed by @hanneshdc within PR #2460 solves this case. const line = {
type: "Feature",
properties: {},
geometry: {
type: "LineString",
coordinates: [ [0, 44], [25, 38], [27, 40], [0, 62] ],
},
};
const splitter = {
type: "Feature",
properties: {},
geometry: {
type: "Polygon",
coordinates: [[ [0, 20], [42, 20], [42, 39], [28, 39], [0, 52], [0, 20] ]],
},
};
turf.lineSplit(line, splitter); // returns single line https://gist.github.com/kudlav/3ce18d90d6eca7ea2712a8b1794b14eb |
LineSplit is a great feature but it doesn't work as expected. I use a simple Polygon (triangle) as a splitter to split a simple four-point LineString. This should result in three LineStrings but only two are produced:
Returns this collection:
Instead of this:
This is my first post ever on GitHub, so please be kind if I'm doing something wrong. Have searched earlier issues and haven't seen this bug report.
The text was updated successfully, but these errors were encountered: