4

The demo I'm working on is based on World tour, which uses canvas instead of SVG, so I cannot attach mouse event to country path to find what country was clicked. Is there any way to find which feature contains lat/long I get from mouse coordinates?

var canvas = d3.select("canvas")
    .on("mousemove", function() {
        var p = d3.mouse(canvas.node());
        console.log(projection.invert(p)); // which country contains these coordinates?
    });

var countries;
queue()
    .defer(d3.json, 'world-110m.json.txt')
    .defer(d3.tsv, 'world-country-names.tsv')
    .await(function ready(error, world, names) {
        countries = topojson.feature(world, world.objects.countries).features;
    });
GibboK
  • 71,848
  • 143
  • 435
  • 658
Nikolay
  • 309
  • 2
  • 8

1 Answers1

3

You best option is to create a hidden canvas that mirrors the visible one but draws each country in a different RGB color (a literal "bitmap"), and look up the corresponding feature by the color of the pixel at the mouse cursor's position.

You can see a working example of this here. I've kept the bitmap visible so you can see what's happening.

You do have some other options:

  1. Use a library (such as Turf.js) to do point-in-polygon checks, e.g. with turf.inside.
  2. As an optimization, construct a d3.geom.quadtree of all of the points in every feature and only perform the point-in-polygon checks for features inside the quadtree leaf node.
Shawn Allen
  • 4,994
  • 2
  • 17
  • 10