如何查询两个自定义字段中的值之间的坐标?

时间:2018-11-27 00:15:22

标签: php wordpress

我的帖子中有两个自定义字段,其值可能类似于

get_usp-custom-19 = 40.85150386578784
get_usp-custom-20 = 14.258907499999964

然后我从表单中收到具有以下值的GET:

$lat = $_GET['usp-custom-19'];
$ln = $_GET['usp-custom-20'];

现在$lat$ln具有latitudelongitude分隔的值,我创建了一个查询,例如:

$args = array(
    'post_type' => 'post',
    'meta_query' => array(
        array(
            'relation' => 'AND',
            array(
                'key' => 'get_usp-custom-19',
                'value' => $lat,
                'compare' => 'BETWEEN',
                'type' => 'NUMERIC',
            ),
            array(
                'key' => 'get_usp-custom-20',
                'value' => $ln,
                'compare' => 'BETWEEN',
                'type' => 'NUMERIC',
            ),
        ),
    ),
);

但是我得到了错误的结果,因为它们之间没有进行比较,我也尝试将其type设置为CHARDECIMALS,但结果仍然是错误的。我也可以得到像-9.258907499999964这样的负坐标,而我正在阅读有关conssen或使用abs()的信息,但是现在我很困惑

更新

在这里我尝试创建半径

$lat = $_GET['usp-custom-19'];
$ln = $_GET['usp-custom-20'];

$args = get_posts( 
    array( 
        'post_type'      => 'post', 
        'posts_per_page' => -1, 
    ) 
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
    while ( $query->have_posts() ) {
        $query->the_post();
        $customCoords = usp_get_meta(false, 'usp-custom-90');
        $arrayCoords = explode( ",", $customCoords );
        $radiusLn = +$arrayCoords[0] + 10;
        $radiusLat = +$arrayCoords[1] + 10;
        $args = array(
            'post_type' => 'post',
            'meta_query' => array(
                array(
                    'relation' => 'AND',
                    array(
                        'key' => 'get_usp-custom-19',
                        'value' => array($ln, $radiusLn),
                        'compare' => '>='
                    ),
                    array(
                        'key' => 'get_usp-custom-20',
                        'value' => array($lat, $radiusLat),
                        'compare' => '<='
                    ),
                ),
            ),
        );
        $query = new WP_Query( $args );
        if ( $query->have_posts() ) {
            while ( $query->have_posts() ) {
                $query->the_post();
                the_title();
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

基本上,您需要确保键的值以及$lat$ln的类型相同,并且可以将它们进行比较,例如十进制。

然后,您可以使用>=<=进行比较。

$args = array(
  'post_type' => 'post',
  'meta_query' => array(
     array(
       'relation' => 'AND',
        array(
            'key' => 'get_usp-custom-19', // make sure the value of this field is the same as $lat; 
            'value' => $lat,
            'compare' => '>=',
            'type' => 'NUMERIC',
        ),
        array(
            'key' => 'get_usp-custom-20', // make sure the value of this field is the same as $ln; 
            'value' => $ln,
            'compare' => '<=',
            'type' => 'NUMERIC',
        ),
    ),
  ),
);

您可能还想先更改$lat$ln的类型。

post很好地解释了比较运算符。

答案 1 :(得分:0)

我猜测您正在尝试找到关于经纬度和经度最近的帖子。在这种情况下,我认为原始SQL查询更易于使用:

$post_ids = $wpdb->get_col( <<<EOD
SELECT m.post_id FROM $wpdb->postmeta m, $wpdb->postmeta n
    WHERE m.post_id=n.post_id AND m.meta_key='get_usp-custom-19' AND n.meta_key='get_usp-custom-20'
        AND (POW( CAST(m.meta_value AS DECIMAL(7,4)) - $lat, 2 )
                + POW( COS(0.0175 * $lat) * ( CAST(n.meta_value AS DECIMAL(7,4)) - $ln ), 2 ) ) )
            < $rad * $rad
EOD
);

SQL联接中的行具有lat和long,然后结果是给定($ lat,$ ln)的差的平方和小于$ rad平方。

附录:

原始查询省略了必须应用于经度的COS校正。这使用了勾股定理,该定理仅在平面上有效。两点必须足够接近,以使三角形基本上在平坦的表面上。 (否则,您需要一个"Great Circle" formula。)此外,如果两个点跨越本初子午线(180度子午线)的相反位置(国际日期线),也会出现问题。

回复评论:

给出的查询确实对于大型数据库而言效率低下。问题在于联接是在整个postmeta表上完成的。要解决此问题,您可以对派生表进行联接,其中,左侧派生表仅限于纬度接近给定纬度的行,而右侧派生表仅限于经度接近给定经度的行。

勾股定理在球体表面上实际上是无效的。但是,这里的目的是要找到不计算完全准确距离的近点。由于我们正在寻找闭合点,因此勾股定理的变形非常小,因为这些点基本上位于平面上。我认为,Haversine公式在计算上要昂贵得多,并且针对此问题提供了不必要的附加准确性。