Monday, November 15, 2010

Lightweight, Cross-platform, Real-time Browser-Browser Communications

During a monthly meeting to discuss cutting edge technologies here at the Biodiversity Informatics Group at the Marine Biological Laboratory, I demonstrated a technique to update distributed browsers in the face of collaborative classification (i.e. tree) editing. In essence, if there are 2+ people asynchronously (i.e. via AJAX calls) updating content on a web page, there is potential for everyone to get horribly out of sync with one another. Imagine for example a chat window on a web page that does not update on everyone's web page in real time....wouldn't make for a particularly pleasant or useful experience for anyone. The same lousy experience was true in the LifeDesks tree editor when 2+ people were simultaneously updating the same classification. Person A might delete or move a node and person B, C, D, ... etc. are none the wiser and might later perform an action on that node (or its children) whereas the database no longer reflects what they see in their browser screen.

To work around the possibility that everyone editing can get horribly out of sync with one another, I implemented a polling mechanism to grab recent adjustments to data every 5 seconds. If you happen to be looking at a portion of the tree that someone else has just deleted or moved elsewhere in the tree, relevant nodes within the tree will now automagically refresh to reflect actions that someone else just did...nodes will flash red then disappear, nodes will flash green then appear, etc. There is also a scrolling activity monitor at the bottom of the screen. To be sure, this isn't a particularly robust mechanism because there is constant polling. Enter web sockets...

Ryan Schenk
who attended this informal demonstration alerted me to Socket IO. I knew of it, but never paid much attention. However, after having poked around a little bit with the examples provided, I am convinced this is the way I should have designed real-time classification tree updates in the face of 2+ simultaneous user actions. The lightweight technique will prove useful for any client-client communications (e.g. real time chat). Plus, it has the excellent benefit of cross-browser, cross-platform capabilities with very little server strain. A database need only be hit once when person A exerts an action and the data propagates to all other users. Very cool.

Friday, November 12, 2010

MapServer, MapScript, MacPorts

For anyone wishing to get into MapServer and serve shapefiles via PHP and also use a Mac with MacPorts for local development, here is how to compile. I discovered the hard way that the MacPorts port for MapServer is horribly dated and DOES NOT include PHP-MapScript. Compile instructions below assume you already have the php5 MacPort.

Install some dependencies if you haven't already got them:

sudo port install php5-gd
sudo port install xpm
sudo port install proj
sudo port install geos
sudo port install gdal

1. Download latest MapServer tarball, (e.g. at time of writing
2. Extract and cd into folder
3. Execute from command line:

$ ./configure \
--prefix=/usr \
--with-agg \
--with-proj=/opt/local \
--with-geos=/opt/local/bin/geos-config \
--with-gdal=/opt/local/bin/gdal-config \
--with-threads \
--with-ogr \
--without-tiff \
--with-freetype=/opt/local \
--with-xpm=/opt/local \
--with-png=/opt/local \
--with-jpeg=/opt/local \
--with-gd=/opt/local \
--with-wfs \
--with-wcs \
--with-wmsclient \
--with-wfsclient \
--with-sos \
--with-fribidi-config \
--with-experimental-png \

4. Execute from command line: $ make
5. Verify that mapserv is working by executing ./mapserv -v
6. Find in mapscripts/php3 and move to PHP extensions directory (usually /opt/local/lib/php/extensions/no-debug-non-zts-20090626/ for MacPorts). You may also need to add to your php.ini.
7. Move mapserv into cgi-bin folder for web server and give permission to execute if desire using it directly (optional)

If MacPorts's GDAL were similarly updated to v. 1.7.3, you could use GeoRSS data just as you would use shapefiles. But, alas, at the time of writing, the version in MacPorts is v. 1.6.2.

While we're on the mapping kick, here is a very excellent source of shapefiles:

...and a bit of PHP code to consume GeoRSS using the Magpie RSS library. The author uses some deprecated PHP functions in places, but it is nonetheless quite useful.