diff -Nuar /var/www/304.ru/drupal/htdocs/gallery2/modules/map/classes/FOWCalculator.class map/classes/FOWCalculator.class --- /var/www/304.ru/drupal/htdocs/gallery2/modules/map/classes/FOWCalculator.class 1970-01-01 03:00:00.000000000 +0300 +++ map/classes/FOWCalculator.class 2010-02-22 15:51:15.000000000 +0300 @@ -0,0 +1,21 @@ + Array(36,24), + 'Canon EOS 40D' => Array(22.2,14.8), + 'Canon EOS 400D' => Array(22.2,14.8), + ); + + if (!isset($FOWCalculatorSensors[$model])) + $model = 'Full frame 35mm matrix'; + if ($width > $height && $FOWCalculatorSensors[$model][0]>$FOWCalculatorSensors[$model][1]) + $orientation = 0; + else + $orientation = 1; + return rad2deg(2*atan($FOWCalculatorSensors[$model][$orientation]/2/$focalLength)); + } +} diff -Nuar /var/www/304.ru/drupal/htdocs/gallery2/modules/map/classes/GoogleMapUtilities.class map/classes/GoogleMapUtilities.class --- /var/www/304.ru/drupal/htdocs/gallery2/modules/map/classes/GoogleMapUtilities.class 2010-02-28 15:52:59.000000000 +0300 +++ map/classes/GoogleMapUtilities.class 2010-02-28 14:22:31.000000000 +0300 @@ -33,6 +33,7 @@ GalleryCoreApi::requireOnce('modules/map/includes/toolkit/JPEG.php'); GalleryCoreApi::requireOnce('modules/map/includes/toolkit/EXIF.php'); +GalleryCoreApi::requireOnce('modules/map/classes/FOWCalculator.class'); class GoogleMapUtilities { @@ -483,11 +484,13 @@ if (!$jpeg_header_data) { $coords = null; } else { - $temp = @get_EXIF_JPEG($filename); + $temp = @get_EXIF_JPEG($filename); $Latitude = ''; $Longitude = ''; $NorthSouth = ''; $EastWest = ''; + $DirectionRef = ''; + $Direction = ''; if (is_array($temp[0])) { foreach ($temp[0] as $id => $data) { if (is_array($data) and array_key_exists('Tag Name', $temp[0][$id]) @@ -509,6 +512,18 @@ } if (is_array($data) and array_key_exists('Tag Name', $gpsdata[$id2]) + and ($gpsdata[$id2]['Tag Name'] + == 'Reference for Direction of Image')) { + $DirectionRef = $gpsdata[$id2]['Data'][0]; + } + if (is_array($data) + and array_key_exists('Tag Name', $gpsdata[$id2]) + and ($gpsdata[$id2]['Tag Name'] + == 'Direction of Image')) { + $Direction = $gpsdata[$id2]['Data'][0]['Numerator']/$gpsdata[$id2]['Data'][0]['Denominator']; + } + if (is_array($data) + and array_key_exists('Tag Name', $gpsdata[$id2]) and ($gpsdata[$id2]['Tag Name'] == 'Latitude')) { $lat = $gpsdata[$id2]['Data']; $Latitude = ($lat[0]['Numerator'] / $lat[0]['Denominator']) @@ -547,6 +562,20 @@ $Latitude = str_replace(',', '.', $Latitude); $Longitude = str_replace(',', '.', $Longitude); + if (trim($DirectionRef) == 'M') { + // TODO direction should be recalculated to real north instead of magnetic north + } + if ($Direction === '') + $Direction = null; + // Calculate angle (field) of view. We need focal length and camera model, because different cameras have diferent sensor size + if (isset($temp[0][34665]['Data'][0][37386]) && isset($temp[0][272]) && isset($temp[0][34665]['Data'][0][40962]) && isset($temp[0][34665]['Data'][0][40963])) { + $FOW = FOWCalculator::getFOW($temp[0][34665]['Data'][0][40962]['Data'][0], + $temp[0][34665]['Data'][0][40963]['Data'][0], + $temp[0][34665]['Data'][0][37386]['Data'][0]['Numerator']/ + $temp[0][34665]['Data'][0][37386]['Data'][0]['Denominator'], $temp[0][272]['Data'][0]); + } else { + $FOW = null; + } } if ($Latitude != '' and $Longitude != '') { @@ -558,7 +587,7 @@ } else { /* this is a directory, no EXIF actions */ $coords = null; } - return array(null, $coords); + return array(null, $coords, $Direction, $FOW); } @@ -634,4 +663,4 @@ } return array ($Sizes, $preload); } -} \ В конце файла нет новой строки +} diff -Nuar /var/www/304.ru/drupal/htdocs/gallery2/modules/map/classes/mapHelper.class map/classes/mapHelper.class --- /var/www/304.ru/drupal/htdocs/gallery2/modules/map/classes/mapHelper.class 2010-02-28 15:52:59.000000000 +0300 +++ map/classes/mapHelper.class 2010-02-28 14:24:01.000000000 +0300 @@ -66,6 +66,7 @@ } $isContainer = false; } + foreach ($sets as $set) { $result[$set] = array(); foreach ((!empty($param[$set]) ? explode('|', $param[$set]) : array()) as $tmp) { @@ -272,7 +273,7 @@ * @static */ function saveFieldValues(&$item, $fields) { - $set = (GalleryUtilities::isA($item, 'GalleryAlbumItem')) + $set = (GalleryUtilities::isA($item, 'GalleryAlbumItem')) ? 1 : ((GalleryUtilities::isA($item, 'GalleryPhotoItem')) ? 2 @@ -290,7 +291,8 @@ return $ret->wrap(__FILE__, __LINE__); } foreach ($fields as $field => $value) { - if (!empty($value)) { + // 0 is a correct value + if ($value !== "" && $value !== null && $value !== array()) { $ret = GalleryCoreApi::addMapEntry('mapMap', array('itemId' => $item->getId(), 'field' => $field, 'value' => $value, 'setId' => $isContainer ? $containerId : 0, 'setType' => $set)); @@ -322,13 +324,17 @@ if ($event->getEventName() == 'GalleryEntity::save') { $item = $event->getEntity(); if ($item->getEntityType() == 'GalleryPhotoItem') { - list ($ret, $coords) = GoogleMapUtilities::getGPSCoordsFromExif($item); + list ($ret, $coords, $direction, $FOW) = GoogleMapUtilities::getGPSCoordsFromExif($item); if ($ret) { return array($ret->wrap(__FILE__, __LINE__), null); } if ($coords != null) { $fields['GPS'] = $coords; + if (isset($direction)) + $fields['direction'] = $direction; + if (isset($FOW)) + $fields['FOW'] = $FOW; $ret = mapHelper::saveFieldValues($item, $fields); if ($ret) { return $ret->wrap(__FILE__, __LINE__); diff -Nuar /var/www/304.ru/drupal/htdocs/gallery2/modules/map/classes/PopulateGPSEXIFInfos.class map/classes/PopulateGPSEXIFInfos.class --- /var/www/304.ru/drupal/htdocs/gallery2/modules/map/classes/PopulateGPSEXIFInfos.class 2010-02-28 15:52:59.000000000 +0300 +++ map/classes/PopulateGPSEXIFInfos.class 2010-02-22 15:31:06.000000000 +0300 @@ -88,7 +88,7 @@ return array($ret->wrap(__FILE__, __LINE__), null); } - list ($ret, $coords) = GoogleMapUtilities::getGPSCoordsFromExif($item); + list ($ret, $coords, $direction, $FOW) = GoogleMapUtilities::getGPSCoordsFromExif($item); if ($ret) { return array($ret->wrap(__FILE__, __LINE__), null); } @@ -96,6 +96,10 @@ if ($coords != null) { list ($ret, $fields) = mapHelper::fetchFieldValues(array($item)); $fields[$id]['GPS'] = $coords; + if (isset($direction)) + $fields['direction'] = $direction; + if (isset($FOW)) + $fields['FOW'] = $FOW; $ret = mapHelper::saveFieldValues($item, $fields[$id]); if ($ret) { return $ret->wrap(__FILE__, __LINE__); diff -Nuar /var/www/304.ru/drupal/htdocs/gallery2/modules/map/classes/WriteExifHeaderToPictures.class map/classes/WriteExifHeaderToPictures.class --- /var/www/304.ru/drupal/htdocs/gallery2/modules/map/classes/WriteExifHeaderToPictures.class 2010-02-28 15:52:59.000000000 +0300 +++ map/classes/WriteExifHeaderToPictures.class 2010-02-22 15:31:44.000000000 +0300 @@ -107,13 +107,14 @@ foreach ($items as $item) { /* Check if EXIF Header exist */ - list ($ret, $coords) = GoogleMapUtilities::getGPSCoordsFromExif($item); + list ($ret, $coords, $direction, $FOW) = GoogleMapUtilities::getGPSCoordsFromExif($item); if ($ret) { return array($ret, null); } if ($coords == null) { /* there are no existing GPS coords in the header, proceed */ + // TODO Write direction information too if (array_key_exists($item->getId(), $coorddata) && trim($coorddata[$item->getId()]['GPS']) != '') { list($ret, $error, $status, $other) = GoogleMapUtilities::setGPSCoordsInExif($item, $coorddata[$item->getId()]['GPS']); diff -Nuar /var/www/304.ru/drupal/htdocs/gallery2/modules/map/GoogleEarth.inc map/GoogleEarth.inc --- /var/www/304.ru/drupal/htdocs/gallery2/modules/map/GoogleEarth.inc 2010-02-28 15:52:59.000000000 +0300 +++ map/GoogleEarth.inc 2010-02-28 14:33:06.000000000 +0300 @@ -100,7 +100,8 @@ . "\nGallery21\n" . '' . "\n" + . '6600bcff' + . '8800bcff4' . "\n" . '' . "\n" @@ -240,6 +241,26 @@ } /* + * Generate coordinates of a point, located at distance from center on azimuth angle + * + * param center Geographical coordinates of initial point. Array, latitude is 0, longitude is 1 + * param angle Azimuth in degrees + * param distance Distance in degrees of merkaror projection + * + * return Coordinates. Array, latitude is 0, longitude is 1 + * + */ + function _getAngleStep ($center, $angle, $distance) { + // Frst we need to move to merkator projection, because it saves angles of small objects. Spherical mercator is used + $center[0] = rad2deg(log(tan(M_PI/4+deg2rad($center[0])/2))); + $result[0] = $center[0] + $distance*cos(deg2rad($angle)); + $result[1] = $center[1] + $distance*sin(deg2rad($angle)); + // Now we move back to geographical coordinates + $result[0] = rad2deg((2 * atan(exp(deg2rad($result[0]))) - M_PI/2)); + return $result; + } + + /* * Create a single Placemark element * * param GalleryItem $item the current GalleryDataItem to represent in a Placemark @@ -263,10 +284,31 @@ } if ($goodcoords) { + // Needed for locales, where decimal separator is comma + setlocale(LC_NUMERIC, 'C'); $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"; + $point = "clampToGround\n" + . $coord . ",0\n"; + + if (isset($fielddata['direction']) && is_numeric($fielddata['direction']) && $fielddata['direction'] >= 0 && $fielddata['direction'] < 360) { + if (empty($fielddata['FOW'])) { + $dcoord = $this->_getAngleStep ($posxy, $fielddata['direction'], 0.002); + $dcoord = sprintf('%s,%s', $dcoord[1], $dcoord[0]); + $point .= "clampToGround" + . $coord . ",0\n". $dcoord . ",0\n"; + } else { + $point .= "clampToGround"; + $point .= $coord . ",0\n"; + for ($angle = $fielddata['direction']-$fielddata['FOW']/2; $angle < $fielddata['direction']+$fielddata['FOW']/2; $angle += $fielddata['FOW']/10) { + $dcoord = $this->_getAngleStep ($posxy, $angle, 0.002); + $dcoord = sprintf('%s,%s', $dcoord[1], $dcoord[0]); + $point .= $dcoord . ",0\n"; + } + $point .= ""; + } + } + $point .= ""; /* Output Placemark to Google Earth */ $coordstring = (!empty($fielddata['GPS'])) ? $fielddata['GPS'] : ''; @@ -387,4 +429,4 @@ return $returnstring; } } -?> \ В конце файла нет новой строки +?> diff -Nuar /var/www/304.ru/drupal/htdocs/gallery2/modules/map/includes/MapAdminViewInit.inc map/includes/MapAdminViewInit.inc --- /var/www/304.ru/drupal/htdocs/gallery2/modules/map/includes/MapAdminViewInit.inc 2010-02-28 15:52:59.000000000 +0300 +++ map/includes/MapAdminViewInit.inc 2010-02-22 14:32:51.000000000 +0300 @@ -38,6 +38,8 @@ /* Add the google map fields (we don't care about errors) */ list($ret, $added) = mapHelper::addField('GPS', 'common', 0); + list($ret, $added) = mapHelper::addField('direction', 'common', 0); + list($ret, $added) = mapHelper::addField('FOW', 'common', 0); list($ret, $added) = mapHelper::addField('ZoomLevel', 'common', 0); list($ret, $added) = mapHelper::addField('GELookAt', 'common', 0); @@ -93,4 +95,4 @@ } $template->head('modules/map/templates/AdminHeader.tpl'); -?> \ В конце файла нет новой строки +?> diff -Nuar /var/www/304.ru/drupal/htdocs/gallery2/modules/map/mapItemEdit.inc map/mapItemEdit.inc --- /var/www/304.ru/drupal/htdocs/gallery2/modules/map/mapItemEdit.inc 2010-02-28 15:52:59.000000000 +0300 +++ map/mapItemEdit.inc 2010-02-22 15:27:39.000000000 +0300 @@ -134,7 +134,7 @@ $form['itemId'] = $item->getId(); } - list ($ret, $form['exif']) = GoogleMapUtilities::getGPSCoordsFromExif($item); + list ($ret, $form['exif'], $direction, $FOW) = GoogleMapUtilities::getGPSCoordsFromExif($item); if ($ret) { return array($ret->wrap(__FILE__, __LINE__), null, null); }