首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >d3.json albers投影和美国生态区域

d3.json albers投影和美国生态区域
EN

Stack Overflow用户
提问于 2017-02-13 23:55:38
回答 1查看 220关注 0票数 1

我有一个使用mapshaper在线工具创建的topojson文件。我从ftp://newftp.epa.gov/EPADataCommons/ORD/Ecoregions/us/ (us_eco_l3.zip)下载了原始的shapefile。我使用了ESRI的ArcMap 10.2来“溶解”shapefile,所以我最终得到了85个独特的生态区域。然后我使用mapshaper (http://www.mapshaper.org/)将shapefile转换为topojson文件。

但是,我无法让topojson文件在我的网页中正确显示。我怀疑我的预测是错的。但是我不知道我错在哪里。

以下是我在网页中的代码(我使用的是ASP.NET MVC5):

代码语言:javascript
复制
<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;        
}

代码语言:javascript
复制
<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>

感谢任何人的帮助。

EN

回答 1

Stack Overflow用户

发布于 2017-02-14 00:30:53

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

  1. 你的数据已经投影到平面上了,D3 projections取表示椭球体上的点的纬度和经度,并将它们投影到平面上。您可以看到,数据已经投影到作为shapefile一部分的.prj文件中:

PROJCS["USA_Contiguous_Albers_Equal_Area_Conic_USGS_version",...

您可以通过使用项目工具(ArcToolbox->Data Management->Projections and Transformations-> ArcMap )在项目中修复此问题,并将projection设置为WGS84。或者,在MapShaper中(确保也将prj文件复制到窗口中),在控制台中键入proj wgs84

虽然使用NAD83作为数据不太可能产生任何问题(尤其是在北美),但D3要求数据采用较长格式,WGS84是最理想的。

  1. 阿尔伯斯投影的投影参数设置不正确。如果您设置阿尔伯斯投影具有0,0旋转和中心点(并缩小到类似.scale(150)的内容),您将得到类似于:

代码语言:javascript
复制
d3.geo.albers()
  .rotation([0,0])
  .center([0,0])

如果您只使用中心来关注您感兴趣的区域,您将简单地将此图像平移到您感兴趣的区域,自然地,美国将以一种最不希望看到的方式旋转。相反,您希望按经度旋转地球,以便感兴趣的区域在中间垂直对齐。对于美国,您希望将地球在投影下旋转100度(这样-100度现在位于中心,而子午线在-100处是垂直的)。因为你在旋转地球,所以你想要你所关注的经度的负数。通过应用100,0的旋转,我们得到如下结果:

代码语言:javascript
复制
d3.geo.projection()
  .rotation([100,0])
  .center([0,0])

现在,您可以沿y轴向上平移以找到您感兴趣的区域。当然,使用适当的比例因子放大所有需要的内容。

如果你现在以x为中心,比方说-50,你是相对于你的旋转,将本初子午线放在西边100度,所以你实际上是在西边150度)

阿尔伯斯投影还设置了平行线,即地球上与锥形投影相交的线,就像阿尔伯斯投影一样,像帽子一样放在地球上。这些应该在你感兴趣的区域,但不是北端和南端,因为失真在它们的两边都是最小的。所有这些都为您提供了一个类似如下的表单:

代码语言:javascript
复制
d3.geo.albers()
  .parallels([a,b])
  .center([0,y])
  .rotate([-x,0])

然而,话虽如此,d3 (至少是v3)中的默认阿尔伯斯预测主要集中在美国:

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

也可以使用投影数据,但这种方法不太常见,并且不能很好地与其他需要投影的数据相匹配

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42208227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档