geohash

一口气说出 4种 LBS “附近的人” 实现方式,面试官笑了

别来无恙 提交于 2020-04-23 13:08:38
原文: 一口气说出 4种 LBS “附近的人” 实现方式,面试官笑了 进技术交流群,加VX:xinzhifu521 引言 昨天一位公众号粉丝和我讨论了一道面试题,个人觉得比较有意义,这里整理了一下分享给大家,愿小伙伴们面试路上少踩坑。面试题目比较简单:“让你实现一个附近的人功能,你有什么方案?”,这道题其实主要还是考察大家对于技术的广度,本文介绍几种方案,给大家一点思路,避免在面试过程中语塞而影响面试结果,如有不严谨之处,还望亲人们温柔指正! “附近的人” 功能生活中是比较常用的,像外卖app附近的餐厅,共享单车app里附近的车辆。既然常用面试被问的概率就很大,所以下边依次来分析基于 mysql数据库 、 Redis 、 MongoDB 实现的 “附近的人” 功能。 科普 :世界上标识一个位置,通用的做法就使用经、纬度。经度的范围在 (-180, 180],纬度的范围 在(-90, 90],纬度正负以赤道为界,北正南负,经度正负以本初子午线 (英国格林尼治天文台) 为界,东正西负。比如:望京摩托罗拉大厦的经、纬度(116.49141,40.01229)全是正数,就是因为我国位于东北半球。 一、“附近的人”原理 “附近的人” 也就是常说的 LBS (Location Based Services,基于位置服务),它围绕用户当前地理位置数据而展开的服务,为用户提供精准的增值服务。

一口气说出 4种 LBS “附近的人” 实现方式,面试官笑了

倾然丶 夕夏残阳落幕 提交于 2020-04-17 00:56:59
【推荐阅读】微服务还能火多久?>>> 引言 昨天一位公众号粉丝和我讨论了一道面试题,个人觉得比较有意义,这里整理了一下分享给大家,愿小伙伴们面试路上少踩坑。面试题目比较简单:“让你实现一个附近的人功能,你有什么方案?”,这道题其实主要还是考察大家对于技术的广度,本文介绍几种方案,给大家一点思路,避免在面试过程中语塞而影响面试结果,如有不严谨之处,还望亲人们温柔指正! “附近的人” 功能生活中是比较常用的,像外卖app附近的餐厅,共享单车app里附近的车辆。既然常用面试被问的概率就很大,所以下边依次来分析基于 mysql数据库 、 Redis 、 MongoDB 实现的 “附近的人” 功能。 科普 :世界上标识一个位置,通用的做法就使用经、纬度。经度的范围在 (-180, 180],纬度的范围 在(-90, 90],纬度正负以赤道为界,北正南负,经度正负以本初子午线 (英国格林尼治天文台) 为界,东正西负。比如:望京摩托罗拉大厦的经、纬度(116.49141,40.01229)全是正数,就是因为我国位于东北半球。 一、“附近的人”原理 “附近的人” 也就是常说的 LBS (Location Based Services,基于位置服务),它围绕用户当前地理位置数据而展开的服务,为用户提供精准的增值服务。 “附近的人” 核心思想如下: 以 “我” 为中心,搜索附近的用户 以 “我”

一口气说出 4种 LBS “附近的人” 实现方式,面试官笑了

本小妞迷上赌 提交于 2020-04-17 00:31:21
【推荐阅读】微服务还能火多久?>>> 引言 昨天一位公众号粉丝和我讨论了一道面试题,个人觉得比较有意义,这里整理了一下分享给大家,愿小伙伴们面试路上少踩坑。面试题目比较简单:“让你实现一个附近的人功能,你有什么方案?”,这道题其实主要还是考察大家对于技术的广度,本文介绍几种方案,给大家一点思路,避免在面试过程中语塞而影响面试结果,如有不严谨之处,还望亲人们温柔指正! “附近的人” 功能生活中是比较常用的,像外卖app附近的餐厅,共享单车app里附近的车辆。既然常用面试被问的概率就很大,所以下边依次来分析基于 mysql数据库 、 Redis 、 MongoDB 实现的 “附近的人” 功能。 科普 :世界上标识一个位置,通用的做法就使用经、纬度。经度的范围在 (-180, 180],纬度的范围 在(-90, 90],纬度正负以赤道为界,北正南负,经度正负以本初子午线 (英国格林尼治天文台) 为界,东正西负。比如:望京摩托罗拉大厦的经、纬度(116.49141,40.01229)全是正数,就是因为我国位于东北半球。 一、“附近的人”原理 “附近的人” 也就是常说的 LBS (Location Based Services,基于位置服务),它围绕用户当前地理位置数据而展开的服务,为用户提供精准的增值服务。 “附近的人” 核心思想如下: 以 “我” 为中心,搜索附近的用户 以 “我”

空间索引 - 四叉树

 ̄綄美尐妖づ 提交于 2020-03-22 11:39:10
/*--> */ /*--> */ /*--> */ /*--> */ /*--> */ /*--> */ 前言 作为程序员,应该都对二叉树都不陌生,我们都知道二叉树的变体二叉查找树,非常适合用来进行对一维数列的存储和查找,可以达到 O(logn) 的效率;我们在用二叉查找树进行插入数据时,根据一个数据的值和树结点值的对比,选择二叉树的两个叉之一向下,直到叶子结点,查找时使用二分法也可以迅速找到需要的数据。 但二叉树只支持一维数据,如一个标量数值,对地图上的位置点这种有xy两个方向上的信息却无能为力,那么是否有一种树能够支持二维数据的快速查询呢? 四叉树 介绍 四元树又称四叉树是一种树状数据结构,在每一个节点上会有四个子区块。四元树常应用于二维空间数据的分析与分类。它将数据区分成为四个象限。 今天要介绍的四叉树可以认为是二叉查找树的高维变体,它适合对有二维属性的数据进行存储和查询,当然四叉树存储的也不一定是二维数据,而是有着二维属性的数据,如有着 x,y 信息的点,用它还可以用来存储线和面数据。它有四个 叉 ,在数据插入时,我们通过其二维属性(一般是 x,y)选择四个叉之一继续向下,直至叶子结点,同样使用“四分法”来迅速查找数据。四叉树的一般图形结构如下: 聪明的小伙伴一定想到了适合存储和查询三维数据的八叉树,它们原理是一致的,不过我们暂不讨论。 分类 四叉树常见的应用有图像处理

Redis(6)——GeoHash查找附近的人

人盡茶涼 提交于 2020-03-12 08:34:55
像微信 "附近的人" ,美团 "附近的餐厅" ,支付宝共享单车 "附近的车" 是怎么设计实现的呢? 一、使用数据库实现查找附近的人 我们都知道,地球上的任何一个位置都可以使用二维的 经纬度 来表示,经度范围 [-180, 180] ,纬度范围 [-90, 90] ,纬度正负以赤道为界,北正南负,经度正负以本初子午线 (英国格林尼治天文台) 为界,东正西负。比如说,北京人民英雄纪念碑的经纬度坐标就是 (39.904610, 116.397724) ,都是正数,因为中国位于东北半球。 所以,当我们使用数据库存储了所有人的 经纬度 信息之后,我们就可以基于当前的坐标节点,来划分出一个矩形的范围,来得知附近的人,如下图: 所以,我们很容易写出下列的伪 SQL 语句: SELECT id FROM positions WHERE x0 - r < x < x0 + r AND y0 - r < y < y0 + r 如果我们还想进一步地知道与每个坐标元素的距离并排序的话,就需要一定的计算。 当两个坐标元素的距离不是很远的时候,我们就可以简单利用 勾股定理 就能够得出他们之间的 距离 。不过需要注意的是,地球不是一个标准的球体, 经纬度的密度 是 不一样 的,所以我们使用勾股定理计算平方之后再求和时,需要按照一定的系数 加权 再进行求和。当然,如果不准求精确的话,加权也不必了。 参考下方

Geohash原理及精度

情到浓时终转凉″ 提交于 2020-03-10 14:59:12
Geohash原理及精度 Geohash原理:参见 https://www.jianshu.com/p/1ecf03293b9a Geohash精度:参见 https://blog.csdn.net/xxxx000/article/details/92771460 来源: CSDN 作者: -Y-Q-Q- 链接: https://blog.csdn.net/Yqq19950707/article/details/104770112

Redis geohash 地理位置存储

依然范特西╮ 提交于 2020-02-26 05:38:20
Redis 的 GEO 特性将在 Redis 3.2 版本释出, 这个功能可以将用户给定的地理位置信息储存起来, 并对这些信息进行操作。 本文将对 Redis 的 GEO 特性进行介绍, 说明这个特性相关命令的用户, 并在最后说明如何使用这些命令去实现“查找附近的人”以及“摇一摇”这两个功能。 版本要求 因为 Redis 目前的稳定版本为 Redis 3.0 , 而 GEO 特性是 Redis 3.2 版本的特性, 所以如果你想要使用这个特性的话, 那么就需要到 Redis 的 GitHub 页面 去克隆 unstable 分支 然后编译 unstable 版本的 Redis 源码, 这样才能用到 Redis GEO 特性。 添加位置和获取位置 为了进行地理位置相关操作, 我们首先需要将具体的地理位置记录起来, 这一点可以通过执行 GEOADD 命令来完成, 该命令的基本格式如下: 1 GEOADD location- set longitude latitude name [longitude latitude name ...] GEOADD 命令每次可以添加一个或多个经纬度地理位置。 其中 location-set 为储存地理位置的集合, 而 longitude 、 latitude 和 name 则分别为地理位置的经度、纬度、名字。 举个例子, 以下代码展示了如何通过

MySQL里的经纬度转为Geohash后插回数据库

帅比萌擦擦* 提交于 2020-01-17 01:34:13
MySQL里的经纬度转为Geohash后插回数据库 from pygeohash import encode , decode import plotly import plotly . plotly as pyf import plotly . graph_objs as go import numpy as np import pandas as pd import math from matplotlib . path import Path import numpy as np import plotly . offline as of import plotly . graph_objs as go import plotly . plotly as py import numpy as np import pandas as pd import folium import webbrowser from folium . plugins import HeatMap import datetime import time import pymysql . cursors import decimal import geohash def geohashsql ( geohash ) : conn = pymysql . connect ( host =

GeoHash算法附近寻址

老子叫甜甜 提交于 2020-01-13 03:28:31
原文出处: zhanlijun 引子 机机是个好动又好学的孩子,平日里就喜欢拿着手机地图点点按按来查询一些好玩的东西。某一天机机到北海公园游玩,肚肚饿了,于是乎打开手机地图,搜索北海公园附近的餐馆,并选了其中一家用餐。 饭饱之后机机开始反思了,地图后台如何根据自己所在位置查询来查询附近餐馆的呢?苦思冥想了半天,机机想出了个方法:计算所在位置P与北京所有餐馆的距离,然后返回距离<=1000米的餐馆。小得意了一会儿,机机发现北京的餐馆何其多啊,这样计算不得了,于是想了,既然知道经纬度了,那它应该知道自己在西城区,那应该计算所在位置P与西城区所有餐馆的距离啊,机机运用了递归的思想,想到了西城区也很多餐馆啊,应该计算所在位置P与所在街道所有餐馆的距离,这样计算量又小了,效率也提升了。 机机的计算思想很朴素,就是通过过滤的方法来减小参与计算的餐馆数目,从某种角度上讲,机机在使用索引技术。 一提到索引,大家脑子里马上浮现出B树索引,因为大量的数据库(如MySQL、oracle、PostgreSQL等)都在使用B树。B树索引本质上是对索引字段进行排序,然后通过类似二分查找的方法进行快速查找,即它要求索引的字段是可排序的,一般而言,可排序的是一维字段,比如时间、年龄、薪水等等。但是对于空间上的一个点(二维,包括经度和纬度),如何排序呢?又如何索引呢?解决的方法很多,下文介绍一种方法来解决这一问题。

Geohash 算法学习

你离开我真会死。 提交于 2020-01-13 03:28:10
Geohash 算法: 这是一套纬度/经度地理编码算法,把纬度/经度编码成base32位的字符串。这种编码和纬度/经度不是唯一对应,其实是一个纬度/经度区间。算法有一个精度概念,精度越高,字符串越长,所表示的区间越小。可以编码后的字符串想象成一个格子,里面存放一些纬度/经度值。格子趋近很小的时候,只能存放一纬度/经度值,那么编码和纬度/经度就是唯一对应的关系。但是这个不是重点,这套算法目的就是把纬度/经度编码成近似值,通过近似值搜索,就能很高效的缩小范围,然后再从小范围里查找精确值。 例如,坐标57.64911,10.40744(日德兰半岛的顶端附近,在丹麦)产生一个u4pruydqqvj字符串。参考Wikipedia: http://en.wikipedia.org/wiki/Geohash 算法原理: 以A[-170,42.6] 为例,纬度范围(-90, 90)平分成两个区间(-90, 0)、(0, 90),位于前一个区间,则编码为0,否则编码为1。由于42.6属于(0, 90),所以取编码为1。 再将(0, 90)分成 (0, 45), (45, 90)两个区间,而42.6位于(0, 45),所以编码为0, 再将(0, 45)分成 (0, 22.5), (22.5, 45)两个区间,而42.6位于(22.5, 45),所以编码为1, 再将(22.5, 45)分成 (22.5,