当前位置: 首页 > news >正文

重庆移动网站制作绍兴公司网站建设 中企动力绍兴

重庆移动网站制作,绍兴公司网站建设 中企动力绍兴,怎么做刷会员的网站,wordpress并排显示图片产品经理说他有一个 idea#xff0c;为广大少男少女提供一个连接彼此的机会。 让处于这最美的年龄的少男少女能在每一个十二时辰里能邂逅到那个 Ta。 所以就想开发一款 App#xff0c;用户登陆后能发现附近的那个 Ta#xff0c;连接彼此。 我该如何实现发现附近的人#xf… 产品经理说他有一个 idea为广大少男少女提供一个连接彼此的机会。 让处于这最美的年龄的少男少女能在每一个十二时辰里能邂逅到那个 Ta。 所以就想开发一款 App用户登陆后能发现附近的那个 Ta连接彼此。 我该如何实现发现附近的人我也希望通过这个 App邂逅女神…… 记忆中一个下班的夜晚她从人群中轻盈的移动着那高挑苗条的身材像漂浮在空间中的一个飘逸的音符。她的眼睛充满清澈的阳光和活力她的双眸中印着银河系的星光。 开篇寄语 “ 多锻炼自己的表达能力特别是在工作中。很多人说「干活的不如那些做 PPT 的」实际上老板都不傻为何他们会更认可那些做 PPT 的 因为他们从老板的角度考虑问题对他而言需要的是一个「解决方案」。多从一个创造者的视角去考虑问题而不是局限在用程序员的视角考虑问题 多想一下这个东西到底给人提供什么价值而不是「我要怎么实现它」。当然怎么实现是必须的但通常不是最重要的。 ” 什么是面向 LBS 应用 经纬度是经度与纬度的合称组成一个坐标系统。又称为地理坐标系统它是一种利用三度空间的球面来定义地球上的空间的球面坐标系统能够标示地球上的任何一个位置小数点后7位精度可以到1厘米。 经度的范围在 (-180, 180]纬度的范围 在(-90, 90]纬度正负以赤道为界北正南负经度正负以本初子午线 (英国格林尼治天文台) 为界东正西负。 附近的人 也就是常说的 LBS (Location Based Services基于位置服务)它围绕用户当前地理位置数据而展开的服务为用户提供精准的邂逅服务。 附近的人核心思想如下 以 “我” 为中心搜索附近的 Ta以 “我” 当前的地理位置为准计算出别人和 “我” 之间的距离按 “我” 与别人距离的远近排序筛选出离我最近的用户。 MySQL 实现 “ 计算「附近的人」通过一个坐标计算这个坐标附近的其他数据按照距离排序如何下手呢 ” 以用户为中心给定一个 1000 米作为半径画圆那么圆形区域内的用户就是我们想要邂逅的「附近的人」。 将经纬度存储到 MySQL CREATE TABLE nearby_user (id int(11) NOT NULL AUTO_INCREMENT,name varchar(255) DEFAULT NULL COMMENT 名称,longitude double DEFAULT NULL COMMENT 经度,latitude double DEFAULT NULL COMMENT 纬度,create_time datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT 创建时间,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; “ 可是总不能遍历所有的「女神」经纬度与自己的经纬度数据计算在根据距离排序这个计算量也太大了。 ” 我们可以通过区域来过滤出有限「女神」坐标数据再对矩形区域内的数据进行全量距离计算再排序这样计算量明显降低。 “ 如何划分矩形区域呢 ” 在圆形外套上一个正方形根据用户经、纬度的最大最小值经、纬度 距离作为筛选条件过滤数据就很容易将正方形内的「女神」信息搜索出来。 “ 多出来的一些区域咋办 ” 多出来的这部分区域内的用户到圆点的距离一定比圆的半径要大那么我们就计算用户中心点与正方形内所有用户的距离筛选出所有距离小于等于半径的用户圆形区域内的所用户即符合要求的附近的人。 为了满足高性能的矩形区域算法数据表需要在经纬度坐标加上复合索引 (longitude, latitude)这样可以最大优化查询性能。 实战 根据经纬度和距离获取外接矩形最大、最小经纬度以及根据经纬度计算距离使用了一个第三方类库 dependencygroupIdcom.spatial4j/groupIdartifactIdspatial4j/artifactIdversion0.5/version /dependency 获取到外接矩形后以矩形的最大最小经、纬度值搜索正方形区域内的用户再剔除超过指定距离的用户就是最终的附近的人。 /*** 获取附近 x 米的人** param distance 搜索距离范围 单位km* param userLng  当前用户的经度* param userLat  当前用户的纬度*/ public String nearBySearch(double distance, double userLng, double userLat) {//1.获取外接正方形Rectangle rectangle  getRectangle(distance, userLng, userLat);//2.获取位置在正方形内的所有用户ListUser users  userMapper.selectUser(rectangle.getMinX(), rectangle.getMaxX(), rectangle.getMinY(), rectangle.getMaxY());//3.剔除半径超过指定距离的多余用户users  users.stream().filter(a - getDistance(a.getLongitude(), a.getLatitude(), userLng, userLat)  distance).collect(Collectors.toList());return JSON.toJSONString(users); }// 获取外接矩形 private Rectangle getRectangle(double distance, double userLng, double userLat) {return spatialContext.getDistCalc().calcBoxByDistFromPt(spatialContext.makePoint(userLng, userLat), distance * DistanceUtils.KM_TO_DEG, spatialContext, null); }/**** 球面中两点间的距离* param longitude 经度1* param latitude  纬度1* param userLng   经度2* param userLat   纬度2* return 返回距离单位km*/private double getDistance(Double longitude, Double latitude, double userLng, double userLat) {return spatialContext.calcDistance(spatialContext.makePoint(userLng, userLat),spatialContext.makePoint(longitude, latitude)) * DistanceUtils.DEG_TO_KM;} 由于用户间距离的排序是在业务代码中实现的可以看到SQL语句也非常的简单。 SELECT * FROM nearby_user WHERE 11 AND (longitude BETWEEN #{minlng} AND #{maxlng}) AND (latitude BETWEEN #{minlat} AND #{maxlat}) 但是数据库查询性能毕竟有限如果「附近的人」查询请求非常多在高并发场合这可能并不是一个很好的方案。 尝试 Redis Hash 未果 我们一起分析下 LBS 数据的特点 每个「女神」都有一个 ID 编号每个ID 对应着经纬度信息。「宅男」登陆 app获取「心动女生」的时候app根据「宅男」的经纬度查找附近的「女神」。获取到位置符合的「女神」ID 列表后再从数据库获取 ID 对应的「女神」信息返回用户。 “ 数据特点就是一个女神用户对应着一组经纬度让我想到了 Redis 的 Hash 结构。也就是一个 key女神 ID 对应着 一个 value经纬度。 ” Hash看起来好像可以实现但是 LBS 应用除了记录经纬度以外还需要对 Hash 集合中的数据进行范围查询根据经纬度换算成距离排序。 而 Hash 集合的数据是无序的显然不可取。 Sorted Set 初见端倪 “ Sorted Set 类型是是否合适呢因为它可以排序。 ” Sorted Set 类型也是一个 key对应一个 valuekey元素内容而value 就是该元素的权重分数。 Sorted Set可以根据元素的权重分数对元素排序这样看起来就满足我们的需求了。 比如Sorted Set 的元素是「女神ID」元素对应的权重 score 是经纬度信息。 “ 问题来了Sorted Set 元素的权重值是一个浮点数经纬度是经度、纬度两个值咋办呢能不能将经纬度转换成一个浮点数呢 ” 思路对了为了实现对经纬度比较Redis 采用业界广泛使用的 GeoHash 编码分别对经度和纬度编码最后再把经纬度各自的编码组合成一个最终编码。 这样就实现了将经纬度转换成一个值而 Redis 的 GEO 类型的底层数据结构用的就是 Sorted Set来实现。 我们来看下 GeoHash 如何将经纬度编码的。 GEOHash 编码 “ 关于 GeoHash 可参考 https://en.wikipedia.org/wiki/Geohash ” GeoHash算法将二维的经纬度数据映射到一维的整数这样所有的元素都将在挂载到一条线上距离靠近的二维坐标映射到一维后的点之间距离也会很接近。 当我们想要计算「附近的人时」首先将目标位置映射到这条线上然后在这个一维的线上获取附近的点就行了。 GeoHash 编码会把一个经度值编码成一个 N 位的二进制值我们来对经度范围[-180,180]做 N 次的二分区操作其中 N 可以自定义。 在进行第一次二分区时经度范围[-180,180]会被分成两个子区间[-180,0) 和[0,180]我称之为左、右分区。 此时我们可以查看一下要编码的经度值落在了左分区还是右分区。如果是落在左分区我们就用 0 表示如果落在右分区就用 1 表示。 这样一来每做完一次二分区我们就可以得到 1 位编码值不是0 就是 1。 再对经度值所属的分区再做一次二分区同时再次查看经度值落在了二分区后的左分区还是右分区按照刚才的规则再做 1 位编码。当做完 N 次的二分区后经度值就可以用一个 N bit 的数来表示了。 所有的地图元素坐标都将放置于唯一的方格中。方格越小坐标越精确。然后对这些方格进行整数编码越是靠近的方格编码越是接近。 编码之后每个地图元素的坐标都将变成一个整数通过这个整数可以还原出元素的坐标整数越长还原出来的坐标值的损失程度就越小。对于「附近的人」这个功能而言损失的一点精确度可以忽略不计。 比如对经度值等于 169.99 进行 4 位编码N 4做 4 次分区,把经度区间[-180,180]分成了左分区[-180,0) 和右分区[0,180]。 169.99 属于右分区使用 1 表示第一次分区编码再将 169.99 经过第一次划分所属的 [0, 180] 区间继续分成 [0, 90) 和 [90, 180]169.99 依然在右区间编码 ‘1’。将[90, 180] 分为[90, 135) 和 [135, 180]这次落在左分区编码 ‘0’。 如此最后我们就得到一个 4 位的编码。 而纬度的编码思路跟经度也是一样的不再赘述。 合并经纬度编码 假如计算的经纬度编码分别是 11011 和00101目标编码第 0 位则从经度第 0 位的值 1 作为目标值目标编码的第 1 位则从纬度第 0 位值 0 作为目标值以此类推 就这样经纬度35.679114.020就可以使用 1010011011 表示而这个值就可以作为 SortedSet 的权重值实现排序。 Redis GEO 实现 “ GEO 类型是将经纬度的经过 GeoHash 编码的合并值作为 Sorted Set 元素的 score 权重Redis 的 GEO 有哪些指令呢 ” 我们需要把登陆 app 的女生 ID 和对应的经纬度存到 Sorted Set 里面。 更多 GEO 类型指令可参考https://redis.io/commands#geo GEOADD Redis 提供了 GEOADD key longitude latitude member 命令将一组经纬度信息和对应的「女神 ID」记录到 GEO 类型的集合中如下一次记录多个用户苍井空、波多野结衣的经纬度信息。 GEOADD girl:localtion 13.361389 38.115556 苍井空 15.087269 37.502669 波多野结衣 GEORADIUS “ 我登陆了 app获取自己的经纬度信息如何查找以这个经纬度为中心的一定范围内的其他用用户呢 ” Redis GEO类型提供了 GEORADIUS指令会根据输入的经纬度位置查找以这个经纬度为中心的一定范围内的其他元素。 假设自己的经纬度是15.087269 37.502669需要获取附近 10 km 的「女神」并返回给 LBS 应用 GEORADIUS girl:locations 15.087269 37.502669 km ASC COUNT 10 ASC可以实现让「女神」信息按照这个距离自己的经纬度由近到远排序。 COUNT选项表示指定返回的「女神」数量防止附近太多「女神」节省带宽资源。 如果觉得自己需要更多女神那么可以无限制但是需要注意身体多吃鸡蛋补一补。 “ 用户下线后如删除下线的「女神」经纬度呢 ” 这个问题问得好GEO 类型是基于 Sorted Set 实现的所以可以借用 ZREM 命令实现对地理位置信息的删除。 比如删除「苍井空」的位置信息 ZREM girl:localtion 苍井空 小结 GEO 本身并没有设计新的底层数据结构而是直接使用了 Sorted Set 集合类型。 GEO 类型使用 GeoHash 编码方法实现了经纬度到 Sorted Set 中元素权重分数的转换这其中的两个关键机制就是对二维地图做区间划分以及对区间进行编码。 一组经纬度落在某个区间后就用区间的编码值来表示并把编码值作为 Sorted Set 元素的权重分数。 在一个地图应用中车的数据、餐馆的数据、人的数据可能会有百万千万条如果使用 Redis 的 Geo 数据结构它们将全部放在一个 zset 集合中。 在 Redis 的集群环境中集合可能会从一个节点迁移到另一个节点如果单个 key 的数据过大会对集群的迁移工作造成较大的影响在集群环境中单个 key 对应的数据量不宜超过 1M否则会导致集群迁移出现卡顿现象影响线上服务的正常运行。 所以这里建议 Geo 的数据使用单独的 Redis 集群实例部署。 如果数据量过亿甚至更大就需要对 Geo 数据进行拆分按国家拆分、按省拆分按市拆分在人口特大城市甚至可以按区拆分。 这样就可以显著降低单个 zset 集合的大小。 巨人肩膀 https://segmentfault.com/a/1190000022734787https://juejin.cn/book/6844733724618129422/section/6844733724710404103https://cloud.tencent.com/developer/article/1393498Redis 核心技术与实战 点个在看女神就来
http://www.dnsts.com.cn/news/25597.html

相关文章:

  • 重庆网站建设技术支持海南建设培训与执业中心网站
  • 用h5开发的网站模板下载创造网站
  • 做网投网站广告行业网站建设方案
  • 网站图片处理方案北京免费发布企业信息网站
  • 花瓣设计网站官网入口智慧团建如何在手机上登录
  • 在建设主题网站时宝应县建设工程管理局网站
  • 网站搭建后台wordpress5.0文章编辑器
  • 程序员 给老婆做网站wordpress插件video player
  • 创业网站怎么做的宁波市建设局官网
  • 工厂的网站在哪里做的win7 iis架设网站
  • 做采集网站赚钱seo优化是什么职位
  • 一流的微商城网站建设wordpress相册管理系统
  • 空调网站模板seo站内优化教程
  • 2012r2做网站代理服务器免费网页版
  • 重庆地产网站建设杭州做网站比较出名的公司
  • 门户网站建设必要性免费行情软件下载
  • 外贸soho网站建设教你免费申请个人网站
  • 国家建设部网站证书查询南山免费做网站公司排名
  • 网站运营计划郴州网站建设推广公司
  • 锦州哪里做网站没有域名能做网站吗
  • 网站统计代码自己做网站实时监控
  • 做网站多久标书制作公司
  • 广东圆心科技网站开发需要多少钱wordpress门户网站
  • 凤翔网站建设wordpress是开源
  • 哪个网站好灵台县住房和城乡建设局网站
  • 做网商哪个国外网站好赣州做网站j
  • 苏州市建设局招标网站网站开发公司怎么查
  • 网站建设与管理办法地方文明网站建设
  • 西部数码网站管理助手使用教程湖南系统建站怎么用
  • 合肥网站设计建自己如何建设网站步骤