Dashboard | Help Login

blogs@bluerhinos.co.uk

Think Blue
The thinkings from the coders at bluerhinos.co.uk

Search
Archives
January 2010 (1)
November 2009 (1)
July 2009 (1)
January 2009 (3)
December 2008 (1)
Sections
Code Tutorial (3)
Misc (2)
QRCode Button (1)
Server Admin (1)
Os
Debian (1)
Code Tags
PHP (2)
Mysql (1)
Tools
Show/Hide QR Code
Show/Hide Keys
Plotting on a World Map
7th January 2009 @ 17:34
Code Tags: PHP;Mysql
I needed to plot visitors to a web site onto a world map to demonstrate world wide coverage. I had an initial google around and couldn't really find anything. It didn't take too long to realise what i needed to make this work with my own script. I also chose to make it pretty so have gone for a lights at night look.
Plotting on a World Map (Website Visitors)


Problem
* Put locations of visitors (for which i already had in a mysql database) on to a world map.

Pre-Requisites
* The data (this example will assume from mysql)
* A World Map (I have gone for "AVHRR Pathfinder" shot from here) the bigger the better)
* PHP with gd2 (I run this from the command line as it might take a while to render)

Understanding the Maths
Firstly to make this work you need a linear cylindrical (latitude/longitude) projection world map, the ones from the source outlined above are. This means that the latitude/longitude are directly proportional to the x/y of the image. So if you have the dimensions the image as $img_x, $img_y you can then plot a long/lat with this:
php code:
$pos_x = (int)(($img_x/2) + (($row['long']/180)*($img_x/2)));
$pos_y = (int)(($img_y/2) - (($row['lat']/90)*($img_y/2)));

For Longitude ($row['long']): the range is from -180°:180° so the above code work out the equivalent x position on the image. The same applies for Latitude($row['long']) with the range -90°:90°

With this sorted the rest of the code is simple.

The Code
php code:
//Setup Image
$imagein = "PathfinderMap.jpg";
$imageout = "output.jpg";
 
//Get Image Dimentions
list($img_x,$img_y) = getimagesize($imagein);
 
//Load in image
$im = imagecreatefromjpeg($imagein);
 
//Make Image "Night time"
$darkblue = imagecolorallocatealpha($im, 0x00, 0x00, 0x00, 25);
imagefilledrectangle($im, 0, 0, $img_x,$img_y, $darkblue);
 
//Mysql Bit
$mysqli = new mysqli("**","**","**","**");
if ($mysqli->connect_error) {
printf("Connect failed: %sn", mysqli_connect_error());
exit();
}
 
$sql = "** Protected for Security **";
 
 
if ($result = $mysqli->query($sql)) {
 
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
 
// work out long/lat on image
$pos_x = (int)(($img_x/2) + (($row['long']/180)*($img_x/2)));
$pos_y = (int)(($img_y/2) - (($row['lat']/90)*($img_y/2)));
 
//if two positions share the same pixel then combine the result
if(!isset($data["{$pos_x}_{$pos_y}"])){
$data["{$pos_x}_{$pos_y}"] = $row['Rows'];
}else{
$data["{$pos_x}_{$pos_y}"] += $row['Rows'];
}
 
}
//free result set
$result->close();
 
}
 
// close connection
$mysqli->close();
 
//Size of data array
$count = count($data);
 
echo "\n"; //debug
 
foreach($data as $key=>$value){
//Decides for each value
// $yellow is the light color
// $size is the diameter of the light
if($value>10000){
$yellow = imagecolorallocatealpha($im, 0xFF, 0xFF, 0x00,0);
$size = 15;
}elseif($value>1000){
$yellow = imagecolorallocatealpha($im, 0xFF, 0xFF, 0x00,0);
$size = 10;
}elseif($value>100){
$yellow = imagecolorallocatealpha($im, 0xFF, 0xFF, 0x00,0);
$size = 7;
}else{
$yellow = imagecolorallocatealpha($im, 0xFF, 0xFF, 0x00,0);
$size = 5;
}
 
// Draw light
list($pos_x,$pos_y) = split("_",$key);
imagefilledellipse($im, $pos_x, $pos_y, $size,$size, $yellow);
 
$i++; //Debug
echo "\r$i/$count (".number_format(($i/$count)*100,1)."%)";
}
 
echo "\rSaving Image this could take a bit\n";
//save Image
imagejpeg($im,$imageout);

So there we go, I welcome any comments.
Attached Files
Plotting on a World Map (Website Visitors)
Plotting on a World Map (Website Visitors) PHP Script
Andrew Milsted | View Source | Code Tutorial | Comments (0)