I wanted to zoom and center my map based on a postal code. In the process I also decided I wanted a proximity filter based on that same zipcode.... After a bit of learning, here is how. It shouldn't be too hard to adjust it to do what you want.

Some known issues:
- doesn't account for country yet (haven't tried either) - I think you can use $arg in the code to do this.
- doesn't validate postal code yet.

Some pre-req's
- you probably don't need this, but this issue #662892: (1=0) in query and Reworking of proximity filter handler to automatically geocode zipcodes (see comment #7) is a great replacement so that you don't need to update the zipcodes table manually. it looks new zipcodes up from google.

How To:
- create a argument with a type "Global: Null"
- select PHP code as a validator
- add the following code:

$lon = 0;
$lat = 0;
foreach ($view->display['page_1']->handler->handlers['filter'] as $k => $v) {
   if ($v->table == 'location' && $v->field == 'distance') {
      $v->value['postal_code'] = $argument;
      $v->query();
      $lon = $v->value['longitude'];
      $lat = $v->value['latitude']; 
 }
}

 $temp = $view->display_handler->get_option('style_options');
  $temp['macro'] = "[gmap |width=50% |center=" . $lat . "," . $lon . " |height=900px]";
  $view->display_handler->set_option('style_options',$temp);

return TRUE;

- the return TRUE determines if the argument validates, you might want to play with this to get your desired results.
- add a "Location: Proximity/Distance" filter.
- leave the defaults blank.
- hit the expose button
- change the "Form Mode" to Postal Code / Country
- save (or Update) the changes
- go back and "Hide" the exposed view.

That should do it.

Some hints:
- dsm($view) is a good way to debug in the php validator of the argument.

Comments

NigelC’s picture

I also want to change this so that I edit the existing gmap to just change what I want. That way it keeps the existing macro but just changes a part of it which would be much more user friendly. Especially if I want to change it from multiple arguments (ie my end goal is to have a different zoom level based on taxonomy and center based on postal code)

deviantintegral’s picture

Note that you don't create the PHP code as a validator, but as a default argument if it's not present.

NigelC’s picture

Well you could do other similar things using the default argument as php. But in my case I want the map centered around my argument... so what I said was correct, unless of course the default argument code always runs (but I suspect it only runs if the argument is not present).

jenlampton’s picture

My solution, based on the above:
- Add an argument of Global: Null
- Set "Action to take if argument is not present" to "Provide default argument"
- Set "Default argument type: to "Node ID from URL"
- Set "Validator" to "PHP code" as follows

$lon = 0;
$lat = 0;
if ($node = node_load($argument)){

  foreach ($view->display['panel_pane_1']->handler->handlers['filter'] as $k => $v) {
     if ($v->table == 'location' && $v->field == 'distance') {
        $v->value['postal_code'] = $node->location['postal_code'];
        $v->query();
        $lon = $v->value['longitude'];
        $lat = $v->value['latitude'];
    }
  }

  $temp = $view->display_handler->get_option('style_options');
  $temp['macro'] = "[gmap |width=250px |center=" . $lat . "," . $lon . " |height=350px]";
  $view->display_handler->set_option('style_options', $temp);
  return TRUE;
}

This takes the location from the node I'm on, and passes it in to the view.
I also cdded a filter for Location: distance / proximity as described above.

Adding a proximity filter (either exposed, or not exposed) always added an additional "AND (0)" to the query, which of course would then fail to return any results. I tracked the source down to this section of code in location_views_handler_filter_proximity.inc, on line 195:

// 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($this->options['group'], "0");
      }
      return;
    }

This code fires before the necessary values are passed in via arg handling code and adds the additional "AND (0)" before the correct where clause gets added. My short-term solution is to comment out the line that adds the additional query, but that's not a satisfactory long-term solution.

stella’s picture

Component: Documentation » Code
Category: task » feature

+1 for this. I don't need a proximity filter. I just need the ability to filter the view on an exposed Location field and have the view automatically zoom in to that area, e.g. enter in a province/state name and have the map zoom in to the selected state. Actually having the option between an autocomplete field and select drop-down for the province would also be very useful.

ljrweb’s picture

Im having a very similar issue where the map is not centering on the node... its a block view and i can see the correct marker-- but the map is centered somewhere else... so i found this post and tried to make it work but if i place:


if (isset($argument)) {
  return true;
} 

or another check on the argument-- it returns false..

also im using clean urls...

any help greatly appreciated!

thanks

ljrweb’s picture

update...

i was passing a node id in the url and wanted to center on that node location on the map..

i got there by slightly modifying the steps above--

but setting my argument to NID

and then putting the code in the validator as suggested above to override the macro..

thanks!

Pavlos-1’s picture

thanks

dsnopek’s picture

I'm a little unclear about what this code accomplishes: Does it center on the argument? Or the proximity filter?

Anyway, if anyone here is trying to center on the proximity filter, I just implemented a patch that adds an option to do so:

#1235932: Center on proximity filter (patch included!)

Best regards,
David.

jenlampton’s picture

Project: GMap Module » Location
Version: 6.x-1.x-dev » 6.x-3.1
Status: Active » Fixed

In the 6.x-3.1 version of this module and configuration described below, we no longer need to comment out any lines in location_views_handler_filter_proximity.inc.

Here's an update on how to get get center-and-zoom action with a proximity filter, without having to add a hack into the Argument validation PHP code section:

Create your view.
- Add an argument of Global: Null
- Set "Action to take if argument is not present" to "Provide default argument"
- Set "Default argument type" to "Node ID from URL"
- Set "Validator" to ""
- add a filter for "Location: Distance / Proximity"
- set the "Operator" to "Proximity (Circular)" - this may also work with rectangular
- set the "Origin" to "Node latitude / longitude from views nid argument"
- set the "Node ID argument to use" to "Global: Null"
- set the "Location to use" to "Node Location"
- set the "Distance" (I choose 5 miles)
- save (or Update and Save) the changes

Summit’s picture

Bookmarking, needing same solution for D7. Greetings, Martijn

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.