PHP DevCenter

oreilly.comSafari Books Online.Conferences.

We've expanded our LAMP news coverage and improved our search! Search for all things LAMP across O'Reilly!

Search
Search Tips

advertisement

Listen Print Subscribe to PHP Subscribe to Newsletters
PHP Cookbook

Trip Mapping with PHP

by David Sklar, coauthor of PHP Cookbook
11/07/2002

Remember Raiders of the Lost Ark? One of the distinctive images was a thick red line cruising across a map, showing Indiana Jones' routes when crisscrossing the globe and fighting bad guys. I don't think they used PHP for any of the special effects in 1981, but you can use PHP today to create a similar map of the United States.

To draw lines in the right places, you need a few things: data describing the location of U.S. places, a blank map image, and a short PHP program to draw the lines where you want them.

Data

First, you need a way to locate different places in the United States. The Census Bureau has already done this. The Gazetteer data file (zcta5.zip) contains information (including longitude and latitude) about over 30,000 US ZIP codes. The Gazetteer page explains the file format:

Columns 1-2:     United States Postal Service State Abbreviation 
Columns 3-66:    Name 
Columns 67-75:   Total Population (2000) 
Columns 76-84:   Total Housing Units (2000) 
Columns 85-98:   Land Area (square meters) 
Columns 99-112:  Water Area (square meters) 
Columns 113-124: Land Area (square miles) 
Columns 125-136: Water Area (square miles) 
Columns 137-146: Latitude (decimal degrees) First character is blank or "-"
                 denoting North or South latitude respectively 
Columns 147-157: Longitude (decimal degrees) First character is blank or "-" 
                 denoting East or West longitude respectively

The zcta5.zip Gazetteer file unzips to zcta.txt. A line of the text file looks like this (without the linebreaks):

PA19096 5-Digit ZCTA                                                  
13299     5456       8907922             0    3.439368    
0.000000 39.992345 -75.276248

The first five characters of the Name field are the ZIP code. To draw lines in the right places on your map, you just need the ZIP code, the longitude, and the latitude. Store the data in this zcta table:

CREATE TABLE zcta (
	zip CHAR(5) NOT NULL,
	lat DECIMAL(12,2) NOT NULL,
	lon DECIMAL(12,2) NOT NULL,
	KEY(zip)
);

This short PHP program parses the file and inserts information into the zcta table. You should change the DSN passed to DB::connect() to have the correct configuration settings for your database.

require 'DB.php';
$dbh = DB::connect('mysql://test:@localhost/test');

$fh = fopen('zcta5.txt','r') or die("can't open: $php_errormsg");
while ($s = fgets($fh, 256)) {
    if (preg_match('/^\d{5}$/',$zip = substr($s,2,5))) {
        $q = $dbh->query(
        'INSERT INTO zcta (zip,lat,lon) VALUES (?,?,?)',
        array($zip,substr($s,136,10),substr($s,146,11)));
        
        if (DB::isError($q)) {
            print_r($q);
            die();
        }
    }
}
fclose($fh);

Some of the entries in the file have some alphabetical characters in the ZIP codes. These seem to be consolidations of metropolitan areas. We want only actual ZIP codes in our table, so we'll use the regular expression /^\d{5}$/ to filter out ZIP codes that aren't just five digits. ZIP codes that match go into the database along with their latitudes and longitudes.

The line:

if (preg_match('/^\d{5}$/',$zip = substr($s,2,5))) {

takes advantage of a shortcut in PHP that an assignment operation also returns the value being assigned. $zip = substr($s,2,5) assigns the five-character substring of the line that holds the ZIP code to $zip. The value of the entire expression "$zip = substr($s,2,5)" is also that substring, so preg_match() thinks its second argument is the value of $zip. If this value matches the regular expression, then preg_match() returns true. You can do the same thing in multiple steps:

$zip = substr($s,2,5);
if (preg_match('/^\d{5}$/',$zip)) {

If the ZIP code passes numeric muster, then it goes into the database:

$q = $dbh->query(
	'INSERT INTO zcta (zip,lat,lon) VALUES (?,?,?)',
	array($zip,substr($s,136,10),substr($s,146,11)));

The first argument to the PEAR DB query() method is a SQL statement. Here, ? is a placeholder. When the query is executed, the placeholders are replaced with the values in the array passed as the second argument to query(): the ZIP code, the longitude, and the latitude. substr() extracts the longitude and latitude.

PHP Cookbook

Related Reading

PHP Cookbook
By David Sklar, Adam Trachtenberg


Read Online--Safari
Search this book on Safari:
 

Code Fragments only

Pages: 1, 2

Next Pagearrow




Tagged Articles

Post to del.icio.us

This article has been tagged:

gis

Articles that share the tag gis:

An Introduction to Open Source Geospatial Tools (56 tags)

Build AJAX-Based Web Maps Using ka-Map (28 tags)

Hacking Maps with the Google Maps API (18 tags)

The Geospatial Web: A Call to Action (16 tags)

Mapping and Markup, Part 1 (10 tags)

View All

php

Articles that share the tag php:

Understanding MVC in PHP (477 tags)

The PHP Scalability Myth (123 tags)

The Dynamic Duo of PEAR::DB and Smarty (53 tags)

PHP Form Handling (43 tags)

Very Dynamic Web Interfaces (39 tags)

View All

map

Articles that share the tag map:

Hacking Maps with the Google Maps API (10 tags)

An Introduction to Open Source Geospatial Tools (5 tags)

Trip Mapping with PHP (5 tags)

Build AJAX-Based Web Maps Using ka-Map (4 tags)

Historical Maps Online (2 tags)

View All

tutorial

Articles that share the tag tutorial:

Rolling with Ruby on Rails (1417 tags)

A Simpler Ajax Path (135 tags)

Ajax on Rails (88 tags)

Rolling with Ruby on Rails, Part 2 (66 tags)

Very Dynamic Web Interfaces (66 tags)

View All

webdev

Articles that share the tag webdev:

Rolling with Ruby on Rails (351 tags)

Very Dynamic Web Interfaces (163 tags)

Understanding MVC in PHP (96 tags)

A Simpler Ajax Path (93 tags)

Ajax on Rails (61 tags)

View All

Sponsored Resources

  • Inside Lightroom
Advertisement

Sponsored by:

O'Reilly Media

©2009, O'Reilly Media, Inc.
(707) 827-7000 / (800) 998-9938
All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.
About O'Reilly
Academic Solutions
Authors
Contacts
Customer Service
Jobs
Newsletters
O'Reilly Labs
Press Room
Privacy Policy
RSS Feeds
Terms of Service
User Groups
Writing for O'Reilly
Content Archive
Business Technology
Computer Technology
Google
Microsoft
Mobile
Network
Operating System
Digital Photography
Programming
Software
Web
Web Design
More O'Reilly Sites
O'Reilly Radar
Ignite
Tools of Change for Publishing
Digital Media
Inside iPhone
O'Reilly FYI
makezine.com
craftzine.com
hackszine.com
perl.com
xml.com

Partner Sites
InsideRIA
java.net
O'Reilly Insights on Forbes.com