php 使用WP REST API计算纬度和经度坐标之间的距离,并返回按用户c的距离排序的帖子
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php 使用WP REST API计算纬度和经度坐标之间的距离,并返回按用户c的距离排序的帖子相关的知识,希望对你有一定的参考价值。
<?php
/**
* Heavily borrowed from: http://xplus3.net/2010/08/08/filtering-on-a-non-standard-database-field-with-wordpress/
**/
class CoordinatesTable extends DB {
protected $db_option = "coordinates_db";
protected $db_version = 2;
protected $id_field = 'pid';
protected $columns = [
'pid' => '%d',
'latitude' => '%f',
'longitude' => '%f',
];
/**
* CoordinatesTable constructor.
*
* Create table if needed
*/
private function __construct() {
global $wpdb;
$this->table = $wpdb->prefix . 'coordinates';
if ( $this->update_required() ) {
$this->run_updates();
}
}
/**
* Create table with indexes for lat/lon
*/
protected function create_table() {
global $wpdb;
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
foreach ( array( 'providers' ) as $table ) {
$sql = "CREATE TABLE {$this->table} (
pid bigint(20) unsigned NOT NULL,
latitude double,
longitude double,
UNIQUE KEY pid (pid),
INDEX latitude (latitude),
INDEX longitude (longitude)
) /*!40100 DEFAULT CHARACTER SET utf8 */;";
dbDelta( $sql );
}
}
/**
* @param $fields
*
* @return string
*
* To be hooked into 'post_fields' filter
*/
public function query_posts_fields( $fields ) {
global $wpdb;
global $wp_query;
list( $lat, $lng ) = explode(',', $wp_query->query_vars['latlong'] );
$fields .= sprintf(",
( 6371000
* acos( cos( radians( %f ) )
* cos( radians( {$this->table}.latitude ) )
* cos( radians( {$this->table}.longitude ) - radians( %f ) )
+ sin( radians( %f ) )
* sin( radians({$this->table}.latitude ) ) ) ) AS distance", $lat, $lng, $lat );
return $fields;
}
/**
* @param $join
*
* @return string
*
* To be hooked into 'posts_join' filter
*/
public function query_posts_join( $join ) {
global $wpdb;
$join = " LEFT JOIN {$this->table} ON {$wpdb->posts}.ID = {$this->table}.pid" . $join;
return $join;
}
/**
* @param $orderby
*
* @return string
*/
public function query_posts_orderby( $orderby ) {
$myorder = "distance ASC";
if ( $orderby ) {
$myorder .= ',' . $orderby;
}
return $myorder; // return the default if we haven't changed it
}
/**
* @param $groupby
*
* @return string
*
* To be hooked into 'posts_groupby' filter. This groups by the distance and orders closest in meters. The limit
* is necessary for max distance to get properly ordered results.
*/
public function query_posts_groupby( $groupby ) {
global $wpdb;
if ( null === $max_distance = get_field( Options::GEO_MAX_DISTANCE, 'option' ) ) {
$max_distance = Options::GEO_MAX_DISTANCE_DEFAULT;
}
$groupby = $wpdb->prepare( " {$wpdb->posts}.ID HAVING distance < %d", $max_distance );
return $groupby;
}
/**
* Inject our query's sql string
*/
public function query_filters() {
add_filter( 'posts_clauses', function( $clauses ) {
$clauses['fields'] = $this->query_posts_fields( $clauses['fields'] );
$clauses['join'] = $this->query_posts_join( $clauses['join'] );
$clauses['orderby'] = $this->query_posts_orderby( $clauses['orderby'] );
$clauses['groupby'] = $this->query_posts_groupby( $clauses['groupby'] );
return $clauses;
} );
}
public function save_coordinates( $post_id, $lat, $long ) {
$this->add( [
'pid' => $post_id,
'latitude' => $lat,
'longitude' => $long,
] );
}
public function delete_coordinates( $post_id ) {
$this->remove( [
'pid' => $post_id,
] );
}
public function get_latitude( $post_id ) {
return $this->get( 'latitude', [ 'pid' => $post_id, ], 1 );
}
public function get_longitude( $post_id ) {
return $this->get( 'longitude', [ 'pid' => $post_id, ], 1 );
}
}
以上是关于php 使用WP REST API计算纬度和经度坐标之间的距离,并返回按用户c的距离排序的帖子的主要内容,如果未能解决你的问题,请参考以下文章