如何在Altair中使用GeoJSON数据制作地图?

Jon*_*han 4 python geojson topojson vega altair

我对制图和Altair / Vega非常陌生。Altair文档中一个示例,说明如何制作以美国各州的轮廓开始的地图,该地图的创建基本上是这样的:

states = alt.topo_feature(data.us_10m.url, feature='states')

# US states background
background = alt.Chart(states).mark_geoshape(
    fill='lightgray',
    stroke='white'
)
Run Code Online (Sandbox Code Playgroud)

但我想在不列颠群岛上绘制点。由于vega数据集中只有美国和世界地图,因此我必须创建自己的GeoJSON,不是吗?

因此,我尝试通过运行此博客文章中的一些命令行命令世界地图上获取不列颠群岛的GeoJSON ,即,

ogr2ogr -f GeoJSON -where "adm0_a3 IN ('GBR','IRL','IMN','GGY','JEY','GBA')" subunits.json ne_10m_admin_0_map_subunits/ne_10m_admin_0_map_subunits.shp
Run Code Online (Sandbox Code Playgroud)

这似乎已经创建了一个GeoJSON文件subunits.json,它可能代表不列颠群岛。但是我怎样才能把它带入Altair?还是有其他方法可以使用Altair制作不列颠群岛的地图?

Mat*_*ijn 8

您引用的示例在使用topojson结构化数据时使用结构geojson化数据。因此,您可能需要:

# remote geojson data object
url_geojson = 'https://raw.githubusercontent.com/mattijn/datasets/master/two_polygons.geo.json'
data_geojson_remote = alt.Data(url=url_geojson, format=alt.DataFormat(property='features',type='json'))

# chart object
alt.Chart(data_geojson_remote).mark_geoshape(
).encode(
    color="properties.name:N"
).properties(
    projection={'type': 'identity', 'reflectY': True}
)
Run Code Online (Sandbox Code Playgroud)

图表

欲了解更多信息,请继续阅读


解释之间的差异geojsontopojson结构化的json文件,并在牛郎星它们的用法

import geojson
import topojson
import pprint
import altair as alt
Run Code Online (Sandbox Code Playgroud)

内联GeoJSON

我们首先创建一个包含两个要素的集合,即两个相邻的多边形。

我们将以GeoJSON数据格式创建的两个多边形的示例:

具有两个功能的FeatureCollection

feature_1 = geojson.Feature(
    geometry=geojson.Polygon([[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]]),
    properties={"name":"abc"}
)
feature_2 = geojson.Feature(
    geometry=geojson.Polygon([[[1, 0], [2, 0], [2, 1], [1, 1], [1, 0]]]),
    properties={"name":"def"}
)
var_geojson = geojson.FeatureCollection([feature_1, feature_2])
Run Code Online (Sandbox Code Playgroud)

通过漂亮地打印变量来检查创建的GeoJSON var_geojson

pprint.pprint(var_geojson)
Run Code Online (Sandbox Code Playgroud)
{'features': [{'geometry': {'coordinates': [[[0, 0],
                                             [1, 0],
                                             [1, 1],
                                             [0, 1],
                                             [0, 0]]],
                            'type': 'Polygon'},
               'properties': {'name': 'abc'},
               'type': 'Feature'},
              {'geometry': {'coordinates': [[[1, 0],
                                             [2, 0],
                                             [2, 1],
                                             [1, 1],
                                             [1, 0]]],
                            'type': 'Polygon'},
               'properties': {'name': 'def'},
               'type': 'Feature'}],
 'type': 'FeatureCollection'}
Run Code Online (Sandbox Code Playgroud)

可以看出,这两个Polygon Features嵌套在features对象中,并且geometry是每个的一部分feature

Altair能够json使用中的property键来解析嵌套对象format。以下是此类示例:

{'features': [{'geometry': {'coordinates': [[[0, 0],
                                             [1, 0],
                                             [1, 1],
                                             [0, 1],
                                             [0, 0]]],
                            'type': 'Polygon'},
               'properties': {'name': 'abc'},
               'type': 'Feature'},
              {'geometry': {'coordinates': [[[1, 0],
                                             [2, 0],
                                             [2, 1],
                                             [1, 1],
                                             [1, 0]]],
                            'type': 'Polygon'},
               'properties': {'name': 'def'},
               'type': 'Feature'}],
 'type': 'FeatureCollection'}
Run Code Online (Sandbox Code Playgroud)

图表

内联TopoJSON

TopoJSON是GeoJSON的,其中所述的延伸geometryfeatures是从命名为顶层对象称为arcs。这样就可以在几何图形上应用哈希函数,因此每个共享arc仅应存储一次。

我们可以将var_geojson变量转换为topojson文件格式结构:

# inline geojson data object
data_geojson = alt.InlineData(values=var_geojson, format=alt.DataFormat(property='features',type='json')) 

# chart object
alt.Chart(data_geojson).mark_geoshape(
).encode(
    color="properties.name:N"
).properties(
    projection={'type': 'identity', 'reflectY': True}
)
Run Code Online (Sandbox Code Playgroud)
{'arcs': [[[1.0, 1.0], [0.0, 1.0], [0.0, 0.0], [1.0, 0.0]],
          [[1.0, 0.0], [2.0, 0.0], [2.0, 1.0], [1.0, 1.0]],
          [[1.0, 1.0], [1.0, 0.0]]],
 'objects': {'data': {'geometries': [{'arcs': [[-3, 0]],
                                      'properties': {'name': 'abc'},
                                      'type': 'Polygon'},
                                     {'arcs': [[1, 2]],
                                      'properties': {'name': 'def'},
                                      'type': 'Polygon'}],
                      'type': 'GeometryCollection'}},
 'type': 'Topology'}
Run Code Online (Sandbox Code Playgroud)

现在,嵌套geometry对象被替换,arcs并按索引引用到顶级arcs对象。FeatureCollection现在我们可以拥有多个objects,而不是只有一个,我们的转换结果以a FeatureCollection形式存储在密钥dataGeometryCollection

注意:键名data是任意的,并且在每个数据集中都不同。

Altair能够使用其中的键来解析格式化结构中的嵌套data对象,同时声明它是一个。以下是此类示例:topojsonfeatureformattopojson type

var_topojson = topojson.Topology(var_geojson, prequantize=False).to_json()
var_topojson
Run Code Online (Sandbox Code Playgroud)

图表

来自URL的TopoJSON

topojson如果可以通过URL访问该文件,则还存在一种从文件中提取对象的快捷方式:

{'arcs': [[[1.0, 1.0], [0.0, 1.0], [0.0, 0.0], [1.0, 0.0]],
          [[1.0, 0.0], [2.0, 0.0], [2.0, 1.0], [1.0, 1.0]],
          [[1.0, 1.0], [1.0, 0.0]]],
 'objects': {'data': {'geometries': [{'arcs': [[-3, 0]],
                                      'properties': {'name': 'abc'},
                                      'type': 'Polygon'},
                                     {'arcs': [[1, 2]],
                                      'properties': {'name': 'def'},
                                      'type': 'Polygon'}],
                      'type': 'GeometryCollection'}},
 'type': 'Topology'}
Run Code Online (Sandbox Code Playgroud)

topojson使用网址引用文件的Altair示例

# inline topojson data object
data_topojson = alt.InlineData(values=var_topojson, format=alt.DataFormat(feature='data',type='topojson')) 

# chart object
alt.Chart(data_topojson).mark_geoshape(
).encode(
    color="properties.name:N"
).properties(
    projection={'type': 'identity', 'reflectY': True}
)
Run Code Online (Sandbox Code Playgroud)

图表

URL的GeoJSON

但是对于geojson可通过URL访问的文件,则没有这样的缩写,应按以下方式链接:

alt.topo_feature(url, feature)
Run Code Online (Sandbox Code Playgroud)

geojson使用网址引用文件的Altair示例

# remote topojson data object
url_topojson = 'https://raw.githubusercontent.com/mattijn/datasets/master/two_polygons.topo.json'
data_topojson_remote = alt.topo_feature(url=url_topojson, feature='data')

# chart object
alt.Chart(data_topojson_remote).mark_geoshape(
).encode(
    color="properties.name:N"
).properties(
    projection={'type': 'identity', 'reflectY': True}
)
Run Code Online (Sandbox Code Playgroud)

图表