From 76d853d1b56355b25936587da21a7f46711d9bfe Mon Sep 17 00:00:00 2001 From: rac98 Date: Fri, 18 Sep 2009 10:06:55 +0000 Subject: [PATCH] initial git-svn-id: http://svn.code.sf.net/p/staticmaplite/code@1 3c7674d3-d6c2-4d0e-87b7-95661b9333b9 --- images/markers/lightblue1.png | Bin 0 -> 317 bytes images/markers/lightblue2.png | Bin 0 -> 417 bytes images/markers/lightblue3.png | Bin 0 -> 435 bytes images/markers/lightblue4.png | Bin 0 -> 387 bytes images/markers/lightblue5.png | Bin 0 -> 434 bytes images/osm_logo.png | Bin 0 -> 1167 bytes index.html | 122 +++++++++++++++++++++ staticmap.php | 199 ++++++++++++++++++++++++++++++++++ 8 files changed, 321 insertions(+) create mode 100644 images/markers/lightblue1.png create mode 100644 images/markers/lightblue2.png create mode 100644 images/markers/lightblue3.png create mode 100644 images/markers/lightblue4.png create mode 100644 images/markers/lightblue5.png create mode 100644 images/osm_logo.png create mode 100644 index.html create mode 100644 staticmap.php diff --git a/images/markers/lightblue1.png b/images/markers/lightblue1.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7ecdfb3c5815a043d6c88dcd8c7070c617fd9b GIT binary patch literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^f7bJU literal 0 HcmV?d00001 diff --git a/images/markers/lightblue2.png b/images/markers/lightblue2.png new file mode 100644 index 0000000000000000000000000000000000000000..47ab258013887c6b829f5c433146484a4575b1d4 GIT binary patch literal 417 zcmV;S0bc%zP)EQ zOC*O0vbQ=S7#KP?qZ&-KAs_=lfeVV6iWRuk5saPpUm;-w;^PWfMsSKnOKdJW3=F#~ zv4@juJ7!|TY6x{w?6T=V;v5j)BEl3^EQTzzVz99If5OPf2xy89K_l4MjD9gdy#v7v z0snP$bS{7R@PY3?kPE_p{`_HrvC%P14q*sG%6}0N(bsqG+))Bal7hj8FxqeW&&J00 z^U$F~Hpn)^6rr=x`4E>di2k29Z(agEClmBeNl8gJE``KkfB*vk*RLLeOaB_h00000 LNkvXXu0mjf!5ge> literal 0 HcmV?d00001 diff --git a/images/markers/lightblue3.png b/images/markers/lightblue3.png new file mode 100644 index 0000000000000000000000000000000000000000..21f5912e34a103f056777c93ea04605c13780a51 GIT binary patch literal 435 zcmV;k0ZjghP)^%wz@zL2d>H z7aazM-IWkFNrr$x#R>)nlNttwut^XDj1}>P2^KJGAA~OVg}4gj6_ULJ104|z3`$~< zaKQx#8p0UOz>q!{5-uPEi8cgeGsqht8s@b{C6FX37;Ffm{igqHYM3M7RI|002ovPDHLkV1fv3obmtw literal 0 HcmV?d00001 diff --git a/images/markers/lightblue4.png b/images/markers/lightblue4.png new file mode 100644 index 0000000000000000000000000000000000000000..aff25c37c070d1a0e07310540049ca5681ab1f67 GIT binary patch literal 387 zcmV-}0et?6P)$>yDJ$Oj1}>@1P>78W?-0^452|78zAVCRe88I z6J{C6FX37;Ffm{igqHY2>zZcWEcW+ z$?B5~3}KV-`-lmb1jrkL+z?#u%fO%{My4S!*K|ZMFq~;Y4IiQm0r|gT1p|X}Ap?U+ z4I+$iM==&~?-c_>=Vk=|?0wu`!fFUe@!fuiMvy@uKFC`jmtg~p;1r7`v4NZp3JXxc zf&eI%(&s|b3VLG0X$S~_3;+ctNF&HqxKb>3LzYbk66b*U77^+GIhHV4X2oD(@&AO8 zkrB`o9fC%%u^IhhfVu>N83O+6=;&Pj@ZkgBe;^lx|NQyG1Y@IPm>j|ohLryzBBHPF z+_|F!k|YI#4Pmt3^q-B5@8_XIhis5-hABd4qw^syVG#X4Z{EBFd`>3losyE0Zd?k9 c!2kgU0HLfQ<&ons+yDRo07*qoM6N<$f?^D>>Hq)$ literal 0 HcmV?d00001 diff --git a/images/osm_logo.png b/images/osm_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..be12b27e5fe2783051540b1ff61f9aada07611aa GIT binary patch literal 1167 zcmV;A1aSL_P)kVdWD#-JNi+H7q{MPx9hpdvC96cj&*;1@-i;H?w(LD(jK*sS8_ zP?#Odsk!)n^dCXcB-@asd*DaTdwSlJ^FPn!oK#cgn+~?6zP^6F z(P*?MlgTrYNaSPm?@|?H`Fy_U-?cL5dCcv0f7a2_(U4B3RVI^BX0usonx>|vrj7>! z0WZb`SAyVjY@oltKPS}H)qNr2feQ>aH#h$`o@pY9hSXb<2r_;F(`I$oV z(_-Vo;qdd4*A9o{8CBs{R4^)XZ73AFRK`5B@pwE7Pq&sB_Y#2AhEcd;s17IS>a@ z?Y{+5Gy1?jj*(5e6+8fvU>Ljw?gc;b-NI(iUA6mh6dfBM9~TkU5<|Bm8uEI*{&%#W z0#Oi=ejt4r@Ht3v10I!htoM@REGj=m}(I9O9tlcmV>;4Bv@o;d;n4CBjO*wY**l|KgF1&dsKlzqQ|bHLB= zKh6!4%{u{l=-pqzAs|QQ#cL{Bxm+$13fs_-N8JT4XOnP`8`)&w9H0r z;_epR;yo_szJc`{bht{YzP`REySuy75coa9cV}B$+mYVh-e6Z(mwSGGUUF~)Uq8&8 zm4(`vU$O}=)58rEa~F7#i%ik;x6osSwvnH2axU@eEYLHj4NQl6@H#i|%C43WyLY44 z+J8rrK^;D2QYni^?f+)-lUy!4>vFlaL2!e~WYQ9eMAq;3pPQSTlgj%xmy zhP~CRTN{mPA*xfUWxbmGIg<4+WU3gRVm0(&kbM$P@+G%lr=wMlt%<@BSE?}meJq(x z+8$r8Wp%3qVk4SbO6pW-NmH?eF3fQS!EsVB3CFJMc$b)_=(0>>81LTbwXA7%nEn!* z(nG9H9h!+Qh8LGR8ICK$N_yC0(sm4ct!pHVFGT+#HcGJpbpx59x=Oph$!_>Fd_` + + + + + staticMapLite + + + + +
+ +
+ +
+

+ staticMapLite - simple map for your website +

+

+

+

+ This image was created using the following simple <img> tag: +

<img src="staticmap.php?center=40.714728,-73.998672&zoom=14&size=865x512&maptype=mapnik" />
+

+
+
+
+

+ Place Markers +

+ +

+ +

Add markers by appending them to the image URL: +

markers=40.702147,-74.015794,lightblue1|40.711614,-74.012318,lightblue2|40.718217,-73.998284,lightblue3
+

+
+
+
+

+ Use Different Map Styles (Tile Sources) +

+ +

+

+ +
maptype=mapnik
+
+
+ +
maptype=osmarenderer
+
+
+ +
maptype=cycle
+
+
+

+
+ +
+ +
+ + \ No newline at end of file diff --git a/staticmap.php b/staticmap.php new file mode 100644 index 0000000..4392ae3 --- /dev/null +++ b/staticmap.php @@ -0,0 +1,199 @@ + + * + * USAGE: + * + * staticmap.php?center=40.714728,-73.998672&zoom=14&size=512x512&maptype=mapnik&markers=40.702147,-74.015794,blues|40.711614,-74.012318,greeng|40.718217,-73.998284,redc + * + */ + +error_reporting(0); +ini_set('display_errors','off'); + +Class staticMapLite { + + protected $tileSize = 256; + protected $tileSrcUrl = array( 'mapnik' => 'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png', + 'osmarenderer' => 'http://c.tah.openstreetmap.org/Tiles/tile/{Z}/{X}/{Y}.png', + 'cycle' => 'http://c.andy.sandbox.cloudmade.com/tiles/cycle/{Z}/{X}/{Y}.png' + ); + protected $tileDefaultSrc = 'mapnik'; + protected $markerBaseDir = 'images/markers'; + protected $osmLogo = 'images/osm_logo.png'; + + protected $useTileCache = true; + protected $tileCacheBaseDir = 'cache'; + + protected $zoom, $lat, $lon, $width, $height, $markers, $image, $maptype; + protected $centerX, $centerY, $offsetX, $offsetY; + + public function __construct(){ + $this->zoom = 0; + $this->lat = 0; + $this->lon = 0; + $this->width = 0; + $this->height = 0; + $this->markers = array(); + $this->maptype = $this->tileDefaultSrc; + } + + public function parseParams(){ + global $_GET; + + $this->zoom = $_GET['zoom']?intval($_GET['zoom']):0; + if($this->zoom>18)$this->zoom = 18; + + list($this->lat,$this->lon) = split(',',$_GET['center']); + + if($_GET['size']){ + list($this->width, $this->height) = split('x',$_GET['size']); + } + if($_GET['markers']){ + $this->markers = split('%7C|\|',$_GET['markers']); + } + if($_GET['maptype']){ + if(array_key_exists($_GET['maptype'],$this->tileSrcUrl)) $this->maptype = $_GET['maptype']; + } + } + + public function lonToTile($long, $zoom){ + return (($long + 180) / 360) * pow(2, $zoom); + } + + public function latToTile($lat, $zoom){ + return (1 - log(tan($lat * pi()/180) + 1 / cos($lat* pi()/180)) / pi()) /2 * pow(2, $zoom); + } + + public function initCoords(){ + $this->centerX = $this->lonToTile($this->lon, $this->zoom); + $this->centerY = $this->latToTile($this->lat, $this->zoom); + $this->offsetX = floor((floor($this->centerX)-$this->centerX)*$this->tileSize); + $this->offsetY = floor((floor($this->centerY)-$this->centerY)*$this->tileSize); + } + + public function createBaseMap(){ + $this->image = imagecreatetruecolor($this->width, $this->height); + $startX = floor($this->centerX-($this->width/$this->tileSize)/2); + $startY = floor($this->centerY-($this->height/$this->tileSize)/2); + $endX = ceil($this->centerX+($this->width/$this->tileSize)/2); + $endY = ceil($this->centerY+($this->height/$this->tileSize)/2); + $this->offsetX = -floor(($this->centerX-floor($this->centerX))*$this->tileSize); + $this->offsetY = -floor(($this->centerY-floor($this->centerY))*$this->tileSize); + $this->offsetX += floor($this->width/2); + $this->offsetY += floor($this->height/2); + $this->offsetX += floor($startX-floor($this->centerX))*$this->tileSize; + $this->offsetY += floor($startY-floor($this->centerY))*$this->tileSize; + + for($x=$startX; $x<=$endX; $x++){ + for($y=$startY; $y<=$endY; $y++){ + $url = str_replace(array('{Z}','{X}','{Y}'),array($this->zoom, $x, $y), $this->tileSrcUrl[$this->maptype]); + $tileImage = imagecreatefromstring($this->fetchTile($url)); + $destX = ($x-$startX)*$this->tileSize+$this->offsetX; + $destY = ($y-$startY)*$this->tileSize+$this->offsetY; + imagecopy($this->image, $tileImage, $destX, $destY, 0, 0, $this->tileSize, $this->tileSize); + } + } + } + + + public function placeMarkers(){ + foreach($this->markers as $marker){ + list($markerLat, $markerLon, $markerImage) = split(',',$marker); + $markerIndex++; + $markerFilename = $markerImage?(file_exists($this->markerBaseDir.'/'.$markerImage.".png")?$markerImage:'lightblue'.$markerIndex):'lightblue'.$markerIndex; + if(file_exists($this->markerBaseDir.'/'.$markerFilename.".png")){ + $markerImg = imagecreatefrompng($this->markerBaseDir.'/'.$markerFilename.".png"); + } else { + $markerImg = imagecreatefrompng($this->markerBaseDir.'/lightblue1.png'); + } + $destX = floor(($this->width/2)-$this->tileSize*($this->centerX-$this->lonToTile($markerLon, $this->zoom))); + $destY = floor(($this->height/2)-$this->tileSize*($this->centerY-$this->latToTile($markerLat, $this->zoom))); + $destY = $destY - imagesy($markerImg); + + imagecopy($this->image, $markerImg, $destX, $destY, 0, 0, imagesx($markerImg), imagesy($markerImg)); + + } +} + + + + public function tileUrlToFilename($url){ + return $this->tileCacheBaseDir."/".str_replace(array('http://'),'',$url); + } + + public function checkTileCache($url){ + $filename = $this->tileUrlToFilename($url); + if(file_exists($filename)){ + return file_get_contents($filename); + } + } + public function mkdir_recursive($pathname, $mode){ + is_dir(dirname($pathname)) || $this->mkdir_recursive(dirname($pathname), $mode); + return is_dir($pathname) || @mkdir($pathname, $mode); + } + public function writeTileToCache($url, $data){ + $filename = $this->tileUrlToFilename($url); + $this->mkdir_recursive(dirname($filename),0777); + file_put_contents($filename, $data); + } + + public function fetchTile($url){ + if($this->useTileCache && ($cached = $this->checkTileCache($url))) return $cached; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0"); + curl_setopt($ch, CURLOPT_URL, $url); + $tile = curl_exec($ch); + curl_close($ch); + if($this->useTileCache){ + $this->writeTileToCache($url,$tile); + } + return $tile; + + } + + public function copyrightNotice(){ + $logoImg = imagecreatefrompng($this->osmLogo); + imagecopy($this->image, $logoImg, imagesx($this->image)-imagesx($logoImg), imagesy($this->image)-imagesy($logoImg), 0, 0, imagesx($logoImg), imagesy($logoImg)); + + } + + public function showMap(){ + $this->parseParams(); + $this->initCoords(); + $this->createBaseMap(); + if(count($this->markers))$this->placeMarkers(); + if($this->osmLogo) $this->copyrightNotice(); + header('Content-Type: image/png'); + $expires = 60*60*24*14; + header("Pragma: public"); + header("Cache-Control: maxage=".$expires); + header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT'); + return imagepng($this->image); + + } + +} + +$map = new staticMapLite(); +print $map->showMap(); + +?> \ No newline at end of file