<?php
/**
 * Project: RSKarte: Display parts of a big map
 * File name: coord.php
 * Description:  
 *   
 * @author Paul Zirnik, paul at zirnik dot de, Copyright (C) 2011.
 * @version : 0.0.4
 */
/* 
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 */
function usage() {
    echo 
"<br><br>Folgende Paramteter werden erkannt<br>";
    echo 
"Pflicht Parameter:<br>";
    echo 
"c1 = Breitengrad Format: [Grad][Anfangsbuchstabe der Himmlesrichtung][Minuten] z.B. c1=10N50<br>";
    echo 
"c2 = L&auml;ngengrad Format: [Grad][Anfangsbuchstabe der Himmlesrichtung][Minuten] z.B. c2=10O50<br>";
    echo 
"Optionale Parameter:<br>";
    echo 
"c3 = Breitengrad Format: [Grad][Anfangsbuchstabe der Himmlesrichtung][Minuten] z.B. c1=10N50<br>";
    echo 
"c4 = L&auml;ngengrad Format: [Grad][Anfangsbuchstabe der Himmlesrichtung][Minuten] z.B. c2=10O50<br>";
    echo 
"x = Bildbreite in Pixel<br>";
    echo 
"y = Bildh&ouml;he in Pixel<br>";
    echo 
"z = Zoomfaktor max. 4  z.B. z=1.5<br>";
    echo 
"map = Karte -> Runescape oder Untergrund";
    echo 
"source = Zeige den Quelltext an.<br>";
    echo 
"nocache = Das erzeugte Bild nicht cachen<br><br>";
    echo 
"Wenn nur c1 und c2 angegeben sind, entspricht der Punkt der Bildmitte und x und y legen die<br>";
    echo 
"Gr&ouml;ße des Bildes fest.<br>";
    echo 
"Wenn c1,c2,c3 und c4 angegeben sind, entspricht c1,c2 dem Eckpunkt einer diagonalen Linie und<br>";
    echo 
"c3,c4 dem anderen Eckpunkt der Linie um ein Rechtreck zu beschreiben.<br>";
    echo 
"Beispiel: <a href=\"http://www.schnupptrupp.org/Weltkarte/coord.php?c1=0N0&c2=0O0&x=350&y=350&z=1\">http://www.schnupptrupp.org/Weltkarte/coord.php?c1=0N0&c2=0O0&x=350&y=350&z=1</a><br>";
    exit(
1);
}

# where originates the coordinate system inside the image
#$xorigin=1279;
#$yorigin=3003;

# how many pixels are one minute
#$xfactor=1.604;
#$yfactor=1.605;

#$xorigin=1574;
#$yorigin=3796;

$xorigin=3600;
$yorigin=7094;

# how many pixels are one minute
$xfactor=2.135;
$yfactor=2.135;


// Cache-Lebensdauer (in Minuten)
$dauer 7*24*60;
$exp_gmt gmdate("D, d M Y H:i:s"time() + $dauer 60) ." GMT";
$mod_gmt gmdate("D, d M Y H:i:s"time() - 60 16) ." GMT";

#opensource
if(isset($_GET['source'])) {
    
highlight_file(__FILE__);
    exit(
0);
}

# scan parameters
$get 0;
if(!isset(
$_GET['c1'])) {
   
$_GET['c1'] = '0N0'
   
$get++;
}
if(!isset(
$_GET['c2'])) {
   
$_GET['c2'] = '0O0';
   
$get++;
}
if(!isset(
$_GET['x'])) {
   
$_GET['x'] = '250';
   
$get++;
}
if(!isset(
$_GET['y'])) {
   
$_GET['y'] = '250';
   
$get++;
}
if(!isset(
$_GET['z'])) {
   
$_GET['z'] = '1';
   
$get++;
}

if(!isset(
$_GET['map'])) {
   
$_GET['map'] = 'Runescape';
}
if(
$get == 5) {
  
usage();
}
$pmode=false;
if (isset(
$_GET['c3'])) {
    
$pmode=true;
    if(!isset(
$_GET['c4'])) {
        
usage();
    }
}
$_GET['c1']=strtoupper($_GET['c1']);
$_GET['c2']=strtoupper($_GET['c2']);
if (
$pmode) {
    
$_GET['c3']=strtoupper($_GET['c3']);
    
$_GET['c4']=strtoupper($_GET['c4']);
    list(
$RyshowH,$RyshowNS,$RyshowM) = sscanf($_GET['c3'],"%d%[N|S]%d");
    list(
$RxshowH,$RxshowOW,$RxshowM) = sscanf($_GET['c4'],"%d%[W|O]%d");
}
list(
$yshowH,$yshowNS,$yshowM) = sscanf($_GET['c1'],"%d%[N|S]%d");
list(
$xshowH,$xshowOW,$xshowM) = sscanf($_GET['c2'],"%d%[W|O]%d");
$xsize=(int) $_GET['x'];
$ysize=(int) $_GET['y'];
$zoom=sscanf($_GET['z'],"%f");
$zoom=(float) sprintf("%1.1f",$zoom[0]);
$map=$_GET['map'];
# validate parameters
if ($xsize<20 || $ysize<20) {
    echo 
"Bild zu klein min. 20 Pixel";
    
usage();
}
if (
$xsize>500 || $ysize>500) {
    echo 
"Bild zu gross max. 500 Pixel";
        
usage();
}
if ( 
$zoom 0.1 || $zoom ) {
        echo 
"Zoomwert ung&uuml;ltig";
        
usage();
}
switch (
$xshowOW) {
    case 
'O':
        
$xshowOW = (int) 1;
        break;
    case 
'W':
        
$xshowOW = (int) -1;
        break;
    default:
        echo 
"Falsche Koordinaten bei c1";
        
usage();
}
switch (
$yshowNS) {
        case 
'N':
                
$yshowNS = (int) -1;
                break;
        case 
'S':
                
$yshowNS = (int) 1;
                break;
        default:
                echo 
"Falsche Koordinaten bei c2";
                
usage();
}

if (
$pmode) {
    switch(
$RxshowOW) {
        case 
'O':
            
$RxshowOW = (int) 1;
            break;
        case 
'W':
            
$RxshowOW = (int) -1;
            break;
        default:
            echo 
"Falsche Koordinaten bei c3";
            
usage();
    }
    switch(
$RyshowNS) {
        case 
'N':
            
$RyshowNS = (int) -1;
            break;
        case 
'S':
            
$RyshowNS = (int) 1;
            break;
        default:
            echo 
"Falsche Koordinaten bei c4";
            
usage();
    }
}

switch (
$map) {
        case 
'Runescape'
        case 
'R':
            
$map="R";
            
$mapfile="RSKarte.png";
            break;
        case 
'Untergrund':
        case 
'U'
            
$map="U";
            
$mapfile="Untergrund.png";
            break;
        case 
'Untergrund2':
        case 
'U2':
            
$map="U2";
            
$mapfile="Untergrund-2.png";
            break;
        default:
            
$map="R";
            
$mapfile="RSKarte.png";
}

if(!isset(
$xshowH)) {
   
$xshowH 0;
}
if(!isset(
$yshowH)) {
   
$yshowH 0;
}
if(!isset(
$xshowM)) {
   
$xshowM 0;
}
if(!isset(
$yshowM)) {
   
$yshowM 0;
}

if (
$pmode) {
    if(!isset(
$RxshowH)) {
           
$RxshowH 0;
    }
    if(!isset(
$RyshowH)) {
           
$RyshowH 0;
    }
    if(!isset(
$RxshowM)) {
           
$RxshowM 0;
    }
    if(!isset(
$RyshowM)) {
           
$RyshowM 0;
    }
}

if ( 
$xshowH <|| $xshowH 60 ) {
    echo 
"L&auml;ngengrad Stunden au&szlig;erhalb des G&uuml;ltigkeitsbereichs";
    
usage();
}
if ( 
$yshowH <|| $yshowH 60 ) {
        echo 
"Breitengrad Stunden au&szlig;erhalb des G&uuml;ltigkeitsbereichs";
        
usage();
}
if ( 
$xshowM <|| $xshowM 60 ) {
        echo 
"L&auml;ngengrad Minuten au&szlig;erhalb des G&uuml;ltigkeitsbereichs";
        
usage();
}
if ( 
$yshowM <|| $yshowM 60 ) {
        echo 
"Breitengrad Minuten au&szlig;erhalb des G&uuml;ltigkeitsbereichs";
        
usage();
}

if (
$pmode) {
    if ( 
$RxshowH <|| $RxshowH 60 ) {
        echo 
"L&auml;ngengrad Stunden au&szlig;erhalb des G&uuml;ltigkeitsbereichs";
        
usage();
    }
    if ( 
$RyshowH <|| $RyshowH 60 ) {
        echo 
"Breitengrad Stunden au&szlig;erhalb des G&uuml;ltigkeitsbereichs";
        
usage();
    }
    if ( 
$RxshowM <|| $RxshowM 60 ) {
        echo 
"L&auml;ngengrad Minuten au&szlig;erhalb des G&uuml;ltigkeitsbereichs";
        
usage();
    }
    if ( 
$RyshowM <|| $RyshowM 60 ) {
        echo 
"Breitengrad Minuten au&szlig;erhalb des G&uuml;ltigkeitsbereichs";
        
usage();
    }
}

#fixfilename
if (substr($_GET['c1'],-1)=='N' || substr($_GET['c1'],-1)=='S') {
    
$_GET['c1'].='0';
}
if (
substr($_GET['c2'],-1)=='O' || substr($_GET['c2'],-1)=='W') {
    
$_GET['c2'].='0';
}

if (
$pmode) {
    if (
substr($_GET['c3'],-1)=='N' || substr($_GET['c3'],-1)=='S') {
        
$_GET['c3'].='0';
    }
    if (
substr($_GET['c4'],-1)=='O' || substr($_GET['c4'],-1)=='W') {
        
$_GET['c4'].='0';
    }
}

# cache handling
# this command should be executed via cron once a day
# to clean up the cache if a newer map is uploaded
# or the cached image was not accessed for 5 days or more 
#
# find cache/ -type f ! -newer RSKarte.png -o -atime +5 -exec rm{}\;
#
if ($pmode) {
    
$filename $map "-B"$_GET['c1'] . "L" $_GET['c2'] . "B" $_GET['c3'] . "L" $_GET['c4'] . "z" $zoom ".png";
} else {
    
$filename $map "B"$_GET['c1'] . "L" $_GET['c2'] . "x" $xsize "y" $ysize "z" $zoom ".png";
}
$cim = @imagecreatefrompng("cache/"$filename );
if (
$cim) {
    if (
filemtime($mapfile) < filemtime("cache/"$filename)) {
        
header("Expires: " $exp_gmt);
        
header("Last-Modified: " $mod_gmt);
        
header("Cache-Control: public, max-age=" $dauer 60);
        
header('Content-type: image/png');
        
imagepng($cim);
        exit(
0);
    } 
    
imagedestroy($cim);
    
unlink("cache/"$filename );
}
# simple file locking, the map is big (5600x5200 px) 
# don't let more than one php instance allocate this amount of memory
# else we will eventually swap and this will slow down more as
# waiting for the lock
if(!($file_handle=fopen('image.lock','r+')))
        die(
"Can't open lockfile");
flock($file_handleLOCK_EX);

#eventualy the image was just created while we waited for the lock ? 
#don't do the same work twice
$cim = @imagecreatefrompng("cache/"$filename );
if (
$cim) {
        if (
filemtime($mapfile) < filemtime("cache/"$filename)) {
                
header("Expires: " $exp_gmt);
                
header("Last-Modified: " $mod_gmt);
                
header("Cache-Control: public, max-age=" $dauer 60);
                
header('Content-type: image/png');
                
imagepng($cim);
                exit(
0);
        }
        
imagedestroy($cim);
        
unlink("cache/"$filename );
}

# ok, we hold the lock and no image is already in cache
# let's create the image

$im imagecreatefrompng($mapfile);

if (
$pmode) {
    
$Lxreal=intval(((($xshowH*60)+$xshowM)*$xshowOW)*$xfactor);
    
$Lyreal=intval(((($yshowH*60)+$yshowM)*$yshowNS)*$yfactor);
    
$Rxreal=intval(((($RxshowH*60)+$RxshowM)*$RxshowOW)*$xfactor);
    
$Ryreal=intval(((($RyshowH*60)+$RyshowM)*$RyshowNS)*$yfactor);
    if (
$Rxreal<=$Lxreal) {
        
$temp=$Lxreal;
        
$Lxreal=$Rxreal;
        
$Rxreal=$temp;
    }
    if (
$Ryreal<=$Lyreal) {
        
$temp=$Lyreal;
        
$Lyreal=$Ryreal;
        
$Ryreal=$temp;
    }
    
$resimg=imagecreatetruecolor($Rxreal-$Lxreal,$Ryreal-$Lyreal);
    
imagecopy($resimg,$im,0,0,$xorigin+$Lxreal,$yorigin+$Lyreal,$Rxreal-$Lxreal,$Ryreal-$Lyreal);
    
$resimg2=imagecreatetruecolor(($Rxreal-$Lxreal)*$zoom,($Ryreal-$Lyreal)*$zoom);
    
imagecopyresized($resimg2,$resimg,0,0,0,0,($Rxreal-$Lxreal)*$zoom,($Ryreal-$Lyreal)*$zoom,$Rxreal-$Lxreal,$Ryreal-$Lyreal);
} else {
    
$xsize=$xsize/$zoom;
    
$ysize=$ysize/$zoom;    
    
$xreal=((($xshowH*60)+$xshowM)*$xshowOW)*$xfactor;
    
$yreal=((($yshowH*60)+$yshowM)*$yshowNS)*$yfactor;
    
$resimg imagecreatetruecolor($xsize,$ysize);
    
imagecopy($resimg,$im,0,0,(int)($xorigin-($xsize/2))+$xreal,(int) ($yorigin-($ysize/2))+$yreal,$xsize,$ysize);
    
$xsize=$xsize*$zoom;
    
$ysize=$ysize*$zoom;
    
$resimg2 imagecreatetruecolor($xsize,$ysize);
    
imagecopyresized($resimg2,$resimg,0,0,0,0,$xsize,$ysize,$xsize/$zoom,$ysize/$zoom);
    
imageline($resimg2,0,$ysize/2,$xsize,$ysize/2,ImageColorAllocate ($resimg2255255255));
    
imageline($resimg2,$xsize/2,0,$xsize/2,$ysize,ImageColorAllocate ($resimg2255255255));
}
header("Expires: " $exp_gmt);
header("Last-Modified: " $mod_gmt);
header("Cache-Control: public, max-age=" $dauer 60);
header('Content-type: image/png');
if (!isset(
$_GET['nocache'])) {
    
imagepng($resimg2,"cache/"$filename);
}
imagepng($resimg2);
fclose($file_handle);
?>