You are here

public function location_handler_argument_location_proximity::query in Location 7.3

Same name and namespace in other branches
  1. 6.3 handlers/location_handler_argument_location_proximity.inc \location_handler_argument_location_proximity::query()
  2. 7.5 handlers/location_handler_argument_location_proximity.inc \location_handler_argument_location_proximity::query()
  3. 7.4 handlers/location_handler_argument_location_proximity.inc \location_handler_argument_location_proximity::query()

Set up the query for this argument.

The argument sent may be found at $this->argument.

Overrides views_handler_argument::query

File

handlers/location_handler_argument_location_proximity.inc, line 121
Location proximity argument handler.

Class

location_handler_argument_location_proximity

Code

public function query($group_by = FALSE) {

  // Get and process argument.
  if ($this->options['type'] == 'postal') {
    foreach ($this->view->argument as $argument) {
      if ($argument->field == 'distance') {
        $arg_parts = explode('_', $this->view->args[$argument->position]);
        if (count($arg_parts) == 3) {
          $this->value['country'] = drupal_strtolower($arg_parts[0]);
          $this->value['postal_code'] = $arg_parts[1];
          $this->value['search_distance'] = $arg_parts[2];
        }
        else {
          $this->value['postal_code'] = $arg_parts[0];
          $this->value['search_distance'] = $arg_parts[1];
        }
        break;
      }
    }
  }
  else {
    if ($this->options['type'] == 'latlon') {
      foreach ($this->view->argument as $argument) {
        if ($argument->field == 'distance') {
          list($coords, $this->value['search_distance']) = explode('_', $this->view->args[$argument->position]);
          list($this->value['latitude'], $this->value['longitude']) = explode(',', $coords);
          break;
        }
      }
    }
  }

  // Coordinates available?
  if (!$this
    ->calculate_coords()) {

    // Distance set?
    if (!empty($this->value['search_distance'])) {

      // Hmm, distance set but unable to resolve coordinates.
      // Force nothing to match.
      $this->query
        ->add_where(0, "1 = 0");
    }
    return;
  }
  $this
    ->ensure_my_table();
  $lat = $this->value['latitude'];
  $lon = $this->value['longitude'];

  // search_distance
  if ($this->options['search_units'] == 'dd') {
    list($lat_distance, $lon_distance) = explode(',', $this->value['search_distance']);
    $latrange[0] = $lat - $lat_distance;
    $latrange[1] = $lat + $lat_distance;
    $lonrange[0] = $lon - $lon_distance;
    $lonrange[1] = $lon + $lon_distance;
  }
  else {
    $distance = $this->value['search_distance'];
    if ($this->options['search_units'] == 'm') {
      $distance_meters = $distance;
    }
    else {
      $distance_meters = _location_convert_distance_to_meters($distance, $this->options['search_units']);
    }
    $latrange = earth_latitude_range($lon, $lat, $distance_meters);
    $lonrange = earth_longitude_range($lon, $lat, $distance_meters);
  }

  // Add MBR check (always).
  // In case we go past the 180/-180 mark for longitude.
  if ($lonrange[0] > $lonrange[1]) {
    $where = "{$this->table_alias}.latitude > :minlat AND {$this->table_alias}.latitude < :maxlat AND (({$this->table_alias}.longitude < 180 AND {$this->table_alias}.longitude > :minlon) OR ({$this->table_alias}.longitude < :maxlon AND {$this->table_alias}.longitude > -180))";
  }
  else {
    $where = "{$this->table_alias}.latitude > :minlat AND {$this->table_alias}.latitude < :maxlat AND {$this->table_alias}.longitude > :minlon AND {$this->table_alias}.longitude < :maxlon";
  }
  $this->query
    ->add_where_expression(0, $where, array(
    ':minlat' => $latrange[0],
    ':maxlat' => $latrange[1],
    ':minlon' => $lonrange[0],
    ':maxlon' => $lonrange[1],
  ));
  if ($this->options['search_method'] == 'dist') {

    // Add radius check.
    $this->query
      ->add_where_expression(0, earth_distance_sql($lon, $lat, $this->table_alias) . ' < :distance', array(
      ':distance' => $distance_meters,
    ));
  }
}