|
<?php |
|
require 'vendor/autoload.php'; |
|
|
|
use DerickR\GPX\Reader; |
|
|
|
/* Configuration */ |
|
$userAgent = "Your Name/your-email@gmail.com"; |
|
$zoomLevel = 12; |
|
|
|
$yourLocation = new LatLon( 51.4847, -1.7813 ); |
|
$yourLocationSize = 50; |
|
$drawYourLocationBox = true; |
|
$hideFromYourLocationBox = true; |
|
|
|
/* Constants, Don't Change */ |
|
$tileSize = 256; |
|
$outputFileName = $argv[1] . '.png'; |
|
|
|
/* Get track data */ |
|
$trackData = (new Reader( $argv[1] ))->getTrack()->getTrackData(); |
|
|
|
/* Finding Boundaries */ |
|
$minX = $minY = PHP_INT_MAX; |
|
$maxX = $maxY = PHP_INT_MIN; |
|
|
|
foreach ($trackData as $point) { |
|
if ($point[0] < $minX) { |
|
$minX = $point[0]; |
|
} |
|
if ($point[0] > $maxX) { |
|
$maxX = $point[0]; |
|
} |
|
if ($point[1] < $minY) { |
|
$minY = $point[1]; |
|
} |
|
if ($point[1] > $maxY) { |
|
$maxY = $point[1]; |
|
} |
|
} |
|
|
|
$p1 = new LatLon( $minY, $minX ); |
|
$p2 = new LatLon( $maxY, $maxX ); |
|
|
|
/* Convert Coordinates to Pixels */ |
|
$pixels = pow(2, $zoomLevel) * $tileSize; |
|
|
|
$x1 = lon2x( $p1->lon, $pixels ); |
|
$x2 = lon2x( $p2->lon, $pixels ); |
|
$y1 = lat2y( $p2->lat, $pixels ); |
|
$y2 = lat2y( $p1->lat, $pixels ); |
|
|
|
$tx1 = floor( $x1 / $tileSize ); |
|
$tx2 = ceil( $x2 / $tileSize ); |
|
$ty1 = floor( $y1 / $tileSize ); |
|
$ty2 = ceil( $y2 / $tileSize ); |
|
|
|
$xOrig = $tx1 * $tileSize; |
|
$yOrig = $ty1 * $tileSize; |
|
|
|
$yourX = lon2x( $yourLocation->lon, $pixels ); |
|
$yourY = lat2y( $yourLocation->lat, $pixels ); |
|
|
|
$hideX = (floor($yourX / $yourLocationSize) * $yourLocationSize) - $xOrig; |
|
$hideY = (floor($yourY / $yourLocationSize) * $yourLocationSize) - $yOrig; |
|
|
|
/* Allocate Image */ |
|
$map = imagecreatetruecolor( |
|
( $tx2 - $tx1 ) * $tileSize, |
|
( $ty2 - $ty1 ) * $tileSize |
|
); |
|
imageantialias( $map, true ); |
|
|
|
/* Define colours */ |
|
$red = imagecolorallocate( $map, 200, 0, 0 ); |
|
$blue = imagecolorallocate( $map, 0, 0, 200 ); |
|
|
|
/* Create Image From Tiles */ |
|
$ctxt = stream_context_create([ 'http' => [ 'method' => "GET", "header" => "User-Agent: {$userAgent}" ] ]); |
|
|
|
for ($i = $tx1; $i < $tx2; $i++) { |
|
for ($j = $ty1; $j < $ty2; $j++) { |
|
echo "https://tile.openstreetmap.org/$zoomLevel/$i/$j.png\n"; |
|
$im = imagecreatefromstring( file_get_contents( "https://tile.openstreetmap.org/$zoomLevel/$i/$j.png", false, $ctxt ) ); |
|
imagecopy( $map, $im, ($i - $tx1) * $tileSize, ($j - $ty1) * $tileSize, 0, 0, $tileSize, $tileSize ); |
|
} |
|
} |
|
|
|
/* Draw Your Location Box */ |
|
if ( $drawYourLocationBox ) |
|
{ |
|
imageline( $map, round($hideX), round($hideY), round($hideX + $yourLocationSize), round($hideY), $blue ); |
|
imageline( $map, round($hideX + $yourLocationSize), round($hideY), round($hideX + $yourLocationSize), round($hideY + $yourLocationSize), $blue ); |
|
imageline( $map, round($hideX + $yourLocationSize), round($hideY + $yourLocationSize), round($hideX), round($hideY + $yourLocationSize), $blue ); |
|
imageline( $map, round($hideX), round($hideY + $yourLocationSize), round($hideX), round($hideY), $blue ); |
|
} |
|
|
|
/* Draw Lines */ |
|
for ($i = 0; $i < count($trackData) - 2; $i++) { |
|
$x1 = lon2x( $trackData[$i][0], $pixels ) - $xOrig; |
|
$x2 = lon2x( $trackData[$i+1][0], $pixels ) - $xOrig; |
|
$y1 = lat2y( $trackData[$i][1], $pixels ) - $yOrig; |
|
$y2 = lat2y( $trackData[$i+1][1], $pixels ) - $yOrig; |
|
|
|
if ($hideFromYourLocationBox) { |
|
if ($x1 > $hideX && $x1 < ($hideX + $yourLocationSize) && $y1 > $hideY && $y1 < ($hideY + $yourLocationSize)) { |
|
continue; |
|
} |
|
if ($x2 > $hideX && $x2 < ($hideX + $yourLocationSize) && $y2 > $hideY && $y2 < ($hideY + $yourLocationSize)) { |
|
continue; |
|
} |
|
} |
|
|
|
imageline( $map, round($x1), round($y1), round($x2), round($y2), $red ); |
|
} |
|
|
|
/* Add Required Attribution */ |
|
imagestring( $map, 5, 10, 10, '(c) OpenStreetMap contributors, CC-BY-SA', imagecolorallocate( $map, 0, 0, 0 ) ); |
|
|
|
/* Write Image */ |
|
imagepng( $map, $outputFileName ); |
|
|
|
|
|
/* Helper Classes and Functions */ |
|
class LatLon |
|
{ |
|
public $lat; |
|
public $lon; |
|
public $height; |
|
|
|
function __construct( $lat, $lon, $height = 0 ) |
|
{ |
|
$this->lat = $lat; |
|
$this->lon = $lon; |
|
$this->height = $height; |
|
} |
|
} |
|
|
|
function lon2x( $lon, $pixels = 32768 ) |
|
{ |
|
return (($lon + 180) / 360) * $pixels; |
|
} |
|
|
|
function lat2y( $lat, $pixels = 32768 ) |
|
{ |
|
return ((atanh(sin(deg2rad(-$lat))) / M_PI) + 1) * ($pixels / 2); |
|
} |