There are a number of great online GIS ( Geographic Information System ) solutions
out there, ranging from Mappoint to Mapquest to some cool PHP projects. However,
it is still nice to be able to plot your own data and put some basic
mapping utilities on your site with a minimum of fuss and bother. Over the next
couple of articles I will hopefully be able to give you a few pointers on how
to create your own basic GIS system for free. I do not claim to be a GIS expert,
and there may be better ways to do things, but hopefully these articles will
give you a start in the right direction.
In this article we will start with the absolute basics - plotting a single
location on a pre drawn map of the world. Later articles will go into drawing
vector maps, drawing roads and rivers and labeling objects all using the principles
in this article.
For this article you will need:
PHP with GD installed
A pair of scissors
And, an adult to help you.
Finding your place in this world
To plot an object on any map, be it a house or a herd of caramelized Wombats,
the object needs to be geocoded - that is have a map coordinate allocated to
it. For all examples we used a standard longitude (long) and latitude (lat)
coordinate. There a numerous other coordinate systems out there - some a lot
more accurate, but this is the most common, the easiest to plot and suits our
needs. The downside of directly plotting long/lat coordinates is that you will
get distortion as you near the poles. However, for our uses this doesn't pose
a problem.
The two coordinates of a longitude and latitude refer to the angle in degrees
from the equatorial plane of the earth, both up and down. Longitude lines extend
from pole to pole giving us an "X" coordinate, Latitude lines give
us the "Y" coordinate. These can either be written as a decimal value
( ie 23.323232 ) or as degrees, minutes and seconds ( D'M'S ). For storing our
coordinates we used the decimal version as it's a lot easier and saves a lot
of processing time. There are a number of sites with Javascript utilities which
will convert coordinates from D'M'S ( degrees, minutes and seconds ) to the
decimal format. I happen to use a Sharp EL-546 scientific calculator which has
the function built in.
There are a number of ways to finding the long/lat of a point in the world,
however a quick and easy way is to used Microsofts online GIS service Mappoint
( www.mappoint.com ). Find your location using Mappoint search utilities and
make sure it is in the center of the map. Right mouse click on the map, and
you will find long/lat coordinates embedded in the URL of the map image. It
is also worth looking at www.geogratis.com, plus a number of government operated
environmental sites will have map data which you can download for free. Those
of you who have Mapinfo will also find very useful geocoded data on the sample
discs which come with it.
The point we are plotting for this article is my 64 bedroom mansion, located
in the bustling urban metropolis which is Prince Edward Island, Canada. Using
Mappoint I have discovered my location is:
Longitude: -63.10774861954596
Latitude: 46.2899306519141
We now need a base map to plot our point on. In future articles we will generate
this ourselves, however to start we will use a simple pre drawn JPG file. The
base map we are using is called earth_310.jpg, and is and view of the earth
in what is called a Cylindrical projection.
The original of this image can be found in various forms all over the web in
various sizes and scales. A cylindrical projection is the simplest projection
to plot long/lat coordinates onto, again with a minimum of conversion needed
reducing processor overhead. For our purposes you can simply right click the
image and "Save picture as ..." to your hard drive.
The base map is scaled to 310x155 for ease of use, but you can rescale this
map to any size.
We are now ready to generate the code to plot our point.
Plots and Schemes
The basic steps for generating the map are:
- Load the background map.
- Convert and scale the long/lat coordinates to screen coordinates.
- Plot the point.
- Return the finished map as an image.
To convert the long/lat to screen coordinate we have a created a function called
getlocationcoords. This takes the longitude and latitude coordinates
plus the size of the base map and return the screen coordinates in an associative
array. $width and $height are calculated from the
size of the background image. In future projects these variables are used scale
the map and set the zoom level.
<?php
function getlocationcoords($lat, $lon, $width, $height)
{
$x = (($lon + 180) * ($width / 360));
$y = ((($lat * -1) + 90) * ($height / 180));
return array("x"=>round($x),"y"=>round($y));
}
?>
Once the coordinates have been converted it's as simple as drawing a rectangle
on the base map using the returned array to mark our location.
So, the code to create the map:
<?php
// These are the coordinates the location we wish to plot.<br>
// These are being passed in the URL, but we will set them to a
// default if nothing is passed.
if(empty($long))$long = -63.10774861954596;
if(empty($lat)) $lat = 46.2899306519141;
// First we load the background/base map. We assume it's located in same dir
// as the script.
// This can be any format but we are using JPG in this example
// We will also allocate the color for the marker
$im = imagecreatefromjpeg("earth_310.jpg");
$red = imagecolorallocate ($im, 255,0,0);
// Next need to find the base image size.
// We need these variables to be able scale the long/lat coordinates.
$scale_x = imagesx($im);
$scale_y = imagesy($im);
// Now we convert the long/lat coordinates into screen coordinates
$pt = getlocationcoords($lat, $long, $scale_x, $scale_y);
// Now mark the point on the map using a red 4 pixel rectangle
imagefilledrectangle($im,$pt["x"]-2,$pt["y"]-2,$pt["x"]+2,$pt["y"]+2,$red);
// Return the map image. We are using a PNG format as it gives better final
image quality than a JPG
header ("Content-type: image/png");
imagepng($im);
imagedestroy($im);
?>
To load the map call the PHP code from an IMG tag, passing the longitude and
latitude in the long and lat variables:
<img src="map_code.php?long=long&lat=lat">
You could easily modify this code to read long/lat coordinates from a database
or a delimited text file and plot multiple points.
Summary
This is a very basic script. However the basic principle will allow you to draw
very complicated maps.
The important part is the getlocationcoords
function - once you have geocoded your data and have the routines to plot the
points on the screen, the sky's the limit!