[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