Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 关注D3.js地图中的geojson_Javascript_Html_D3.js_Geojson_Topojson - Fatal编程技术网

Javascript 关注D3.js地图中的geojson

Javascript 关注D3.js地图中的geojson,javascript,html,d3.js,geojson,topojson,Javascript,Html,D3.js,Geojson,Topojson,我试图查看城市中建筑物的topojson文件中的对象,但出现以下错误: Error: <path> attribute d: Expected number, "MNaN,NaNLNaN,NaNL…". 这是我的密码: <!DOCTYPE html> <meta charset="utf-8"> <style> .land { fill: #e5e5e5; stroke: #000; stroke-width: 0.2; s

我试图查看城市中建筑物的topojson文件中的对象,但出现以下错误:

Error: <path> attribute d: Expected number, "MNaN,NaNLNaN,NaNL…".
这是我的密码:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.land {
  fill: #e5e5e5;
  stroke: #000;   
  stroke-width: 0.2;
  stroke-opacity: 0.8;
}
.states {
  fill: none;
  stroke: #fff;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/queue.v1.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script>
<script>
    var width = 800;
    var height = 600;
var projection = d3.geo.mercator()
    .center([30, 30])
        .scale(500)
    .translate([width / 2, height / 2]);
var path = d3.geo.path().projection(projection);
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);
queue()
    .defer(d3.json, "cairomonuments.json")
    .await(ready);
function ready(error, cairo) {
  if (error) throw error;

      // Refine projection
      var b, s, t;
      projection.scale(1).translate([0, 0]);
      var b = path.bounds(cairo);
      var s = .95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height);
      var t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2];
      projection.scale(s).translate(t); 

  svg.selectAll("path")
      .data(topojson.feature(cairo, cairo.objects.monuments).features)
        .enter()
        .append('path')
        .attr('class', 'land')
        .attr('d', path);
}
</script>
</body>
我只想将地图放在geojson文件的中心,并将其翻转到一边。我错过了什么

问题 据我所知,主要问题是这一行:

var b = path.bounds(cairo);
path.bounds不会对一组功能(如图层)产生预期结果:

计算指定对象的投影边界框(以像素为单位) 特色边界框由二维数组表示: [[左,上],[右,下]],不同于GIS geo.bounds' 惯例

另外,您不是在传递geojson,而是在传递topojson。如果您想使用特定功能的边界,您的代码看起来更像:

var b = path.bounds(topojson.feature(cairo, cairo.objects.monuments).features[0]);
即使以正确的格式将单个特征传递给它,它仍然无法正确投影,因为在定义投影时,您的比例已定义为500-这将在动态重新计算比例时扭曲计算

保持d3.js v3的可能解决方案 Topojson通常具有bbox属性。您可以使用它来获取中心坐标:

var x = (cairo.bbox[0] + cairo.bbox[2]) / 2; // get middle x coordinate
var y = (cairo.bbox[1] + cairo.bbox[3]) / 2; // get middle y coordinate
请注意,geojson或topojson边界框的顺序为:左、下、右、上

因此,我们现在可以轻松地将地图居中放置在图层中心:

投影。居中[x,y]或投影。旋转[-x,0]。居中[0,y]或投影。旋转[-x,-y]

现在剩下的就是计算比例,将其设置为1开始

如果path.bounds在SVG坐标空间中返回左上角和右下角坐标[min x,min y],[max x,max y]的两个坐标数组,那么我们可以使用topojson.bbox生成等效数组:

var b = [ projection([cairo.bbox[0],cairo.bbox[3]]),projection([cairo.bbox[2],cairo.bbox[1]]) ];
这里有点棘手,因为SVG坐标空间的y坐标从顶部的零开始,与地理特征相反,并且边界中的坐标顺序是:左上右下,与地理特征不同

这就给我们留下了您已有的计算:

var s = 0.95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height);
这给了我们:

初次申报比额表:

var projection = d3.geo.mercator()
    .scale(1)
    .translate([width / 2, height / 2]);
基于数据层的规模和中心细化:

var x = (cairo.bbox[0] + cairo.bbox[2]) / 2;
var y = (cairo.bbox[1] + cairo.bbox[3]) / 2; 
projection.rotate([-x,-y]);

var b = [ projection([cairo.bbox[0],cairo.bbox[3]]),projection([cairo.bbox[2],cairo.bbox[1]]) ];
var s = 0.95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height);
projection.scale(s);
这是在行动中展示的一切

翻转地图 投影旋转中有一个很少使用的参数,允许您实现这一点。在我上面的bl.ock和上面的代码块中,我使用旋转将地图投影居中。通过添加第三个参数,我可以相对于视口旋转贴图:

projection.rotate([-x,-y,90]);

你有我们可以看到的topojson的副本吗?我在底部编辑了我的原始问题,以获得指向文件“topojson file here”的链接。但以防万一,这里又是链接。[链接]谢谢安德鲁·里德。这很有启发性!