1 /* 2 * Timemap.js Copyright 2010 Nick Rabinowitz. 3 * Licensed under the MIT License (see LICENSE.txt) 4 */ 5 6 /** 7 * @fileOverview 8 * TimeMap Export Functions 9 * 10 * <p>Functions in this file allow TimeMap, TimeMapDataset, and TimeMapItem 11 * objects to be serialized to a JSON string suitable for loading back into 12 * TimeMap.init(). This allows for a range of server-side options for 13 * data persistence and management.</p> 14 * 15 * @requires json2: lib/json2.pack.js 16 * 17 * @author Nick Rabinowitz (www.nickrabinowitz.com) 18 */ 19 20 /*globals TimeMap, TimeMapDataset, TimeMapItem */ 21 22 /** 23 * Clean up TimeMap into a nice object for serialization 24 * This is called automatically by the JSON.stringify() function 25 */ 26 TimeMap.prototype.toJSON = function() { 27 var data = { 28 'options': this.makeOptionData, 29 'datasets': this.datasets 30 }; 31 data = this.addExportData(data); 32 return data; 33 }; 34 35 /** 36 * Make a cleaned up object for the TimeMap options 37 */ 38 TimeMap.prototype.makeOptionData = function() { 39 var data = {}, util = TimeMap.util; 40 // copy options 41 var opts = this.opts; 42 for (var k in opts) { 43 if (opts.hasOwnProperty(k)) { 44 data[k] = opts[k]; 45 } 46 } 47 // clean up: mapCenter 48 if (data.mapCenter) { 49 data.mapCenter = util.makePoint(data.mapCenter); 50 } 51 // clean up: mapType 52 if (data.mapType) { 53 data.mapType = util.revHash(TimeMap.mapTypes, data.mapType); 54 } 55 // clean up: mapTypes 56 if (data.mapTypes) { 57 var mts=[], mt; 58 for (var x=0; x<data.mapTypes.length; x++) { 59 mt = util.revHash(TimeMap.mapTypes, data.mapTypes[x]); 60 if (mt) { 61 mts.push(mt); 62 } 63 } 64 data.mapTypes = mts; 65 } 66 // clean up: bandIntervals 67 if (data.bandIntervals) { 68 data.bandIntervals = util.revHash(TimeMap.intervals, data.bandIntervals); 69 } 70 // including themes here too - might be a TimeMap attribute 71 var themes=[], t, id; 72 for (id in this.datasets) { 73 if (this.datasets.hasOwnProperty(id)) { 74 t = util.revHash(TimeMapDataset.themes, this.datasets[id].opts.theme); 75 if (t) { 76 themes.push(t); 77 } 78 } 79 } 80 data.themes = t; 81 return data; 82 }; 83 84 /** 85 * Specify additional data for export. Replace this function to change settings. 86 * 87 * @param {Object} data Initial map of export data 88 * @return {Object} Expanded map of export data 89 */ 90 TimeMap.prototype.addExportData = function(data) { 91 data.options = data.options || {}; 92 // set any additional server info (e.g. a database key) in opts.saveOpts 93 data.options.saveOpts = this.opts.saveOpts; 94 return data; 95 }; 96 97 /** 98 * Clean up dataset into a nice object for serialization 99 * This is called automatically by the JSON.stringify() function. 100 * 101 * <p>Note that, at the moment, this function only supports fully-serialized 102 * datasets - so external data imported with JSON or KML will be serialized 103 * in full and no longer connected to their original file.</p> 104 */ 105 TimeMapDataset.prototype.toJSON = function() { 106 var data = { 107 'title': this.getTitle(), 108 'theme': TimeMap.util.revHash(TimeMapDataset.themes, this.opts.theme), 109 'data': { 110 'type':'basic', // only type supported by serialization at the moment 111 'value': this.getItems() 112 } 113 }; 114 data = this.addExportData(data); 115 return data; 116 }; 117 118 /** 119 * Specify additional data for export. Replace this function to change settings. 120 * 121 * @param {Object} data Initial map of export data 122 * @return {Object} Expanded map of export data 123 */ 124 TimeMapDataset.prototype.addExportData = function(data) { 125 data.options = data.options || {}; 126 // set any additional server info (e.g. a database key) in opts.saveOpts 127 data.options.saveOpts = this.opts.saveOpts; 128 return data; 129 }; 130 131 // XXX: export items to KML with placemark.getKmlAsync? 132 133 /** 134 * Clean up item into a nice object for serialization. 135 * This is called automatically by the JSON.stringify() function 136 */ 137 TimeMapItem.prototype.toJSON = function() { 138 // any additional info (e.g. a database key) should be set in opts.saveOpts 139 var data = { 140 'title': this.getTitle(), 141 'options': { 142 'description': this.opts.description 143 } 144 }; 145 // add event info 146 if (this.event) { 147 data.start = this.event.getStart(); 148 if (!this.event.isInstant()) { 149 data.end = this.event.getEnd(); 150 } 151 } 152 // add placemark info 153 if (this.placemark) { 154 var util = TimeMap.util; 155 // internal function - takes type, placemark, data 156 var makePlacemarkJSON = function(type, pm, pdata) { 157 type = type || util.getPlacemarkType(pm); 158 switch (type) { 159 case "marker": 160 pdata.point = util.makePoint(pm.getLatLng()); 161 break; 162 case "polyline": 163 case "polygon": 164 var line = []; 165 for (var x=0; x<pm.getVertexCount(); x++) { 166 line.push(util.makePoint(pm.getVertex(x))); 167 } 168 pdata[type] = line; 169 break; 170 } 171 return pdata; 172 }; 173 if (this.getType() == 'array') { 174 data.placemarks = []; 175 for (var i=0; i<this.placemark.length; i++) { 176 data.placemarks.push(makePlacemarkJSON(false, this.placemark[i], {})); 177 } 178 } else { 179 data = makePlacemarkJSON(this.getType(), this.placemark, data); 180 } 181 } 182 data = this.addExportData(data); 183 return data; 184 }; 185 186 /** 187 * Specify additional data for export. Replace this function to change settings. 188 * 189 * @param {Object} data Initial map of export data 190 * @return {Object} Expanded map of export data 191 */ 192 TimeMapItem.prototype.addExportData = function(data) { 193 data.options = data.options || {}; 194 // set any additional server info (e.g. a database key) in opts.saveOpts 195 data.options.saveOpts = this.opts.saveOpts; 196 return data; 197 }; 198 199 /** 200 * Util function: get the key from the map if the value is found 201 * 202 * @param {Object} map Object to search 203 * @param {?} val Value to look for 204 * @return {String} Key if found, null if not 205 */ 206 TimeMap.util.revHash = function(map, val) { 207 for (var k in map) { 208 if (map[k] == val) { 209 return k; 210 } 211 } 212 // nothing found 213 return null; 214 }; 215