Python GIS 脚本编程(四)

原文:zh.annas-archive.org/md5/14eca96eb97dc47d28f8de5385dca806

译者:飞龙

协议:CC BY-NC-SA 4.0

第十四章:云地理数据库分析和可视化

本章将介绍 CARTOframes,这是一个由位置智能软件公司 CARTO 于 2017 年 11 月发布的 Python 包。它提供了一个 Python 接口来处理 CARTO 栈,使 CARTO 地图、分析和数据服务能够集成到数据科学工作流程中。

本章将涵盖以下主题:

  • CARTOframes Python 库的详细信息
  • 熟悉 CARTO 栈以及 CARTOframes 如何与它的不同部分交互
  • 如何安装 CARTOframes、其包依赖项和文档
  • CARTOframes 的不同包依赖项
  • 如何获取 CARTO API 密钥
  • 设置 CARTO Builder 账户
  • 虚拟环境
  • 使用 Jupyter Notebook
  • 安装 GeoPandas

考虑到数据科学家,CARTOframes 是一种数据科学工具,它将 CARTO 的 SaaS 提供和 Web 地图工具与 Python 数据科学工作流程相结合。由 CARTO(www.carto.com)于 2017 年末发布,可通过 GitHub 和 Python 包索引PyPI)存储库下载。

该包可以被视为一种将 CARTO 元素与数据科学工作流程集成的方式,使用 Jupyter Notebooks 作为工作环境。这不仅使其对数据科学家具有吸引力,还允许您通过 Jupyter Notebooks 保存和分发代码和工作流程。这些数据科学工作流程可以通过使用 CARTO 的服务进行扩展,例如托管、动态或静态地图和来自 CARTO 数据观测站的数据集——所有这些都可以通过 CARTO 的云平台获得。该平台通过 API 密钥访问,当在 Jupyter Notebook 中使用 CARTOframes 时需要使用该密钥。我们将简要描述如何获取 API 密钥以及如何安装 CARTOframes 包。

该包提供了读取和写入不同类型空间数据的功能。例如,您可以将 pandas 数据框写入 CARTO 表,也可以将 CARTO 表和查询读入 pandas 数据框。CARTOframes 包将 CARTO 的外部数据位置数据服务引入 Jupyter Notebook,例如位置数据服务、基于云的数据存储、CARTOColors(一套基于地图上颜色使用标准的自定义调色板)、PostGIS 和动画地图。

使用 CARTOframes 的一个很好的理由是其绘图功能。它是对 GeoPandas、matplotlib、Folio 和 GeoNotebook 等其他地图绘图包的良好替代品。所有这些包都有其优点和缺点。例如,matplotlib 是一个不易学习的包,制作基本地图需要大量代码。而 CARTOframes 则不是这样,其结果看起来令人印象深刻,尤其是在使用颜色、结合动态图像(时间流逝)和易于阅读、编写、查询、绘图和删除数据的命令方面。

如何安装 CARTOframes

CARTOframes 库的最佳安装方式是通过启动 Anaconda Navigator 并创建一个新的环境。从那里,你可以打开一个终端并使用 pip install,这将为你安装库。这是目前安装它的唯一方式(目前还没有 conda 支持)。使用以下命令:

>>pip install cartoframes 

其他资源

CARTOframes 文档可以在以下网址找到:CARTOframes.readthedocs.io/en/latest/.

CARTOframes 的当前版本是 0.5.5。CARTOframes 的 PyPi 仓库可以通过以下网址访问:pypi.python.org/pypi/CARTOframes

此外,还有一个包含额外信息的 GitHub 仓库,作为许多 CARTO GitHub 仓库之一:github.com/CARTODB/CARTOframes.

Jupyter Notebooks

建议在 Jupyter Notebooks 中使用 CARTOframes。在本章后面的示例脚本中,我们将使用 CARTOframes 包与其他地理空间包一起使用,因此你可能希望与 GeoPandas 一起在虚拟环境中安装它,这样你就可以访问其依赖项。请参考 第二章 中 GeoPandas 和其他库的安装指南,地理空间代码库简介。你可以在单独的 Python 环境中使用以下命令安装 Jupyter Notebook 应用程序,在终端窗口中:

>>pip install jupyter 

CARTO API 密钥

安装 CARTOframes 后,我们需要创建一个 CARTO API 密钥,以便能够使用库中的功能。该库与 CARTO 基础设施交互,类似于第九章 ArcGIS API for Python 和 ArcGIS Online 中的 ArcGIS API for Python。API 密钥可用于将数据帧写入账户、从私有表中读取以及将数据可视化在地图上。CARTO 为教育和非营利用途等提供了 API 密钥。如果你是学生,可以通过注册 GitHub 的学生开发者包来获取 API 密钥:education.github.com/pack.

另一个选择是成为 CARTO 使节:

carto.com/community/ambassadors/.

包依赖项

CARTOframes 依赖于一些 Python 库,一旦运行 pip 安装命令,这些库就会自动安装。以下 Python 库会被安装:

  • ipython:提供用于交互式使用 Python 的丰富工具包
  • appdirs:一个用于确定适当平台特定目录的小型 Python 模块
  • carto:提供围绕 CARTO API 的 SDK
  • chardet:Python 2 和 3 的通用编码检测器
  • colorama:在 MS Windows 中启用彩色终端文本和光标定位
  • decorator:在 Python 各个版本中一致地保留装饰函数的签名
  • future:提供 Python 2 和 Python 3 之间的兼容层
  • idna:为应用程序中的 国际化域名(IDNA)提供支持
  • ipython-genutils:来自 IPython 的残余实用工具
  • jedi:一个用于文本编辑器的 Python 自动完成工具
  • numpy:执行数字、字符串、记录和对象的数组处理
  • pandas:提供强大的数据分析、时间序列和统计数据结构
  • parso:一个支持不同 Python 版本错误恢复的 Python 解析器,以及更多
  • pickleshare:一个具有并发支持的类似 shelve 的小型数据存储库
  • prompt-toolkit:一个用于在 Python 中构建强大交互式命令行的库
  • pygments:一个用 Python 编写的语法高亮包
  • pyrestcli:一个通用的 Python REST 客户端
  • python-dateutil:为标准的 Python datetime 模块提供扩展
  • pytz:提供现代和历史的世界时区定义
  • requests:一个 HTTP 请求库
  • simplegeneric:让您定义简单的单分派泛型函数
  • six:一个 Python 2 和 3 兼容库
  • tqdm:提供快速、可扩展的进度条
  • traitlets:一个用于 Python 应用程序的配置系统
  • urllib3:一个具有线程安全连接池、文件上传等功能的 HTTP 库
  • wcwidth:测量宽字符代码的终端列单元格数
  • webcolors:一个用于处理 HTML 和 CSS 定义的名称和颜色值格式的库

CARTO 数据观测站

您可以通过使用 CARTO 数据观测站来增强 CARTOframes 库,CARTO 数据观测站是 CARTO 提供的在线数据服务。它提供三件事——即插即用的位置数据、访问分析数据方法的目录,以及基于快速 API 构建位置智能应用的机会。这个数据服务是在这样的想法下创建的,即网络上的数据必须是可搜索的,因此需要良好的标签。为了能够找到这些数据,提供数据上下文,并使用它进行空间分析,这是这个服务所能实现的。

CARTO 数据观测站对 CARTO 企业用户可用,这需要付费订阅。在本章中,我们不会介绍这个选项,但在这里提及它,以便让您了解 CARTOframes 库可以实现的功能。

注册 CARTO 账户

要使用 CARTOframes 并与 CARTO 提供的基于云的 PostGIS 数据库服务中存储的数据交互,您需要注册一个 CARTO 账户。虽然提供免费账户,但存储容量有限,且对现有数据资源的访问有限,要使用 CARTOframes,您需要有一个付费账户,因为这些账户提供了 API 密钥。API 密钥将由 CARTOframes 用于识别账户,每个数据请求都将发送到用户的云地理数据库。

CARTO 的免费试用

通过注册,账户最初是一个带有访问所有 CARTO 功能的付费账户。付费账户提供免费 30 天试用期,可用于评估目的。请访问网站carto.com/signup并创建账户:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/9dd2dcdb-9ab0-4a3d-9c24-bbf172f2b1c9.png

一旦创建账户,30 天的试用期就开始了。这将允许您将数据添加到云数据库,或从 CARTO 库访问公开数据。它还允许您轻松发布地图。点击 NEW MAP 按钮开始:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/72034ea5-69c4-483f-b163-1be4c3f298f5.png

添加数据集

使用 DATA LIBRARY 标签页,将波特兰建筑足迹添加到地图中。从列表中选择数据集,然后点击 Create Map。数据集将被添加到账户数据集标签页和称为 Builder 的地图创建界面中:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/d1ab5f89-5baa-4c17-8e10-a7b56944b76a.png

数据集被添加为地图的一层。可以在地图编辑器中操纵层的所有方面,包括层的颜色、显示的属性、弹出窗口等。也可以调整底图。

可以添加表示属性实时数据的控件。我已经将来自数据库的 US Census Tracts 层添加到地图中,并添加了一个显示所选属性字段值的图形控件。此图形是动态的,并将根据地图窗口中显示的具体人口普查区调整显示的值:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/27049833-8a32-455e-97a9-2bcad929301f.png

查看 Builder 中的其他标签页,包括 DATA(数据)、ANALYSIS(分析)、STYLE(样式)、POP-UP(弹出)和 LEGEND(图例),以进一步自定义地图。有许多调整和小部件可以使数据交互式。地图也可以设置为公开或私有,并且可以通过点击 PUBLISH 按钮发布到网络上。CARTO 的编辑器和数据导入界面使得创建和共享地图变得非常容易。

API 密钥

要使用 CARTOframes 连接到 CARTO 账户,需要一个 API 密钥。要访问它,请转到账户仪表板,点击右上角的图片,然后从下拉菜单中选择 Your API keys 链接:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/4c3e11e3-b0e6-4aeb-92b8-404730089c84.png

API 密钥是一长串用于确保我们将编写的脚本可以访问账户及其相关数据集的文本。当编写脚本时,复制密钥文本并将其作为 Python 字符串分配给脚本中的变量:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/a0c47392-c9d3-4715-83d2-f9451d440ed4.png

添加数据集

有一种方便的方法可以将您电脑上的数据添加到账户中。然而,当添加 shapefiles 时,构成 shapefile 的所有数据文件都必须在一个 ZIP 文件中。我们将从第十一章,Flask 和 GeoAlchemy2,将 NBA 场馆 shapefile 作为 ZIP 文件添加到账户中。点击仪表板数据集区域中的“新建数据集”按钮:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/d07aa76d-d9d7-432a-a995-e141a3ba494b.png

一旦按下“新建数据集”按钮,并出现“连接数据集”界面,点击“浏览”并导航到压缩文件以上传它:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/d141f6df-1a86-432f-9824-72c5c031b29b.png

上传过程完成后,数据将被分配一个 URL,并可以使用 Builder 进行编辑。也可以使用 CARTOframes 进行编辑。

现在账户已经设置好,并且已经从本地文件以及数据库中添加了一个数据集,我们需要在我们的本地机器上设置 Python 环境,以便能够连接到账户中存储的数据。

虚拟环境

为了管理 CARTOframes 和其他相关 Python 3 模块的安装,我们将使用虚拟环境包 virtualenv。这个 Python 模块使得在同一台计算机上设置完全独立的 Python 安装变得非常容易。使用 virtualenv,会创建一个 Python 的副本,当激活后,所有安装的模块都将与主 Python 安装分开(换句话说,虚拟环境中安装的模块不会添加到主 site-packages 文件夹中)。这大大减少了包管理的麻烦。

安装 virtualenv

使用 PyPI 中的 pip 安装 virtualenv 包非常简单 (pypi.org):

pip install virtualenv 

此命令将添加 virtualenv 及其支持模块。请确保主 Python 安装已添加到 Windows 环境变量中的路径,以便可以从命令行调用 virtualenv

运行 virtualenv

要创建虚拟环境,打开命令行并输入以下命令结构,virtualenv {环境名称}. 在这个例子中,环境的名称是 cartoenv

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/b9f8c0a8-f588-40ac-85d4-0d419eae77cb.png

在创建 virtualenv 的文件夹内,会生成一系列文件夹,包含支持 Python 所需的代码文件。还有一个 Lib 文件夹,其中包含将存放所有在此 Python 虚拟版本中安装的模块的 site-packages 文件夹:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/bb44e0fd-ef8d-4500-86cf-51804eaf0c00.png

激活虚拟环境

要从命令行开始使用新的虚拟环境,在虚拟环境所在的文件夹内传递以下参数。这将运行 activate 批处理文件,并启动虚拟环境:

C:\PythonGeospatial3>cartoenv\Scripts\activate 

一旦激活了虚拟环境,环境名称将出现在文件夹名称之前,表示命令是在环境中运行的,并且任何执行的操作(如安装模块)都不会影响主 Python 安装:

(cartoenv) C:\PythonGeospatial3>

在 Linux 环境中,使用命令 source {environment}/bin/activate 代替。在 Linux 中编程时,终端中的命令看起来会是这样:

silas@ubuntu16:~$ mkdir carto silas@ubuntu16:~$ cd carto/ silas@ubuntu16:~/carto$ virtualenv cartoenv New python executable in/home/silas/carto/cartoenv/bin/python Installing setuptools, pip, wheel...done. silas@ubuntu16:~/carto$ source cartoenv/bin/activate (cartoenv) silas@ubuntu16:~/carto$ 

在任何操作系统上,要退出虚拟环境,输入 deactivate 命令。这将结束虚拟会话:

C:\PythonGeospatial3>cartoenv\Scripts\activate (cartoenv) C:\PythonGeospatial3>deactivate C:\PythonGeospatial3>

在 virtualenv 中安装模块

由于每个虚拟环境都与主 Python 安装分开,每个环境都必须安装所需的模块。虽然这可能会让人感到烦恼,但 pip 使得这个过程变得相当简单。在设置第一个虚拟环境之后,一个名为 freezepip 命令可以让你生成一个名为 requirements.txt 的文件。这个文件可以被复制到一个新的虚拟环境中,并使用 pip install 命令,所有列出的模块都将从 PyPI 添加。

要在当前文件夹中生成 requirements.txt 文件,使用以下命令:

(cartoenv) C:\Packt\Chapters>pip freeze > requirements.txt 

在文件被复制到新的虚拟环境文件夹之后,激活环境并输入以下命令进行读取:

(newenv) C:\Packt\Chapters>pip install -r requirements.txt 

要使用的模块

对于这个虚拟环境,我们将安装 CARTOframes 和 Jupyter 这两个模块。第二个模块将允许我们运行 Jupyter Notebook,这是一种基于浏览器的专业编码环境。

激活虚拟环境,并使用以下命令在虚拟环境中安装模块:

(cartoenv) C:\Packt\Chapters>pip install cartoframes (cartoenv) C:\Packt\Chapters>pip install jupyter 

所需的所有模块也将被下载并安装,包括我们直接安装的两个模块。使用 pipvirtualenv 使得包安装和管理变得简单快捷。

使用 Jupyter Notebook

我们已经在 第一章,包安装和管理 以及前一章的多个实例中介绍了 Jupyter Notebook 的基本安装,以运行代码并获得所需的输出。

在这里,我们将使用 Jupyter Notebook 为 CARTOframes 连接到账户并分析地理空间数据,并将其显示出来。

连接到账户

在第一个代码框中,我们将导入 CARTOframes 模块,并传递 API 密钥字符串以及从你的 CARTO 用户名生成的基 URL,即 https://{username}.carto.com。在这种情况下,URL 是 https://lokiintelligent.carto.com

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/591ae76b-2dd4-4178-8394-4f798f245af0.png

在这个代码块中,API 密钥和 URL 被传递给 CartoContext 类,并返回一个 CartoContext 连接对象,将其分配给变量 cc。有了这个对象,我们现在可以与我们的账户关联的数据集进行交互,将数据集加载到账户中,甚至可以直接在 Jupyter Notebook 中生成地图。

一旦代码被输入到部分,点击运行按钮以执行当前部分的代码。任何输出都将出现在代码运行的下方 Out 部分。这部分可以包括地图、表格,甚至图表——Jupyter Notebooks 经常用于科学计算,因为它们能够即时生成图表并在 Notebook 中保存它们。

保存凭据

可以使用Credentials库保存和稍后访问 CARTO 账户凭据:

from cartoframes import Credentials creds = Credentials(username='{username}', key='{password}') creds.save()

访问数据集

要访问我们已加载到账户中的 NBA 场馆数据集,我们将使用CartoContextread方法,将我们想要交互的数据集名称作为字符串传递。在 Jupyter Notebook 部分,运行以下代码:

import cartoframes APIKEY ="{YOUR API KEY}" cc = cartoframes.CartoContext(base_url='https://{username}.carto.com/', api_key=APIKEY) df = cc.read('arenas_nba')print(df)

使用CartoContext,访问账户。使用cc对象,read方法从 NBA arenas数据集创建一个DataFrame对象。DataFrame对象是查询或更新的对象。

print语句将生成一个包含已加载到 CARTOframe 对象中的 NBA arenas数据集值的表格:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/117be600-7f09-4f7d-a4f1-deef661e8c40.png

可以使用点符号(例如,df.address1)或使用键(例如,df['address1'])访问单个列:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/75f11b12-f0e7-4df9-aad7-a5323119f728.png

选择单个行

要选择来自 CARTO 账户数据集的 Pandas 数据框中的特定行,可以将条件语句传递到括号中的对象。在这里,通过传递一个 NBA 球队的名称作为参数,查询 NBA arenas数据集的球队列:

df[df.team=='Toronto Raptors']

加载 CSV 数据集

要使用 CARTOframes 将数据集加载到账户中,我们再次使用pandas库,该库与 Jupyter 模块一起安装。Pandas 允许我们从 CSV(以及其他文件格式)中读取数据,将其加载到 Pandas 数据框(一个特殊的数据对象,允许进行多种数据操作,并生成输出)。然后,使用CartoContext,数据框(作为一个表)被写入账户:

import pandas as pd APIKEY ="{YOUR API KEY}" cc = cartoframes.CartoContext(base_url='https://{username}.carto.com/', api_key=APIKEY) df = pd.read_csv(r'Path\to\sacramento.csv') cc.write(df,'sacramento_addresses')

这将把作为数据框导入的 CSV 表格写入 CARTO 账户的 DATASETS 部分:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/30feff43-aea0-466e-9788-d380d7aa3c60.png

导入的数据集将不会是一个地理空间表,而是一个可以查询和与空间数据连接的表。

加载 shapefile

手动将地理空间数据加载到 CARTO 中非常简单,正如我们之前所探讨的。当使用 CARTOframes 时,它甚至更容易,因为它使得自动化数据管理成为可能。新的、更新的数据文件或来自 REST API 的数据可以转换为数据框并写入 CARTO 账户。

Shapefiles 需要安装 GeoPandas 库,因为几何形状需要 GeoPandas DataFrame对象进行数据管理。

安装 GeoPandas

如 第五章 所述,GeoPandas 是 Pandas 的地理空间补充。为了能够从 shapefiles 创建数据框对象,我们必须确保 GeoPandas 已安装并添加到虚拟环境中。使用 pip install 添加 GeoPandas 库:

(cartoenv) C:\PythonGeospatial3>pip install geopandas 

如果在 Windows 上存在安装问题,GeoPandas 和 Fiona(GeoPandas 的动力)的预构建二进制文件在此处可用,还有许多其他 Python 库:www.lfd.uci.edu/~gohlke/pythonlibs。通过下载它们,将它们复制到一个文件夹中,并使用 pip install 从 wheel 安装 Fiona 和 GeoPandas。例如,在这里,Fiona 是从 wheel 文件安装的:

C:\PythonGeospatial3>pip install Fiona-1.7.11.post1-cp36-cp36m-win_amd64.whl 

写入 CARTO

将 shapefile 写入 CARTO 账户只需要一个 CartoContext 对象、一个文件路径以及通常的 URL 和 API 密钥组合。现在 GeoPandas 已安装,MLB Stadiums shapefile 可以被加载到 GeoPandas DataFrame 中,然后使用 CartoContextwrite 方法写入 CARTO 账户:

import geopandas as gdp import cartoframes APIKEY ="{API KEY}" cc = cartoframes.CartoContext(base_url='https://{username}.carto.com/', api_key=APIKEY) shp =r"C:\Data\Stadiums_MLB\Stadiums_MLB.shp" data = gdp.read_file(shp) cc.write(data,"stadiums_mlb")

登录 CARTO 账户以确认数据集已被添加。

加载带有几何形状的 CSV

为了确保具有纬度和经度列的表(在这种情况下是从 OpenAddresses 导入的地址数据)作为地理空间数据集导入,我们必须使用 Shapely 库的 Point 类。每个 Point 几何对象都是从已导入的地址数据集的 LONLAT 字段生成的:

import geopandas as gdp import cartoframes import pandas as pd from shapely.geometry import Point APIKEY ="{API KEY}" cc = cartoframes.CartoContext(base_url='https://{username}.carto.com/', api_key=APIKEY) address_df = pd.read_csv(r'data/city_of_juneau.csv') geometry =[Point(xy)for xy inzip(address_df.LON, address_df.LAT)] address_df = address_df.drop(['LON','LAT'], axis=1) crs ={'init':'epsg:4326'} geo_df = gdp.GeoDataFrame(address_df, crs=crs, geometry=geometry) cc.write(geo_df,'juneau_addresses')

确保在导入 CARTOframes 之前导入 GeoPandas 库,以避免从 Fiona 库中导入错误。

地理空间分析

要执行地理空间分析,使用云数据集,我们可以通过 CARTOframes 连接并使用 GeoPandas 和 Shapely 的组合执行空间查询。在这个示例中,NBA arenas 数据集使用相交空间查询与 US States shapefile 进行比较。如果 arena 对象与州对象相交,则打印出 arena 和州的名称:

import geopandas as gdp import cartoframes import pandas as pd APIKEY ="1353407a098fef50ec1b6324c437d6d52617b890" cc = cartoframes.CartoContext(base_url='https://lokiintelligent.carto.com/', api_key=APIKEY)from shapely.geometry import Point from shapely.wkb import loads arenas_df = cc.read('arenas_nba') shp =r"C:\Data\US_States\US_States.shp" states_df = gdp.read_file(shp)for index, orig in states_df.iterrows():for index2, ref in arenas_df.iterrows():if loads(ref['the_geom'],hex=True).intersects(orig['geometry']):print(orig['STATE'], ref['team'])

编辑和更新数据集

因为 CARTOframes 集成了 Pandas 的数据框对象,这些对象可以在内存中进行编辑,并将数据写入存储在 CARTO 账户中的数据集,我们可以创建脚本来自动上传地理空间数据。数据集可以完全更新,或者可以使用 Pandas 的数据方法(如 replace)更新单个行和值。这,加上 Builder,CARTO 网络地图部署工具,使得创建具有网络地图前端和云数据存储的 GIS 变得容易,这些数据可以通过脚本进行管理。

在这个示例代码中,使用 intersect 查询找到包含 NBA arena 的州的名字。这些名字被添加到一个列表中,然后这个列表被添加到 arena 数据框中作为名为 states 的新列。存储在 arenas 数据集中的几何数据需要使用 loads 模块转换为 Shapely 对象:

import geopandas as gdp import cartoframes import pandas as pd from shapely.wkb import loads APIKEY ="API KEY" cc = cartoframes.CartoContext(base_url='https://{username}.carto.com/', api_key=APIKEY) arenas_df = cc.read('arenas_nba') shp =r"C:\Data\US_States\US_States.shp" states_df = gdp.read_file(shp) data =[]for index, ref in arenas_df.iterrows(): check =0for index2, orig in states_df.iterrows():if loads(ref['the_geom'],hex=True).intersects(orig['geometry']): data.append(orig['STATE']) check =1if check ==0: data.append(None) arenas_df['state']= data cc.write(arenas_df,'arenas_nba', overwrite=True)

overwrite=True

随着数据集的每次更新,必须将更改写入 CARTO 账户。要使用新数据覆盖云数据库中的数据,必须将 overwrite 参数设置为 True

cc.write(data,"stadiums_mlb",'overwrite=True')

创建地图

由于 Jupyter Notebooks 的交互性,代码和代码输出是同时存在的。当处理地理空间数据时,这非常棒,因为它使得创建数据地图变得容易。在这个例子中,NBA arenas 和 MLB 场馆数据集被添加到一个 BaseMap 对象上的地图中:

from cartoframes import Layer, BaseMap, styling cc.map(layers=[BaseMap('light'), Layer('arenas_nba',), Layer('stadiums_mlb')], interactive=True)

生成的输出如下:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/3a2534bd-e1eb-40d7-90bd-e46c4e72b82d.png

摘要

本章涵盖了以下主题。首先,我们介绍了 CARTOframes Python 库,并讨论了它与 CARTO 堆栈的其他部分(如 CARTO Builder 和 CARTO Data Observatory)的关系。接下来,我们解释了如何安装 CARTOframes 库,它依赖于哪些其他 Python 包,以及在哪里查找文档。由于 CARTOframes 使用来自 CARTO Builder 的数据,我们解释了如何设置 CARTO Builder 账户。在构成本章其余部分的示例脚本中,我们看到了如何将库与 pandas 数据框集成,如何处理表格,以及如何制作地图并将它们与其他地理空间库(如 Shapely 和 GeoPandas)结合。

在下一章中,我们将介绍另一个利用 Jupyter Notebooks 和地图视觉化的模块,MapboxGL—Jupyter。

第十五章:自动化云制图

Mapbox 已成为移动地图和数据可视化的同义词。除了被应用程序开发者和制图师采用的底图样式工具集外,他们还在生产用 Python 和 JavaScript 编写的有趣的制图工具。

将这两种有用的语言结合到一个包中,Mapbox 最近发布了新的 MapboxGL—Jupyter Python 模块。这个新模块允许在 Jupyter Notebook 环境中即时创建数据可视化。与允许 API 访问账户服务的 Mapbox Python SDK 模块一起,Python 使得向企业地理空间应用程序添加 Mapbox 工具和服务变得容易。

本章我们将学习:

  • 如何创建 Mapbox 账户以生成访问令牌
  • 如何设计自定义底图样式
  • 对云数据和底图的读写访问
  • 如何创建分级圆可视化
  • 如何创建分级圆可视化

所有制图相关内容

Mapbox 成立于 2010 年,由 Eric Gunderson 创立,迅速扩张并超越了初创公司的根基,成为制图复兴的领导者。他们的 MapboxGL JavaScript API 是一个用于创建交互式网络地图和数据可视化的有用库。他们向地理空间社区贡献了多个开放制图规范,包括矢量瓦片。

Mapbox 专注于为地图和应用程序开发者提供定制底图瓦片,将自己定位为领先的网络地图和移动应用软件公司。本章中使用的两个 Python 模块允许 GIS 管理人员和开发者将他们的服务和工具集成到企业地理信息系统生态中。

如何将 Mapbox 集成到您的 GIS 中

通过他们的 JavaScript 库和新的 MapboxGL—Jupyter Python 模块,Mapbox 工具的使用比以往任何时候都更加容易。地理空间开发者和程序员可以将他们的工具集成到现有的 GIS 工作流程中,或者创建利用 Mapbox 提供的套件的新地图和应用程序。

与 CARTO 类似,Mapbox 允许基于账户的云数据存储。然而,他们的重点更少在分析工具上,更多在制图工具上。对于大小不同的制图团队,使用 Mapbox 工具可以降低创建和支持自定义底图以用于交互式网络地图的成本,并且与其他地图瓦片选项(如 Google Maps API)相比,可以节省更多。

Mapbox Studio 使得创建具有制图外观和感觉的地图变得容易,可以与公司或部门的品牌相匹配。底图可以使用现有样式构建,并叠加您的组织层,或者设计一个全新的底图。它甚至允许基于被拖入工作室的图像进行样式设计,根据从图像像素生成的直方图为要素分配颜色。

Mapbox 工具

Mapbox 采用了地理空间领域的领导者(如 Mapbox 开源负责人 Sean Gillies,Shapely、Fiona 和 Rasterio 的重要开发者),为开源许可下的分析和地图 Python 库做出了贡献。他们新的 MapboxGL—Jupyter 库代表了一种利用其工具套件的新方法,结合其他 Python 模块(如 Pandas/GeoPandas)和多种数据类型(如 GeoJSON、CSVs 以及甚至 shapefiles)。

除了新的 Python 模块外,Mapbox 的开源工具还包括基于 Web 图形库WebGL)的 MapboxGL JavaScript 库,以及 Mapbox Python SDK。

MapboxGL.js

MapboxGL 是建立在著名的 JavaScript 地图库 Leaflet.js 之上的。Leaflet 于 2011 年发布,支持各种知名的 Web 地图应用,包括 Foursquare、Craigslist 和 Pinterest。Leaflet 的开发者 Vladimir Agafonkin 自 2013 年以来一直在 Mapbox 工作。

基于 Leaflet 开发工作的原始努力,MapboxGL.js 集成了 WebGL 库,利用 HTML 5 的 canvas 标签支持无需插件的 Web 图形。MapboxGL.js 支持矢量瓦片,以及平滑缩放和平移的 3D 环境。它支持 GeoJSON 叠加以及标记和形状。可以使用包括点击、缩放和平移在内的事件来触发数据处理函数,使其非常适合交互式网络地图应用。

Mapbox Python SDK

Mapbox Python SDK 用于访问大多数 Mapbox 服务,包括路线、地理编码、分析和数据集。对支持数据编辑和上传、行政管理和基于位置查询的云服务进行低级访问,允许与本地 GIS 进行企业集成和扩展。

安装 Python SDK

使用 pip 安装 Python SDK,允许访问 Mapbox 服务 API。此模块不是使用 MapboxGL—Jupyter 工具所必需的,但对于上传和查询很有用:

C:\Python3Geospatial>pip install mapbox 

在此处下载 Mapbox Python SDK:

github.com/mapbox/mapbox-sdk-py.

开始使用 Mapbox

要开始使用 Mapbox 工具和 Mapbox Studio,您需要注册一个账户。这将允许您生成 API 密钥,这些密钥对于将 Mapbox 底图瓦片添加到网络地图以及创建区分您地图的定制底图是必需的。有了这个账户,您还可以将数据加载到云中,以便在您的地图中使用。

注册 Mapbox 账户

要使用 Mapbox 工具和底图,您必须注册一个账户。这是一个简单的过程,需要提供用户名、电子邮件和密码:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/7e90dd7d-5cb0-4c8f-82a5-4e283e818c38.png

注册后,您将被带到账户仪表板,在那里可以生成 API 访问令牌并访问 Mapbox Studio。仪表板还显示了您的账户统计信息,包括对各种服务(如路线、地理编码和数据集)的 API 调用次数。

创建 API 令牌

新账户附带账户仪表板,默认提供 API 访问令牌。这个公开访问令牌或密钥以 pk 开头,是一长串字符。此 API 访问令牌用于验证使用此账户构建的所有地图和应用程序。复制字符串并将其添加到您的地图中:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/7c65efb6-75f3-4db5-bf14-e0688f5c508b.png

要创建新的 API 访问令牌,请点击“创建令牌”按钮并选择它将允许的访问级别:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/0b3f8431-1c31-4e78-9584-5e72c58de0d7.png

在 JavaScript 代码中,API 访问令牌被传递给 MapboxGL 对象以启用对瓦片和工具的访问。以下是一个简单的使用 HTML/JavaScript 的 Web 地图示例,展示了如何使用访问令牌创建地图。请将以下代码中提到的访问令牌替换为您自己的公开访问令牌:

<html><head><script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'></script><link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css' rel='stylesheet'/></head><body><div id='map' style='width: 400px; height: 300px;'></div><script> mapboxgl.accessToken ='pk.eyJ1IjoibG9raXByZXNpZGVud0.8S8l9kH4Ws_ES_ZCjw2i8A'; var map= new mapboxgl.Map({ container:'map', style:'mapbox://styles/mapbox/streets-v9'});</script></body></html>

将此代码保存为"index.html",然后使用浏览器打开以查看简单的地图。请确保将早期示例中的 API 访问令牌替换为您自己的密钥,否则地图将不会显示。

查阅文档了解 API 访问令牌的各种配置:

www.mapbox.com/help/how-access-tokens-work/.

将数据添加到 Mapbox 账户

Mapbox 支持使用您自己的数据。您不仅可以样式化底图瓦片,甚至可以将自己的数据添加到瓦片中,使其对客户或用户更加相关。这可以使用 Mapbox Python SDK 和上传以及数据集 API 进行程序化管理。

要上传数据,您必须创建一个秘密 API 访问令牌。这些是通过之前详细说明的创建令牌过程创建的,但包括秘密范围。选择以下范围以允许数据集和瓦片集的读写能力:

  • DATASETS:WRITE
  • UPLOADS:READ
  • UPLOADS:WRITE
  • TILESETS:READ
  • TILESETS:WRITE

在这里了解更多关于将数据加载到您的 Mapbox 账户的信息:

www.mapbox.com/help/how-uploads-work/.

瓦片集

瓦片集是经过分块处理的栅格数据,用于创建可滑动地图,允许它们叠加在底图上。它们可以从矢量数据生成,以使用您自己的数据创建自定义底图。使用 Mapbox Python SDK 中的Uploader类,可以将 GeoJSON 文件和 shapefile 以瓦片集的形式程序化地加载到您的云账户中。

在这里了解更多关于瓦片集的信息:

www.mapbox.com/api-documentation/#tilesets.

数据集

数据集是 GeoJSON 层,可以比瓦片集更频繁地编辑。虽然您可以使用账户仪表板上传数据集,但要加载大于 5 MB 的数据集,您必须使用数据集 API。

在此处了解更多关于数据集的信息:

www.mapbox.com/api-documentation/#datasets.

示例 - 上传 GeoJSON 数据集

mapbox 模块有一个 Datasets 类,用于在账户中创建和填充数据集。此演示代码将从邮编 GeoJSON 文件中读取,并将一个邮编 GeoJSON 对象加载到新的数据集中。将秘密访问令牌传递给 Datasets 类:

from mapbox import Datasets import json datasets = Datasets(access_token='{secrettoken}') create_resp = datasets.create(name="Bay Area Zips", description ="ZTCA zones for the Bay Area") listing_resp = datasets.list() dataset_id =[ds['id']for ds in listing_resp.json()][0] data = json.load(open(r'ztca_bayarea.geojson'))for count,feature inenumerate(data['features'][:1]): resp = datasets.update_feature(dataset_id, count, feature)

这将向图层添加一个邮编,可以从账户仪表板中查看:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/9deb66ea-c49d-465f-a445-6cb157c5e3db.png

示例 - 将数据作为瓦片集上传

可以将瓦片集添加到自定义底图样式,这使得快速加载数据层成为可能。此演示代码使用具有读写能力的秘密令牌,通过 Mapbox Python SDK 将 GeoJSON 文件作为瓦片集上传:

token ='sk.eyJ1IjoibG9oxZGdqIn0.Y-qlJfzFzr3MGkOPPbtZ5g'#example secret tokenfrom mapbox import Uploader import uuid set_id = uuid.uuid4().hex service = Uploader(access_token=token)withopen('ztca_bayarea.geojson','rb')as src: response = service.upload(src, set_id)print(response)

如果返回的响应是 201 响应,则上传成功。

在此处了解更多关于上传 API 的信息:

www.mapbox.com/api-documentation/?language=Python.

Mapbox Studio

创建自定义底图可能对经验丰富的制图员来说也是一个耗时过程。为了帮助简化这个过程,Mapbox 工程师使用了 Open Street MapOSM)数据来生成预构建的自定义底图,这些底图可用于商业和非商业应用。使用 Mapbox Studio,还可以调整这些样式以添加更多自定义细节。此外,可以从头开始构建底图,以创建应用程序的特定外观:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/c15cb8cd-5290-41d8-9a58-6e51f5ccc3a1.png

要访问 Mapbox Studio,请登录账户仪表板并点击 Mapbox Studio 链接。在这个 Studio 环境中,您可以管理底图、瓦片集和数据集。

自定义底图

点击新建样式按钮并选择卫星街道主题:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/379c4100-c11a-4300-9c9d-533480bfc71a.png

一份快速教程解释了自定义选项。已添加了各种可用的图层,并且可以通过在目录表中点击图层来调整它们的标签和样式。还可以添加新图层,包括账户瓦片集:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/cadcf094-22bc-47d5-9fd6-015e22207530.png

可以调整地图缩放级别、方位角、俯仰角和初始坐标。使用地图位置菜单,可以更改这些地图参数,并使用底部的锁定按钮将其锁定为默认位置:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/c13f6524-9725-4c66-8731-776797dc370f.png

探索其他样式选项,例如标签颜色和图层缩放级别。完成自定义后,通过点击发布样式按钮发布样式。样式 URL 将添加到 MapboxGL 可视化中的这些 Jupyter Notebook 练习或网络地图中。

添加瓦片集

要将您的数据添加到基础地图样式,请点击图层按钮并从可用选项中选择一个瓦片集。之前使用 Mapbox Python SDK 加载的邮编瓦片集应该可用,并可以添加到基础地图并对其进行样式化:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/cfc3fdb9-9c6c-46aa-9bd9-5de97af7eea2.jpg

虚拟环境

使用 virtualenv(参见上一章中的安装说明)启动虚拟环境,并使用 pip 安装以下列出的模块。如果您有一个文件夹路径为 C:\Python3Geospatialvirtualenv 将创建一个虚拟环境文件夹,这里称为 mapboxenv,它可以按以下方式激活:

C:\Python3Geospatial>virtualenv mapboxenv Using base prefix 'c:\\users\\admin\\appdata\\local\\programs\\python\\python36' New python executable in C:\Python3Geospatial\mapboxenv\python.exe Installing setuptools, pip, wheel...done. C:\Python3Geospatial>mapboxenv\Scripts\activate 

安装 MapboxGL – Jupyter

您可以通过 pipPyPI.org 仓库安装 MapboxGL—Jupyter 库:

(mapboxenv) C:\Python3Geospatial>pip install mapboxgl 

所有支持模块都将与 Mapbox 创建的核心库一起定位和安装。

安装 Jupyter 笔记本

在虚拟环境中安装 Jupyter Notebooks 库:

(mapboxenv) C:\Python3Geospatial>pip install jupyter 

安装 Pandas 和 GeoPandas

Pandas 应已安装,因为它是与 GeoPandas 一起安装的,但如果尚未安装,请使用 pipPyPI.org 仓库中查找它:

(mapboxenv) C:\Python3Geospatial>pip install geopandas 

如果您在 Windows 计算机上安装这些模块时遇到任何问题,请在此处探索预构建的 wheel 二进制文件(下载后使用 pip 安装它们):

www.lfd.uci.edu/~gohlke/pythonlibs/.

使用 Jupyter Notebook 服务器

启动 Jupyter Notebook 服务器非常简单。当使用虚拟环境时,您需要首先激活环境,然后启动服务器。如果不这样做,请确保 Python 和 Notebook 服务器位置在路径环境变量中。

打开命令提示符并输入 jupyter notebook 以启动服务器:

(mapboxenv) C:\Python3Geospatial>jupyter notebook 

服务器将启动并显示其端口号和可以用于重新登录网页浏览器的令牌:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/42a1dabb-19f7-4b47-ba68-cacfeb5191ac.png

启动服务器将在系统浏览器中打开一个浏览器窗口。服务器地址是 localhost,默认端口是 8888。浏览器将在 http://localhost:8888/tree 打开:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/4b060dfb-333b-4206-af65-68be15997378.png

点击新建按钮创建一个新的笔记本。从笔记本部分选择 Python 版本,新的笔记本将在第二个标签页中打开。这个笔记本应该重命名,因为它很快就会变得难以组织未命名的笔记本:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/ac90a315-68f3-4341-9e0e-e0532f262576.png

一旦窗口打开,编码环境就处于活动状态。在这个例子中,我们将使用 GeoPandas 导入人口普查区数据,将其转换为点数据,选择特定列,并使用 MapboxGL—Jupyter 进行可视化。

使用 GeoPandas 导入数据

导入所需的模块并将 API 密钥分配给一个变量。以下命令应添加到 Jupyter Notebook 单元中:

import geopandas as gpd import pandas as pd import os from mapboxgl.utils import*from mapboxgl.viz import* token ='{user API Key}'

API 密钥也可以分配给 Windows 路径环境变量(例如,"MAPBOX_ACCESS_TOKEN"),并使用os模块调用:

token = os.getenv("MAPBOX_ACCESS_TOKEN")

从多边形创建点数据

旧金山地区的普查区 GeoJSON 文件包含具有多边形geometry的人口数据。为了创建第一个可视化,我们需要将几何类型转换为点:

tracts = gpd.read_file(r'tracts_bayarea.geojson') tracts['centroids']= tracts.centroid tract_points = tracts tract_points = tract_points.set_geometry('centroids') tract_points.plot()

之前代码的输出如下:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/b962da69-204f-43c7-8b1b-7fa6822742c8.png

数据清理

这份数据可视化将比较旧金山地区的男性和女性人口。为了生成圆形可视化,我们可以使用 Geopandas 的数据框操作重命名和删除不必要的列:

tract_points['Total Population']= tract_points['ACS_15_5YR_S0101_with_ann_Total; Estimate; Total population'] tract_points['Male Population']= tract_points['ACS_15_5YR_S0101_with_ann_Male; Estimate; Total population'] tract_points['Female Population']= tract_points['ACS_15_5YR_S0101_with_ann_Female; Estimate; Total population'] tract_points = tract_points[['Total Population','Male Population','Female Population','centroids']]

这段代码通过传递新列的名称并将数据值赋给现有列,从三个现有列创建了三个新列。然后,整个 GeoDataFrame(在内存中)被重写,只包含三个新列和中心点列,消除了不想要的列。探索新的 GeoDataFrame 的前五行,我们可以看到新的数据结构:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/acb4b206-d9c9-4841-817d-ca598cf087f5.png

将点保存为 GeoJSON

保存新清理的 GeoDataFrame 是将其加载到 Mapbox CircleViz类所必需的。必须指定 GeoJSON 驱动程序,因为默认输出文件格式是 shapefile:

tract_points.to_file('tract_points.geojson',driver="GeoJSON")

将点添加到地图上

要简单地查看地图上的点,我们可以提供一些参数并调用CircleViz对象的show属性:

viz = CircleViz('tract_points.geojson', access_token=token, radius =2, center =(-122,37.75), zoom =8) viz.show()

之前的代码将产生以下输出:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/c1ed2c88-cd1c-46d8-a99e-7ccf7bfdc893.png

要对数据进行分类,我们可以为特定字段设置颜色停止点,传递一个包含相关颜色信息的类断点列表:

color_stops =[[0.0,'rgb(255,255,204)'],[500.0,'rgb(255,237,160)'],[1000.0,'rgb(252,78,42)'],[2500.0,'rgb(227,26,28)'],[5000.0,'rgb(189,0,38)'],[max(tract_points['Total Population']),'rgb(128,0,38)']] viz.color_property ='Total Population' viz.color_function_type ='interpolate' viz.color_stops = color_stops viz.radius =1 viz.center =(-122,37.75) viz.zoom =8 viz.show()

输出将看起来像这样:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/ed8a327a-6925-47b3-b346-59c846a3442f.png

tract_points GeoDataFrame 添加一些新字段并重新保存:

tract_points['Percent Male']= tract_points['Male Population']/tract_points['Total Population'] tract_points['Percent Female']= tract_points['Female Population']/tract_points['Total Population'] tract_points.to_file("tract_points2.geojson", driver="GeoJSON")

创建渐变色可视化

这段代码将手动为数据的具体部分分配颜色,将数据分为类别。这还将为数据分配特定的半径大小,以便可视化可以通过颜色和圆的大小传达信息:

color_stops =[[0.0,'rgb(107,174,214)'],[3000.0,'rgb(116,196,118)'],[8000.0,'rgb(254,153,41)'],[max(tract_points['Total Population']),'rgb(222,45,38)'],] minmax =[min(tract_points['Percent Male']),max(tract_points['Percent Male'])] diff = minmax[1]- minmax[0] radius_stops =[[round(minmax[0],2),4.0],[round(minmax[0]+(diff/6.0),2),7.0],[round(minmax[1]-(diff/2.0),2),10.0],[minmax[1],15.0],]

在设置好这些半径大小和颜色范围后,它们可以应用于新的 GeoJSON 中的两个字段:总人口男性百分比。对于这个可视化,圆的大小将表示人口的男性百分比,颜色将表示总人口:

vizGrad = GraduatedCircleViz('tract_points2.geojson', access_token=token) vizGrad.color_function_type ='interpolate' vizGrad.color_stops = color_stops vizGrad.color_property ='Total Population' vizGrad.color_default ='grey' vizGrad.opacity =0.75 vizGrad.radius_property ='Percent Male' vizGrad.radius_stops = radius_stops vizGrad.radius_function_type ='interpolate' vizGrad.radius_default =1 vizGrad.center =(-122,37.75) vizGrad.zoom =9 vizGrad.show()

这将生成一个交互式地图,如下所示:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/546f3b6a-2201-409c-8b2b-85b79b3442e2.png

自动设置颜色、大小和断点

与手动设置颜色、半径大小和断点不同,MapboxGL—Jupyter 包含一些实用工具(如 create_color_stops),它们在颜色(或大小)和断点值之间创建匹配。颜色方案通过传递 YlOrRd 关键字(表示 黄橙红)来设置。此外,我们可以通过设置可视化样式为样式 URL 来调整底图,使用另一个预置样式或我们自己的自定义样式:

measure_color ='Percent Male' color_breaks =[round(tract_points[measure_color].quantile(q=x*0.1),3)for x inrange(1,11,3)] color_stops = create_color_stops(color_breaks, colors='YlOrRd') measure_radius ='Total Population' radius_breaks =[round(tract_points[measure_radius].quantile(q=x*0.1),1)for x inrange(2,12,2)] radius_stops = create_radius_stops(radius_breaks,5.0,20) vizGrad = GraduatedCircleViz('tract_points2.geojson', access_token=token, color_property = measure_color, color_stops = color_stops, radius_property = measure_radius, radius_stops = radius_stops, stroke_color ='black', stroke_width =0.5, center =(-122,37.75), zoom =9, opacity=0.75) vizGrad.style='mapbox://styles/mapbox/dark-v9' vizGrad.show()

深色底图使得渐变圆可视化更加清晰可见:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/18546256-83fb-42d9-8220-298df0f4268f.png

在此处探索文档中可用的可视化选项:

github.com/mapbox/mapboxgl-jupyter/blob/master/docs-markdown/viz.md.

在此处探索可用的数据工具:

github.com/mapbox/mapboxgl-jupyter/blob/master/docs-markdown/utils.md.

在此处探索可用的颜色渐变:

github.com/mapbox/mapboxgl-jupyter/blob/master/mapboxgl/colors.py.

创建渐变色地图

使用渐变色地图,我们可以显示一个多边形 GeoJSON 文件。使用 tracts GeoDataFrame,我们将创建另一个具有多边形 geometry 和一个表格字段的 GeoDataFrame,并将其保存为 GeoJSON 文件:

tract_poly = tracts tract_poly['Male Population']= tract_poly['ACS_15_5YR_S0101_with_ann_Male; Estimate; Total population'] tract_poly = tract_poly[['Male Population','geometry']] tract_poly.to_file('tracts_bayarea2.geojson', driver="GeoJSON")

可视化是通过 ChoroplethViz 类创建的。底图样式是 MapBox Studio 章节中先前创建的卫星影像样式的 URL:

vizClor = ChoroplethViz('tracts_bayarea2.geojson', access_token=API_TOKEN, color_property='Male Population', color_stops=create_color_stops([0,2000,3000,5000,7000,15000], colors='YlOrRd'), color_function_type='interpolate', line_stroke='-', line_color='rgb(128,0,38)', line_width=1, opacity=0.6, center=(-122,37.75), zoom=9) vizClor.style='mapbox://styles/lokipresident/cjftywpln22sp9fcpqa8rl' vizClor.show()

生成的输出如下:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/b769edfc-3131-4be3-a7d9-1b79b9541fda.png

保存地图

要保存渐变色地图,请使用可视化的 create_html 方法:

withopen('mpop.html','w')as f: f.write(vizClor.create_html())

要在本地查看保存的 HTML 文件,请打开命令提示符,并在与保存的 HTML 文件相同的文件夹中使用 Python 启动本地 HTTP 服务器。然后,在 http://localhost:8000/mpop.html 打开浏览器查看地图:

C:\Python3Geospatial>python -m http.server Serving HTTP on 0.0.0.0 port 8000(http://0.0.0.0:8000/)...

创建热图

使用 HeatmapViz 类从数据生成热图:

measure ='Female Population' heatmap_color_stops = create_color_stops([0.01,0.25,0.5,0.75,1], colors='PuRd') heatmap_radius_stops =[[0,3],[14,100]] color_breaks =[round(tract_poly[measure].quantile(q=x*0.1),2)for x inrange(2,10)] color_stops = create_color_stops(color_breaks, colors='Spectral') heatmap_weight_stops = create_weight_stops(color_breaks) vizheat = HeatmapViz('tracts_points2.geojson', access_token=token, weight_property ="Female Population", weight_stops = heatmap_weight_stops, color_stops = heatmap_color_stops, radius_stops = heatmap_radius_stops, opacity =0.8, center=(-122,37.78), zoom=7, below_layer='waterway-label') vizheat.show()

使用 Mapbox Python SDK 上传数据

使用 MapboxGL—Jupyter 和 Mapbox Python SDK 在账户中存储数据集并将它们与其他表格数据连接起来是可能的。加载 GeoJSON 文件需要仅分配给秘密 API 访问令牌的特定权限。为了确保使用的 API 令牌具有正确的范围,您可能需要生成一个新的 API 令牌。转到您的账户仪表板并生成一个新的令牌,并确保您检查了 入门 Mapbox 部分中显示的上传和数据集的读写能力。

创建数据集

第一步是创建一个数据集,如果您还没有创建,此代码将在账户中生成一个空数据集,该数据集将具有 datasets.create 方法提供的名称和描述:

from mapbox import Datasets import json datasets = Datasets(access_token={secrettoken}) create_resp = datasets.create(name="Bay Area Zips", description ="ZTCA zones for the Bay Area")

将数据加载到数据集中

要将数据加载到新数据集中,我们将遍历包含在邮编 GeoJSON 中的特征,将它们全部写入数据集(而不是像之前演示的那样只写入一个)。由于此文件大于 5MB,必须使用 API 加载,该 API 通过mapbox模块访问。update_feature方法的所有参数都是必需的:数据集的 ID(使用datasets.list方法检索)、行 ID 和feature

listing_resp = datasets.list() dataset_id =[ds['id']for ds in listing_resp.json()][0] data = json.load(open(r'ztca_bayarea.geojson'))for count,feature inenumerate(data['features']): resp = datasets.update_feature(dataset_id, count, feature)

完成后的数据集在 Mapbox Studio 中看起来如下所示:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/4b9c0414-eea1-400e-a41d-a19037ae1776.png

从数据集中读取数据

要读取数据集中存储的 JSON 数据,请使用read_dataset方法:

 datasets.read_dataset(dataset_id).json()

删除行

要从数据集中删除特定行,请将数据集 ID 和行 ID 传递给datasets.delete_feature方法:

resp = datasets.delete_feature(dataset_id,0)

摘要

在本章中,我们学习了如何使用 MapboxGL—Jupyter 和 Mapbox Python SDK 创建数据可视化,并将数据上传到 Mapbox 账户。我们创建了点数据可视化、面状图、热图和渐变圆可视化。我们学习了如何定制底图样式,如何将其添加到 HTML 地图中,以及如何将自定义瓦片集添加到底图中。我们还学习了如何使用 GeoPandas 将多边形数据转换为点数据,以及如何可视化结果。

在下一章中,我们将探讨使用 Python 模块和 Hadoop 进行地理空间分析的使用。

第十六章:使用 Hadoop 进行 Python 地理处理

本书中的大多数示例都使用单个计算机上的相对较小的数据集进行工作。但随着数据量的增加,数据集甚至单个文件可能会分布在机器集群中。处理大数据需要不同的工具。在本章中,你将学习如何使用 Apache Hadoop 处理大数据,以及 Esri GIS 工具用于在空间上处理大数据。

本章将教你如何:

  • 安装 Linux
  • 安装和运行 Docker
  • 安装和配置 Hadoop 环境
  • 在 HDFS 中处理文件
  • 使用 Hive 进行基本查询
  • 安装 Esri GIS 工具用于 Hadoop
  • 在 Hive 中执行空间查询

什么是 Hadoop?

Hadoop 是一个开源框架,用于处理分布在单台计算机到数千台计算机上的大量数据。Hadoop 由四个模块组成:

  • Hadoop 核心组件
  • Hadoop 分布式文件系统HDFS
  • 另一个资源协商者YARN
  • MapReduce

Hadoop 核心组件包括运行其他三个模块所需的组件。HDFS 是一个基于 Java 的文件系统,它被设计成分布式,并且能够在多台机器上存储大量文件。当我们说大量文件时,我们指的是千兆字节。YARN 管理你的 Hadoop 框架中的资源和调度。MapReduce 引擎允许你并行处理数据。

有几个其他项目可以安装以与 Hadoop 框架一起使用。在本章中,你将使用 Hive 和 Ambari。Hive 允许你使用 SQL 读取和写入数据。你将在本章末尾使用 Hive 对你的数据进行空间查询。Ambari 为 Hadoop 和 Hive 提供了一个网页用户界面。在本章中,你将使用它上传文件并输入你的查询。

现在你已经对 Hadoop 有了一个概述,下一节将展示如何设置你的环境。

安装 Hadoop 框架

在本章中,你将不会自己配置 Hadoop 框架的每个组件。你将运行一个 Docker 镜像,这需要你安装 Docker。目前,Docker 在 Windows 10 专业版或企业版上运行,但在 Linux 或 Mac 上运行得更好。Hadoop 也可以在 Windows 上运行,但需要你从源代码构建,因此它将在 Linux 上运行得更容易。此外,你将使用的 Docker 镜像正在运行 Linux,因此熟悉 Linux 可能会有所帮助。在本节中,你将学习如何安装 Linux。

安装 Linux

设置 Hadoop 框架的第一步是安装 Linux。你需要获取一个 Linux 操作系统的副本。Linux 有很多版本。你可以选择你喜欢的任何版本,然而,本章是使用 CentOS 7 编写的,因为大多数你将要安装的工具也已经在 CentOS 上进行了测试。CentOS 是基于 Red Hat 的 Linux 版本。你可以在以下网址下载 ISO:www.centos.org/。选择“立即获取 CentOS”。然后,选择“DVD 图像”。选择一个镜像下载 ISO。

下载镜像后,您可以使用 Windows 将其烧录到磁盘上。一旦烧录完成,将磁盘放入将要运行 Linux 的机器中并启动它。安装过程中会有提示。需要关注的两个步骤是软件选择步骤和分区。在软件选择步骤中,选择 GNOME 桌面。这将提供一个带有流行 GUI 的足够的基础系统。如果您在计算机上还有其他文件系统,您可以在分区屏幕上选择覆盖它或选择分区上的空闲空间。

对于如何安装 Linux 的更详细解释,谷歌是你的朋友。有许多优秀的教程和 YouTube 视频会引导你完成安装过程。不幸的是,看起来 CentOS 网站没有 CentOS 7 的安装手册。

安装 Docker

Docker 提供了软件,以便您可以运行容器。容器是一个包含运行其包含的软件所需所有内容的可执行文件。例如,如果我有一个配置为运行 Hadoop、Hive 和 Ambari 的 Linux 系统,并且我从它创建了一个容器,我可以给你这个容器,当你运行它时,它将包含运行该系统所需的所有内容,无论你的计算机配置或安装了什么软件。如果我把这个容器镜像给任何其他人,它也会始终以相同的方式运行。容器不是虚拟机。虚拟机是硬件层面的抽象,而容器是应用层面的抽象。容器包含运行软件所需的所有内容。对于本章,这就是你需要知道的所有内容。

现在您已经安装了 Linux 并了解了 Docker 是什么,您可以安装 Docker 的一个副本。使用您的终端,输入以下命令:

curl -fsSL https://get.docker.com/| sh 

前面的命令使用 curl 应用程序下载并安装 Docker 的最新版本。参数告诉 curl 在服务器错误发生时静默失败,不显示进度,报告任何错误,并在服务器表示位置已更改时进行重定向。curl 命令的输出通过管道 - | 传递到 sh(Bash shell)以执行。

当 Docker 安装完成后,你可以通过执行以下命令来运行它:

sudo systemctl start docker 

上一条命令使用 sudo 以管理员(root)身份运行命令。想象一下在 Windows 中右键点击并选择“以管理员身份运行”选项。下一条命令是 systemctl。这是在 Linux 中启动服务的方式。最后,start docker 正好做了这件事,它启动了 docker。如果您在执行前面提到的命令时收到提及 sudoers 的错误,那么您的用户可能没有权限以 root 身份运行应用程序。您需要以 root 身份登录(或使用 su 命令)并编辑 /etc/sudoers 中的文本文件。请添加以下行:

your username ALL=(ALL) ALL 

上一行将授予您使用 sudo 的权限。您的 /etc/sudoers 文件应类似于以下截图:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/737f6f46-0fa2-4f2d-94ce-b99d42273c68.png

现在你已经运行了 docker,你可以下载我们将要加载的包含 Hadoop 框架的镜像。

安装 Hortonworks

与安装 Hadoop 和所有其他组件相比,你将使用预配置的 Docker 镜像。Hortonworks 有一个数据平台沙盒,它已经包含了一个可以在 Docker 中加载的容器。要下载它,请访问 hortonworks.com/downloads/#sandbox 并选择“为 Docker 下载”。

你还需要安装 start_sandox_hdp_version.sh 脚本。这将简化在 Docker 中启动容器。你可以从 GitHub 下载脚本:gist.github.com/orendain/8d05c5ac0eecf226a6fed24a79e5d71a.

现在你需要在 Docker 中加载这个镜像。以下命令将展示如何操作:

docker load -i <image name>

之前的命令将镜像加载到 Docker 中。镜像名称将类似于 HDP_2.6.3_docker_10_11_2017.tar,但会根据你的版本而变化。要查看沙盒是否已加载,请运行以下命令:

docker images 

如果没有其他容器,输出应该看起来如下截图所示:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/56dc5a44-976b-4eb5-9a74-9b5f075fc8f2.png

为了使用基于 Web 的 GUI Ambari,你将需要一个为沙盒设置的域名。为此,你需要容器的 IP 地址。你可以通过运行两个命令来获取它:

docker ps docker inspect <container ID>

第一个命令将包含 container ID,第二个命令将使用 container ID 返回大量信息,其中 IP 地址位于末尾。或者,你可以利用 Linux 命令行,只需使用以下命令即可获取 IP 地址:

docker inspect $(docker ps --format"{{.ID}}")--format="{{json .NetworkSettings.IPAddress}}"

之前的命令将之前提到的命令包装成一个单独的命令。docker inspect 命令将 docker ps 的输出作为 container ID。它是通过将输出放在 $() 中来实现的,但它还传递了一个过滤器,以便只返回 ID。然后,inspect 命令还包含一个过滤器,只返回 IP 地址。{{}} 之间的文本是一个 Go 模板。此命令的输出应该是一个 IP 地址,例如,172.17.0.2。

现在你已经得到了镜像的 IP 地址,你应该使用以下命令更新你的主机文件:

echo '172.17.0.2 sandbox.hortonworks.com sandbox-hdp.hortonworks.com sandbox-hdf.hortonworks.com'| sudo tee -a /etc/hosts 

之前的命令将 echo 命令的输出(你希望在 /etc/hosts 文件中的文本)重定向到 sudo tee -a /etc/hosts 命令。这个第二个命令使用 sudoroot 用户身份运行。tee 命令将输出发送到文件和终端(STDOUT)。-a 参数告诉 tee 向文件追加内容,而 /etc/hosts 是你想要追加的文件。现在,在你的浏览器中,你将能够使用名称而不是 IP 地址。

现在您已准备好启动镜像并浏览到您的 Hadoop 框架。

Hadoop 基础

在本节中,您将启动您的 Hadoop 镜像,并学习如何使用 ssh 和 Ambari 进行连接。您还将移动文件并执行一个基本的 Hive 查询。一旦您了解了如何与框架交互,下一节将向您展示如何使用空间查询。

首先,从终端使用提供的 Bash 脚本启动 Hortonworks Sandbox。以下命令将展示如何操作:

sudo sh start_sandbox-hdp.sh 

之前的命令执行了您下载的包含沙盒的脚本。同样,它使用了 sudoroot 身份运行。根据您的机器,完全加载并启动所有服务可能需要一些时间。完成之后,您的终端应该看起来像以下截图所示:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/da573ba6-8cc1-4b01-b171-4d716cd3555b.png

通过 Secure Shell 连接

现在沙盒正在运行,您可以使用 Secure Shell (SSH) 进行连接。安全壳允许您远程登录到另一台机器。打开一个新的终端并输入以下命令:

ssh [email protected] 

之前的命令使用 ssh 连接到用户 raj_opslocalhost (127.0.0.1) 端口 2222。您将收到一个警告,表示无法验证主机的真实性。我们没有为 ssh 创建任何密钥。只需键入 yes,然后您将被提示输入密码。用户 raj_ops 的密码是 raj_ops。您的终端提示符现在应该看起来像以下行:

[raj_ops@sandbox-hdp ~]$ 

如果您的终端与之前的代码一样,您现在已登录到容器中。

关于用户、权限和配置沙盒的更多信息,请访问以下页面:hortonworks.com/tutorial/learning-the-ropes-of-the-hortonworks-sandbox/

您现在可以使用大多数 Linux 命令在容器中导航。您现在可以下载和移动文件,运行 Hive,以及从命令行运行所有其他工具。由于本节已经对 Linux 做了足够的介绍,所以您在本章中不会仅使用命令行。相反,下一节将向您展示如何在 Ambari 中执行这些任务,Ambari 是一个基于 Web 的 GUI,用于执行任务。

Ambari

Ambari 是一个用于简化 Hadoop 管理的用户界面。在前一节中,您学习了如何将 ssh 实现到容器中。从那里,您可以管理 Hadoop,运行 Hive 查询,下载数据,并将其添加到 HDFS 文件系统中。Ambari 使得所有这些操作都变得更加简单,尤其是如果您不熟悉命令行的话。要打开 Ambari,浏览到以下 URL:sandbox.hortonworks.com:8080/

Ambari 的 URL 依赖于您的安装。如果您遵循了本章中的说明,那么这将将是您的 URL。您还必须从 Docker 镜像中启动了服务器。

您将被重定向到 Ambari 登录页面。输入 raj_ops/raj_ops 的用户/密码组合,如下面的截图所示:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/65c4ceb9-cceb-4d6a-b092-ff998fcf28ee.png

登录后,您将看到 Ambari 仪表板。它看起来如下面的截图所示:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/3eae97d4-ff3a-4642-86be-336f5f71d124.png

在左侧,您有一个服务列表。窗口的主要部分包含指标,顶部菜单栏有不同功能的标签页。在本章中,您将使用由九个小方块组成的方形。将鼠标悬停在方形图标上,您将看到一个文件视图的下拉菜单。

这是 HDFS 文件系统的 root 目录。

通过 ssh 连接到容器后,运行 hdfs dfs -ls / 命令,您将看到相同的目录结构。

从这里,您可以上传文件。为了尝试一下,打开一个文本编辑器并创建一个简单的 CSV。本例将使用以下数据:

40, Paul 23, Fred 72, Mary 16, Helen 16, Steve 

保存 CSV 文件,然后在 Ambari 中点击上传按钮。您可以将 CSV 文件拖放到浏览器中。Ambari 将文件添加到容器上的 HDFS 文件系统:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/bdd196ed-7da5-4458-afca-231aea3689d5.png

现在您已经将数据加载到容器中,您可以使用 SQL 在 Hive 中查询它。再次使用方形图标,选择 Hive View 2.0 的下拉菜单。您应该会看到一个如下所示的工作区:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/384475d8-8bd7-4fc7-93e9-3d5d53389ba0.png

在 Hive 中,您有工作表。在工作表中,您连接到的数据库,在本例中是默认数据库。下面是主要的查询窗口。在右侧,您有一个现有表的列表。最后,向下滚动,您将看到执行按钮,下面是结果加载的位置。

在查询面板中,输入以下 SQL 查询:

SELECT * FROM sample_07 

之前的查询是一个基本的 SQL 全选查询。结果将如下所示:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/5d00e72c-b222-454c-93bc-ca3253e11597.png

Esri 为 Hadoop 优化的 GIS 工具

在您的环境设置完成,并对 Ambari、HDFS 和 Hive 有一些基本了解之后,您现在将学习如何将空间组件添加到您的查询中。为此,我们将使用 Esri 为 Hadoop 优化的 GIS 工具。

第一步是下载位于 GitHub 仓库中的文件,该仓库位于:github.com/Esri/gis-tools-for-hadoop。您将使用 Ambari 将文件移动到 HDFS,而不是容器,因此请将这些文件下载到您的本地机器上。

Esri 提供了一个教程,说明如何使用 ssh 连接到容器,然后使用 git 克隆仓库来下载文件。您可以在以下位置找到这些说明:github.com/Esri/gis-tools-for-hadoop/wiki/GIS-Tools-for-Hadoop-for-Beginners

您可以通过使用存储库右侧的 GitHub Clone 或下载按钮来下载文件。要解压存档,请使用以下命令之一:

unzip gis-tools-for-hadoop-master.zip unzip gis-tools-for-hadoop-master.zip-d /home/pcrickard 

第一个命令将在当前目录中解压文件,这很可能是您家目录的“下载”文件夹。第二个命令将解压文件,但通过传递 -d 和一个路径,它将解压到该位置。在这种情况下,这是我的家目录的“根”。

现在您已经解压了文件,可以通过在 Ambari 中选择图标下拉菜单中的“文件视图”来打开它。选择“上传”,将弹出一个模态窗口,允许您拖放文件。在您的本地机器上,浏览到 Esri Java ARchive (JAR) 文件的位置。如果您将压缩文件移动到您的家目录,路径将类似于 /home/pcrickard/gis-tools-for-hadoop-master/samples/lib。您将拥有三个 JAR 文件:

  • esri-geometry-api-2.0.0.jar
  • spatial-sdk-hive-2.0.0.jar
  • spatial-sdk-json-2.0.0.jar

将这三个文件中的每一个移动到 Ambari 的“根”文件夹。这是 / 目录,这是您启动文件视图时默认打开的位置。

接下来,您通常会也将数据移动到 HDFS,然而,您在之前的示例中已经这样做过了。在这个例子中,您将保留数据文件在您的本地机器上,您将学习如何在不位于 HDFS 的情况下将它们加载到 Hive 表中。

现在您已经准备好在 Hive 中执行空间查询。从图标下拉菜单中选择 Hive View 2.0。在查询面板中,输入以下代码:

add jar hdfs:///esri-geometry-api-2.0.0.jar; add jar hdfs:///spatial-sdk-json-2.0.0.jar; add jar hdfs:///spatial-sdk-hive-2.0.0.jar; create temporary function ST_Point as'com.esri.hadoop.hive.ST_Point'; create temporary function ST_Contains as'com.esri.hadoop.hive.ST_Contains'; drop table earthquakes; drop table counties; CREATE TABLE earthquakes (earthquake_date STRING, latitude DOUBLE, longitude DOUBLE, depth DOUBLE, magnitude DOUBLE,magtype string, mbstations string, gap string, distance string, rms string, source string, eventid string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE; CREATE TABLE counties (Area string, Perimeter string, State string, County string, Name string, BoundaryShape binary) ROW FORMAT SERDE 'com.esri.hadoop.hive.serde.EsriJsonSerDe' STORED AS INPUTFORMAT 'com.esri.json.hadoop.EnclosedEsriJsonInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'; LOAD DATA LOCAL INPATH '/gis-tools-for-hadoop-master/samples/data/earthquake-data/earthquakes.csv' OVERWRITE INTO TABLE earthquakes; LOAD DATA LOCAL INPATH '/gis-tools-for-hadoop-master/samples/data/counties-data/california-counties.json' OVERWRITE INTO TABLE counties; SELECT counties.name, count(*) cnt FROM counties JOIN earthquakes WHERE ST_Contains(counties.boundaryshape, ST_Point(earthquakes.longitude, earthquakes.latitude)) GROUP BY counties.name ORDER BY cnt desc;

运行前面的代码将花费一些时间,具体取决于您的机器。最终结果将看起来像以下图像:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/6d09ff04-db16-420f-8c00-85d0ebc55456.png

之前的代码和结果未加解释,以便您能够运行示例并查看输出。之后,代码将逐块进行解释。

以下代码块的第一部分如下所示:

add jar hdfs:///esri-geometry-api-2.0.0.jar; add jar hdfs:///spatial-sdk-json-2.0.0.jar; add jar hdfs:///spatial-sdk-hive-2.0.0.jar; create temporary function ST_Point as'com.esri.hadoop.hive.ST_Point'; create temporary function ST_Contains as'com.esri.hadoop.hive.ST_Contains';

此块将 HDFS 位置的 JAR 文件添加到其中。在这种情况下,它是 / 文件夹。一旦代码加载了 JAR 文件,它就可以通过调用 JAR 文件中的类来创建函数 ST_PointST_Contains。JAR 文件可能包含许多 Java 文件(类)。add jar 语句的顺序很重要。

以下块删除了两个表——earthquakescounties。如果您从未运行过此示例,您可以跳过这些行:

drop table earthquakes; drop table counties;

接下来,代码为 earthquakescounties 创建表。earthquakes 表被创建,并将每个字段和类型传递给 CREATE。行格式指定为 CSV——','。最后,它是一个文本文件:

CREATE TABLE earthquakes (earthquake_date STRING, latitude DOUBLE, longitude DOUBLE, depth DOUBLE, magnitude DOUBLE,magtype string, mbstations string, gap string, distance string, rms string, source string, eventid string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE;

通过将字段名称和类型传递给CREATE来以类似的方式创建counties表,但数据是 JSON 格式,并将使用你导入的 JAR 文件spatial-sdk-json-2.0.0中的com.esri.hadoop.hive.serde.EsriJSonSerDe类。STORED AS INPUTFORMATOUTPUTFORMAT对于 Hive 来说,是必须的,以便知道如何解析和处理 JSON 数据:

CREATE TABLE counties (Area string, Perimeter string, State string, County string, Name string, BoundaryShape binary) ROW FORMAT SERDE 'com.esri.hadoop.hive.serde.EsriJsonSerDe' STORED AS INPUTFORMAT 'com.esri.json.hadoop.EnclosedEsriJsonInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';

接下来的两个块将数据加载到创建的表中。数据存在于你的本地机器上,而不是 HDFS 上。为了使用本地数据而不先将其加载到 HDFS,你可以使用LOCAL命令与LOAD DATA INPATH一起指定数据的本地路径:

LOAD DATA LOCAL INPATH '/gis-tools-for-hadoop-master/samples/data/earthquake-data/earthquakes.csv' OVERWRITE INTO TABLE earthquakes; LOAD DATA LOCAL INPATH '/gis-tools-for-hadoop-master/samples/data/counties-data/california-counties.json' OVERWRITE INTO TABLE counties;

在加载了 JAR 文件并创建了表并填充了数据后,你现在可以使用两个定义好的函数——ST_PointST_Contains——运行空间查询。这些函数的使用方式与第三章中的示例相同,地理数据库简介

 SELECT counties.name, count(*) cnt FROM counties JOIN earthquakes WHERE ST_Contains(counties.boundaryshape, ST_Point(earthquakes.longitude, earthquakes.latitude)) GROUP BY counties.name ORDER BY cnt desc;

之前的查询通过将县几何形状和每个地震的位置作为点传递给ST_Contains来选择县的name和地震的count。结果如下所示:

https://github.com/OpenDocCN/freelearn-ds-zh/raw/master/docs/py-scp-gis/img/6d09ff04-db16-420f-8c00-85d0ebc55456.png

Python 中的 HDFS 和 Hive

本书是关于 Python 地理空间开发的,因此在本节中,你将学习如何使用 Python 进行 HDFS 操作和 Hive 查询。有几个 Python 和 Hadoop 的数据库包装库,但似乎没有单个库成为突出的首选库,而像 Snakebite 这样的库似乎还没有准备好在 Python 3 上运行。在本节中,你将学习如何使用两个库——PyHive 和 PyWebHDFS。你还将学习如何使用 Python 的子进程模块来执行 HDFS 和 Hive 命令。

要获取 PyHive,你可以使用conda和以下命令:

conda install -c blaze pyhive 

你可能还需要安装sasl库:

conda install -c blaze sasl 

之前的库将赋予你从 Python 运行 Hive 查询的能力。你还将想要能够将文件移动到 HDFS。为此,你可以安装pywebhdfs

conda install -c conda-forge pywebhdfs 

上述命令将安装库,并且像往常一样,你也可以使用pip install或使用其他任何方法。

在安装了库之后,让我们首先看看pywebhdfs

pywebhdfs的文档位于:pythonhosted.org/pywebhdfs/

在 Python 中建立连接,你需要知道你的 Hive 服务器位置。如果你已经跟随了本章,特别是/etc/hosts中的配置更改——你可以使用以下代码来完成:

from pywebhdfs.webhdfs import PyWebHdfsClient as h hdfs=h(host='sandbox.hortonworks.com',port='50070',user_name='raj_ops')

之前的代码将PyWebHdfsClient导入为h。然后它创建与在容器中运行的 HDFS 文件系统的连接。该容器映射到sandbox.hortonworks.com,HDFS 运行在端口50070。由于示例一直使用raj_ops用户,代码也是如此。

现在可用于hdfs变量的函数类似于您的标准终端命令,但名称不同——mkdir现在是make_dirls现在是list_dir。要删除文件或目录,您将使用delete_file_dirmakedelete命令在成功时将返回True

让我们使用 Python 查看我们的 HDFS 文件系统的root目录:

ls=hdfs.list_dir('/')

之前的代码发出了list_dir命令(与ls等效)并将其分配给ls。结果是包含目录中所有文件和文件夹的字典。

要查看单个记录,您可以使用以下代码:

ls['FileStatuses']['FileStatus'][0]

之前的代码通过使用字典键FileStatusesFileStatus来获取单个记录。

要获取字典中的键,您可以使用.keys(),即ls.keys()返回[FileStatuses],以及ls['FileStatuses'].keys()返回['FileStatus']

之前代码的输出如下所示:

{'accessTime':0,'blockSize':0,'childrenNum':1,'fileId':16404,'group':'hadoop','length':0,'modificationTime':1510325976603,'owner':'yarn','pathSuffix':'app-logs','permission':'777','replication':0,'storagePolicy':0,'type':'DIRECTORY'}

每个文件或目录都包含多个数据项,但最重要的是类型、所有者和权限。

运行 Hive 查询示例的第一步是将我们的数据文件从本地机器移动到 HDFS。使用 Python,您可以使用以下代码来完成此操作:

hdfs.make_dir('/samples',permission=755) f=open('/home/pcrickard/sample.csv') d=f.read() hdfs.create_file('/samples/sample.csv',d)

之前的代码创建了一个名为samples的目录,权限为755。在 Linux 中,权限基于三种用户的读取(4)、写入(2)和执行(1)权限——所有者、组和其它。因此,755的权限意味着所有者有读取、写入和执行权限(4+2+1=7),而组和其它有读取和执行权限(4+1=5)。

接下来,代码打开并读取我们想要传输到 HDFS 的 CSV 文件,并将其分配给变量d。然后,代码在samples目录中创建名为sample.csv的文件,传递d的内容。

要验证文件是否已创建,您可以使用以下代码来读取文件的内容:

hdfs.read_file('/samples/sample.csv')

之前代码的输出将是 CSV 文件的字符串。它已成功创建。

或者,您可以使用以下代码来获取文件的状态和详细信息:

hdfs.get_file_dir_status('/samples/sample.csv')

之前的代码将返回以下详细信息,但仅当文件或目录存在时。如果不存在,前面的代码将引发FileNotFound错误。您可以将前面的代码包裹在tryexcept块中:

{'FileStatus':{'accessTime':1517929744092,'blockSize':134217728,'childrenNum':0,'fileId':22842,'group':'hdfs','length':47,'modificationTime':1517929744461,'owner':'raj_ops','pathSuffix':'','permission':'755','replication':1,'storagePolicy':0,'type':'FILE'}}

数据文件已传输到 HDFS 后,您可以继续使用 Hive 查询数据。

PyHive 的文档位于:github.com/dropbox/PyHive

使用pyhive,以下代码将创建一个表:

from pyhive import hive c=hive.connect('sandbox.hortonworks.com').cursor() c.execute('CREATE TABLE FromPython (age int, name string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ","')

之前的代码将pyhive导入为hive。它创建了一个连接并获取了游标。最后,它执行了一个 Hive 语句。一旦您有了连接和游标,您就可以通过将它们包裹在.execute()方法中来执行 SQL 查询。要将 HDFS 中的 CSV 数据加载到表中并选择所有内容,您将使用以下代码:

c.execute("LOAD DATA INPATH '/samples/sample.csv' OVERWRITE INTO TABLE FromPython") c.execute("SELECT * FROM FromPython") result=c.fetchall()

之前的代码使用了 execute() 方法两次来加载数据,然后执行了全选操作。使用 fetchall(),结果被传递到 result 变量中,其外观将类似于以下输出:

[(40,' Paul'),(23,' Fred'),(72,' Mary'),(16,' Helen'),(16,' Steve')]

使用 pyhive 就像使用 psycopg2 一样——这是连接到 PostgreSQL 的 Python 库。大多数数据库包装库都非常相似,你只需建立连接,获取一个 cursor,然后执行语句。结果可以通过获取所有、一个或下一个(可迭代)来检索。

摘要

在本章中,你学习了如何设置 Hadoop 环境。这需要你安装 Linux 和 Docker,从 Hortonworks 下载镜像,并学习该环境的使用方法。本章的大部分内容都花在了环境和如何使用提供的 GUI 工具执行空间查询上。这是因为 Hadoop 环境很复杂,如果没有正确的理解,就很难完全理解如何使用 Python 来操作它。最后,你学习了如何在 Python 中使用 HDFS 和 Hive。用于与 Hadoop、Hive 和 HDFS 一起工作的 Python 库仍在开发中。本章为你提供了一个基础,这样当这些库改进时,你将拥有足够的关于 Hadoop 和相关技术的知识,以实现这些新的 Python 库。

Read more

从零开始使用ISSACLAB训练自己的机器人行走

从零开始使用ISSACLAB训练自己的机器人行走

ISAACLAB入门教程 作者:陈维耀 1. 环境配置 1.1 推荐配置 * 操作系统: Ubuntu 22.04 LTS * 显卡: NVIDIA RTX 4080或以上 1.2 ubuntu 22.04 LTS安装 参考ZEEKLOG的Ubuntu 16.04 LTS安装教程,将其中的ubuntu 16.04镜像文件替换为ubuntu 22.04镜像文件,其他步骤保持不变,建议/home与/usr的硬盘容量均不少于200G。 1.3 安装NVIDIA驱动 根据自身显卡型号与操作系统,选择对应的显卡驱动,建议选择550.xxx.xxx版本的显卡驱动,按照教程进行安装即可,安装完成后在终端输入nvidia-smi,若出现以下信息则表示驱动安装成功: Thu Jun 5

By Ne0inhk
最新 neo4j 5.26版本下载安装配置步骤(新手必备)

最新 neo4j 5.26版本下载安装配置步骤(新手必备)

目录 初识:neo4j 安装环境要求 一、下载Neo4j 二、配置环境变量 三、启动测试 四、常用命令及配置 创作不易,禁止转载抄袭!!!违者必究!!! 创作不易,禁止转载抄袭!!!违者必究!!! 创作不易,禁止转载抄袭!!!违者必究!!! 初识:neo4j Neo4j是一个高性能的NoSQL图形数据库,它将结构化数据存储在网络(从数学角度称为图)上而不是传统的表中。‌ Neo4j是一个嵌入式的、基于磁盘的、具备完全事务特性的Java持久化引擎,特别适合处理具有复杂关系的数据‌。 安装环境要求 * 操作系统:Windows 10/8/7、macOS 10.13或更高版本、Linux(Ubuntu、CentOS、Red Hat 等) * JDK 17 或更高版本(Neo4j

By Ne0inhk
【VR音游】音符轨道系统开发实录与原理解析(OpenXR手势交互)

【VR音游】音符轨道系统开发实录与原理解析(OpenXR手势交互)

VR音游音符轨道系统开发实录与原理解析 在 VR 音游的开发过程中,音符轨道系统是最核心的交互与可视化部分。本文结合一次完整的开发实录,分享从核心原理与设计到VR内容构建的完整过程,帮助读者快速理解音符轨道系统的实现思路。 文章目录 * VR音游音符轨道系统开发实录与原理解析 * 一、实录结果 * 二、VR内容开发步骤 * 1. 准备音符与交互逻辑 * 2. 创建谱面 * 3. 绘制音轨 * 4. 预制件与音频替换 * 三、原理解析(音符轨道系统) * 1. 音符轨道(Note Track) * 2. 轨迹调节与偏移控制 * 3. 音符触摸激活 * 4. 谱面编辑工具(Editor 功能) * 四、总结与展望 * 1. 成果回顾:从零到一的核心突破 * 2. 技术总结:核心设计理念 * 3. 开发难点与问题反思 * 4. 优化策略与改进方向 * 5.

By Ne0inhk
医疗连续体机器人模块化控制界面设计与Python库应用研究(下)

医疗连续体机器人模块化控制界面设计与Python库应用研究(下)

软件环境部署 系统软件架构以实时性与兼容性为核心设计目标,具体配置如下表所示: 类别配置详情操作系统Ubuntu 20.04 LTS,集成RT_PREEMPT实时内核补丁(调度延迟<1 ms)开发环境Python 3.8核心库组件PyQt5 5.15.4(图形界面)、OpenCV 4.5.5(图像处理)、NumPy 1.21.6(数值计算) 该环境支持模块化控制界面开发与传感器数据的实时融合处理,为连续体机器人的逆运动学求解(如FB CCD算法测试)提供稳定运行基础[16]。 手眼协调校准 为实现视觉引导的精确控制,需完成相机与机器人基坐标系的空间映射校准,具体流程如下: 1. 标识点布置:在机器人末端及各段首尾、中间位置共固定7个反光标识点,构建臂型跟踪特征集[29]; 2. 数据采集:采用NOKOV度量光学动作捕捉系统(8台相机,

By Ne0inhk