From 337aef87ef141c767c106cbe2cec0a7c6914eeab Mon Sep 17 00:00:00 2001
From: rabuzarus <trebor@central-unit>
Date: Wed, 30 Sep 2015 00:19:54 +0200
Subject: [PATCH] port of reds geotag feature

---
 include/Photo.php    | 51 +++++++++++++++++++++++--------------------
 include/features.php |  1 +
 include/photos.php   | 27 +++++++++++++++++++++++
 mod/photos.php       | 52 ++++++++++++++++++++++++++++++++++++--------
 4 files changed, 98 insertions(+), 33 deletions(-)
 create mode 100644 include/photos.php

diff --git a/include/Photo.php b/include/Photo.php
index 785601c7e..9732801c9 100644
--- a/include/Photo.php
+++ b/include/Photo.php
@@ -345,38 +345,37 @@ class Photo {
     }
 
     public function orient($filename) {
-        if ($this->is_imagick()) {
-            // based off comment on http://php.net/manual/en/imagick.getimageorientation.php
-            $orientation = $this->image->getImageOrientation();
-            switch ($orientation) {
-            case imagick::ORIENTATION_BOTTOMRIGHT:
-                $this->image->rotateimage("#000", 180);
-                break;
-            case imagick::ORIENTATION_RIGHTTOP:
-                $this->image->rotateimage("#000", 90);
-                break;
-            case imagick::ORIENTATION_LEFTBOTTOM:
-                $this->image->rotateimage("#000", -90);
-                break;
-            }
+	if ($this->is_imagick()) {
+		// based off comment on http://php.net/manual/en/imagick.getimageorientation.php
+		$orientation = $this->image->getImageOrientation();
+		switch ($orientation) {
+		case imagick::ORIENTATION_BOTTOMRIGHT:
+		    $this->image->rotateimage("#000", 180);
+		    break;
+		case imagick::ORIENTATION_RIGHTTOP:
+		    $this->image->rotateimage("#000", 90);
+		    break;
+		case imagick::ORIENTATION_LEFTBOTTOM:
+		    $this->image->rotateimage("#000", -90);
+		    break;
+		}
 
-            $this->image->setImageOrientation(imagick::ORIENTATION_TOPLEFT);
-            return TRUE;
-        }
+		$this->image->setImageOrientation(imagick::ORIENTATION_TOPLEFT);
+		return TRUE;
+	}
 	// based off comment on http://php.net/manual/en/function.imagerotate.php
 
 	if(!$this->is_valid())
-	    return FALSE;
+		return FALSE;
 
 	if( (! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg') )
-	    return;
+		return;
 
-	$exif = @exif_read_data($filename);
+	$exif = @exif_read_data($filename,null,true);
+	if(! $exif)
+		return;
 
-		if(! $exif)
-			return;
-
-	$ort = $exif['Orientation'];
+	$ort = $exif['IFD0']['Orientation'];
 
 	switch($ort)
 	{
@@ -413,6 +412,10 @@ class Photo {
 		$this->rotate(90);
 		break;
 	}
+
+	//	logger('exif: ' . print_r($exif,true));
+	return $exif;
+
     }
 
 
diff --git a/include/features.php b/include/features.php
index 091dfc6e9..5450c7fab 100644
--- a/include/features.php
+++ b/include/features.php
@@ -23,6 +23,7 @@ function get_features() {
 			t('General Features'),
 			//array('expire',         t('Content Expiration'),		t('Remove old posts/comments after a period of time')),
 			array('multi_profiles', t('Multiple Profiles'),			t('Ability to create multiple profiles')),
+			array('photo_location', t('Photo Location'),			t('Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map.'),false),
 		),
 
 		// Post composition
diff --git a/include/photos.php b/include/photos.php
new file mode 100644
index 000000000..93a565b51
--- /dev/null
+++ b/include/photos.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @file include/photos.php
+ * @brief Functions related to photo handling.
+ */
+
+function getGps($exifCoord, $hemi) {
+	$degrees = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0;
+	$minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0;
+	$seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0;
+
+	$flip = ($hemi == 'W' or $hemi == 'S') ? -1 : 1;
+
+	return floatval($flip * ($degrees + ($minutes / 60) + ($seconds / 3600)));
+}
+
+function gps2Num($coordPart) {
+	$parts = explode('/', $coordPart);
+
+	if (count($parts) <= 0)
+		return 0;
+
+	if (count($parts) == 1)
+		return $parts[0];
+
+	return floatval($parts[0]) / floatval($parts[1]);
+}
diff --git a/mod/photos.php b/mod/photos.php
index 3d3b92a46..e911c6505 100644
--- a/mod/photos.php
+++ b/mod/photos.php
@@ -1,5 +1,6 @@
 <?php
 require_once('include/Photo.php');
+require_once('include/photos.php');
 require_once('include/items.php');
 require_once('include/acl_selectors.php');
 require_once('include/bbcode.php');
@@ -194,6 +195,10 @@ function photos_post(&$a) {
 			goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
 		}
 
+		/*
+		 * RENAME photo album
+		 */
+
 		$newalbum = notags(trim($_POST['albumname']));
 		if($newalbum != $album) {
 			q("UPDATE `photo` SET `album` = '%s' WHERE `album` = '%s' AND `uid` = %d",
@@ -206,6 +211,9 @@ function photos_post(&$a) {
 			return; // NOTREACHED
 		}
 
+		/*
+		 * DELETE photo album and all its photos
+		 */
 
 		if($_POST['dropalbum'] == t('Delete Album')) {
 
@@ -534,12 +542,12 @@ function photos_post(&$a) {
 							if(count($links)) {
 								foreach($links as $link) {
 									if($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page')
-        		            			$profile = $link['@attributes']['href'];
+										$profile = $link['@attributes']['href'];
 									if($link['@attributes']['rel'] === 'salmon') {
 										$salmon = '$url:' . str_replace(',','%sc',$link['@attributes']['href']);
 										if(strlen($inform))
 											$inform .= ',';
-                    					$inform .= $salmon;
+											$inform .= $salmon;
 									}
 								}
 							}
@@ -833,7 +841,7 @@ function photos_post(&$a) {
 		killme();
 	}
 
-	$ph->orient($src);
+	$exif = $ph->orient($src);
 	@unlink($src);
 
 	$max_length = get_config('system','max_image_length');
@@ -874,8 +882,20 @@ function photos_post(&$a) {
 
 	// Create item container
 
+	$lat = $lon = null;
+
+	if($exif && $exif['GPS']) {
+		if(feature_enabled($channel_id,'photo_location')) {
+			$lat = getGps($exif['GPS']['GPSLatitude'], $exif['GPS']['GPSLatitudeRef']);
+			$lon = getGps($exif['GPS']['GPSLongitude'], $exif['GPS']['GPSLongitudeRef']);
+		}
+	}
+
 	$arr = array();
 
+	if($lat && $lon)
+		$arr['coord'] = $lat . ' ' . $lon;
+
 	$arr['uid']           = $page_owner_uid;
 	$arr['uri']           = $uri;
 	$arr['parent-uri']    = $uri;
@@ -1062,10 +1082,9 @@ function photos_content(&$a) {
 	$_is_owner = (local_user() && (local_user() == $owner_uid));
 	$o .= profile_tabs($a,$_is_owner, $a->data['user']['nickname']);
 
-	//
-	// dispatch request
-	//
-
+	/**
+	 * Display upload form
+	 */
 
 	if($datatype === 'upload') {
 		if(! ($can_post)) {
@@ -1176,6 +1195,10 @@ function photos_content(&$a) {
 		return $o;
 	}
 
+	/*
+	 * Display a single photo album
+	 */
+
 	if($datatype === 'album') {
 
 		$album = hex2bin($datum);
@@ -1203,6 +1226,7 @@ function photos_content(&$a) {
 			intval($a->pager['itemspage'])
 		);
 
+		//edit album name
 		if($cmd === 'edit') {
 			if(($album !== t('Profile Photos')) && ($album !== 'Contact Photos') && ($album !== t('Contact Photos'))) {
 				if($can_post) {
@@ -1290,11 +1314,12 @@ function photos_content(&$a) {
 
 	}
 
+	/** 
+	 * Display one photo
+	 */
 
 	if($datatype === 'image') {
 
-
-
 		//$o = '';
 		// fetch image, item containing image, then comments
 
@@ -1418,6 +1443,9 @@ function photos_content(&$a) {
 		$linked_items = q("SELECT * FROM `item` WHERE `resource-id` = '%s' $sql_extra LIMIT 1",
 			dbesc($datum)
 		);
+
+		$map = null;
+
 		if(count($linked_items)) {
 			$link_item = $linked_items[0];
 			$r = q("SELECT COUNT(*) AS `total`
@@ -1461,6 +1489,10 @@ function photos_content(&$a) {
 				);
 				update_thread($link_item['parent']);
 			}
+
+			if($link_item['coord']) {
+				$map = generate_map($link_item['coord']);
+			}
 		}
 
 		$tags=Null;
@@ -1753,6 +1785,8 @@ function photos_content(&$a) {
 			'$desc' => $ph[0]['desc'],
 			'$tags' => $tags_e,
 			'$edit' => $edit,
+			'$map' => $map,
+			'$map_text' => t('Map'),
 			'$likebuttons' => $likebuttons,
 			'$like' => $like_e,
 			'$dislike' => $dikslike_e,