function overlap($query) { $html = ''; $html .= '<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Overlap</title> </head> <body>'; $html .= '<p><a href=".">Back</a>'; $html .= '<p>Results for <b>' . $query . '</b></p>'; // GBIF $gbif_pts = array(); $gbif_csquare = array(); $data = get_gbif_data($query); //print_r($data);exit(); $gbif_pts = get_points($data); /* echo '<pre>'; print_r($gbif_pts); echo '</pre>'; //exit(); */ // map $html .= '<h3>GBIF</h3>'; $html .= '<object id="gbif" type="image/svg+xml" width="360" height="180" data="map.php?coordinates=' . json_encode($gbif_pts) . '"></object>'; $html .= '<p><a href="http://www.gbif.org/species/search?q=' . $query . '" target="_new">View in GBIF</a></p>'; //echo $html; foreach ($gbif_pts as $pt) { $csq = lat_lon_2_csquare($pt[0], $pt[1]); $gbif_csquare[] = $csq; } $gbif_csquare = array_unique($gbif_csquare); /* $url = 'http://data.gbif.org/ws/rest/taxon/list?scientificname=' . urlencode($query) . '&dataresourcekey=1'; $xml = get($url); $js = ''; if ($xml != '') { // Convert GBIF XML to Javascript $xp = new XsltProcessor(); $xsl = new DomDocument; $xsl->load('../services/gbif-taxa2json.xsl'); $xp->importStylesheet($xsl); $dom = new DOMDocument; $dom->loadXML($xml); $xpath = new DOMXPath($dom); $js = $xp->transformToXML($dom); } $obj = json_decode($js); if (count($obj->taxonConcepts) >= 1) { $id = $obj->taxonConcepts[0]->gbifKey; $url = 'http://data.gbif.org/ws/rest/density/list?taxonconceptkey=' . $id; $xml = get($url); $js = ''; if ($xml != '') { // Convert GBIF XML to Javascript for Google Maps $xp = new XsltProcessor(); $xsl = new DomDocument; $xsl->load('../services/gbif2json.xsl'); $xp->importStylesheet($xsl); $dom = new DOMDocument; $dom->loadXML($xml); $xpath = new DOMXPath($dom); $js = $xp->transformToXML($dom); //print_r($js); $map = json_decode($js); //print_r($map); foreach ($map->cells as $cell) { $pt = array(); $pt[0] = $cell->minLatitude; $pt[1] = $cell->minLongitude; $gbif_pts[] = $pt; } //print_r($gbif_pts); // map $html .= '<h3>GBIF</h3>'; $html .= '<object id="gbif" type="image/svg+xml" width="360" height="180" data="map.php?coordinates=' . json_encode($gbif_pts) . '"></object>'; $html .= '<p><a href="http://data.gbif.org/species/' . $id . '" target="_new">View in GBIF</a></p>'; //echo $html; foreach ($gbif_pts as $pt) { $csq = lat_lon_2_csquare($pt[0], $pt[1]); $gbif_csquare[] = $csq; } $gbif_csquare = array_unique($gbif_csquare); //print_r($gbif_csquare); } } if (count($obj->taxonConcepts) > 1) { $html .= '<p>More than one taxon with this name</p>'; } */ // Flickr $flickr_pts = array(); $flickr_csquare = array(); $tag = str_replace(' ', '', $query); $tag = strtolower($tag); $url = 'http://api.flickr.com/services/feeds/geo/?tags=' . $tag . '&lang=en-us&format=rss_200'; $xml = get($url); //echo $xml; // Extract lat and long $dom = new DOMDocument(); $dom->loadXML($xml); $xpath = new DOMXPath($dom); $xpath->registerNamespace('geo', 'http://www.w3.org/2003/01/geo/wgs84_pos#'); $xpath->registerNamespace('georss', 'http://www.georss.org/georss'); $nodeCollection = $xpath->query("//item/georss:point"); foreach ($nodeCollection as $node) { $pt = $node->firstChild->nodeValue; $pts = explode(' ', $pt); $pts[0] = (double) $pts[0]; $pts[1] = (double) $pts[1]; $flickr_pts[] = $pts; } // make a map //print_r($flickr_pts); $html .= '<h3>Flicker</h3>'; $html .= '<object id="map" type="image/svg+xml" width="360" height="180" data="map.php?coordinates=' . json_encode($flickr_pts) . '"></object>'; $html .= '<p><a href="http://www.flickr.com/photos/tags/' . $tag . '/" target="_new">View in Flickr</a></p>'; //echo $html; // compute overlap with GBIF foreach ($flickr_pts as $pt) { $csq = lat_lon_2_csquare($pt[0], $pt[1]); $flickr_csquare[] = $csq; } $flickr_csquare = array_unique($flickr_csquare); //print_r($flickr_csquare); // compute difference $html .= '<h3>Summary</h3>'; $html .= '<p>GBIF has ' . count($gbif_pts) . ' records.</p>'; $html .= '<p>Flickr has ' . count($flickr_pts) . ' geotagged photos.</p>'; $html .= '<p>GBIF has records from ' . count($gbif_csquare) . ' csquares.</p>'; $html .= '<p>Flickr has records from ' . count($flickr_csquare) . ' csquares</p>'; $html .= '<p>Overlap between GBIF and Flickr = ' . count(array_intersect($gbif_csquare, $flickr_csquare)) . '</p>'; $html .= '</body> </html>'; echo $html; }
function draw_map($name) { $data = get_gbif_data($name); //print_r($data);exit(); $points = get_points($data); //print_r($points); if (count($points) == 0) { echo "No data for <b>{$name}</b><br /><a href=\".\">Go back</a>"; exit; } $geojson = make_polygon($points); $min_long = 180; $max_long = -180; $min_lat = 90; $max_lat = -90; foreach ($points as $pt) { $min_long = min($min_long, $pt[0]); $max_long = max($max_long, $pt[0]); $min_lat = min($min_lat, $pt[1]); $max_lat = max($max_lat, $pt[1]); } $polygon = array(); foreach ($geojson->features as $feature) { if ($feature->properties->name == 'Polygon') { $polygon = $feature->geometry->coordinates[0]; } } $num_cells = 0; $num_cells_occupied = 0; $size = 1; for ($long = $min_long; $long < $max_long; $long += $size) { for ($lat = $min_lat; $lat < $max_lat; $lat += $size) { $feature = new stdclass(); $feature->type = 'Feature'; $feature->properties = new stdclass(); $feature->properties->name = "Polygon"; $feature->geometry = new stdclass(); $feature->geometry->type = 'Polygon'; $feature->geometry->coordinates = array(); $box = array(); $x1 = min($long, $long + $size); $x2 = max($long, $long + $size); $y1 = min($lat, $lat + $size); $y2 = max($lat, $lat + $size); $box[] = array($x1, $y2); $box[] = array($x2, $y2); $box[] = array($x2, $y1); $box[] = array($x1, $y1); $box[] = array($x1, $y2); // note edge case of polygon with spike where none of corners of square are in polygon // (e.g, Mehelya nyassae) $in_polygon = 0; $i = 0; while ($i < 4) { if (pointInPolyonQ($box[$i], $polygon)) { $in_polygon++; } $i++; } if ($in_polygon > 0) { $num_cells++; } $in_cell = 0; foreach ($points as $pt) { if (pointInPolyonQ($pt, $box)) { $in_cell++; } } if ($in_cell == 0) { $in_polygon = 0; } else { $num_cells_occupied++; } if ($in_polygon > 0) { $feature->geometry->coordinates[] = $box; $geojson->features[] = $feature; } } } $template = <<<EOT \t<!DOCTYPE html> \t<html> \t <head> \t\t<title><NAME></title> \t\t<meta name="viewport" content="initial-scale=1.0, user-scalable=no"> \t\t<meta charset="utf-8"> \t\t<style> \t\tbody { font-family: sans-serif; } \t\t #map-canvas { \t\t\theight: 500px; \t\t\tmargin: 0px; \t\t\tpadding: 20px \t\t } \t\t</style> \t\t<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script> \t\t<script> \tvar map; \tfunction initialize() { \t // Create a simple map. \t map = new google.maps.Map(document.getElementById('map-canvas'), { \t\tzoom: 4, \t\tcenter: {lat: <LATITUDE>, lng: <LONGITUDE>} \t }); \t \t // Load a GeoJSON \t \t var j = <GEOJSON>; \t \t map.data.addGeoJson(j); \t} \t \tgoogle.maps.event.addDomListener(window, 'load', initialize); \t \t\t</script> \t </head> \t <body> \t\t<h1><NAME></h1> \t\t<div id="map-canvas"></div> \t\t<p>Number of cells: <b><NUMCELLS></b>, number occupied: <b><NUMCELLSOCCUPIED></b></p> \t </body> \t</html> EOT; $template = str_replace('<NAME>', $name, $template); $template = str_replace('<GEOJSON>', json_encode($geojson), $template); $template = str_replace('<LATITUDE>', $min_lat + ($max_lat - $min_lat) / 2, $template); $template = str_replace('<LONGITUDE>', $min_long + ($max_long - $min_long) / 2, $template); $template = str_replace('<NUMCELLS>', $num_cells, $template); $template = str_replace('<NUMCELLSOCCUPIED>', $num_cells_occupied, $template); echo $template; }