缩放d3 v4映射以适合SVG(或者根本) [英] Scaling d3 v4 map to fit SVG (or at all)

查看:253
本文介绍了缩放d3 v4映射以适合SVG(或者根本)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让这张地图的缩放更小。到我的SVG,或者甚至手动。

I am trying to make this map of the us scale smaller. Either to my SVG, or even manually.

这是我最简单的代码:

function initializeMapDifferent(){
    var svg = d3.select("#map").append("svg")
        .attr("width", 1000)
        .attr("height", 500);



    d3.json("https://d3js.org/us-10m.v1.json", function (error, us){

        svg.append("g")
            .attr("class", "states")
            .selectAll("path")
            .data(topojson.feature(us, us.objects.states).features)
            .enter().append("path")
            .attr("fill", "gray")
            .attr("d", d3.geoPath());
    });
}

我尝试过:

  var path = d3.geoPath()
  .projection(d3.geoConicConformal()
      .parallels([33, 45])
      .rotate([96, -39])
      .fitSize([width, height], conus));

但每次我添加任何东西到我的路径变量,我从D3的内部部分得到NAN错误。感谢任何帮助!

but every time I add anything to my path variable I get NAN errors from the internal parts of D3. Thanks for any help!

推荐答案

为什么数据无法正确投影



关键问题是您的数据已经投影。 D3 geoProjections使用未投影的数据,或使用拉长对。 WGS84数据中的数据。基本上一个d3 geoProjection使用球面坐标,并将它们转换为平面笛卡尔坐标x,y。

Why the data doesn't project properly

The key issue is that your data is already projected. D3 geoProjections use data that is unprojected, or in lat long pairs. Data in the WGS84 datum. Essentially a d3 geoProjection takes spherical coordinates and translates them into planar cartesian x,y coordinates.

您的数据不符合 - 它已经是平面的。你可以看到最明显的,因为阿拉斯加不是应该的地方(除非有人改变了阿拉斯加的拉长对,这是不可能的)。已经投影的数据的其他迹象和症状可能是覆盖整个地球的特征,以及NaN误差。

Your data does not conform to this - it is already planar. You can see most evidently because Alaska is not where it should be (unless someone changed the lat long pairs of Alaska, which is unlikely). Other signs and symptoms of already projected data may be a feature that covers the entire planet, and NaN errors.

这是一个复合投影,很难取消项目,但是你可以在d3.js中显示已投影的数据。

That this is a composite projection makes it hard to unproject, but you can display already projected data in d3.js.

最简单的,您可以将投影定义为null:

Most simply, you can define your projection as null:

var path = d3.geoPath(null);

这将从geojson几何获取x,y数据,并将其显示为x,y数据。然而,如果你的x,y坐标超过你的svg的宽度和高度,地图将不会包含在你的svg中(如你在 .attr(d,d3.geoPath ()); )。

This will take the x,y data from the geojson geometries and display it as x,y data. However, if your x,y coordinates exceed the width and height of your svg, the map will not be contained within your svg (as you found in your example with .attr("d", d3.geoPath());).

如果您想要控制数据的显示方式,您可以使用 geoTransform

If you want a little control over how that data is displayed you can use a geoTransform.

Mike Bostock


但是如果你的几何图形已经是平面的了呢?也就是说,如果你只是
想要投影几何,但是仍然将其转换或缩放到
适合视口呢?

But what if your geometry is already planar? That is, what if you just want to take projected geometry, but still translate or scale it to fit the viewport?

自定义几何转换以在投影过程中获得完全控制

You can implement a custom geometry transform to gain complete control over the projection process.

使用 geoTransform 是相对简单的,假设您不想更改投影类型。例如,如果要缩放数据,可以使用 geoTransform 实现缩放的简短函数:

To use a geoTransform is relatively straightforward assuming that you do not want to change the type of projection. For example, if you want to scale the data you could implement a short function for scaling with geoTransform:

function scale (scaleFactor) {
    return d3.geoTransform({
        point: function(x, y) {
            this.stream.point(x * scaleFactor, y  * scaleFactor);
        }
    });
}

var path = d3.geoPath().projection(scale(0.2));

但是,缩放时会将所有内容缩放到左上角。为了使事情保持中心,您可以添加一些代码以使投影居中:

Though, this will scale everything into the top left corner as you zoom out. To keep things centered, you could add some code to center the projection:

function scale (scaleFactor,width,height) {
    return d3.geoTransform({
        point: function(x, y) {
            this.stream.point( (x - width/2) * scaleFactor + width/2 , (y - height/2) * scaleFactor + height/2);
        }
    });
    }

var path = d3.geoPath().projection(scale(0.2,width,height))



演示:



如果代码段未加载json, bl.ock 此处

这是使用您的文件的示例:

Here is an example using your file:

var width = 600;
var height = 300;

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


function scale (scaleFactor,width,height) {
  return d3.geoTransform({
    point: function(x, y) {
      this.stream.point( (x - width/2) * scaleFactor + width/2 , (y - height/2) * scaleFactor + height/2);
    }
  });
}
  
d3.json("https://d3js.org/us-10m.v1.json", function (error, us){
  var path = d3.geoPath().projection(scale(0.2,width,height))
 
  svg.append("g")
    .attr("class", "states")
    .selectAll("path")
    .data(topojson.feature(us, us.objects.states).features)
    .enter().append("path")
    .attr("fill", "gray")
    .attr("d", path);
  
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/2.2.0/topojson.js"></script>

您可以检查您的地图项的几何形状是否符合纬度和经度的限制。例如,如果您要记录:

You could do check to see that the geometry of your features respect the limits of latitude and longitude. For example, if you were to log:

d3.json("https://d3js.org/us-10m.v1.json", function (error, us){
   console.log(topojson.feature(us, us.objects.states).features);
});

您将很快看到值超过+/- 90度N / S和+ - 180度E / W。

You will quickly see that values are in excess of +/- 90 degrees N/S and +/- 180 degrees E/W. Unlikely to be lat long pairs.

或者,您可以将数据导入到在线服务(例如mapshaper.org),并与另一个您知道是未投影的topojson / geojson进行比较(或使用WGS84投影)。

Alternatively, you could import your data to an online service such as mapshaper.org and compare against another topojson/geojson that you know is unprojected (or 'projected' using WGS84).

如果处理geojson,你可能很幸运地看到一个定义投影的属性,例如:name:urn:ogc:def:crs:OGC:1.3:CRS84(CRS代表坐标参考系)或EPSG编号: EPSG:4326 (EPSG代表欧洲石油勘测集团)。

If dealing with geojson, you may be lucky enough to see a property that defines the projection, such as: "name": "urn:ogc:def:crs:OGC:1.3:CRS84" (CRS stands for coordinate reference system) or an EPSG number: EPSG:4326 (EPSG stands for European Petroleum Survey Group).

此外,如果您的数据项目具有零投影但不是标准投影缩小以确保您不在错误的区域),您可能正在处理投影数据。同样,如果您的视口完全被一个特征覆盖(并且您没有放大)。 NaN坐标也是一个潜在的指标。然而,这些投影数据的最后指标也可能意味着其他问题。

Also, if your data projects with a null projection but not a standard projection (scaled/zoomed out to ensure you aren't looking in the wrong area), you might be dealing with projected data. Likewise if your viewport is entirely covered by one feature (and you aren't zoomed in). NaN coordinates are also a potential indicator. However, these last indicators of projected data can also mean other problems.

最后,数据源还可能表明数据已经投影在元数据或如何使用:查看此,我们可以看到,当 geoPath

Lastly, the data source may also indicate data is already projected either in meta data or how it is used: Looking at this block, we can see that no projection was used when the geoPath is defined.

这篇关于缩放d3 v4映射以适合SVG(或者根本)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆