You are here

public function IpGeoLocViewsPluginStyle::pluginStyleExtractLatLng in IP Geolocation Views & Maps 8

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.

string $loc_field_value: Pending doc.

Return value

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

1 call to IpGeoLocViewsPluginStyle::pluginStyleExtractLatLng()
IpGeoLocViewsPluginStyle::pluginStyleExtractLocations in src/Services/IpGeoLocViewsPluginStyle.php
Extract an array of locations from the supplied views_plugin_style.

File

src/Services/IpGeoLocViewsPluginStyle.php, line 860

Class

IpGeoLocViewsPluginStyle
Class IpGeoLocViewsPluginStyle.

Namespace

Drupal\ip_geoloc\Services

Code

public function pluginStyleExtractLatLng($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.
  // @TODO review is this is needed for drupal 8

  /*foreach ((array) $row as $key => $value) {
    if (Unicode::substr($key, -6) == '_delta' && strpos($key, 'field_data_field_') === 0) {
    $delta = $value;
    break;
    }
    }*/
  $row = $row->_entity;
  $field_name = $latitude;
  $field_value = $row
    ->get($field_name)
    ->getValue();

  // @TODO check the count function for multivalued locations
  if (!isset($delta) || !$row
    ->get($field_name)
    ->isEmpty() || $delta >= count($field_value)) {
    $delta = 0;
  }
  $location = new \StdClass();
  $base = $this
    ->pluginStyleGetBase2($row, $field_name, $delta);
  if (empty($base)) {

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

    // @TODO check location module
    // 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.
      $moduleHandler = \Drupal::service('module_handler');
      if ($moduleHandler
        ->moduleExists('leaflet')) {
        $leafletSevice = \Drupal::service('leaflet.service');

        // leaflet.service
        // 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['value'];
        }
        $location = $leafletSevice
          ->leafletProcessGeofield([
          $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 = Unicode::substr(trim($point), 0, 7) == 'POINT (';
          if ($is_point) {
            $parts = explode(' ', Unicode::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;
}