矢量数据空间查询

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
实时计算 Flink 版,1000CU*H 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
简介: 空间查询就是根据地物的空间位置进行查询的一种数据检索方式。比如,我们要查询一条河流经的城市;一个公园内的所有路灯;离当前位置最近的公共卫生间等等都属于常用的空间查询。

开篇

在前面四篇博客中我们主要讲了对于空间矢量数据的属性数据的增删改查,在这篇博文中我们要讲解空间查询--GIS系统很重要的一项功能。空间查询就是根据地物的空间位置进行查询的一种数据检索方式。比如,我们要查询一条河流经的城市;一个公园内的所有路灯;离当前位置最近的公共卫生间等等都属于常用的空间查询。

OGC简单要素规范定义了空间几何体之间的空间关系,包括Equals,Disjoint,Intersects,Touches,Crosses,Within,Contains,Overlaps,Relate,LocateAlong,LocateBetween。感兴趣的同学可以从OGC官网下载下来看看。

现有的空间数据库例如Oracle Spatial,PostGIS,SQL Server都根据OGC简单要素规范提供了对空间查询的支持,他们有差异地在标准SQL语句中添加了空间关系查询的功能。

本文主要介绍如何使用GDAL库对空间数据进行空间查询,常用的方法可以概括为三大类:

  1. 第一类就是使用支持空间查询的SQL语句进行查询,但是这种方式只对某些特定种类的数据源可以使用,有些数据源不一定支持。
  2. 第二类是使用GDAL提供的SetSpatialFilter()方法增加过滤条件。但是这种方式只能是选择给定范围的空间地位,类似于Within或者Contains的功能,不能实现其他类型的空间关系查询。
  3. 第三类就是读取每个Feature要素包含的Geometry对象,根据Geometry的空间关系手动进行筛选。因为GDAL中的Geometry对象基本上实现了OGC简单要素规范定义的空间关系,所以这种方式最灵活,本文主要介绍如何使用这种方式进行空间查询。

案例一

案例说明

我们现在有省的面状数据以及每个城市的点数据,我们需要找到湖北省内的所有城市。

实现思路是先从省的面状数据中找出湖北省,然后遍历城市的点数据看是否落在湖北省境内。

代码演示

import ogr
ogr.UseExceptions()

ds_province: ogr.DataSource = ogr.Open('../data/Provinces.shp')
l_province: ogr.Layer = ds_province.GetLayer()
# 使用filter()方法找出湖北省
f_hubei: ogr.Feature = next(filter(lambda f: '湖北' in f.GetField('NAME'), l_province))

ds_city: ogr.DataSource = ogr.Open('../data/Cities.shp')
l_city: ogr.Layer = ds_city.GetLayer()
# 使用filter()方法过滤出落在湖北省境内的所有市
selected = filter(lambda f: f.GetGeometryRef().Within(f_hubei.GetGeometryRef()), l_city)
for city in selected:
    print(city.GetField('name'))
del ds_province
del ds_city

方法总结

  1. 使用ogr.Open()函数读取Shapefile数据,使用GetLayer()获取当前图层,图层中包含了所有的Feature要素。
  2. 使用Python的内置filter()函数对省进行过滤,通过NAME字段找出湖北省。filter()函数的第一个参数是一个自定义函数,第二个参数是一个可迭代对象iterable。该函数会遍历可迭代对象将满足第一个自定义函数的值过滤出来。通过next()方法拿到迭代器的当前值,即湖北省的Feature对象。
  3. 继续使用filter()函数对城市的点数据进行筛选,这里通过Feature的GetGeometryRef()方法获得要素代表的几何体,然后调用Geometry的Within()方法判断该城市是否落在湖北省对应的Geometry中。

案例二

案例说明

我们将使用城市的点数据获取离武汉市最近的三座城市。

实现的思路是首先从数据中找到武汉市,然后计算每个城市到武汉市的距离并排序,对排好序的Feature选择前三即可。

代码演示

import ogr
ogr.UseExceptions()

ds: ogr.DataSource = ogr.Open('../data/Cities.shp')
cities: ogr.Layer = ds.GetLayer()
# 使用filter()方法找出武汉市
city: ogr.Feature = next(filter(lambda f: '武汉' in f.GetField('name'), cities))
# 调用ResetReading()方法特别重要,如果不ResetReading的话后面的对Feature的遍历会出错
cities.ResetReading()
# 根据每个市到武汉市的距离进行排序
selected = sorted(cities, key=lambda f: f.GetGeometryRef().Distance(city.GetGeometryRef()))
for i in range(1, 4):
    print(selected[i].GetField('name'))
del ds

方法总结

  1. 跟案例一一样,我们使用Python的内置filter()函数对市进行过滤,通过NAME字段找出武汉市。
  2. 需要特别注意了,当我们遍历完一遍Layer的Feature以后需要调用ResetReading()对迭代器重新归位,否则后面要继续进行要素遍历的话会出错。
  3. 接着我们使用Python内置函数sorted()根据每个城市到武汉市的距离进行排序。sorted()函数包含三个参数(后两个可选),第一个参数是一个可迭代对象iterable,第二个参数是用于自定义排序的函数,第三个参数指定是否逆序。sorted()函数的返回值是一个list对象。
  4. 对于距离的计算,我们首先使用GetGeometryRef()函数获得要素对应的空间几何体,然后再使用Geometry对象的Distance()函数进行。
  5. 计算完以后我们从第二个元素进行输出,因为第一个元素肯定是武汉市,武汉市到武汉市的距离为0,为最小距离。
目录
相关文章
|
6月前
|
存储 监控 网络协议
了解流量探针,助你更好地优化网络
流量探针是现代网络运维中不可或缺的工具,用于实时监测网络数据包,提供一手数据。它通过镜像方式采集、过滤、分析流量,支持从二层到七层协议解码,助力网络瓶颈排查、业务性能优化及安全威胁检测。合理部署流量探针可实现精细化网络管理,提升性能与安全性。
|
缓存 关系型数据库 MySQL
高并发架构系列:数据库主从同步的 3 种方案
本文详解高并发场景下数据库主从同步的三种解决方案:数据主从同步、数据库半同步复制、数据库中间件同步和缓存记录写key同步,旨在帮助解决数据一致性问题。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
高并发架构系列:数据库主从同步的 3 种方案
|
SQL 关系型数据库 MySQL
MySQL语法
MySQL语法
284 4
|
SQL 分布式计算 关系型数据库
超详细!搭建本地大数据研发环境(16G内存+CDH)(二)
超详细!搭建本地大数据研发环境(16G内存+CDH)(二)
1471 0
超详细!搭建本地大数据研发环境(16G内存+CDH)(二)
|
Java 编译器 数据安全/隐私保护
Java 重写(Override)与重载(Overload)详解
在 Java 中,重写(Override)和重载(Overload)是两个容易混淆但功能和实现方式明显不同的重要概念。重写是在子类中重新定义父类已有的方法,实现多态;重载是在同一类中定义多个同名但参数不同的方法,提供多种调用方式。重写要求方法签名相同且返回类型一致或为父类子类关系,而重载则关注方法参数的差异。理解两者的区别有助于更好地设计类和方法。
1063 3
|
Kubernetes 监控 Cloud Native
Cluster Optimizer:一款云原生集群优化平台
**Cluster Optimizer** 是一款云原生集群优化平台,旨在通过自动化和智能化工具帮助企业降低云成本,解决云原生架构中的成本管理难题。面对资源闲置、配置不当和缺乏自动化优化机制等挑战,Cluster Optimizer能够深入分析云资源、应用和用户行为,精准识别优化机会,并给出具体建议,涵盖节点组、节点、GPU 节点、磁盘、持久卷和应用等多个维度。通过优化实例类型、自动扩缩容和资源分配,帮助企业降低成本、提升性能和效率。[点击此处](https://www.wiseinf.com.cn/docs/setup/) 免费安装和试用 **Cluster Optimizer 社区版**。
263 10
|
存储 NoSQL 分布式数据库
数据库的演进之路:从传统到现代,技术的飞跃与应用
一、引言 数据库作为数据存储和管理的核心工具,随着信息技术的快速发展,经历了从简单到复杂、从单机到分布式的演进过程
|
Web App开发 存储 Linux
Linux Apache服务详解——Apache服务访问控制
Linux Apache服务详解——Apache服务访问控制
671 7
|
算法 安全 数据处理
【C++ 编程范式】理解C++ 中编程范式,选择合适的方式
【C++ 编程范式】理解C++ 中编程范式,选择合适的方式
545 2
|
关系型数据库 MySQL
MySQL union和union all的用法详解和区别
MySQL union和union all的用法详解和区别
1700 0
下一篇
oss云网关配置