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

Use marchingsquares lib for turf-isoband and turf-isoline, fixes "first break" bug #2527

Merged
merged 3 commits into from
Nov 9, 2023

Conversation

smallsaucepan
Copy link
Member

Refactoring and fixes to turf-isoband and turf-isoline. Use third party marchingsquares module instead of hosting a copy of it internally. Resolves #1797 (sort of - it was already fixed, but was still open and we've added a regression test for it here) and also chose to resolve #2129 while we were in there.

Please fill in this template.

  • 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.

Submitting a new TurfJS Module.

n/ahttps://docs.github.com/articles/closing-issues-using-keywords

@smallsaucepan smallsaucepan changed the title Use marchingsquares lib for turf-isoband and turf-isoline, fix breaks bug Use marchingsquares lib for turf-isoband and turf-isoline, fixes "first break" bug Nov 2, 2023
Copy link
Collaborator

@stebogit stebogit left a comment

Choose a reason for hiding this comment

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

👍🏻

});

// resize and shift each point/line of the createdIsoLines
clonedIsoLines.forEach((isoline) => {
coordEach(isoline, resize);
Copy link
Collaborator

Choose a reason for hiding this comment

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

just a guess here, but if the problem is related to an unexpected mutation using coordEach, have you tried to replace that function with code that does not mutate anything, instead of cloning the entire isoline object? This for sake of performance.
At the very least you could instead clone just each coord array during the loop instead of the entire (potentially very large) isoline object.

Copy link
Collaborator

@stebogit stebogit Nov 8, 2023

Choose a reason for hiding this comment

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

on a second thought, maybe the resize function should just not mutate the values in the first place, but return a new array:

const resize = (point: number[]) => [
  point[0] * scaleX + x0,
  point[1] * scaleY + y0,
];

Copy link
Member Author

Choose a reason for hiding this comment

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

I think the resize function has to mutate in place - coordEach discards the return value of the callback.

It's more a quirk of the marchingsquares library which seems to re-use the first coordinate array as the closing point as well. So the callback passed to coordEach is being unexpectedly run twice on a single set of numbers i.e.

What we get back from marchingsquares:

[0] -> [1, 1]
[1] -> [2, 2]
[2] -> [3, 3]
[3] -> [1, 1] // <-- not another array that also contains [1, 1], the exact same array referred to by [0]

What we end up with after coordEach (if callback appends an "x" for the sake of visualisation):

[0] -> [1xx, 1xx]
[1] -> [2x, 2x]
[2] -> [3x, 3x]
[3] -> [1xx, 1xx] // in our case making one point way off target

I'll tweak the workaround to maybe only clobber the last coord in each linestring with a cloned value, then run the resize function over that.

Copy link
Member Author

Choose a reason for hiding this comment

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

Looks like this might have been a red herring. Pulled out the cloning operation to rework it and the tests still passed. Suspect adding linearRing: false to marchingsquares.isoContours() may have fixed it already. CI tests have passed so will merge. Thanks for questioning it @stebogit 👍

@@ -2,7 +2,7 @@ import fs from "fs";
import path from "path";
import load from "load-json-file";
import Benchmark from "benchmark";
import matrixToGrid from "matrix-to-grid";
import matrixToGrid from "./lib/matrix-to-grid";
Copy link
Collaborator

Choose a reason for hiding this comment

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

what's the purpose of using these internal modules? That is, why not using the npm versions?

Copy link
Member Author

Choose a reason for hiding this comment

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

For matrix-to-grid the file committed to turf differs from the one in npm. Looks like @DenisCarriere included a tweak when it was originally added? See https://github.com/Turfjs/turf/blame/2faafab9162bcadd35a79ec329f578881038b5ec/packages/turf-isolines/lib/matrix-to-grid.js#L45

More than happy to use the NPM version. Do you want to roll in that change and re-release? I'm not sure what the original justification was though.

For now will go with the internal modules and we can refactor this depending on what you'd like to do.

packages/turf-isolines/index.ts Show resolved Hide resolved
packages/turf-isolines/test.js Outdated Show resolved Hide resolved
packages/turf-isolines/index.ts Outdated Show resolved Hide resolved
…s library from NPM. This commit supercedes PR Turfjs#1801 which is a few years old now. Resolves Turfjs#1797 based on a test case mentioned in that issue (added to unit tests in isobands). Slight changes to resulting coordinates in most fixtures, though all fixtures verified visually using geojson.io
…e it looked like the unit tests have had a 0 break added as a work around e.g. 5 breaks but only 4 break properties, have removed the presumed workaround and reviewed test fixture output. Resolves Turfjs#2129.
…have been unnecessary, possibly already having been fixed by adding linearRing: false to the isoContours call.
@smallsaucepan smallsaucepan merged commit ef8b904 into Turfjs:master Nov 9, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Isolines ignores first break value isobands fails on flat data
2 participants