'lt'); $options['proximity']['radius_unit'] = array('default' => GEOFIELD_KILOMETERS); return $options; } /** * Add form elements to select options for this contextual filter. */ function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); $form['proximity'] = array( '#type' => 'fieldset', '#title' => t('Filter locations by proximity to a reference point'), ); $form['proximity']['operation'] = array( '#type' => 'select', '#title' => t('Select locations'), '#options' => array( 'lt' => t('Inside radius'), 'gt' => t('Outside radius'), ), '#default_value' => $this->options['operation'], '#description' => t("Reference point coordinates (lat,lon) and distance are typically appended to the URL. A fallback may be entered above under Provide default value as either a Fixed value or as PHP Code.
In all cases use this format: lat,lon distance. You may omit either lat,lon or distance. Instead of spaces and comma's, you can use underscores."), ); $form['proximity']['radius_unit'] = array( '#type' => 'select', '#title' => t('Unit of distance'), '#options' => array( GEOFIELD_KILOMETERS => t('kilometer'), GEOFIELD_MILES => t('mile'), ), '#default_value' => $this->options['radius_unit'], '#description' => t('Select the unit of distance.'), ); } /** * Set up the where clause for the contextual filter argument. */ function query($group_by = FALSE) { // Get and process arguments foreach ($this->view->argument as $argument) { if ($argument->field == 'field_geofield_distance') { // Expect and parse this format: "lat,lon dist" $arg_string = $this->view->args[$argument->position]; $args = array_filter(preg_split(GEOFIELD_PROXIMITY_REGEXP_PATTERN, $arg_string)); // Use next() on $args as after array_filter() we cannot be sure what the // element indices are. $lat = reset($args); $lon = next($args); $dist = next($args); if (count($args) == 3) { // we're good to proceed break; } // Either distance or lat,lon where omitted. See if we can get these // from either the Fixed or PHP Code default values. if (empty($this->options['default_argument_options'])) { // nope return; } $default = $this->options['default_argument_options']; if (!empty($default['argument'])) { $defaults = preg_split(GEOFIELD_PROXIMITY_REGEXP_PATTERN, $default['argument']); } elseif (!empty($default['code'])) { $defaults = preg_split(GEOFIELD_PROXIMITY_REGEXP_PATTERN, php_eval('')); } else { return; } $defaults = array_filter($defaults); if ($lat !== FALSE && $lon !== FALSE) { // 2 args received, interpret as lat,lon and take distrance from default if (empty($defaults) || count($defaults) == 2) { // expecting either 1 or 3 numbers return; } $dist = isset($defaults[2]) ? $defaults[2] : reset($defaults); break; } if ($lat !== FALSE && $lon === FALSE) { // 1 arg received, interpret as distance and take lat,lon from default $dist = $lat; $lat = reset($defaults); $lon = next($defaults); break; } // If we get here, we're dealing with rubbish return; } } $haversine_args = array( 'earth_radius' => $this->options['proximity']['radius_unit'], 'origin_latitude' => $lat, 'origin_longitude' => $lon, 'destination_latitude' => $this->table . '.' . $this->definition['field_name'] . '_lat', 'destination_longitude' => $this->table . '.' . $this->definition['field_name'] . '_lon', ); $formula = geofield_haversine($haversine_args); $operator = ($this->options['proximity']['operation'] == 'gt') ? '>' : '<'; $this->ensure_my_table(); $this->query->add_where_expression(0, "$formula $operator $dist"); } }