Use cloudmade tiles for static maps
Use cloudmade tiles for static maps

#!/bin/bash #!/bin/bash
#this script should be run from a fresh git checkout from http://maxious.lambdacomplex.org #this script should be run from a fresh git checkout from http://maxious.lambdacomplex.org
#ami base must have yum install lighttpd-fastcgi, git, tomcat6 #ami base must have yum install lighttpd-fastcgi, git, tomcat6
#screen php-cli php-gd tomcat6-webapps tomcat6-admin-webapps svn maven2 #screen php-cli php-gd tomcat6-webapps tomcat6-admin-webapps svn maven2
#http://www.how2forge.org/installing-lighttpd-with-php5-and-mysql-support-on-fedora-12 #http://www.how2forge.org/installing-lighttpd-with-php5-and-mysql-support-on-fedora-12
   
cp /root/aws.php /tmp/ cp /root/aws.php /tmp/
  mkdir /var/www/lib/staticmaplite/cache
chcon -h system_u:object_r:httpd_sys_content_t /var/www chcon -h system_u:object_r:httpd_sys_content_t /var/www
chcon -R -h root:object_r:httpd_sys_content_t /var/www/* chcon -R -h root:object_r:httpd_sys_content_t /var/www/*
chcon -R -t httpd_sys_content_rw_t /var/www/lib/staticmaplite/cache chcon -R -t httpd_sys_content_rw_t /var/www/lib/staticmaplite/cache
chmod -R 777 /var/www/lib/staticmaplite/cache chmod -R 777 /var/www/lib/staticmaplite/cache
wget http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \ wget http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \
-O /var/www/cbrfeed.zip -O /var/www/cbrfeed.zip
easy_install transitfeed easy_install transitfeed
easy_install simplejson easy_install simplejson
screen -S viewsh -X quit screen -S viewsh -X quit
screen -S viewsh -d -m /var/www/view.sh screen -S viewsh -d -m /var/www/view.sh
   
wget http://s3-ap-southeast-1.amazonaws.com/busresources/Graph.obj \ wget http://s3-ap-southeast-1.amazonaws.com/busresources/Graph.obj \
-O /tmp/Graph.obj -O /tmp/Graph.obj
rm -rfv /usr/share/tomcat6/webapps/opentripplanner* rm -rfv /usr/share/tomcat6/webapps/opentripplanner*
wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-webapp.war \ wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-webapp.war \
-O /usr/share/tomcat6/webapps/opentripplanner-webapp.war -O /usr/share/tomcat6/webapps/opentripplanner-webapp.war
wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-api-webapp.war \ wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-api-webapp.war \
-O /usr/share/tomcat6/webapps/opentripplanner-api-webapp.war -O /usr/share/tomcat6/webapps/opentripplanner-api-webapp.war
/etc/init.d/tomcat6 restart /etc/init.d/tomcat6 restart
   
   
<?php <?php
// SELECT array_to_string(array(SELECT REPLACE(name_2006, ',', '\,') as name FROM suburbs order by name), ',') // SELECT array_to_string(array(SELECT REPLACE(name_2006, ',', '\,') as name FROM suburbs order by name), ',')
$suburbs = explode(",", "Acton,Ainslie,Amaroo,Aranda,Banks,Barton,Belconnen,Bonner,Bonython,Braddon,Bruce,Calwell,Campbell,Chapman,Charnwood,Chifley,Chisholm,City,Conder,Cook,Curtin,Deakin,Dickson,Downer,Duffy,Dunlop,Evatt,Fadden,Farrer,Fisher,Florey,Flynn,Forrest,Franklin,Fraser,Fyshwick,Garran,Gilmore,Giralang,Gordon,Gowrie,Greenway,Griffith,Gungahlin,Hackett,Hall,Harrison,Hawker,Higgins,Holder,Holt,Hughes,Hume,Isaacs,Isabella Plains,Kaleen,Kambah,Kingston,Latham,Lawson,Lyneham,Lyons,Macarthur,Macgregor,Macquarie,Mawson,McKellar,Melba,Mitchell,Monash,Narrabundah,Ngunnawal,Nicholls,Oaks Estate,O'Connor,O'Malley,Oxley,Page,Palmerston,Parkes,Pearce,Phillip,Pialligo,Red Hill,Reid,Richardson,Rivett,Russell,Scullin,Spence,Stirling,Symonston,Tharwa,Theodore,Torrens,Turner,Wanniassa,Waramanga,Watson,Weetangera,Weston,Yarralumla"); $suburbs = explode(",", "Acton,Ainslie,Amaroo,Aranda,Banks,Barton,Belconnen,Bonner,Bonython,Braddon,Bruce,Calwell,Campbell,Chapman,Charnwood,Chifley,Chisholm,City,Conder,Cook,Curtin,Deakin,Dickson,Downer,Duffy,Dunlop,Evatt,Fadden,Farrer,Fisher,Florey,Flynn,Forrest,Franklin,Fraser,Fyshwick,Garran,Gilmore,Giralang,Gordon,Gowrie,Greenway,Griffith,Gungahlin,Hackett,Hall,Harrison,Hawker,Higgins,Holder,Holt,Hughes,Hume,Isaacs,Isabella Plains,Kaleen,Kambah,Kingston,Latham,Lawson,Lyneham,Lyons,Macarthur,Macgregor,Macquarie,Mawson,McKellar,Melba,Mitchell,Monash,Narrabundah,Ngunnawal,Nicholls,Oaks Estate,O'Connor,O'Malley,Oxley,Page,Palmerston,Parkes,Pearce,Phillip,Pialligo,Red Hill,Reid,Richardson,Rivett,Russell,Scullin,Spence,Stirling,Symonston,Tharwa,Theodore,Torrens,Turner,Wanniassa,Waramanga,Watson,Weetangera,Weston,Yarralumla");
function staticmap($mapPoints, $zoom = 0, $markerImage = "iconb", $collapsible = true) function staticmap($mapPoints, $zoom = 0, $markerImage = "iconb", $collapsible = true)
{ {
$width = 300; $width = 300;
$height = 300; $height = 300;
$metersperpixel[9] = 305.492 * $width; $metersperpixel[9] = 305.492 * $width;
$metersperpixel[10] = 152.746 * $width; $metersperpixel[10] = 152.746 * $width;
$metersperpixel[11] = 76.373 * $width; $metersperpixel[11] = 76.373 * $width;
$metersperpixel[12] = 38.187 * $width; $metersperpixel[12] = 38.187 * $width;
$metersperpixel[13] = 19.093 * $width; $metersperpixel[13] = 19.093 * $width;
$metersperpixel[14] = 9.547 * $width; $metersperpixel[14] = 9.547 * $width;
$metersperpixel[15] = 4.773 * $width; $metersperpixel[15] = 4.773 * $width;
$metersperpixel[16] = 2.387 * $width; $metersperpixel[16] = 2.387 * $width;
// $metersperpixel[17]=1.193*$width; // $metersperpixel[17]=1.193*$width;
$center = ""; $center = "";
$markers = ""; $markers = "";
$minlat = 999; $minlat = 999;
$minlon = 999; $minlon = 999;
$maxlat = 0; $maxlat = 0;
$maxlon = 0; $maxlon = 0;
if (sizeof($mapPoints) < 1) return "map error"; if (sizeof($mapPoints) < 1) return "map error";
if (sizeof($mapPoints) === 1) { if (sizeof($mapPoints) === 1) {
if ($zoom == 0) $zoom = 14; if ($zoom == 0) $zoom = 14;
$markers.= "{$mapPoints[0][0]},{$mapPoints[0][1]},$markerimage"; $markers.= "{$mapPoints[0][0]},{$mapPoints[0][1]},$markerimage";
$center = "{$mapPoints[0][0]},{$mapPoints[0][1]}"; $center = "{$mapPoints[0][0]},{$mapPoints[0][1]}";
} }
else { else {
foreach ($mapPoints as $index => $mapPoint) { foreach ($mapPoints as $index => $mapPoint) {
$markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . $markerImage . ($index + 1); $markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . $markerImage . ($index + 1);
if ($index + 1 != sizeof($mapPoints)) $markers.= "|"; if ($index + 1 != sizeof($mapPoints)) $markers.= "|";
if ($mapPoint[0] < $minlat) $minlat = $mapPoint[0]; if ($mapPoint[0] < $minlat) $minlat = $mapPoint[0];
if ($mapPoint[0] > $maxlat) $maxlat = $mapPoint[0]; if ($mapPoint[0] > $maxlat) $maxlat = $mapPoint[0];
if ($mapPoint[1] < $minlon) $minlon = $mapPoint[1]; if ($mapPoint[1] < $minlon) $minlon = $mapPoint[1];
if ($mapPoint[1] > $maxlon) $maxlon = $mapPoint[1]; if ($mapPoint[1] > $maxlon) $maxlon = $mapPoint[1];
$totalLat+= $mapPoint[0]; $totalLat+= $mapPoint[0];
$totalLon+= $mapPoint[1]; $totalLon+= $mapPoint[1];
} }
if ($zoom == 0) { if ($zoom == 0) {
$mapwidthinmeters = distance($minlat, $minlon, $minlat, $maxlon); $mapwidthinmeters = distance($minlat, $minlon, $minlat, $maxlon);
foreach (array_reverse($metersperpixel, true) as $zoomLevel => $maxdistance) { foreach (array_reverse($metersperpixel, true) as $zoomLevel => $maxdistance) {
if ($zoom == 0 && $mapwidthinmeters < ($maxdistance + 50)) $zoom = $zoomLevel; if ($zoom == 0 && $mapwidthinmeters < ($maxdistance + 50)) $zoom = $zoomLevel;
} }
} }
$center = $totalLat / sizeof($mapPoints) . "," . $totalLon / sizeof($mapPoints); $center = $totalLat / sizeof($mapPoints) . "," . $totalLon / sizeof($mapPoints);
} }
$output = ""; $output = "";
if ($collapsible) $output.= '<div data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>'; if ($collapsible) $output.= '<div data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>';
$output.= '<center><img src="' . curPageURL() . 'lib/staticmaplite/staticmap.php?center=' . $center . '&zoom=' . $zoom . '&size=' . $width . 'x' . $height . '&maptype=mapnik&markers=' . $output.= '<center><img src="' . curPageURL() . 'lib/staticmaplite/staticmap.php?center=' . $center . '&zoom=' . $zoom . '&size=' . $width . 'x' . $height . '&markers=' .
$markers . '" width=' . $width . ' height=' . $height . '></center>'; $markers . '" width=' . $width . ' height=' . $height . '></center>';
if ($collapsible) $output.= '</div>'; if ($collapsible) $output.= '</div>';
return $output; return $output;
} }
function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false) function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false)
{ {
$pi80 = M_PI / 180; $pi80 = M_PI / 180;
$lat1*= $pi80; $lat1*= $pi80;
$lng1*= $pi80; $lng1*= $pi80;
$lat2*= $pi80; $lat2*= $pi80;
$lng2*= $pi80; $lng2*= $pi80;
$r = 6372.797; // mean radius of Earth in km $r = 6372.797; // mean radius of Earth in km
$dlat = $lat2 - $lat1; $dlat = $lat2 - $lat1;
$dlng = $lng2 - $lng1; $dlng = $lng2 - $lng1;
$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2); $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2);
$c = 2 * atan2(sqrt($a) , sqrt(1 - $a)); $c = 2 * atan2(sqrt($a) , sqrt(1 - $a));
$km = $r * $c; $km = $r * $c;
if ($roundLargeValues) { if ($roundLargeValues) {
if ($km < 1) return floor($km * 1000); if ($km < 1) return floor($km * 1000);
else return round($km,2)."k"; else return round($km,2)."k";
} else return floor($km * 1000); } else return floor($km * 1000);
} }
function decodePolylineToArray($encoded) function decodePolylineToArray($encoded)
{ {
// source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5 // source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5
$length = strlen($encoded); $length = strlen($encoded);
$index = 0; $index = 0;
$points = array(); $points = array();
$lat = 0; $lat = 0;
$lng = 0; $lng = 0;
while ($index < $length) { while ($index < $length) {
// Temporary variable to hold each ASCII byte. // Temporary variable to hold each ASCII byte.
$b = 0; $b = 0;
// The encoded polyline consists of a latitude value followed by a // The encoded polyline consists of a latitude value followed by a
// longitude value. They should always come in pairs. Read the // longitude value. They should always come in pairs. Read the
// latitude value first. // latitude value first.
$shift = 0; $shift = 0;
$result = 0; $result = 0;
do { do {
// The `ord(substr($encoded, $index++))` statement returns the ASCII // The `ord(substr($encoded, $index++))` statement returns the ASCII
// code for the character at $index. Subtract 63 to get the original // code for the character at $index. Subtract 63 to get the original
// value. (63 was added to ensure proper ASCII characters are displayed // value. (63 was added to ensure proper ASCII characters are displayed
// in the encoded polyline string, which is `human` readable) // in the encoded polyline string, which is `human` readable)
$b = ord(substr($encoded, $index++)) - 63; $b = ord(substr($encoded, $index++)) - 63;
// AND the bits of the byte with 0x1f to get the original 5-bit `chunk. // AND the bits of the byte with 0x1f to get the original 5-bit `chunk.
// Then left shift the bits by the required amount, which increases // Then left shift the bits by the required amount, which increases
// by 5 bits each time. // by 5 bits each time.
// OR the value into $results, which sums up the individual 5-bit chunks // OR the value into $results, which sums up the individual 5-bit chunks
// into the original value. Since the 5-bit chunks were reversed in // into the original value. Since the 5-bit chunks were reversed in
// order during encoding, reading them in this way ensures proper // order during encoding, reading them in this way ensures proper
// summation. // summation.
$result|= ($b & 0x1f) << $shift; $result|= ($b & 0x1f) << $shift;
$shift+= 5; $shift+= 5;
} }
// Continue while the read byte is >= 0x20 since the last `chunk` // Continue while the read byte is >= 0x20 since the last `chunk`
// was not OR'd with 0x20 during the conversion process. (Signals the end) // was not OR'd with 0x20 during the conversion process. (Signals the end)
while ($b >= 0x20); while ($b >= 0x20);
// Check if negative, and convert. (All negative values have the last bit // Check if negative, and convert. (All negative values have the last bit
// set) // set)
$dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1)); $dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1));
// Compute actual latitude since value is offset from previous value. // Compute actual latitude since value is offset from previous value.
$lat+= $dlat; $lat+= $dlat;
// The next values will correspond to the longitude for this point. // The next values will correspond to the longitude for this point.
$shift = 0; $shift = 0;
$result = 0; $result = 0;
do { do {
$b = ord(substr($encoded, $index++)) - 63; $b = ord(substr($encoded, $index++)) - 63;
$result|= ($b & 0x1f) << $shift; $result|= ($b & 0x1f) << $shift;
$shift+= 5; $shift+= 5;
} while ($b >= 0x20); } while ($b >= 0x20);
$dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1)); $dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1));
$lng+= $dlng; $lng+= $dlng;
// The actual latitude and longitude values were multiplied by // The actual latitude and longitude values were multiplied by
// 1e5 before encoding so that they could be converted to a 32-bit // 1e5 before encoding so that they could be converted to a 32-bit
// integer representation. (With a decimal accuracy of 5 places) // integer representation. (With a decimal accuracy of 5 places)
// Convert back to original values. // Convert back to original values.
$points[] = array( $points[] = array(
$lat * 1e-5, $lat * 1e-5,
$lng * 1e-5 $lng * 1e-5
); );
} }
return $points; return $points;
} }
function geocode($query, $giveOptions) function geocode($query, $giveOptions)
{ {
global $cloudmadeAPIkey; global $cloudmadeAPIkey;
$url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?query=" . urlencode($query) . "&bbox=-35.5,149.00,-35.15,149.1930&return_location=true&bbox_only=true"; $url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?query=" . urlencode($query) . "&bbox=-35.5,149.00,-35.15,149.1930&return_location=true&bbox_only=true";
$contents = json_decode(getPage($url)); $contents = json_decode(getPage($url));
if ($giveOptions) return $contents->features; if ($giveOptions) return $contents->features;
elseif (isset($contents->features[0]->centroid)) return $contents->features[0]->centroid->coordinates[0] . "," . $contents->features[0]->centroid->coordinates[1]; elseif (isset($contents->features[0]->centroid)) return $contents->features[0]->centroid->coordinates[0] . "," . $contents->features[0]->centroid->coordinates[1];
else return ""; else return "";
} }
function reverseGeocode($lat, $lng) function reverseGeocode($lat, $lng)
{ {
global $cloudmadeAPIkey; global $cloudmadeAPIkey;
$url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?around=" . $lat . "," . $lng . "&distance=closest&object_type=road"; $url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?around=" . $lat . "," . $lng . "&distance=closest&object_type=road";
$contents = json_decode(getPage($url)); $contents = json_decode(getPage($url));
return $contents->features[0]->properties->name; return $contents->features[0]->properties->name;
} }
?> ?>
   
<?php <?php
   
/** /**
* staticMapLite 0.02 * staticMapLite 0.02
* *
* Copyright 2009 Gerhard Koch * Copyright 2009 Gerhard Koch
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
* @author Gerhard Koch <gerhard.koch AT ymail.com> * @author Gerhard Koch <gerhard.koch AT ymail.com>
* *
* USAGE: * 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 * 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); error_reporting(0);
ini_set('display_errors','off'); ini_set('display_errors','off');
   
Class staticMapLite { Class staticMapLite {
   
protected $tileSize = 256; protected $tileSize = 256;
protected $tileSrcUrl = array( 'mapnik' => 'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png', protected $tileSrcUrl = array( 'mapnik' => 'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png',
'osmarenderer' => 'http://c.tah.openstreetmap.org/Tiles/tile/{Z}/{X}/{Y}.png', 'cloudmade' => 'http://b.tile.cloudmade.com/daa03470bb8740298d4b10e3f03d63e6/1/256/{Z}/{X}/{Y}.png',);
'cycle' => 'http://c.andy.sandbox.cloudmade.com/tiles/cycle/{Z}/{X}/{Y}.png'  
); protected $tileDefaultSrc = 'cloudmade';
   
protected $tileDefaultSrc = 'mapnik';  
protected $markerBaseDir = 'images/markers'; protected $markerBaseDir = 'images/markers';
protected $osmLogo = 'images/osm_logo.png'; protected $osmLogo = 'images/osm_logo.png';
   
protected $useTileCache = true; protected $useTileCache = true;
protected $tileCacheBaseDir = './cache/tiles'; protected $tileCacheBaseDir = './cache/tiles';
   
protected $useMapCache = true; protected $useMapCache = true;
protected $mapCacheBaseDir = './cache/maps'; protected $mapCacheBaseDir = './cache/maps';
protected $mapCacheID = ''; protected $mapCacheID = '';
protected $mapCacheFile = ''; protected $mapCacheFile = '';
protected $mapCacheExtension = 'png'; protected $mapCacheExtension = 'png';
protected $zoom, $lat, $lon, $width, $height, $markers, $image, $maptype; protected $zoom, $lat, $lon, $width, $height, $markers, $image, $maptype;
protected $centerX, $centerY, $offsetX, $offsetY; protected $centerX, $centerY, $offsetX, $offsetY;
   
public function __construct(){ public function __construct(){
$this->zoom = 0; $this->zoom = 0;
$this->lat = 0; $this->lat = 0;
$this->lon = 0; $this->lon = 0;
$this->width = 500; $this->width = 500;
$this->height = 350; $this->height = 350;
$this->markers = array(); $this->markers = array();
$this->maptype = $this->tileDefaultSrc; $this->maptype = $this->tileDefaultSrc;
} }
public function parseParams(){ public function parseParams(){
global $_GET; global $_GET;
// get zoom from GET paramter // get zoom from GET paramter
$this->zoom = $_GET['zoom']?intval($_GET['zoom']):0; $this->zoom = $_GET['zoom']?intval($_GET['zoom']):0;
if($this->zoom>18)$this->zoom = 18; if($this->zoom>18)$this->zoom = 18;
// get lat and lon from GET paramter // get lat and lon from GET paramter
list($this->lat,$this->lon) = split(',',$_GET['center']); list($this->lat,$this->lon) = split(',',$_GET['center']);
$this->lat = floatval($this->lat); $this->lat = floatval($this->lat);
$this->lon = floatval($this->lon); $this->lon = floatval($this->lon);
// get zoom from GET paramter // get zoom from GET paramter
if($_GET['size']){ if($_GET['size']){
list($this->width, $this->height) = split('x',$_GET['size']); list($this->width, $this->height) = split('x',$_GET['size']);
$this->width = intval($this->width); $this->width = intval($this->width);
$this->height = intval($this->height); $this->height = intval($this->height);
} }
if($_GET['markers']){ if($_GET['markers']){
$markers = split('%7C|\|',$_GET['markers']); $markers = split('%7C|\|',$_GET['markers']);
foreach($markers as $marker){ foreach($markers as $marker){
list($markerLat, $markerLon, $markerImage) = split(',',$marker); list($markerLat, $markerLon, $markerImage) = split(',',$marker);
$markerLat = floatval($markerLat); $markerLat = floatval($markerLat);
$markerLon = floatval($markerLon); $markerLon = floatval($markerLon);
$markerImage = basename($markerImage); $markerImage = basename($markerImage);
$this->markers[] = array('lat'=>$markerLat, 'lon'=>$markerLon, 'image'=>$markerImage); $this->markers[] = array('lat'=>$markerLat, 'lon'=>$markerLon, 'image'=>$markerImage);
} }
} }
if($_GET['maptype']){ if($_GET['maptype']){
if(array_key_exists($_GET['maptype'],$this->tileSrcUrl)) $this->maptype = $_GET['maptype']; if(array_key_exists($_GET['maptype'],$this->tileSrcUrl)) $this->maptype = $_GET['maptype'];
} }
} }
   
public function lonToTile($long, $zoom){ public function lonToTile($long, $zoom){
return (($long + 180) / 360) * pow(2, $zoom); return (($long + 180) / 360) * pow(2, $zoom);
} }
   
public function latToTile($lat, $zoom){ public function latToTile($lat, $zoom){
return (1 - log(tan($lat * pi()/180) + 1 / cos($lat* pi()/180)) / pi()) /2 * pow(2, $zoom); return (1 - log(tan($lat * pi()/180) + 1 / cos($lat* pi()/180)) / pi()) /2 * pow(2, $zoom);
} }
   
public function initCoords(){ public function initCoords(){
$this->centerX = $this->lonToTile($this->lon, $this->zoom); $this->centerX = $this->lonToTile($this->lon, $this->zoom);
$this->centerY = $this->latToTile($this->lat, $this->zoom); $this->centerY = $this->latToTile($this->lat, $this->zoom);
$this->offsetX = floor((floor($this->centerX)-$this->centerX)*$this->tileSize); $this->offsetX = floor((floor($this->centerX)-$this->centerX)*$this->tileSize);
$this->offsetY = floor((floor($this->centerY)-$this->centerY)*$this->tileSize); $this->offsetY = floor((floor($this->centerY)-$this->centerY)*$this->tileSize);
} }
   
public function createBaseMap(){ public function createBaseMap(){
$this->image = imagecreatetruecolor($this->width, $this->height); $this->image = imagecreatetruecolor($this->width, $this->height);
$startX = floor($this->centerX-($this->width/$this->tileSize)/2); $startX = floor($this->centerX-($this->width/$this->tileSize)/2);
$startY = floor($this->centerY-($this->height/$this->tileSize)/2); $startY = floor($this->centerY-($this->height/$this->tileSize)/2);
$endX = ceil($this->centerX+($this->width/$this->tileSize)/2); $endX = ceil($this->centerX+($this->width/$this->tileSize)/2);
$endY = ceil($this->centerY+($this->height/$this->tileSize)/2); $endY = ceil($this->centerY+($this->height/$this->tileSize)/2);
$this->offsetX = -floor(($this->centerX-floor($this->centerX))*$this->tileSize); $this->offsetX = -floor(($this->centerX-floor($this->centerX))*$this->tileSize);
$this->offsetY = -floor(($this->centerY-floor($this->centerY))*$this->tileSize); $this->offsetY = -floor(($this->centerY-floor($this->centerY))*$this->tileSize);
$this->offsetX += floor($this->width/2); $this->offsetX += floor($this->width/2);
$this->offsetY += floor($this->height/2); $this->offsetY += floor($this->height/2);
$this->offsetX += floor($startX-floor($this->centerX))*$this->tileSize; $this->offsetX += floor($startX-floor($this->centerX))*$this->tileSize;
$this->offsetY += floor($startY-floor($this->centerY))*$this->tileSize; $this->offsetY += floor($startY-floor($this->centerY))*$this->tileSize;
   
for($x=$startX; $x<=$endX; $x++){ for($x=$startX; $x<=$endX; $x++){
for($y=$startY; $y<=$endY; $y++){ for($y=$startY; $y<=$endY; $y++){
$url = str_replace(array('{Z}','{X}','{Y}'),array($this->zoom, $x, $y), $this->tileSrcUrl[$this->maptype]); $url = str_replace(array('{Z}','{X}','{Y}'),array($this->zoom, $x, $y), $this->tileSrcUrl[$this->maptype]);
$tileImage = imagecreatefromstring($this->fetchTile($url)); $tileImage = imagecreatefromstring($this->fetchTile($url));
$destX = ($x-$startX)*$this->tileSize+$this->offsetX; $destX = ($x-$startX)*$this->tileSize+$this->offsetX;
$destY = ($y-$startY)*$this->tileSize+$this->offsetY; $destY = ($y-$startY)*$this->tileSize+$this->offsetY;
imagecopy($this->image, $tileImage, $destX, $destY, 0, 0, $this->tileSize, $this->tileSize); imagecopy($this->image, $tileImage, $destX, $destY, 0, 0, $this->tileSize, $this->tileSize);
} }
} }
} }