getPhpVm();
$itemId = GalleryUtilities::getRequestVariables('itemId');
list ($ret, $item) = GalleryCoreApi::loadEntitiesById($itemId);
if ($ret) {
return array($ret->wrap(__FILE__, __LINE__), null);
}
list ($ret, $placemarks) = GoogleEarthView::_createGETree($item, array(), array());
if ($ret) {
return array($ret->wrap(__FILE__, __LINE__), null);
}
if (!empty($placemarks)) {
$outstring = ''
. ''
. "\nGallery21\n"
. '' . "\n"
. '' . "\n"
. '' . "\n"
. 'normal#PhotoIconNormal' . "\n"
. 'highlight#PhotoIconHighlight'
. "\n" . $placemarks . "\n\n";
$phpVm->header('Content-Type: application/vnd.google-earth.kml+xml');
$phpVm->header('Content-Description: View Gallery items in Google Earth');
$phpVm->header("Content-Disposition: inline; filename=GalleryGE-{$itemId}.kml");
$phpVm->header('Content-Length: ' . strlen($outstring));
echo $outstring;
} else {
/* Should probably return some error that no child elements had valid GPS coordinates */
}
return null;
}
/*
* Recursive function to generate the Folder and Placemark elements to represent the albums
* and items that have GPS coordinates set.
*
* param GalleryItem $item the current item/album to process
* param array $data array of arrays (keyed by itemID) of field data (keyed by field name)
* associated with the $item (e.g., GPS coordinates)
* param array $ancestors list of parent item IDs already processed (to prevent infinite loops)
*
* returns string KML subelements: folder(s) and/or placemark(s)
*/
function _createGETree($item, $data, $ancestors) {
GalleryCoreApi::requireOnce('modules/map/classes/mapHelper.class');
$returnstring = ''; /* start with a blank string */
if (empty($data)) { /* workaround for first call if no field data passed */
list ($ret, $data) = mapHelper::fetchFieldValues(array($item));
}
/* If it's an album or similar */
if ($item->getCanContainChildren()) {
/* Get all the direct children of this item, in album sort order */
list ($ret, $childIds) = GalleryCoreApi::fetchChildItemIds($item);
if ($ret) {
return array($ret->wrap(__FILE__, __LINE__), null);
}
/* If the list of direct children wasn't empty */
if (!empty($childIds)) {
/* If we haven't already included this item in a parent folder */
if (!array_search($item->getId(), $ancestors)) {
/* Add ourselves to the ancestors array */
$ancestors[] = $item->getId();
/* Load the children */
list ($ret, $childItems) = GalleryCoreApi::loadEntitiesById($childIds);
if ($ret) {
return array($ret->wrap(__FILE__, __LINE__), null);
}
/* Grab the field data for the child items */
list ($ret, $fielddata) = mapHelper::fetchFieldValues($childItems);
if ($ret) {
return array($ret->wrap(__FILE__, __LINE__), null);
}
foreach ($childItems as $childItem) {
/* Recurse into this function with the next level down */
list ($ret, $childstring) =
GoogleEarthView::_createGETree($childItem, $fielddata, $ancestors);
if ($ret) {
return array($ret->wrap(__FILE__, __LINE__), null);
}
$returnstring .= $childstring;
}
/*
* Only add containing folder info if there are child elements or if the folder
* has coordinates of its own.
*/
if (!empty($returnstring) or !empty($data[$item->getId()]['GPS'])) {
$coordstring = (!empty($data[$item->getId()]['GPS']))
? $data[$item->getId()]['GPS']
: '';
$LookAtstring = (!empty($data[$item->getId()]['GELookAt']))
? $data[$item->getId()]['GELookAt']
: '';
$returnstring = ''
. GoogleEarthView::_createTextElements($item)
. GoogleEarthView::_createLookAtBlock($coordstring, $LookAtstring)
. $returnstring . "\n";
}
}
}
}
else { /* It's not a container item */
if (GalleryUtilities::isA($item, 'GalleryDataItem')) {
list ($ret, $childitemstring) =
GoogleEarthView::_createGEChildItem($item, $data[$item->getId()]);
if ($ret) {
return array($ret->wrap(__FILE__, __LINE__), null);
}
$returnstring .= $childitemstring;
}
}
return array(null, $returnstring);
}
/*
* Create name, Snippet and description elements single Placemark element
*
* param GalleryItem $item the current GalleryDataItem for which to generate text elements
*
* return string name, Snippet and description elements for the item, properly CDATA-escaped
*
*/
function _createTextElements($item) {
$returnstring = '';
GalleryCoreApi::requireOnce('lib/smarty_plugins/modifier.entitytruncate.php');
/* Get the item title if not blank, else use the file/directory name (path component) */
$title = $item->getTitle() ? $item->getTitle() : $item->getPathComponent();
/* Use the item summary for the Snippet, otherwise use the item description */
$summstring = $item->getSummary()
? GalleryUtilities::markup($item->getSummary(), 'strip')
: smarty_modifier_entitytruncate(
GalleryUtilities::markup($item->getDescription(), 'strip'),
80);
/** @todo If/when KML officially supports HTML in Snippet blocks, remove the 'strip' */
$returnstring = '\ngetSummary()
? GalleryUtilities::markup($item->getSummary()) . "
\n"
: '')
. GoogleEarthView::_createThumbnailLink($item)
. GalleryUtilities::markup($item->getDescription())
. ']]>' . $summstring . "\n";
return $returnstring;
}
/*
* Create a single Placemark element
*
* param GalleryItem $item the current GalleryDataItem to represent in a Placemark
* param array $fielddata field data associated with the $item
*
* return string KML placemark element
*
*/
function _createGEChildItem($item, $fielddata) {
$goodcoords = false;
$returnstring = '';
/* Select items that have GPS coordinates filled out */
if (!empty($fielddata['GPS'])) {
$posxy = explode(',', $fielddata['GPS']);
if (count($posxy) >= 2) { /* changed to >= 2 to accommodate possible elevation field */
$lat = (float)$posxy[0];
$lon = (float)$posxy[1];
$goodcoords = ((abs($lat) < 90) and (abs($lat) < 180));
}
}
if ($goodcoords) {
$coord = sprintf('%s,%s', $posxy[1], $posxy[0]);
/* This spot is one of the weird ones that wants longitude listed first */
$point = "clampToGround\n"
. $coord . ",0\n\n";
/* Output Placemark to Google Earth */
$coordstring = (!empty($fielddata['GPS'])) ? $fielddata['GPS'] : '';
$LookAtstring = (!empty($fielddata['GELookAt'])) ? $fielddata['GELookAt'] : '';
$returnstring .= ''
. GoogleEarthView::_createTextElements($item)
. "#PhotoIconPair\n" . $point
. GoogleEarthView::_createLookAtBlock($coordstring, $LookAtstring)
. "\n";
}
return array(null, $returnstring);
}
/*
* Create a LookAt block to apply to a folder or placemark
*
* param string $GPSstring the GPS coordinates in latitude,longitude format
* param string $LookAtstring the Google Earth LookAt parameters in heading,tilt,range format
*
* returns string KML LookAt block
*
*/
function _createLookAtBlock($GPSstring, $LookAtstring) {
$headingstr = "0";
$tiltstr = "45";
$rangestr = "3000";
$returnstring = '';
$goodcoords = false;
$posxy = array();
if (!empty($GPSstring)) {
$posxy = explode(',', $GPSstring);
if (count($posxy) >= 2) { /* changed to >= 2 to accommodate possible elevation field */
$lat = (float)$posxy[0];
$lon = (float)$posxy[1];
$goodcoords = ((abs($lat) < 90) and (abs($lon) < 180));
}
}
/*
* Use sprintf and %F to force non-locale-aware float printing to avoid inadvertant
* commas in the float values. Limit decimal places for range, tilt, heading. If %F is
* not supported (PHP 4.3.9 or 5.0.2 or earlier), fall back to the raw string.
*/
if ($goodcoords) {
/* Parse the 'GELookAt' field */
if (!empty($LookAtstring)) {
$lookat = explode(',', $LookAtstring);
/*
* If at least one parameter, then #1 is the heading in degrees.
* Must be between 0 and 360 degrees
*/
if (count($lookat) >= 1 and !empty($lookat[0])
and $lookat[0] >= -360 and $lookat[0] <= 360) {
$heading = (float)$lookat[0];
$headingstr = sprintf('%.2F', $heading) == '' ? $lookat[0]
: sprintf('%.2F', $heading);
}
/*
* If at least two parameters, then #2 is the tilt in degrees.
* Must be between 0 and 90 degrees
*/
if (count($lookat) >= 2 and !empty($lookat[1])
and $lookat[1] >= 0 and $lookat[1] <= 90) {
$tilt = (float)$lookat[1];
$tiltstr = sprintf('%.2F', $tilt) == '' ? $lookat[1]
: sprintf('%.2F', $tilt);
}
/* If at least three parameters, then #3 is the range in meters. Must be > 0 */
if (count($lookat) >= 3 and !empty($lookat[2]) and $lookat[2] > 0) {
$range = (float)$lookat[2];
$rangestr = sprintf('%.2F', $range) == '' ? $lookat[2]
: sprintf('%.2F', $range);
}
}
$lonstr = $posxy[1];
$latstr = $posxy[0];
$returnstring = sprintf('%s%s'
. '%s%s%s',
$lonstr, $latstr, $rangestr, $tiltstr, $headingstr)
. "\n";
}
return $returnstring;
}
/*
* Create an HTML snippet to display the thumbnail for an item and create a link to the gallery
* item
*
* param GalleryItem $item the current GalleryDataItem to represent in a Placemark
*
* returns string HTML snippet suitable for inclusion in a CDATA-escaped description element
*
*/
function _createThumbnailLink($item) {
$hsitemLink = '';
$dthumbLink = '';
global $gallery;
$urlGenerator =& $gallery->getUrlGenerator();
$returnstring = '';
$theid = $item->getId();
/* Get the thumbnail item ID for the item */
list ($ret, $thumbs) = GalleryCoreApi::fetchThumbnailsByItemIds(array($theid));
$thumbId = $thumbs[$theid]->getId();
$dthumbLink = $urlGenerator->generateUrl(
array('view' => 'core.DownloadItem', 'itemId' => $thumbId),
array('forceFullUrl' => true, 'htmlEntities' => false));
$hsitemLink = $urlGenerator->generateUrl(
array('view' => 'core.ShowItem', 'itemId' => $theid),
array('forceFullUrl' => true, 'htmlEntities' => false));
if ($hsitemLink != '' and $dthumbLink != '') {
$returnstring = '\n
';
}
return $returnstring;
}
}
?>