westdc-zf1/htdocs/js/timemap/loaders/georss.js

204 lines
6.9 KiB
JavaScript
Raw Normal View History

2009-12-20 10:56:42 +00:00
/*
* Timemap.js Copyright 2008 Nick Rabinowitz.
* Licensed under the MIT License (see LICENSE.txt)
*/
/**
* @fileOverview
* GeoRSS Loader
*
* @author Nick Rabinowitz (www.nickrabinowitz.com)
*/
/*globals GXml, TimeMap, TimeMapDataset */
/**
* @class
* GeoRSS loader factory - inherits from remote loader.
*
* <p>This is a loader class for GeoRSS feeds. Parsing is complicated by the
* diversity of GeoRSS formats; this parser handles:</p>
* <ul>
* <li>RSS feeds</li>
* <li>Atom feeds</li>
* </ul>
* <p>and looks for geographic information in the following formats:</p>
* <ul>
* <li>GeoRSS-Simple</li>
* <li>GML </li>
* <li>W3C Geo</li>
* </ul>
* <p>At the moment, this only supports points; polygons, polylines, and boxes
* will be added at some later point.</p>
*
* @example Usage in TimeMap.init():
datasets: [
{
title: "GeoRSS Dataset",
type: "georss", // Data to be loaded in GeoRSS
options: {
url: "mydata.rss" // GeoRSS file to load - must be a local URL
}
}
]
*
* @param {Object} options All options for the loader:<pre>
* {Array} url URL of GeoRSS file to load (NB: must be local address)
* {Function} preloadFunction Function to call on data before loading
* {Function} transformFunction Function to call on individual items before loading
* </pre>
* @return {TimeMap.loaders.remote} Remote loader configured for GeoRSS
*/
TimeMap.loaders.georss = function(options) {
var loader = new TimeMap.loaders.remote(options);
loader.parse = TimeMap.loaders.georss.parse;
return loader;
}
/**
* Static function to parse GeoRSS
*
* @param {XML text} rss GeoRSS to be parsed
* @return {TimeMapItem Array} Array of TimeMapItems
*/
TimeMap.loaders.georss.parse = function(rss) {
var items = [], data, node, placemarks, pm;
node = GXml.parse(rss);
// get TimeMap utilty functions
// assigning to variables should compress better
var util = TimeMap.util;
var getTagValue = util.getTagValue,
getNodeList = util.getNodeList,
makePoint = util.makePoint,
makePoly = util.makePoly,
formatDate = util.formatDate,
nsMap = util.nsMap;
// define namespaces
nsMap.georss = 'http://www.georss.org/georss';
nsMap.gml = 'http://www.opengis.net/gml';
nsMap.geo = 'http://www.w3.org/2003/01/geo/wgs84_pos#';
nsMap.kml = 'http://www.opengis.net/kml/2.2';
// determine whether this is an Atom feed or an RSS feed
var feedType = (node.firstChild.tagName == 'rss') ? 'rss' : 'atom';
// look for placemarks
var tName = (feedType == 'rss' ? "item" : "entry");
placemarks = getNodeList(node, tName);
for (var i=0; i<placemarks.length; i++) {
pm = placemarks[i];
data = { options: {} };
// get title & description
data.title = getTagValue(pm, "title");
tName = (feedType == 'rss' ? "description" : "summary");
data.options.description = getTagValue(pm, tName);
// get time information, allowing KML-namespaced time elements
var nList = getNodeList(pm, "TimeStamp", "kml");
if (nList.length > 0) {
data.start = getTagValue(nList[0], "when", "kml");
}
// look for timespan
if (!data.start) {
nList = getNodeList(pm, "TimeSpan", "kml");
if (nList.length > 0) {
data.start = getTagValue(nList[0], "begin", "kml");
data.end = getTagValue(nList[0], "end", "kml") ||
// unbounded spans end at the present time
formatDate(new Date());
}
}
// otherwise, use pubDate/updated elements
if (!data.start) {
if (feedType == 'rss') {
// RSS needs date conversion
var d = new Date(Date.parse(getTagValue(pm, "pubDate")));
// reformat
data.start = formatDate(d);
} else {
// atom uses ISO 8601
data.start = getTagValue(pm, "updated");
}
}
// find placemark - single geometry only for the moment
PLACEMARK: {
var coords, geom;
// look for point, GeoRSS-Simple
coords = getTagValue(pm, "point", 'georss');
if (coords) {
data.point = makePoint(coords);
break PLACEMARK;
}
// look for point, GML
nList = getNodeList(pm, "Point", 'gml');
if (nList.length > 0) {
// GML <pos>
coords = getTagValue(nList[0], "pos", 'gml');
// GML <coordinates>
if (!coords) {
coords = getTagValue(nList[0], "coordinates", 'gml');
}
if (coords) {
data.point = makePoint(coords);
break PLACEMARK;
}
}
// look for point, W3C Geo
if (getTagValue(pm, "lat", 'geo')) {
coords = [
getTagValue(pm, "lat", 'geo'),
getTagValue(pm, "long", 'geo')
];
data.point = makePoint(coords);
break PLACEMARK;
}
// look for polyline, GeoRSS-Simple
coords = getTagValue(pm, "line", 'georss');
if (coords) {
data.polyline = makePoly(coords);
break PLACEMARK;
}
// look for polygon, GeoRSS-Simple
coords = getTagValue(pm, "polygon", 'georss');
if (coords) {
data.polygon = makePoly(coords);
break PLACEMARK;
}
// look for polyline, GML
nList = getNodeList(pm, "LineString", 'gml');
if (nList.length > 0) {
geom = "polyline";
} else {
nList = getNodeList(pm, "Polygon", 'gml');
if (nList.length > 0) {
geom = "polygon";
}
}
if (nList.length > 0) {
// GML <posList>
coords = getTagValue(nList[0], "posList", 'gml');
// GML <coordinates>
if (!coords) {
coords = getTagValue(nList[0], "coordinates", 'gml');
}
if (coords) {
data[geom] = makePoly(coords);
break PLACEMARK;
}
}
// XXX: deal with boxes
}
items.push(data);
}
// clean up
node = null;
placemarks = null;
pm = null;
nList = null;
return items;
};