【问题标题】:D3js cartography: auto-focus on geographic area ? (svg canvas, zoom scale, coordinate translation)D3js 制图:自动关注地理区域? (svg 画布、缩放比例、坐标转换)
【发布时间】:2013-08-22 08:40:21
【问题描述】:

我处理了 SRTM 栅格数据以生成 shapefile -> geojson -> topojson,因此我可以为 D3js 提供合适的格式。

结果如下所示(蓝色区域是我的超大 svg 画布):

给定地理边界地理区域(西部边界、北部、东部、南部)和中心

// India geo-frame borders in decimal ⁰
var WNES = { "W": 67.0, "N":37.5, "E": 99.0, "S": 5.0 };
// India geo-center :
var latCenter = (WNES.S + WNES.N)/2,
    lonCenter =  (WNES.W + WNES.E)/2;

// HTML expected frame dimensions
var width  = 713,
    height = 724;   

// Projection: projection, center coord, scale(?), translate:
var projection = d3.geo.mercator()
    .center([lonCenter, latCenter])
    .scale(width)
    .translate([width/2, height/2]); // this push into the center of the html frame

// SVG injection:
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

地理维度、svg 维度和比例之间的关系是什么?

如何尽可能简化“自动对焦”?

【问题讨论】:

  • 您需要计算比例以使投影区域充满框架。
  • 是的,但我看不到我可以利用的关系。
  • 你见过this question吗?
  • 好的。非常感谢这个提示。我很早就上路了,但是很好。似乎 Bostock 先生从path.bounds(state) 获得了特征尺寸值(以 ⁰ 为单位)。为了适应我不需要那部分的情况。

标签: d3.js maps topojson


【解决方案1】:

我重用了 Bostock & al 的一些代码,并进行了一些编辑,以便您输入您的焦点地理区域边界(十进制坐标):

var WNES = { "W": 67.0, "N":37.5, "E": 99.0, "S": 5.0 };

和目标 svg 画布的 width (px) 例如:

var width  = 600,

自动设置 svg 画布的高度缩放比例平移,以便仅集中显示并完全集中显示在目标地理区域上。

// 1. -------------- SETTINGS ------------- //
// India geo-frame borders (decimal ⁰)
var WNES = { "W": 67.0, "N":37.5, "E": 99.0, "S": 5.0 };
// Geo values of interest :
var latCenter = (WNES.S + WNES.N)/2, // will not be used
    lonCenter = (WNES.W + WNES.E)/2, // will not be used
    geo_width = (WNES.E - WNES.W),
    geo_height= (WNES.N - WNES.S);
// HTML expected frame dimensions
var width  = 600,
    height = (geo_height / geo_width) * width ; // height function of width with ratio of geo-frame (later requires equirectangular projection!)

// Projection: projection, reset scale and reset translate
var projection = d3.geo.equirectangular()
      .scale(1)
      .translate([0, 0]);

// Normal stuff: SVG injection:
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

// Normal stuff: Path
var path = d3.geo.path()
    .projection(projection)
    .pointRadius(4);

// Data (getJSON: TopoJSON)
d3.json("final.json", showData);

// 2. ---------- FUNCTION ------------- //
function showData(error, fra) {
    var Levels = topojson.feature(fra, fra.objects.levels);

// Focus area box compute to derive scale & translate.
var b = path.bounds(Levels), // get data's bounds as [​[left, bottom], [right, top]​]  [[W, S], [E, N]]
    s = 1 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height),
    t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2];

// Projection update
projection
    .scale(s)
    .translate(t);

//Normal stuff: Append my topojson objects => svg layers
    svg.append("path")
        .datum(Levels)
        .attr("d", path)
    svg.selectAll(".levels")
        .data(topojson.feature(fra, fra.objects.levels).features)
      .enter().append("path")
        .attr("class", function(d) { return "Topo_" + d.properties.name; })
        .attr("data-elev", function(d) { return d.properties.name; })
        .attr("d", path)
}

结果很完美:

见:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-13
    • 2020-08-24
    • 2016-09-26
    • 2019-12-30
    • 2014-10-29
    • 2015-06-16
    • 2014-08-27
    • 2014-05-03
    相关资源
    最近更新 更多