使用两个 quantized/transformed topojson 构建一个统一的 topojson?
Building a uniform topojson with two quantized/transformed topojsons?
背景
我正在制作一张显示美国地图的地图。在这张地图上,我绘制了与 Nielsen DMA 地形相对应的热圈。
我使用的第一个 topojson 是这个 Nielsen DMA topojson(来自 simzhou 的 repo here),用于在美国地图上直观地绘制这些热圈。
下面你可以看到地图,有 DMA 热圈,还有完全根据 Nielsen DMA 拓扑构建的 DMA 边界线json。
问题:
我遇到的问题是尝试绘制州边界线,而不是这些 DMA 边界线。我引入了@mbostock 为我们提供的“https://unpkg.com/us-atlas@1/us/10m.json”。当通过 topojson.feature(us, us.objects.states).features
绘制州边界时(我也尝试过 topojson.mesh
),那就是事情出错的时候。我 99% 确定这是因为两个 json 文件使用不同的 transform
值,因此 positions/coordinates 以不同的比例进行转换。
这是两个 json:Nielsen DMA here and the US here
您可以在下面看到转换对象的不同之处:
从美国地图集转换对象
"transform": {
"scale": [0.009995801851947097,0.005844667153098606],
"translate":[-56.77775821661018,12.469025989284091]
}
从 DMA 拓扑json
转换对象
"transform": {
"scale": [0.00577894299429943, 0.002484260626062607],
"translate": [-124.732975, 24.544237]
},
这是我到目前为止所做的。
方法:
1。通过 GeoJSON 往返
如 Bostock 所详述 here 我已经尝试制作一个新的 topoJSON "via a round trip through GeoJSON."
Quantized → non-quantized, to remove quantization. This is often done temporarily to process data (for example, topojson.presimplify). I suppose you might want this so that you could combine topologies with different quantized transforms, but you could always do this by making a round trip through GeoJSON.
对于每个 json
1. 我将它们从 topoJSON 转换为 geoJSON。
topo2geo nielsen_dma=us-dma-geo.json < us-dma-topo.json
现在对于每个 json 我们都有一个带有绝对坐标的特征集合。
2. 使用新的 geoJSON,然后我通过 CLI 将它们转换回 topoJSON。
geo2topo nielsen_dma=us-dma-geo.json > us-dma-topo.json
两个 JSON 不再有 transform
属性,但它们有 bbox
。
3. 现在我让两个 json 从 topojson -> geojson -> topojson 往返一次。
4. 我从两个 json 中删除了 bbox
属性,因为它们是 optional.
5. 然后我简单地将一个的几何集合添加到另一个。 statesJSON.objects.nielsen_dma = dmaJSON.objects.nielsen_dma
我现在有一个具有 nielsen_dma
和 states
几何形状的拓扑 json。然而这还是不行,画州界线会带来混乱。
在 geoJSON 的往返过程中,我是否未能删除两个 json 的坐标量化?
可能(不)相关的问题:
- Nielsen DMA 地图不包括阿拉斯加和夏威夷的几何图形。两个 json 之间的这种差异会导致这个问题吗?
当我第一次阅读这篇文章时,我试图解决评论中的潜在问题(为此我有点错过了标记,因为我认为显示地图的代码看起来有点不同可能是 - 我为误读道歉)。然而,在第二次检查中,我意识到虽然问题是 x,y problem,但尝试的解决方案导致了一些关于 D3 和 topojson 的有趣问题,这些问题并没有立即明确——但潜在的问题仍然是混合的投影和未投影数据,所以我将尝试在此处同时解决 x 和 y:
拓扑json
Topojson 本质上是一种通过编码拓扑和可选的量化增量编码整数坐标来存储 geojson 特征或特征 类 的方法。 Topojson 本身不会改变底层坐标,它会改变它们的表示。
为了在 D3 中使用 topojson,我们需要将其转换回 geojson,因为 D3 geoPaths 只接受 geojson - topojson.feature( ) returns地理json.
痛苦的根本来源
最终的问题根本不是拓扑json引起的。您有两个使用不同坐标系的拓扑源:
美国json使用二维笛卡尔坐标space(用阿尔伯斯投影投影的特征)。未压缩的坐标是 SVG 像素。
Nielsen json 使用 latitude/longitude 坐标 space(3d 地球上的点)。未压缩坐标不是笛卡尔坐标(除非应用直线 Plate Carree 投影:long = x, lat = y)。
当美国 json 通过 topojson.feature()
时,返回的 geojson 的 x,y 值将在大约 [0,0],[960,600 的边界框内] (在这种情况下)。当任何未投影的 topojson(Nielsen json for exmaple)通过 topojson.feature()
时,返回的 geojson 将在 [-180] 的边界框内具有 long,lat 值,90],[180,-90] - 即它将具有有效的 long/lat 对。
这些潜在的和不同的坐标系是问题所在,而不是拓扑中坐标的表示json。
组合拓扑json
我不确定您如何将两者结合的细节。 topojson 将 geojson 分成组成部分 - 弧和特征(引用弧并保存特征属性)。弧以数字方式引用 - 如果您没有修改索引,则不能只使用:
statesJSON.objects.nielsen_dma = dmaJSON.objects.nielsen_dma
但是,即使您确实修改了弧索引并引入了不在 statesJSON 中但在 dmaJSON 中的弧,您仍然 运行 会遇到问题。这是因为我们还在使用不同的坐标系。
topojson 使用的变换包括缩放和平移 - 投影数据使用 Albers 投影,未投影数据不使用任何投影,但可以使用Plate Carree 投影(long=x,lat=y)。但是 Plate Carree 的纬度是直的(它是等距柱状投影),而 Albers 的纬度是弯曲的(它是圆锥投影)。因此,相同特征在每个坐标系中的形状将不同。每个坐标系之间的方向也会有所不同(在 Albers 上的大多数地方,东不是直接向右)。您不能使用平移和缩放修改形状和方向。
不同拓扑json变换
I am 99% sure that this is because the two json files are using different transform values, and therefore the positions/coordinates are transformed on different scales.
很少会使用两个具有相同变换值的拓扑json 文件,边界框也是如此。变换仅对再现用于创建拓扑 json 的原始坐标至关重要。它的值只与将编码的 topojson 坐标转换回原始 (geojson) 坐标有关。该变换特定于该拓扑 json 的坐标。
最终,转换在使用 D3 时不相关:用于创建拓扑的原始坐标 json 是 D3 实际使用的坐标,直到 topojson.feature()
。变换本质上是无关紧要的 - 只要它对于编码和解码是恒定的。
我该如何解决这个问题?
您有一个投影文件(美国 json),您不知道用于创建它的投影。在不知道用于创建它的投影的情况下,您无法对 Nielsen 数据应用相同的投影。 即使您可以通过 d3 geoProjection 运行 Nielsen 数据,使其覆盖美国数据(使用空投影),您也不应该这样做。不同的坐标系在缩放、平移或设置诸如居中坐标之类的东西时很麻烦 - 它需要单独的代码来处理未投影和投影的数据,本质上是重复代码
这意味着您需要为美国寻找新的数据源。幸运的是有很多在线资源,例如这里有两个:excessive size for web or reasonable size for web。如果需要,可以使用 mapshaper.org 转换为 topojson(并简化文件)。
对于未投影的美国 geojson/topojson(long/lat 对),您现在有两个共享同一坐标系的文件。 topojson 变换对于每个都不同(如果两者都使用 topojson),这无关紧要,重要的是底层坐标在同一坐标 space 中,而不是它们在 topojson 中的量化表示使用相同的变换。
这是一个使用未投影的美国各州 geojson 的基本示例(来自第二个链接的 geojson,转换为 topojson):
https://bl.ocks.org/andrew-reid/178445c6acd84aa3b43525076f277157
背景
我正在制作一张显示美国地图的地图。在这张地图上,我绘制了与 Nielsen DMA 地形相对应的热圈。
我使用的第一个 topojson 是这个 Nielsen DMA topojson(来自 simzhou 的 repo here),用于在美国地图上直观地绘制这些热圈。
下面你可以看到地图,有 DMA 热圈,还有完全根据 Nielsen DMA 拓扑构建的 DMA 边界线json。
问题:
我遇到的问题是尝试绘制州边界线,而不是这些 DMA 边界线。我引入了@mbostock 为我们提供的“https://unpkg.com/us-atlas@1/us/10m.json”。当通过 topojson.feature(us, us.objects.states).features
绘制州边界时(我也尝试过 topojson.mesh
),那就是事情出错的时候。我 99% 确定这是因为两个 json 文件使用不同的 transform
值,因此 positions/coordinates 以不同的比例进行转换。
这是两个 json:Nielsen DMA here and the US here
您可以在下面看到转换对象的不同之处:
从美国地图集转换对象
"transform": {
"scale": [0.009995801851947097,0.005844667153098606],
"translate":[-56.77775821661018,12.469025989284091]
}
从 DMA 拓扑json
转换对象"transform": {
"scale": [0.00577894299429943, 0.002484260626062607],
"translate": [-124.732975, 24.544237]
},
这是我到目前为止所做的。
方法:
1。通过 GeoJSON 往返
如 Bostock 所详述 here 我已经尝试制作一个新的 topoJSON "via a round trip through GeoJSON."
Quantized → non-quantized, to remove quantization. This is often done temporarily to process data (for example, topojson.presimplify). I suppose you might want this so that you could combine topologies with different quantized transforms, but you could always do this by making a round trip through GeoJSON.
对于每个 json
1. 我将它们从 topoJSON 转换为 geoJSON。
topo2geo nielsen_dma=us-dma-geo.json < us-dma-topo.json
现在对于每个 json 我们都有一个带有绝对坐标的特征集合。
2. 使用新的 geoJSON,然后我通过 CLI 将它们转换回 topoJSON。
geo2topo nielsen_dma=us-dma-geo.json > us-dma-topo.json
两个 JSON 不再有 transform
属性,但它们有 bbox
。
3. 现在我让两个 json 从 topojson -> geojson -> topojson 往返一次。
4. 我从两个 json 中删除了 bbox
属性,因为它们是 optional.
5. 然后我简单地将一个的几何集合添加到另一个。 statesJSON.objects.nielsen_dma = dmaJSON.objects.nielsen_dma
我现在有一个具有 nielsen_dma
和 states
几何形状的拓扑 json。然而这还是不行,画州界线会带来混乱。
在 geoJSON 的往返过程中,我是否未能删除两个 json 的坐标量化?
可能(不)相关的问题:
- Nielsen DMA 地图不包括阿拉斯加和夏威夷的几何图形。两个 json 之间的这种差异会导致这个问题吗?
当我第一次阅读这篇文章时,我试图解决评论中的潜在问题(为此我有点错过了标记,因为我认为显示地图的代码看起来有点不同可能是 - 我为误读道歉)。然而,在第二次检查中,我意识到虽然问题是 x,y problem,但尝试的解决方案导致了一些关于 D3 和 topojson 的有趣问题,这些问题并没有立即明确——但潜在的问题仍然是混合的投影和未投影数据,所以我将尝试在此处同时解决 x 和 y:
拓扑json
Topojson 本质上是一种通过编码拓扑和可选的量化增量编码整数坐标来存储 geojson 特征或特征 类 的方法。 Topojson 本身不会改变底层坐标,它会改变它们的表示。
为了在 D3 中使用 topojson,我们需要将其转换回 geojson,因为 D3 geoPaths 只接受 geojson - topojson.feature( ) returns地理json.
痛苦的根本来源
最终的问题根本不是拓扑json引起的。您有两个使用不同坐标系的拓扑源:
美国json使用二维笛卡尔坐标space(用阿尔伯斯投影投影的特征)。未压缩的坐标是 SVG 像素。
Nielsen json 使用 latitude/longitude 坐标 space(3d 地球上的点)。未压缩坐标不是笛卡尔坐标(除非应用直线 Plate Carree 投影:long = x, lat = y)。
当美国 json 通过 topojson.feature()
时,返回的 geojson 的 x,y 值将在大约 [0,0],[960,600 的边界框内] (在这种情况下)。当任何未投影的 topojson(Nielsen json for exmaple)通过 topojson.feature()
时,返回的 geojson 将在 [-180] 的边界框内具有 long,lat 值,90],[180,-90] - 即它将具有有效的 long/lat 对。
这些潜在的和不同的坐标系是问题所在,而不是拓扑中坐标的表示json。
组合拓扑json
我不确定您如何将两者结合的细节。 topojson 将 geojson 分成组成部分 - 弧和特征(引用弧并保存特征属性)。弧以数字方式引用 - 如果您没有修改索引,则不能只使用:
statesJSON.objects.nielsen_dma = dmaJSON.objects.nielsen_dma
但是,即使您确实修改了弧索引并引入了不在 statesJSON 中但在 dmaJSON 中的弧,您仍然 运行 会遇到问题。这是因为我们还在使用不同的坐标系。
topojson 使用的变换包括缩放和平移 - 投影数据使用 Albers 投影,未投影数据不使用任何投影,但可以使用Plate Carree 投影(long=x,lat=y)。但是 Plate Carree 的纬度是直的(它是等距柱状投影),而 Albers 的纬度是弯曲的(它是圆锥投影)。因此,相同特征在每个坐标系中的形状将不同。每个坐标系之间的方向也会有所不同(在 Albers 上的大多数地方,东不是直接向右)。您不能使用平移和缩放修改形状和方向。
不同拓扑json变换
I am 99% sure that this is because the two json files are using different transform values, and therefore the positions/coordinates are transformed on different scales.
很少会使用两个具有相同变换值的拓扑json 文件,边界框也是如此。变换仅对再现用于创建拓扑 json 的原始坐标至关重要。它的值只与将编码的 topojson 坐标转换回原始 (geojson) 坐标有关。该变换特定于该拓扑 json 的坐标。
最终,转换在使用 D3 时不相关:用于创建拓扑的原始坐标 json 是 D3 实际使用的坐标,直到 topojson.feature()
。变换本质上是无关紧要的 - 只要它对于编码和解码是恒定的。
我该如何解决这个问题?
您有一个投影文件(美国 json),您不知道用于创建它的投影。在不知道用于创建它的投影的情况下,您无法对 Nielsen 数据应用相同的投影。 即使您可以通过 d3 geoProjection 运行 Nielsen 数据,使其覆盖美国数据(使用空投影),您也不应该这样做。不同的坐标系在缩放、平移或设置诸如居中坐标之类的东西时很麻烦 - 它需要单独的代码来处理未投影和投影的数据,本质上是重复代码
这意味着您需要为美国寻找新的数据源。幸运的是有很多在线资源,例如这里有两个:excessive size for web or reasonable size for web。如果需要,可以使用 mapshaper.org 转换为 topojson(并简化文件)。
对于未投影的美国 geojson/topojson(long/lat 对),您现在有两个共享同一坐标系的文件。 topojson 变换对于每个都不同(如果两者都使用 topojson),这无关紧要,重要的是底层坐标在同一坐标 space 中,而不是它们在 topojson 中的量化表示使用相同的变换。
这是一个使用未投影的美国各州 geojson 的基本示例(来自第二个链接的 geojson,转换为 topojson):
https://bl.ocks.org/andrew-reid/178445c6acd84aa3b43525076f277157