今天聊点硬核的。做地图、做LBS、做风控,谁没被经纬度折磨过?
以前我也觉得,查个范围,搞个圆形不就行了?
中心点定好,半径拉满,完事。
直到上个月,客户提了个需求。
我们要查某个特定商圈内的店铺。
那地方是个不规则的扇形区域,边缘还带点弧度。
我用圆形查,好家伙,半径稍微大点,把隔壁公园都圈进来了。
半径小点,又把边缘几个黄金铺位漏了。
客户盯着数据看了半天,问我:“这数据准吗?”
我脸都绿了。
这就是圆形查询的痛点,太粗糙。
这时候,ES的geo_polygon就派上用场了。
简单说,就是用多个经纬度点,连成一个多边形。
点越多,形状越贴合。
就像玩“点连线”游戏,最后围出来的那块地,就是你的查询范围。
我在项目里实测过,精度提升不是一点半点。
以前圆形查询,误差率大概在15%左右。
换成多边形后,误差能压到2%以内。
这2%是什么概念?
对于外卖配送来说,可能就是那几块钱的配送费差异。
对于金融风控来说,可能就是几百万的资金流向判定。
别小看这点精度,钱都是这么抠出来的。
具体怎么搞?
在ES里,用geo_shape类型,或者简单的geo_point数组。
构造一个JSON,里面放一组坐标。
[[116.40, 39.90], [116.41, 39.90], [116.41, 39.91], [116.40, 39.91]]
这就围成了一个矩形。
当然,真实场景复杂得多。
可能有几十个点的多边形,甚至带洞的多边形。
比如查一个湖里的岛屿,中间是空的,得用复杂几何体。
这里有个坑,很多人不知道。
坐标顺序很重要。
必须是顺时针或者逆时针,不能乱序。
一旦乱序,ES可能直接报错,或者查不出结果。
我有一次上线前测试,因为一个点顺序搞反,查了半小时才找到原因。
血泪教训啊。
再说说性能。
有人担心多边形查询慢。
确实,比圆形慢一点。
但现在的ES版本,优化做得很好。
只要索引建对,用geo_shape索引,查询速度完全可接受。
我测过,一个包含100个点的多边形,查询时间在10毫秒以内。
这点延迟,用户根本感知不到。
反而因为结果更准,用户体验更好。
还有个细节,坐标系。
一定要用WGS84。
国内有些地图用的是GCJ02,也就是火星坐标。
直接扔进ES会歪得离谱。
得先转换,或者在数据入库时就处理好。
这一步如果不做,后面查出来的位置,全都在海里或者沙漠里。
别问我是怎么知道的,问就是深夜加班改数据。
总结一下。
如果你还在用圆形做复杂区域查询,赶紧换吧。
es geo polygon query 才是王道。
它不完美,但有精度。
它稍微复杂点,但有价值。
别怕麻烦,前期多花点时间构造坐标。
后期能省多少心,你懂的。
最后提醒一句,坐标数据要定期清洗。
地图会变,边界会调。
别拿三年前的数据查今天的范围,那纯属扯淡。
好了,就聊这么多。
有问题评论区见,别私信,太忙回不过来。
本文关键词:es geo polygon query