geo.module

<?php // $Id: geo.module,v 1.17 2009/05/30 04:21:15 vauxia Exp $

/**
 * Geo: Geospatial storage and retrieval.
 */

define(GEO_SRID_DEFAULT, 4326);
define(GEO_DEGREE_M, 111206);

/**
 * Call an API function from the geo backend databases.
 * This function will find and load the database backend files, and call
 * the requested op from the backend or the default library, as needed.
 *
 * @return mixed
 *  The result of the database operation execution.
 */
function geo($op = NULL) {
  static $backend;

  // Load common functions.
  module_load_include('inc', 'geo');

  // Load database-specific functions.
  if (!isset($backend)) {
    $backend = geo_backend_type();
    module_load_include('inc', 'geo', 'db/'. $backend);
  }

  // Call the appropriate API function: If geo_$backend_$op exists, call that.
  // Otherwise, resort to geo_$op.  This creates a sort of inheritence system.
  $args = func_get_args();
  if($args) {
    $op = array_shift($args);
    if (!function_exists($func = 'geo_'. $backend .'_'. $op)) {
      $func = 'geo_'. $op;
    }
    if (!function_exists($func)) {
      drupal_set_message(t('Call to undefined geo operation %op', array('%op' => $op)), 'error');
      return FALSE;
    }
    return call_user_func_array($func, $args);
  }
}

/**
 * Implementation of hook_theme().
 */
function geo_theme() {
  $file_path = drupal_get_path('module', 'geo') .'/includes';
  return array(
    'geo_formatter_default' => array(
      'arguments' => array('element' => NULL),
      'file' => 'geo.formatters.inc',
      'path' => $file_path,
    ),
    'geo_formatter_lat' => array(
      'arguments' => array('element' => NULL),
      'file' => 'geo.formatters.inc',
      'path' => $file_path,
    ),
    'geo_formatter_lon' => array(
      'arguments' => array('element' => NULL),
      'file' => 'geo.formatters.inc',
      'path' => $file_path,
    ),
    'geo_formatter_georss' => array(
      'arguments' => array('element' => NULL),
      'file' => 'geo.formatters.inc',
      'path' => $file_path,
    ),
    'geo_formatter_svg' => array(
      'arguments' => array('element' => NULL),
      'file' => 'geo.formatters.inc',
      'path' => $file_path,
    ),
  );
}

/**
 * Implementation of hook_field_formatter_info().
 */
function geo_field_formatter_info() {
  // TODO some other formatters: asKML, asGML, asGeoRSS, etc
  return array(
    'default' => array(
      'label' => t('Well Known Text'),
      'field types' => geo_field_types(),
    ),
    'lat' => array(
      'label' => t('Latitude'),
      'field types' => geo_field_types(),
    ),
    'lon' => array(
      'label' => t('Longitude'),
      'field types' => geo_field_types(),
    ),
    'georss' => array(
      'label' => t('GeoRSS'),
      'field types' => geo_field_types(),
    ),
  );
}

/**
 * API Function: Return any field types that may contain geospatial data.
 */
function geo_field_types() {
  static $field_types;
  if (!isset($field_types)) {
    $field_types = array('geo', 'geo_data');
    drupal_alter('geo_field_types', $field_types);
  }
  return $field_types;
}

/**
 * Implementation of hook_geo_views_api().
 */
function geo_views_api() {
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'geo') .'/includes/views',
  );
}

/**
 * API Function: Format WKB data
 */
function geo_wkb_get_data($wkb = NULL, $format = 'text', $fp = NULL, $type = NULL) {
  module_load_include('inc', 'geo', 'includes/geo.wkb');
  return _geo_wkb_get_data($wkb, $format, $fp, $type);
}

/**
 * API Function: List of available units.
 */
function geo_units($unit = NULL) {
  $units = array(
    'mi' => t('Miles'),  
    'km' => t('Kilometers'),
    'm'  => t('Meters'),
  );

  return $unit ? $units[$unit] : $units;
}

/**
 * API Function: Convert between units.
 */
function geo_unit_convert($val, $from_unit, $to_unit) {
  switch ($from_unit) {

    case 'm': // Meters
      switch ($to_unit) {
        case 'km':
          $val = $val / 1000;
          break;
        case 'mi':
          $val = $val / 1609.344;
          break;
      }
      break;

    case 'km': // Kilometers
      switch ($to_unit) {
        case 'm':
          $val = $val * 1000;
          break;
        case 'mi':
          $val = $val * 0.62137;
          break;
      }
      break;

    case 'mi': // Miles
      switch ($to_unit) {
        case 'm':
          $val = $val * 1609.344;
          break;
        case 'km':
          $val = $val * 1.60934;
          break;
      }
      break;
  }

  return $val;
}