脚本宝典收集整理的这篇文章主要介绍了php – 按坐标之间的距离过滤wordpress帖子,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
/?cat=0&s=5041GW&range=250&lat=51.5654368&lon=5.071263999999928
然后有一些帖子(不是全部)有一个lat和long字段,我使用插件高级自定义字段创建.这些是我传递给get_posts以获取按类别过滤的帖子的参数:
$args = array( 'posts_PEr_page' => 24,'category' => $_GET["cat"],'orderby' => 'post_date','order' => 'DESC','post_type' => 'adressen','post_status' => 'publish',);
现在我要做的就是修改它,以便在实际传递范围和位置时,帖子将被过滤为仅返回位置在用户搜索位置的范围(以千米为单位)内的帖子.我似乎无法找到一个好的解决方案,因为我很难使用wordpress及其插件.我真的很感激我能理解的解决方案.
由于米和纬度/长度之间没有线性映射,因此出现了困难.这取决于你在地球上的位置.有关详情,请参见this question. PHPcoord library存在为您进行此计算,但由于我提出的答案的略微近似性质,我将使用Haversine formula使用Haversine formula描述的近似方法.
我将使用以下公式:
>计算两个lat / lng坐标之间的距离(以km为单位):
x = Δλ ⋅ cos φm y = Δφ d = R ⋅ √(x² + y²)
其中φ是弧度的纬度,λ是弧度的经度,R是地球的半径(平均半径= 6,371km)
>在给定起始纬度,距离和方位的情况下计算目的地:
φ2 = asin( sin φ1 ⋅ cos δ + cos φ1 ⋅ sin δ ⋅ cos θ ) λ2 = λ1 + atan2( sin θ ⋅ sin δ ⋅ cos φ1,cos δ − sin φ1 ⋅ sin φ2 )
其中θ是方位(从北向顺时针方向),δ是角距离d / R,d是行进距离.见atan2.
因此,我们将定义以下辅助函数:
const R = 6371; // km function distance_between_points_rad($lat1,$lng1,$lat2,$lng2){ // latlng in radians $x = ($lng2-$lng1) * cos(($lat1+$lat2)/2); $y = ($lat2-$lat1); // return distance in km return sqrt($x*$x + $y*$y) * R; } function get_destination_lat_rad($lat1,$d,$brng){ return asin( sin($lat1)*cos($d/R) + cos($lat1)*sin($d/R)*cos($brng) ); } function get_destination_lng_rad($lat1,$brng){ $lat2 = get_destination_lat_rad($lat1,$brng); return $lng1 + atan2(sin($brng)*sin($d/R)*cos($lat1),cos($d/R)-sin($lat1)*sin($lat2)); } function get_bounding_Box_rad($lat,$lng,$range){ // latlng in radians,$range in km $latmin = get_destination_lat_rad($lat,$range,0); $latmax = get_destination_lat_rad($lat,deg2rad(180)); $lngmax = get_destination_lng_rad($lat,deg2rad(90)); $lngmin = get_destination_lng_rad($lat,deg2rad(270)); // return apPRox bounding latlng in radians return array($latmin,$latmax,$lngmin,$lngmax); } function distance_between_points_deg($lat1,$lng2){ // latlng in degrees // return distance in km return distance_between_points_rad( deg2rad($lat1),deg2rad($lng1),deg2rad($lat2),deg2rad($lng2) ); } function get_bounding_Box_deg($lat,$range){ // latlng in degrees,$range in km return array_map(rad2deg,get_bounding_Box_rad(deg2rad($lat),deg2rad($lng),$range)); }
现在,一般过程应是:
>创建一个边界square-ish框,将帖子过滤到一个
很少是正确的.这不应该太计算
昂贵,但是可能会留下一些边缘的近似值
out,并包括一些不适合的帖子.
>优化退货
只发布适合账单的那些帖子.这是计算上的
昂贵的过程,因此是第一阶段.少数帖子被排除在外
第一步仍将被排除在外.边界框可以
可能会变大以适应.
您要使用的查询应包含元信息:
请参阅here以获取有关这些元查询的有用指南
$lat1 = $_GET['lat']; // degrees $lng1 = $_GET['lng']; // degrees $range = $_GET['range']; // km // get the approxiMATE bounding Box $bBox = get_bounding_Box_deg($lat1,$range); // query the posts $args = array( 'posts_per_page' => 24,'Meta_query' => array( 'relation' => 'AND',array( 'key' => 'lat','value' => array( $bBox[0],$bBox[1] ),'type' => 'numeric','compare' => 'BETWEEN' ),array( 'key' => 'lng','value' => array( $bBox[2],$bBox[3] ),'compare' => 'BETWEEN' ) ) ); $the_query = new WP_Query( $args );
然后在循环中过滤帖子:
// Then filter the posts down in the loop if ( $the_query->have_posts() ) { while ( $the_query->have_posts() ) { $the_query->the_post(); $custom_fields = get_post_custom(); if (isset($custom_fields['lat']) && isset($custom_fields['lng'])){ $lat2 = $custom_fields['lat']; $lng2 = $custom_fields['lng']; $dist = distance_between_points_deg($lat1,$lng2); if ($dist <= $range){ // post is in range } else { // post out of range,discard } } else { // post has no latlng coords } } } else { // no posts found } /* ReStore original Post Data */ wp_reset_postdata();
以上是脚本宝典为你收集整理的php – 按坐标之间的距离过滤wordpress帖子全部内容,希望文章能够帮你解决php – 按坐标之间的距离过滤wordpress帖子所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。