Illuminated Hacks Mikel Maron Where 2.0 101 Tutorial [email_address] http://brainoff.com/
Some of my favorite hacks for the pleasure of your hacking sensibility with the hopeful outcome of illuminating best practices of putting your website on the geoweb and hinting at the means  to get exactly what you need. cause I likes the hacks. hacks are rad.
Upcoming StreetView
Bangladesh Boat Journey
geocodr
UNDP Environment Projects
Upcoming StreetView
http://googlesightseeing.com/2008/05/07/street-view-sabotage/
http://gregsadetsky.com/?p=81
http://cbk0.google.com/cbk?output=xml&ll=37.784692,-122.39303 <panorama> <data_properties image_width=&quot;3500&quot; image_height=&quot;1750&quot;   tile_width=&quot;512&quot; tile_height=&quot;512&quot;  pano_id=&quot;fPaYJ83UesLvxeiFe1FXdA&quot;  num_zoom_levels=&quot;3&quot;  lat=&quot;37.784691&quot; lng=&quot;-122.392995&quot;> <copyright>© 2008 Google</copyright> <text>I-80</text> </data_properties> <projection_properties projection_type=&quot;spherical&quot; pano_yaw_deg=&quot;235.97&quot;  tilt_yaw_deg=&quot;-84.62&quot; tilt_pitch_deg=&quot;3.21&quot;/> <annotation_properties> <link yaw_deg=&quot;55.54&quot; pano_id=&quot;j-LK2ptQjG2w0EfQ1-6zMQ&quot; road_argb=&quot;0x80f2bf24&quot;> <link_text>I-80</link_text> </link> <link yaw_deg=&quot;233.22&quot; pano_id=&quot;SoF-Grk1MNAwHEJvEsCBTw&quot; road_argb=&quot;0x80f2bf24&quot;> <link_text>I-80</link_text> </link> </annotation_properties> </panorama>
http://code.google.com/apis/maps/documentation/reference.html#GStreetviewOverlay Official StreetView API panoClient = new GStreetviewClient();  latlng = new GLatLng(37.784692,-122.39303);  panoClient.getNearestPanorama(latlng, showPanoData); function showPanoData(panoData) { if (panoData.code != 200) { GLog.write('showPanoData: Server rejected with code: ' + panoData.code); return; } console.log( panoData.location.latlng ); }
http://cbk0.google.com/cbk?output=tile&zoom=2&y=0&x={0,3}&panoid=j-LK2ptQjG2w0EfQ1-6zMQ
Official StreetView API
http://upcoming.yahoo.com/event/461321/
http://flickr.com/photos/tags/upcoming:event=461321
http://flickr.com/photos/10111/2467558023/
Machine Tags namespace:predicate=value geobloggers user controlled, just normal tags structured data geo:lat=37.784692 geo:long=-122.39303 geotagged camel:humpcount=1 loosely coupled lastfm:event=97947 iso:isbn=0713998393 http://www.flickr.com/groups/api/discuss/72157594497877875/ http://adactio.com/journal/1274/
machine_tags (Optional) Aside from passing in a fully formed machine tag, there is a special syntax for searching on specific properties : * Find photos using the 'dc' namespace : &quot;machine_tags&quot; => &quot;dc:&quot; * Find photos with a title in the 'dc' namespace : &quot;machine_tags&quot; => &quot;dc:title=&quot; * Find photos titled &quot;mr. camera&quot; in the 'dc' namespace : &quot;machine_tags&quot; => &quot;dc:title=\&quot;mr. camera\&quot; * Find photos whose value is &quot;mr. camera&quot; : &quot;machine_tags&quot; => &quot;*:*=\&quot;mr. camera\&quot;&quot; * Find photos that have a title, in any namespace : &quot;machine_tags&quot; => &quot;*:title=&quot; * Find photos that have a title, in any namespace, whose value is &quot;mr. camera&quot; : &quot;machine_tags&quot; => &quot;*:title=\&quot;mr. camera\&quot;&quot; * Find photos, in the 'dc' namespace whose value is &quot;mr. camera&quot; : &quot;machine_tags&quot; => &quot;dc:*=\&quot;mr. camera\&quot;&quot; Multiple machine tags may be queried by passing a comma-separated list. The number of machine tags you can pass in a single query depends on the tag mode (AND or OR) that you are querying with. &quot;AND&quot; queries are limited to (16) machine tags. &quot;OR&quot; queries are limited to (8). http://www.flickr.com/services/api/flickr.photos.search.html a hack all grown up
http://upcoming.yahoo.com/place/hCca8XSYA5nn0X1Sfw
GeoRSS http://upcoming.yahoo.com/syndicate/v2/place/hCca8XSYA5nn0X1Sfw <item> <title>May  7, Manifesto SF at The Stud</title> <description><![CDATA[MANIFESTO - Leave the boys at home, this is music for men! Deep house, classic disco. Dance the night away! David Harness & Cez Every Wed - 9pm to 2am players.<br /> ]]></description> <guid>http://upcoming.yahoo.com/event/ 600466 /</guid> <link>http://upcoming.yahoo.com/event/600466/</link> <comments>http://upcoming.yahoo.com/event/60046/#comments</comments> <geo:lat>37.7697</geo:lat> <geo:long>-122.42</geo:long> <pubDate>Thu, 07 May 2008 15:50:49 -0700</pubDate> <dc:date>2008-05-08T15:50:49-07:00</dc:date> <xCal:summary>Manifesto SF</xCal:summary> <xCal:dtstart>2008-05-07T21:00:00Z</xCal:dtstart> <xCal:dtend></xCal:dtend> <xCal:location>http://upcoming.yahoo.com/venue/16322/</xCal:location> <xCal:x-calconnect-venue> <xCal:x-calconnect-venue-id>http://upcoming.yahoo.com/venue/16322/</xCal:x-calconnect-venue-id> <xCal:adr> <xCal:x-calconnect-venue-name> The Stud </xCal:x-calconnect-venue-name> <xCal:x-calconnect-street>Harrison @ 9 th  Street</xCal:x-calconnect-street> <xCal:x-calconnect-city>San Francisco</xCal:x-calconnect-city> <xCal:x-calconnect-region>California</xCal:x-calconnect-region> <xCal:x-calconnect-postalcode>94103</xCal:x-calconnect-postalcode> <xCal:x-calconnect-country>United States</xCal:x-calconnect-country> </xCal:adr> <xCal:url type='Venue Website'>http://upcoming.yahoo.com/venue/16322/</xCal:url> <xCal:x-calconnect-tel></xCal:x-calconnect-tel> </xCal:x-calconnect-venue> </item>
Proposals Reference External Geometries Simple Features (for SQL) Multiple Locations elev floor radius featuretypetag relationshiptag featurename georss.org Geometries Attributes Simple  GML  RSS 1.0  RSS 2.0  Atom Flavors RSS formats
Reguest Upcoming GeoRSS Feed For each item, parse out lat, lng, event-id, venue-name With lat/lng, get panoid from StreetView XML api Request StreetView tiles Post images to flickr with upcoming:event maching tag Wait for upcoming squirrels to run Do a little dance
#!/usr/bin/ruby require 'rexml/document' include REXML require 'net/http' require 'cgi' require 'uri' upcomingrss = &quot;http://upcoming.yahoo.com/syndicate/v2/place/hCca8XSYA5nn0X1Sfw--&quot; panoxml = &quot;http://cbk0.google.com/cbk?output=xml&ll=&quot; panoimg = &quot;http://cbk0.google.com/cbk?output=tile\\&zoom=2\\&y=0\\&panoid=&quot; url = URI.parse(upcomingrss) req = Net::HTTP::Get.new(url.path) res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) } doc = Document.new( res.body ) XPath.each( doc, &quot;//item/&quot;) { |element| begin lat = XPath.first( element, &quot;geo:lat&quot; ).text lng = XPath.first( element, &quot;geo:long&quot; ).text venue = XPath.first( element, &quot;.//xCal:x-calconnect-venue-name&quot; ).text guid = XPath.first( element, &quot;guid&quot; ).text upid = /http:\/\/upcoming.yahoo.com\/event\/(.*)\//.match(guid)[1] panourl = URI.parse(panoxml + lat + &quot;,&quot; + lng) panoreq = Net::HTTP::Get.new(panourl.path + &quot;?&quot; + panourl.query) panores = Net::HTTP.start(panourl.host, panourl.port) {|http| http.request(panoreq) } panodoc = Document.new( panores.body ) panoid = XPath.first(panodoc, &quot;//data_properties&quot;).attributes[&quot;pano_id&quot;] for i in 0..3 system(&quot;wget &quot; + panoimg + panoid + &quot;\\&x=&quot; + i.to_s + &quot; -O img/&quot; + panoid + &quot;.jpg&quot;) tags = &quot;geo:lat=&quot; + lat + &quot; geo:long=&quot; + lng + &quot; upcoming:event=&quot; + upid system(&quot;./flickr.pl img/&quot; + panoid + &quot;.jpg '&quot; + venue + &quot;' '&quot; + tags + &quot;'&quot;) end rescue end }
#!/usr/bin/perl use Flickr::Upload; use Flickr::API; my $api_key  =  'b78f44c2721ef1f146a6d83eb9559f33';  my $api_secret = 'd05b91178ddb026c'; my $api = new Flickr::API( {'key' => $api_key,  'secret' => $api_secret }, 'perms' => 'write' ); my $auth_token = '72157600303046027-ce35689cc50c1afc'; my $ua = Flickr::Upload->new( { 'key' =>  $api_key, 'secret' => $api_secret } ); $photo_id = $ua->upload( auth_token =>  $auth_token, photo=>&quot;@ARGV[0]&quot;,  email=>'wherecamp@yahoo.com', title=>&quot;@ARGV[1]&quot;, description=>'', tags =>&quot;@ARGV[2]&quot;, is_public => 1, is_friend => 1, is_family => 1 ) ;
http://upcoming.yahoo.com/event/600466 Studly!
http://www.flickr.com/photos/8721477@N08/
Improvements? Directionality Undistorted
 
Bangladesh Boat Journey project led by Dharmafly http://www.bbc.co.uk/worldservice/bangladeshboat/ http://dharmafly.com/
http://www.flickr.com/photos/mikel_maron/2304719567/ Dharmafly. Prem melted my brain
Hack 1 Easily geotag posts and pics
http://twittervision.com/
http://twitter.com/bangladeshboat
http://microformats.org/wiki/microblogging-nanoformats Nanoformats! L: o Used to define a location o Example: Good place to visit  L: Place Georges Pompidou, Paris, France o Example2: Good place to visit  L: Place Georges Pompidou, Paris, 75004 o Example3: Good place to visit  L:48.860500,2.352260 o Text Syntax:  L:<Addres, city or town, region> or L:<Address, city or town, postal code>  at the end of  a tweet o Geo Syntax: L:<lat,long> + info: (Section 3.4.2 of RFC2426)
nanoformat parsing engine suite
A Model for GeoWeb friendliness http://dev.opera.com/articles/view/location-based-publishing-and-services/ http://dharmafly.com/blog/bangladeshboat
TwitterVision http://twittervision.com/bangladeshboat
Geo Microformats https://addons.mozilla.org/en-US/firefox/addon/4106
hAtom microformat <ul class=&quot; hfeed  vcalendar xoxo&quot;> <li class=&quot; hentry  vevent xfolkentry postid-t444623812&quot;> <p class=&quot;status&quot;>&#8220; <a rel=&quot;bookmark&quot; class=&quot; entry-title entry-content summary description taggedlink url &quot;  href=&quot;http://twitter.com/bangladeshboat/statuses/444623812&quot;  title=&quot;Posts from the Bangladesh Boat (on Twitter)&quot;> The month long BBC Bangladesh boat trip has come to an end, and what a momentous four weeks it's been! </a>&#8221; </p> <ul class=&quot;meta&quot;> <li class=&quot;update last-update&quot;>Last updated by  <address class=&quot;author vcard fn&quot;> <span class=&quot;photo&quot;> <img class=&quot;photo&quot; src=&quot;http://www.bbc.co.uk/worldservice/bangladeshboat/images/alastair_ben.jpg&quot;        alt=&quot;Alastair Lawson-Tancred (left) and Ben Sutherland&quot; width=&quot;134&quot; height=&quot;96&quot;    title=&quot;Alastair Lawson-Tancred (left) and Ben Sutherland&quot; /> </span> <span class=&quot;fn&quot;>Ben Sutherland and Alastair Lawson</span> </address> <abbr class=&quot; published dtstart &quot; title=&quot;2007-11-26T16:57:52+06:00&quot;>on 28th November 2007</abbr> </li> </ul>
hAtom microformat http://tools.microformatic.com/transcode/rss/hatom/www.bbc.co.uk/worldservice/bangladeshboat/
Google Maps http://maps.google.com/maps?q=http://www.bbc.co.uk/worldservice/bangladeshboat/rss.xml&z=8
mapufacture http://mapufacture.com/feeds/1009982
Google Earth http://bangladeshboat.welcomebackstage.com/feed/?format=kml&numPosts=all
iCal feed
API http://bangladeshboat.welcomebackstage.com/
http://bangladeshboat.welcomebackstage.com/
Greasemonkey API http://bangladeshboat.welcomebackstage.com/
Pacer Feeds http://mapufacture.com/users/{user-id}/pacer
Hack 2 Free the Bubble! http://www.bbc.co.uk/worldservice/bangladeshboat/js/mashup.js
Extreme DOM
http://maps.google.com/intl/en_us/mapfiles/iw2.png
Explode the InfoWindow divs = document.getElementsByTagName('div'); for (var i=0; i < divs.length; i++) { if (divs[i].style.overflow == &quot;hidden&quot;) { divs[i].style.overflow = &quot;visible&quot;; } }
 
Capture the Window Opening function CustomBalloon(map) { var that = this; this.gmap = map; this.visible = false; this.closed = true; this.infoWindow = this.gmap.getInfoWindow(); // Set global settings.map.custom_infowindow to false  // for default GMaps behavior if (settings.map.custom_infowindow) { GEvent.addListener(this.gmap, &quot;infowindowopen&quot;, function() { that.closed = false; if (that.grabbed) { // infoWindow opened off-screen -> move to correct location that.setPosition(); if (!that.visible){ that.show(); } } else { // wait until first infoWindow initialized  // -> grab balloon element that.grabGMapInfoWindow(); } }); .. }
Grab the InfoWindow grabGMapInfoWindow: function() { var that = this; this.balloon =  this.infoWindow[settings.map.gmElements.infoWindow.balloon].parentNode; this.balloon.parentNode.removeChild(this.balloon); this.balloonShadow =  this.infoWindow[settings.map.gmElements.infoWindow.shadow].parentNode; this.balloonShadow.parentNode.removeChild(this.balloonShadow); this.newBalloon = document.body.appendChild(extend(cE('div'),{ id: 'balloon' })); this.newBalloon.appendChild(this.balloon); this.hide(); this.infoWindow.hide = function() { that.hide(); }; this.grabbed = true; applyFilters('customBalloonGrabGMapInfoWindow', this); }
move the window setPosition: function() { var x; var y; var a; //L[0] = div containing icon; L[1] is shadow a = findPos(this.marker[settings.map.gmElements.marker.icon_imgs][0]); x = a[0]; y = a[1]; // balloon.firstChild.lastChild is an image stretched to cover // the entire visible balloon, so it's the place to get width/height // arrowx, arrowy are offsets for &quot;arrow&quot; portion of the balloon  var arrowx = -25; var arrowy = 70; x -= parseInt(this.balloon.firstChild.lastChild.style.width,10)/2 + arrowx; y -= parseInt(this.balloon.firstChild.lastChild.style.height,10) + arrowy; // offset by the specified offset position x -= this.offset.x; y -= this.offset.y; this.balloon.firstChild.style.left = x + &quot;px&quot;; this.balloon.firstChild.style.top = y +&quot;px&quot;; applyFilters('customBalloonSetPosition', this); }
findPos // Position of an object on screen function findPos(obj) { var curleft = 0; var curtop = 0; if (obj.offsetParent) { curleft = obj.offsetLeft; curtop = obj.offsetTop; while ((obj = obj.offsetParent)) { curleft += obj.offsetLeft; curtop += obj.offsetTop; } } return [curleft, curtop]; }
http://www.bbc.co.uk/worldservice/bangladeshboat/js/mashup.js
cute cow code break lolcows! mooove!
geocodr http://geocodr.net/
mapping flickr tags - europe http://brainoff.com/openplan/flickr/
foot and mouth http://brainoff.com/openplan/flickr/
worldKit some Perl serving WMS requests (I'll spare you) flickr tag tiles
naïve Flickr geocoding http://brainoff.com/flickr/geocodrer/ sub handle_fl { my ($e, %attr); parseElem(\$e,\%attr,@_); if ($e eq &quot;photo&quot;) { $lat += $attr{'latitude'}; $lng += $attr{'longitude'}; $count++; } } $ua = LWP::UserAgent->new('worldKit','http://brainoff.com/worldkit/ @'); $response = $ua->get( $flickrurl . &quot;tags=$tags&quot; ); if (defined($response)) { if ($response->is_success()) { $xp = new XML::Parser(Handlers => {Start => \&handle_fl, }); eval { $xp->parse($response->content); }; } else { die; } } $lat = $lat / $count; $lng = $lng / $count; print &quot;<b>$tags</b><br>&quot;; print &quot;$lat, $lng<br>&quot;; print &quot;<a href='http://maps.google.com/maps?q=$lat,$lng'>GMap</a>&quot;;
http://brainoff.com/flickr/geocodrer/ http://brainoff.com/flickr/geocoder/?tags=santa+cruz santacruz 31.219397388, -104.796292444
k-means clustering http://en.wikipedia.org/wiki/K-means
smarter Flickr geocoding function geocode($key, $place,  $searchmode, $sortmode, $format, $bbox, $numresults,$numclusters, $tryagain ) { $error = &quot;1&quot;; $f = new phpFlickr('1b5c444be51e50c05eeeed1b72b8747f'); $resp = $f->photos_search(array(  $searchmode => $place, 'bbox' => $bbox, 'per_page' => $numresults,  'sort' => $sortmode, 'tag_mode' => 'all', 'extras' => 'geo', )); if ($resp){ $cnt =&quot;0&quot;; $datapoints = array(); foreach ($resp['photo'] as $photo) { $photolat = $photo['latitude']; $photolon = $photo['longitude']; array_push($datapoints,  new DataPoint((float)$photolat,(float)$photolon,$photo['title'])); $cnt++; }
smarter Flickr geocoding $jca = new JCA($numclusters,$numresults * 2 ,$datapoints); $jca->startAnalysis(); $clusters = $jca->getClusterOutput(); $largestClust = 0; $largestClustSize = 0; for ($i=0; $i<count($clusters); $i++){ $tempCluster = $clusters[$i]; if (count($tempCluster) > $largestClustSize) {   $largestClustSize =  count($tempCluster);   $largestClust = $i; } }//for $cX = $jca->getCluster($largestClust)->getCentroid()->getCx(); $cY = $jca->getCluster($largestClust)->getCentroid()->getCy(); }
rockin
http://geothings.ning.com/Flickr/flickrgeocodr_cluster.php to output more detailed information regarding the clusters themselves  in REST XML or JSON. You will need to create a query string. The only required key-value pair is &quot;place&quot;, and it will use the other values on their default settings. *  place  = the placename to search for. *  format = json|xml (default xml). *  searchmode  = tags|text (default tags) (text searchs tags, title and description). *  sortmode  = interestingness-desc|relevance| (or any other values from Flickr API)(default interestingness-desc). *  bbox  = any min_lon, min_lat, max_lon, max_lat Comma separated, no spaces. Good for limiting to continent / country. (default world -180.0,-90.0,180.0,90.0). *  numresults  = 5 to 500 (default 50) Number of photo results to process from  Flickr, more will slow things down,  but may increase sample size, and accuracy. *  numclusters  = 2 to 20 (default 3) Number of clusters to use internally, experiment with this, I find 3 and 4 fine. *  xn_auth =no - a Ning tweak to bypass Ning authenitcation, speeds things up. *  showpoints  = true|false (defaults to false) Returns photos in each cluster (link to photo, and link url) *  showclusters  = true|false (defaults to true) format = xml or json (default is xml)  http://geocodr.net/FlickrGeocodrDocs.php
http://geothings.ning.com/Flickr/flickrgeocodr_cluster.php?place=santa+cruz&numclusters=5&numresults=500 <clusters> <cluster> <type>cluster</type> <id>0</id> <pointcount>10</pointcount> <latitude>-49.734894</latitude> <longitude>-72.9383211</longitude> <place>santa cruz</place> <bbox>-50.483625,-73.280869,-49.280298,-72.321281</bbox> </cluster> <cluster> <type>cluster</type> <id>1</id> <pointcount>178</pointcount> <latitude>36.961319095506</latitude> <longitude>-122.02093021348</longitude> <place>santa cruz</place> <bbox>36.922587,-122.120348,37.025473,-121.854225</bbox> </cluster> <cluster> <type>cluster</type> <id>2</id> <pointcount>6</pointcount> <latitude>49.930333833333</latitude> <longitude>1.7630273333333</longitude> <place>santa cruz</place> <bbox>43.769071,-1.70371,53.4371,11.261426</bbox> </cluster> <cluster> <type>cluster</type> <id>3</id> <pointcount>51</pointcount> <latitude>38.893761862745</latitude> <longitude>-9.4491147254902</longitude> <place>santa cruz</place> <bbox>28.454712,-16.249337,39.164552,-5.990155</bbox> </cluster> <cluster> <type>cluster</type> <id>4</id> <pointcount>5</pointcount> <latitude>37.1452402</latitude> <longitude>-122.2436208</longitude> <place>santa cruz</place> <bbox>37.000924,-122.394363,37.251595,-122.112962</bbox> </cluster> <error>1</error> </clusters>
Cluster 2: Santa Cruz, Portugal
Cluster 3: Santa Cruz, Argentina
Kite Hill, San Francisco
Kite Hill, San Francisco, Google
headmap manifesto http://www.technoccult.com/library/headmap.pdf
http://geothings.ning.com/Flickr/flickrgeocodr.php?place=sadness &bbox=-74.06021118164062,40.694175391548754,-73.86314392089844,40.86108317321337 &searchmode=text&sortmode=relevance&numresults=100&numclusters=4&xn_auth=no <item>   <latitude>40.767735142857</latitude>   <longitude>-73.974891142857</longitude>   <place>sadness</place>   <error>1</error> </item>
sadness in new york! http://maps.google.com/maps?q=40.720959166667%2C-73.995379
sadness in new york! http://maps.google.com/maps?q=40.720959166667%2C-73.995379
global sadness in ... switzerland!
Other Geometries, Bay to Breakers http://geobloggers.com/archives/2008/04/28/making-sense-of-the-world-web20expo-slides-are-online/ thanks Dan Catt!
Crowd Sourced Reverse Geocoding http://geobloggers.com/archives/2008/04/28/making-sense-of-the-world-web20expo-slides-are-online/ thanks Dan Catt!
 
UNDP Environment Projects http://europeandcis.undp.org/environment/#map
Hacks 1 Geotag Projects * RSS -> Mapufacture -> GeoRSS Fit in the layout * Lightbox maps Plot Custom GeoRSS/Layers * Mapstraction/MGeoRSS
Half a world of projects  custom CMS w/ no maps http://europeandcis.undp.org/environment/show/3D245417-F203-1EE9-B535882303FB38F5
Vanilla RSS of UNDP Projects http://europeandcis.undp.org/home/rss?feed=projects&a=121676,121677,121678,121679,121680,121681&showTags=5
UNDP Projects in Mapufacture http://mapufacture.com/feeds/1000504
Editing in UNDP Projects in Cyprus http://mapufacture.com/feeds/1000504/edit?category=Cyprus
Export GeoRSS back out to UNDP <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <rss version=&quot;2.0&quot; xmlns:opensearch=&quot;http://a9.com/-/spec/opensearch/1.1/&quot; xmlns:georss=&quot;http://www.georss.org/georss&quot;> <channel> <title>UNDP Europe &amp;amp; CIS projects</title> <link>http://mapufacture.com/feeds/1000504.rss</link> <pubDate>Sat, 10 May 2008 09:46:15 +0000</pubDate> <description>UNDP Europe &amp;amp; CIS projects</description> <opensearch:startIndex>1</opensearch:startIndex> <opensearch:itemsPerPage>300</opensearch:itemsPerPage> <opensearch:totalResults>297</opensearch:totalResults> <georss:polygon>35.1019340572461 14.26025390625 64.1297836764257 14.26025390625 64.1297836764257 166.22314453125 35.1019340572461 166.22314453125 35.1019340572461 14.26025390625</georss:polygon> <item> <guid>607DD33A-F203-1EE9-BE72B91BA22313DF</guid> <title>Second National Communication for Kyrgyzstan</title> <link>http://europeandcis.undp.org/home/show/607DD33A-F203-1EE9-BE72B91BA22313DF</link> <pubDate>Sun, 20 Apr 2008 17:01:26 +0000</pubDate> <description>Preparation of the Kyrgyz Republic&#8217;s Second National Communication to the UNFCCC</description> <category>Frameworks and strategies for sustainable development Europe &amp; CIS Kyrgyzstan Central Asia</category> <georss:point>42.8679124839153 74.542236328125</georss:point> </item> <item> <guid>3D2883E9-F203-1EE9-B3320F78E2657ECE</guid> <title>Support to alignment of NBSAP with CBD obligations</title> <link>http://europeandcis.undp.org/home/show/3D2883E9-F203-1EE9-B3320F78E2657ECE</link> <pubDate>Sun, 20 Apr 2008 17:01:25 +0000</pubDate> <description>Support to alignment of NBSAP with CBD obligations and to development of CHM</description> <category>Frameworks and strategies for sustainable development Europe &amp; CIS Romania EU member countries and Turkey</category> <georss:point>44.355278211603 26.2353515625</georss:point> </item> http://mapufacture.com/feeds/1000504.rss
Hacks 2 Geotag Projects * RSS -> Mapufacture -> GeoRSS Fit in the layout * Lightbox maps Plot Custom GeoRSS/Layers * Mapstraction/MGeoRSS
Cramped Style Guidelines Redux http://europeandcis.undp.org/environment/
UNDP Environment Projects http://europeandcis.undp.org/environment/#map
Leightbox http://www.eight.nl/files/leightbox/
Adding a Map <a href=&quot;#mapstraction&quot; filter=&quot;water&quot;  latlonzoom=&quot;44.150681,44.34082,4&quot; rel=&quot;mapstraction&quot; class=&quot;lbOn&quot;>
Leightbox mods initialize: function(ctrl) { this.content = ctrl.rel; Event.observe(ctrl, 'click', this.activate.bindAsEventListener(this), false); ctrl.onclick = function(){return false;}; /* CUSTOM MAP CODE */ this.latlonzoom = ctrl.getAttribute('latlonzoom'); this.filter = ctrl.getAttribute('filter'); this.guid = ctrl.getAttribute('guid'); this.edit = ctrl.getAttribute('edit'); if (window.location.hash == &quot;#map&quot;) { this.activate(); } }
//CUSTOM MAP CODE HERE! //mapstraction specific stuff should be done through actions.... displayLightbox: function(display){ var firstLoad = false; if (! mapstraction) { loadmapstraction(this.latlonzoom, this.filter, this.edit, this.guid); firstLoad = true; } $('overlay').style.display = display; $(this.content).style.display = display; mapstraction.getMap().checkResize(); if (firstLoad) { var llz_a = this.latlonzoom.split(&quot;,&quot;);   var lat, lon, zoom;     lat = parseFloat(llz_a[0]); lon = parseFloat(llz_a[1]);  zoom =  parseFloat(llz_a[2]); var myPoint = new LatLonPoint(lat,lon); mapstraction.setCenterAndZoom(myPoint, zoom); } window.scroll(0,0);  if (display == 'none') { window.location = &quot;http://&quot;  + window.location.host + window.location.pathname + &quot;#&quot;; } else { window.location = &quot;http://&quot;  + window.location.host + window.location.pathname + &quot;#map&quot;; } if(display != 'none') this.actions(); }
Hacks 3 Geotag Projects * RSS -> Mapufacture -> GeoRSS Fit in the layout * Lightbox maps Plot Custom GeoRSS/Layers * Mapstraction/MGeoRSS
UNDP Environment Projects http://europeandcis.undp.org/environment/#map
http://brainoff.com/gmaps/mgeorss.html
MGeoRSS MGeoRSS.prototype.initialize=function(map) { this.map = map; this.rssurl = false; this.request = false; this.initIconsAndCats(); } //All too custom... MGeoRSS.prototype.initIconsAndCats=function(){ this.cat2icon = new Array(); this.cat2icon['Access to sustainable energy services'] =  &quot;/uploads/public/File/eemap/icons/sun_20px.png&quot;; this.cat2icon['Frameworks and strategies for sustainable development'] =  &quot;/uploads/public/File/eemap/icons/doc_20px.png&quot;; this.cat2icon['Conservation and sustainable use of biodiversity'] =  &quot;/uploads/public/File/eemap/icons/leaf_20px.png&quot;; this.cat2icon['Sustainable land management to combat desertification and land degradation'] =  &quot;/uploads/public/File/eemap/icons/shovel_20px.png&quot;; this.cat2icon['Effective water governance'] =  &quot;/uploads/public/File/eemap/icons/water_20px.png&quot;; this.cat2icon['National/sectoral policy and planning to control emissions of ODS and POPs'] =  &quot;/uploads/public/File/eemap/icons/doc_20px.png&quot;; this.cat2layer = new Array(); this.cat2layer['Access to sustainable energy services'] = &quot;energy&quot;; this.cat2layer['Frameworks and strategies for sustainable development'] = &quot;policy&quot;; this.cat2layer['Conservation and sustainable use of biodiversity'] = &quot;biodiversity&quot;; this.cat2layer['Sustainable land management to combat desertification and land degradation'] = &quot;land&quot;; this.cat2layer['Effective water governance'] = &quot;water&quot;; this.cat2layer['National/sectoral policy and planning to control emissions of ODS and POPs'] = &quot;policy&quot;; this.cat2layer['country'] = &quot;country&quot;; }
MGeoRSS var marker = new Marker(new LatLonPoint(parseFloat(lat), parseFloat(lng))); var marker; if (cat) { var a_cat = new Array(); for (c in this.cat2layer) { if (cat.indexOf( c ) > -1) { a_cat.push(c);  } } //var a_cat = cat.split(','); for (var i=0; i<=a_cat.length; i++) { var caticon = this.cat2icon[ a_cat[i] ]; if (caticon && ! icon) { icon = caticon; } if (this.cat2layer[ a_cat[i] ]) { var tmp = &quot;&quot;; if (marker.getAttribute('category')) { tmp = marker.getAttribute('category'); tmp = tmp + &quot;,&quot;; tmp = tmp + this.cat2layer[ a_cat[i] ]; } else { tmp = this.cat2layer[ a_cat[i] ]; } marker.setAttribute('category', tmp); } } } if (icon) { if (rss_icon) { marker.setIcon(icon,[18,12]); //marker.setIcon(icon, [23,15]); } else { marker.setIcon(icon,[20,20]); } }
http://mapstraction.com/
Mapstraction/MGeoRSS setup function loadmapstraction(latlonzoom, filter, edit, guid) { .. if (filter) { mapstraction.addFilter('category','contains','country'); var filter_a = filter.split(&quot;,&quot;); for (var i=0; i < filter_a.length; i++) { mapstraction.addFilter('category', 'contains', filter_a[i]); var cb = &quot;checkbox_&quot; + filter_a[i]; if ($(cb)) { $(cb).checked = &quot;CHECKED&quot;; } } } else { mapstraction.addFilter('category','contains','country'); mapstraction.addFilter('category','contains','biodiversity'); mapstraction.addFilter('category','contains','water'); mapstraction.addFilter('category','contains','energy'); mapstraction.addFilter('category','contains','policy'); mapstraction.addFilter('category','contains','land'); } georss2 = new MGeoRSS(); if (guid) { georss2.centerOnGuid(guid); } mapstraction.addMGeoRSS(georss2); georss2.load(&quot;/uploads/public/File/eemap/projects.xml&quot;); georss2 = new MGeoRSS(); mapstraction.addMGeoRSS(georss2); georss2.load(&quot;/uploads/public/File/eemap/countries.xml&quot;); }
Layer Toggle onClick= &quot;javascript:mapstraction.toggleFilter(\'category\',\'contains\',\'water\');    mapstraction.doFilter(true);&quot;
THANKS! Illuminated Hacks http://www.slideshare.net/mikel_maron (soonish) Mikel Maron Where 2.0 101 Tutorial [email_address] http://brainoff.com/

Illuminated Hacks -- Where 2.0 101 Tutorial

  • 1.
    Illuminated Hacks MikelMaron Where 2.0 101 Tutorial [email_address] http://brainoff.com/
  • 2.
    Some of myfavorite hacks for the pleasure of your hacking sensibility with the hopeful outcome of illuminating best practices of putting your website on the geoweb and hinting at the means to get exactly what you need. cause I likes the hacks. hacks are rad.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
    http://cbk0.google.com/cbk?output=xml&ll=37.784692,-122.39303 <panorama> <data_propertiesimage_width=&quot;3500&quot; image_height=&quot;1750&quot; tile_width=&quot;512&quot; tile_height=&quot;512&quot; pano_id=&quot;fPaYJ83UesLvxeiFe1FXdA&quot; num_zoom_levels=&quot;3&quot; lat=&quot;37.784691&quot; lng=&quot;-122.392995&quot;> <copyright>© 2008 Google</copyright> <text>I-80</text> </data_properties> <projection_properties projection_type=&quot;spherical&quot; pano_yaw_deg=&quot;235.97&quot; tilt_yaw_deg=&quot;-84.62&quot; tilt_pitch_deg=&quot;3.21&quot;/> <annotation_properties> <link yaw_deg=&quot;55.54&quot; pano_id=&quot;j-LK2ptQjG2w0EfQ1-6zMQ&quot; road_argb=&quot;0x80f2bf24&quot;> <link_text>I-80</link_text> </link> <link yaw_deg=&quot;233.22&quot; pano_id=&quot;SoF-Grk1MNAwHEJvEsCBTw&quot; road_argb=&quot;0x80f2bf24&quot;> <link_text>I-80</link_text> </link> </annotation_properties> </panorama>
  • 11.
    http://code.google.com/apis/maps/documentation/reference.html#GStreetviewOverlay Official StreetViewAPI panoClient = new GStreetviewClient(); latlng = new GLatLng(37.784692,-122.39303); panoClient.getNearestPanorama(latlng, showPanoData); function showPanoData(panoData) { if (panoData.code != 200) { GLog.write('showPanoData: Server rejected with code: ' + panoData.code); return; } console.log( panoData.location.latlng ); }
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
    Machine Tags namespace:predicate=valuegeobloggers user controlled, just normal tags structured data geo:lat=37.784692 geo:long=-122.39303 geotagged camel:humpcount=1 loosely coupled lastfm:event=97947 iso:isbn=0713998393 http://www.flickr.com/groups/api/discuss/72157594497877875/ http://adactio.com/journal/1274/
  • 18.
    machine_tags (Optional) Asidefrom passing in a fully formed machine tag, there is a special syntax for searching on specific properties : * Find photos using the 'dc' namespace : &quot;machine_tags&quot; => &quot;dc:&quot; * Find photos with a title in the 'dc' namespace : &quot;machine_tags&quot; => &quot;dc:title=&quot; * Find photos titled &quot;mr. camera&quot; in the 'dc' namespace : &quot;machine_tags&quot; => &quot;dc:title=\&quot;mr. camera\&quot; * Find photos whose value is &quot;mr. camera&quot; : &quot;machine_tags&quot; => &quot;*:*=\&quot;mr. camera\&quot;&quot; * Find photos that have a title, in any namespace : &quot;machine_tags&quot; => &quot;*:title=&quot; * Find photos that have a title, in any namespace, whose value is &quot;mr. camera&quot; : &quot;machine_tags&quot; => &quot;*:title=\&quot;mr. camera\&quot;&quot; * Find photos, in the 'dc' namespace whose value is &quot;mr. camera&quot; : &quot;machine_tags&quot; => &quot;dc:*=\&quot;mr. camera\&quot;&quot; Multiple machine tags may be queried by passing a comma-separated list. The number of machine tags you can pass in a single query depends on the tag mode (AND or OR) that you are querying with. &quot;AND&quot; queries are limited to (16) machine tags. &quot;OR&quot; queries are limited to (8). http://www.flickr.com/services/api/flickr.photos.search.html a hack all grown up
  • 19.
  • 20.
    GeoRSS http://upcoming.yahoo.com/syndicate/v2/place/hCca8XSYA5nn0X1Sfw <item><title>May 7, Manifesto SF at The Stud</title> <description><![CDATA[MANIFESTO - Leave the boys at home, this is music for men! Deep house, classic disco. Dance the night away! David Harness & Cez Every Wed - 9pm to 2am players.<br /> ]]></description> <guid>http://upcoming.yahoo.com/event/ 600466 /</guid> <link>http://upcoming.yahoo.com/event/600466/</link> <comments>http://upcoming.yahoo.com/event/60046/#comments</comments> <geo:lat>37.7697</geo:lat> <geo:long>-122.42</geo:long> <pubDate>Thu, 07 May 2008 15:50:49 -0700</pubDate> <dc:date>2008-05-08T15:50:49-07:00</dc:date> <xCal:summary>Manifesto SF</xCal:summary> <xCal:dtstart>2008-05-07T21:00:00Z</xCal:dtstart> <xCal:dtend></xCal:dtend> <xCal:location>http://upcoming.yahoo.com/venue/16322/</xCal:location> <xCal:x-calconnect-venue> <xCal:x-calconnect-venue-id>http://upcoming.yahoo.com/venue/16322/</xCal:x-calconnect-venue-id> <xCal:adr> <xCal:x-calconnect-venue-name> The Stud </xCal:x-calconnect-venue-name> <xCal:x-calconnect-street>Harrison @ 9 th Street</xCal:x-calconnect-street> <xCal:x-calconnect-city>San Francisco</xCal:x-calconnect-city> <xCal:x-calconnect-region>California</xCal:x-calconnect-region> <xCal:x-calconnect-postalcode>94103</xCal:x-calconnect-postalcode> <xCal:x-calconnect-country>United States</xCal:x-calconnect-country> </xCal:adr> <xCal:url type='Venue Website'>http://upcoming.yahoo.com/venue/16322/</xCal:url> <xCal:x-calconnect-tel></xCal:x-calconnect-tel> </xCal:x-calconnect-venue> </item>
  • 21.
    Proposals Reference ExternalGeometries Simple Features (for SQL) Multiple Locations elev floor radius featuretypetag relationshiptag featurename georss.org Geometries Attributes Simple GML RSS 1.0 RSS 2.0 Atom Flavors RSS formats
  • 22.
    Reguest Upcoming GeoRSSFeed For each item, parse out lat, lng, event-id, venue-name With lat/lng, get panoid from StreetView XML api Request StreetView tiles Post images to flickr with upcoming:event maching tag Wait for upcoming squirrels to run Do a little dance
  • 23.
    #!/usr/bin/ruby require 'rexml/document'include REXML require 'net/http' require 'cgi' require 'uri' upcomingrss = &quot;http://upcoming.yahoo.com/syndicate/v2/place/hCca8XSYA5nn0X1Sfw--&quot; panoxml = &quot;http://cbk0.google.com/cbk?output=xml&ll=&quot; panoimg = &quot;http://cbk0.google.com/cbk?output=tile\\&zoom=2\\&y=0\\&panoid=&quot; url = URI.parse(upcomingrss) req = Net::HTTP::Get.new(url.path) res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) } doc = Document.new( res.body ) XPath.each( doc, &quot;//item/&quot;) { |element| begin lat = XPath.first( element, &quot;geo:lat&quot; ).text lng = XPath.first( element, &quot;geo:long&quot; ).text venue = XPath.first( element, &quot;.//xCal:x-calconnect-venue-name&quot; ).text guid = XPath.first( element, &quot;guid&quot; ).text upid = /http:\/\/upcoming.yahoo.com\/event\/(.*)\//.match(guid)[1] panourl = URI.parse(panoxml + lat + &quot;,&quot; + lng) panoreq = Net::HTTP::Get.new(panourl.path + &quot;?&quot; + panourl.query) panores = Net::HTTP.start(panourl.host, panourl.port) {|http| http.request(panoreq) } panodoc = Document.new( panores.body ) panoid = XPath.first(panodoc, &quot;//data_properties&quot;).attributes[&quot;pano_id&quot;] for i in 0..3 system(&quot;wget &quot; + panoimg + panoid + &quot;\\&x=&quot; + i.to_s + &quot; -O img/&quot; + panoid + &quot;.jpg&quot;) tags = &quot;geo:lat=&quot; + lat + &quot; geo:long=&quot; + lng + &quot; upcoming:event=&quot; + upid system(&quot;./flickr.pl img/&quot; + panoid + &quot;.jpg '&quot; + venue + &quot;' '&quot; + tags + &quot;'&quot;) end rescue end }
  • 24.
    #!/usr/bin/perl use Flickr::Upload;use Flickr::API; my $api_key = 'b78f44c2721ef1f146a6d83eb9559f33'; my $api_secret = 'd05b91178ddb026c'; my $api = new Flickr::API( {'key' => $api_key, 'secret' => $api_secret }, 'perms' => 'write' ); my $auth_token = '72157600303046027-ce35689cc50c1afc'; my $ua = Flickr::Upload->new( { 'key' => $api_key, 'secret' => $api_secret } ); $photo_id = $ua->upload( auth_token => $auth_token, photo=>&quot;@ARGV[0]&quot;, email=>'wherecamp@yahoo.com', title=>&quot;@ARGV[1]&quot;, description=>'', tags =>&quot;@ARGV[2]&quot;, is_public => 1, is_friend => 1, is_family => 1 ) ;
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
    Bangladesh Boat Journeyproject led by Dharmafly http://www.bbc.co.uk/worldservice/bangladeshboat/ http://dharmafly.com/
  • 30.
  • 31.
    Hack 1 Easilygeotag posts and pics
  • 32.
  • 33.
  • 34.
    http://microformats.org/wiki/microblogging-nanoformats Nanoformats! L:o Used to define a location o Example: Good place to visit L: Place Georges Pompidou, Paris, France o Example2: Good place to visit L: Place Georges Pompidou, Paris, 75004 o Example3: Good place to visit L:48.860500,2.352260 o Text Syntax: L:<Addres, city or town, region> or L:<Address, city or town, postal code> at the end of a tweet o Geo Syntax: L:<lat,long> + info: (Section 3.4.2 of RFC2426)
  • 35.
  • 36.
    A Model forGeoWeb friendliness http://dev.opera.com/articles/view/location-based-publishing-and-services/ http://dharmafly.com/blog/bangladeshboat
  • 37.
  • 38.
  • 39.
    hAtom microformat <ulclass=&quot; hfeed vcalendar xoxo&quot;> <li class=&quot; hentry vevent xfolkentry postid-t444623812&quot;> <p class=&quot;status&quot;>&#8220; <a rel=&quot;bookmark&quot; class=&quot; entry-title entry-content summary description taggedlink url &quot; href=&quot;http://twitter.com/bangladeshboat/statuses/444623812&quot; title=&quot;Posts from the Bangladesh Boat (on Twitter)&quot;> The month long BBC Bangladesh boat trip has come to an end, and what a momentous four weeks it's been! </a>&#8221; </p> <ul class=&quot;meta&quot;> <li class=&quot;update last-update&quot;>Last updated by <address class=&quot;author vcard fn&quot;> <span class=&quot;photo&quot;> <img class=&quot;photo&quot; src=&quot;http://www.bbc.co.uk/worldservice/bangladeshboat/images/alastair_ben.jpg&quot; alt=&quot;Alastair Lawson-Tancred (left) and Ben Sutherland&quot; width=&quot;134&quot; height=&quot;96&quot; title=&quot;Alastair Lawson-Tancred (left) and Ben Sutherland&quot; /> </span> <span class=&quot;fn&quot;>Ben Sutherland and Alastair Lawson</span> </address> <abbr class=&quot; published dtstart &quot; title=&quot;2007-11-26T16:57:52+06:00&quot;>on 28th November 2007</abbr> </li> </ul>
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
    Hack 2 Freethe Bubble! http://www.bbc.co.uk/worldservice/bangladeshboat/js/mashup.js
  • 50.
  • 51.
  • 52.
    Explode the InfoWindowdivs = document.getElementsByTagName('div'); for (var i=0; i < divs.length; i++) { if (divs[i].style.overflow == &quot;hidden&quot;) { divs[i].style.overflow = &quot;visible&quot;; } }
  • 53.
  • 54.
    Capture the WindowOpening function CustomBalloon(map) { var that = this; this.gmap = map; this.visible = false; this.closed = true; this.infoWindow = this.gmap.getInfoWindow(); // Set global settings.map.custom_infowindow to false // for default GMaps behavior if (settings.map.custom_infowindow) { GEvent.addListener(this.gmap, &quot;infowindowopen&quot;, function() { that.closed = false; if (that.grabbed) { // infoWindow opened off-screen -> move to correct location that.setPosition(); if (!that.visible){ that.show(); } } else { // wait until first infoWindow initialized // -> grab balloon element that.grabGMapInfoWindow(); } }); .. }
  • 55.
    Grab the InfoWindowgrabGMapInfoWindow: function() { var that = this; this.balloon = this.infoWindow[settings.map.gmElements.infoWindow.balloon].parentNode; this.balloon.parentNode.removeChild(this.balloon); this.balloonShadow = this.infoWindow[settings.map.gmElements.infoWindow.shadow].parentNode; this.balloonShadow.parentNode.removeChild(this.balloonShadow); this.newBalloon = document.body.appendChild(extend(cE('div'),{ id: 'balloon' })); this.newBalloon.appendChild(this.balloon); this.hide(); this.infoWindow.hide = function() { that.hide(); }; this.grabbed = true; applyFilters('customBalloonGrabGMapInfoWindow', this); }
  • 56.
    move the windowsetPosition: function() { var x; var y; var a; //L[0] = div containing icon; L[1] is shadow a = findPos(this.marker[settings.map.gmElements.marker.icon_imgs][0]); x = a[0]; y = a[1]; // balloon.firstChild.lastChild is an image stretched to cover // the entire visible balloon, so it's the place to get width/height // arrowx, arrowy are offsets for &quot;arrow&quot; portion of the balloon var arrowx = -25; var arrowy = 70; x -= parseInt(this.balloon.firstChild.lastChild.style.width,10)/2 + arrowx; y -= parseInt(this.balloon.firstChild.lastChild.style.height,10) + arrowy; // offset by the specified offset position x -= this.offset.x; y -= this.offset.y; this.balloon.firstChild.style.left = x + &quot;px&quot;; this.balloon.firstChild.style.top = y +&quot;px&quot;; applyFilters('customBalloonSetPosition', this); }
  • 57.
    findPos // Positionof an object on screen function findPos(obj) { var curleft = 0; var curtop = 0; if (obj.offsetParent) { curleft = obj.offsetLeft; curtop = obj.offsetTop; while ((obj = obj.offsetParent)) { curleft += obj.offsetLeft; curtop += obj.offsetTop; } } return [curleft, curtop]; }
  • 58.
  • 59.
    cute cow codebreak lolcows! mooove!
  • 60.
  • 61.
    mapping flickr tags- europe http://brainoff.com/openplan/flickr/
  • 62.
    foot and mouthhttp://brainoff.com/openplan/flickr/
  • 63.
    worldKit some Perlserving WMS requests (I'll spare you) flickr tag tiles
  • 64.
    naïve Flickr geocodinghttp://brainoff.com/flickr/geocodrer/ sub handle_fl { my ($e, %attr); parseElem(\$e,\%attr,@_); if ($e eq &quot;photo&quot;) { $lat += $attr{'latitude'}; $lng += $attr{'longitude'}; $count++; } } $ua = LWP::UserAgent->new('worldKit','http://brainoff.com/worldkit/ @'); $response = $ua->get( $flickrurl . &quot;tags=$tags&quot; ); if (defined($response)) { if ($response->is_success()) { $xp = new XML::Parser(Handlers => {Start => \&handle_fl, }); eval { $xp->parse($response->content); }; } else { die; } } $lat = $lat / $count; $lng = $lng / $count; print &quot;<b>$tags</b><br>&quot;; print &quot;$lat, $lng<br>&quot;; print &quot;<a href='http://maps.google.com/maps?q=$lat,$lng'>GMap</a>&quot;;
  • 65.
  • 66.
  • 67.
    smarter Flickr geocodingfunction geocode($key, $place, $searchmode, $sortmode, $format, $bbox, $numresults,$numclusters, $tryagain ) { $error = &quot;1&quot;; $f = new phpFlickr('1b5c444be51e50c05eeeed1b72b8747f'); $resp = $f->photos_search(array( $searchmode => $place, 'bbox' => $bbox, 'per_page' => $numresults, 'sort' => $sortmode, 'tag_mode' => 'all', 'extras' => 'geo', )); if ($resp){ $cnt =&quot;0&quot;; $datapoints = array(); foreach ($resp['photo'] as $photo) { $photolat = $photo['latitude']; $photolon = $photo['longitude']; array_push($datapoints, new DataPoint((float)$photolat,(float)$photolon,$photo['title'])); $cnt++; }
  • 68.
    smarter Flickr geocoding$jca = new JCA($numclusters,$numresults * 2 ,$datapoints); $jca->startAnalysis(); $clusters = $jca->getClusterOutput(); $largestClust = 0; $largestClustSize = 0; for ($i=0; $i<count($clusters); $i++){ $tempCluster = $clusters[$i]; if (count($tempCluster) > $largestClustSize) { $largestClustSize = count($tempCluster); $largestClust = $i; } }//for $cX = $jca->getCluster($largestClust)->getCentroid()->getCx(); $cY = $jca->getCluster($largestClust)->getCentroid()->getCy(); }
  • 69.
  • 70.
    http://geothings.ning.com/Flickr/flickrgeocodr_cluster.php to outputmore detailed information regarding the clusters themselves in REST XML or JSON. You will need to create a query string. The only required key-value pair is &quot;place&quot;, and it will use the other values on their default settings. * place = the placename to search for. * format = json|xml (default xml). * searchmode = tags|text (default tags) (text searchs tags, title and description). * sortmode = interestingness-desc|relevance| (or any other values from Flickr API)(default interestingness-desc). * bbox = any min_lon, min_lat, max_lon, max_lat Comma separated, no spaces. Good for limiting to continent / country. (default world -180.0,-90.0,180.0,90.0). * numresults = 5 to 500 (default 50) Number of photo results to process from Flickr, more will slow things down, but may increase sample size, and accuracy. * numclusters = 2 to 20 (default 3) Number of clusters to use internally, experiment with this, I find 3 and 4 fine. * xn_auth =no - a Ning tweak to bypass Ning authenitcation, speeds things up. * showpoints = true|false (defaults to false) Returns photos in each cluster (link to photo, and link url) * showclusters = true|false (defaults to true) format = xml or json (default is xml) http://geocodr.net/FlickrGeocodrDocs.php
  • 71.
    http://geothings.ning.com/Flickr/flickrgeocodr_cluster.php?place=santa+cruz&numclusters=5&numresults=500 <clusters> <cluster><type>cluster</type> <id>0</id> <pointcount>10</pointcount> <latitude>-49.734894</latitude> <longitude>-72.9383211</longitude> <place>santa cruz</place> <bbox>-50.483625,-73.280869,-49.280298,-72.321281</bbox> </cluster> <cluster> <type>cluster</type> <id>1</id> <pointcount>178</pointcount> <latitude>36.961319095506</latitude> <longitude>-122.02093021348</longitude> <place>santa cruz</place> <bbox>36.922587,-122.120348,37.025473,-121.854225</bbox> </cluster> <cluster> <type>cluster</type> <id>2</id> <pointcount>6</pointcount> <latitude>49.930333833333</latitude> <longitude>1.7630273333333</longitude> <place>santa cruz</place> <bbox>43.769071,-1.70371,53.4371,11.261426</bbox> </cluster> <cluster> <type>cluster</type> <id>3</id> <pointcount>51</pointcount> <latitude>38.893761862745</latitude> <longitude>-9.4491147254902</longitude> <place>santa cruz</place> <bbox>28.454712,-16.249337,39.164552,-5.990155</bbox> </cluster> <cluster> <type>cluster</type> <id>4</id> <pointcount>5</pointcount> <latitude>37.1452402</latitude> <longitude>-122.2436208</longitude> <place>santa cruz</place> <bbox>37.000924,-122.394363,37.251595,-122.112962</bbox> </cluster> <error>1</error> </clusters>
  • 72.
    Cluster 2: SantaCruz, Portugal
  • 73.
    Cluster 3: SantaCruz, Argentina
  • 74.
    Kite Hill, SanFrancisco
  • 75.
    Kite Hill, SanFrancisco, Google
  • 76.
  • 77.
  • 78.
    sadness in newyork! http://maps.google.com/maps?q=40.720959166667%2C-73.995379
  • 79.
    sadness in newyork! http://maps.google.com/maps?q=40.720959166667%2C-73.995379
  • 80.
    global sadness in... switzerland!
  • 81.
    Other Geometries, Bayto Breakers http://geobloggers.com/archives/2008/04/28/making-sense-of-the-world-web20expo-slides-are-online/ thanks Dan Catt!
  • 82.
    Crowd Sourced ReverseGeocoding http://geobloggers.com/archives/2008/04/28/making-sense-of-the-world-web20expo-slides-are-online/ thanks Dan Catt!
  • 83.
  • 84.
    UNDP Environment Projectshttp://europeandcis.undp.org/environment/#map
  • 85.
    Hacks 1 GeotagProjects * RSS -> Mapufacture -> GeoRSS Fit in the layout * Lightbox maps Plot Custom GeoRSS/Layers * Mapstraction/MGeoRSS
  • 86.
    Half a worldof projects custom CMS w/ no maps http://europeandcis.undp.org/environment/show/3D245417-F203-1EE9-B535882303FB38F5
  • 87.
    Vanilla RSS ofUNDP Projects http://europeandcis.undp.org/home/rss?feed=projects&a=121676,121677,121678,121679,121680,121681&showTags=5
  • 88.
    UNDP Projects inMapufacture http://mapufacture.com/feeds/1000504
  • 89.
    Editing in UNDPProjects in Cyprus http://mapufacture.com/feeds/1000504/edit?category=Cyprus
  • 90.
    Export GeoRSS backout to UNDP <?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?> <rss version=&quot;2.0&quot; xmlns:opensearch=&quot;http://a9.com/-/spec/opensearch/1.1/&quot; xmlns:georss=&quot;http://www.georss.org/georss&quot;> <channel> <title>UNDP Europe &amp;amp; CIS projects</title> <link>http://mapufacture.com/feeds/1000504.rss</link> <pubDate>Sat, 10 May 2008 09:46:15 +0000</pubDate> <description>UNDP Europe &amp;amp; CIS projects</description> <opensearch:startIndex>1</opensearch:startIndex> <opensearch:itemsPerPage>300</opensearch:itemsPerPage> <opensearch:totalResults>297</opensearch:totalResults> <georss:polygon>35.1019340572461 14.26025390625 64.1297836764257 14.26025390625 64.1297836764257 166.22314453125 35.1019340572461 166.22314453125 35.1019340572461 14.26025390625</georss:polygon> <item> <guid>607DD33A-F203-1EE9-BE72B91BA22313DF</guid> <title>Second National Communication for Kyrgyzstan</title> <link>http://europeandcis.undp.org/home/show/607DD33A-F203-1EE9-BE72B91BA22313DF</link> <pubDate>Sun, 20 Apr 2008 17:01:26 +0000</pubDate> <description>Preparation of the Kyrgyz Republic&#8217;s Second National Communication to the UNFCCC</description> <category>Frameworks and strategies for sustainable development Europe &amp; CIS Kyrgyzstan Central Asia</category> <georss:point>42.8679124839153 74.542236328125</georss:point> </item> <item> <guid>3D2883E9-F203-1EE9-B3320F78E2657ECE</guid> <title>Support to alignment of NBSAP with CBD obligations</title> <link>http://europeandcis.undp.org/home/show/3D2883E9-F203-1EE9-B3320F78E2657ECE</link> <pubDate>Sun, 20 Apr 2008 17:01:25 +0000</pubDate> <description>Support to alignment of NBSAP with CBD obligations and to development of CHM</description> <category>Frameworks and strategies for sustainable development Europe &amp; CIS Romania EU member countries and Turkey</category> <georss:point>44.355278211603 26.2353515625</georss:point> </item> http://mapufacture.com/feeds/1000504.rss
  • 91.
    Hacks 2 GeotagProjects * RSS -> Mapufacture -> GeoRSS Fit in the layout * Lightbox maps Plot Custom GeoRSS/Layers * Mapstraction/MGeoRSS
  • 92.
    Cramped Style GuidelinesRedux http://europeandcis.undp.org/environment/
  • 93.
    UNDP Environment Projectshttp://europeandcis.undp.org/environment/#map
  • 94.
  • 95.
    Adding a Map<a href=&quot;#mapstraction&quot; filter=&quot;water&quot; latlonzoom=&quot;44.150681,44.34082,4&quot; rel=&quot;mapstraction&quot; class=&quot;lbOn&quot;>
  • 96.
    Leightbox mods initialize:function(ctrl) { this.content = ctrl.rel; Event.observe(ctrl, 'click', this.activate.bindAsEventListener(this), false); ctrl.onclick = function(){return false;}; /* CUSTOM MAP CODE */ this.latlonzoom = ctrl.getAttribute('latlonzoom'); this.filter = ctrl.getAttribute('filter'); this.guid = ctrl.getAttribute('guid'); this.edit = ctrl.getAttribute('edit'); if (window.location.hash == &quot;#map&quot;) { this.activate(); } }
  • 97.
    //CUSTOM MAP CODEHERE! //mapstraction specific stuff should be done through actions.... displayLightbox: function(display){ var firstLoad = false; if (! mapstraction) { loadmapstraction(this.latlonzoom, this.filter, this.edit, this.guid); firstLoad = true; } $('overlay').style.display = display; $(this.content).style.display = display; mapstraction.getMap().checkResize(); if (firstLoad) { var llz_a = this.latlonzoom.split(&quot;,&quot;); var lat, lon, zoom; lat = parseFloat(llz_a[0]); lon = parseFloat(llz_a[1]); zoom = parseFloat(llz_a[2]); var myPoint = new LatLonPoint(lat,lon); mapstraction.setCenterAndZoom(myPoint, zoom); } window.scroll(0,0); if (display == 'none') { window.location = &quot;http://&quot; + window.location.host + window.location.pathname + &quot;#&quot;; } else { window.location = &quot;http://&quot; + window.location.host + window.location.pathname + &quot;#map&quot;; } if(display != 'none') this.actions(); }
  • 98.
    Hacks 3 GeotagProjects * RSS -> Mapufacture -> GeoRSS Fit in the layout * Lightbox maps Plot Custom GeoRSS/Layers * Mapstraction/MGeoRSS
  • 99.
    UNDP Environment Projectshttp://europeandcis.undp.org/environment/#map
  • 100.
  • 101.
    MGeoRSS MGeoRSS.prototype.initialize=function(map) {this.map = map; this.rssurl = false; this.request = false; this.initIconsAndCats(); } //All too custom... MGeoRSS.prototype.initIconsAndCats=function(){ this.cat2icon = new Array(); this.cat2icon['Access to sustainable energy services'] = &quot;/uploads/public/File/eemap/icons/sun_20px.png&quot;; this.cat2icon['Frameworks and strategies for sustainable development'] = &quot;/uploads/public/File/eemap/icons/doc_20px.png&quot;; this.cat2icon['Conservation and sustainable use of biodiversity'] = &quot;/uploads/public/File/eemap/icons/leaf_20px.png&quot;; this.cat2icon['Sustainable land management to combat desertification and land degradation'] = &quot;/uploads/public/File/eemap/icons/shovel_20px.png&quot;; this.cat2icon['Effective water governance'] = &quot;/uploads/public/File/eemap/icons/water_20px.png&quot;; this.cat2icon['National/sectoral policy and planning to control emissions of ODS and POPs'] = &quot;/uploads/public/File/eemap/icons/doc_20px.png&quot;; this.cat2layer = new Array(); this.cat2layer['Access to sustainable energy services'] = &quot;energy&quot;; this.cat2layer['Frameworks and strategies for sustainable development'] = &quot;policy&quot;; this.cat2layer['Conservation and sustainable use of biodiversity'] = &quot;biodiversity&quot;; this.cat2layer['Sustainable land management to combat desertification and land degradation'] = &quot;land&quot;; this.cat2layer['Effective water governance'] = &quot;water&quot;; this.cat2layer['National/sectoral policy and planning to control emissions of ODS and POPs'] = &quot;policy&quot;; this.cat2layer['country'] = &quot;country&quot;; }
  • 102.
    MGeoRSS var marker= new Marker(new LatLonPoint(parseFloat(lat), parseFloat(lng))); var marker; if (cat) { var a_cat = new Array(); for (c in this.cat2layer) { if (cat.indexOf( c ) > -1) { a_cat.push(c); } } //var a_cat = cat.split(','); for (var i=0; i<=a_cat.length; i++) { var caticon = this.cat2icon[ a_cat[i] ]; if (caticon && ! icon) { icon = caticon; } if (this.cat2layer[ a_cat[i] ]) { var tmp = &quot;&quot;; if (marker.getAttribute('category')) { tmp = marker.getAttribute('category'); tmp = tmp + &quot;,&quot;; tmp = tmp + this.cat2layer[ a_cat[i] ]; } else { tmp = this.cat2layer[ a_cat[i] ]; } marker.setAttribute('category', tmp); } } } if (icon) { if (rss_icon) { marker.setIcon(icon,[18,12]); //marker.setIcon(icon, [23,15]); } else { marker.setIcon(icon,[20,20]); } }
  • 103.
  • 104.
    Mapstraction/MGeoRSS setup functionloadmapstraction(latlonzoom, filter, edit, guid) { .. if (filter) { mapstraction.addFilter('category','contains','country'); var filter_a = filter.split(&quot;,&quot;); for (var i=0; i < filter_a.length; i++) { mapstraction.addFilter('category', 'contains', filter_a[i]); var cb = &quot;checkbox_&quot; + filter_a[i]; if ($(cb)) { $(cb).checked = &quot;CHECKED&quot;; } } } else { mapstraction.addFilter('category','contains','country'); mapstraction.addFilter('category','contains','biodiversity'); mapstraction.addFilter('category','contains','water'); mapstraction.addFilter('category','contains','energy'); mapstraction.addFilter('category','contains','policy'); mapstraction.addFilter('category','contains','land'); } georss2 = new MGeoRSS(); if (guid) { georss2.centerOnGuid(guid); } mapstraction.addMGeoRSS(georss2); georss2.load(&quot;/uploads/public/File/eemap/projects.xml&quot;); georss2 = new MGeoRSS(); mapstraction.addMGeoRSS(georss2); georss2.load(&quot;/uploads/public/File/eemap/countries.xml&quot;); }
  • 105.
    Layer Toggle onClick=&quot;javascript:mapstraction.toggleFilter(\'category\',\'contains\',\'water\'); mapstraction.doFilter(true);&quot;
  • 106.
    THANKS! Illuminated Hackshttp://www.slideshare.net/mikel_maron (soonish) Mikel Maron Where 2.0 101 Tutorial [email_address] http://brainoff.com/