Почтовые запросы по широте и долготе

Я борюсь с получением почтовых запросов по координатам. У меня есть мета-поля map_lat и map_lng для почти всех типов сообщений. Я пытаюсь вернуть сообщения из одного настраиваемого типа сообщений («пляжи» в этом примере):

 function get_nearby_locations($lat, $long, $distance){ global $wpdb; $nearbyLocations = $wpdb->get_results( "SELECT DISTINCT map_lat.post_id, map_lat.meta_key, map_lat.meta_value as locLat, map_lng.meta_value as locLong, ((ACOS(SIN($lat * PI() / 180) * SIN(map_lat.meta_value * PI() / 180) + COS($lat * PI() / 180) * COS(map_lat.meta_value * PI() / 180) * COS(($long - map_lng.meta_value) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance, wp_posts.post_title FROM wp_postmeta AS map_lat LEFT JOIN wp_postmeta as map_lng ON map_lat.post_id = map_lng.post_id INNER JOIN wp_posts ON wp_posts.ID = map_lat.post_id WHERE map_lat.meta_key = 'map_lat' AND map_lng.meta_key = 'map_lng' AND post_type='beaches' HAVING distance < $distance ORDER BY distance ASC;" ); if($nearbyLocations){ return $nearbyLocations; } } 

и я называю это:

 $nearbyLocation = get_nearby_cities(get_post_meta($post->ID, 'map_lat', true), get_post_meta($post->ID, 'map_lng', true), 25); 

но он не возвращает то, что я хочу.

Solutions Collecting From Web of "Почтовые запросы по широте и долготе"

Закрыть. Вам понадобится еще одна INNER JOIN и вам следует избегать всех ваших переменных, используя $wpdb->prepare .

Я также включил более эффективную формулу Хаверсина ( источник ) для вычисления радиуса.

Если вы используете километры, измените значение $earth_radius на 6371.

Кроме того, отличным способом отладки является эхо-код sql и вставка его в phpMyAdmin (или любое другое используемое приложение db) и настроить его там.

 function get_nearby_locations( $lat, $long, $distance ) { global $wpdb; // Radius of the earth 3959 miles or 6371 kilometers. $earth_radius = 3959; $sql = $wpdb->prepare( " SELECT DISTINCT p.ID, p.post_title, map_lat.meta_value as locLat, map_lng.meta_value as locLong, ( %d * acos( cos( radians( %s ) ) * cos( radians( map_lat.meta_value ) ) * cos( radians( map_lng.meta_value ) - radians( %s ) ) + sin( radians( %s ) ) * sin( radians( map_lat.meta_value ) ) ) ) AS distance FROM $wpdb->posts p INNER JOIN $wpdb->postmeta map_lat ON p.ID = map_lat.post_id INNER JOIN $wpdb->postmeta map_lng ON p.ID = map_lng.post_id WHERE 1 = 1 AND p.post_type = 'beaches' AND p.post_status = 'publish' AND map_lat.meta_key = 'map_lat' AND map_lng.meta_key = 'map_lng' HAVING distance < %s ORDER BY distance ASC", $earth_radius, $lat, $lng, $lat, $distance ); // Uncomment to echo, paste into phpMyAdmin, and debug. // echo $sql; $nearbyLocations = $wpdb->get_results( $sql ); if ( $nearbyLocations ) { return $nearbyLocations; } } 

Мне удалось заставить его работать:

 function get_nearby_locations( $lat, $long, $distance ) { global $wpdb; // Radius of the earth 3959 miles or 6371 kilometers. $earth_radius = 3959; $sql = $wpdb->prepare( " SELECT DISTINCT map_lat.post_id, p.post_title, map_lat.meta_value as locLat, map_lng.meta_value as locLong, ( 6371 * ACOS( COS(RADIANS( %s )) * COS(RADIANS(map_lat.meta_value)) * COS( RADIANS(map_lng.meta_value) - RADIANS( %s ) ) + SIN(RADIANS( %s )) * SIN(RADIANS(map_lat.meta_value)) ) ) AS distance FROM $wpdb->posts p INNER JOIN $wpdb->postmeta map_lat ON p.ID = map_lat.post_id INNER JOIN $wpdb->postmeta map_lng ON p.ID = map_lng.post_id WHERE 1 = 1 AND p.post_type = 'beaches' AND p.post_status = 'publish' AND map_lat.meta_key = 'geo_lat' AND map_lng.meta_key = 'geo_lng' HAVING distance < %s ORDER BY distance ASC", $earth_radius, $lat, $lng, $lat, $radius ); // Uncomment to echo, paste into phpMyAdmin, and debug. // echo $sql; $nearbyLocations = $wpdb->get_results( $sql ); if ( $nearbyLocations ) { return $nearbyLocations; } }