如何将lat-lng坐标的帖子作为帖子元查询?

时间:2012-08-14 作者:ifdion

我正在计划一个自定义WordPress主题,其中自定义帖子类型(CPT)将纬度和经度坐标作为其元值。纬度和经度将在谷歌地图中显示为标记。

到目前为止,我在显示谷歌地图和CPT作为标记时没有任何问题。这是如果我使用默认顺序查询CPT。

当我需要n个最接近坐标(无论是当前用户位置还是在地图上单击的位置)的CPT时,就会出现问题。另一种情况是查询坐标x km半径内的所有CPT。

问题是:如何根据保存在帖子元上的经纬度值查询帖子?

我真的不知道怎么做,但我认为纬度和经度值应该保存在一个单独的自定义字段中。

提前谢谢你。

4 个回复
最合适的回答,由SO网友:woony 整理而成

这是一个简单的数学问题。您确实需要访问经度和纬度,所以请将其保存在元字段中。

然后,您将不得不像这样以sql查询的方式查询您的帖子。没有机会测试它。或者将其倒入wordpress。现在没有访问我的测试环境的权限。但我想你可以自己做:)如果不行,我以后可以的时候再做。

set @latitude = xxx; — center latitude
set @longitude = xxx; — center longitude
set @distance = xx; — search distance

select p.ID, p.post_name, ((ACOS(SIN(@latitude * PI() / 180) * SIN(`latitude.meta_value` * PI() / 180) + COS(@latitude * PI() / 180) * COS(`latitude.meta_value` * PI() / 180) * COS((@longitude – `longitude.meta_value`) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance
from wp_posts p
left join wp_postmeta latitude on latitude.post_id = p.ID and latitude.meta_key = ‘_latitude’
left join wp_postmeta longitude on longitude.post_id = p.ID and longitude.meta_key = ‘_longitude’
having distance < @distance;

SO网友:mread1208

对于将来寻找这个答案的任何人来说,我对woony的代码进行了额外的研究,并在Wordpress的post\\u元表结构中实现了所有功能。这假设您有两个单独的自定义字段,一个用于纬度(city\\u Latitude),另一个用于经度(city\\u Latitude)。只需将纬度、经度和距离参数传递到WP函数中,就可以进行设置。

这是WP函数。把这个放在你的函数中。php文件:

function get_nearby_cities($lat, $long, $distance){
    global $wpdb;
    $nearbyCities = $wpdb->get_results( 
    "SELECT DISTINCT    
        city_latitude.post_id,
        city_latitude.meta_key,
        city_latitude.meta_value as cityLat,
        city_longitude.meta_value as cityLong,
        ((ACOS(SIN($lat * PI() / 180) * SIN(city_latitude.meta_value * PI() / 180) + COS($lat * PI() / 180) * COS(city_latitude.meta_value * PI() / 180) * COS(($long - city_longitude.meta_value) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance,
        wp_posts.post_title
    FROM 
        wp_postmeta AS city_latitude
        LEFT JOIN wp_postmeta as city_longitude ON city_latitude.post_id = city_longitude.post_id
        INNER JOIN wp_posts ON wp_posts.ID = city_latitude.post_id
    WHERE city_latitude.meta_key = \'city_latitude\' AND city_longitude.meta_key = \'city_longitude\'
    HAVING distance < $distance
    ORDER BY distance ASC;"
    );

    if($nearbyCities){
        return $nearbyCities;
    }
}
返回模板文件中的值:

$nearbyCities = get_nearby_cities(get_post_meta($post->ID, \'city_latitude\', true), get_post_meta($post->ID, \'city_longitude\', true), 25);

SO网友:Adrian

另一个解决方案建立在其他解决方案的基础上:

使用了$wpdb->;准备参数转义从$wpdb中使用的表名添加了最小距离添加了限制添加了在英里和公里之间切换的选项添加了设置后置类型的选项为元字段提取的名称

     /**
     * @param float   $latitude Latitude of the center
     * @param float   $longitude longitude of the center
     * @param int     $min_distance Minimal distance from the center (Default: 0).
     * @param int     $max_distance Maximal distance from the center (Default: 100).
     * @param int     $limit Maximal number of results (Default: 20).
     * @param string  $post_type Post type to filter for (Default: \'pois\').
     * @param boolean $use_miles Set to true, if you are using miles instead of kilometers (Default: false).
     * @return array|object
     */
    function my_get_nearby_locations( $latitude, $longitude, $min_distance = 0, $max_distance = 100, $limit = 20, $post_type = \'pois\', $use_miles = false ) {
        global $wpdb;
    
        $meta_key_latitude = \'location_lat\';
        $meta_key_longitude = \'location_long\';
    
        $miles_to_km = $use_miles ? 1 : 1.609344;
    
        $query = "SELECT DISTINCT
            t_lat.post_id,
            t_post.post_title,
            t_lat.meta_value as latitude,
            t_long.meta_value as longitude,
            ((ACOS(SIN(%f * PI() / 180) * SIN(t_lat.meta_value * PI() / 180) + COS(%f * PI() / 180) * COS(t_lat.meta_value * PI() / 180) * COS((%f - t_long.meta_value) * PI() / 180)) * 180 / PI()) * 60 * 1.1515 * {$miles_to_km}) AS distance
            FROM {$wpdb->postmeta} AS t_lat
            LEFT JOIN {$wpdb->postmeta} as t_long ON t_lat.post_id = t_long.post_id
            INNER JOIN {$wpdb->posts} as t_post ON t_post.ID = t_lat.post_id
            WHERE t_lat.meta_key = %s AND t_long.meta_key = %s AND t_post.post_type = %s
            HAVING distance > %d AND distance < %d ORDER BY distance ASC LIMIT %d;";
    
        $prepared_query = $wpdb->prepare( $query, [ $latitude, $latitude, $longitude, $meta_key_latitude, $meta_key_longitude, $post_type, $min_distance, $max_distance, $limit ] );
    
        return $wpdb->get_results( $prepared_query );
    }

SO网友:Mattvic

看看Geo Data Store plugin. 它为您的纵横坐标创建了一个优化的表,并有两个模板标记可供使用。

中的更多信息和代码示例this post

结束

相关推荐

使用新的WP-Query()从循环中过滤后期格式;

嗨,我目前正在为我的博客构建一个主题。下面的代码指向最新的帖子(特色帖子)。因为这将有一个不同的风格比所有其他职位。然而我想过滤掉帖子格式:链接使用我在循环中定义的WP查询,因为它给我带来了更多的灵活性。我该怎么做呢? <?php $featured = new WP_Query(); $featured->query(\'showposts=1\'); ?> <?php while ($featured->have_post