Making WordPress.org


Ignore:
Timestamp:
03/08/2017 04:32:24 PM (9 years ago)
Author:
iandunn
Message:

Events API: Return the name of a city when passed coordinates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/api.wordpress.org/public_html/events/1.0/index.php

    r5102 r5128  
    252252        ! empty( $args['longitude'] ) && is_numeric( $args['longitude'] )
    253253    ) {
    254         // TODO: Ensure that the data here is rounded to city-level and return the name of the city/region.
     254        $city = get_city_from_coordinates( $args['latitude'], $args['longitude'] );
     255
    255256        return array(
    256             'description' => "{$args['latitude']}, {$args['longitude']}",
     257            'description' => $city ? $city : "{$args['latitude']}, {$args['longitude']}",
    257258            'latitude'  => $args['latitude'],
    258259            'longitude' => $args['longitude']
     
    373374
    374375    return $country_code;
     376}
     377
     378/**
     379 * Get the name of the city that's closest to the given coordinates
     380 *
     381 * @todo - This can probably be optimized by SELECT'ing from a derived table of the closest rows, instead of the
     382 *         entire table, similar to the technique described at
     383 *         http://www.techfounder.net/2009/02/02/selecting-closest-values-in-mysql/
     384 *         There's only 140k rows in the table, though, so this is performant for now.
     385 *
     386 * @param float $latitude
     387 * @param float $longitude
     388 *
     389 * @return false|string
     390 */
     391function get_city_from_coordinates( $latitude, $longitude ) {
     392    global $wpdb;
     393
     394    $results = $wpdb->get_col( $wpdb->prepare( "
     395        SELECT
     396            name,
     397            ABS( %f - latitude  ) AS latitude_distance,
     398            ABS( %f - longitude ) AS longitude_distance
     399        FROM geoname
     400        HAVING
     401            latitude_distance  < 0.3 AND    -- 0.3 degrees is about 30 miles
     402            longitude_distance < 0.3
     403        ORDER by latitude_distance ASC, longitude_distance ASC
     404        LIMIT 1",
     405        $latitude,
     406        $longitude
     407    ) );
     408
     409    return isset( $results[0] ) ? $results[0] : false;
    375410}
    376411
Note: See TracChangeset for help on using the changeset viewer.