March 23, 2004

Open Source GIS Mapping

Geographic Information Systems (GIS) are growing in popularity. Commercial and goverment interests alike are investing heavily in mapping software such as ArcView. A single day doesn't go by without someone sending me directions generated by MapQuest. Oddly enough, Mapquest's aerial views seem to have mysteriously disappeared after the formation of the Department of Homeland Security. Wonder why that is? Here's what most people don't know: GIS doesn't have to be done by proprietary software, or be an expensive endeavor. GeoURL ICBM Address Server plots the physical location of web sites, using freely available data. Here's how you can do it too, using widely available software and data.

While this may not be exactly how GeoURL works, the concepts are very similar. First, you'll need to acquire a few pieces before being able to plot points.

PHP

Before you start, you'll need a copy of PHP compiled the GD Graphics Library (usually by running ./configure --with-gd). Follow the directions and get it working correctly before proceding.

A Map

You'll need a map to plot the points on, else you'll have a bunch of points hanging in mid-air. Cool, but not very functional or impressive. NASA's Earth Observatory offers true-color global imagery at no cost. The images are of excellent quality and there are several versions you can choose from. We like the Land Surface, Shallow Water, and Shaded Topography map, a 230KB JPEG that is 2048 pixels wide by 1024 pixels tall (which can be downloaded directly).

Coordinates

Find out your current location in a latitude and longitude format. geoURL's resources can be of help there. In the future you may wish to pull these values from a database of some sort, but for now we'll show you how to plot a single point. We recommend using SideBit's Project Locate. Just punch in your zip code. We'll use 78621 as an example.

Showing: ELGIN, TX at 30.323136, -97.373748

The first value is the latitude, the second the longitude.

The Plotting Script

The script to do this - which we've called plot.php - is relatively small, a few lines at most. It's commented, showing you exactly what every line is doing. As you can see, we've included our coordinates from the last step.

<?php
Header("Content-type: image/png");

$lat = "30.323136";
$long = "-97.373748";

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));
}

// Create a blank image.
$im = imagecreate(2048,1024);

// Allocate the colors we need.
$black = imagecolorallocate ($im, 0,0,0);
$red = imagecolorallocate ($im, 255,0,0);

// Fill the entire image with black pixels.
imagefill($im,0,0,$black);

// Convert our coordinated into pixel notation.
$pt = getlocationcoords($lat, $long, 2048, 1024);

// Flip a single red pixel.
imagesetpixel($im,$pt["x"],$pt["y"],$red);

// Take all the remaining black pixels and make them transparent.
ImageColorTransparent($im,$black);

// Create the image.
imagepng($im,'',100);

// Destroy the image and clear up the memory.
imagedestroy($im);
?>

A Display Method

As you can see, we create the dot on an transparent overlay. This is a lot faster than sampling the original image, adding a pixel, and then re-creating the image. The original image is large enough without PHP's inefficient sampling algorithms, which can easily double the size of the original image with no apparent gain. So we stick the overlay image over an otherwise empty table block, which happens to have our original map set as the background. Simple and efficient, and it works in most browsers.

<table border=0 cellspacing=0 cellpadding=0>
  <tr>
    <td background="land_shallow_topo_2048.jpg">
      <img src="plot.php">
    </td>
  </tr>
</table>

And that's all it takes to create a simple map with a point on it. To add this to a production site, we would not recommend generating the overlay on-the-fly, as the load can add up as you begin to plot more points. Instead we'd run the script from the command line (or crontab), ala php plot.php > plot.png and then change our HTML to refer to the now-static image. Integrating zipcode/coordinate data (such as TIGER/Line) would be the next step, as would pulling coordinates from an array (or even a database).

Posted by alexm at March 23, 2004 03:58 PM.
Send comments/suggestions to contact@moundalexis.com.
Add to del.icio.us | Digg this | Subscribe to this feed
Comments