mourner / geokdbush

The fastest spatial index for geographic locations in JavaScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting distances in result set

ilblog opened this issue · comments

Hi Vladimir

Do you think there is a chance to get distance with a result somehow?

IL

Yes — a few options here:

  1. Make the API a bit more complicated by returning an array of {distance, item} objects rather than items directly.
  2. Let the users calculate distances afterwards. For this, we could expose a geokdbush.distance(lng1, lat1, lng2, lat2) method for convenience.

I'm on the fence but inclined towards 2 — although it requires redundant calculations (since internally all the distances are already calculated), this shouldn't be a bottleneck in practice, and would allow keeping the API simpler.

Well 2 looks good

Have an idea. The distance are already computed when you return indexes of NN. Just leave them in some array as a property of KNN index.

Sync are operations are sync you just ask for NN, get results and if someone wants, gets computed distances also

Saving a distances array as an index property is easy, but a bit awkward from the API design standpoint. I might end up going with option 1 since it sounds more straightforward.

I went with the option 1 first, but it turned out that performance for the "1000 queries" benchmark decreases by ~20%. Maybe because V8 has a harder time creating arrays of more complex objects?

So I ended up simply exposing a geokdbush.distance(lon1, lat1, lon2, lat2) function. It should be fast enough for most practical cases.

If I send you pull rqst code and add options to the around fun that will do just

result.push( options.includeDist ? candidate : candidate.item );

would you merge? No harm to simple API done

@ilblog this might be a good solution, although I'm not sure whether it has any performance benefit compared to recalculating distances afterwards. Let me make a benchmark to confirm.

WOW

while (q.length && q.peek().item) {
            var candidate = q.pop();
            if (candidate.dist > maxDistance) return result;
            result.push(candidate); // this is gamechanger
            if (result.length === maxResults) return result;
}

With this change the library become completely different tool. I got not only distance but also original item (not only index). I tweaked my local copy and being happy now.