d3.json表示预测和美国生态区域

时间:2017-02-13 15:55:38

标签: d3.js topojson

我有一个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>

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

有两个问题导致显示地理数据出现问题。

  1. 您的数据已投射到平面上,D3投影采用纬度和经度表示球体上的点并将它们投影到平面上。您可以看到数据已经投影在shapefile中的.prj文件中:

    PROJCS["USA_Contiguous_Albers_Equal_Area_Conic_USGS_version",...

  2. 您可以使用项目工具(ArcToolbox-&gt; Data Management-&gt; Projections and Transformations-&gt; Project)在ArcMap中修复此问题,并将投影设置为WGS84。或者,在MapShaper中(确保将prj文件复制到窗口中),在控制台类型proj wgs84中。

    D3要求数据采用长格式,WGS84是最理想的,尽管使用NAD83作为您的数据不会产生任何问题(特别是在北美)。

    1. Albers投影的投影参数设置不正确。如果您将Albers投影设置为[0,0]旋转和居中点(并缩小到喜欢.scale(150)的内容),您将获得类似的内容:
    2. enter image description here

      d3.geo.albers()
        .rotation([0,0])
        .center([0,0])
      

      如果您只使用中心来关注您感兴趣的区域,您只需将此图像平移到您感兴趣的区域,当然,美国将以最不可能的方式旋转。相反,您希望按经度旋转地球,以便您感兴趣的区域在中间垂直对齐。对于美国,你想要在投影下面旋转地球100度(这样-100度现在位于中心,-100度的子午线是垂直的)。因为你正在旋转地球,你想要你所关注的经度的负面影响。通过应用[100,0]的旋转,我们得到类似的东西:

      enter image description here

      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),主要集中在美国:

      enter image description here

      这仅仅基于:var projection = d3.geo.albers()

      也可以使用投影数据,但这种方法不太常见,也不能与需要投影的其他数据进行网格划分