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

169 lines
5.5 KiB
JavaScript

/*
* Timemap.js Copyright 2008 Nick Rabinowitz.
* Licensed under the MIT License (see LICENSE.txt)
*/
/**
* @fileOverview
* KML Loader
*
* @author Nick Rabinowitz (www.nickrabinowitz.com)
*/
/*globals GXml, TimeMap */
/**
* @class
* KML loader factory - inherits from remote loader
*
* <p>This is a loader class for KML files. Currently supports all geometry
* types (point, polyline, polygon, and overlay) and multiple geometries.</p>
*
* @example Usage in TimeMap.init():
datasets: [
{
title: "KML Dataset",
type: "kml",
options: {
url: "mydata.kml" // Must be local
}
}
]
*
* @param {Object} options All options for the loader:<pre>
* {Array} url URL of KML 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 KML
*/
TimeMap.loaders.kml = function(options) {
var loader = new TimeMap.loaders.remote(options);
loader.parse = TimeMap.loaders.kml.parse;
return loader;
}
/**
* Static function to parse KML with time data.
*
* @param {XML string} kml KML to be parsed
* @return {TimeMapItem Array} Array of TimeMapItems
*/
TimeMap.loaders.kml.parse = function(kml) {
var items = [], data, kmlnode, placemarks, pm, i, j;
kmlnode = GXml.parse(kml);
// 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;
// recursive time data search
var findNodeTime = function(n, data) {
var check = false;
// look for instant timestamp
var nList = getNodeList(n, "TimeStamp");
if (nList.length > 0) {
data.start = getTagValue(nList[0], "when");
check = true;
}
// otherwise look for span
else {
nList = getNodeList(n, "TimeSpan");
if (nList.length > 0) {
data.start = getTagValue(nList[0], "begin");
data.end = getTagValue(nList[0], "end") ||
// unbounded spans end at the present time
formatDate(new Date());
check = true;
}
}
// try looking recursively at parent nodes
if (!check) {
var pn = n.parentNode;
if (pn.nodeName == "Folder" || pn.nodeName=="Document") {
findNodeTime(pn, data);
}
pn = null;
}
};
// look for placemarks
placemarks = getNodeList(kmlnode, "Placemark");
for (i=0; i<placemarks.length; i++) {
pm = placemarks[i];
data = { options: {} };
// get title & description
data.title = getTagValue(pm, "name");
data.options.description = getTagValue(pm, "description");
// get time information
findNodeTime(pm, data);
// find placemark(s)
var nList, coords, pmobj;
data.placemarks = [];
// look for marker
nList = getNodeList(pm, "Point");
for (j=0; j<nList.length; j++) {
pmobj = { point: {} };
// get lat/lon
coords = getTagValue(nList[j], "coordinates");
pmobj.point = makePoint(coords, 1);
data.placemarks.push(pmobj);
}
// look for polylines
nList = getNodeList(pm, "LineString");
for (j=0; j<nList.length; j++) {
pmobj = { polyline: [] };
// get lat/lon
coords = getTagValue(nList[j], "coordinates");
pmobj.polyline = makePoly(coords, 1);
data.placemarks.push(pmobj);
}
// look for polygons
nList = getNodeList(pm, "Polygon");
for (j=0; j<nList.length; j++) {
pmobj = { polygon: [] };
// get lat/lon
coords = getTagValue(nList[j], "coordinates");
pmobj.polygon = makePoly(coords, 1);
// XXX: worth closing unclosed polygons?
data.placemarks.push(pmobj);
}
items.push(data);
}
// look for ground overlays
placemarks = getNodeList(kmlnode, "GroundOverlay");
for (i=0; i<placemarks.length; i++) {
pm = placemarks[i];
data = { options: {}, overlay: {} };
// get title & description
data.title = getTagValue(pm, "name");
data.options.description = getTagValue(pm, "description");
// get time information
findNodeTime(pm, data);
// get image
nList = getNodeList(pm, "Icon");
data.overlay.image = getTagValue(nList[0], "href");
// get coordinates
nList = getNodeList(pm, "LatLonBox");
data.overlay.north = getTagValue(nList[0], "north");
data.overlay.south = getTagValue(nList[0], "south");
data.overlay.east = getTagValue(nList[0], "east");
data.overlay.west = getTagValue(nList[0], "west");
items.push(data);
}
// clean up
kmlnode = null;
placemarks = null;
pm = null;
nList = null;
return items;
};