Skip to content
Snippets Groups Projects
gmap.module 42.7 KiB
Newer Older
      // Hmm, missing #map. Try to figure it out.
Brandon Bergren's avatar
Brandon Bergren committed
      if (isset($element['#gmap_settings']['id'])) {
        $map = $element['#gmap_settings']['id'];
Brandon Bergren's avatar
Brandon Bergren committed
  if (!isset($element['#attributes']['class'])) {
    $element['#attributes']['class'] = array();
Brandon Bergren's avatar
Brandon Bergren committed
  }
  $element['#attributes']['class'] = array_merge($element['#attributes']['class'], array(
    'gmap-control',
Brandon Bergren's avatar
 
Brandon Bergren committed
    'gmap-' . $type,
  $element['#id'] = gmap_get_id($map, $type);
  $element['#map'] = $map;
}

/**
 * @todo move this to GmapToolbox
 * Get a CSS id for a map and type.
 * Since CSS ids have to be unique, GMap related IDs are assigned by
 * this function.
 */
function gmap_get_id($map, $type) {
  static $serial = array();
  if (!isset($serial[$map])) {
    $serial[$map] = array();
  }
  if (!isset($serial[$map][$type])) {
    $serial[$map][$type] = -1;
  }
  $serial[$map][$type]++;
Brandon Bergren's avatar
 
Brandon Bergren committed
  return 'gmap-' . $map . '-' . $type . $serial[$map][$type];
 * @todo move this to GmapToolbox
 * Generate a dynamic map identifier.
 */
function gmap_get_auto_mapid() {
  static $auto = 0;
  $auto++;
Brandon Bergren's avatar
 
Brandon Bergren committed
  return 'auto' . $auto . 'map';
 * @todo move this to GmapMarkerInfo class
 * Get the list of marker titles.
 */
function gmap_get_marker_titles($reset = FALSE) {
  static $titles;

    $cached = cache_get('gmap_marker_titles', 'cache');
    if (!empty($cached)) {
      $titles = $cached->data;
      if (is_array($titles)) {
        return $titles;
      }
    }
Brandon Bergren's avatar
 
Brandon Bergren committed
  require_once(drupal_get_path('module', 'gmap') . '/gmap_markerinfo.inc');
  cache_set('gmap_marker_titles', $titles, 'cache');
 * @todo move this to GmapMarkerInfo class
 * Get the JSON icon data for all the default markers.
 */
function gmap_get_icondata($reset = FALSE) {
  static $icons;
  if (is_array($icons) && !$reset) {
    return $icons;
  }

  $icons = cache_get('gmap_icondata');
  if ($icons) {
    $icons = $icons->data;
  }

  if ($reset || !$icons) {
Brandon Bergren's avatar
 
Brandon Bergren committed
    require_once(drupal_get_path('module', 'gmap') . '/gmap_markerinfo.inc');
    $icons = _gmap_get_icondata();
  }
  cache_set('gmap_icondata', $icons, 'cache');
 * @todo move this to GmapPolylineToolbox or GmapToolbox
 * Utility function to allow high-precision decimals to work with the SQL layer.
 * Use concatenation. (Apparently unquoted %s is bad.)
 */
function gmap_decimal($num) {
  // Paraphrased from postgresql documentation:
  //
  // Numbers in SQL can be in one of these forms:
  //   digits
  //   digits.[digits][e[+-]digits]
  //   [digits].digits[e[+-]digits]
  //   digitse[+-]digits
  // where "digits" is one or more decimal digits.

  // Trim extra whitespace
  $num = trim($num);
  // Check if we're in an acceptable form.
  if (preg_match('/^[+\-]?((\d+)|(\d+\.\d*)|(\d*\.\d+))(e[+\-]?\d+)?$/', $num) === 1) {
    // Good, we can pass that right along.
    return $num;
  }
  // Otherwise, cast to float, possibly losing precision.
  return (float) $num;
}

/**
 * @todo move this to GmapRequest class
 * Utility function to use the google maps geocoder server side.
 * This is an easy, quick way to geocode a single address.
 * Note: This is a REMOTE CALL TO GOOGLE. Do NOT use this where performance matters,
 * as it could possibly take several seconds for this function to return.
 * See http://www.google.com/apis/maps/documentation/reference.html#GGeoStatusCode
 *  for a description of the possible status codes.
 * @see http://drupal.org/node/1940474
 */
function gmap_geocode($address, $tld = 'com') {
  $data = drupal_http_request(gmap_views_protocol() . '://maps.googleapis.' . $tld . '/maps/api/geocode/json?address=' . urlencode($address) . '&sensor=false');
  if ($data->code == 200) {
    $data_decoded = json_decode($data->data);
    if ($data_decoded->status == 'ZERO_RESULTS' || $data_decoded->status == 'OVER_QUERY_LIMIT') {
      return array(
        'status' => $data_decoded->status,
        'accuracy' => NULL,
        'latitude' => NULL,
        'longitude' => NULL,
      );
    }
    else {
      return array(
        'status' => $data_decoded->status,
        'accuracy' => $data_decoded->results[0]->geometry->location_type,
        'latitude' => $data_decoded->results[0]->geometry->location->lat,
        'longitude' => $data_decoded->results[0]->geometry->location->lng,
      );
    }
  }
  // Non 200 is G_GEO_SERVER_ERROR (500).
  return array(
    'status' => 500,
  );
}

/**
 * @todo move this to GmapDraw class
 * Simple way to draw a map from inside a theme.
 * @param $latitude
 * Latitude of marker.
 * @param $longitude
 * Longitude of marker.
 * @param string $markername
 * Marker to use.
 *   '' will fall back to google's default marker.
 * @param string $info
 * What to show in the bubble when the marker is clicked.
 *   Leave blank if you don't want a bubble.
 * @param string $zoom
 * 'default' will use the default zoom from the settings page.
 *  3 is usually a good value to use.
 * @param string $width
 * 'default' will use the default width from the settings page.
 * @param string $height
 * 'default' will use the default height from the settings page.
 * @param bool $autoshow
 * If set to TRUE, automatically show the marker bubble.
 * @param array $map
 *   Override parts of the map array.
 *   If you need to do much with this, you should probabaly be putting together
 *   the map array manually.
 */
function gmap_simple_map($latitude, $longitude, $markername = '', $info = '', $zoom = 'auto', $width = 'default', $height = 'default', $autoshow = FALSE, $map = array()) {
  $settings = array(
    'id' => gmap_get_auto_mapid(),
    'latitude' => $latitude, // Center the map
    'longitude' => $longitude, // on the marker.
  );
  if ($zoom != 'default') {
    $settings['zoom'] = $zoom;
  }
  if ($width != 'default') {
    $settings['width'] = $width;
  }
  if ($height != 'default') {
    $settings['height'] = $height;
  }

  $settings['markers'] = array(
    array(
      'latitude' => $latitude,
      'longitude' => $longitude,
      'markername' => $markername,
      'offset' => 0,
    )
  );

  if (!empty($info)) {
    $settings['markers'][0]['text'] = $info;
  }

  if ($autoshow) {
    $settings['markers'][0]['autoclick'] = TRUE;
  }

  if (!empty($map)) {
    $settings = array_merge($settings, $map);
  }

Brandon Bergren's avatar
Brandon Bergren committed
  $element = array(
    '#type' => 'gmap',
    '#gmap_settings' => $settings,
  );
  return drupal_render($element);
 * @todo move this to GmapContribToolbox class
 * Implementation of hook_keys_service(). (from the keys api)
 */
function gmap_keys_service() {
  // @todo Remove after everyone has upgraded from keys api.
  if (module_exists('keys_api')) {
    return array(
      'gmap' => array(
        'name' => t('Gmap'),
        'description' => t('Google Maps API Key'),
      ),
    );
  }
  elseif (module_exists('keys')) {
    // @greenSkin:
    // What is your reasoning behind predefining this?
    // I'll avoid overriding you for now, but this seems rather arbitrary.
    // Reference: http://drupal.org/cvs?commit=310498

    // Probe keys to determine if it is defining our key for us.
    $test = array();
    if (function_exists('keys_keys_service')) {
      $test = keys_keys_service();
    }
    if (!isset($test['google_maps'])) {
      // Be forward compatible with future versions of keys api
      // that no longer define it.
      return array(
        'google_maps' => array(
          'name' => t('Google Maps'),
          'description' => t('Google Maps API Key'),
        ),
      );
    }
  }
/**
 * Retrieve the Google Maps key that is in use for the site.
 *
 * @todo move this to GmapDefaults class
 */
function gmap_get_key() {
  if (module_exists('keys_api')) {
    $key = keys_api_get_key('gmap', $_SERVER['HTTP_HOST']);
  }
  elseif (module_exists('keys')) {
    $key = keys_get_key('google_maps');
  }
  return $key;
}

/**
 * Implementation of hook_views_plugins().
 * @todo move this to GmapViews class
 */
function gmap_views_plugins() {
  return array(
    'module' => 'gmap',
    'style' => array(
      'gmap' => array(
        'title' => t('GMap'),
        'help' => t('Displays rows as a map.'),
        'handler' => 'gmap_plugin_style_gmap',
        'theme' => 'gmap_view_gmap',
        'uses row plugin' => TRUE,
        'uses grouping' => TRUE,
        'uses options' => TRUE,
        'type' => 'normal',
      ),
      'gmapextended' => array(
        'title' => t('Extended GMap'),
        'help' => t('Displays a map of markers.'),
        'handler' => 'gmap_plugin_style_gmapextended',
        'theme' => 'gmap_views_view_gmapextended',
        'uses row plugin' => TRUE,
        'uses fields' => TRUE,
        'uses options' => TRUE,
        //'uses grouping' => TRUE,
        'type' => 'normal',
      ),
 * @todo move this to GmapViews class
 * Implementation of hook_views_ajax_data_alter().
 */
function gmap_views_ajax_data_alter(&$commands, $view) {
  // Add js callback only with gmap style plugins and with ajax.
  $plugin_styles = array($view->plugin_name);
  foreach ($view->display as $display) {
    if (isset($display->display_options['style_plugin'])) {
      $plugin_styles[] = $display->display_options['style_plugin'];
    }
  if (!(in_array('gmap', $plugin_styles))) {

  // Find the JQuery selector for the view's wrapper in the DOM
  $target = '';
  foreach ($commands as $command) {
    if ($command['command'] == 'insert') {
      $target = $command['selector'];
    }
  }
  $command = array('command' => 'gmapAjaxViewsFix', 'target' => $target);
  // Save settings.
  $js = drupal_add_js(NULL, array('scope' => 'header'));
  $command['settings'] = $js['settings']['data'];
  $commands[] = $command;
}

/**
 * @param $variables
 * @return string
 * @todo possible move this to GmapView class
 */
function theme_gmap_views_ui_gmapextended($variables) {
  $form = $variables['form'];

  $output = drupal_render($form['description_markup']);

  $header = array(
    t('Field'),
    t('Purpose'),
    t('Separator'),
    /*    array(
          'data' => t('Sortable'),
          'align' => 'center',
        ),
        array(
          'data' => t('Default sort'),
          'align' => 'center',
        ),*/
  );
  $rows = array();
  foreach (element_children($form['field_purposes']) as $id) {
    $row = array();
    $row[] = drupal_render($form['info'][$id]['name']);
    $row[] = drupal_render($form['field_purposes'][$id]);
    $row[] = drupal_render($form['info'][$id]['separator']);
    $rows[] = $row;
  }

  // Add the special 'None' row.
//  $rows[] = array(t('None'), '', '', '', array('align' => 'center', 'data' => drupal_render($form['default'][-1])));

  $output .= theme('table', array('header' => $header, 'rows' => $rows));
  $output .= drupal_render_children($form);
  return $output;
}

 * @todo possible move this to GmapView class
 * Preprocess function for theme_gmap_view_gmap().
 */
function template_preprocess_gmap_view_gmap(&$vars) {
  $vars['map_object'] = $vars['rows'];
  // Rows is actually our map object.
  unset($vars['rows']);
  $vars['map_element'] = array(
    '#type' => 'gmap',
    '#gmap_settings' => $vars['map_object'],
  );
  // Theme the map.
  $vars['map'] = drupal_render($vars['map_element']);
}
 * @todo move this to GmapRequest class
 * Determine the site protocol (http or https)
 */
function gmap_views_protocol() {
  return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
}