-
Notifications
You must be signed in to change notification settings - Fork 10
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 a "ghost points" scenario #27
Conversation
This happens where a map query is made with 'forks' disabled, meaning only the latest version of each OSM element is returned. In some cases an OSM 'way' that is excluded will reference OSM nodes that are not present in the way that is ultimately returned. Prior to this commit, those ways' unreferenced nodes would be returned regardless, resulting in the final map being peppered with unlabeled "ghost points", with no way referencing them. This fixes the issue by tracking which nodes are referenced to by ways that are excluded, and filtering them out of the final result.
@@ -29,13 +29,7 @@ module.exports = function (req, res, api, params, next) { | |||
} | |||
api.getMap(bbox, function (err, elements) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fork logic should be in https://github.com/digidem/osm-p2p-server/blob/master/api/get_map.js I think. I see now an unrelated error: the switch (accept.types(['xml', 'json']))
should be called whether query.forks
is true or false - I introduced this bug when I introduced the json
endpoint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move the logic to api/get_map.js? I think it makes more sense there. We could extract the filterForkElements
function and test that independently, which would make the test simpler - we just test that function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry somehow started another "review" instead of just leaving a comment
// Remove excluded entries that appear in the keep entries. | ||
Object.keys(keepNodeRefs).forEach(function (ref) { | ||
if (excludeNodeRefs[ref]) { | ||
delete excludeNodeRefs[ref] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be slow and can cause memory issues. I think that looking at line #94 you don't actually need this, but my head is a little slow right now...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see an opportunity to expand my Node knowledge! Why will this be slow? What memory issues will it cause?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed; though I'm still curious to understand the performance concerns.
The route logic for /bbox does will not return json even if it is requested.
|
I don't know that much, other than having a PR comment from MapBox for
including delete. The issue I think is with using it in a loop, so
performance impacts can add up. There is this:
http://stackoverflow.com/questions/27397034/why-is-delete-slow-in-javascript
And this with good discussion:
googleapis/google-api-nodejs-client#375
I think because this object could be very large for a large forked way, and
could be looped hundreds of times, this is a time where it is worth
considering this kind of performance
On Jan 11, 2017, at 12:35 AM, Stephen Whitmore <[email protected]> wrote:
*@noffle* commented on this pull request.
------------------------------
In routes/misc_map.js <#27>:
+
+ // Note that all of the nodes referenced by this way should be culled.
+ if (element.type === 'way') {
+ element.nodes.forEach(function (ref) {
+ excludeNodeRefs[ref] = true
+ })
+ }
+
+ return false
+ }
+ })
+
+ // Remove excluded entries that appear in the keep entries.
+ Object.keys(keepNodeRefs).forEach(function (ref) {
+ if (excludeNodeRefs[ref]) {
+ delete excludeNodeRefs[ref]
Removed; though I'm still curious to understand the performance concerns.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#27>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AARumRcRCLyXXTHMH2iqafh4_sGAC9npks5rRCO6gaJpZM4Le9US>
.
|
I added some more tests to cover the scenario where there are two forks to a way: one modifies a point, one deletes a point. |
Sorry to report bad news... Unfortunately there seems to be some kind of race condition here, and
Unfortunately setting env |
I added slowdb() to the tests but still not reliably reproducing. This race condition may be coming from somewhere else, maybe in the test setup itself. |
Still getting random errors... Without fully parsing your code, I suspect that this may be due to unstable sorting of forks because you are creating points directly (i.e. not with the osm-server api) without timestamps, so the sorting will be based on version numbers rather than timestamps. |
Ok, adding timestamps fixes this. I'm going to merge and cut a release so we can work with this today, but @noffle can you review this test once more to check I'm not missing anything with this fix? |
This happens where a map query is made with 'forks' disabled, meaning only
the latest version of each OSM element is returned.
In some cases an OSM 'way' that is excluded will reference OSM nodes that
are not present in the way that is ultimately returned. Prior to this
commit, those ways' unreferenced nodes would be returned regardless,
resulting in the final map being peppered with unlabeled
"ghost points", with no way referencing them.
This fixes the issue by tracking which nodes are referenced to by ways that
are excluded, and filtering them out of the final result.