Newer
Older
Brandon Bergren
committed
// $Id$
/**
* @file
* GMap Views: A Views Style plugin providing a GMap view.
*/
/**
* Implementation of hook_views_style_plugins().
*/
function gmap_views_views_style_plugins() {
return array(
'gmap' => array(
'name' => t('Gmap View'),
'theme' => 'views_view_gmap',
'needs_fields' => true,
'validate' => 'gmap_views_validate',
)
);
}
/**
* Implementation of hook_gmap().
*/
function gmap_views_gmap($op, &$map) {
switch ($op) {
case 'behaviors':
return array(
'fatmarkers' => array(
'title' => t('Views "fat" markers'),
'default' => FALSE,
'help' => t('Enabling this flag will pass the raw views data with a marker for use with custom manipulation code. Hook the preparemarker event to make use of this.'),
'internal' => TRUE,
),
);
Brandon Bergren
committed
case 'pre_theme_map':
// Don't pass the gmap_view settings to the client.
unset($map['settings']['gmap_view']);
break;
* GMap Views requires one of the following:
* - Location: Lat and Location: Lon
* - Two columns, one titled t('Latitude'), one titled t('Longitude')
* - A module that can transform a field into lat, long coordinates
$ids = _gmap_views_find_coords_ids($view);
if (!($ids['lat'] && $ids['lon']) && !(isset($ids['module']))) {
form_error($form["$type-info"][$type .'_type'],
t('GMap View requires: either "Location: Latitude" and "Location: Longitude" or a field titled "Latitude" and a field titled "Longitude"'));
}
return views_ui_plugin_validate_list($type, $view, $form);
}
/**
* Display the results of a view in a Google Map.
*/
function theme_views_view_gmap($view, $results) {
// Work when multiple views are displayed at once.
$mapid = "view_gmap_{$view->name}_{$view->build_type}";
// Fields are used to render the markers.
$fields = _views_get_fields();
// find the ids of the column we want to use
$point_ids = _gmap_views_find_coords_ids($view);
if (isset($view->gmap_macro) && $view->gmap_macro) {
Brandon Bergren
committed
$thismap = array(
'#map' => $mapid,
'#settings' => array_merge(gmap_defaults(), gmap_parse_macro($view->gmap_macro)),
Brandon Bergren
committed
);
if ($thismap['#settings']['behavior']['views_autocenter']) {
// Find the first valid location.
foreach ($results as $entry) {
$location = _gmap_views_get_lat_long_from_ids($entry, $point_ids);
if (($location['lat']) && ($location['lon'])) {
// Set default location for map
$thismap['#settings']['latitude'] = $location['lat'];
$thismap['#settings']['longitude'] = $location['lon'];
// Break loop because we have what we want.
break;
}
}
}
Brandon Bergren
committed
}
else if (!empty($view->gmap_map)) {
$thismap = $view->gmap_map;
Brandon Bergren
committed
}
else {
$thismap = array(
'#map' => $mapid,
Brandon Bergren
committed
'#settings' => gmap_defaults(),
);
}
$fatmarkers = (isset($thismap['#settings']['behavior']['fatmarkers']) && $thismap['#settings']['behavior']['fatmarkers']);
Brandon Bergren
committed
if ($fatmarkers) {
$thismap['#settings']['viewfields'] = $view->field;
Brandon Bergren
committed
$datafields = array();
foreach ($view->field as $field) {
Brandon Bergren
committed
if ($fields[$field['id']]['visible'] !== FALSE) {
$datafields[] = $field['queryname'];
}
Brandon Bergren
committed
}
Brandon Bergren
committed
}
$markermode = $thismap['#settings']['markermode'];
$markertypes = variable_get('gmap_node_markers', array());
Brandon Bergren
committed
$type = $entry->gmap_node_type;
$location = _gmap_views_get_lat_long_from_ids($entry, $point_ids);
Brandon Bergren
committed
if ($fatmarkers) {
Brandon Bergren
committed
$data = array();
Brandon Bergren
committed
foreach ($view->field as $field) {
if ($fields[$field['id']]['visible'] !== FALSE) {
$data[] = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $entry, $view);
}
Brandon Bergren
committed
}
Brandon Bergren
committed
$themarker = array(
'markername' => isset($markertypes[$type]) ? $markertypes[$type] : 'drupal',
Brandon Bergren
committed
'latitude' => $location['lat'],
'longitude' => $location['lon'],
Brandon Bergren
committed
'view' => array_values($data),
Brandon Bergren
committed
);
if (isset($entry->gmap_taxonomy_marker) && !empty($entry->gmap_taxonomy_marker)) {
$themarker['markername'] = $entry->gmap_taxonomy_marker;
}
Brandon Bergren
committed
else {
Brandon Bergren
committed
// Common
$themarker = array(
'markername' => isset($markertypes[$type]) ? $markertypes[$type] : 'drupal',
Brandon Bergren
committed
'latitude' => $location['lat'],
'longitude' => $location['lon']
);
if (isset($entry->gmap_taxonomy_marker) && !empty($entry->gmap_taxonomy_marker)) {
$themarker['markername'] = $entry->gmap_taxonomy_marker;
}
Brandon Bergren
committed
// Popup
Brandon Bergren
committed
// @@@ TODO: Switch to using views_theme sometime. Unfortunately, it changes the function prototype.. :-/
//$marker_popup = views_theme('gmap_views_marker_label', $view->name, $view, $fields, $entry);
$marker_popup = theme('gmap_views_marker_label', $view, $fields, $entry);
// add themed HTML to either text or tabs depending on whether or not
// it was an array.
if (is_array($marker_popup)) {
// Tabbed.
$themarker['tabs'] = $marker_popup;
Brandon Bergren
committed
$themarker['text'] = $marker_popup;
Brandon Bergren
committed
// Link
else if ($markermode == 2) {
$themarker['link'] = url('node/'. $entry->nid);
Brandon Bergren
committed
}
if (isset($entry->node_title)) {
$themarker['opts']['title'] = $entry->node_title;
}
Brandon Bergren
committed
$markers[] = $themarker;
}
/**
* Theme a marker label.
*/
function theme_gmap_views_marker_label($view, $fields, $entry) {
$marker_label = '';
foreach ($view->field as $field) {
$marker_label .= '<div class="gmap-popup '. $field['field'] .'">'. views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $entry, $view) .'</div>';
}
/**
* Helper function to find a valid latitude and longitude in this field
*/
function _gmap_views_find_coords_ids($view) {
$ids = array();
$copy = (array) $view;
foreach ($copy['field'] as $key => $field) {
if (!is_numeric($key)) {
continue; // skip the 'count', etc.
}
// we check to see if the field is a location:lat field or titled Latitude
if ($field['id'] == 'location.latitude' || $field['label'] == t('Latitude')) {
$ids['lat'] = $field['queryname'];
}
if ($field['id'] == 'location.longitude' || $field['label'] == t('Longitude')) {
$ids['lon'] = $field['queryname'];
}
// see if any module will take on the task of adding lat-lon to the view
foreach (module_implements('gmap_views_handle_field') as $module) {
if ($res = module_invoke($module, 'gmap_views_handle_field', 'discover', $field)) {
$ids['module'] = array(
'module' => $module,
'field' => $field['queryname'],
'extra' => $res,
);
}
}
}
return $ids;
}
/**
* Helper function to find actual lat and lon values from the work done in _gmap_views_find_coords_ids
*/
function _gmap_views_get_lat_long_from_ids($entry, $ids) {
// during the discovery phase, a module registered that it could turn this entry into a lat-lon array
if ($ids['module']) {
$ids['entry'] = $entry;
return module_invoke($ids['module']['module'], 'gmap_views_handle_field', 'process', $ids);
}
// standard stuff, we can handle it
return array('lat' => $entry->{$ids['lat']}, 'lon' => $entry->{$ids['lon']});
}
Brandon Bergren
committed
/**
* Implementation of hook_views_query_alter().
* We need to add in the node type so we can determine markers.
*/
function gmap_views_query_alter(&$query, &$view, $summary, $level) {
Brandon Bergren
committed
if (($view->page && $view->page_type == 'gmap') || ($view->block && $view->block_type == 'gmap')) {
Brandon Bergren
committed
$query->add_field('type', 'node', 'gmap_node_type');
if (module_exists('gmap_taxonomy')) {
$query->ensure_table('gmap_taxonomy_node');
$query->add_field('marker', 'gmap_taxonomy_node', 'gmap_taxonomy_marker');
}
Brandon Bergren
committed
}