使用Python进行密集度分析以找到最近的酒吧
利用Python进行密集度分析,轻松发现最近的酒吧
关于空间数据处理的几点说明

免责声明:在本文中,我们将使用开源库estaty来演示所有方法。该库是为了将我们工作中使用的算法形式化成为一个可供其他开发者使用的工具而创建的。换句话说,本文是由该库的维护者编写的。
今天我们想继续讨论使用开源Python库进行空间数据处理的主题。我们已经讨论过如何结合Open Street Map和Landsat开放数据验证绿色区域附近的房地产对象。
现在让我们来考虑另一种类型的分析:邻近分析,或者是某些有用对象(如公园、医院、幼儿园等)的可用性或可访问性(图1)。

关于邻近分析的一点说明
我们建议从简短的文献综述开始讲述。我喜欢文章“每个数据科学家都应该了解的位置分析应用案例”(注意-这是会员专属文章),它很容易向读者介绍地理信息分析是什么。
- AI如何提升虚拟现实设备的用户体验
- 据耶鲁大学和Google DeepMind的研究人员使用先进的微调技术在大型语言模型上取得了数学问题解决的成功
- 《来自华盛顿大学和NVIDIA的研究人员提出的人形智能代理:一种用于生成型代理的人类模拟的人工智能平台》
文章“创建成本距离表面以衡量公园可达性”和“犹他州不断增长:犹他州居民对医疗保健设施的邻近分析”也很清楚地展示了城市工程师可以计算的这些分析的特征。这个主题相当受欢迎,已经开发了许多科学论文和实际应用-让我们参与其中。
我们使用的库
现在让我们进入更具体的讨论:用于进行该邻近分析的工具(除了像QGIS或ArcGIS这样的地理信息系统和作为产品最终用户的专有服务)。
作为开发者,我们希望使用方便的库或服务来分析原始值而不是聚合数据(最好是开源的)。我们没有找到适合我们的工具,所以我们自己编写并使用了一个名为estaty的开源Python库。如果您愿意,在阅读本文后,可以查看该库的文档页面:
基于这个库,我们组织了使用案例。基于这些示例,我们开发了微服务,帮助房地产经理进行分析。除了现成的服务,这些脚本也被组织成使用案例,并提供给任何想使用该库的人。
estaty可以使用不同的数据源来进行计算,但开放的示例(为保持其真实性)是基于OpenStreetMap数据的。在本文中,我们希望展示如何进行相当快速的附带评估,并根据需要扩展到新的数据源。
分析(我们可以做的)
首先,使用以下命令安装库
pip install estaty==0.1.0
或者,如果您使用poetry:
poetry add estaty==0.1.0
我们现在准备好使用0.1.0版本
让我们开始实现。我们将对以下地址提供附近分析:“柏林,Neustädtische Kirchstraße 4-7” – 坐标 {纬度: 52.5171411, 经度: 13.3857187}。我们将在2公里的半径内分析该对象的邻域。
为了了解我们到最近的酒吧需要多长时间(根据OSM的数据 – 值得一提的是),让我们编写并运行以下代码:
这里发生了以下情况 – 我们构建一个用于分析属性的处理流水线。该流水线看起来像是一个图形,由对数据进行顺序转换的节点组成:

让我们更详细地看看“车底下”发生了什么。让我们从estaty架构的5个抽象层开始讲起(在上面的流水线中,只使用了三种节点类型):
- DataSource – 从所需源加载数据,将数据转换为通用标准(矢量和栅格)。无论源自何处,该节点的输出将仅有两种可能的变体,这样可以统一它们的进一步处理;
- Preprocessor – 对矢量或栅格数据进行预处理,例如分配新的坐标参考系统(CRS);
- Merger – 以所需方式合并数据。可能的组合:矢量数据与矢量数据,栅格与栅格以及矢量数据与栅格数据;
- Analyzer – 库的核心 – 使用简单的原子转换对栅格和矢量对象进行某些分析,例如区域匹配或路径查找;
- Report – 可选的最终分析模块,允许以用户友好的格式生成报告。
通过以某种方式组合这些节点,可以在不修改原始数据处理方式的情况下构建不同的数据分析流水线 – 仅替换原始来源或分析方法(参见动画1)。

因此,图2显示分析中仅使用了三个节点 – 这是一个相当简单的流水线。通过其工作,我们将获得一个geopandas GeoDataFrame(包含对象的几何形状的表)与线状对象 – 到我们感兴趣的对象(酒吧)的路线。顺便说一句,结果的可视化将如下所示:

我们有权对获得的一系列线状对象做任何我们想做的事情 – 例如,找到到最近酒吧的距离,或从样本中请求平均值(代码中所做的):
- 最小长度:308.93米
- 平均长度:2306.49米
作为一个对大城市中心的酒吧位置非常了解的专家,我可以说实际上在分析区域内的酒吧可能更多。但是,我们一开始就约定了基于OSM数据进行分析,所以……。
管道本身与数据源之间的关联性是独立的。这是通过库模块的弱关联性来保证的。让我们从数据源节点开始——它内置了一种数据转换机制,将数据转换为一种类型(例如,这里的矢量数据将以geopandas GeoDataFrame格式进行,并且始终只有三种类型,无论我们使用的数据源是什么,都将被转换为点、线或面)。然后是预处理器,它将自动确定我们数据的适当度量投影。对预处理器来说,唯一重要的是数据必须来自节点的数据源,其他的事情应该由它之前的节点来处理。而我们简单的管道最后由一个分析块完成,它将在任何几何对象上运行,无论它们是区域、线性还是点。
因此,我们可以对从OSM提取的其他数据类别进行完全相同的计算(当然,列表不仅限于OSM),例如,针对学校、公园、水体、公共厕所、垃圾处理箱、警察局等的接近度分析——任何东西(有关可以通过标签定义的对象类型,请参阅维基页面 Map features或文档 estaty about data sources):

如何扩大这一方法
我们提到了可以分析任何性质的空间数据:社交数据、自然对象或人工建筑。让我们更深入地看一下源代码。从图中可以看出,距离计算是基于考虑道路的路径进行的,这是合理的,因为我们通常不会乘直升机去酒吧,而是步行。因此,“距离”分析包括在道路图上搜索路径,使用的道路图来自OSM。也就是说,算法在以下抽象上搜索路径(我们依赖于以下文章,强烈推荐 — OSMnx: Python for Street Networks):

这里的图是具有地理参考(具有纬度和经度属性)的节点和边。为了找到从A对象到B对象的最短路径,我们需要经过三个步骤:
- 在图中找到离A对象最近的节点(我们称之为节点1)
- 在图中找到离B对象最近的节点(我们称之为节点2)
- 使用图遍历算法,找到从节点1到节点2的最佳路径
如果我们想得到距离,需要将从节点1到节点2的路径长度与从A对象到节点1和从B对象到节点2的距离相加。由于节点网络相当密集,最后两个组成部分可以直接以直线距离计算。但是这里存在一个困难 —— 如果A和B是点,则相对容易找到最靠近它们的节点(计算两点间的距离)。如果A的几何形状是一个区域,那么我们就必须寻找最靠近多边形的“最近”节点。对于线性对象的情况,该怎么办也是一个需要解决的问题。
那么,让我们来回答这个问题,“如何以统一的方式计算图形节点与不同类型的矢量对象(线、点和多边形)之间的距离”?为此,该库在开始计算路径之前将对象转换为点类型(计算点之间的距离非常简单)。我们将这样的转换称为表示(图7)。

也就是说,我们不再编写和维护三个算法,而是编写一个(用于搜索到达点的路径),然后将所有初始数据类型简化为一个类型。如何将它们简化为一个类型是一个含糊的问题。我们可以通过计算质心来简化。然而,在城市区域进行计算时,特别是对于大型对象(如公园),计算质心的路径可能是不必要的——我们认为当我们从铺着柏油的路径上第一步进入愉快的泥土公园黑暗时,我们已经到达了公园。
因此,我们决定采用一种方法,即找到多边形或线性对象与分析对象(构建路径的对象)最近的点。然后,将此点视为最终目标节点,通过此节点构建进一步的图形路径。
更高级的分析
仅仅通过到酒吧的路线并不能给任何人留下深刻的印象。因此,让我们将任务复杂化。假设我们想通过结合来自不同来源的数据进行更复杂的分析。例如,我们想计算平均要走多远才能到达橡树公园(我们喜欢在酒吧后散步并欣赏长满树木的公园)。为此,我们将结合两个来源的数据:
- 从GBIF | 全球生物多样性信息设施(请查看 https://www.gbif.org/,截至2023年10月20日相关)下载矢量数据
- OpenStreetMap – 在该库中进行数据下载的原生集成
GBIF数据是一个具有点几何形状的矢量图层,显示了已发现某些植物、动物(以及其他一些东西)的位置。在这种情况下,我们将对橡树(或拉丁名为欧洲栎)感兴趣。当我们将一个点图层与公园的多边形叠加在一起时,我们的数据将如下所示:

分析的代码如下所示:
需要注意的一件重要事情是,这些点不必完全落在公园的多边形内。我们结合了不同来源的数据,它们可能会略有差异。因此,我们设置一个10米的缓冲区并查看结果(图9)——根据GBIF数据,我们认为如果公园多边形与缓冲区多边形有交集,那么公园中就存在一棵橡树:

关于相关性的更多说明
这个分析主题是有需求且显而易见的。因此,例如,在许多源代码解决方案中都有路由功能(在准备本文时,我遇到了一个有趣的笔记本“Exploring routing tools for calculating paths for a set of origin-destination pairs”),以及在流行的用户服务(如Google Maps)和与地图相关的服务中也提供了此功能。如果我们谈论接近性分析,那么这方面也有很多已实施的解决方案,例如可以提及像 pandana 这样的工具。
所有这些工具当然都非常有用,但是在应用示例中使用它们需要编写一些辅助代码。我们正在努力为我们自己的团队制作一个方便的工具,并希望与社区分享我们的发现。在本文中提出的方法中,我们提到了与数据源无关的方法和一种灵活的组合数据的方式。我们将非常乐意收到评论和建议。
有用的链接:
- https://github.com/red5ai/estaty — 用于处理空间数据并为财产分析准备原型算法的Python开源库。该库非常新,但我们计划持续开发和改进它;
- https://estaty.readthedocs.io/en/latest/ — 文档页面;
- https://github.com/red5ai/estaty_examples — 为本文提供示例启动的开源存储库
本文中使用的数据集(及其许可证):
- 地图数据版权归OpenStreetMap贡献者所有,并可从 https://www.openstreetmap.org 获取授权 — 开放数据共享公共数据库许可证链接截至2023年10月25日是最新的
- GBIF.org (2023年10月20日) GBIF出现性下载 https://doi.org/10.15468/dl.f487j5 许可证 — 署名-非商业性使用 4.0 国际许可证链接截至2023年10月25日是最新的
关于使用OpenStreetMap数据进行邻近性分析等的故事,由Mikhail Sarafanov和Wiredhut团队提供。




