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; } } ?>