按最近的位置过滤WordPress帖子

Filtering WordPress posts by closest locations

本文关键字:WordPress 帖子 过滤 位置 最近      更新时间:2023-09-26

我有WordPress帖子显示在谷歌地图上。帖子从包含 latlng 值的自定义帖子字段中提取。纬度和液化天然气一起在这个值中。

该地图还显示了用户的位置与谷歌的地理位置。

有人可以指出我正确的方向,按离用户位置最近的 100 个帖子过滤帖子吗?

我正在通过query_posts元键在其他情况下进行过滤,并认为它在这种情况下也可能有效。

--更新--

我现在将纬度值和经度值存储在两个单独的字段中。如果我像这样设置用户的纬度/经度的预定值,我可以很好地过滤它......

  $lat_plus = '40.496755';
  $lat_minus = '35.496755';
  $long_plus = '-85.051597';
  $long_minus = '-89.3874682';
  $the_query = new WP_Query(array(
       'cat'   => $custom_category,
       'posts_per_page' => 50,
       'order' => 'ASC',
       'meta_query' => array(
             'relation' => 'AND',
              array(
                  'key' => 'latitude',
                  'value' => $lat_plus,
                  'compare' => '<',
                  'type' => 'NUMERIC'
              ),
              array(
                  'key' => 'latitude',
                  'value' => $lat_minus,
                  'compare' => '>',
                  'type' => 'NUMERIC'
              ),
              array(
                  'key' => 'longitude',
                  'value' => $long_plus,
                  'compare' => '<',
                  'type' => 'NUMERIC'
              ),
              array(
                  'key' => 'longitude',
                  'value' => $long_minus,
                  'compare' => '>',
                  'type' => 'NUMERIC'
              )

我想根据用户的当前位置设置这些值。我能够获取这些值并加减一个数字,以使用此代码在用户当前位置周围创建一个正方形。

 <SCRIPT type="text/javascript">
        $(function() {
            if(navigator.geolocation) {
                var fallback = setTimeout(function() { fail('10 seconds expired'); }, 10000);
                navigator.geolocation.getCurrentPosition(
                    function (pos) {
                        clearTimeout(fallback);
                        console.log('pos', pos);
                        var point = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
                        new google.maps.Geocoder().geocode({'latLng': point}, function (res, status) {
                            if(status == google.maps.GeocoderStatus.OK && typeof res[0] !== 'undefined') {
                                var change = '2.5';
                                var lat1 = pos.coords.latitude;
                                var lat2 = parseFloat(lat1,10) + parseFloat(change,10);
                                if(lat2) {
                                    $("._lat_more").html(lat2);
                                } else fail('Failed to parse');
                                var lat3 = parseFloat(lat1,10) - parseFloat(change,10);
                                if(lat3) {
                                    $("._lat_minus").html(lat3);
                                } else fail('Failed to parse');
                                var long1 = pos.coords.longitude;
                                var long2 = parseFloat(long1,10) + parseFloat(change,10);
                                if(long2) {
                                    $("._long_more").html(long2);
                                } else fail('Failed to parse');
                                var long3 = parseFloat(long1,10) - parseFloat(change,10);
                                if(long3) {
                                    $("._long_minus").html(long3);
                                } else fail('Failed to parse');
                                var zip = res[0].formatted_address.match(/,'s'w{2}'s('d{5})/);
                            } else {
                                fail('Failed to reverse');
                            }
                        });
                    }, function(err) {
                        fail(err.message);
                    }
                );
            } else {
                $("._res").html('Geolocation unsupported!');
            }
            function fail(err) {
                console.log('err', err);
                $("._res").html('Error ' + err);
            }
        });
        </SCRIPT>
<?php
 $lat_plus = '<div class="_lat_more"></div>';
 $lat_minus = '<div class="_lat_minus"></div>';
 $long_plus = '<div class="_long_more"></div>';
 $long_minus = '<div class="_long_minus"></div>
echo $lat_plus
echo $lat_minus
echo $long_plus
echo $long_minus
?>

问题是试图将JavaScript创建的值引入WordPress meta_query。我猜,因为我的变量基本上是在创建一个div,WordPress 无法将div 的值读取为元值。

有人可以帮助我指出正确的方向吗?

对我来说

,以下内容有效(从 http://www.bluefinengineering.com/blog/wordpress-geolocation-query-wp_query-lat-lng-post-metadata 开始)。这将过滤 PHP 中已有的帖子。

首先扩展WP_Query类

<?php
class WP_Query_Geo extends WP_Query {
  var $lat;
  var $lng;
  var $distance;
  function __construct($args=array()) {
    if(!empty($args['lat'])) {
      $this->lat = $args['lat'];
      $this->lng = $args['lng'];
      $this->distance = $args['distance'];
      add_filter('posts_fields', array($this, 'posts_fields'));
      add_filter('posts_groupby', array($this, 'posts_groupby'));
      add_filter('posts_join_paged', array($this, 'posts_join_paged'));
    }
    parent::query($args);
    remove_filter('posts_fields', array($this, 'posts_fields'));
    remove_filter('posts_groupby', array($this, 'posts_groupby'));
    remove_filter('posts_join_paged', array($this, 'posts_join_paged'));
  }
  function posts_fields($fields) {
    global $wpdb;
    $fields = $wpdb->prepare(" ((ACOS(SIN(%f * PI() / 180) * SIN(mtlat.meta_value * PI() / 180) + COS(%f * PI() / 180) * COS(mtlat.meta_value * PI() / 180) * COS((%f - mtlng.meta_value) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance", $this->lat, $this->lat, $this->lng);
    return $fields;
  }
  function posts_groupby($where) {
    global $wpdb;
    $where .= $wpdb->prepare(" HAVING distance < %d ", $this->distance);
    return $where;
  }
  function posts_join_paged($join) {
    $join .= " INNER JOIN uc_postmeta AS mtlat ON (IF(mtmaster.meta_value != uc_posts.ID, mtmaster.meta_value, uc_posts.ID) = mtlat.post_id AND mtlat.meta_key = 'lat') ";
    $join .= " INNER JOIN uc_postmeta AS mtlng ON (IF(mtmaster.meta_value != uc_posts.ID, mtmaster.meta_value, uc_posts.ID) = mtlng.post_id AND mtlng.meta_key = 'lng') ";
    return $join;
  }
}

然后使用新的 WP_Query_Geo 类查询帖子:

<?php
$args = array(
    'post_status' => 'publish',
    'posts_per_page' => $per_page,
    'paged' => $paged,
    'fields' => 'all',
    'lat' =>  $distance['lat'],
    'lng' =>  $distance['lng'],
    'distance' => $distance['range']
);
$query = new WP_Query_Geo( $args );