当前位置:首页 > AI技术 > 正文内容

如何在Think中计算两点 间的地理距离 Dbraw执行GIS空间函数最佳践|Duuu笔记

admin3天前AI技术11

PHP进阶技巧:本文深入解析

行,但需数据库支持GIS函数、函数名正确、坐标系一致;MySQL用ST_Distance_Sphere,PostgreSQL用ST_DistanceSphere,字段须为POINT类型且坐标顺序为经度纬度,推荐参数绑定防注入并确保走空间索引。

ThinkPHP里直接用

Db::raw

调GIS函数算距离行不行?

行,但得看数据库是否支持、函数名是否匹配、坐标系是否一致。MySQL 5.7+、PostgreSQL + PostGIS 都可以,SQLite 基本不行;

Db::raw

只是把字符串原样塞进 SQL,不校验语法也不转义,写错就报错。

常见错误现象:

SQLSTATE[42000]: Syntax error or access violation

FUNCTION xxx does not exist

,基本都是函数名拼错、没开启空间扩展、或者字段类型不是

POINT

MySQL 必须用

ST_Distance_Sphere

(推荐)或

ST_Distance

(平面近似,精度差)

PostgreSQL + PostGIS 要用

ST_DistanceSphere

,注意大小写和参数顺序

字段必须是

POINT

类型,且用

POINT(longitude latitude)

格式存(经度在前,纬度在后)

别直接拼字符串,用

Db::raw("ST_Distance_Sphere(location, POINT(?, ?))", [$lng, $lat])

这种带参数绑定的方式,防注入也保类型

为什么

ST_Distance_Sphere

haversine

手动算更可靠?

因为 MySQL 内置函数自动处理了椭球模型(WGS84),而手写 haversine 是球面近似,10km 以内误差可能不到 10 米,但跨纬度大范围(比如哈尔滨到三亚)偏差能到百米级。而且

ST_Distance_Sphere

能走空间索引(如果字段加了

SPATIAL

索引),查询快几倍。

ST_Distance_Sphere

返回单位是「米」,不用再乘 1000 或除 1000

必须确保两个

POINT

在同一坐标系(通常是 EPSG:4326),否则结果无意义

如果用

ST_Distance

(不带 Sphere),它算的是平面欧氏距离,单位是「度」,完全不能直接当公里用

ThinkPHP 的

whereRaw

fieldRaw

才真正需要

Db::raw

,单纯

select

字段里用就足够

where

条件里用

Db::raw

算距离并过滤,怎么写才不出错?

重点不是“怎么写”,而是“怎么避免全表扫描”。只要用了

ST_Distance_Sphere

就没法走 B-tree 索引,但可以先用矩形范围粗筛,再精算。

Sheet+

Excel和GoogleSheets表格AI处理工具

下载

PHP免费学习笔记(深入)

”;

先用

ST_Contains(ST_MakeEnvelope(...), location)

或简单

lng BETWEEN ? AND ? AND lat BETWEEN ? AND ?

锁定候选集

再在

whereRaw

里用

ST_Distance_Sphere

做最终过滤,例如:

whereRaw('ST_Distance_Sphere(location, POINT(?, ?))

别在

order by

里直接写

Db::raw('ST_Distance_Sphere(...)')

排序——除非数据量极小,否则慢得明显

如果真要按距离排序,考虑加个虚拟列(MySQL 5.7+)或用子查询缓存距离值

PostgreSQL + PostGIS 场景下,

Db::raw

要注意什么?

PostGIS 函数名首字母大写(

ST_DistanceSphere

),参数顺序是

(geom1, geom2)

,且要求 geometry 类型必须显式指定 SRID,否则返回

null

建表时字段定义得写成

location GEOGRAPHY(POINT, 4326)

,不能只写

GEOMETRY

查询时用

ST_SetSRID(ST_MakePoint(?, ?), 4326)

构造目标点,否则

ST_DistanceSphere

拒绝计算

ThinkPHP 默认 PDO 不启用

PDO::ATTR_EMULATE_PREPARES = false

,PostgreSQL 对二进制协议敏感,建议显式配置

错误信息像

function st_distancesphere(geography, geography) does not exist

,八成是 SRID 没对齐或类型不匹配

地理距离计算最麻烦的从来不是写那一行

Db::raw

,而是确认数据库版本、空间类型定义、坐标系一致性,以及有没有悄悄绕过索引。漏查任意一项,线上查一次就卡三秒。

相关文章

什么是LLM?看这一篇就够了!

一、全套AGI大模型学习路线 AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能! 二、640套AI大模型报告合集 这套包含640份报告的合集,涵盖了AI大...

LLM介绍

。LLM 被证明在使用指令形式化描述的未见过的任务上表现良好。这意味着 LLM 能够根据任务指令执行任务,而无需事先见过具体示例,展示了其强大的泛化能力。 :小型语言模型通常难以解决涉...

【DL】2023年你应该知道的 10 大深度学习算法

3. 循环神经网络 (RNN) 4. 生成对抗网络 (GAN) 5. 径向基函数网络 (RBFN) 6. 多层感知器 (MLP) 7. 自组织图 (SOM)...

神经网络分类总结

从网络性能角度可分为连续型与离散型网络、确定性与随机性网络。 从网络结构角度可为前向网络与反馈网络。 从学习方式角度可分为有导师学习网络和无导师学习网络。 按连续突触性...

推荐10个AI人工智能技术网站

除了研究和开发人工智能技术,OpenAI还积极参与人工智能伦理和安全的研究和探讨。 认为,人工智能技术的发展必须遵循伦理和法律的规范,以确保人工智能的应用不会对人类带来负面影响。...

什么是人工智能 ?

您可以使用 ML 训练 AI,使其精确、快速地执行任务。这可以通过自动化员工感到吃力或厌烦的业务部分来提高运营效率。同样,您可以使用 AI 自动化来腾出员工资源,用于更复杂和更具创造性的工作。...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。