You are here

geolocation_html5.module in Geolocation Field 7

HTML5 widget and formaters for Geolocation.

File

modules/geolocation_html5/geolocation_html5.module
View source
<?php

/**
 * @file
 * HTML5 widget and formaters for Geolocation.
 */

/**
 * Implements hook_field_formatter_info().
 */
function geolocation_html5_field_formatter_info() {
  return array(
    'geolocation_html5_mapimage' => array(
      'label' => t('HTML5 Map image'),
      'field types' => array(
        'geolocation_latlng',
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function geolocation_html5_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  drupal_add_css(drupal_get_path('module', 'geolocation_html5') . '/geolocation_html5.css', 'file');
  switch ($display['type']) {
    case 'geolocation_html5_mapimage':
      foreach ($items as $delta => $item) {

        // Calculate dot position.
        $latitude = $item['lat'];
        $longitude = $item['lng'];
        $left = _geolocation_html5_lng2px($longitude, -168, 450);
        $bottom = _geolocation_html5_lat2px($latitude, 78, -58, 250);
        $dot_style = ' style="display:block; left:' . $left . 'px; bottom:' . $bottom . 'px;"';
        $element[$delta]['mapimage'] = array(
          '#type' => 'markup',
          '#markup' => '<div class="geolocation-html5-map" style="display:block;"><div class="dot"' . $dot_style . '></div></div>',
        );
      }
      break;
  }
  return $element;
}

/**
 * Implements hook_field_widget_info().
 */
function geolocation_html5_field_widget_info() {
  return array(
    'geolocation_html5_widget' => array(
      'label' => t('HTML5 widget'),
      'field types' => array(
        'geolocation_latlng',
      ),
    ),
  );
}

/**
 * Implements hook_field_widget_form().
 */
function geolocation_html5_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $lat_value = isset($items[$delta]['lat']) ? $items[$delta]['lat'] : '';
  $lng_value = isset($items[$delta]['lng']) ? $items[$delta]['lng'] : '';
  $element += array(
    '#delta' => $delta,
  );
  switch ($instance['widget']['type']) {
    case 'geolocation_html5_widget':
      $element['lat'] = array(
        '#type' => 'hidden',
        '#attributes' => array(
          'class' => 'geolocation-lat',
        ),
        '#default_value' => $lat_value,
        '#maxlength' => 30,
      );
      $element['lng'] = array(
        '#type' => 'hidden',
        '#attributes' => array(
          'class' => 'geolocation-lng',
        ),
        '#default_value' => $lng_value,
        '#maxlength' => 30,
      );
      $element['save'] = array(
        '#type' => 'checkbox',
        '#title' => t('Save my location'),
        '#description' => t('Your web browser does not support geolocation (<a href="http://en.wikipedia.org/wiki/W3C_Geolocation_API">W3C Geolocation API</a>).'),
        '#default_value' => $lat_value !== '',
        '#required' => $instance['required'],
      );
      $dot_style = '';

      // If we have a lat/lng pair, calculate dot position.
      if ($lat_value != '' && $lng_value != '') {
        $latitude = $lat_value;
        $longitude = $lng_value;
        $left = _geolocation_html5_lng2px($longitude, -168, 450);
        $bottom = _geolocation_html5_lat2px($latitude, 78, -58, 250);
        $dot_style = ' style="display:block; left:' . $left . 'px; bottom:' . $bottom . 'px;"';
      }
      $element['map'] = array(
        '#type' => 'markup',
        '#markup' => '<div class="geolocation-html5-map"><div class="dot"' . $dot_style . '></div></div>',
      );
      $element['messages'] = array(
        '#type' => 'markup',
        '#markup' => '
          <div class="geolocation-html5-messages">
            <div class="geolocating">' . t('Your browser is looking for your location, you may need to approve this…') . '</div>
          </div>',
      );

      // Attach CSS and JS files via FAPI '#attached'.
      $element['map']['#attached']['css'][] = drupal_get_path('module', 'geolocation_html5') . '/geolocation_html5.css';
      $element['map']['#attached']['js'][] = array(
        'data' => drupal_get_path('module', 'geolocation_html5') . '/geolocation_html5.js',
        'type' => 'file',
      );
      $element['#element_validate'] = array(
        'geolocation_html5_field_widget_validate',
      );
      break;
  }
  return $element;
}

/**
 * Validation handler for geolocation_html5_field_widget_form().
 */
function geolocation_html5_field_widget_validate($element, &$form_state, $form) {
  if ($element['#required']) {
    if ($element['save']['#value'] && (!$element['lat']['#value'] || !$element['lng']['#value'])) {
      form_error($element, t('!name field is required. You may need to allow your browser detect your location.', array(
        '!name' => $element['#title'],
      )));
    }
  }
}

/**
 * Implements hook_field_widget_error().
 */
function geolocation_html5_field_widget_error($element, $error, $form, &$form_state) {
  switch ($error['error']) {
    case 'geolocation_invalid':
      form_error($element, $error['message']);
      break;
  }
}

/**
 * Implements hook_modernizr_info().
 */
function geolocation_html5_modernizr_info() {
  $tests = array();
  $tests[] = 'geolocation';
  return $tests;
}

/**
 * Helper function converts latitude to mercator value (Mercator projection).
 */
function _lat2mercator($latitude) {
  return log(tan($latitude * pi() / 180) + 1 / cos($latitude * pi() / 180));
}

/**
 * Helper function converts longitude pixel value for display in image map.
 */
function _geolocation_html5_lng2px($longitude, $leftLongitude, $width) {
  return fmod(($longitude - $leftLongitude + 360) / 360, 1) * $width;
}

/**
 * Helper function converts latitude pixel value for display in image map.
 */
function _geolocation_html5_lat2px($latitude, $topLatitude, $bottomLatitude, $height) {
  return (_lat2mercator($latitude) - _lat2mercator($bottomLatitude)) / (_lat2mercator($topLatitude) - _lat2mercator($bottomLatitude)) * $height;
}

Functions

Namesort descending Description
geolocation_html5_field_formatter_info Implements hook_field_formatter_info().
geolocation_html5_field_formatter_view Implements hook_field_formatter_view().
geolocation_html5_field_widget_error Implements hook_field_widget_error().
geolocation_html5_field_widget_form Implements hook_field_widget_form().
geolocation_html5_field_widget_info Implements hook_field_widget_info().
geolocation_html5_field_widget_validate Validation handler for geolocation_html5_field_widget_form().
geolocation_html5_modernizr_info Implements hook_modernizr_info().
_geolocation_html5_lat2px Helper function converts latitude pixel value for display in image map.
_geolocation_html5_lng2px Helper function converts longitude pixel value for display in image map.
_lat2mercator Helper function converts latitude to mercator value (Mercator projection).