Project

General

Profile

Download (14.7 KB) Statistics
| Branch: | Tag: | Revision:
1
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
2
 * full list of contributors). Published under the 2-clause BSD license.
3
 * See license.txt in the OpenLayers distribution or repository for the
4
 * full text of the license. */
5

    
6
/**
7
 * @requires OpenLayers/Format.js
8
 * @requires OpenLayers/Feature/Vector.js
9
 * @requires OpenLayers/Geometry/Point.js
10
 * @requires OpenLayers/Geometry/MultiPoint.js
11
 * @requires OpenLayers/Geometry/LineString.js
12
 * @requires OpenLayers/Geometry/MultiLineString.js
13
 * @requires OpenLayers/Geometry/Polygon.js
14
 * @requires OpenLayers/Geometry/MultiPolygon.js
15
 */
16

    
17
/**
18
 * Class: OpenLayers.Format.WKT
19
 * Class for reading and writing Well-Known Text.  Create a new instance
20
 * with the <OpenLayers.Format.WKT> constructor.
21
 * 
22
 * Inherits from:
23
 *  - <OpenLayers.Format>
24
 */
25
OpenLayers.Format.WKT = OpenLayers.Class(OpenLayers.Format, {
26
    
27
    /**
28
     * Constructor: OpenLayers.Format.WKT
29
     * Create a new parser for WKT
30
     *
31
     * Parameters:
32
     * options - {Object} An optional object whose properties will be set on
33
     *           this instance
34
     *
35
     * Returns:
36
     * {<OpenLayers.Format.WKT>} A new WKT parser.
37
     */
38
    initialize: function(options) {
39
        this.regExes = {
40
            'typeStr': /^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/,
41
            'spaces': /\s+/,
42
            'parenComma': /\)\s*,\s*\(/,
43
            'doubleParenComma': /\)\s*\)\s*,\s*\(\s*\(/,  // can't use {2} here
44
            'trimParens': /^\s*\(?(.*?)\)?\s*$/
45
        };
46
        OpenLayers.Format.prototype.initialize.apply(this, [options]);
47
    },
48

    
49
    /**
50
     * APIMethod: read
51
     * Deserialize a WKT string and return a vector feature or an
52
     * array of vector features.  Supports WKT for POINT, MULTIPOINT,
53
     * LINESTRING, MULTILINESTRING, POLYGON, MULTIPOLYGON, and
54
     * GEOMETRYCOLLECTION.
55
     *
56
     * Parameters:
57
     * wkt - {String} A WKT string
58
     *
59
     * Returns:
60
     * {<OpenLayers.Feature.Vector>|Array} A feature or array of features for
61
     * GEOMETRYCOLLECTION WKT.
62
     */
63
    read: function(wkt) {
64
        var features, type, str;
65
        wkt = wkt.replace(/[\n\r]/g, " ");
66
        var matches = this.regExes.typeStr.exec(wkt);
67
        if(matches) {
68
            type = matches[1].toLowerCase();
69
            str = matches[2];
70
            if(this.parse[type]) {
71
                features = this.parse[type].apply(this, [str]);
72
            }
73
            if (this.internalProjection && this.externalProjection) {
74
                if (features && 
75
                    features.CLASS_NAME == "OpenLayers.Feature.Vector") {
76
                    features.geometry.transform(this.externalProjection,
77
                                                this.internalProjection);
78
                } else if (features &&
79
                           type != "geometrycollection" &&
80
                           typeof features == "object") {
81
                    for (var i=0, len=features.length; i<len; i++) {
82
                        var component = features[i];
83
                        component.geometry.transform(this.externalProjection,
84
                                                     this.internalProjection);
85
                    }
86
                }
87
            }
88
        }    
89
        return features;
90
    },
91

    
92
    /**
93
     * APIMethod: write
94
     * Serialize a feature or array of features into a WKT string.
95
     *
96
     * Parameters:
97
     * features - {<OpenLayers.Feature.Vector>|Array} A feature or array of
98
     *            features
99
     *
100
     * Returns:
101
     * {String} The WKT string representation of the input geometries
102
     */
103
    write: function(features) {
104
        var collection, geometry, isCollection;
105
        if (features.constructor == Array) {
106
            collection = features;
107
            isCollection = true;
108
        } else {
109
            collection = [features];
110
            isCollection = false;
111
        }
112
        var pieces = [];
113
        if (isCollection) {
114
            pieces.push('GEOMETRYCOLLECTION(');
115
        }
116
        for (var i=0, len=collection.length; i<len; ++i) {
117
            if (isCollection && i>0) {
118
                pieces.push(',');
119
            }
120
            geometry = collection[i].geometry;
121
            pieces.push(this.extractGeometry(geometry));
122
        }
123
        if (isCollection) {
124
            pieces.push(')');
125
        }
126
        return pieces.join('');
127
    },
128

    
129
    /**
130
     * Method: extractGeometry
131
     * Entry point to construct the WKT for a single Geometry object.
132
     *
133
     * Parameters:
134
     * geometry - {<OpenLayers.Geometry.Geometry>}
135
     *
136
     * Returns:
137
     * {String} A WKT string of representing the geometry
138
     */
139
    extractGeometry: function(geometry) {
140
        var type = geometry.CLASS_NAME.split('.')[2].toLowerCase();
141
        if (!this.extract[type]) {
142
            return null;
143
        }
144
        if (this.internalProjection && this.externalProjection) {
145
            geometry = geometry.clone();
146
            geometry.transform(this.internalProjection, this.externalProjection);
147
        }                       
148
        var wktType = type == 'collection' ? 'GEOMETRYCOLLECTION' : type.toUpperCase();
149
        var data = wktType + '(' + this.extract[type].apply(this, [geometry]) + ')';
150
        return data;
151
    },
152
    
153
    /**
154
     * Object with properties corresponding to the geometry types.
155
     * Property values are functions that do the actual data extraction.
156
     */
157
    extract: {
158
        /**
159
         * Return a space delimited string of point coordinates.
160
         * @param {OpenLayers.Geometry.Point} point
161
         * @returns {String} A string of coordinates representing the point
162
         */
163
        'point': function(point) {
164
            return point.x + ' ' + point.y;
165
        },
166

    
167
        /**
168
         * Return a comma delimited string of point coordinates from a multipoint.
169
         * @param {OpenLayers.Geometry.MultiPoint} multipoint
170
         * @returns {String} A string of point coordinate strings representing
171
         *                  the multipoint
172
         */
173
        'multipoint': function(multipoint) {
174
            var array = [];
175
            for(var i=0, len=multipoint.components.length; i<len; ++i) {
176
                array.push('(' +
177
                           this.extract.point.apply(this, [multipoint.components[i]]) +
178
                           ')');
179
            }
180
            return array.join(',');
181
        },
182
        
183
        /**
184
         * Return a comma delimited string of point coordinates from a line.
185
         * @param {OpenLayers.Geometry.LineString} linestring
186
         * @returns {String} A string of point coordinate strings representing
187
         *                  the linestring
188
         */
189
        'linestring': function(linestring) {
190
            var array = [];
191
            for(var i=0, len=linestring.components.length; i<len; ++i) {
192
                array.push(this.extract.point.apply(this, [linestring.components[i]]));
193
            }
194
            return array.join(',');
195
        },
196

    
197
        /**
198
         * Return a comma delimited string of linestring strings from a multilinestring.
199
         * @param {OpenLayers.Geometry.MultiLineString} multilinestring
200
         * @returns {String} A string of of linestring strings representing
201
         *                  the multilinestring
202
         */
203
        'multilinestring': function(multilinestring) {
204
            var array = [];
205
            for(var i=0, len=multilinestring.components.length; i<len; ++i) {
206
                array.push('(' +
207
                           this.extract.linestring.apply(this, [multilinestring.components[i]]) +
208
                           ')');
209
            }
210
            return array.join(',');
211
        },
212
        
213
        /**
214
         * Return a comma delimited string of linear ring arrays from a polygon.
215
         * @param {OpenLayers.Geometry.Polygon} polygon
216
         * @returns {String} An array of linear ring arrays representing the polygon
217
         */
218
        'polygon': function(polygon) {
219
            var array = [];
220
            for(var i=0, len=polygon.components.length; i<len; ++i) {
221
                array.push('(' +
222
                           this.extract.linestring.apply(this, [polygon.components[i]]) +
223
                           ')');
224
            }
225
            return array.join(',');
226
        },
227

    
228
        /**
229
         * Return an array of polygon arrays from a multipolygon.
230
         * @param {OpenLayers.Geometry.MultiPolygon} multipolygon
231
         * @returns {String} An array of polygon arrays representing
232
         *                  the multipolygon
233
         */
234
        'multipolygon': function(multipolygon) {
235
            var array = [];
236
            for(var i=0, len=multipolygon.components.length; i<len; ++i) {
237
                array.push('(' +
238
                           this.extract.polygon.apply(this, [multipolygon.components[i]]) +
239
                           ')');
240
            }
241
            return array.join(',');
242
        },
243

    
244
        /**
245
         * Return the WKT portion between 'GEOMETRYCOLLECTION(' and ')' for an <OpenLayers.Geometry.Collection>
246
         * @param {OpenLayers.Geometry.Collection} collection
247
         * @returns {String} internal WKT representation of the collection
248
         */
249
        'collection': function(collection) {
250
            var array = [];
251
            for(var i=0, len=collection.components.length; i<len; ++i) {
252
                array.push(this.extractGeometry.apply(this, [collection.components[i]]));
253
            }
254
            return array.join(',');
255
        }
256

    
257
    },
258

    
259
    /**
260
     * Object with properties corresponding to the geometry types.
261
     * Property values are functions that do the actual parsing.
262
     */
263
    parse: {
264
        /**
265
         * Return point feature given a point WKT fragment.
266
         * @param {String} str A WKT fragment representing the point
267
         * @returns {OpenLayers.Feature.Vector} A point feature
268
         * @private
269
         */
270
        'point': function(str) {
271
            var coords = OpenLayers.String.trim(str).split(this.regExes.spaces);
272
            return new OpenLayers.Feature.Vector(
273
                new OpenLayers.Geometry.Point(coords[0], coords[1])
274
            );
275
        },
276

    
277
        /**
278
         * Return a multipoint feature given a multipoint WKT fragment.
279
         * @param {String} str A WKT fragment representing the multipoint
280
         * @returns {OpenLayers.Feature.Vector} A multipoint feature
281
         * @private
282
         */
283
        'multipoint': function(str) {
284
            var point;
285
            var points = OpenLayers.String.trim(str).split(',');
286
            var components = [];
287
            for(var i=0, len=points.length; i<len; ++i) {
288
                point = points[i].replace(this.regExes.trimParens, '$1');
289
                components.push(this.parse.point.apply(this, [point]).geometry);
290
            }
291
            return new OpenLayers.Feature.Vector(
292
                new OpenLayers.Geometry.MultiPoint(components)
293
            );
294
        },
295
        
296
        /**
297
         * Return a linestring feature given a linestring WKT fragment.
298
         * @param {String} str A WKT fragment representing the linestring
299
         * @returns {OpenLayers.Feature.Vector} A linestring feature
300
         * @private
301
         */
302
        'linestring': function(str) {
303
            var points = OpenLayers.String.trim(str).split(',');
304
            var components = [];
305
            for(var i=0, len=points.length; i<len; ++i) {
306
                components.push(this.parse.point.apply(this, [points[i]]).geometry);
307
            }
308
            return new OpenLayers.Feature.Vector(
309
                new OpenLayers.Geometry.LineString(components)
310
            );
311
        },
312

    
313
        /**
314
         * Return a multilinestring feature given a multilinestring WKT fragment.
315
         * @param {String} str A WKT fragment representing the multilinestring
316
         * @returns {OpenLayers.Feature.Vector} A multilinestring feature
317
         * @private
318
         */
319
        'multilinestring': function(str) {
320
            var line;
321
            var lines = OpenLayers.String.trim(str).split(this.regExes.parenComma);
322
            var components = [];
323
            for(var i=0, len=lines.length; i<len; ++i) {
324
                line = lines[i].replace(this.regExes.trimParens, '$1');
325
                components.push(this.parse.linestring.apply(this, [line]).geometry);
326
            }
327
            return new OpenLayers.Feature.Vector(
328
                new OpenLayers.Geometry.MultiLineString(components)
329
            );
330
        },
331
        
332
        /**
333
         * Return a polygon feature given a polygon WKT fragment.
334
         * @param {String} str A WKT fragment representing the polygon
335
         * @returns {OpenLayers.Feature.Vector} A polygon feature
336
         * @private
337
         */
338
        'polygon': function(str) {
339
            var ring, linestring, linearring;
340
            var rings = OpenLayers.String.trim(str).split(this.regExes.parenComma);
341
            var components = [];
342
            for(var i=0, len=rings.length; i<len; ++i) {
343
                ring = rings[i].replace(this.regExes.trimParens, '$1');
344
                linestring = this.parse.linestring.apply(this, [ring]).geometry;
345
                linearring = new OpenLayers.Geometry.LinearRing(linestring.components);
346
                components.push(linearring);
347
            }
348
            return new OpenLayers.Feature.Vector(
349
                new OpenLayers.Geometry.Polygon(components)
350
            );
351
        },
352

    
353
        /**
354
         * Return a multipolygon feature given a multipolygon WKT fragment.
355
         * @param {String} str A WKT fragment representing the multipolygon
356
         * @returns {OpenLayers.Feature.Vector} A multipolygon feature
357
         * @private
358
         */
359
        'multipolygon': function(str) {
360
            var polygon;
361
            var polygons = OpenLayers.String.trim(str).split(this.regExes.doubleParenComma);
362
            var components = [];
363
            for(var i=0, len=polygons.length; i<len; ++i) {
364
                polygon = polygons[i].replace(this.regExes.trimParens, '$1');
365
                components.push(this.parse.polygon.apply(this, [polygon]).geometry);
366
            }
367
            return new OpenLayers.Feature.Vector(
368
                new OpenLayers.Geometry.MultiPolygon(components)
369
            );
370
        },
371

    
372
        /**
373
         * Return an array of features given a geometrycollection WKT fragment.
374
         * @param {String} str A WKT fragment representing the geometrycollection
375
         * @returns {Array} An array of OpenLayers.Feature.Vector
376
         * @private
377
         */
378
        'geometrycollection': function(str) {
379
            // separate components of the collection with |
380
            str = str.replace(/,\s*([A-Za-z])/g, '|$1');
381
            var wktArray = OpenLayers.String.trim(str).split('|');
382
            var components = [];
383
            for(var i=0, len=wktArray.length; i<len; ++i) {
384
                components.push(OpenLayers.Format.WKT.prototype.read.apply(this,[wktArray[i]]));
385
            }
386
            return components;
387
        }
388

    
389
    },
390

    
391
    CLASS_NAME: "OpenLayers.Format.WKT" 
392
});     
(31-31/41)