地图中的圆圈在D3 V4中显示的位置不正确 [英] Circles in Map Displayed Incorrect Location in D3 V4

查看:86
本文介绍了地图中的圆圈在D3 V4中显示的位置不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用教程来学习如何在D3.v3中生成地图,但是我正在使用D3.v4.我只是想让一些圆圈出现在地图上(请参见下文).该代码有效,但圆圈位于内华达州上方且应位于海湾地区.我想这是地图的投影与投影坐标之间的不匹配.我不确定地图所处的投影位置,但是我试图将其强制为albersUsa(请参阅在生成路径的地方注释掉的命令),但这会导致整个地图消失.任何帮助将不胜感激!

I am using a tutorial to learn how to generate maps in D3.v3, but I am using D3.v4. I am just trying to get some circles to appear on the map (see below). The code works except that the circles are over Nevada and should be in the Bay Area. I imagine this is a mismatch between projections of the map and the projected coordinates. I am not sure what projection the map is in, but I have tried to force it to be albersUsa (see commented out commands where I generate path) but this causes the entire map to disappear. Any help would be appreciated!

<!DOCTYPE html>

<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script>

var w = 960,
    h = 600;
var projection = d3.geoAlbersUsa();
var path = d3.geoPath()
             //.projection(projection)

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

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

  svg.selectAll("path")
     .data(topojson.feature(us, us.objects.states).features)
     .enter().append("path")
	 .attr("class", "states")
     .attr("d", path);

   svg.append("path")
      .attr("class", "state-borders")
      .attr("d", path(topojson.mesh(us, us.objects.states)))

   svg.append("path")
      .attr("class", "county-borders")
      .attr("d", path(topojson.mesh(us, us.objects.counties)));

      aa = [-122.490402, 37.786453];
  	  bb = [-122.389809, 37.72728];

   svg.selectAll("circle")
      .data([aa,bb]).enter()
      .append("circle")
      .attr("cx", function (d) { return projection(d)[0]; })
      .attr("cy", function (d) { return projection(d)[1]; })
      .attr("r", "8px")
      .attr("fill", "red")
    });

</script>

推荐答案

您的美国json已被投影,要显示该图像,您可以使用空投影:

Your US json is already projected, and to show it you use a null projection:

var path = d3.geoPath()
             //.projection(projection)

不定义投影,您的topojson/geojson坐标将转换为直线像素坐标.碰巧的是,这个特定的topojson文件的像素坐标在[0,0]和[960,600]之内,几乎与默认的bl.ock视图大小相同.在不知道所使用的投影也无法创建该文件的情况下,您无法复制该投影以使地理特征与数据对齐. 除非您直接使用像素值放置要素并完全跳过投影(这对于不在可识别地标附近或精度至关重要的点没有用.)

Without defining a projection, your topojson/geojson coordinates will be translated to straight pixel coordinates. It just so happens that this particular topojson file has pixel coordinates that are within [0,0] and [960,600], almost the same size as a default bl.ock view. Without knowing the projection used too create that file you cannot replicated that projection to align geographic features to your data. Unless you place your features with pixel values directly and skip the projection altogether (not useful for points not near identifiable landmarks or where precision matters).

使用geoUsaAlbers()进行投影时,您的US topojson功能会消失,因为您正在平面上获取像素坐标并将其转换为svg坐标,就好像它们是三维地球上的点一样(d3投影期望纬度对对).

Your US topojson features disappear when projecting with a geoUsaAlbers() because you are taking pixel coordinates on a plane and transforming them to svg coordinates as though they were points on a three dimensional globe (d3 projections expect latitude longitude pairs).

相反,请使用未投影的topojson或geojson.也就是说,它包含纬度/经度对,并将这些数据与您的点一起投影.请参阅此 bl.ock 的示例,其中包含未投影(纬/长对)json的示例使用您的代码(但将投影分配给path).

Instead, use a topojson or geojson that is unprojected. That is to say it contains latitude/longitude pairs and project that data along with your points. See this bl.ock for an example with unprojected (lat/long pairs) json for the US using your code (but assigning a projection to path).

要检查您是否有纬度/经度对,可以轻松地在geojson文件中查看这些要素的几何形状,并查看值是否为有效的经纬度点.对于topojson,topojson库会将要素转换为geojson,因此您可以在此转换后查看几何.

To check if you have latitude/longitude pairs you can view the geometry of these features in a geojson file easily and see if the values are valid long, lat points. For topojson, the topojson library converts features to geojson, so you can view the geometries after this conversion.

这是美国的非预期topojson: https://bl.ocks .org/mbostock/raw/4090846/us.json

Here's an unprojected topojson of the US: https://bl.ocks.org/mbostock/raw/4090846/us.json

假设您确实想使用相同的topojson文件,那么我们很可能可以推断出它使用的投影.首先,我将显示您的投影点(通过使用美国的未投影轮廓)与已经投影的topojson(未投影的topojson用d3.geoAlbersUsa()投影并且使用零投影的投影)之间的差异:

Let's say you really wanted to use the same topojson file though, well we can probably deduce the projection it uses. First, I'll show the difference between your projected points (by using an unprojected outline of the US) and the already projected topojson (the unprojected topojson is projected with d3.geoAlbersUsa() and the projected with a null projection):

机会是投影d3.geoAlbersUsa已针对bl.ocks.org默认视口960x500进行了优化.未投影的数据集的边界框大约为960x600,因此,如果我们将缩放比例增加600/500并调整平移,我们可以在960x600的svg中对齐要素:

Chances are the projection d3.geoAlbersUsa is optimized for a bl.ocks.org default viewport, 960x500. The unprojected dataset has a bounding box of roughly 960x600, so perhaps if we increase the scale by a factor of 600/500 and adjust the translate we can align our features in an svg that is 960x600:

var projection = d3.geoAlbersUsa();
var scale = projection.scale() * 600 / 500;
projection.scale(scale).translate([960/2,600/2])
var projectedPath = d3.geoPath().projection(projection);

而且,这似乎对齐得很好,我看不到两者之间的区别:

And, this appears to align fairly well, I can't see the difference between the two:

这是一个方块,它显示了对齐的特征.

Here's a block showing the aligned features.

但是,正如我在评论中提到的那样,即使您可以对齐要素,也可以: 任何缩放或居中都会出现问题,因为您需要对已投影的数据使用geoTransform,而对原始地理数据使用geoProjection.使用所有(统一)投影数据或所有非投影数据可以简化工作.

But as I mention in the comments, even if you can align the features: any zoom or centering would be problematic as you need to use a geoTransform on already projected data but a geoProjection on the raw geographic data. Using all (uniformly) projected data or all unprojected data makes life simpler.

这篇关于地图中的圆圈在D3 V4中显示的位置不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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