示例#1
0
 /**
  *
  * @param Array $coordinates Contains latitude and longitude values
  * @return Array containing geocoded information
  */
 function reverse_geocode($coordinates, $options = array())
 {
     $results = array();
     $parameters = array('radius' => 10, 'maxRows' => 20, 'style' => 'FULL');
     if (!empty($options)) {
         foreach ($options as $key => $value) {
             if (isset($parameters[$key])) {
                 $parameters[$key] = $value;
             }
         }
     }
     if (!isset($coordinates['latitude']) && !isset($coordinates['longitude'])) {
         $this->error = 'POSITIONING_MISSING_ATTRIBUTES';
         return null;
     }
     $params = array();
     $params[] = 'lat=' . urlencode($coordinates['latitude']);
     $params[] = 'lng=' . urlencode($coordinates['longitude']);
     foreach ($parameters as $key => $value) {
         if (!is_null($value)) {
             $params[] = "{$key}=" . urlencode($value);
         }
     }
     $http_request = new org_openpsa_httplib();
     $url = 'http://ws.geonames.org/findNearbyPlaceName?' . implode('&', $params);
     $response = $http_request->get($url);
     $simplexml = simplexml_load_string($response);
     if (!isset($simplexml->geoname) || count($simplexml->geoname) == 0) {
         $this->error = 'POSITIONING_DETAILS_NOT_FOUND';
         if (isset($simplexml->status)) {
             $constant_name = strtoupper(str_replace(" ", "_", $simplexml->status));
             $this->error = $constant_name;
         }
         return null;
     }
     for ($i = 0; $i < $parameters['maxRows']; $i++) {
         if (!isset($simplexml->geoname[$i])) {
             break;
         }
         $entry = $simplexml->geoname[$i];
         $entry_coordinates = array('latitude' => (double) $entry->lat, 'longitude' => (double) $entry->lng);
         $meters = round(org_routamc_positioning_utils::get_distance($coordinates, $entry_coordinates) * 1000);
         $entry_meters = round((double) $entry->distance * 1000);
         if ($entry_meters < $meters) {
             $meters = $entry_meters;
         }
         $position = array();
         $position['latitude'] = (double) $entry->lat;
         $position['longitude'] = (double) $entry->lng;
         $position['distance'] = array('meters' => $meters, 'bearing' => org_routamc_positioning_utils::get_bearing($coordinates, $entry_coordinates));
         $position['city'] = (string) $entry->name;
         $position['region'] = (string) $entry->adminName2;
         $position['country'] = (string) $entry->countryCode;
         $position['postalcode'] = (string) $entry->postalcode;
         $position['alternate_names'] = (string) $entry->alternateNames;
         $position['accuracy'] = ORG_ROUTAMC_POSITIONING_ACCURACY_GPS;
         $results[] = $position;
     }
     return $results;
 }
示例#2
0
$user = midcom::get('auth')->user->get_storage();
$user_position = new org_routamc_positioning_person($user);
$coordinates = $user_position->get_coordinates();
if (!$coordinates) {
    throw new midcom_error("Failed to get your current position.");
}
echo "<p>" . sprintf('Your position is %s', org_routamc_positioning_utils::pretty_print_coordinates($coordinates['latitude'], $coordinates['longitude'])) . "</p>\n";
$run_times = 1;
$run = 0;
$total_time = 0;
while ($run < $run_times) {
    $run++;
    $start = microtime();
    $closest = org_routamc_positioning_utils::get_closest('org_routamc_positioning_city_dba', $coordinates, 10);
    echo "<p>Closest places to you are:<br />";
    echo "<ol>\n";
    foreach ($closest as $city) {
        $city_coordinates = array('latitude' => $city->latitude, 'longitude' => $city->longitude);
        echo "<li>{$city->city}, {$city->country} is " . round(org_routamc_positioning_utils::get_distance($coordinates, $city_coordinates)) . " kilometers " . org_routamc_positioning_utils::get_bearing($coordinates, $city_coordinates) . " from you</li>";
    }
    echo "</ol>\n";
    $end = microtime();
    $end_parts = explode(' ', $end);
    $end = $end_parts[1] + $end_parts[0];
    $start_parts = explode(' ', $start);
    $start = $start_parts[1] + $start_parts[0];
    $time_used = $end - $start;
    $total_time = $time_used + $total_time;
}
$average = $total_time / $run_times;
echo "<p>Query took {$total_time} seconds (on average {$average} seconds per query).</p>";
示例#3
0
        $manual_position['country'] = trim($params[1]);
        $manual_position['person'] = $person->id;
        $import = $manual->import($manual_position);
        if (!$import) {
            // Send error message to user
            org_routamc_positioning_send_sms($person->handphone, "Failed to store position, reason {$manual->error}", $config->get('smslib_from'), $config);
        } else {
            // Get current coordinates
            $user_position = new org_routamc_positioning_person($person);
            $latest_log = $user_position->seek_log();
            $latest_coord = array('latitude' => $latest_log->latitude, 'longitude' => $latest_log->longitude);
            $previous_log = $latest_log->get_previous();
            $message = "New location is " . org_routamc_positioning_utils::pretty_print_coordinates($latest_log->latitude, $latest_log->longitude) . ".";
            if ($previous_log) {
                $previous_coord = array('latitude' => $previous_log->latitude, 'longitude' => $previous_log->longitude);
                $message .= " Previous was " . org_routamc_positioning_utils::get_distance($previous_coord, $latest_coord) . "km " . org_routamc_positioning_utils::get_bearing($latest_coord, $previous_coord) . ".";
            }
            org_routamc_positioning_send_sms($person->handphone, $message, $config->get('smslib_from'), $config);
        }
    }
    midcom::get('auth')->drop_sudo();
    midcom::get()->finish();
    _midcom_stop_request();
}
midcom::get('auth')->require_valid_user();
$user = midcom::get('auth')->user->get_storage();
if (array_key_exists('add_position', $_POST)) {
    $manual = org_routamc_positioning_importer::create('manual');
    $manual_position = array();
    if (array_key_exists('geocoder', $_POST)) {
        $manual_position['geocoder'] = $_POST['geocoder'];
示例#4
0
文件: utils.php 项目: nemein/openpsa
 /**
  * Get closest items
  *
  * Note: If you set a max distance you may not always get the number of items specified in the limit.
  *
  * @param string $class MidCOM DBA class to query
  * @param array $position Center position
  * @param integer $limit How many results to return
  * @param integer $max_distance Maximum distance of returned objects in kilometers, or null if any
  * @param float $modifier
  * @return array array of MidCOM DBA objects sorted by proximity
  */
 function get_closest($class, $center, $limit, $max_distance = null, $modifier = 0.15)
 {
     $classname = org_routamc_positioning_utils::get_positioning_class($class);
     $direct = false;
     if ($classname != $class) {
         $direct = false;
     } else {
         $direct = true;
     }
     $qb = midcom::get('dbfactory')->new_query_builder($classname);
     if (!$direct) {
         // We're querying a regular DBA object through a location object
         $qb->add_constraint('parentclass', '=', $class);
     }
     static $rounds = 0;
     $rounds++;
     // Limit to earth coordinates
     $from['latitude'] = $center['latitude'] + $modifier;
     if ($from['latitude'] > 90) {
         $from['latitude'] = 90;
     }
     $from['longitude'] = $center['longitude'] - $modifier;
     if ($from['longitude'] < -180) {
         $from['longitude'] = -180;
     }
     $to['latitude'] = $center['latitude'] - $modifier;
     if ($to['latitude'] < -90) {
         $to['latitude'] = -90;
     }
     $to['longitude'] = $center['longitude'] + $modifier;
     if ($to['longitude'] > 180) {
         $to['longitude'] = 180;
     }
     if (!isset($current_locale)) {
         $current_locale = setlocale(LC_NUMERIC, '0');
         setlocale(LC_NUMERIC, 'C');
     }
     $qb->begin_group('AND');
     $qb->add_constraint('latitude', '<', (double) $from['latitude']);
     $qb->add_constraint('latitude', '>', (double) $to['latitude']);
     $qb->end_group();
     $qb->begin_group('AND');
     $qb->add_constraint('longitude', '>', (double) $from['longitude']);
     $qb->add_constraint('longitude', '<', (double) $to['longitude']);
     $qb->end_group();
     $result_count = $qb->count();
     if ($result_count == 0) {
         // Check that there are any in the DB before proceeding further
         $qb_check = midcom::get('dbfactory')->new_query_builder($classname);
         if ($qb_check->count_unchecked() == 0) {
             return array();
         }
     }
     if ($result_count < $limit) {
         if ($from['latitude'] == 90 && $from['longitude'] == -180 && $to['latitude'] == -90 && $to['longitude'] == 180) {
             // We've queried the entire globe so we return whatever we got
             $results = $qb->execute();
             $closest = array();
             foreach ($results as $result) {
                 $result_coordinates = array('latitude' => $result->latitude, 'longitude' => $result->longitude);
                 $distance = sprintf("%05d", round(org_routamc_positioning_utils::get_distance($center, $result_coordinates)));
                 if (!is_null($max_distance) && $distance > $max_distance) {
                     // This entry is too far
                     continue;
                 }
                 if (!$direct) {
                     // Instantiate the real object as the result
                     $located_object = new $class($result->parent);
                     if (!$located_object->guid) {
                         // This one has been deleted
                         midcom::get('auth')->request_sudo('org.routamc.positioning');
                         $result->delete();
                         midcom::get('auth')->drop_sudo();
                         continue;
                     }
                     $result = $located_object;
                     $result->latitude = $result_coordinates['latitude'];
                     $result->longitude = $result_coordinates['longitude'];
                     $result->distance = (int) $distance;
                 }
                 $closest[$distance . $result->guid] = $result;
             }
             ksort($closest);
             reset($closest);
             return $closest;
         }
         $modifier = $modifier * 1.05;
         setlocale(LC_NUMERIC, $current_locale);
         return org_routamc_positioning_utils::get_closest($class, $center, $limit, $max_distance, $modifier);
     }
     $results = $qb->execute();
     $closest = array();
     foreach ($results as $result) {
         $result_coordinates = array('latitude' => $result->latitude, 'longitude' => $result->longitude);
         $distance = sprintf("%05d", round(org_routamc_positioning_utils::get_distance($center, $result_coordinates)));
         if (!is_null($max_distance) && $distance > $max_distance) {
             // This entry is too far
             continue;
         }
         if (!$direct) {
             // Instantiate the real object as the result
             $located_object = new $class($result->parent);
             if (!$located_object->guid) {
                 // This one has been deleted
                 midcom::get('auth')->request_sudo('org.routamc.positioning');
                 $result->delete();
                 midcom::get('auth')->drop_sudo();
                 continue;
             }
             $result = $located_object;
             $result->latitude = $result_coordinates['latitude'];
             $result->longitude = $result_coordinates['longitude'];
             $result->distance = (int) $distance;
         }
         $closest[$distance . $result->guid] = $result;
     }
     ksort($closest);
     reset($closest);
     while (count($closest) > $limit) {
         array_pop($closest);
     }
     setlocale(LC_NUMERIC, $current_locale);
     return $closest;
 }
示例#5
0
文件: city.php 项目: nemein/openpsa
 /**
  * @param Array $coordinates Contains latitude and longitude values
  * @param Array $options
  * @return Array containing geocoded information
  */
 function reverse_geocode($coordinates, $options = array())
 {
     $results = array();
     $parameters = array('maxRows' => 1);
     if (!empty($options)) {
         foreach ($options as $key => $value) {
             if (isset($parameters[$key])) {
                 $parameters[$key] = $value;
             }
         }
     }
     if (!isset($coordinates['latitude']) && !isset($coordinates['longitude'])) {
         $this->error = 'POSITIONING_MISSING_ATTRIBUTES';
         return null;
     }
     $closest = org_routamc_positioning_utils::get_closest('org_routamc_positioning_city_dba', $coordinates, $parameters['maxRows']);
     if (empty($closest)) {
         $this->error = 'POSITIONING_DETAILS_NOT_FOUND';
         return null;
     }
     foreach ($closest as $city) {
         $city_coordinates = array('latitude' => $city->latitude, 'longitude' => $city->longitude);
         $position = array();
         $position['latitude'] = $city->latitude;
         $position['longitude'] = $city->longitude;
         $position['distance'] = array('meters' => round(org_routamc_positioning_utils::get_distance($coordinates, $city_coordinates) * 1000), 'bearing' => org_routamc_positioning_utils::get_bearing($coordinates, $city_coordinates));
         $position['city'] = $city->city;
         $position['region'] = $city->region;
         $position['country'] = $city->country;
         $position['alternate_names'] = $city->alternatenames;
         $position['accuracy'] = ORG_ROUTAMC_POSITIONING_ACCURACY_GPS;
         $results[] = $position;
     }
     return $results;
 }
示例#6
0
文件: utils.php 项目: abbra/midcom
 /**
  * Get closest items
  *
  * @param string $class MidCOM DBA class to query
  * @param org_routamc_positioning_spot $spot Center position
  * @param integer $limit How many results to return
  * @return Array Array of MidCOM DBA objects sorted by proximity
  */
 static function get_closest($class, org_routamc_positioning_spot $spot, $limit, $modifier = 0.15)
 {
     $classname = org_routamc_positioning_utils::get_positioning_class($class);
     if ($classname != $class) {
         $direct = false;
     } else {
         $direct = true;
     }
     $qb = new midgard_query_builder($classname);
     if (!$direct) {
         // We're querying a regular DBA object through a location object
         $qb->add_constraint('parentclass', '=', $class);
     }
     static $rounds = 0;
     $rounds++;
     $from['latitude'] = $spot->latitude + $modifier;
     if ($from['latitude'] > 90) {
         $from['latitude'] = 90;
     }
     $from['longitude'] = $spot->longitude - $modifier;
     if ($from['longitude'] < -180) {
         $from['longitude'] = -180;
     }
     $to['latitude'] = $spot->latitude - $modifier;
     if ($to['latitude'] < -90) {
         $to['latitude'] = -90;
     }
     $to['longitude'] = $spot->longitude + $modifier;
     if ($to['longitude'] > 180) {
         $to['longitude'] = 180;
     }
     if (!isset($current_locale)) {
         $current_locale = setlocale(LC_NUMERIC, '0');
         setlocale(LC_NUMERIC, 'C');
     }
     $qb->begin_group('AND');
     $qb->add_constraint('latitude', '<', (double) $from['latitude']);
     $qb->add_constraint('latitude', '>', (double) $to['latitude']);
     $qb->end_group();
     $qb->begin_group('AND');
     $qb->add_constraint('longitude', '>', (double) $from['longitude']);
     $qb->add_constraint('longitude', '<', (double) $to['longitude']);
     $qb->end_group();
     $result_count = $qb->count();
     //echo "<br />Round {$rounds}, lat1 {$from['latitude']} lon1 {$from['longitude']}, lat2 {$to['latitude']} lon2 {$to['longitude']}: {$result_count} results\n";
     if ($result_count < $limit) {
         if ($from['latitude'] == 90 && $from['longitude'] == -180 && $to['latitude'] == -90 && $to['longitude'] == 180) {
             // We've queried the entire globe so we return whatever we got
             $results = $qb->execute();
             $closest = array();
             foreach ($results as $result) {
                 $result_spot = new org_routamc_positioning_spot($result);
                 $distance = sprintf("%05d", round(org_routamc_positioning_utils::get_distance($spot, $result_spot)));
                 if (!$direct) {
                     // Instantiate the real object as the result
                     $result = new $class($result->parent);
                     $result->spot = $result_spot;
                     $result->latitude = $result_spot->latitude;
                     $result->longitude = $result_spot->longitude;
                 }
                 $closest[$distance . $result->guid] = $result;
             }
             ksort($closest);
             reset($closest);
             return $closest;
         }
         $modifier = $modifier * 1.05;
         setlocale(LC_NUMERIC, $current_locale);
         return org_routamc_positioning_utils::get_closest($class, $spot, $limit, $modifier);
     }
     $results = $qb->execute();
     $closest = array();
     foreach ($results as $result) {
         $result_spot = new org_routamc_positioning_spot($result);
         $distance = sprintf("%05d", round(org_routamc_positioning_utils::get_distance($spot, $result_spot)));
         if (!$direct) {
             // Instantiate the real object as the result
             $result = new $class($result->parent);
             $result->spot = $result_spot;
             $result->latitude = $result_spot->latitude;
             $result->longitude = $result_spot->longitude;
         }
         $closest[$distance . $result->guid] = $result;
     }
     ksort($closest);
     reset($closest);
     while (count($closest) > $limit) {
         array_pop($closest);
     }
     setlocale(LC_NUMERIC, $current_locale);
     return $closest;
 }