【问题标题】:Setting a custom projection using d3-geo-projection command line tool使用 d3-geo-projection 命令行工具设置自定义投影
【发布时间】:2018-02-06 07:09:06
【问题描述】:

我正在尝试使用 geoproject 在 geojson 文件上设置投影。具体来说,我正在尝试将投影设置为 BCalbers (http://spatialreference.org/ref/epsg/3005/)

我看到 geoproject 有许多投影选项,即

geoproject 'd3.geoAlbersUsa()' us.json \
  > us-albers.json

但是可以使用命令行工具设置自定义投影吗?我希望这样的事情是可能的:

geoproject '+proj=aea +lat_1=50 +lat_2=58.5 +lat_0=45 +lon_0=-126 +x_0=1000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs' build/airzones.geojson \
  > bc-albers.json

但没有骰子。这适用于 ogr2ogr

ogr2ogr -f GeoJSON -t_srs "+proj=aea +lat_1=50 +lat_2=58.5 +lat_0=45 +lon_0=-126 +x_0=1000000 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs  " \

【问题讨论】:

    标签: d3.js map-projections


    【解决方案1】:

    D3 地理投影支持一系列通用投影(和自定义投影),通常可以重新创建任何给定的特定投影。但是,在重新创建投影时,d3 投影不会复制地图单位*。 D3 投影在 svg 坐标空间中创建单位(投影坐标将从左上角的[0,0] 开始)。这允许跳过投影数据的步骤(通常使用 d3 即时),然后重新缩放和翻译它以显示地图。

    比较:使用引用的d3.geoAlbersUsa(),如果使用默认比例,d3 将沿 x 轴投影大约 960 像素的数据。非常适合在 SVG 中未经修改使用 - 坐标可以用作直接 SVG 坐标。在 ArcGIS 或 QGIS 中使用 BC Albers 将投影数百万米的数据。

    但是,除了单位之外,您可以重新创建一个按比例缩放的 BC Albers,以保留常规 BC Albers 的形状、距离、方向和面积。但由于 d3 不采用 .prj 文件等投影定义或其他定义,因此您需要使用 d3 的投影方法和适当的参数。

    对于 BC 阿尔伯斯,您的平行线是:50 和 58.5,您的中心经度是 -126,您的投影类型是阿尔伯斯。这就是您所需要的 - (错误的)东/北参考是重新创建地图单位 - 在 Web 场景中通常不需要(如果您这样做,使用更完整的 GIS 平台会更合适)。

    因此,要设置投影,您可以使用:

    d3.geoAlbers()
      .center([0,y])
      .rotate([-x,0])
      .parallels([a,b])
      .scale(k)
    

    在哪里

    x = center longitude (negative because we rotate the globe under the map)
    
    a, b = standard parallels
    
    k = scale factor(for a d3.geoAlbers(): whole world is 960 px across with a scale of 1070, the default scale, larger numbers expand this/zoom in)
    
    y = centering latitude.
    

    注意:y 不会改变投影,它只是转换它 - BC Albers 的 y 参考位于 BC 以南,它只是北向的参考,因为它对地图形状、面积、距离没有影响,或方向。对于 BC Albers,我可能会选择 50.5,因为它位于育空边界和华盛顿边界之间,这是 BC 的北部和南部边界(嗯,除了温哥华岛和一些海湾群岛,假设 50 度北,对不起,我忘了你维多利亚)。

    还请记住,d3 的投影功能假设数据是未投影的(或 WGS84 中的“投影”),由长纬度对组成。

    您可以在他的命令行制图文章here 中了解 Mike Bostock 如何使用这些方法:

    geoproject 'd3.geoConicEqualArea().parallels([34, 40.5]).rotate([120, 0]).fitSize([960, 960], d)' < ca.json > ca-albers.json
    

    fitSize 在此示例中缩放并将特征转换为指定的边界框 - 此平移和缩放不会改变投影参数,并且与 center 方法中的 y 坐标一样,不会改变距离、面积、形状或角度(嗯,距离和面积仍然与适当的 BC 阿尔伯斯成正比)。

    *您可以重新创建地图单位(假东/北可能需要一些自定义投影工作),但这并不是真正的平台,使用许多其他平台会更容易。

    另请参阅此问答:Converting EPSG projection bounds to a D3.js

    【讨论】:

    • 我告诉过你一次,我会再告诉你一次:创建一个标签d3-geo,或者任何类似的东西,并带有一个很好的描述。这不仅对未来的用户提出/定位与地理相关的 D3 问题很有好处,而且您将很快成为最佳回答者。
    • 我记得,我正在解决这个问题 - 删除已故 SO 文档的链接(通常也是 d3 投影主题),当然,会从其他人也可以使用 d3 投影/地理标记。
    • 感谢您周到的回答,不要忘记我们维多利亚人!很高兴有一个清晰的解释。我想太多了。
    • @AndrewReid 多么好的答案,再次!但是,我不认为比例因子 k 的解释是 “以像素为单位的投影宽度” 是正确的还是我遗漏了什么?对于d3.geoAlbers() 投影,比例默认为 1070 而默认宽度等于 960
    • @altocumulus,是的,你是对的,现在更新答案,感谢您的注意。
    猜你喜欢
    • 2012-08-14
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 2015-07-01
    • 1970-01-01
    • 2017-09-04
    • 2014-11-27
    相关资源
    最近更新 更多