コード例 #1
0
 public function test_bounding_box_for_radius()
 {
     // Helsinki-Malmi airport (EFHF)
     $efhf = new midgardmvc_helper_location_spot(60.254558, 25.042828);
     // Get 20km bounding box
     $bbox = midgardmvc_helper_location_utils::get_bounding_box_for_radius($efhf, 20);
     $this->assertTrue(is_array($bbox));
     $this->assertEquals(count($bbox), 2);
     // Ensure the box limits are in right directions
     $this->assertEquals(midgardmvc_helper_location_utils::get_bearing($efhf, $bbox[0]), 'SW');
     $this->assertEquals(midgardmvc_helper_location_utils::get_bearing($efhf, $bbox[1]), 'NE');
     // Check that the distance to a corner is correct.
     // Note: using 2D trigonometry on 3D globe so numbers are not exact
     $distance1 = midgardmvc_helper_location_utils::get_distance($bbox[0], $efhf);
     $this->assertEquals(round($distance1), round(sqrt(pow(20, 2) + pow(20, 2))));
 }
コード例 #2
0
 /**
  * Get closest items
  *
  * @param string $class MidCOM DBA class to query
  * @param midgardmvc_helper_location_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, midgardmvc_helper_location_spot $spot, $limit, $modifier = 0.15)
 {
     $classname = midgardmvc_helper_location_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 midgardmvc_helper_location_spot($result);
                 $distance = sprintf("%05d", round(midgardmvc_helper_location_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 midgardmvc_helper_location_utils::get_closest($class, $spot, $limit, $modifier);
     }
     $results = $qb->execute();
     $closest = array();
     foreach ($results as $result) {
         $result_spot = new midgardmvc_helper_location_spot($result);
         $distance = sprintf("%05d", round(midgardmvc_helper_location_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;
 }