我有一个topojson文件,我使用mapshaper在线工具创建。我从ftp://newftp.epa.gov/EPADataCommons/ORD/Ecoregions/us/下载了原始shapefile (us_eco_l3.zip)。我已经使用ESRI的ArcMap 10.2来解析"解散" shapefile所以我最终得到了85个独特的ecoregions。然后我使用mapshaper(http://www.mapshaper.org/)将shapefile转换为topojson文件。
但是,我无法在我的网页中正确显示topojson文件。我怀疑我的投射是错误的。但我无法弄清楚我哪里出错了。
以下是我的网页中的代码(我使用的是ASP.NET MVC 5):
<style>
.region {
stroke: #fff;
fill: #005DAA;
}
.hover {
fill: yellow;
}
.selected{
stroke: #fff;
fill: #00C800;
}
#regName{
position: absolute;
top: 150px;
height: 22px;
width: 250px;
padding: 3px;
text-align:center;
}
<input type="text" id="regName" disabled />
<div id="map" style="text-align:center">
<h1>US Ecoregions Level III</h1>
<h3 id="reg"></h3>
</div>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script type="text/javascript">
var width = 960,
height = 400,
centered;
var projection = d3.geo.albers()
.center([-96.5, 38.68])
.scale(1000)
.rotate([0, 0]);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height);
queue()
.defer(d3.json, "/topo/ecol3.json")
.await(ready);
function ready(error, us) {
svg.append("g")
.selectAll("path")
.data(topojson.feature(us, us.objects.ecol3).features)
.enter()
.append("path")
.attr("d", path)
.attr("class", "region")
.on("mouseover", function (d) {
d3.select("h3").text(d.properties.US_L3NAME);
d3.select(this).attr("class", "region hover");
})
.on("mouseout", function (d) {
d3.select("h3").text("");
d3.select(this).attr("class", "region");
})
.on("click", function (d) {
var name = d.properties.US_L3NAME;
var region = d3.select("#regName");
region.property("value", name);
});
}
</script>
感谢任何帮助。
答案 0 :(得分:0)
有两个问题导致显示地理数据出现问题。
您的数据已投射到平面上,D3投影采用纬度和经度表示球体上的点并将它们投影到平面上。您可以看到数据已经投影在shapefile中的.prj
文件中:
PROJCS["USA_Contiguous_Albers_Equal_Area_Conic_USGS_version",...
您可以使用项目工具(ArcToolbox-&gt; Data Management-&gt; Projections and Transformations-&gt; Project)在ArcMap中修复此问题,并将投影设置为WGS84。或者,在MapShaper中(确保将prj文件复制到窗口中),在控制台类型proj wgs84
中。
D3要求数据采用长格式,WGS84是最理想的,尽管使用NAD83作为您的数据不会产生任何问题(特别是在北美)。
.scale(150)
的内容),您将获得类似的内容:d3.geo.albers()
.rotation([0,0])
.center([0,0])
如果您只使用中心来关注您感兴趣的区域,您只需将此图像平移到您感兴趣的区域,当然,美国将以最不可能的方式旋转。相反,您希望按经度旋转地球,以便您感兴趣的区域在中间垂直对齐。对于美国,你想要在投影下面旋转地球100度(这样-100度现在位于中心,-100度的子午线是垂直的)。因为你正在旋转地球,你想要你所关注的经度的负面影响。通过应用[100,0]的旋转,我们得到类似的东西:
d3.geo.projection()
.rotation([100,0])
.center([0,0])
现在您可以向下平移y轴以找到您感兴趣的区域。当然,使用适当的比例因子放大所需的一切。
如果你现在以x为中心,比如说-50,那么你将它相对于你的旋转居中,它将本初子午线放置在西经100度,所以你实际上将居中150度以西)
Albers投影也设置了平行线,地球上的线条与锥形投影相交,就像阿尔伯斯一样,像帽子一样放在它上面。这些应该在你感兴趣的领域,而不是北方和南方的极端,因为它们两侧的扭曲最小化。总之,这给你一个像:
的形式d3.geo.albers()
.parallels([a,b])
.center([0,y])
.rotate([-x,0])
然而,说到这一切,d3中的默认Albers投影(至少是v3),主要集中在美国:
这仅仅基于:var projection = d3.geo.albers()
也可以使用投影数据,但这种方法不太常见,也不能与需要投影的其他数据进行网格划分