shapefiles/import.php

Unless stated otherwise, code available for viewing through this tool is dedicated to the public domain. If you have any questions, drop me a line.

<?php

die();

require('../../wp-config.php');

// use PDO for db connection
try {
	$dbh = new PDO('mysql:host=mysql.uwmike.com;dbname=uwmike_maps', DB_USER, DB_PASSWORD);
	$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

	$statement_insert_poly = $dbh->prepare("INSERT INTO shape_polygons (code, source) VALUES (:code, :source)");

	$statement_update_poly_dimensions = $dbh->prepare("UPDATE shape_polygons SET latitude_min = :latitude_min, latitude_max = :latitude_max, longitude_min = :longitude_min, longitude_max = :longitude_max WHERE id = :id");

	$statement_insert_vertex = $dbh->prepare("INSERT INTO shape_vertices (polygon_id, latitude, longitude, ordering) VALUES (:polygon_id, :latitude, :longitude, :ordering)");
} catch (PDOException $e) {
   print "Error: " . $e->getMessage();
   die();
}

$filename = 'output.gpx';

$this_rte = array();
$this_rte_meta = array();

$current_element = '';


function startElement($parser, $name, $attrs)
{
	global $this_rte, $this_rte_meta, $current_element;

	switch($name)
	{
		case 'RTE': $this_rte = $this_rte_meta = array(); break;
		case 'RTEPT': $this_rte[] = array('latitude' => trim($attrs['LAT']), 'longitude' => trim($attrs['LON']));
		case 'NUMBER': 
		case 'NAME':
		case 'CMT':
			$current_element = strtolower($name); 
		break;
	}
}

function characterData($parser, $data)
{
	global $this_rte_meta, $current_element;
	
	if ($current_element != '')
	{
		if (isset($this_rte_meta[$current_element]))
			$this_rte_meta[$current_element] .= $data;
		else
			$this_rte_meta[$current_element] = $data;
	}
}

function endElement($parser, $name)
{
	global $this_rte, $this_rte_meta, $current_element, $statement_insert_vertex,
		$statement_insert_poly, $statement_update_poly_dimensions, $dbh;

	if ('RTE' == $name) 
	{
		// store this shape in SQL, use a transaction so we don't end up with dangling records.
		$dbh->beginTransaction();
		$statement_insert_poly->execute(array('code' => 'US.States.' . $this_rte_meta['name'], 'source' => $filename));
		
		$poly = array(
			'id' => $dbh->lastInsertId(),
			'latitude_min' => 90,
			'latitude_max' => -90,
			'longitude_min' => 180,
			'longitude_max' => -180
		);


		foreach($this_rte as $order => $vertex)
		{
			extract($vertex);
			if ($latitude < $poly['latitude_min']) $poly['latitude_min'] = $latitude;
			if ($latitude > $poly['latitude_max']) $poly['latitude_max'] = $latitude;
			if ($longitude < $poly['longitude_min']) $poly['longitude_min'] = $longitude;
			if ($longitude > $poly['longitude_max']) $poly['longitude_max'] = $longitude;
			$vertex['polygon_id'] = $poly['id'];
			$vertex['ordering'] = $order;
			$statement_insert_vertex->execute($vertex);
		}

		$statement_update_poly_dimensions->execute($poly);
		$dbh->commit();

		echo 'Success writing polygon: <strong>'.$this_rte_meta['name'].'</strong><br />';

		unset($this_rte, $this_rte_meta);
	}
	else
	{
		$current_element = '';
	}
}

$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");

if (!($fp = fopen($filename, "r"))) {
   die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
   if (!xml_parse($xml_parser, $data, feof($fp))) {
       die(sprintf("XML error: %s at line %d",
                   xml_error_string(xml_get_error_code($xml_parser)),
                   xml_get_current_line_number($xml_parser)));
   }
}

xml_parser_free($xml_parser);

$dbh = null;

?>