对 SQLite 表中的行进行地理编码
使用 pip
或 pipx
安装此工具
# install inside a virtualenv
pip install geocode-sqlite
# install globally
pipx install geocode-sqlite
假设您有一个包含地址的电子表格,并且想要将这些位置映射出来。首先,使用 sqlite-utils
创建一个 SQLite 数据库并将电子表格中的行插入其中。
sqlite-utils insert data.db data data.csv --csv
现在,使用 OpenStreetMap 的 Nominatim 地理编码器对其进行地理编码。
geocode-sqlite nominatim data.db data \
--location="{address}, {city}, {state} {zip}" \
--delay=1 \
--user-agent="this-is-me"
在上面的命令中,您使用的是 Nominatim,它是免费的,只需要一个唯一的用户代理(--user-agent
)。
这将连接到数据库 (data.db
) 并读取表 data
中的所有行(跳过任何已填充 latitude
和 longitude
列的行)。
您还在告诉地理编码器如何使用 Python 的内置字符串格式从数据行中提取位置查询(--location
),并设置每秒一个请求的速率限制(--delay
)。
对于地理编码成功的每一行,都会填充 latitude
和 longitude
。如果遇到错误或达到速率限制,请再次运行相同的查询,从中断的地方继续。
可以使用 datasette-cluster-map 将结果表布局可视化。
在底层,此软件包使用了优秀的 geopy 库,该库稳定且经过充分实践检验。如果您需要帮助理解特定地理编码器的选项,请查阅 geopy 的文档。
CLI 目前支持这些地理编码器
bing
googlev3
mapquest
(和open-mapquest
)mapbox
nominatim
opencage
- 以地理编码服务的名称作为议题标题提出议题(示例)。将任何值得注意的实现细节放在议题正文中,例如如果需要 API 密钥,在哪里获取。
- Fork 仓库并添加一个地理编码器。
- 在
Makefile
中添加示例。如果新增了共享功能,请添加测试。
每个地理编码器需要知道在哪里找到它处理的数据。这是前两个参数
database
: SQLite 文件的路径,必须已存在table
: 该数据库中已存在且包含待地理编码数据的表的名称
此外,我们还有一组传递给每个地理编码器的选项
location
: 一个 字符串格式,将用每行数据进行展开,以构建完整的待地理编码查询delay
: 每次调用之间的延迟(某些服务要求此项)latitude
: 纬度列名longitude
: 经度列名geojson
: 将结果存储为 GeoJSON,而不是存储在 latitude 和 longitude 列中spatialite
: 将结果存储在 SpatiaLite 几何列中,而不是存储在 latitude 和 longitude 列中raw
: 将原始地理编码结果存储在 JSON 列中
每个地理编码器除上述选项外,还接受额外的特定参数,例如 API 密钥。同样,geopy 的文档 是一个极好的资源。
--spatialite
标志会将结果存储在 几何列 中,而不是存储在 latitude
和 longitude
列中。如果您正在进行其他 GIS 操作,例如使用 空间索引,这将非常有用。请参阅 SpatiaLite 手册 和 函数列表,了解更多可能性。
地理编码服务通常返回的不仅仅是坐标数据。这可能包括精度、标准化地址或其他上下文信息。可以使用 --raw
标志捕获这些信息。默认情况下,这将添加一个 raw
列并将完整的地理编码响应存储为 JSON。如果您想重命名该列,请传递一个值,例如 --raw custom_raw
。
此响应对象的结构会因服务而异。您可以使用 SQLite 的内置 JSON 函数 查询特定值。例如,这适用于 Google 的地理编码器
select
json_extract(raw, '$.formatted_address') as address,
json_extract(raw, '$.geometry.location_type') as location_type
from
innout_test
请查阅各地理编码服务的文档,了解响应中包含哪些内容。
命令行界面旨在支持每个地理编码器最常用的选项。如需更精细的控制,请使用 Python API。
与 CLI 一样,这假设您已经有一个 SQLite 数据库和包含位置数据的表。
from geocode_sqlite import geocode_table
from geopy.geocoders import Nominatim
# create a geocoder instance, with some extra options
nominatim = Nominatim(user_agent="this-is-me", domain="nominatim.local.dev", scheme="http")
# assuming our database is in the same directory
count = geocode_table("data.db", "data", query_template="{address}, {city}, {state} {zip}")
# when it's done
print(f"Geocoded {count} rows")
任何 geopy 地理编码器 都可以与 Python API 一起使用。
要为这个工具贡献代码,首先检出代码。然后创建一个新的虚拟环境
cd geocode-sqlite
python -m venv .venv
source .venv/bin/activate
或者如果您使用的是 pipenv
pipenv shell
现在安装依赖和测试
pip install -e '.[test]'
运行测试
pytest
请记住,这个库主要是其他经过充分测试的项目(特别是:click、geopy 和 sqlite-utils)之间的“胶水”代码。测试应侧重于确保这些部分正确地连接在一起。我们可以假设这些部分本身已经正常工作。
为此,其中包含一个测试地理编码器:geocode_sqlite.testing.DummyGeocoder
。该地理编码器配合 AllThePlaces 提供的 In-N-Out Burger 位置数据集使用。它像一个普通的 GeoPy 地理编码器一样工作,但只使用包含的数据库返回 In-N-Out 位置的结果。