You are here

function _ip_geoloc_plugin_style_extract_lat_lng in IP Geolocation Views & Maps 8

Same name and namespace in other branches
  1. 7 views/ip_geoloc_plugin_style.inc \_ip_geoloc_plugin_style_extract_lat_lng()

Extract coordinates from the View result row.

@todo This function is in flux and a bit messy at the moment....

Parameters

array $row: View result row.

string $latitude: Name of the row field that holds latitude.

string $longitude: Name of the row field that holds longitude.

Return value

object|null Location -- @todo return array for consistency with Leaflet?

1 call to _ip_geoloc_plugin_style_extract_lat_lng()
ip_geoloc_plugin_style_extract_locations in src/Plugin/views/style/ip_geoloc_plugin_style.inc
Extract an array of locations from the supplied views_plugin_style.

File

src/Plugin/views/style/ip_geoloc_plugin_style.inc, line 784
ip_geoloc_plugin_style.inc

Code

function _ip_geoloc_plugin_style_extract_lat_lng(array $row, $latitude, $longitude, $loc_field_value = NULL) {
  $delta =& drupal_static(__FUNCTION__);
  if (isset($delta)) {
    $delta++;
  }

  // Hack for http://drupal.org/node/1824538
  // In the View, AddressField must have "Display all values in the same row"
  // UNTICKED, while Geofield (and all other fields) must have it TICKED.
  foreach ((array) $row as $key => $value) {
    if (drupal_substr($key, -6) == '_delta' && strpos($key, 'field_data_field_') === 0) {
      $delta = $value;
      break;
    }
  }
  $field_name = 'field_' . $latitude;
  if (!isset($delta) || !isset($row->{$field_name}) || $delta >= count($row->{$field_name})) {
    $delta = 0;
  }
  $location = new stdClass();
  $base = _ip_geoloc_plugin_style_get_base2($row, $field_name, $delta);
  if (empty($base)) {

    // Drop the "field_" prefix and try again.
    $base = _ip_geoloc_plugin_style_get_base2($row, $latitude, $delta);
  }
  if (empty($base)) {
    $base = $loc_field_value;
  }
  if (empty($base)) {

    // Empty $base, e.g. Location module.
    if (isset($row->{$latitude}) && isset($row->{$longitude})) {

      // If not node fields then db table fields...
      $location->latitude = $row->{$latitude};
      $location->longitude = $row->{$longitude};
    }
  }
  else {
    if (is_string($base)) {

      // Expect a rendered result like "Latitude: -37.8<br/>Longitude: 144.96".
      $parts = explode(':', $base);
      if (isset($parts[2])) {
        $location->latitude = (double) $parts[1];
        $location->longitude = (double) $parts[2];
      }
    }
    elseif (isset($base['geo_type'])) {

      // Geofield.
      // Quick fix: take advantage of Leaflet module, if enabled.
      // @todo generalise Leaflet code and incorporate here.
      if (function_exists('leaflet_process_geofield')) {

        // Support WKT lines and polygons in Leaflet. Call requires:
        // $base['geo_type'] eg 'point' or 'linestring'
        // $base['geom'] eg. 'POINT(145 -37)' or 'LINESTRING(145 -37, 146, -38)'.
        if (!isset($base['wkt'])) {

          // Until fixed in leaflet_process_geofield().
          $base['wkt'] = $base['geom'];
        }
        $location = leaflet_process_geofield([
          $base,
        ]);
        $location = (object) reset($location);

        // @todo get rid of this duality, use lat/lon throughout
        if (isset($location->lat)) {
          $location->latitude = $location->lat;
          unset($location->lat);
        }
        if (isset($location->lon)) {
          $location->longitude = $location->lon;
          unset($location->lon);
        }
      }
      else {
        $is_point = $base['geo_type'] == 'point';
        if ($is_point) {

          // Wkt more accurate than lat,lon in Geofield 7.x-1.x.
          $point = empty($base['geom']) ? $base['wkt'] : $base['geom'];

          // @todo Consider using the following:
          // $geometry = geoPHP::load($base['geom']);
          // $location = json_decode($geometry->out('json'));
          $is_point = drupal_substr(trim($point), 0, 7) == 'POINT (';
          if ($is_point) {
            $parts = explode(' ', drupal_substr($point, 7));
            $is_point = count($parts) > 1;
          }
        }

        // $is_point==FALSE may indicate a MULTIPOINT cluster, which has its
        // averaged center on 'lat' and 'lon' indices.
        $location->longitude = $is_point ? (double) $parts[0] : $base['lon'];
        $location->latitude = $is_point ? (double) $parts[1] : $base['lat'];
      }
    }
    elseif (isset($base['lng'])) {

      // GeoLocation.
      $location->latitude = $base['lat'];
      $location->longitude = $base['lng'];
    }
    elseif (isset($base['longitude'])) {

      // Get Locations.
      $location->latitude = $base['latitude'];
      $location->longitude = $base['longitude'];
    }
    elseif (isset($row->{'field_' . $latitude}[$delta]['raw']['value'])) {

      // Other module.
      // Field values tend to be inside ...[0]['raw']['value']:
      $location->latitude = $row->{'field_' . $latitude}[$delta]['raw']['value'];
      $location->longitude = $row->{'field_' . $longitude}[$delta]['raw']['value'];
    }
  }
  return isset($location->type) || isset($location->latitude) ? $location : NULL;
}