WordPress ACF Google Maps Radius Search - PullRequest
0 голосов
/ 21 июня 2020

У меня большая проблема и нет решения. Я работаю с WordPress и Custom-Post-Type (CPT) и Advanced Custom Fields (ACF) . Я создаю новый CPT под названием «projekt» и ACF «Поле карты Google» , в котором сохраняются адрес, долгота и широта . Плохо то, что поля ACF были сохранены сериализованы в MySQL DB.

Я нашел следующий SQL -запрос на Net для вычисления радиуса.

$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.

DB -Поле "meta_value":

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...

Есть ли у вас какое-нибудь решение для меня?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 21 июня 2020

Я нашел решение самостоятельно. Большинство людей создают дополнительные таблицы с широтой и долготой. Я думаю, что это бессмысленно, потому что они уже есть в поле 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 Map field), где 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

0 голосов
/ 21 июня 2020

Хорошо, это выглядит довольно неприятно, но при тестировании без добавления части радиуса я смог извлечь lat и lng из сериализованных данных.

введите описание изображения здесь

Итак, я думаю, вы можете закрепить свою проверку радиуса как 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 . ")"
...