[转载]结合地理位置信息的搜索服务

2019-03-27 01:08|来源: 网路

转载声明:http://backend.blog.163.com/blog/static/202294126201282403425572/

介绍

 

随着越来越多和地理位置相关的应用和产品的出现,尤其是在移动类应用中,能有效地结合地理位置信息进行相关信息的搜索显得越来越重要。

一个典型的应用场景:滨江网商路附近的餐馆,基于口碑和距离远近综合排序,:)

基于现有的搜索系统,对地理位置信息进行针对性的索引和查询处理,可以提供准确和高效的结果地理位置信息的搜索查询服务。

本文会简单介绍结果地理位置信息进行搜索涉及的一些技术点和可用方案。

 

 

索引

 

1. 介绍

2. 实现分析

3. 地理信息抽取和解析

4. 基于地理信息查询和过滤

    4.1 基于经纬度

    4.2 分层模型

    4.3 Geohash

5. 距离计算

6. 开源方案

7. 参考

 

 

实现分析

 

结合地理位置信息的搜索应用,其过程可以分为以下几个方面:

* 数据处理与索引:从原始数据信息中提取地理位置信息,转化为结构化的地理信息数据,进行索引

* 查询解析:解析查询中的地理信息查询条件(中心点,范围),结合其它查询条件(关键词,排序条件),构造组合结构化查询

* 查询结果匹配:同时匹配地理信息查询条件和其它搜索条件

* 查询结果过滤:基于地理信息条件进一步过滤掉不在地理范围内的结果

* 查询结果距离计算:为每一结果计算到中心点的距离

* 查询结果排序:把计算出的距离作为排序因素和权重之一,与其它排序因素综合在一起,共同决定最终的结果排序

 

以上几个方面中,地理数据抽取/查询解析、查询结果基于地理信息过滤、查询结果距离计算,都是地理信息搜索中特有的,区别于一般搜索的,需要关注的地方。

 

 

地理信息抽取和解析

 

原始数据中包含的地理位置信息,通常以多种形式存在:

1. 直接带有精准的经纬数据(比如:东经30.274089,北纬120.155069)

2. 带有相对比较准确的地理名称(比如:六合塔,萧山机场,望湖宾馆)

3. 带有比较模糊的描述性地理信息(比如:西湖以北2公里)

 

其中:

1.是可以直接使用和索引的地理数据;

2.可以进行文本地标索引;同时也可以转换成准确的经纬度数据

3.一般比较难进行准确的识别和处理,有时通过一些第三方服务,比如说Google Maps API等,可以把部分数据也转换成相应的经纬度数据

 

查询时,地理位置条件也存在有多种形式:

1. 通过GPS定位,直接给出经纬度

2. 通过在地图上标注,给出经纬度

3. 通过相对准确的地理名称,可转换成较准确的地理位置信息(通过查询本地地理数据表,或调用第三方地理位置信息查询服务)

 

 

基于地理信息查询和过滤

 

这应该是地理位置搜索的关键点,常用的方案有:

1. 基于经纬度直接进行过滤

2. 基于分层网格模形进行过滤

3. 基于Geohash进行过滤

 

基于经纬度

结合地理位置信息的查询,最直接的方式,即直接使用原始经纬度信息。

在索引时,对原始经度和纬度数值都建立索引。

查询时,会在进行关键词查询的同时,同时构造经度范围查询,纬度范围查询查询。

查询结果会合并各个查询的结果集,得到符合条件的结果交集。

在此基础上进行距离计算,以及最终排序。

 

这个方法的好处是比较简单直接,不需要在索引时和查询时进行过多额外处理。

 

缺点是,由于经纬度数值非常离散,通常会造成相应的索引非常的大,键值多,值列表极短;

搜索查询的范围查询通常并非一个高效的操作,存在拆分查询和合并结果的操作;

所以这使得基于原始经纬度的查询操作的开销比较大,尤其是在数据量比较大的情况下,查询效率可能存在问题。

 

分层模形

分层模型(笛卡尔层,Cartesian Tier)是一种比较有效的改进方案,将原始经纬度转换成更大粒度的分层网格。

这种模型创建了很多的地理层,分别对应不同的切分粒度;每一层在前一层的基础上细化切分粒度(x2);20层后,切分粒度已非常小;每一格会被分配一个ID,代表一个地理区域。

 

在索引时,具体的经纬度值会被映射为区域ID,基于区域ID创建索引。

查询时,会将地理查询条件映射成对应的区域ID查询。

由于区域的粒度远大小原始经纬度,索引的聚合性会有很大提高,从而查询效率会远高于基于经纬度的索引查询。

 

Geohash

还有一种方案是用一种称为Geohash的编码方式(geohash.org)将二元的经纬度编码成一元的字符串中。

这种编码方式还能为邻近地点产生相同的前缀值,并试图通过相同前缀的长短来近似表达两个地点的相近程度。

 

这种方法的好处是,通过特定编码转换方式,使索引和查询的效率都会比较高。

但地理相近查询的准确度对编码算法的依赖较大,精度不容易控制。

 

 

距离计算

 

计算地理上两点距离的方式有:

1. 基于平面模型,直接计算近似欧几里德距离

2. 基于球形模型,计算圆弧距离

3. 基于地球的椭球模型,计算更精确的距离

4. 基于市内行车路线,计算实际行车距离

 

几种方式依次提高距离计算精度,同时增大计算复杂度。

要注意到距离计算将应用于每一过滤后的候选结果,所以开销过大会对最终查询排序性能有较大影响。

通常会结合实际情况,在精度能满足需求的前提下,选择计算相对简单的方法;比如说2.圆弧距离,通常已能满足大部分应用场景下的需求。

 

 

开源方案

 

比较流行的开源搜索库Lucene在比较新的版本中已经对基于地理位置信息的搜索有了一定的支持:

http://wiki.apache.org/lucene-java/SpatialSearch

 

同时基于Lucene的Solr也对地理信息检索提供了一些相应的支持:

http://wiki.apache.org/solr/SpatialSearch

 

 

参考

 

* Lucene Spatial Search: http://wiki.apache.org/lucene-java/SpatialSearch

* Solr Spatial Search: http://wiki.apache.org/solr/SpatialSearch

* Lucene Geographical Search: http://www.nsshutdown.com/projects/lucene/whitepaper/locallucene_v2.html

* Geohash: http://en.wikipedia.org/wiki/Geohash


转自:http://www.cnblogs.com/lenolix/articles/2707822

相关问答

更多
  • 由于小程序只提供了我们一个获取地理位置、速度的api,并没有获取的相关地位位置的信息等等,因此我们还需要借助一些第三方的api来实现 我们可以使用百度地图的api来获取地位位置的信息。 1>申请地址 http://lbsyun.baidu.com/index.php?title=wxjsapi/guide/key 2> 第二步:下载百度地图的api ,链接:http://download.csdn.net/detail/michael_ouyang/9754015 解压后,里面有2个js文件,一个是常规没压 ...
  • 一个是统计你正在使用它们的软件,统计用户数量,第二就是有针对性的记录你的IMEI号码平时多浏览什么内容,然后可以针对爱好投放广告
  • 为什么不使用$ polygon来制作本质上粗线? collection.find({'loc':{'$within':{'$polygon':[[linestart_x, linestart_y], [linestart_x+jiggle, linestart_y+jiggle], [lineend_x, lineend_y], [lineend_x+jiggle, lineend_y+jiggle]]}}}) 你将不得不尝试找到适当数量的'摇晃'。 请享用! Why not use a $polygon ...
  • 要聚合结果,您可以先将结果收集到结果集合中,然后再将其收集到SelectMany : List responses = new List(); postcodeChunks.ForEach( postcodeList => { try // handle exception for individual call ...
  • 我有类似的问题,但我试图找到与用户位置相比最接近的特色广告,我写了这段代码: $userAddress = GeoLocation::fromDegrees($request->latitude, $request->longitude); $geocode = GeoLocation::getGeocodeFromGoogle($address); $latitude = $geocode->results[0]->geometry->location->lat?:24.55; //Here I was ...
  • 其他正在处理ewntire州/国家的供应商,您可以添加Polygon地理位置.. 如果这有帮助,请检查此链接: https://www.simple-talk.com/sql/t-sql-programming/introduction-to-sql-server-spatial-data/ Other vendor who are handling ewntire state /country, you can add Polygon geolocation.. Check this link out i ...
  • 我想你不会在IP地址地址太近的地方,你可以尝试找到更多的REST服务,比如http://freegeoip.net/ ,你可以使用普通的HTTP GET和IP地址来获取城市命名为回复。 然后,如果您想在地图上显示,您当然可以使用地理编码服务来获取城市的坐标,并向用户显示带有地图的位置。 I suppose you wont be getting too close locations with IP Address address, you could try finding more REST servi ...
  • 由于太阳黑子计算位置类型的方式,您需要做一些额外的腿部工作,以便按距离目标进行排序。 它的工作方式是为每个点创建一个地理哈希,然后使用常规全文搜索对该地理哈希进行搜索。 结果是你可能无法确定10公里以外的点是否比5公里以外的点更远,但是你能够判断50公里以外的点是否比1-2公里以外的点还要远。 。 确切的距离是任意的,但结果是你可能没有像你想要的那样精细的结果,并且搜索更像是一种过滤可接受范围内的点的方法。 使用内置位置搜索过滤积分后,有三种方法可以完成您想要的操作: 升级到Solr 3.1或更高版本并升级 ...
  • 取决于地理位置的类型。 如果您的意思是ip <> country / city [例如www.maxmind.com] - 基本信息可以在网络运营商/ 地区互联网注册管理机构维护的whois记录中找到。 例如: http : //tools.whois.net/whoisbyip/?host = 64.34.119.12 我想可以半自动清理/标准化这些数据。 如果你的意思是mac地址<>地理坐标 - 很可能只是暗中监视用户[经过他们的同意......或者没有] - 从运行在移动设备上的应用程序收集信息,包括 ...
  • 我在评论exif_read_data中提到过。 现在我在我的办公桌上,我可以详细阐述一下。 我创建了一个函数,然后执行此操作: // get geo-data from image function get_image_location($file) { if (is_file($file)) { $info = exif_read_data($file); if ($info !== false) { $direction = array(' ...