Room数据库自定义排序:基于经纬度距离的ORDER BY实现
在Room中按经纬度距离排序(与指定Kotlin函数逻辑一致)
要实现和你提供的Kotlin计算距离函数完全匹配的排序效果,只需将函数中的数学逻辑直接转换成Room支持的SQL表达式,嵌入到ORDER BY子句中即可,具体实现如下:
核心逻辑转换
你给出的Kotlin函数是基于球面距离公式的实现,核心是先将角度转为弧度,再通过三角函数计算两点间的球面距离。我们直接把每一步逻辑转换成SQL语句:
- 角度转弧度:Kotlin里的
pk = 180/π,等价于SQL中* PI() / 180.0(除以180/π等于乘以π/180) - 用SQLite内置的
COS()、SIN()、ACOS()函数对应Kotlin里的同名数学方法 - 最后乘以地球半径6366000米得到实际距离,按此距离排序
完整的Room Query示例
@Query(""" SELECT * FROM example_table ORDER BY 6366000 * ACOS( COS(:sourceLatitude * PI() / 180.0) * COS(:sourceLongitude * PI() / 180.0) * COS(latitude * PI() / 180.0) * COS(longitude * PI() / 180.0) + COS(:sourceLatitude * PI() / 180.0) * SIN(:sourceLongitude * PI() / 180.0) * COS(latitude * PI() / 180.0) * SIN(longitude * PI() / 180.0) + SIN(:sourceLatitude * PI() / 180.0) * SIN(latitude * PI() / 180.0) ) ASC """) fun getItems(sourceLatitude: Double, sourceLongitude: Double): List<ExampleItems>
关键说明
:sourceLatitude和:sourceLongitude:对应你传入的参考点经纬度参数,参数名要和函数的参数名完全一致latitude、longitude:你的example_table中存储目标点经纬度的列名,需和实体类字段名匹配ASC:表示按距离从近到远排序,若需要从远到近,改成DESC即可- 整个表达式和你给出的Kotlin函数逻辑完全一致,计算出的距离值(单位:米)完全相同
内容的提问来源于stack exchange,提问作者Darren
相关产品推荐
相关产品推荐

