PostGIS笔记(下)

上篇说了为什么用Geography,这篇具体讲怎么取“范围n米以内的数据”。

Rails里运行Migration,建Portal Model,以下是Schema

距离东京站1km内所有的portals

  • ST_Distance

    float ST_Distance(geography gg1, geography gg2, boolean use_spheroid);

  • ST_DWithin

    boolean ST_DWithin(geography gg1, geography gg2, double precision distance_meters, boolean use_spheroid);

结果:

虽然只运行了一条语句,但是两条语句的运行速度不同是完全可以直观感受出来的。
ST_DWithinST_Distance 快很多。
这里的结果并没有根据距离远近排序,只是一个单纯的结果。

接下来我们继续用 ST_Distance 来取按距离排序的portals

距离东京站1km内的所有portals(按近远距排序)

排序后结果

顺便,速度很快。

大家可能注意到了,不管是 ST_Distance 还是 ST_DWithin 的最后都有个参数 use_spheroid,默认是 false
根据文档,设置为 true 的时候计算速度会变慢。
之前说过 Geography 是球面坐标系,那 Spheroid 是什么呢,是回转椭圆球体,地球本来的形状。
会慢多少我没试过,这次需求也没有要求那么精确,顺便即便为 true 算出来的距离好像也是一样的。

Model Scope

接下来就是把查询语句写到model里可以方便查询就ok了。

以上,Controller 里就能用 Portal.nearby_in_distance(139.767052, 35.681167) 来取所有距离东京站1km以内所有portals的记录了。

注意事项

顺便这里说一下,Google Maps 的查询结果返回的是 {lat, lon},PostGIS要求的参数是 (lon lat) ,不要写反了。

如果用ActiveAdmin作为管理界面的,:lonlat 的显示是字符串 POINT(139.767052 35.681167)
但是编辑的时候会报错,具体错误不记得了,反正是说没有这个input类型。
因为 :lonlat 的类型是 geography
解决方法是自己创建新的 Formtastic input ,方法见 Github

inputs/geography_input.rb 里的代码:

就可以编辑Geography类型的Column了。

总结

最后Production环境就用了一台db.t2.micro的RDS,放了Staging和Production环境两个数据库。
压测结果出乎意料的速度很快,相当满意,虽然写压测脚步花了好长时间。
(因为要随机出日本国内一个坐标,而且这个随机坐标要包含在数据密集的地方,最后看地图取四个顶点坐标花了很久)

这次项目Backend/Server只有我一个人,Leader帮我CR,但是最满意却不是Backend这块,而是前端这块。
除了这个游戏 App Backend/Server ,还一个人开发了一个用Vuex的坐标数据可视化的地图工具,
用来管理Portal坐标,比如给主坐标添加subMarker,拖拽编辑、删除、无效化数据等等。
另外还做了一个基于 Redux 的海报生成工具,写了Print专用CSS。
这两个系统产品设计(?)/设计/前后端/server都是自己一个人做的,相当自由,不过都是给客户用的,所以没有公开过。
还记得 Leader 看我在那里用Photoshop给GoogleMaps做Marker图标的时候那(;´∀`)的表情www
总之很开心,2个月的时间里从0开始学PostgreSQL/PostGIS/Vue.js/Redux,有种无与伦比充实感。

在这次开发过程中发现了RubyChina的强大之处,这之后搜东西除了Stackoverflow之外又多了一个选项。

当然这blog也不是白写的,之后要翻译成日文放到公司技术博客上,被逼的……这也是写这blog的初衷。
但是写都写了,就好好记录一下这两个月的成果,当然因为业务原因换掉了很多词汇,删了很多字段不能写在博客里,也是leader要求的。
App六月份就要下线了,下线后估计就可以公开两个内部系统的截图了。

最后吐槽一下,
本来leader说可以写中文放技术博客上的,但是我和他说因为有墙放中文博客也没有多少人能搜到这里来,然后他就让我翻译成日文算了。
我们小组的美国人好像写了一篇英文的给了leader,但leader和我说肯定是英文的所以他拖到现在还没审阅。
那最初干嘛让我写中文的呢……你又看不懂……心好累……_(:3 」∠ )_

最后的最后,感谢看过的朋友们,感谢看完的朋友们。