Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 103 additions & 46 deletions GeolocationPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,19 +135,47 @@ public function hookDefineAcl($args)
public function hookDefineRoutes($args)
{
$router = $args['router'];
$mapRoute = new Zend_Controller_Router_Route('items/map',
array('controller' => 'map',
'action' => 'browse',
'module' => 'geolocation'));
$router->addRoute('items_map', $mapRoute);

// Map based on an item to get all other items around.
$mapRoute = new Zend_Controller_Router_Route(
'items/map/:item_id/:page',
array(
'module' => 'geolocation',
'controller' => 'map',
'action' => 'browse',
'page' => 1,
),
array(
'item_id' => '\d+',
'page' => '\d+',
));
$router->addRoute('items_map_item', $mapRoute);

$mapRoute = new Zend_Controller_Router_Route(
'items/map/:pager/:page',
array(
'module' => 'geolocation',
'controller' => 'map',
'action' => 'browse',
'pager' => 'page',
'page' => 1,
),
array(
'pager' => 'page',
'page' => '\d+',
));
$router->addRoute('items_map_page', $mapRoute);

// Trying to make the route look like a KML file so google will eat it.
// @todo Include page parameter if this works.
$kmlRoute = new Zend_Controller_Router_Route_Regex('geolocation/map\.kml',
array('controller' => 'map',
'action' => 'browse',
'module' => 'geolocation',
'output' => 'kml'));
$kmlRoute = new Zend_Controller_Router_Route_Regex(
'geolocation/map\.kml',
array(
'module' => 'geolocation',
'controller' => 'map',
'action' => 'browse',
'output' => 'kml',
));
$router->addRoute('map_kml', $kmlRoute);
}

Expand Down Expand Up @@ -251,42 +279,73 @@ public function hookItemsBrowseSql($args)
{
$db = $this->_db;
$select = $args['select'];
$params = $args['params'];

$alias = $this->_db->getTable('Location')->getTableAlias();
if (!empty($args['params']['only_map_items'])
|| !empty($args['params']['geolocation-address'])
if (!empty($params['only_map_items'])
|| !empty($params['item_id'])
|| !empty($params['geolocation-address'])
) {
$select->joinInner(
array($alias => $db->Location),
"$alias.item_id = items.id",
array()
);
}
if (!empty($args['params']['geolocation-address'])) {

// Select all items around the selected one.
if (!empty($params['item_id'])) {
// TODO Use a sub-query?
$location = $db->getTable('Location')->findLocationByItem($params['item_id'], true);
if ($location) {
$params['geolocation-address'] = $location->address;
$params['geolocation-latitude'] = $location->latitude;
$params['geolocation-longitude'] = $location->longitude;
$params['geolocation-radius'] = isset($params['geolocation-radius'])
? $params['geolocation-radius']
: get_option('geolocation_default_radius');
$this->_selectItemsBrowseSql($select, $params);
}
}

elseif (!empty($params['geolocation-address'])) {
// Get the address, latitude, longitude, and the radius from parameters
$address = trim($args['params']['geolocation-address']);
$lat = trim($args['params']['geolocation-latitude']);
$lng = trim($args['params']['geolocation-longitude']);
$radius = trim($args['params']['geolocation-radius']);
$params['geolocation-address'] = trim($params['geolocation-address']);
$params['geolocation-latitude'] = trim($params['geolocation-latitude']);
$params['geolocation-longitude'] = trim($params['geolocation-longitude']);
$params['geolocation-radius'] = trim($params['geolocation-radius']);
// Limit items to those that exist within a geographic radius if an address and radius are provided
if ($address != ''
&& is_numeric($lat)
&& is_numeric($lng)
&& is_numeric($radius)
if ($params['geolocation-address'] != ''
&& is_numeric($params['geolocation-latitude'])
&& is_numeric($params['geolocation-longitude'])
&& is_numeric($params['geolocation-radius'])
) {
// SELECT distance based upon haversine forumula
if (get_option('geolocation_use_metric_distances')) {
$denominator = 111;
$earthRadius = 6371;
} else {
$denominator = 69;
$earthRadius = 3959;
}
$this->_selectItemsBrowseSql($select, $params);
}
}
}

$radius = $db->quote($radius, Zend_Db::FLOAT_TYPE);
$lat = $db->quote($lat, Zend_Db::FLOAT_TYPE);
$lng = $db->quote($lng, Zend_Db::FLOAT_TYPE);
/**
* Helper for hookItemsBrowseSql().
*/
private function _selectItemsBrowseSql($select, $params)
{
$db = $this->_db;

// Select distance based upon haversine forumula.
if (get_option('geolocation_use_metric_distances')) {
$denominator = 111;
$earthRadius = 6371;
} else {
$denominator = 69;
$earthRadius = 3959;
}

$lat = $db->quote($params['geolocation-latitude'], Zend_Db::FLOAT_TYPE);
$lng = $db->quote($params['geolocation-longitude'], Zend_Db::FLOAT_TYPE);
$radius = $db->quote($params['geolocation-radius'], Zend_Db::FLOAT_TYPE);

$select->columns(<<<SQL
$select->columns(<<<SQL
$earthRadius * ACOS(
COS(RADIANS($lat)) *
COS(RADIANS(locations.latitude)) *
Expand All @@ -296,23 +355,21 @@ public function hookItemsBrowseSql($args)
SIN(RADIANS(locations.latitude))
) AS distance
SQL
);
);

// WHERE the distance is within radius miles/kilometers of the specified lat & long
$select->where(<<<SQL
// WHERE the distance is within radius miles/kilometers of the specified lat & long
$select->where(<<<SQL
(locations.latitude BETWEEN $lat - $radius / $denominator AND $lat + $radius / $denominator)
AND
(locations.longitude BETWEEN $lng - $radius / $denominator AND $lng + $radius / $denominator)
SQL
);
);

// Actually use distance calculation.
//$select->having('distance < radius');
// Actually use distance calculation.
//$select->having('distance < radius');

//ORDER by the closest distances
$select->order('distance');
}
}
//ORDER by the closest distances
$select->order('distance');
}

/**
Expand Down Expand Up @@ -456,7 +513,7 @@ public function filterExhibitLayouts($layouts)
);
return $layouts;
}

public function filterApiImportOmekaAdapters($adapters, $args)
{
$geolocationAdapter = new ApiImport_ResponseAdapter_Omeka_GenericAdapter(null, $args['endpointUri'], 'Location');
Expand Down Expand Up @@ -510,7 +567,7 @@ public function geolocationShortcode($args)

if (isset($args['tags'])) {
$options['params']['tags'] = $args['tags'];
}
}

$pattern = '#^[0-9]*(px|%)$#';

Expand Down Expand Up @@ -550,7 +607,7 @@ protected function _mapForm($item, $label = 'Find a Location by Address:', $conf
$post = $_POST;
}

$usePost = !empty($post)
$usePost = !empty($post)
&& !empty($post['geolocation'])
&& $post['geolocation']['longitude'] != ''
&& $post['geolocation']['latitude'] != '';
Expand Down
22 changes: 14 additions & 8 deletions controllers/MapController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,36 @@ public function init()
{
$this->_helper->db->setDefaultModelName('Item');
}

public function browseAction()
{
$table = $this->_helper->db->getTable();
$locationTable = $this->_helper->db->getTable('Location');

$params = $this->getAllParams();
$params['only_map_items'] = true;
$limit = (int) get_option('geolocation_per_page');
$currentPage = $this->getParam('page', 1);

// Only get pagination data for the "normal" page, only get
// item/location data for the KML output.
// Only get item/location data for the KML output.
if ($this->_helper->contextSwitch->getCurrentContext() == 'kml') {
$items = $table->findBy($params, $limit, $currentPage);
$this->view->items = $items;
$this->view->locations = $locationTable->findLocationByItem($items);
} else {
}
// Only get pagination data for the "normal" page.
else {
$item_id = $this->getParam('item_id');
if (!empty($item_id)) {
$this->view->item = get_record_by_id('Item', $item_id);
$this->view->location = $locationTable->findLocationByItem($item_id, true);
}
$this->view->totalItems = $table->count($params);
$this->view->params = $params;

$pagination = array(
'page' => $currentPage,
'per_page' => $limit,
'page' => $currentPage,
'per_page' => $limit,
'total_results' => $this->view->totalItems
);
Zend_Registry::set('pagination', $pagination);
Expand Down
18 changes: 15 additions & 3 deletions views/public/map/browse.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
<?php
<?php
queue_css_file('geolocation-items-map');

$title = __('Browse Items on the Map') . ' ' . __('(%s total)', $totalItems);
$center = array();
if (isset($item)) {
$radius = isset($params['geolocation-radius']) ? $params['geolocation-radius'] : get_option('geolocation_default_radius');
$unit = get_option('geolocation_use_metric_distances') ? __('kilometers') :__('miles');
$title = __('Browse Items around Item "%s" (%d total, %s %s radius)', link_to_item(null, array(), 'show', $item), $totalItems, $radius, $unit);
$center['latitude'] = (double) $location->latitude;
$center['longitude'] = (double) $location->longitude;
$center['zoomLevel'] = (double) get_option('geolocation_default_zoom_level');
}
else {
$title = __('Browse Items on the Map (%s total)', $totalItems);
}

echo head(array('title' => $title, 'bodyclass' => 'map browse'));
?>

Expand All @@ -17,7 +29,7 @@
?>

<div id="geolocation-browse">
<?php echo $this->googleMap('map_browse', array('list' => 'map-links', 'params' => $params)); ?>
<?php echo $this->googleMap('map_browse', array('list' => 'map-links', 'params' => $params), array(), $center); ?>
<div id="map-links"><h2><?php echo __('Find An Item on the Map'); ?></h2></div>
</div>

Expand Down