Monthly Archive for February, 2010

Python Flickr API geo-search example

I just started using the wonderful flickrapi Python interface for, well, searching Flickr for geocoded photos around given locations. It’s fairly easy to use and does most things for you. You start with a Flickr API object…


import flickrapi
api_key = '1234567890'
flickr = flickrapi.FlickrAPI(api_key, cache=True)

…replace some dots with underscores in the Flickr API methods…


photos = flickr.photos_search(tags='boston', lat='42.355056', lon='-71.065503', radius='5')

…and loop through the parsed results…


for photo in photos[0]:
	print photo.attrib['title']
	photoLoc = flickr.photos_geo_getLocation(photo_id=photo.attrib['id'])
	print photoLoc[0][0].attrib['latitude']
	print photoLoc[0][0].attrib['longitude']
	photoSizes = flickr.photos_getSizes(photo_id=photo.attrib['id'])
	print photoSizes[0][1].attrib['source']

…done.

The above code example lists title, latitude, longitude and thumbnail-source of photos found in a 5km radius search around the Boston Common.

Crowdsourcing bicycle routes

If I had to think of a solution to start creating a bicycle routing system, I’d do exactly what The San Francisco County Transportation Authority has done: create smart phone apps, gather information where cyclists are riding, data mine those tracks and build route suggestions on top of that knowledge.

Bicycle routing is in my opinion far more complex than car routing. Car routing is mostly based on well known and documented rules, also known as road traffic regulations. Mix in estimated traffic figures, average speeds and fuel consumptions and you get pretty decent car directions.

For cyclists, a similar rule set exists, but it’s maybe a little more, let’s call it, elastic. Cyclists use short-cuts, turn where cars can’t, go against traffic, ride through parks and on poorly documented trails. High traffic doesn’t mean slowdown for cyclists. They ride by on the bike lane on the right side of a traffic jam at almost the same speed as without traffic. But high traffic creates a security risk some cyclists aren’t comfortable with taking and rather choose a different route.

A perfect route from A to B for speedy messengers doesn’t necessarily mean it’s also an ideal route for kids. For your daily commute you probably pick another route than for weekend rides, even though it connects the same points.

Bicycle routing criteria is manifold, sometimes psychological, hard to measure and to quantify. Researching how cyclists are going, for what purpose and under what conditions, is a very smart way to get started on that topic.

Re-projecting vectors in JavaScript

I know, it eventually all boils down to maths. But it still blows my mind that you can re-project geographic features on-the-fly with a few lines of JavaScript in a web browser.

How?

There is this great library PROJ.4, that does everything you’d ever want in terms of cartographic projections. A few smart people have ported PROJ.4 to JavaScript, called Proj4js then.

Proj4js works great in combination with OpenLayers, a popular JavaScript web mapping framework, and allows on-the-fly projections between any spatial reference systems browser applications.

<script src="proj4js-compressed.js"></script>
<script src="http://openlayers.org/api/OpenLayers.js"></script>

Define the spatial reference you’re planning to use. Check Spatial Reference for the exact projection parameters and include them in your code.

Proj4js.defs["EPSG:26986"] = "+title=Massachusetts Mainland NAD83 +proj=lcc +lat_1=42.68333333333333 +lat_2=41.71666666666667 +lat_0=41 +lon_0=-71.5 +x_0=200000 +y_0=750000 +ellps=GRS80 +datum=NAD83 +units=m +no_defs";

Adding all desired projections to the OpenLayers script…

projOSM = new OpenLayers.Projection("EPSG:900913");
projWGS84 = new OpenLayers.Projection("EPSG:4326");
projMassGIS = new OpenLayers.Projection("EPSG:26986");

map = new OpenLayers.Map ("map", {
	maxExtent: new OpenLayers.Bounds( -20037508.34, -20037508.34, 20037508.34, 20037508.34),
	maxResolution: 156543.0399,
	units: 'm',
	projection: projOSM,
	displayProjection: projWGS84,
	allOverlays: false
});

osm = new OpenLayers.Layer.OSM(
	"OpenStreetMap",
       "http://tile.openstreetmap.org/${z}/${x}/${y}.png"
);

openspace = new OpenLayers.Layer.WFS("Open space", "http://giswebservices.massgis.state.ma.us/geoserver/wfs", {
	typename: "massgis:GISDATA.OPENSPACE_POLY"
}, {
	projection: projMassGIS
	attribution: "<a href='http://www.mass.gov/mgis/'>MassGIS</a>"
});

…results in an interactive map with MassGIS Open Space WFS vector features overlayed on an OpenStreetMap base layer, using WGS84 lat/lon as display coordinates.

On a sidenote: OpenLayers comes with a Python proxy to retrieve information from remote servers via an XMLHttpRequest. Here is a good how-to get Python play well with IIS 6 on Windows Server 2003, which was quite useful.

Don’t forget to add the domains you’re trying to access to the Python proxy. For MassGIS you would add following string for instance:

allowedHosts = ['giswebservices.massgis.state.ma.us']