maps.nyc.gov

Source: storage.js

var nyc = nyc || {};

/**
 * @public
 * @namespace
 */
nyc.storage = {};

/**
 * @desc Class to provide access to localStorage and filesystem
 * @public
 * @class
 * @constructor
 */
nyc.storage.Local = function(){};

nyc.storage.Local.prototype = {
	/**
	 * @desc Check if download is available
	 * @public
	 * @function
	 * @return {boolean}
	 */
	canDownload: function(name, data){
		return 'download' in $('<a></a>').get(0);
	},
	/**
	 * @desc Save data to a file prompting the user with a file dialog
	 * @public
	 * @function
	 * @param {string} name File name
	 * @param {string} data JSON data to write to file
	 */
	saveGeoJson: function(name, data){
		var href = 'data:application/json;charset=utf-8,' + encodeURIComponent(data);
		var a = $('<a class="file-dwn"><img></a>');
		$('body').append(a);
		a.attr('href', href).attr('download', name).find('img').trigger('click');
		a.remove();
	},
	/**
	 * @desc Set data in localStorage if available
	 * @public
	 * @function
	 * @param {string} key Storage key
	 * @param {string} data Data to store
	 */
	setItem: function(key, data){
		if ('localStorage' in window){
			localStorage.setItem(key, data);
		}
	},
	/**
	 * @desc Get data from localStorage if available
	 * @public
	 * @function
	 * @param {string} key Storage key
	 * @return {string}
	 */
	getItem: function(key){
		if ('localStorage' in window){
			return localStorage.getItem(key);
		}
	},
	/**
	 * @desc Remove data from localStorage if available
	 * @public
	 * @function
	 * @param {string} key Storage key
	 * @return {string}
	 */
	removeItem: function(key){
		if ('localStorage' in window){
			return localStorage.removeItem(key);
		}
	},
	/**
	 * @desc Open a text file from local disk
	 * @public
	 * @function
	 * @param {function} callback The callback function to receive file content
	 * @param {File=} file File
	 */
	readTextFile: function(callback, file){
		var reader = new FileReader();
		reader.onload = function(){
			callback(reader.result);
		};
		if (!file){
			var input = $('<input class="file-in" type="file">');
			$('body').append(input);
			input.change(function(event){
				input.remove();
				reader.readAsText(event.target.files[0]);
			});
			input.trigger('click');
		}else{
			reader.readAsText(file);
		}
	},
	/**
	 * @desc Open a GeoJSON file from local disk
	 * @public
	 * @function
	 * @param {ol.Map|L.Map} map The map in which the data will be displayed
	 * @param {function=} callback The callback function to receive the added ol.vector.Layer
	 * @param {File=} file File
	 */
	loadGeoJsonFile: function(map, callback, file){
		var me = this;
		me.readTextFile(function(geoJson){
			var layer = me.addToMap(map, geoJson);
			if (callback) callback(layer);
		}, file);
	},
	/**
	 * @desc Open a shapefile from local disk
	 * @public
	 * @function
	 * @param {ol.Map|L.Map} map The map in which the data will be displayed
	 * @param {function=} callback The callback function to receive the added ol.vector.Layer
	 * @param {FileList=} files Files (.shp, .dbf, .prj)
	 * @see https://github.com/mbostock/shapefile
	 */
	loadShapeFile: function(map, callback, files){
		var me = this;
		if (!files){
			var input = $('<input class="file-in" type="file" multiple>');
			$('body').append(input);
			input.change(function(event){
				me.getShpDbfPrj(map, event.target.files, callback);
				input.remove();
			});
			input.trigger('click');
		}else{
			me.getShpDbfPrj(map, files, callback);
		}
	},
	/**
	 * @private
	 * @method
	 * @param {ol.Map|L.Map} map
	 * @param {FileList} file
	 * @param {function} callback
	*/
	getShpDbfPrj: function(map, files, callback){
		var me = this, shp, dbf, prj;
		$.each(files, function(){
			var ext = this.name.substr(name.length - 4);
			if (ext == '.shp') shp = this;
			else if (ext == '.dbf') dbf = this;
			else if (ext == '.prj') prj = this;
		});
		if (shp){
			me.readPrj(prj, function(projcs){
				me.readShpDbf(map, shp, dbf, projcs, callback);
			});
		}else if (callback){
			callback();
		}
	},
	/**
	 * @private
	 * @method
	 * @param {File} prj
	 * @param {function} callback
	*/
	readPrj: function(prj, callback){
		if (prj){
			this.readTextFile(callback, prj);
		}else{
			callback();
		}
	},
	/**
	 * @private
	 * @method
	 * @param {ol.Map|L.Map} map
	 * @param {File} shp
	 * @param {File} dbf
	 * @param {string} projcs
	 * @param {function} callback
	*/
	readShpDbf: function(map, shp, dbf, projcs, callback){
		var me = this, shpBuffer, dbfBuffer;

		var shpReader = new FileReader();
		shpReader.onload = function(event){
			shpBuffer = event.target.result;
			if (dbfBuffer || !dbf){
				me.readShp(map, shpBuffer, dbfBuffer, projcs, callback);
			}
		};

		var dbfReader = new FileReader();
		dbfReader.onload = function(event){
			dbfBuffer = event.target.result;
			if (shpBuffer){
				me.readShp(map, shpBuffer, dbfBuffer, projcs, callback);
			}
		};

		shpReader.readAsArrayBuffer(shp);
		if (dbf) dbfReader.readAsArrayBuffer(dbf);
	},
	/**
	 * @private
	 * @method
	 * @param {ol.Map|L.Map} map
	 * @param {string|ArrayBuffer} shp
	 * @param {string|ArrayBuffer} dbf
	 * @param {function} callback
	*/
	readShp: function(map, shp, dbf, projcs, callback){
		var me = this, features = [];
		shapefile.open(shp, dbf)
		  .then(function(source){
				source.read()
				.then(function collect(result){
					if (result.done){
						var layer = me.addToMap(map, features, projcs);
						if (callback) callback(layer);
						return;
					}else{
						features.push(result.value);
					}
					return source.read().then(collect);
				})
			}).catch(function(error){
				console.error(error.stack);
			});
	},
	/**
	 * @public
	 * @abstract
	 * @method
	 * @param {ol.Map|L.Map} map
	 * @param {string|Array<Object>} features
	 * @param {string} projcs
	 * @return {Object}
	*/
	addToMap: function(map, features, projcs){
		throw 'Must be implemented';
	},
	/**
	 * @private
	 * @method
	 * @param {string} projcs
	  * @return {string|undefined}
	*/
	customProj: function(projcs){
		if (projcs){
			proj4.defs('shp:prj', projcs);
			return 'shp:prj';
		}
	}
};

nyc-lib: Source: storage.js

maps.nyc.gov

Source: storage.js

var nyc = nyc || {};

/**
 * @public
 * @namespace
 */
nyc.storage = {};

/**
 * @desc Class to provide access to localStorage and filesystem
 * @public
 * @class
 * @constructor
 */
nyc.storage.Local = function(){};

nyc.storage.Local.prototype = {
	/**
	 * @desc Check if download is available
	 * @public
	 * @function
	 * @return {boolean}
	 */
	canDownload: function(name, data){
		return 'download' in $('<a></a>').get(0);
	},
	/**
	 * @desc Save data to a file prompting the user with a file dialog
	 * @public
	 * @function
	 * @param {string} name File name
	 * @param {string} data JSON data to write to file
	 */
	saveGeoJson: function(name, data){
		var href = 'data:application/json;charset=utf-8,' + encodeURIComponent(data);
		var a = $('<a class="file-dwn"><img></a>');
		$('body').append(a);
		a.attr('href', href).attr('download', name).find('img').trigger('click');
		a.remove();
	},
	/**
	 * @desc Set data in localStorage if available
	 * @public
	 * @function
	 * @param {string} key Storage key
	 * @param {string} data Data to store
	 */
	setItem: function(key, data){
		if ('localStorage' in window){
			localStorage.setItem(key, data);
		}
	},
	/**
	 * @desc Get data from localStorage if available
	 * @public
	 * @function
	 * @param {string} key Storage key
	 * @return {string}
	 */
	getItem: function(key){
		if ('localStorage' in window){
			return localStorage.getItem(key);
		}
	},
	/**
	 * @desc Remove data from localStorage if available
	 * @public
	 * @function
	 * @param {string} key Storage key
	 * @return {string}
	 */
	removeItem: function(key){
		if ('localStorage' in window){
			return localStorage.removeItem(key);
		}
	},
	/**
	 * @desc Open a text file from local disk
	 * @public
	 * @function
	 * @param {function} callback The callback function to receive file content
	 * @param {File=} file File
	 */
	readTextFile: function(callback, file){
		var reader = new FileReader();
		reader.onload = function(){
			callback(reader.result);
		};
		if (!file){
			var input = $('<input class="file-in" type="file">');
			$('body').append(input);
			input.change(function(event){
				input.remove();
				reader.readAsText(event.target.files[0]);
			});
			input.trigger('click');
		}else{
			reader.readAsText(file);
		}
	},
	/**
	 * @desc Open a GeoJSON file from local disk
	 * @public
	 * @function
	 * @param {ol.Map|L.Map} map The map in which the data will be displayed
	 * @param {function=} callback The callback function to receive the added ol.vector.Layer
	 * @param {File=} file File
	 */
	loadGeoJsonFile: function(map, callback, file){
		var me = this;
		me.readTextFile(function(geoJson){
			var layer = me.addToMap(map, geoJson);
			if (callback) callback(layer);
		}, file);
	},
	/**
	 * @desc Open a shapefile from local disk
	 * @public
	 * @function
	 * @param {ol.Map|L.Map} map The map in which the data will be displayed
	 * @param {function=} callback The callback function to receive the added ol.vector.Layer
	 * @param {FileList=} files Files (.shp, .dbf, .prj)
	 * @see https://github.com/mbostock/shapefile
	 */
	loadShapeFile: function(map, callback, files){
		var me = this;
		if (!files){
			var input = $('<input class="file-in" type="file" multiple>');
			$('body').append(input);
			input.change(function(event){
				me.getShpDbfPrj(map, event.target.files, callback);
				input.remove();
			});
			input.trigger('click');
		}else{
			me.getShpDbfPrj(map, files, callback);
		}
	},
	/**
	 * @private
	 * @method
	 * @param {ol.Map|L.Map} map
	 * @param {FileList} file
	 * @param {function} callback
	*/
	getShpDbfPrj: function(map, files, callback){
		var me = this, shp, dbf, prj;
		$.each(files, function(){
			var ext = this.name.substr(name.length - 4);
			if (ext == '.shp') shp = this;
			else if (ext == '.dbf') dbf = this;
			else if (ext == '.prj') prj = this;
		});
		if (shp){
			me.readPrj(prj, function(projcs){
				me.readShpDbf(map, shp, dbf, projcs, callback);
			});
		}else if (callback){
			callback();
		}
	},
	/**
	 * @private
	 * @method
	 * @param {File} prj
	 * @param {function} callback
	*/
	readPrj: function(prj, callback){
		if (prj){
			this.readTextFile(callback, prj);
		}else{
			callback();
		}
	},
	/**
	 * @private
	 * @method
	 * @param {ol.Map|L.Map} map
	 * @param {File} shp
	 * @param {File} dbf
	 * @param {string} projcs
	 * @param {function} callback
	*/
	readShpDbf: function(map, shp, dbf, projcs, callback){
		var me = this, shpBuffer, dbfBuffer;

		var shpReader = new FileReader();
		shpReader.onload = function(event){
			shpBuffer = event.target.result;
			if (dbfBuffer || !dbf){
				me.readShp(map, shpBuffer, dbfBuffer, projcs, callback);
			}
		};

		var dbfReader = new FileReader();
		dbfReader.onload = function(event){
			dbfBuffer = event.target.result;
			if (shpBuffer){
				me.readShp(map, shpBuffer, dbfBuffer, projcs, callback);
			}
		};

		shpReader.readAsArrayBuffer(shp);
		if (dbf) dbfReader.readAsArrayBuffer(dbf);
	},
	/**
	 * @private
	 * @method
	 * @param {ol.Map|L.Map} map
	 * @param {string|ArrayBuffer} shp
	 * @param {string|ArrayBuffer} dbf
	 * @param {function} callback
	*/
	readShp: function(map, shp, dbf, projcs, callback){
		var me = this, features = [];
		shapefile.open(shp, dbf)
		  .then(function(source){
				source.read()
				.then(function collect(result){
					if (result.done){
						var layer = me.addToMap(map, features, projcs);
						if (callback) callback(layer);
						return;
					}else{
						features.push(result.value);
					}
					return source.read().then(collect);
				})
			}).catch(function(error){
				console.error(error.stack);
			});
	},
	/**
	 * @public
	 * @abstract
	 * @method
	 * @param {ol.Map|L.Map} map
	 * @param {string|Array<Object>} features
	 * @param {string} projcs
	 * @return {Object}
	*/
	addToMap: function(map, features, projcs){
		throw 'Must be implemented';
	},
	/**
	 * @private
	 * @method
	 * @param {string} projcs
	  * @return {string|undefined}
	*/
	customProj: function(projcs){
		if (projcs){
			proj4.defs('shp:prj', projcs);
			return 'shp:prj';
		}
	}
};