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

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

admin1周前 (03-31)AI技术17

行,但需数据库支持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

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

相关文章

【深度学习】Java DL4J 2024年度技术总结

一、Java DL4J深度学习概述 1.1 DL4J框架简介 1.2 与其他深度学习框架的比较 1.3 DL4J 的优势 1.3.1 与 Java 生态系统的无...

神经网络分类总结

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

深入理解AI:WorkBuddy 怎么做组织架构图 WorkBuddy 组织架构图生成教程【实战】完全指南|Duuu笔记

WorkBuddy可通过四种方式生成组织架构图:一、用自然语言指令触发AI自动解析并渲染Mermaid图表;二、上传Excel结构化数据映射字段后批量构建动态树状图;三、启用OpenClaw技能包对接...

AI实战详解:Perplexity 怎么做市场调研 Perplexity 市场分析实操教程【商业】最佳实践|Duuu笔记

掌握Perplexity AI市场调研需五步:一、结构化提问嵌入地域/时间/主体/指标四要素;二、限定PDF等原始信源提升可信度;三、分步提问生成制表符分隔文本以自动导入Excel;四、启用Pro S...

深入理解前端开发:Minimax 视频生成中负面提示词(Negative Prompt)写法完全指南|Duuu笔记

Minimax视频生成中负面提示词需用英文、逗号分隔,支持权重调节(如(blurry:1.3)),按构图/主体/画质/风格四类精简选取,禁用not/no/中文及违规词,须通过A/B测试验证有效性。...

AI高级应用:Perplexity 怎么写用户手册 Perplexity 产品帮助文档生成【技术】实战案例|Duuu笔记

Perplexity AI用户手册需基于API元数据、真实UI截图、典型场景示例、响应字段解析及动态调试指令五步构建:一调用API获取参数与错误码;二标注网页端搜索框、引用图标等组件;三设计信息检索、...

发表评论

访客

看不清,换一张

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