如何在Altair中使用GeoJSON数据制作地图? [英] How can I make a map using GeoJSON data in Altair?

查看:136
本文介绍了如何在Altair中使用GeoJSON数据制作地图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对制图和Altair/Vega非常陌生. Altair文档中有一个示例,用于说明如何以美国各州的轮廓开始制作地图,它基本上是通过以下方式创建的:

I'm very new to mapping, and to Altair/Vega. There's an example in the Altair documentation for how to make a map starting with an outline of US states, which is created basically with:

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

# US states background
background = alt.Chart(states).mark_geoshape(
    fill='lightgray',
    stroke='white'
)

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

but I want to plot points in the British Isles, instead. Since there are only US and World maps in the vega data collections, I would have to create my own GeoJSON, no?

因此,我尝试通过运行一些命令行命令

So I tried getting GeoJSON for the British Isles from a world map, by running some of the command-line commands from this blog post, namely,

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

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

This seems to have created a GeoJSON file, subunits.json, which probably represents the British Isles. But how can I get this into Altair? Or is there another way to make a map of the British Isles using Altair?

推荐答案

您引用的示例使用的是topojson结构化数据,而您拥有的是geojson结构化数据.因此,您可能需要:

The example you refer to is using topojson structured data, while you have geojson structured data. So you probably need:

# 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}
)

有关更多信息,请继续阅读

For more insight read on

更新:由于Altair版本3.3.0是GeoDataFrame(geopandas)直接

Update: since Altair version 3.3.0 are GeoDataFrame (geopandas) directly supported. So do any objects that support the __geo_interface__.

以下讨论了这些变体:

  1. 内联GeoJSON
  2. 内联TopoJSON
  3. 来自URL的TopoJSON
  4. 来自URL的GeoJSON

解释geojsontopojson结构化的json文件之间的区别以及它们在Altair中的用法

Explaining the differences between geojson and topojson structured json files and their usage within Altair

import geojson
import topojson
import pprint
import altair as alt

内联GeoJSON

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

Inline GeoJSON

We start with creating a collection containing two features, namely two adjacent polygons.

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

Example of the two polygons that we will create in the GeoJSON data format.:

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])

通过漂亮地打印变量var_geojson

pprint.pprint(var_geojson)

{'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'}

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

As can be seen, the two Polygon Features are nested within the features object and the geometry is part of each feature.

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

Altair has the capability to parse nested json objects using the property key within format. The following is an example of such:

# 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}
)

TopoJSON是GeoJSON的扩展,其中featuresgeometry是从名为arcs的顶级对象引用的.这样就可以在几何图形上应用哈希函数,因此每个共享的arc仅应存储一次.

TopoJSON is an extension of GeoJSON, where the geometry of the features are referred to from a top-level object named arcs. This makes it possible to apply a hash function on the geometry, so each shared arc should only be stored once.

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

We can convert the var_geojson variable into a topojson file format structure:

var_topojson = topojson.Topology(var_geojson, prequantize=False).to_json()
var_topojson

{'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'}

现在,嵌套的geometry对象被arcs替换,并通过索引引用到顶级arcs对象.现在我们可以拥有多个objects,而不是只有一个FeatureCollection,我们转换后的FeatureCollection会以GeometryCollection的形式存储在键data中.

Now the nested geometry objects are replaced by arcs and refer by index to the top-level arcs object. Instead of having a single FeatureCollection we now can have multiple objects, where our converted FeatureCollection is stored within the key data as a GeometryCollection.

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

NOTE: the key-name data is arbitrary and differs in each dataset.

Altair能够使用format中的feature键解析topojson格式的结构中嵌套的data对象,同时声明它是topojson type.以下是此类示例:

Altair has the capability to parse the nested data object in the topojson formatted structure using the feature key within format, while declaring it is a topojson type. The following is an example of such:

# 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}
)

如果可以通过URL访问该文件,也可以从topojson文件中提取对象:

There also exist a shorthand to extract the objects from a topojson file if this file is accessible by URL:

alt.topo_feature(url, feature)

Altair示例,其中topojson文件由URL引用

Altair example where a topojson file is referred by URL

# 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}
)

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

But for geojson files accessible by URL there is no such shorthand and should be linked as follows:

alt.Data(url, format)

Altair示例,其中geojson文件由URL引用

Altair example where a geojson file is referred by URL

# 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}
)

这篇关于如何在Altair中使用GeoJSON数据制作地图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆