WordPress ACF 谷歌地图半径搜索

Posted

技术标签:

【中文标题】WordPress ACF 谷歌地图半径搜索【英文标题】:WordPress ACF Google Maps Radius Search 【发布时间】:2020-10-11 00:33:43 【问题描述】:

我遇到了一个大问题,没有解决方案。 我使用 WordPressCustom-Post-Type (CPT)高级自定义字段 (ACF)。 我创建了一个名为“projekt”的新 CPT 和一个保存 地址、经度和纬度ACF “Google Map Field”。坏事是 ACF 字段被序列化保存在 mysql 数据库中。

我在网上找到了以下 SQL-Query 来计算半径。

$lat = '50.12335';
$lng = '-1.344453';
$radius = 10; // (km)  

???....WHERE ( 6371 * acos( cos( radians(" . $lat . ") ) 
* cos( radians( lat ) ) 
* cos( radians( lng ) 
- radians(" . $lng . ") ) 
+ sin( radians(" . $lat . ") ) 
* sin( radians( lat ) ) ) ) <= " . $radius . ")"

我不知道如何构建查询,因为查询需要从序列化的 ACF 字段中获取经度和纬度信息。

数据库字段“元值”:

a:13:s:7:"address";s:44:"Moskauer Straße 5, Düsseldorf, Deutschland";s:3:"lat";d:51.2199565;s:3:"lng";d:6.8044928;s:4:"zoom";i:14;s:8:"place_id";s:114:"EiNNb3NrYXVlciBTdHIuLCBEw7xzc2VsZG9yZiwgR2VybWFueSIuKiwKFAoSCZV-jR3Ny7hHEVVgUQUBF7q8EhQKEgkBGQXwtsu4RxHgwS1K_GAnBQ";s:4:"name";s:16:"Moskauer Straße";s:11:"street_name";s:16:"Moskauer Straße";s:17:"street_name_short";s:13:"Moskauer Str.";s:4:"city";s:11:"Düsseldorf";s:5:"state";s:19:"Nordrhein-Westfalen";s:11:"state_short";s:3:"NRW";s:7:"country";s:11:"Deutschland";s:13:"country_short";s:2:"DE";

我可以通过以下方式获得我所有的“项目”:

也许可以扩展以下查询

SELECT P.ID, P.post_title, P.post_content, P.post_author, meta_value
FROM wp_posts AS P
LEFT JOIN wp_postmeta AS PM on PM.post_id = P.ID
WHERE P.post_type = 'projekt' and P.post_status = 'publish' and ( meta_key = 'adress' )
ORDER BY P.post_date DESC

结果是:

ID|post_title  |post_content|post_author|meta_value
55|Test Projekt|            |1          |a:13:s:7:"address";s:44:"Moskauer Straße 5, Düss...

你有什么解决办法吗?

谢谢!

【问题讨论】:

你能把数据在数据库中的样子贴出来吗? 我已经用序列化的字符串更新了我的帖子 【参考方案1】:

好的,所以这看起来很讨厌,但在不添加半径部分的测试中,我能够从序列化数据中提取 latlng

所以我认为您可以将半径检查作为AND 如下所示:

SELECT 
  REPLACE(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(pm.meta_value, 'lat', -1), ';', 2), ':', -1), '"', '') AS latitude,
  REPLACE(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(pm.meta_value, 'lng', -1), ';', 2), ':', -1), '"', '') AS longitude
FROM wp_postmeta pm
WHERE pm.meta_key = 'change_to_your_meta_key'
AND ( 6371 * acos( cos( radians(" . $lat . ") ) 
* cos( radians( latitude ) ) 
* cos( radians( longitude ) 
- radians(" . $lng . ") ) 
+ sin( radians(" . $lat . ") ) 
* sin( radians( longitude ) ) ) ) <= " . $radius . ")"

【讨论】:

【参考方案2】:

我自己找到了解决方案。 大多数人,创建额外的经纬度表。 我认为这是没有意义的,因为它们已经存在于 acf 领域。 我对 MySQL 不是很熟练,所以有些人当然可以缩短查询。 我不知道如何在 MySQL 中使用变量,因此可以将 lat 和 long 的正则表达式放入变量中:

REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lat\";d:([0-9\.]+).+','\\1') AS latitude

REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lng\";d:([0-9\.]+).+','\\1') AS longitude

现在这里是使用 WordPress、ACF(Google 地图字段)进行 Radius Search 的完整查询,其中 INPUTLAT、INPUTLONG、INPUTKM 是您提供的值:

SELECT P.ID, P.post_title, P.post_content, P.post_author,
    IF(PM.meta_key = 'adress', PM.meta_value, NULL) AS adress,
    REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lat\";d:([0-9\.]+).+','\\1') AS latitude,
    REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lng\";d:([0-9\.]+).+','\\1') AS longitude
FROM wp_posts AS P
LEFT JOIN wp_postmeta AS PM on PM.post_id = P.ID
WHERE P.post_type = 'projekt' and P.post_status = 'publish' and IF(PM.meta_key = 'adress', PM.meta_value, NULL) IS NOT NULL and IF(PM.meta_key = 'adress', PM.meta_value, NULL) IS NOT NULL AND 
( 6371 * acos( cos( radians(INPUTLAT) ) 
* cos( radians( REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lat\";d:([0-9\.]+).+','\\1') ) ) 
* cos( radians( REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lng\";d:([0-9\.]+).+','\\1') ) 
- radians(INPUTLONG) ) 
+ sin( radians(INPUTLAT) ) 
* sin( radians( REGEXP_REPLACE(IF(PM.meta_key = 'adress', PM.meta_value, NULL), '.+\"lat\";d:([0-9\.]+).+','\\1') ) ) ) ) <= INPUTKM 
ORDER BY P.post_date DESC

这仅适用于 MariaDB 或 MySQL 8。MySQL 5 不知道 REGEX_REPLACE

【讨论】:

在单独的表中添加 lat 和 long 并不是毫无意义的。只要它们被索引,它就比尝试在一个查询中完成所有事情更有意义。 1. 它简化了 SQL,意味着引入错误的风险更小,但 2. 更重要的是,它是一个更优化的查询,将提高性能。数据库需要做很多的工作来执行查询,需要更少的内存,减少数据库的负载并花费更少的时间来提高它的速度。

以上是关于WordPress ACF 谷歌地图半径搜索的主要内容,如果未能解决你的问题,请参考以下文章

javascript 谷歌地图半径搜索

我如何检索ACF谷歌地图数据并使用我自己的自定义字段来代替地图?

如何使用谷歌地图API制作一个搜索特定半径周围项目的表单?

如何用经纬度查地点?

php ACF谷歌地图单标记

php WP ACF多谷歌地图