CSC220 Homework 6 Solution 2010
--D. Thiebaut 19:28, 5 November 2010 (UTC)
Solution for Homework #6
One Self-Reloading Form
- In this approach, the two files showMap.htm and outputKml.php have been replaced by one program, now called showMap.php.
- In order to better pass information from the database to GoogleMaps, and to go around the caching that GGeoXml implements, the program works in the following fashion:
- It gets the Id that the user is interested and saves it in the $Id variable
- It fetches a KML file from the database at that $Id
- It stores the KML contents in a local file that is stored in a subdirectory called uploads, which is world-writeable (not very secure solution!)
- The name of that local file is made random by adding a random number to it (before the ".kml" extension). This will force GoogleMaps to load it, as it will never have it in its cache. The filename is of the form "dft_399410603.kml".
- The name of the kml file is saved in a global array that stays on the server between sessions, and called $_SESSION. This is an easy way to pass the name of the random kml file from php to javascript.
- GoogleMaps loads the file from a URL pointing to our own Website.
- Note: You must provide a valid GoogleMaps key in place of the xxxxxxxxxxxxxxx string.
- The source code is below:
<?php
// showMap.php
// D. Thiebaut
// Solution for Hw #6
// Nov. 2010
//
session_start(); // initialize access to the global array $_SESSION
?>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps API Example: GGeoXml KML Overlay</title>
<!-- =================================================================
J A V A S C R I P T
=================================================================
-->
<script src="http://maps.google.com/maps?file=api&v=2&key=xxxxxxxxxxxxxxxxxxx"
type="text/javascript"></script>
<script type="text/javascript">
var map;
var geoXml;
var toggleState = 1;
function initialize() {
if (GBrowserIsCompatible()) {
var url;
url = "http://cs.smith.edu/~220a/mysql/GoogleMaps/uploads/" + "<?php echo $_SESSION[ 'kmlFile' ];?>";
//alert( url );
geoXml = new GGeoXml( url );
map = new GMap2(document.getElementById( "map_canvas" ) );
map.setCenter(new GLatLng(42.32012788333333,-72.6431288999999), 11);
geoXml.gotoDefaultViewport( map );
map.setUIToDefault();
map.addControl(new GLargeMapControl());
map.addOverlay( geoXml );
}
}
function toggleMyKml() {
return;
if (toggleState == 1) {
map.removeOverlay(geoXml);
toggleState = 0;
} else {
map.addOverlay(geoXml);
toggleState = 1;
}
}
</script>
</head>
<?php
// ==================================================
// P H P
// ==================================================
//-----------------------------------------------------
// logit: logs information to a text file. Debugging
//-----------------------------------------------------
date_default_timezone_set( "America/New_York" );
function logit($msg){
$fp = fopen("log.txt","a+");
$msg = date("Y-m-d h:i:s a") . ": " . $msg;
fwrite($fp, $msg."\r\n");
fclose($fp);
}
//-----------------------------------------------------
//-----------------------------------------------------
function connectToMySql( ) {
include 'accessinfo.php';
$database = "220a_hw6";
//--- connect to mysql server ---
$link = mysql_connect( $hostName, $userName, $password );
if ( ! $link )
die( "Could not connect to server: " . $mysql_error() );
//--- select database ---
$database = "220a_hw6";
$db = mysql_select_db( $database, $link );
if ( ! $db )
die( "Could not connect to database " . $database . ": "
. mysql_error() );
return $link;
}
//-----------------------------------------------------
// getKml: get Kml file with Index $Id from database
//-----------------------------------------------------
function getKml( $link, $Id ) {
$query = sprintf( "SELECT `data` from `kmldata` WHERE `Id`='%s'", $Id );
$result = mysql_query( $query, $link );
if ( ! $result )
die( "Invalid query (" . $query . "): " . mysql_error() );
if ( $row = mysql_fetch_array( $result, MYSQL_NUM ) )
return $row[0];
return "";
}
// ---------------------------
// PROGRAM STARTS HERE!
// ---------------------------
$Id = $_REQUEST[ 'Id' ];
if ( ! isset( $Id ) ) {
//--- this must be the very first call. Just show the form ---
?>
<body>
<FORM ACTION="showMap3.php" METHOD="POST">
KML File Id: <INPUT TYPE="text" NAME="Id" VALUE="" SIZE="5"><br />
<INPUT TYPE="SUBMIT" VALUE="Show Map!">
</FORM>
</body>
</html>
<?php
}
else {
//--- the user has picked an Id...
logit( "Requested Id = $Id" );
//--- get kml data ---
$link = connectToMySql();
$kmlData = getKml( $link, $Id );
mysql_close( $link );
//--- store it to file with a random name ---
$fileName = sprintf( "dft_%d.kml", rand() );
//--- pass the $fileName to javascript through the global SESSION array ---
$_SESSION[ 'kmlFile' ] = $fileName;
//--- save kml in temp file in uploads directory ---
//--- (Note: we have to figure out a way to erase old temporary KML files!!!!) ---
file_put_contents( "uploads/" . $fileName, $kmlData );
//--- wait 1/3 of a second to smooth out operation
usleep( 300000 );
//--- open a body that loads up the map ---
?>
<body>
<div id="map_canvas" style="width: 640px; height: 480px;
float:left; border: 1px solid black;"></div>
</div>
<br clear="all"/>
<br/>
<FORM ACTION="showMap3.php" METHOD="POST">
KML File Id: <INPUT TYPE="text" NAME="Id" VALUE="" SIZE="5"><br />
<INPUT TYPE="SUBMIT" VALUE="Show Map!">
</FORM>
<br />
<input type="button" value="Toggle KML" onClick="toggleMyKml();" />
<?php
//--- call the javascript initialize routine() ---
echo "<script language=\"javascript\">initialize()</script>\n";
?>
</body>
</html>
<?php
}
?>
Other Options
- There were several interesting tricks used by various people for various parts of the homework
- Alex passes the Id of the kml data from showMap to outputKml by storing it in a text file in the current directory. That works!
- Alex also uses a random name for saving the kml file (avoiding the caching issues), and passes this name through another dummy text file that is written to by outputKml and read by showMap.
Solution 2
- This one offered by Aigerim and Elizabeth.
- In two parts, showMap.php and outputKml.php
- The php passes the $id of what needs to be fetched directly to the javascript code as it is printing it. In other words the showMap.php file uses php to output the html containing the javascript functions. This way it is easy to pass information from php to Javascript.
- This solution suffers from the caching of GoogleMaps.
outputKML.php
<?php
// outputKML.php
// Elizabeth Do and Aigerim Karabekova
// 220a-aa, 220a-aa
// November 4, 2010
// Obtains KML data from database
include 'accessinfo.php';
$database = "220a_hw6";
$id = $_REQUEST['id'];
//--- connect to mysql server ---
$link = mysql_connect( $hostName, $userName, $password );
if ( ! $link )
die( "Could not connect to server: " . $mysql_error() );
//--- select database ---
$db = mysql_select_db( $database, $link );
if ( ! $db )
die( "Could not connect to database " . $database . ": "
. mysql_error() );
//--- get KML data using id from kmldata table ---
$query = sprintf( "SELECT `data` FROM `kmldata` WHERE `Id`=$id" );
$result = mysql_query( $query, $link );
if ( ! $result )
printf( "Unsuccessful query" );
header('Content-type: application/vnd.google-earth.kml+xml');
$row = mysql_fetch_array($result, MYSQL_NUM);
echo $row[0];
//--- close database ---
mysql_close( $link );
?>
showMap.php
<!-- showMap.php
Homework 6
Elizabeth Do and Aigerim Karabekova
220a-ab and 220a-aa
November 3, 2010
Form that allows a user to enter name and then look at KML
data mapped onto Google map.
-->
<?php
//--------------------------------------------------------------------
// testPage: checks to see if both fields are given. If one or
// more missing.
//--------------------------------------------------------------------
function testPage( $name, $id ) {
if ( !empty( $name ) && !empty( $id )) {
displayFinalPage( $name, $id );
return 2;
}
else{
print "<font color=\"red\"><small>At least one field is empty.</small></font>";
}
$params = 0;
if ( !empty( $name ) ) {
$params++;
}
if ( !empty( $id ) ) {
$params++;
}
return $params;
}
//--------------------------------------------------------------------
// displayFinalpage: displays the Google map with route
// Uses API key to access Google Map
// Retrieves KML file, that corresponds to user-defined id
// from MySQL database using outputKML.php
//--------------------------------------------------------------------
function displayFinalPage( $name, $id ) {
print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\"
xmlns:v=\"urn:schemas-microsoft-com:vml\">
<head>
<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/>
<title>CSC 220 Homework 6 - Map </title>
<script src=\"http://maps.google.com/maps?file=api&v=2&key=ABQIAAAA1hfBOWWxhf2UqkBxdXc1oRTenvGCkuE4L-QveR3t9IDzpHpEURSsoqBnRcnT-8s-k2DUuXyqEJGiLw\"
type=\"text/javascript\"></script>
<script type=\"text/javascript\">
var map;
var geoXml;
var toggleState = 1;
function initialize() {
if (GBrowserIsCompatible()) {
geoXml = new GGeoXml(\"http://maven.smith.edu/~220a-aa/outputKML.php?id=$id\");
map = new GMap2(document.getElementById(\"map_canvas\"));
map.setCenter(new GLatLng(42.32012788333333,-72.6431288999999), 11);
map.setUIToDefault();
map.addControl(new GLargeMapControl());
map.addOverlay(geoXml);
}
}
function toggleMyKml() {
if (toggleState == 1) {
map.removeOverlay(geoXml);
toggleState = 0;
} else {
map.addOverlay(geoXml);
toggleState = 1;
}
}
</script>
</head>
<body onload=\"initialize()\">
<h4>Hi, $name! Thank you for using this service. </h4>
<p>You chose to see trip number $id.
<div id=\"map_canvas\" style=\"width: 640px; height: 480px; float:left; border: 1px solid black;\"></div>
</div>
<br clear=\"all\"/>
<br/>
<input type=\"button\" value=\"Toggle KML\" onClick=\"toggleMyKml();\"/>
</body>
</html>
";
}
//--- get the form parameters ---
$name = $_REQUEST['name'];
$id = $_REQUEST['id'];
//--- did we get both parameters? ---
$noParamsSet = testPage( $name, $id );
//--- HTML code for form ---
if ( $noParamsSet < 2 ) {
printf( '
<HTML>
<HEAD>
<TITLE>CSC 220 Homework 6 - Form</TITLE>
<meta http-equiv="Pragma" content="no-cache">
</HEAD>
<BODY>
<h3> Please provide your name and id of the trip: </h3>
<FORM ACTION="showMap.php" METHOD="POST">
<P>
Name: <INPUT TYPE="text" NAME="name" VALUE="%s" SIZE="40">
<P>
Choose ID (6-18 or 24-28): <INPUT TYPE="text" NAME="id" VALUE="%s" SIZE="10">
<P>
<INPUT TYPE="SUBMIT" VALUE="Send">
</FORM>
<P>
</BODY>
</HTML>
', $name, $id);
}
?>