In this version I pared out everything that was not being reported to the display, so there is a lot less to wrestle with and no wasted clock ticks. I also switched to abbreviated underscore_case as a variable naming convention. camelCaseNames are nice, but better used for function names. First letter uppercase is generally reserved for class names in OOP.
The idea was to free up the clutter and make everything easily discernible. One can pretty it up all one wants, but if it works and you understand its workings, there is no need for the extra verbiage. The key is to ensure that any programmer can work with the code, if they need to. And it makes your life easier, too.
Simple, concise, brief is always best, as long as you can understand it six months or six years later.
I'll start this time with the HTML portion as there is some explanation owed.
PHP Code:
<?php
require_once "gps_exif_inc.php";
$image = isset($img) ? $img . ".jpg" : null;
readExif($image);
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>.: GPS EXIF :.</title>
<link rel="stylesheet" href="gps_exif.css">
</head>
<body>
<div id="header"><div class="headerbox">GPS EXIF</div></div>
<div id="image"><div class="imagebox"><div class="imageshow"><?php getImg($image); ?></div></div></div>
<div id="exif">
<div class="exifbox">
<div class="exifboxtable">
<table>
<tr><th>GPS</th><th>LONGITUDE</th><th>LATITUDE</th></tr>
<?php print_data(); ?>
</table>
</div>
</div>
</div>
</body>
</html>
The include file can be placed anywhere for easy site wide sharing. Keep the URL relative to the folder asking for it and it will work fine. I use require_once instead of include_once because it is unconditional. include_once is generally used only when it is the action of a condition.
The image must be in the same folder as this page. Using your earlier discovery script, you could build a table then store it for retrieval in a series of pages using this one template. Then you could add previous/next navigation.
The biggest change to this page is the headline. I switched over to TH, as they are headings. Styling the TH's allowed removal of all extraneous markup.
I like to separate code from HTML from CSS as early as possible in a project; always thinking of portability and re-use. Ease of maintenance and debugging goes without saying. Something to adopt early in your programming exploits. It also saves you reinventing the wheel or creating multiple versions of essentially the same thing. Work toward building a code library; as well set up custom, section and site wide CSS, and template your pages so they can be re-used.
Now the CSS, which is not much changed, but I had to work it a little bit. The images are commented out so I wouldn't be generating 404 responses with every refresh.
Code:
body {
margin: 0;
text-align: left;
/* background-image: url('background.jpg'); */
}
p,
.exifboxtable th {
font-family: Helvetica Neue, Geneva, Arial, Verdana;
font-size: 10px;
letter-spacing: 1px;
font-weight: normal;
color: #303030;
margin: 0;
text-align: left;
}
p {
font-weight: normal;
}
#header {
position: relative;
height: 50px;
width: 100%;
margin-top: 20px;
margin-bottom: 0;
}
.headerbox {
position: absolute;
width: 800px;
height: 50px;
top: 0;
left: 50%;
margin-left: -400px;
z-index: 0;
overflow: hidden;
font-family: Helvetica Neue, Geneva, Arial, Verdana;
font-size: 36px;
letter-spacing: 1px;
font-weight: normal;
color: #f3f3f3;
}
#image {
position: relative;
height: 500px;
}
.imagebox {
position: absolute;
width: 800px;
height: 500px;
top: 0;
left: 50%;
margin-left: -400px;
z-index: 0;
overflow: hidden;
/* background-image: url('box_image.gif'); */
}
.imageshow {
float: left;
width:780px;
margin-left: 10px;
}
#exif {
position: relative;
height: 260px;
width: 100%;
}
.exifbox {
position: absolute;
width: 800px;
height: 260px;
top: 0px;
left: 50%;
margin-left: -400px;
z-index: 0;
overflow: hidden;
/* background-image: url('box_exif.gif'); */
}
.exifboxtable {
position: absolute;
width: 800px;
height: 240px;
top: 20px;
left: 50%;
margin-left: -400px;
z-index: 0;
overflow: hidden;
text-align: center;
}
.exifboxtable table {
width: 760px;
padding: 0;
border-collapse: collapse;
border: none;
}
.exifboxtable td,
.exifboxtable th { width: 30%; vertical-align: top; padding: 0; }
.exifboxtable td+td+td,
.exifboxtable th+th+th { width: 40%; }
.exifboxtable th { font-weight: bold; line-height: 3em; }
img { border: none; }
p { line-height: 2em; }
Last the include file, which as I mentioned, is pared down considerably.
PHP Code:
<?php
function readExif($img) {
if (file_exists($img)) {
global $exif, $gps_alt,$lat_dec, $lon_dec;
$exif = read_exif_data($img, 0, true);
$gps_alt = $exif["GPS"]["GPSAltitude"][0];
$gps = getGPS();
if ($gps != null) {
$lat_dec = $gps[0];
$lon_dec = $gps[1];
}
normalizeSeconds();
}
}
function normalizeSeconds() {
global $lat_min, $lat_sec, $log_min, $log_sec;
$x = (int)$lat_min;
$y = (int)$log_min;
$lat_sec = ($lat_min - $x) * 60;
$log_sec = ($log_min - $y) * 60;
$lat_min = $x;
$log_min = $y;
}
function print_data() {
global $exif, $gps_alt, $lat_deg, $lat_min, $lat_sec, $lat_hem, $lat_dec, $log_deg, $log_min, $log_sec, $log_hem, $lon_dec;
$str = " <tr>\n";
$str .= " <td>\n <p>Altitude: $gps_alt</p>\n </td>\n";
$str .= " <td>\n <p>Degrees: $lat_deg</p>\n <p>Minutes: $lat_min</p>\n <p>Seconds: $lat_sec</p>\n <p>Latitude Hemisphere: $lat_hem</p>\n <p>Decimal Latitude: $lat_dec</p>\n </td>\n";
$str .= " <td>\n <p>Degrees: $log_deg</p>\n <p>Minutes: $log_min</p>\n <p>Seconds: $log_sec</p>\n <p>Longitude Hemisphere: $log_hem</p>\n <p>Decimal Longitude: $lon_dec</p>\n </td>\n";
$str .= " </tr>";
echo $str;
}
function getImg($img) {
global $exif;
$fil_wid = $exif['COMPUTED']['Width'];
$fil_hgt = $exif['COMPUTED']['Height'];
if (file_exists($img)) {
$str = "<img src=\"$img\" width=\"$fil_wid\" height=\"$fil_hgt\" alt=\"" . strTrunc($img,4) . "\">";
echo $str;
} else {
echo "Image not found.";
}
}
function strTrunc($str,$trunc) { return substr($str,0,strlen($str)-$trunc); };
// adapted from http://www.quietless.com/kitchen/extract-exif-data-using-php-to-display-gps-tagged-images-in-google-maps/
function toDecimal($deg, $min, $sec, $hem) {
$d = $deg + $min/60 + $sec/3600;
return ($hem=='S' || $hem=='W') ? $d*=-1 : $d;
}
function divide($a) {
$e = explode('/', $a);
if (!$e[0] || !$e[1]) {
return 0;
} else {
return $e[0] / $e[1];
}
}
function getGPS() {
global $exif, $lat_deg, $lat_min, $lat_sec, $lat_hem, $log_deg, $log_min, $log_sec, $log_hem;
if ($exif) {
$lat = $exif['GPS']['GPSLatitude'];
$log = $exif['GPS']['GPSLongitude'];
if (!$lat || !$log) return null;
$lat_deg = divide($lat[0]);
$lat_min = divide($lat[1]);
$lat_sec = divide($lat[2]);
$lat_hem = $exif['GPS']['GPSLatitudeRef'];
$log_deg = divide($log[0]);
$log_min = divide($log[1]);
$log_sec = divide($log[2]);
$log_hem = $exif['GPS']['GPSLongitudeRef'];
$lat_dec = toDecimal($lat_deg, $lat_min, $lat_sec, $lat_hem);
$log_dec = toDecimal($log_deg, $log_min, $log_sec, $log_hem);
return array($lat_dec, $log_dec);
} else {
return null;
}
}
//
?>
I could be dead wrong about the seconds normalization, but it was bugging me that minutes had a decimal fraction and seconds were always zero. The function can be dropped by simply not calling it. (comment out the function call line). Unfortunately it goes under the assumption that seconds will ALWAYS be zero and simply replaces that value with the computed normalized value for the minutes decimal fraction. It is accurate in this sense.
This should give you something to work with. Questions are always welcome.
---------- Post added at 03:38 AM ---------- Previous post was at 02:15 AM ----------
You do notice I don't say, "// adapted from..." on your code? If I look around where am I going to find the code you've started me with? You do realize I know how to search?
---------- Post added at 04:01 AM ---------- Previous post was at 03:38 AM ----------
Piping in one last comment, the use of first letter uppercase for CSS selectors is not a recommended practice. The first time you forget a capital first letter your page could break and you'd be searching for hours for the cause. Stick to lowercase or underscore_lowercase and save yourself and any other programmer much grief.