it-swarm.com.de

Ist es möglich, die Suche nach geografischen Standorten um WP_Query zu wickeln?

Ich möchte nur hinzufügen, dass ich über eine aktuelle funktionierende Lösung verfüge, die gut funktioniert, aber ich suche nach Ideen, wie ich es besser oder sauberer machen kann, wenn es möglich ist.

Wir haben Hunderte von Eigenschaften in einem benutzerdefinierten Beitragstyp, wobei Metakey/Metavalue die Längen- und Breitengradkoordinaten der Eigenschaften enthält.

Wir erlauben einem Besucher, einen Ort und einen Radius einzugeben, um nach diesen Eigenschaften in diesem Bereich zu suchen. Irgendwie wie ein Händlersuchdienst. So mache ich es im Moment:

// Work out square radius
if(!empty($_SESSION['s_property_radius'])) {$dist = $_SESSION['s_property_radius'];}else{$dist = 50;}
$orig_lat = $_SESSION['s_property_address_lat'];
$orig_lon = $_SESSION['s_property_address_lng'];
$lon1 = $orig_lon - $dist / abs( cos( deg2rad( $orig_lat ) ) * 69 );
$lon2 = $orig_lon + $dist / abs( cos( deg2rad( $orig_lat ) ) * 69 );
$lat1 = $orig_lat - ( $dist / 69 );
$lat2 = $orig_lat + ( $dist / 69 );

// Compile a map search query to get all property ID's.
$mapsearchquery = "
            SELECT `t`.`ID`
            , 3956 * 2 * ASIN( SQRT( POWER( SIN( ( ".$orig_lat." - CAST(`t`.`property_address_lat` AS DECIMAL(9,6)) ) * pi() / 180 / 2), 2 ) + COS( ".$orig_lat." * pi() / 180) * COS( CAST(`t`.`property_address_lat` AS DECIMAL(9,6)) * pi() / 180 ) * POWER( SIN( ( ".$orig_lon." - CAST(`t`.`property_address_lng` AS DECIMAL(9,6)) ) * pi() / 180 / 2 ), 2 ) ) ) AS `distance` 
            FROM (

            SELECT `$wpdb->posts`.`ID`
            , MAX(CASE WHEN `$wpdb->postmeta`.`meta_key` = 'chb_homes_for_sale_address_longitude' THEN `$wpdb->postmeta`.`meta_value` END ) AS `property_address_lng`
            , MAX(CASE WHEN `$wpdb->postmeta`.`meta_key` = 'chb_homes_for_sale_address_latitude' THEN `$wpdb->postmeta`.`meta_value` END ) AS `property_address_lat`
            FROM `$wpdb->posts` 
            LEFT JOIN `$wpdb->postmeta` ON ( `$wpdb->posts`.`ID` = `$wpdb->postmeta`.`post_id` ) 
            WHERE `$wpdb->posts`.`post_status` = 'publish' 
            AND `$wpdb->posts`.`post_type` = 'homes-for-sale' 
            GROUP BY `$wpdb->posts`.`ID` 
            HAVING CAST(`property_address_lng` AS DECIMAL(9,6)) BETWEEN '".$lon1."' AND '".$lon2."' AND CAST(`property_address_lat` AS DECIMAL(9,6)) BETWEEN '".$lat1."' AND '".$lat2."'

            ) AS `t`
            HAVING `distance` < ".$dist."
        ";

// Just get the ID's
$mapsearchresults = $wpdb->get_col($mapsearchquery);

Dies gibt ein Array aller Beitrags-IDs zurück, die in den Suchparametern des Benutzers enthalten sind. Ich füge dieses Array dann zu WP_Query hinzu, um nur Posts mit den oben genannten IDs anzuzeigen, die post__in verwenden. Ich kann danach auch andere Suchkriterien für die WP_Query ausführen.

In der obigen Abfrage führe ich eine Quadratradiusprüfung durch und weiß, dass dies in WP_Query mit meta_query problemlos möglich ist. Aber wo ich stecken bleibe, läuft der Kreisradiuscheck. Gibt es eine Möglichkeit, dies in WP_Query zu verpacken?

Grundsätzlich versuche ich, dies alles in einem Schritt zu erledigen, anstatt zwei Abfragen zu erledigen.

5
Brady

Ich würde die Koordinaten der Beiträge in einer separaten Tabelle (post_id, lat, lon) mit einem Index auf (lat, lon) duplizieren. Bei all den Joins und Casts bezweifle ich, dass die Datenbank einen effizienten Index für Ihre Abfrage verwenden kann.

Ich schrieb einmal eine Antwort auf eine ähnliche Frage mit diesem Ansatz.

2
Jan Fabry