eby*_*byt 3 gis geojson map-projections d3.js
我按照指南在 d3js 中创建了美国的基本地图
指南链接 - http://bl.ocks.org/michellechandra/0b2ce4923dc9b5809922。
我已经了解了 GeoJSON 和地图投影的基础知识。
目前我的地图看起来像这样 - (地图 1)
- 这使用d3.geoAlbersUsa()投影

我希望我的地图看起来像这样 - (地图 2) - 即顶部不是弯曲的,而是直线边界
链接https://www.worldatlas.com/webimage/countrys/namerica/usstates/usa50mer.htm
要求 -
我已经尝试过什么 -
d3.geoMercator()投影,但阿拉斯加太大,无法容纳在视口中,并且位于我不想要的左上角。你无法矫正阿尔伯斯。阿尔伯斯投影是圆锥投影 - 纬线的大小不同,因为它们被投影到圆锥上,这意味着由于投影长度不同(地球上的纬线长度也不同),因此会出现一条曲线。
圆柱形墨卡托投影将较短的纬线拉伸以占据与赤道相同的宽度,这就是为什么墨卡托投影中的纬线是直的、水平的且长度相等的原因。
我们可以滥用 Albers 投影来消除部分曲线,但 d3 的 geoAlbersUsa 投影是复合投影,不允许进行此类修改。它实际上只是预测的集合。
相反,我们可以使用 d3.geoTransform 和 d3.geoMercator 创建自己的复合投影。结果应该是这样的:
这是一个简单的 d3 geoTransform:
let projection = d3.geoTransform({
point: function(x, y) {
this.stream.point(x*2,y*2);
}
});
Run Code Online (Sandbox Code Playgroud)
这只是将 x 和 y 值乘以二,它可以传递给路径生成器,如下所示:d3.geoPath(projection);
要在这里进行复合投影,我们需要正确设置三个投影,然后正确翻译到地图上。我假设 960x500 地图构建了这些投影(类似于 d3.geoAlbersUsa):
let scale = 800;
let width = 960;
let height = 500;
let continental = d3.geoMercator()
.center([-98.58,39.83])
.translate([width*0.5,height*0.42]) // placed near center
.scale(scale);
let hawaii = d3.geoMercator()
.center([-157.25,20.8])
.scale(scale)
.translate([width*0.35,height*0.87]) // placed near bottom, slightly left of center
let alaska = d3.geoMercator()
.center([-152.5,65])
.translate([width*0.15,height*0.8]) // placed in lower left
.scale(scale*0.3)
Run Code Online (Sandbox Code Playgroud)
当人们移动到极端纬度时,墨卡托确实夸大了大小,因此地理上已经很大的阿拉斯加(超过德克萨斯州大小的两倍)在投影时变得太大了。我已将其缩小以使其适合(这样它大约是投影尺寸的 1/10)。
我们还需要选择何时使用什么投影,因此根据一些规则,我们可以确定一个点是在阿拉斯加、夏威夷还是 48 以内:
let projection = d3.geoTransform({
point: function(x, y) {
if(y < 50 && x < -140) { // south and west : hawaii
this.stream.point(...hawaii([x,y]));
}
else if (y > 50) { // north : alaska
this.stream.point(...alaska([x,y]));
}
else { // otherwise, it's in the lower 48.
this.stream.point(...continental([x,y]));
}
}
});
Run Code Online (Sandbox Code Playgroud)
就是这样,我们有了三个投影和一个方法来确定给定点应该使用哪个投影。
我将把它们全部捆绑起来,以d3.geoMercatorUsa()使其更加独立,我们得到:
let projection = d3.geoTransform({
point: function(x, y) {
this.stream.point(x*2,y*2);
}
});
Run Code Online (Sandbox Code Playgroud)
let scale = 800;
let width = 960;
let height = 500;
let continental = d3.geoMercator()
.center([-98.58,39.83])
.translate([width*0.5,height*0.42]) // placed near center
.scale(scale);
let hawaii = d3.geoMercator()
.center([-157.25,20.8])
.scale(scale)
.translate([width*0.35,height*0.87]) // placed near bottom, slightly left of center
let alaska = d3.geoMercator()
.center([-152.5,65])
.translate([width*0.15,height*0.8]) // placed in lower left
.scale(scale*0.3)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1205 次 |
| 最近记录: |