[OpenLayers-Commits] r3141 - in sandbox/tschaub/google/lib: . OpenLayers/Format
commits at openlayers.org
commits at openlayers.org
Mon May 7 16:04:31 EDT 2007
Author: tschaub
Date: 2007-05-07 16:04:29 -0400 (Mon, 07 May 2007)
New Revision: 3141
Added:
sandbox/tschaub/google/lib/OpenLayers/Format/GeoJSON.js
sandbox/tschaub/google/lib/OpenLayers/Format/JSON.js
Modified:
sandbox/tschaub/google/lib/OpenLayers.js
Log:
adding GeoJSON support to google sandbox
Added: sandbox/tschaub/google/lib/OpenLayers/Format/GeoJSON.js
===================================================================
--- sandbox/tschaub/google/lib/OpenLayers/Format/GeoJSON.js (rev 0)
+++ sandbox/tschaub/google/lib/OpenLayers/Format/GeoJSON.js 2007-05-07 20:04:29 UTC (rev 3141)
@@ -0,0 +1,270 @@
+/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
+ * for the full text of the license. */
+
+/**
+ * Read and write GeoJSON.
+ * @requires OpenLayers/Format/JSON.js
+ */
+OpenLayers.Format.GeoJSON = OpenLayers.Class.create();
+OpenLayers.Format.GeoJSON.prototype =
+ OpenLayers.Class.inherit(OpenLayers.Format.JSON, {
+
+ /**
+ * Deserialize a GeoJSON string.
+ * @param {String} json A GeoJSON string
+ * @param {Function} filter A function which will be called for every key
+ * and value at every level of the final result.
+ * Each value will be replaced by the result of
+ * the filter function. This can be used to reform
+ * generic objects into instances of classes, or to
+ * transform date strings into Date objects.
+ * @returns {Array(OpenLayers.Feature.Vector)} An array of features
+ */
+ read: function(json, filter) {
+ var obj = OpenLayers.Format.JSON.prototype.read.apply(this, [json, filter]);
+ var features = [];
+ var f = null;
+ if(!(obj.features instanceof Array)) {
+ // deal with bad GeoJSON
+ //OpenLayers.console.error("Bad GeoJSON: " + obj);
+ } else {
+ for(var i=0; i<obj.features.length; ++i) {
+ try {
+ f = this.parseFeature(obj.features[i]);
+ features.push(f);
+ } catch(err) {
+ // deal with bad features
+ //OpenLayers.console.error('Bad Features:' + err);
+ }
+ }
+ }
+ return features;
+ },
+
+ /**
+ * Convert a feature object from GeoJSON into an OpenLayers.Feature.Vector.
+ * @param {Object} obj An object created from a GeoJSON fragment
+ * @returns {OpenLayers.Feature.Vector} A feature
+ * @private
+ */
+ parseFeature: function(obj) {
+ var feature, geometry, attributes;
+ attributes = (obj.properties) ? obj.properties : {};
+ try {
+ geometry = this.parseGeometry(obj.geometry);
+ } catch(err) {
+ // deal with bad geometries
+ throw err;
+ }
+ feature = new OpenLayers.Feature.Vector(geometry, attributes);
+ return feature;
+ },
+
+ /**
+ * Convert a geometry object from GeoJSON into an OpenLayers.Geometry.
+ * @param {Object} obj An object created from a GeoJSON fragment
+ * @returns {OpenLayers.Geometry} A geometry
+ * @private
+ */
+ parseGeometry: function(obj) {
+ var geometry;
+ if(!(obj.coordinates instanceof Array)) {
+ throw "Geometry must have coordinates array: " + obj;
+ }
+ if(!this.parseCoords[obj.type]) {
+ throw "Unsupported geometry type: " + obj.type;
+ }
+ try {
+ geometry = this.parseCoords[obj.type].apply(this, [obj.coordinates]);
+ } catch(err) {
+ // deal with bad coordinates
+ throw err;
+ }
+ return geometry;
+ },
+
+ /**
+ * Object with properties corresponding to the GeoJSON geometry types.
+ * Property values are functions that do the actual parsing.
+ * @private
+ */
+ parseCoords: {
+ /**
+ * Convert a coordinate array from GeoJSON into an OpenLayers.Geometry.
+ * @param {Object} array The coordinates array from the GeoJSON fragment
+ * @returns {OpenLayers.Geometry} A geometry
+ * @private
+ */
+ "Point": function(array) {
+ if(array.length != 1) {
+ throw "Bad point coordinates: " + array;
+ }
+ if(array[0].length != 2) {
+ throw "Only 2D points are supported: " + array[0];
+ }
+ return new OpenLayers.Geometry.Point(array[0][0], array[0][1]);
+ },
+
+ /**
+ * Convert a coordinate array from GeoJSON into an OpenLayers.Geometry.
+ * @param {Object} array The coordinates array from the GeoJSON fragment
+ * @returns {OpenLayers.Geometry} A geometry
+ * @private
+ */
+ "Line": function(array) {
+ var points = [];
+ var p = null;
+ for(var i=0; i<array.length; ++i) {
+ p = this.parseCoords["Point"].apply(this, [[array[i]]]);
+ points.push(p);
+ }
+ return new OpenLayers.Geometry.LineString(points);
+ },
+
+ /**
+ * Convert a coordinate array from GeoJSON into an OpenLayers.Geometry.
+ * @param {Object} array The coordinates array from the GeoJSON fragment
+ * @returns {OpenLayers.Geometry} A geometry
+ * @private
+ */
+ "Polygon": function(array) {
+ var rings = [];
+ var r, l;
+ for(var i=0; i<array.length; ++i) {
+ l = this.parseCoords["Line"].apply(this, [array[i]]);
+ r = new OpenLayers.Geometry.LinearRing(l.components);
+ rings.push(r);
+ }
+ return new OpenLayers.Geometry.Polygon(rings);
+ }
+ },
+
+ /**
+ * Serialize an array of features into a GeoJSON string.
+ * @param {Array} features An array of OpenLayers.Feature.Vector
+ * @returns {String} The GeoJSON string representation of the input features
+ */
+ write: function(features) {
+ var feature, geometry, type, data, crs;
+ var array = [];
+ try {
+ crs = features[0].layer.projection;
+ } catch(e) {
+ crs = null;
+ }
+ for(var i=0; i<features.length; ++i) {
+ feature = features[i];
+ geometry = feature.geometry;
+ type = geometry.CLASS_NAME.split('.')[2];
+ data = this.extract[type.toLowerCase()].apply(this, [geometry]);
+ if (type == "LineString") {
+ type = "Line";
+ }
+ if (type == "Point") {
+ data = [data];
+ }
+ array.push({
+ 'id': feature.id,
+ 'properties': feature.attributes,
+ 'geometry': {
+ 'type': type,
+ 'coordinates': data
+ }
+ });
+ }
+ return OpenLayers.Format.JSON.prototype.write.apply(this, [{
+ 'features': array,
+ 'crs': crs
+ }]);
+ },
+
+ /**
+ * Object with properties corresponding to the geometry types.
+ * Property values are functions that do the actual value extraction.
+ */
+ extract: {
+ /**
+ * Return an array of coordinates from a point.
+ * @param {OpenLayers.Geometry.Point} point
+ * @returns {Array} An array of coordinates representing the point
+ */
+ 'point': function(point) {
+ return [point.x, point.y];
+ },
+
+ /**
+ * Return an array of point coordinates from a multipoint.
+ * @param {OpenLayers.Geometry.MultiPoint} multipoint
+ * @returns {Array} An array of point coordinate arrays representing
+ * the multipoint
+ */
+ 'multipoint': function(multipoint) {
+ var array = [];
+ for(var i=0; i<multipoint.components.length; ++i) {
+ array.push(this.extract.point.apply(this, [multipoint.components[i]]));
+ }
+ return array;
+ },
+
+ /**
+ * Return an array of coordinate arrays from a line.
+ * @param {OpenLayers.Geometry.LineString} linestring
+ * @returns {Array} An array of coordinate arrays representing
+ * the linestring
+ */
+ 'linestring': function(linestring) {
+ var array = [];
+ for(var i=0; i<linestring.components.length; ++i) {
+ array.push(this.extract.point.apply(this, [linestring.components[i]]));
+ }
+ return array;
+ },
+
+ /**
+ * Return an array of linestring arrays from a line.
+ * @param {OpenLayers.Geometry.MultiLineString} line
+ * @returns {Array} An array of linestring arrays representing
+ * the multilinestring
+ */
+ 'multilinestring': function(multilinestring) {
+ var array = [];
+ for(var i=0; i<multilinestring.components.length; ++i) {
+ array.push(this.extract.linestring.apply(this, [multilinestring.components[i]]));
+ }
+ return array;
+ },
+
+ /**
+ * Return an array of linear ring arrays from a polygon.
+ * @param {OpenLayers.Geometry.Polygon} polygon
+ * @returns {Array} An array of linear ring arrays representing the polygon
+ */
+ 'polygon': function(polygon) {
+ var array = [];
+ for(var i=0; i<polygon.components.length; ++i) {
+ array.push(this.extract.linestring.apply(this, [polygon.components[i]]));
+ }
+ return array;
+ },
+
+ /**
+ * Return an array of polygon arrays from a multipolygon.
+ * @param {OpenLayers.Geometry.MultiPolygon} multipolygon
+ * @returns {Array} An array of polygon arrays representing
+ * the multipolygon
+ */
+ 'multipolygon': function(multipolygon) {
+ var array = [];
+ for(var i=0; i<multipolygon.components.length; ++i) {
+ array.push(this.extract.polygon.apply(this, [multipolygon.components[i]]));
+ }
+ return array;
+ }
+
+ },
+
+ /** @final @type String */
+ CLASS_NAME: "OpenLayers.Format.GeoJSON"
+
+});
Added: sandbox/tschaub/google/lib/OpenLayers/Format/JSON.js
===================================================================
--- sandbox/tschaub/google/lib/OpenLayers/Format/JSON.js (rev 0)
+++ sandbox/tschaub/google/lib/OpenLayers/Format/JSON.js 2007-05-07 20:04:29 UTC (rev 3141)
@@ -0,0 +1,226 @@
+/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
+ * for the full text of the license. */
+
+/**
+ * This work draws heavily from the public domain JSON serializer/deserializer
+ * at http://www.json.org/json.js.
+ * Rewritten so that it doesn't modify basic data prototypes.
+ */
+
+/**
+ * Read and write JSON.
+ * @requires OpenLayers/Format.js
+ */
+OpenLayers.Format.JSON = OpenLayers.Class.create();
+OpenLayers.Format.JSON.prototype =
+ OpenLayers.Class.inherit( OpenLayers.Format, {
+
+ /**
+ * Deserialize a json string.
+ * @param {String} json A JSON string
+ * @param {Function} filter A function which will be called for every key
+ * and value at every level of the final result.
+ * Each value will be replaced by the result of
+ * the filter function. This can be used to reform
+ * generic objects into instances of classes, or to
+ * transform date strings into Date objects.
+ * @returns {Object} An object, array, string, or number
+ */
+ read: function(json, filter) {
+ // Parsing happens in three stages. In the first stage, we run the text against
+ // a regular expression which looks for non-JSON characters. We are especially
+ // concerned with '()' and 'new' because they can cause invocation, and '='
+ // because it can cause mutation. But just to be safe, we will reject all
+ // unexpected characters.
+ try {
+ if(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.
+ test(json)) {
+
+ // In the second stage we use the eval function to compile the text into a
+ // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+ // in JavaScript: it can begin a block or an object literal. We wrap the text
+ // in parens to eliminate the ambiguity.
+ var object = eval('(' + json + ')');
+
+ // In the optional third stage, we recursively walk the new structure, passing
+ // each name/value pair to a filter function for possible transformation.
+ if(typeof filter === 'function') {
+ function walk(k, v) {
+ if(v && typeof v === 'object') {
+ for(var i in v) {
+ if(v.hasOwnProperty(i)) {
+ v[i] = walk(i, v[i]);
+ }
+ }
+ }
+ return filter(k, v);
+ }
+ object = walk('', object);
+ }
+ return object;
+ }
+ } catch(e) {
+ // Fall through if the regexp test fails.
+ }
+ return null;
+ },
+
+ /**
+ * Serialize an object into a JSON string.
+ * @param {String} value The object, array, string, number, boolean or date
+ * to be serialized.
+ * @returns {String} The JSON string representation of the input value
+ */
+ write: function(value) {
+ var json = null;
+ var type = typeof value;
+ if(this.serialize[type]) {
+ json = this.serialize[type].apply(this, [value]);
+ }
+ return json;
+ },
+
+ /**
+ * Object with properties corresponding to the serializable data types.
+ * Property values are functions that do the actual serializing.
+ */
+ serialize: {
+ /**
+ * Transform an object into a JSON string.
+ * @param {Object} object The object to be serialized
+ * @returns {String} A JSON string representing the object
+ */
+ 'object': function(object) {
+ // three special objects that we want to treat differently
+ if(object == null) {
+ return "null";
+ }
+ if(object.constructor == Date) {
+ return this.serialize.date.apply(this, [object]);
+ }
+ if(object.constructor == Array) {
+ return this.serialize.array.apply(this, [object]);
+ }
+ var pieces = ['{'];
+ var key, keyJSON, valueJSON;
+
+ var addComma = false;
+ for(key in object) {
+ if(object.hasOwnProperty(key)) {
+ // recursive calls need to allow for sub-classing
+ keyJSON = OpenLayers.Format.JSON.prototype.write.apply(this, [key]);
+ valueJSON = OpenLayers.Format.JSON.prototype.write.apply(this, [object[key]]);
+ if(keyJSON != null && valueJSON != null) {
+ if(addComma) {
+ pieces.push(',');
+ }
+ pieces.push(keyJSON, ':', valueJSON);
+ addComma = true;
+ }
+ }
+ }
+
+ pieces.push('}');
+ return pieces.join('');
+ },
+
+ /**
+ * Transform an array into a JSON string.
+ * @param {Array} array The array to be serialized
+ * @returns {String} A JSON string representing the array
+ */
+ 'array': function(array) {
+ var json;
+ var pieces = ['['];
+
+ for(var i=0; i<array.length; ++i) {
+ // recursive calls need to allow for sub-classing
+ json = OpenLayers.Format.JSON.prototype.write.apply(this, [array[i]]);
+ if(json != null) {
+ if(i > 0) {
+ pieces.push(',');
+ }
+ pieces.push(json);
+ }
+ }
+
+ pieces.push(']');
+ return pieces.join('');
+ },
+
+ /**
+ * Transform a string into a JSON string.
+ * @param {String} string The string to be serialized
+ * @returns {String} A JSON string representing the string
+ */
+ 'string': function(string) {
+ // If the string contains no control characters, no quote characters, and no
+ // backslash characters, then we can simply slap some quotes around it.
+ // Otherwise we must also replace the offending characters with safe
+ // sequences.
+ var m = {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ };
+ if(/["\\\x00-\x1f]/.test(string)) {
+ return '"' + string.replace(/([\x00-\x1f\\"])/g, function(a, b) {
+ var c = m[b];
+ if(c) {
+ return c;
+ }
+ c = b.charCodeAt();
+ return '\\u00' +
+ Math.floor(c / 16).toString(16) +
+ (c % 16).toString(16);
+ }) + '"';
+ }
+ return '"' + string + '"';
+ },
+
+ /**
+ * Transform a number into a JSON string.
+ * @param {Number} number The number to be serialized
+ * @returns {String} A JSON string representing the number
+ */
+ 'number': function(number) {
+ return isFinite(number) ? String(number) : "null";
+ },
+
+ /**
+ * Transform a boolean into a JSON string.
+ * @param {Boolean} bool The boolean to be serialized
+ * @returns {String} A JSON string representing the boolean
+ */
+ 'boolean': function(bool) {
+ return String(bool);
+ },
+
+ /**
+ * Transform a date into a JSON string.
+ * @param {Date} date The date to be serialized
+ * @returns {String} A JSON string representing the date
+ */
+ 'date': function(date) {
+ function format(number) {
+ // Format integers to have at least two digits.
+ return (number < 10) ? '0' + number : number;
+ }
+ return '"' + date.getFullYear() + '-' +
+ format(date.getMonth() + 1) + '-' +
+ format(date.getDate()) + 'T' +
+ format(date.getHours()) + ':' +
+ format(date.getMinutes()) + ':' +
+ format(date.getSeconds()) + '"';
+ }
+ },
+
+ /** @final @type String */
+ CLASS_NAME: "OpenLayers.Format.JSON"
+
+});
Modified: sandbox/tschaub/google/lib/OpenLayers.js
===================================================================
--- sandbox/tschaub/google/lib/OpenLayers.js 2007-05-07 19:56:03 UTC (rev 3140)
+++ sandbox/tschaub/google/lib/OpenLayers.js 2007-05-07 20:04:29 UTC (rev 3141)
@@ -145,6 +145,8 @@
"OpenLayers/Format/GeoRSS.js",
"OpenLayers/Format/WFS.js",
"OpenLayers/Format/WKT.js",
+ "OpenLayers/Format/JSON.js",
+ "OpenLayers/Format/GeoJSON.js",
"OpenLayers/Layer/WFS.js",
"OpenLayers/Control/MouseToolbar.js",
"OpenLayers/Control/NavToolbar.js",
More information about the Commits
mailing list