基于timemap 1.5,实现时空浏览
This commit is contained in:
parent
c3edc3f083
commit
6dc1248cfa
|
@ -273,7 +273,7 @@ class DataController extends Zend_Controller_Action
|
|||
$dateformat="D M j Y G:i:s O";
|
||||
$md = new MetadataTable();
|
||||
$db=$md->getAdapter();
|
||||
$state=$db->query('select id,uuid,title,description,timebegin,timeend from metadata where timebegin is not null');
|
||||
$state=$db->query('select id,uuid,title,timebegin,timeend from metadata where timebegin is not null');
|
||||
$rows=$state->fetchAll();
|
||||
$timexml='<data>';
|
||||
foreach($rows as $row) {
|
||||
|
@ -331,6 +331,14 @@ class DataController extends Zend_Controller_Action
|
|||
$this->_helper->json($geomd);
|
||||
}
|
||||
/*
|
||||
* 时空动态浏览
|
||||
*/
|
||||
function timemapAction()
|
||||
{
|
||||
$sql='select id,uuid,west,south,north,east,title,timebegin,timeend,description from metadata where timebegin is not null';
|
||||
$this->view->rows=$this->db->fetchAll($sql);
|
||||
}
|
||||
/*
|
||||
* 返回XML源文件
|
||||
*/
|
||||
function xmlAction()
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
$this->headTitle($this->config->title->site);
|
||||
$this->headTitle($this->config->title->data);
|
||||
$this->headTitle('时空导航');
|
||||
$this->headTitle()->setSeparator(' - ');
|
||||
$this->headLink()->appendStylesheet('/css/metadata.css');
|
||||
$this->breadcrumb('<a href="/">首页</a>');
|
||||
$this->breadcrumb('<a href="/data">'.$this->config->title->data.'</a>');
|
||||
$this->breadcrumb('<a href="/data/timeline">时空导航</a>');
|
||||
$this->breadcrumb()->setSeparator(' > ');
|
||||
$this->headScript()->appendFile('http://maps.google.com/maps?file=api&v=2&key=ABQIAAAACD-MqkkoOm60o_dvwdcKVhThiRESR0xRCe9JKd36EL3glTk0OxTsRzifkUWmTTrYWaE7dY1lYUlGxA');
|
||||
$this->headScript()->appendFile('/js/timeline_var.js');
|
||||
$this->headScript()->appendFile('/js/timeline_js/timeline-api.js');
|
||||
$this->headScript()->appendFile('/js/timemap/timemap.js');
|
||||
$this->headScript()->captureStart();
|
||||
?>
|
||||
var tm;
|
||||
window.onload=function() {
|
||||
tm = TimeMap.init({
|
||||
mapId: "map", // Id of map div element (required)
|
||||
timelineId: "timeline", // Id of timeline div element (required)
|
||||
options: {
|
||||
eventIconPath: "../images/"
|
||||
},
|
||||
datasets: [
|
||||
{
|
||||
id: "artists",
|
||||
title: "Artists",
|
||||
theme: "orange",
|
||||
// note that the lines below are now the preferred syntax
|
||||
type: "basic",
|
||||
options: {
|
||||
items: [
|
||||
<?php
|
||||
foreach($this->rows as $row) : ?>
|
||||
{
|
||||
"start" : "<?php echo $row['timebegin']; ?>",
|
||||
<?php if ($row['timeend']!='') : ?>
|
||||
"end" : "<?php echo $row['timeend']; ?>",
|
||||
<?php endif; ?>
|
||||
"polygon" : [
|
||||
{
|
||||
"lat" : <?php echo $row['south']; ?>,
|
||||
"lon" : <?php echo $row['west']; ?>
|
||||
},{
|
||||
"lat" : <?php echo $row['north']; ?>,
|
||||
"lon" : <?php echo $row['west']; ?>
|
||||
},{
|
||||
"lat" : <?php echo $row['north']; ?>,
|
||||
"lon" : <?php echo $row['east']; ?>
|
||||
},{
|
||||
"lat" : <?php echo $row['south']; ?>,
|
||||
"lon" : <?php echo $row['east']; ?>
|
||||
},{
|
||||
"lat" : <?php echo $row['south']; ?>,
|
||||
"lon" : <?php echo $row['west']; ?>
|
||||
}
|
||||
],
|
||||
"title" : "<?php echo $row['title']; ?>",
|
||||
"options" : {
|
||||
// set the full HTML for the info window
|
||||
"infoHtml": "<a href=/data/<?php echo $row['uuid']; ?>><?php echo $row['title']; ?></a><hr /><img src=/data/thumb/id/<?php echo $row['id']; ?> />"
|
||||
}
|
||||
},
|
||||
<?php endforeach; ?>
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
bandIntervals: [
|
||||
Timeline.DateTime.MONTH,
|
||||
Timeline.DateTime.DECADE
|
||||
]
|
||||
});
|
||||
// manipulate the timemap further here if you like
|
||||
}
|
||||
window.onunload=GUnload();
|
||||
<?php $this->headScript()->captureEnd(); ?>
|
||||
<div id='tools'><?= $this->partial('data/tools.phtml'); ?></div>
|
||||
<div id="timemap" style="clear:both;">
|
||||
<div id="timeline" style="height:300px;width:100%;"></div>
|
||||
<div id="map" style="height:300px;"></div>
|
||||
</div>
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Timemap.js Copyright 2008 Nick Rabinowitz.
|
||||
* Licensed under the MIT License (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview
|
||||
* Flickr Loader
|
||||
*
|
||||
* @author Nick Rabinowitz (www.nickrabinowitz.com)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class
|
||||
* Flickr loader factory - inherits from jsonp loader
|
||||
*
|
||||
* <p>This is a loader for data from Flickr. You probably want to use it with a
|
||||
* URL for the Flickr Geo Feed API: <a href="http://www.flickr.com/services/feeds/geo/">http://www.flickr.com/services/feeds/geo/</a></p>
|
||||
*
|
||||
* <p>The loader takes a full URL, minus the JSONP callback function.</p>
|
||||
*
|
||||
* <p>Depends on:</p>
|
||||
* <ul>
|
||||
* <li>loaders/jsonp.js</li>
|
||||
* </ul>
|
||||
*
|
||||
* @example Usage in TimeMap.init():
|
||||
|
||||
datasets: [
|
||||
{
|
||||
title: "Flickr Dataset",
|
||||
type: "flickr",
|
||||
options: {
|
||||
// This is just the latest geotagged photo stream - try adding
|
||||
// an "id" or "tag" or "photoset" parameter to get what you want
|
||||
url: "http://www.flickr.com/services/feeds/geo/?format=json&jsoncallback="
|
||||
}
|
||||
}
|
||||
]
|
||||
*
|
||||
* @param {Object} options All options for the loader:<pre>
|
||||
* {String} url Full JSONP url of Flickr feed to load
|
||||
* {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 Flickr
|
||||
*/
|
||||
TimeMap.loaders.flickr = function(options) {
|
||||
var loader = new TimeMap.loaders.jsonp(options);
|
||||
|
||||
// preload function for Flickr feeds
|
||||
loader.preload = function(data) {
|
||||
return data["items"];
|
||||
};
|
||||
|
||||
// transform function for Flickr feeds
|
||||
loader.transform = function(data) {
|
||||
var item = {
|
||||
title: data["title"],
|
||||
start: data["date_taken"],
|
||||
point: {
|
||||
lat: data["latitude"],
|
||||
lon: data["longitude"]
|
||||
},
|
||||
options: {
|
||||
description: data["description"]
|
||||
.replace(/>/g, ">")
|
||||
.replace(/</g, "<")
|
||||
.replace(/"/g, '"')
|
||||
}
|
||||
};
|
||||
if (options.transformFunction)
|
||||
item = options.transformFunction(item);
|
||||
return item;
|
||||
};
|
||||
|
||||
return loader;
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* 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;
|
||||
};
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Timemap.js Copyright 2008 Nick Rabinowitz.
|
||||
* Licensed under the MIT License (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview
|
||||
* Google Spreadsheet Loader
|
||||
*
|
||||
* @author Nick Rabinowitz (www.nickrabinowitz.com)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class
|
||||
* Google spreadsheet loader factory - inherits from jsonp loader.
|
||||
*
|
||||
* <p>This is a loader for data from Google Spreadsheets. Takes an optional map
|
||||
* to indicate which columns contain which data elements; the default column
|
||||
* names (case-insensitive) are: title, description, start, end, lat, lon</p>
|
||||
*
|
||||
* <p>See <a href="http://code.google.com/apis/spreadsheets/docs/2.0/reference.html#gsx_reference">http://code.google.com/apis/spreadsheets/docs/2.0/reference.html#gsx_reference</a>
|
||||
* for details on how spreadsheet column ids are derived. Note that date fields
|
||||
* must be in yyyy-mm-dd format - you may need to set the cell format as "plain text"
|
||||
* in the spreadsheet (Google's automatic date formatting won't work).</p>
|
||||
*
|
||||
* <p>The loader takes either a full URL, minus the JSONP callback function, or
|
||||
* just the spreadsheet key. Note that the spreadsheet must be published.</p>
|
||||
*
|
||||
* <p>Depends on:</p>
|
||||
* <ul>
|
||||
* <li>loaders/jsonp.js</li>
|
||||
* </ul>
|
||||
*
|
||||
* @example Usage in TimeMap.init():
|
||||
|
||||
datasets: [
|
||||
{
|
||||
title: "Google Spreadsheet by key",
|
||||
type: "gss",
|
||||
options: {
|
||||
key: "pjUcDAp-oNIOjmx3LCxT4XA" // Spreadsheet key
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Google Spreadsheet by url",
|
||||
type: "gss",
|
||||
options: {
|
||||
url: "http://spreadsheets.google.com/feeds/list/pjUcDAp-oNIOjmx3LCxT4XA/1/public/values?alt=json-in-script&callback="
|
||||
}
|
||||
}
|
||||
]
|
||||
*
|
||||
* @param {Object} options All options for the loader:<pre>
|
||||
* {String} key Key of spreadsheet to load, or
|
||||
* {String} url Full JSONP url of spreadsheet to load
|
||||
* {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 Google Spreadsheets
|
||||
*/
|
||||
TimeMap.loaders.gss = function(options) {
|
||||
var loader = new TimeMap.loaders.jsonp(options);
|
||||
|
||||
// use key if no URL was supplied
|
||||
if (!loader.url) {
|
||||
loader.url = "http://spreadsheets.google.com/feeds/list/" +
|
||||
options.key + "/1/public/values?alt=json-in-script&callback=";
|
||||
}
|
||||
|
||||
// column map
|
||||
loader.map = options.map;
|
||||
|
||||
// preload function for spreadsheet data
|
||||
loader.preload = function(data) {
|
||||
return data["feed"]["entry"];
|
||||
};
|
||||
|
||||
// transform function for spreadsheet data
|
||||
loader.transform = function(data) {
|
||||
// map spreadsheet column ids to corresponding TimeMap elements
|
||||
var fieldMap = loader.map || TimeMap.loaders.gss.map;
|
||||
var getField = function(f) {
|
||||
if (f in fieldMap && fieldMap[f]) {
|
||||
return data['gsx$' + fieldMap[f]]['$t'];
|
||||
} else return false;
|
||||
};
|
||||
var item = {
|
||||
title: getField("title"),
|
||||
start: getField("start"),
|
||||
point: {
|
||||
lat: getField("lat"),
|
||||
lon: getField("lon")
|
||||
},
|
||||
options: {
|
||||
description: getField("description")
|
||||
}
|
||||
};
|
||||
// hook for further transformation
|
||||
if (options.transformFunction)
|
||||
item = options.transformFunction(item);
|
||||
return item;
|
||||
};
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1:1 map of expected spreadsheet column ids.
|
||||
*/
|
||||
TimeMap.loaders.gss.map = {
|
||||
'title':'title',
|
||||
'description':'description',
|
||||
'start':'start',
|
||||
'end':'end',
|
||||
'lat':'lat',
|
||||
'lon':'lon'
|
||||
};
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Timemap.js Copyright 2008 Nick Rabinowitz.
|
||||
* Licensed under the MIT License (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview
|
||||
* JSON Loaders (JSONP, JSON String)
|
||||
*
|
||||
* @author Nick Rabinowitz (www.nickrabinowitz.com)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class
|
||||
* JSONP loader class - expects a service that takes a callback function name as
|
||||
* the last URL parameter.
|
||||
*
|
||||
* <p>The jsonp loader assumes that the JSON can be loaded from a url to which a
|
||||
* callback function name can be appended, e.g. "http://www.test.com/getsomejson.php?callback="
|
||||
* The loader then appends a nonce function name which the JSON should include.
|
||||
* This works for services like Google Spreadsheets, etc., and accepts remote URLs.</p>
|
||||
*
|
||||
* @example Usage in TimeMap.init():
|
||||
|
||||
datasets: [
|
||||
{
|
||||
title: "JSONP Dataset",
|
||||
type: "jsonp",
|
||||
options: {
|
||||
url: "http://www.test.com/getsomejson.php?callback="
|
||||
}
|
||||
}
|
||||
]
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} options All options for the loader:<pre>
|
||||
* {Array} url URL of JSON service to load, callback name left off
|
||||
* {Function} preloadFunction Function to call on data before loading
|
||||
* {Function} transformFunction Function to call on individual items before loading
|
||||
* </pre>
|
||||
*/
|
||||
TimeMap.loaders.jsonp = function(options) {
|
||||
// get standard functions
|
||||
TimeMap.loaders.mixin(this, options);
|
||||
// get URL to load
|
||||
this.url = options.url;
|
||||
}
|
||||
|
||||
/**
|
||||
* JSONP load function.
|
||||
*
|
||||
* @param {TimeMapDataset} dataset Dataset to load data into
|
||||
* @param {Function} callback Function to call once data is loaded
|
||||
*/
|
||||
TimeMap.loaders.jsonp.prototype.load = function(dataset, callback) {
|
||||
var loader = this;
|
||||
// get items
|
||||
TimeMap.loaders.jsonp.read(this.url, function(result) {
|
||||
// load
|
||||
items = loader.preload(result);
|
||||
dataset.loadItems(items, loader.transform);
|
||||
// callback
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Static - for naming anonymous callback functions
|
||||
* @type int
|
||||
*/
|
||||
TimeMap.loaders.jsonp.counter = 0;
|
||||
|
||||
/**
|
||||
* Static - reads JSON from a URL, assuming that the service is set up to apply
|
||||
* a callback function specified in the URL parameters.
|
||||
*
|
||||
* @param {String} jsonUrl URL to load, missing the callback function name
|
||||
* @param {function} f Callback function to apply to returned data
|
||||
*/
|
||||
TimeMap.loaders.jsonp.read = function(url, f) {
|
||||
// Define a unique function name
|
||||
var callbackName = "_" + TimeMap.loaders.jsonp.counter++;
|
||||
|
||||
TimeMap.loaders.jsonp[callbackName] = function(result) {
|
||||
// Pass result to user function
|
||||
f(result);
|
||||
// Delete the callback function
|
||||
delete TimeMap.loaders.jsonp[callbackName];
|
||||
};
|
||||
|
||||
// Create a script tag, set its src attribute and add it to the document
|
||||
// This triggers the HTTP request and submits the query
|
||||
var script = document.createElement("script");
|
||||
script.src = url + "TimeMap.loaders.jsonp." + callbackName;
|
||||
document.body.appendChild(script);
|
||||
};
|
||||
|
||||
/**
|
||||
* @class
|
||||
* JSON string loader factory - expects a plain JSON array.
|
||||
* Inherits from remote loader.
|
||||
*
|
||||
* <p>The json_string loader assumes an array of items in plain JSON, with no
|
||||
* callback function - this will require a local URL.</p>
|
||||
*
|
||||
* <p>Depends on:</p>
|
||||
* <ul>
|
||||
* <li>lib/json2.pack.js</li>
|
||||
* </ul>
|
||||
*
|
||||
* @example Usage in TimeMap.init():
|
||||
|
||||
datasets: [
|
||||
{
|
||||
title: "JSON String Dataset",
|
||||
type: "json_string",
|
||||
options: {
|
||||
url: "mydata.json" // Must be a local URL
|
||||
}
|
||||
}
|
||||
]
|
||||
*
|
||||
* @param {Object} options All options for the loader:<pre>
|
||||
* {Array} url URL of JSON service to load, callback name left off
|
||||
* {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 JSON strings
|
||||
*/
|
||||
TimeMap.loaders.json_string = function(options) {
|
||||
var loader = new TimeMap.loaders.remote(options);
|
||||
loader.parse = JSON.parse;
|
||||
return loader;
|
||||
}
|
||||
|
||||
// Probably the default json loader should be json_string, not
|
||||
// jsonp. I may change this in the future, so I'd encourage you to use
|
||||
// the specific one you want.
|
||||
TimeMap.loaders.json = TimeMap.loaders.jsonp;
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* 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;
|
||||
};
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Timemap.js Copyright 2008 Nick Rabinowitz.
|
||||
* Licensed under the MIT License (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview
|
||||
* Metaweb Loader
|
||||
*
|
||||
* @author Nick Rabinowitz (www.nickrabinowitz.com)
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Loader
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class
|
||||
* Metaweb loader factory - inherits from jsonp loader
|
||||
*
|
||||
* <p>This is a loader for data from the Metaweb service at freebase.com. See
|
||||
* the API documentation at <a href="http://www.freebase.com/view/en/documentation">http://www.freebase.com/view/en/documentation</a> for
|
||||
* a description of how to write MQL queries. This code is based on code from
|
||||
* the API site.</p>
|
||||
*
|
||||
* <p>Depends on:</p>
|
||||
* <ul>
|
||||
* <li>lib/json2.pack.js</li>
|
||||
* <li>loaders/jsonp.js</li>
|
||||
* </ul>
|
||||
*
|
||||
* @example Usage in TimeMap.init():
|
||||
|
||||
datasets: [
|
||||
{
|
||||
title: "Freebase Dataset",
|
||||
type: "metaweb",
|
||||
options: {
|
||||
query: [
|
||||
{
|
||||
// query here - see Metaweb API
|
||||
}
|
||||
],
|
||||
transformFunction: function(data) {
|
||||
// map returned data to the expected format - see
|
||||
// http://code.google.com/p/timemap/wiki/JsonFormat
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
*
|
||||
* @param {Object} options All options for the loader:<pre>
|
||||
* {Object} query MQL query to load
|
||||
* {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 MetaWeb
|
||||
*/
|
||||
TimeMap.loaders.metaweb = function(options) {
|
||||
var loader = new TimeMap.loaders.jsonp(options);
|
||||
|
||||
// Host and service - default to freebase.com
|
||||
loader.HOST = options.host || "http://www.freebase.com";
|
||||
loader.QUERY_SERVICE = options.service || "/api/service/mqlread";
|
||||
|
||||
// Metaweb preload functon
|
||||
loader.preload = function(data) {
|
||||
// Open outer envelope
|
||||
var innerEnvelope = data.qname;
|
||||
// Make sure the query was successful
|
||||
if (innerEnvelope.code.indexOf("/api/status/ok") != 0) {
|
||||
// uncomment for debugging
|
||||
/*
|
||||
// If error, get error message and throw
|
||||
var error = innerEnvelope.messages[0];
|
||||
throw error.code + ": " + error.message;
|
||||
*/
|
||||
return [];
|
||||
}
|
||||
// Get result from inner envelope
|
||||
var result = innerEnvelope.result;
|
||||
return result;
|
||||
};
|
||||
|
||||
// format the query URL for Metaweb
|
||||
var q = options.query || {};
|
||||
var querytext = encodeURIComponent(JSON.stringify({qname: {query: q}}));
|
||||
|
||||
// Build the URL using encoded query text and the callback name
|
||||
loader.url = loader.HOST + loader.QUERY_SERVICE + "?queries=" + querytext + "&callback=";
|
||||
|
||||
return loader;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue