PostGIS学习教程二十一:最近领域搜索

PostGIS学习教程二十一:最近领域搜索

注意:本节涉及的功能只在PostGIS2.0及更高的版本可用。

文章目录

  • PostGIS学习教程二十一:最近领域搜索
  • 一、什么是最近邻域搜索?
  • 二、基于索引的KNN


一、什么是最近邻域搜索?

一个常见的空间查询是:“距离一个要素最近的是哪些要素?”

与距离查询不同,最近邻域搜索(Nearest Neighbour Search)没有限制候选几何图形在什么范围之内,任何距离的要素都将被接受,只要它们是最近的。这引出了关于传统的索引辅助查询的一个问题,这些查询需要一个搜索框,因此需要某种测量值来限定这个框。

执行最近邻域搜索的简单方法是按与要查询的几何图形的距离对候选表进行排序,然后获取最小距离对应的表记录。

SELECT streets.gid, streets.name
FROMnyc_streets streets,nyc_subway_stations subways
WHERE subways.name = 'Broad St'
ORDER BY ST_Distance(streets.geom, subways.geom) ASC
LIMIT 1;

在这里插入图片描述
这种方法的问题是,它强制数据库计算查询几何图形和候选要素表中每个要素之间的距离,然后对它们进行排序。对于一个庞大的候选要素表,这不是一个合理的方法。

提高性能的一种方法是向搜索添加空间索引约束。这需要一个神奇的数字:我们可以在查询几何图形周围搜索的最小方框是什么?并且仍然可以找到至少一个候选几何图形?

如果启用计时,可以看到下面的方框辅助查询和上面的简单查询之间的性能差异。

-- Closest street to Broad Street station is Wall St
SELECT streets.gid, streets.name
FROMnyc_streets streets,nyc_subway_stations subways
WHERE subways.name = 'Broad St'
AND streets.geom && ST_Expand(subways.geom, 200) -- Magic number: 200m
ORDER BY ST_Distance(streets.geom, subways.geom) ASC
LIMIT 1;

在这里插入图片描述
这种方法的问题在于200米这个神奇的数字,如果在200米内没有道路呢?我们可能不会得出结果:因为虽然总会有一个近邻要素,但它可能不在200米之内。

二、基于索引的KNN

“KNN"代表"K nearest neighbours(K近邻)”,其中"K"是要寻找的结果的数量。

KNN是一种基于纯空间索引的近邻搜索方法。通过在索引中上下移动,搜索可以在不指定任何半径的情况下找到最近的候选几何图形,因此该技术适用于具有高度变量数据密度的大表,并且具有很高的性能。

注意:KNN功能仅在PostgreSQL 9.1和PostGIS 2.0或更高版本上可用。

KNN系统的工作原理是评估PostGIS的R-Tree索引中几何图形边界框之间的距离。

由于索引是使用几何图形的边界框构建的,因此任何不是点的几何图形之间的距离都将不精确:它们将是几何图形边界框之间的距离,而不是几何图形之间的距离。

基于索引的KNN查询的语法在查询的ORDER BY子句中放置了一个特殊的"基于索引的距离运算符",在本例中使用了"<->"运算符。有两种基于索引的距离运算符:

<-> —— 表示边界框中心之间的距离
<#> —— 表示边界框边界之间的距离
基于索引的距离运算符的一侧必须是字面几何值。可以使用返回为单个几何图形的子查询代替,也可以使用一个WKT几何图形代替。

-- Closest 10 streets to Broad Street station are ?
SELECTstreets.gid,streets.name
FROMnyc_streets streets
ORDER BYstreets.geom <->(SELECT geom FROM nyc_subway_stations WHERE name = 'Broad St')
LIMIT 10;-- Same query using a geometry EWKT literalSELECT ST_AsEWKT(geom)
FROM nyc_subway_stations
WHERE name = 'Broad St';
-- SRID=26918;POINT(583571 4506714)SELECTstreets.gid,streets.name,ST_Distance(streets.geom,'SRID=26918;POINT(583571.905921312 4506714.34119218)'::geometry) AS distance
FROMnyc_streets streets
ORDER BYstreets.geom <->'SRID=26918;POINT(583571.905921312 4506714.34119218)'::geometry
LIMIT 10;

在这里插入图片描述
在这里插入图片描述
第二个查询的结果显示了对非点几何图形的基于空间索引的查询看上去有多奇怪。Wall St(华尔街)在我们的结果集中仅排名第三,尽管从Broad St车站到Wall St的绝对距离仅仅只有0.714米!
请记住,所有计算都是在边界框上完成的。地铁站点的边界框就是该点本身,因此是准确的。但是街道的边界框和街道线串几何图形本身是不一样的,最近的前十条街道的边界框是这样的:
在这里插入图片描述
我们可以看到车站正好落在华尔街的线串上,并且在华尔街的边界框中。但是这个索引顺序是由"<->"操作符控制的,它计算边界框中心之间的距离。边界框中心如下:
在这里插入图片描述
现在很清楚为什么华尔街没有作为我们搜索结果的第一个记录出现了。因为华尔街边界框的中心确实比Exchange Place(交易所)的边界框的中心离Broad St车站更远。

那么"<#>"运算符呢?如果我们计算边界框边界之间的距离,车站就会落在华尔街边界框内,车站与华尔街的边界框之间的距离为0,所以它作为返回结果的第一个条目返回对吗?

-- Closest 10 streets to Broad Street station are ?
SELECTstreets.gid,streets.name
FROMnyc_streets streets
ORDER BYstreets.geom <#>'SRID=26918;POINT(583571.905921312 4506714.34119218)'::geometry
LIMIT 10;

在这里插入图片描述
很遗憾,并不是。
有许多带有大的边界框的要素,这些边界框也与车站重叠,所以车站与它们的边界框的距离也为0。。。那到底该怎么搞?
在这里插入图片描述
要获得高性能但精确的近邻计算,正确的方法是使用一个子查询提取前100个可能的结果(或者,如果你认为你的数据在分布上更均匀,则可以选择一个较小的数字),然后再计算所有这些结果与车站(Broad St)的真实距离,并从该结果集合返回最近的记录。

-- "Closest" 100 streets to Broad Street station are?
WITH closest_candidates AS (SELECTstreets.gid,streets.name,streets.geomFROMnyc_streets streetsORDER BYstreets.geom <->'SRID=26918;POINT(583571.905921312 4506714.34119218)'::geometryLIMIT 100
)
SELECT gid, name
FROM closest_candidates
ORDER BYST_Distance(geom,'SRID=26918;POINT(583571.905921312 4506714.34119218)'::geometry)
LIMIT 1;

在这里插入图片描述
请注意,在查询点表时,由于边界框与点完全相同,因此可以直接使用按空间索引排序的结果,而不必使用子查询。
– The 10 nearest stations to Broad St station
SELECT gid, name
FROM nyc_subway_stations
ORDER BY geom <-> ‘SRID=26918;POINT(583571.905921312 4506714.34119218)’::geometry
LIMIT 10;

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/667715.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游戏如何选择服务器

游戏如何选择服务器 1、CPU处理器&#xff1a;作为游戏服务器的运算和控制核心&#xff0c;是信息处理、程序运行的最终执行单元。我们可以将它简单的理解为公司的核心部门&#xff0c;一个核心部门的处理效率&#xff0c;就是核心数和线程数&#xff0c;比如16核心32线程&…

在java中获取excel的cell值的时候报错

在获取cell的时候&#xff0c;通常会有报错类型不匹配的问题&#xff0c;这是因为你的cell中存储的数据类型和使用的方法不匹配的原因&#xff0c;假如说cell中存储了一个数字&#xff0c;但是使用的cell.getStringCellValue()获取值&#xff0c;就会有如下错误 java.lang.Ill…

微信小程序checkbox多选

效果图 <view class"block"><view class"header"><view class"header-left"><text class"pu-title">数据</text><text class"pu-tip">至少选择一个指标</text></view>&l…

go-redis hash slot 之旅

搭建redis 集群 创建一个网桥 docker network create -d bridge --subnet192.168.148.0/24 --gateway192.168.148.1 -o parenteno1 redis-net通过docker 文件创建redis 集群&#xff0c; 这里注意要不要使用redis 7以上的版本&#xff0c;不然会出问题 version: "3&quo…

Tomcat组件架构与数据流

一、背景与简介 Tomcat我们都知道是一个开源的、实现了大部分Java EE、Servlet、JSP规范的Servlet容器, 允许我们将实现了Serlvet接口的Web程序war包进行部署运行。 但是你有对Tomcat做过细致的学习么? 我相信大部分同学和我一样&#xff0c;之前也是只会进行简单使用&#x…

django线上教育学习平台大数据分析系统python

随着互联网技术不断地发展&#xff0c;网络与大数据成为了人们生活的一部分&#xff0c;而线上教育平台大数据分析作为网上应用的一个全新的体现&#xff0c;由于其特有的便捷性&#xff0c;已经被人们所接受。目前主流的线上教育平台大数据分析服务不仅不明确并且管理盈利较低…

解析Go内存逃逸

Go语言以其内建的垃圾回收机制和内存安全性而著称。然而&#xff0c;在编写Go代码时&#xff0c;我们仍然需要关注内存的分配和释放&#xff0c;以确保程序的性能和稳定性。接下来将深入讨论Go中的内存逃逸现象&#xff0c;探讨其原因、优化策略&#xff0c;以及在实际开发中的…

NLP任务之Named Entity Recognition

深度学习的实现方法&#xff1a; 双向长短期记忆网络&#xff08;BiLSTM&#xff09;: BiLSTM是一种循环神经网络&#xff08;RNN&#xff09;的变体&#xff0c;能够捕捉序列数据中的长期依赖关系。在NER任务中&#xff0c;BiLSTM能有效地处理文本序列&#xff0c;捕捉前后文本…

专业课130+总分420+南京大学851信号与系统考研经验南大电子信息与通信系统

经过一年的复习&#xff0c;顺利上岸&#xff0c;被南京大学录取&#xff0c;今年专业课130&#xff0c;总分420&#xff0c;回忆这一年的复习还是有很多经验分享&#xff0c;希望对大家复习有帮助。 专业课&#xff1a; 南京大学851信号与系统难度这几年无论是范围还是难度都…

【MySQL】学习并使用DQL实现排序查询和分页查询

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-SP91zTA41FlGU0Ce {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

计算机服务器中了DevicData勒索病毒如何解密,DevicData勒索病毒解密流程

网络数据安全一直是企业关心的主要话题&#xff0c;近期&#xff0c;云天数据恢复中心接到很多企业的求助&#xff0c;企业的计算机服务器遭到了DevicData勒索病毒攻击&#xff0c;导致企业计算机服务器瘫痪无法正常工作&#xff0c;严重影响了工作业务开展。经过云天数据恢复中…

软件架构风格:您的系统设计指南

软件架构风格&#xff1a;您的系统设计指南 软件架构不仅仅是组织代码的方式&#xff0c;它是对软件整体结构和行为的全面规划。一个好的架构能够让软件更加灵活、可维护&#xff0c;并且能够应对未来的变化。下面是一些流行的软件架构风格&#xff0c;以及它们的C#代码例子&a…

docker-compose常用命令全集

1、启动或构建应用程序&#xff1a; docker-compose up 根据 docker-compose.yml 文件中定义的配置启动应用程序的服务。如果镜像不存在&#xff0c;将会构建镜像 2、后台启动应用程序&#xff1a; docker-compose up -d 在后台模式下启动应用程序的服务&#xff0c;不会在…

【算法刷题】前K个高频单词

给定一个单词列表 words 和一个整数 k &#xff0c;返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率&#xff0c; 按字典顺序 排序。 示例 1&#xff1a; 输入: words [“i”, “love”, “leetcode”, “i”, “l…

Flask 项目自动生成 API 文档的高效实践

Flasgger&#xff0c;作为一款强大的 Flask 扩展&#xff0c;自动从 Flask 应用中提取并生成 OpenAPI 规范文档&#xff0c;配备 SwaggerUI&#xff0c;为开发者提供了一条快捷通道&#xff0c;让 API 的文档编制和交互式测试变得简单易行。Flasgger 的设计原则是简化开发流程&…

【已解决】c++ qt选中该行为什么该列部分变色

笔者开启了QTableView中交替行改变颜色&#xff0c;发现笔者自定义绘制的水平滚动条&#xff0c;在选中后不发生颜色改变&#xff0c;这让笔者很疑惑。笔者查阅资料后发现&#xff0c;自定义绘制的控件&#xff0c;要自身设置颜色。当笔者解决了这个问题时&#xff0c;顺手就将…

flutter 操作mysql

引入模块 dependencies: flutter: sdk: flutter mysql1: ^0.20.0 mysql helper 的代码 import dart:async; import package:mysql1/mysql1.dart; class MySqlHelper { static const _host localhost; static const _port 3333; static const _user user; static c…

6.0 MapReduce 服务使用教程

在学习了之前的 MapReduce 概念之后&#xff0c;我们应该已经知道什么是 Map 和 Reduce&#xff0c;并了解了他们的工作方式。 本章将学习如何使用 MapReduce。 Word Count Word Count 就是"词语统计"&#xff0c;这是 MapReduce 工作程序中最经典的一种。它的主要…

PyTorch中的nn.Embedding的使用、参数及案例

PyTorch中的nn.Embedding的使用 Embedding层在神经网络中主要起到降维或升维的作用。具体来说&#xff0c;它通过将输入&#xff08;通常是离散的、不连续的数据&#xff0c;如单词或类别&#xff09;映射到连续的向量空间&#xff0c;从而实现数据的降维或升维。 在降维方面&…

【SAR成像】基于RD、CS和ωk算法的合成孔径雷达成像算法原理与实现

基于RD、CS和ωk算法的合成孔径雷达成像算法实现 前言SAR基本概念雷达获取数据的几何关系低斜视角下的回波信号模型 RADARSAT-1主要参数数据预处理数据读取与再封装数据补零 成像算法坐标轴的产生RD算法距离压缩距离徙动矫正方位压缩 CS算法第一次相位相乘 变标后的信号第二次相…