In this section of this chapter, I’ll walk you through an example that mashes up Flickr, Google Earth, and Google Maps. Specifically, I’ll show you how to query Flickr for public geotagged photos and convert the response to KML that can then be channeled to either Google Earth or Google Maps.
You can see the program that combines this functionality here:
http://examples.mashupguide.net/ch13/flickrgeo.php
And you can see the PHP code here:
http://examples.mashupguide.net/ch13/flickrgeo.php.txt
The flickrgeo.php
script described in this chapter is the same code as that
in Chapter 10.
What you will see is a basic HTML form aimed at a user who already understands the
parameters for the flickr.photos.search
method (http://examples.mashupguide.net/?
ch13/flickrgeo.php
). There are two differences between the parameters used for
Flickrgeo and the Flickr API:
The bbox
parameter used by the Flickr API is broken out into four
individual parameters for Flickrgeo: lat0
, lon0
for the
southwest corner and lat1
, lon1
for the northeast corner of
the bounding box. This approach will be familiar to you from Chapter 10, which
focuses in detail on how to query Flickr for geotagged photos.
Flickrgeo has an o_format
parameter to set the requested output.
Recognized values are html
(for the simple user interface),
rest
(to return the Flickr API in REST format), json
(to
return the results as JSON), nl
(to return a KML NetworkLink), and
kml
(to return the photo data as KML). The appropriate value for
format
is passed to flickr.photos.search
.
When the Flickrgeo form loads, o_format
is set by default to
html
so that you can use the form to enter some values and see some search
results rendered as HTML. For example, the following:
or
displays my public geotagged photos in the Berkeley area. You can change
o_format
to json
and rest
to get JavaScript and
XML versions of this data, respectively; Flickrgeo just passes back the data that comes
from Flickr.
If you set o_format
to kml
, you get the results as a KML feed.
For example, here’s a KML feed of my public geotagged photos in the Berkeley
area:
or
which you can see on Google Maps (see Figure 13-7):[218]
or
If you set o_format
to nl
, you get a KML NetworkLink that
enables you to use Google Earth to interact with Flickrgeo. That is, if you change your
viewpoint on Google Earth, Google Earth will send to Flickrgeo the parameters of your new
viewpoint to get pictures for that new viewpoint.
Hence, Flickrgeo does four major tasks to pull off the mashup:
Querying Flickr for geotagged photos
Converting Flickr results from a single flickr.photos.search
into
the corresponding KML
Generating a KML NetworkLink to feed your actions in Google Earth to Flickrgeo
Knitting together the various possibilities for o_format
into one
script
For the first topic, I refer you to Chapter 10 for a detailed discussion and remind you
that the essential point is that you use the bbox
parameter to specify a
bounding box, add geo
to the extras parameter to get the latitude and
longitude, and set a minimum upload time to something like 820483200 (for January 1, 1996
Pacific Time) to coax some photos from the API when you are not searching on tags or
text.
For the final topic, you can see the logic of what is done by studying the source code.
Next I’ll discuss the topics of KML NetworkLink and generating KML from
flickr.photos.search
results.
So far I have shown you how to write a KML document and render it with Google Earth and Google Maps. In many situations, including the mashup I create here, it’s extremely helpful to get information flowing from Google Earth back to the program that generated the KML in the first place. Foremost among that data would be the current viewpoint of the user. If you as the generator of the KML know the region that the user is focused on, you can generate data that would be visible in that viewpoint.
That’s the purpose of the <NetworkLink>
element in KML. Here
I’ll show you how to use it by example. Load the following into Google
Earth:
http://examples.mashupguide.net/ch13/hello.world.networklink.kml
You will see a pin appear in the middle of your current viewpoint announcing the current time. If you click the pin, you’ll see a list of parameters corresponding to the current viewpoint. If you change the viewpoint and wait a couple of seconds, the pin is refreshed to be located in the center of the new viewpoint. How does this happen?
Let’s look first at this:
http://examples.mashupguide.net/ch13/hello.world.networklink.kml
which is the following:
<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://earth.google.com/kml/2.2"> <NetworkLink> <flyToView>0</flyToView> <name>Hello World</name> <open>1</open> <visibility>1</visibility> <Link> <href>http://examples.mashupguide.net/ch13/hello.world.networklink.php</href> <viewRefreshMode>onStop</viewRefreshMode> <viewRefreshTime>2</viewRefreshTime> <viewFormat>bboxWest=[bboxWest]&bboxSouth=[bboxSouth]&bboxEast=[bboxEast] &bboxNorth=[bboxNorth]&lookatLon=[lookatLon]&lookatLat=[lookatLat] &lookatRange=[lookatRange]&lookatTilt=[lookatTilt]&lookatHeading= [lookatHeading]&lookatTerrainLon=[lookatTerrainLon]&lookatTerrainLat= [lookatTerrainLat]&lookatTerrainAlt=[lookatTerrainAlt]&cameraLon=[cameraLon] &cameraLat=[cameraLat]&cameraAlt=[cameraAlt]&horizFov=[horizFov] &vertFov=[vertFov]&horizPixels=[horizPixels]&vertPixels=[vertPixels] &terrainEnabled=[terrainEnabled]</viewFormat> </Link> </NetworkLink> </kml>
A KML NetworkLink defines how often refreshing occurs or the conditions under which
it happens. I’ll discuss what a refresh actually does in the next paragraph. There
are two modes of refreshing that can be specified in a NetworkLink. The first, based on
time, uses the <refreshMode>
and <refreshInterval>
elements. With those tags, you can, for instance, set a refresh to happen every ten
seconds. For the KML I present here, I use refreshing based on changes in the viewpoint,
which are parameterized by two tags: <viewRefreshMode>
and
<viewRefreshTime>
. If you consult the KML documentation,
you’ll see that one choice for <viewRefreshMode>
is
onStop
—which means a refresh event happens once the viewpoint
stops changing for the amount of time specified by the
<viewRefreshTime>
element—in this case two seconds.
So, what happens during a refresh event? Google Earth does an HTTP GET
request on the URL specified by the href
element with parameters specified
in the <viewFormat>
element, which contains something akin to a URI
template. That is, Google Earth substitutes the values that correspond to the viewpoint
at the time of the refresh event for the value templates such as
[bboxWest]
, [bboxSouth]
, [bboxEast]
, and so on.
Consult the documentation for a comprehensive list of parameters supported in KML. The
template I specify here has the complete current list of parameters. Note that there is
no requirement that the parameter names match the naming scheme given by Google. In
fact, you should match the parameter names to the ones recognized by the script
specified by the href
element.
Let’s now turn to the script here:
http://examples.mashupguide.net/ch13/hello.world.networklink.php
to see how the HTTP GET
request is processed. Here’s the PHP
code:
<?php // get the time $timesnap = date("H:i:s"); // for clarity, place each coordinate into a clearly marked ?bottom-?left // or ?top-?right variable $bboxWest = isset($_GET['bboxWest']) ? $_GET['bboxWest'] : "-180.0"; $bboxSouth = isset($_GET['bboxSouth']) ? $_GET['bboxSouth'] : "-90.0"; $bboxEast = isset($_GET['bboxEast']) ? $_GET['bboxEast'] : "180.0"; $bboxNorth = isset($_GET['bboxNorth']) ? $_GET['bboxNorth'] : "90.0"; // calculate the approx center of the view -- note that this is inaccurate // if the user is not looking straight down $userlon = (($bboxEast - $bboxWest)/2) + $bboxWest; $userlat = (($bboxNorth - $bboxSouth)/2) + $bboxSouth; $response = '<?xml version="1.0" encoding="UTF-8"?>'; $response .= '<kml xmlns="http://earth.google.com/kml/2.2">'; $response .= '<Placemark>'; $response .= "<name>Hello at: $timesnap</name>"; # calculate all the parameters $arg_text = ""; foreach ($_GET as $key => $val) { $arg_text .= "<b>{$key}</b>:{$val}<br>"; } $description_text = $arg_text; $description = "<![CDATA[{$description_text}]]>"; $response .= "<description>{$description}</description>"; $response .= '<Point>'; $response .= "<coordinates>$userlon,$userlat,0</coordinates>"; $response .= '</Point>'; $response .= '</Placemark>'; $response .= '</kml>'; # set $myKMLCode together as a string $downloadfile="myKml.kml"; # give a name to appear at the client header("Content-disposition: attachment; filename=$downloadfile"); header("Content-Type: application/vnd.google-earth.kml+xml; charset=utf8"); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".strlen($response)); header("Pragma: ?no-?cache"); header("Expires: 0"); echo $response; ?>
hello.world.networklink.php
reads all the parameters that are passed to it
and displays them to the user. This is accomplished by generating the KML for a
<Placemark>
element with a <description>
element with all the parameters.
Let’s return to how I use the KML NetworkLink in flickrgeo.php
. In
that script, I needed to generate <NetworkLink>
elements that looked
like this:
<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://earth.google.com/kml/2.2"> <NetworkLink> <flyToView>0</flyToView> <name>Pictures from Flickr</name> <description> <![CDATA[<a href='http://examples.mashupguide.net/ch13/flickrgeo.php? text=stop+sign&page=1&per_page=10&min_upload_date=820483200&extras=geo%2Clicense %2Cowner_name%2Cicon_server%2Ctags&o_format=html'>Search Something Different</a>]]> </description> <open>1</open> <visibility>1</visibility> <Link> <href>http://examples.mashupguide.net/ch13/flickrgeo.php? text=stop+sign&page=1&per_page=10&min_upload_date=820483200 &extras=geo&o_format=kml</href> <viewRefreshMode>onStop</viewRefreshMode> <viewRefreshTime>3</viewRefreshTime> <viewFormat>lat0=[bboxSouth]&lon0=[bboxWest]&lat1=[bboxNorth] &lon1=[bboxEast]</viewFormat> </Link> </NetworkLink> </kml>
This is a <NetworkLink>
element for generating refreshable KML on
photos that match a full-text search for stop sign
. Notice how the
viewpoint is passed from Google Earth to http://examples.mashupguide.net/ch13/flickrgeo.php
by the
viewFormat
element:
lat0=[bboxSouth]&lon0=[bboxWest]&lat1=[bboxNorth]&lon1=[bboxEast]
The following excerpt of KML shows the structure of the KML that
flickrgeo.php
generates to display the photos in Google Earth or Google
Maps (I have put some KML elements in bold that I have yet to introduce.):
<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://earth.google.com/kml/2.2"> <Document> <Style id="118550863"> <IconStyle> <Icon> <href>http://farm1.static.flickr.com/56/118550863_1b8f5a26aa_s.jpg</href> </Icon> </IconStyle> </Style> [....] <Folder> <name>Flickr Photos</name> <description>Total Number of Photos available: 72&nbsp;< a href='http://examples.mashupguide.net/ch13/flickrgeo.php? user_id=48600101146%40N01&lat0=37.75976100792328&lon0=-122. 4470955684774&lat1=37.95649244418595&lon1=-122.1471302328438 &page=1&per_page=10&min_upload_date=820483200&extras=geo%2Clicense %2Cowner_name%2Cicon_server%2Ctags&o_format=kml'>KML</a>&nbsp;< a href='http://maps.google.com?q=http%3A%2F%2Fexamples.mashupguide.net%2F ch13%2Fflickrgeo.php%3Fuser_id%3D48600101146%2540N01%26lat0%3D37.75976100792328%26 lon0%3D-122.4470955684774%26lat1%3D37.95649244418595%26lon1%3D-122. 1471302328438%26page%3D1%26per_page%3D10%26min_upload_date%3D820483200%26extras%3D geo%252Clicense%252Cowner_name%252Cicon_server%252Ctags%26o_format%3Dkml'>GMap </a></description> <Placemark> <name>shrink wrap car</name> <description> <![CDATA[<a href='http://www.flickr.com/photos/48600101146@N01/118550863'> <img src='http://farm1.static.flickr.com/56/118550863_1b8f5a26aa.jpg'></a>]]> </description> <LookAt> <longitude>-122.300915</longitude> <latitude>37.898562</latitude> <altitude>0</altitude> <altitudeMode>relativeToGround</altitudeMode> <range>2000</range> <tilt>0</tilt> <heading>0</heading> </LookAt> <styleUrl>#118550863</styleUrl> <Point> <coordinates>-122.300915,37.898562,0</coordinates> </Point> </Placemark> [....] </Folder> </Document> </kml>
Note the following features of the KML:
There is a <Placemark>
element for each photo, whose
name
element holds the title for the photo. In the
<description>
element is HTML for the medium-sized
version of the photo. The latitude and longitude, drawn from the geo information
provided by Flickr, goes into two places: the coordinates element for the
<Point>
element and a <LookAt>
view.
Each <Placemark>
element is tied to a
<Style>
element to generate custom icons for each photo. The
icon is the square version of the Flickr photo. The association is made through
the <styleUrl>
element.
There is a <Folder>
element that groups all the
<Placemark>
elements. The <description>
element for the <Folder>
element contains links to the KML
itself and to a Google Map showing this KML. These links provide you with a way of
getting hold of what you are seeing in Google Earth.
Here’s an edited listing of the flickrgeo.php
code:
<?php # flickrgeo.php # copyright Raymond Yee, 2007 # http://examples.mashupguide.net/ch13/flickrgeo.php # xmlentities substitutes characters in $string that can be expressed # as the predefined XML entities. function xmlentities ($string) { return str_replace ( array ( '&', '"', "'", '<', '>' ), array ( '&' , '"', ''' , '<' , '>' ), $string ); } # converts an associative array representing form parameters # and values into the request part of a URL. function form_url_params($arg_list, $rid_empty_value=TRUE) { $list = array(); foreach ($arg_list as $arg => $val) { if (!($rid_empty_value) || (strlen($val) > 0)) { $list[] = $arg . "=" . urlencode($val); } } return join("&",$list); } # a simple wrapper around flickr.photos.search for public photos. # It deals a request for either the Flickr REST or JSON formats class flickrwrapper { protected $api_key; public function __construct($api_key) { $this->api_key = $api_key; } # generic method for retrieving content for a given URL. protected function getResource($url){ $chandle = curl_init(); curl_setopt($chandle, CURLOPT_URL, $url); curl_setopt($chandle, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($chandle); curl_close($chandle); return $result; } # returns an HTTP response body and headers public function search($arg_list) { # attach API key $arg_list['api_key'] = $this->api_key; # attach parameters specific to the format request, which is either JSON or REST. $format = $arg_list["format"]; if ($format == "rest") { $url = "http://api.flickr.com/services/rest/?method=flickr.photos.search&" . form_url_params($arg_list); $rsp = $this->getResource($url); $response["body"] = $rsp; $response["headers"] = array("Content-Type"=>"application/xml"); return $response; } elseif ($format == "json") { $arg_list["nojsoncallback"] = 1; $url = "http://api.flickr.com/services/rest/?method=flickr.photos.search&" . form_url_params($arg_list); $rsp = $this->getResource($url); $response["headers"] = array("Content-Type"=>"text/javascript"); $response["body"] = $rsp; return $response; } } // search } //flickrwrapper class flickr_html { # generates a simple form based on the parameters # and values of the input associative array $arg_array # uses $path as the target of the form's action attribute public function generate_form($arg_array, $path) { $form_html = ""; foreach ($arg_array as $arg => $default) { $form_html .= <<<EOT {$arg}:<input type="text" size="20" name="{$arg}" value="{$default}"><br> EOT; } $form_html = <<<EOT <form action="{$path}" method="get"> {$form_html}<br> <input type="submit" value="Go!"> </form> EOT; return $form_html; } //generate_form # generates a simple HTML representation of the results of flickr.photos.search public function html_from_pics($rsp) { $xml = simplexml_load_string($rsp); #print_r($xml); #var_dump($xml); $s = ""; $s .= "Total number of photos: " . $xml->photos['total'] . "<br>"; # http://www.flickr.com/services/api/misc.urls.html # http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}.jpg foreach ($xml->photos->photo as $photo) { $farmid = $photo['farm']; $serverid = $photo['server']; $id = $photo['id']; $secret = $photo['secret']; $owner = $photo['owner']; $thumb_url = "http://farm{$farmid}.static.flickr.com/{$serverid}/{$id}_{$secret}_t.jpg"; $page_url = "http://www.flickr.com/photos/{$owner}/{$id}"; $image_html= "<a href='{$page_url}'><img src='{$thumb_url}'></a>"; $s .= $image_html; } return $s; } } // flickr_html # a class to handle conversion of Flickr results to KML class flickr_kml { # helper function to create a new text node with $string that is wrapped by an # element named by $childName -- and then attach the whole thing to $parentNode. # allow for a namespace to be specified for $childName protected function attachNewTextNode($parentNode, $childName,$childNS="",$string="") { $childNode = $parentNode->appendChild(new DOMElement($childName,$childNS)); $childNode->appendChild(new DOMText($string)); return $childNode; } # create the subelements for Style /* e.g., <Style id="118550863"> <IconStyle> <Icon> <href>http://farm1.static.flickr.com/56/118550863_1b8f5a26aa_s.jpg</href> </Icon> </IconStyle> </Style> */ protected function populate_style($style,$photo) { $id = $photo['id']; $farmid = $photo['farm']; $serverid = $photo['server']; $secret = $photo['secret']; $square_url = "http://farm{$farmid}.static.flickr.com/{$serverid}/{$id}_{$secret}_s.jpg"; $id_attr = $style->setAttributeNode(new DOMAttr('id', $id)); $iconstyle = $style->appendChild(new DOMElement("IconStyle")); $icon = $iconstyle->appendChild (new DOMElement("Icon")); $href = $this->attachNewTextNode($icon,"href","",$square_url); return $style; } # converts the response from the Flickr photo search ($rsp), # the arguments from the original search ($arg_array), # the $path of the script to KML public function kml_from_pics($arg_array, $path, $rsp) { $xml = simplexml_load_string($rsp); $dom = new DOMDocument('1.0', 'UTF-8'); $kml = $dom->appendChild(new DOMElement('kml')); $attr = $kml->setAttributeNode(new DOMAttr('xmlns', 'http://earth.google.com/kml/2.2')); $document = $kml->appendChild(new DOMElement('Document')); # See http://www.flickr.com/services/api/misc.urls.html # Remember http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}.jpg # syntax for URLs # parameters for LookAt -- ?hard-?coded in this instance $range = 2000; $altitude = 0; $heading =0; $tilt = 0; # make the <Style> elements first foreach ($xml->photos->photo as $photo) { $style = $document->appendChild(new DOMElement('Style')); $this->populate_style($style,$photo); } # now make the <Placemark> elements -- but tuck them under one Folder # in the Folder, add URLs for the KML document and how to send # the KML document to Google Maps $folder = $document->appendChild(new DOMElement('Folder')); $folder_name_node = $this->attachNewTextNode($folder,"name","","Flickr Photos"); $kml_url = $path . "?" . form_url_params($arg_array,TRUE); $description_string = "Total Number of Photos available: {$xml-> photos['total']}" . " <a href='{$kml_url}'>KML</a>"; $description_string .= " <a href='" . "http://maps.google.com?q=" . urlencode($kml_url) . "'>GMap</a>"; $folder_description_node = $this-> attachNewTextNode($folder,"description","",$description_string); # loop through the photos to convert to a Placemark KML element foreach ($xml->photos->photo as $photo) { $farmid = $photo['farm']; $serverid = $photo['server']; $id = $photo['id']; $secret = $photo['secret']; $owner = $photo['owner']; $thumb_url = "http://farm{$farmid}.static.flickr.com/{$serverid}/{$id}_{$secret}_t.jpg"; $med_url = "http://farm{$farmid}.static.flickr.com/{$serverid}/{$id}_{$secret}.jpg"; $page_url = "http://www.flickr.com/photos/{$owner}/{$id}"; $image_html= "<a href='{$page_url}'><img src='{$med_url}'></a>"; $title = $photo['title']; $latitude = $photo['latitude']; $longitude = $photo['longitude']; $placemark = $folder->appendChild(new DOMElement('Placemark')); # place the photo title into the <name> KML element $name = $this->attachNewTextNode($placemark,"name","",$title); # drop the title and thumbnail into description and wrap in CDATA # to work around encoding issues $description_string = "{$image_html}"; $description = $placemark->appendChild(new DOMElement('description')); $description->appendChild($dom->createCDATASection($description_string)); $lookat = $placemark->appendChild(new DOMElement('LookAt')); $longitude_node = $this->attachNewTextNode($lookat,"longitude","",$longitude); $latitude_node = $this->attachNewTextNode($lookat,"latitude","",$latitude); $altitudeNode = $this->attachNewTextNode($lookat,"altitude","",$altitude); $altitudeMode = $this->attachNewTextNode($lookat,"altitudeMode","","relativeToGround"); $rangeNode = $this->attachNewTextNode($lookat,"range","",$range); $tiltNode = $this->attachNewTextNode($lookat,"tilt","",$tilt); $headingNode = $this->attachNewTextNode($lookat,"heading","",$heading); $styleurl = $this->attachNewTextNode($placemark, "styleUrl","","#".$id); $point = $placemark->appendChild(new DOMElement('Point')); $coordinates_string = "{$longitude},{$latitude},{$altitude}"; $coordinates = $this->attachNewTextNode($point,"coordinates","",$coordinates_string); } return $dom->saveXML(); } # generate a network link based on the user search parameters ($arg_list) # and the $path to this script public function generate_network_link ($arg_list, $path) { # look through the $arg_list but get rid of lat/long and blanks unset ($arg_list['lat0']); unset ($arg_list['lat1']); unset ($arg_list['lon0']); unset ($arg_list['lon1']); $arg_list['o_format'] = 'kml'; //set to KML $url = $path . "?" . form_url_params($arg_list,TRUE); $url = xmlentities($url); # generate a description string to guide user # to reparameterizing the network link $arg_list['o_format'] = 'html'; $url2 = $path . "?" . form_url_params($arg_list,TRUE); $description = "<a href='{$url2}'>Search Something Different</a>"; $nl = <<<EOT <?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://earth.google.com/kml/2.2"> <NetworkLink> <flyToView>0</flyToView> <name>Pictures from Flickr</name> <description><![CDATA[{$description}]]></description> <open>1</open> <visibility>1</visibility> <Link> <href>{$url}</href> <viewRefreshMode>onStop</viewRefreshMode> <viewRefreshTime>3</viewRefreshTime> <viewFormat>lat0=[bboxSouth]&lon0=[bboxWest]&lat1=[bboxNorth] &lon1=[bboxEast]</viewFormat> </Link> </NetworkLink> </kml> EOT; return $nl; } } // flickr_kml # this class translates what comes in on the URL and from form values # to parameters to submit to Flickr class flickr_view { # this function filters $_GET passed in as $get by parameters # that are in $defaults # only parameters named in $defaults are allowed -- and if that value isn't set in # $get, then this function passes back the default value public function form_input_to_user_inputs($get,$defaults) { $params = array(); foreach ($defaults as $arg => $default_value) { $params[$arg] = isset($get[$arg]) ? $get[$arg] : $default_value; } return $params; } # translate the user inputs to the appropriate ones for Flickr. # for example -- fold the latitudes and longitude coordinates into bbox # get rid of o_format for Flickr public function user_inputs_to_flickr_params($user_inputs) { $search_params = $user_inputs; $o_format = $user_inputs["o_format"]; unset ($search_params["o_format"]); if (($o_format == "json") || ($o_format == "rest")) { $search_params["format"] = $o_format; } else { $search_params["format"] = "rest"; } #recast the lat and long parameters in bbox $bbox = "{$search_params['lon0']},{$search_params['lat0']}, {$search_params['lon1']},{$search_params['lat1']}"; $search_params['bbox'] = $bbox; unset($search_params['lon0']); unset($search_params['lon1']); unset($search_params['lat0']); unset($search_params['lat1']); return $search_params; } // user_inputs_to_flickr_params } //flickr_view // API key here $api_key = "[API-KEY]"; # a set of defaults -- center the search around Berkeley by default # and any geotagged photo in that bounding box. # BTW, this script needs at least geo in extras. # min_upload_date corresponds to Jan 1, 1996 (Pacific time) $default_args = array( "user_id" => '', "tags" => '', "tag_mode" => '', "text" => '', "min_upload_date" => '820483200', "max_upload_date" => '', "min_taken_date" => '', "max_taken_date" => '', "license" => '', "sort" => '', "privacy_filter" => '', "lat0" => 37.81778516606761, "lon0" => -122.34374999999999, "lat1" => 37.92619056937629, "lon1" => -122.17208862304686, "accuracy" => '', "safe_search" => '', "content_type" => '', "machine_tags" => '', "machine_tag_mode" => '', "group_id" => '', "place_id" => '', "extras" => "geo", "per_page" => 10, "page" => 1, "o_format" => 'html' ); # calculate the path to this script as a URL. $path = "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF']; # instantiate the Flickr wrapper and the view object $fw = new flickrwrapper($api_key); $fv = new flickr_view(); # get the parameters that have been submitted to it. $user_inputs = $fv->form_input_to_user_inputs($_GET,$default_args); $search_params = $fv->user_inputs_to_flickr_params($user_inputs); # see what the requested format is $o_format = $user_inputs["o_format"]; # if the user is looking for a network link, # calculate the Networklink KML and return it # with the appropriate ?Content-?Type for KML if ($o_format == 'nl') { $fk = new flickr_kml(); header("Content-Type:application/vnd.google-earth.kml+xml"); $downloadfile="flickr.kml"; # give a name to appear at the client header("Content-disposition: attachment; filename=$downloadfile"); print $fk->generate_network_link($user_inputs,$path); exit(); } # If the user is looking instead for JSON, REST, HTML, or KML, we query Flickr $response = $fw->search($search_params); # If the request is for JSON or REST, # just pass back the results of the Flickr search if (($o_format == "json") || ($o_format == "rest")) { foreach ($response["headers"] as $header => $val) { header("{$header}:{$val}"); } print $response["body"]; # if the request is for HTML or KML, do the appropriate transformations. } elseif ($o_format == "html") { # now translate to HTML $fh = new flickr_html(); header("Content-Type:text/html"); print $fh->generate_form($user_inputs, $_SERVER['PHP_SELF']); print $fh->html_from_pics($response["body"]); } elseif ($o_format == "kml") { $fk = new flickr_kml(); header("Content-Type:application/vnd.google-earth.kml+xml"); $downloadfile="flickr.kml"; # give a name to appear at the client header("Content-disposition: attachment; filename=$downloadfile"); print $fk->kml_from_pics($user_inputs, $path, $response["body"]); } ?>