You are here

function gm3_region_get_region_id_from_latlng in Google Maps API V3 7

Get the region_id from the lat,lng and zoom

1 string reference to 'gm3_region_get_region_id_from_latlng'
gm3_region_menu in gm3_region/gm3_region.module
Implementation of hook_menu().

File

gm3_region/gm3_region.callback.inc, line 6

Code

function gm3_region_get_region_id_from_latlng($latlng, $iso_codes, $level) {

  // Because the TDWG data and Google data don't quite match, here we convert
  // some of the codes sent to us by Google.
  $convert_codes = array(
    'GB' => 'UK',
    'RS' => 'YU',
    'ME' => 'MK',
    'SS' => 'SD',
    'UNKNOWN' => array(
      'YU',
      'IN',
    ),
  );
  if (isset($convert_codes[$iso_codes])) {
    $iso_codes = $convert_codes[$iso_codes];
  }
  if (!is_array($iso_codes)) {
    $iso_codes = array(
      $iso_codes,
    );
  }

  // First we try to get a single hit using the MySQL geo extension.
  $latlng = preg_replace("/[)(]/", "", $latlng);
  $latlng = explode(", ", $latlng);
  $point_wkt = "POINT({$latlng[1]} {$latlng[0]})";
  $results = db_query("SELECT CONCAT(level_1_code, ':', level_2_code, ':', level_3_code, ':', level_3_code, '-', level_4_code) as code \n  \t\t\t\t\t\t\t\t\t\t FROM {gm3_region_data} WHERE WITHIN(POINTFROMTEXT('{$point_wkt}'), mysql_polygons) AND level_4_code != ''", array(
    ':iso_code' => $iso_codes,
  ));
  if ($results
    ->rowCount() == 1) {

    // We've had success with our trimmed down method. WOOT!
    $results = $results
      ->fetch();
    if (arg(4) < 4) {
      $code_parts = explode(':', $results->code);
      for ($i = arg(4); $i < 4; $i++) {
        array_pop($code_parts);
      }
      $results->code = implode(":", $code_parts);
    }
    print json_encode($results->code);
    exit;
  }

  // Load the Library.
  gm3_load_geophp();
  $wkt_reader = new WKT();

  // Create a point object from the sent data.
  $point = geoPHP::load($point_wkt, 'wkt');
  foreach ($iso_codes as $iso_code) {

    // Loop through each Level 1 region.
    $region_id = '';
    $level4s = db_select('gm3_region_data', 'g')
      ->fields('g')
      ->condition('level_4_code', '', '!=')
      ->condition('iso_code', $iso_code, 'LIKE')
      ->execute();
    $level_2_codes = array();
    foreach ($level4s as $level4) {
      $level_2_codes[$level4->level_2_code] = $level4->level_2_code;
      $polygon = $wkt_reader
        ->read($level4->polygons, TRUE);
      if ($point
        ->within($polygon)) {
        $region_id = "{$level4->level_1_code}:{$level4->level_2_code}:{$level4->level_3_code}:{$level4->level_3_code}-{$level4->level_4_code}";

        // Stop on the first match.
        break;
      }
    }
    if (!$region_id) {

      // Due to a fuck up with the TDWG data, we can't restrict by the iso_code
      // being null, so instead we search by the level_2_code.
      foreach ($level_2_codes as $level_2_code) {
        $level4s = db_select('gm3_region_data', 'g')
          ->fields('g')
          ->condition('level_4_code', '', '!=')
          ->condition('level_2_code', $level_2_code)
          ->execute();
        foreach ($level4s as $level4) {
          $polygon = $wkt_reader
            ->read($level4->polygons, TRUE);
          if ($point
            ->within($polygon)) {
            $region_id = "{$level4->level_1_code}:{$level4->level_2_code}:{$level4->level_3_code}:{$level4->level_3_code}-{$level4->level_4_code}";

            // stop on the first match
            break 2;
          }
        }
      }
    }
    if ($region_id) {
      break;
    }
  }
  if ($region_id && $level < 4) {
    $region_id = explode(":", $region_id);
    for ($i = 4; $i > $level; $i--) {
      array_pop($region_id);
    }
    $region_id = implode(":", $region_id);
  }
  print json_encode($region_id);
  exit;
}