D3地图可见区域坐标

时间:2014-01-19 10:18:43

标签: javascript d3.js

这是d3可缩放地图的简单代码:

  winWidth = $(window).width();
  winHeight = $(window).height();

  projection = d3.geo.mercator()
      .translate([0, 0])
      .scale(winWidth / 2 / Math.PI);

  zoom = d3.behavior.zoom()
      .scaleExtent([1, 50])
      .on("zoom", manageMap);

  path = d3.geo.path()
      .projection(projection);

  svg = d3.select("#map").append("svg")
      .attr("viewBox", "0 0 " + winWidth + " " + winHeight)
      .attr("preserveAspectRatio", "xMidYMid meet")
      .append("g")
      .attr("transform", "translate(" + winWidth / 2 + "," + winHeight / 2 + ")")
      .call(zoom);

  g = svg.append("g");

  d3.json("world-50m.json", function(error, world) {
    g.append("path")
        .datum(topojson.feature(world, world.objects.countries))
        .attr("class", "land")
        .attr("d", path);

    g.append("path")
        .datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
        .attr("class", "boundary")
        .attr("d", path);
  });

function manageMap() {

  var t = d3.event.translate,
      s = d3.event.scale;

  t[0] = Math.min(winWidth / 2 * (s - 1), Math.max(winWidth / 2 * (1 - s), t[0]));
  t[1] = Math.min(winHeight / 2 * (s - 1) + 230 * s, Math.max(winHeight / 2 * (1 - s) - 230 * s, t[1]));

  zoom.translate(t);
  g.style("stroke-width", 1/s).attr("transform", "translate(" + t + ")scale(" + s + ")");
  svg.select("g").selectAll("circle")
      .attr("cx", function(d) { return projection([d.lng, d.lat])[0]; })
      .attr("cy", function(d) { return projection([d.lng, d.lat])[1]; })
      .attr("r", 11/s);

}

当缩放和翻译地图时,有没有简单的方法来获得当前可见区域坐标?我已经尝试过预测地图的翻译,但只是得到了一些奇怪的数字。

1 个答案:

答案 0 :(得分:2)

这样做。我还在http://bl.ocks.org/sfinktah/1d38c8a268d893d769ed

上提出了这个问题

即使你找到了你的解决方案,这对未来的google也许有用。

function getScreenBounds() {
  return [getPoint(0,0), getPoint()];
}

function getPoint(x,y) {
  if (x == null) x = winWidth;
  if (y == null) y = winHeight;
  var container = g.node();
  var svg = container.ownerSVGElement || container;
  var point = svg.createSVGPoint();
  point.x = x, point.y = y;
  point = point.matrixTransform(container.getScreenCTM().inverse());
  return formatLocation(projection.invert([point.x, point.y]), zoom.scale());
}

function formatLocation(p, k) {
  var format = d3.format("." + Math.floor(Math.log(k) / 2 - 2) + "f");
  return (p[1] < 0 ? format(-p[1]) + "°S" : format(p[1]) + "°N") + " "
       + (p[0] < 0 ? format(-p[0]) + "°W" : format(p[0]) + "°E");
}