1 /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2 * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3 * full text of the license. */
6 * @requires OpenLayers/Format.js
7 * @requires OpenLayers/Feature/Vector.js
11 * Class: OpenLayers.Format.WKT
12 * Class for reading and writing Well-Known Text. Create a new instance
13 * with the <OpenLayers.Format.WKT> constructor.
16 * - <OpenLayers.Format>
18 OpenLayers.Format.WKT = OpenLayers.Class(OpenLayers.Format, {
21 * Constructor: OpenLayers.Format.WKT
22 * Create a new parser for WKT
25 * options - {Object} An optional object whose properties will be set on
29 * {<OpenLayers.Format.WKT>} A new WKT parser.
31 initialize: function(options) {
33 'typeStr': /^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/,
35 'parenComma': /\)\s*,\s*\(/,
36 'doubleParenComma': /\)\s*\)\s*,\s*\(\s*\(/, // can't use {2} here
37 'trimParens': /^\s*\(?(.*?)\)?\s*$/
39 OpenLayers.Format.prototype.initialize.apply(this, [options]);
44 * Deserialize a WKT string and return a vector feature or an
45 * array of vector features. Supports WKT for POINT, MULTIPOINT,
46 * LINESTRING, MULTILINESTRING, POLYGON, MULTIPOLYGON, and
50 * wkt - {String} A WKT string
53 * {<OpenLayers.Feature.Vector>|Array} A feature or array of features for
54 * GEOMETRYCOLLECTION WKT.
57 var features, type, str;
58 var matches = this.regExes.typeStr.exec(wkt);
60 type = matches[1].toLowerCase();
62 if(this.parse[type]) {
63 features = this.parse[type].apply(this, [str]);
65 if (this.internalProjection && this.externalProjection) {
67 features.CLASS_NAME == "OpenLayers.Feature.Vector") {
68 features.geometry.transform(this.externalProjection,
69 this.internalProjection);
70 } else if (features &&
71 type != "geometrycollection" &&
72 typeof features == "object") {
73 for (var i=0, len=features.length; i<len; i++) {
74 var component = features[i];
75 component.geometry.transform(this.externalProjection,
76 this.internalProjection);
86 * Serialize a feature or array of features into a WKT string.
89 * features - {<OpenLayers.Feature.Vector>|Array} A feature or array of
93 * {String} The WKT string representation of the input geometries
95 write: function(features) {
96 var collection, geometry, type, data, isCollection;
97 if(features.constructor == Array) {
98 collection = features;
101 collection = [features];
102 isCollection = false;
106 pieces.push('GEOMETRYCOLLECTION(');
108 for(var i=0, len=collection.length; i<len; ++i) {
109 if(isCollection && i>0) {
112 geometry = collection[i].geometry;
113 type = geometry.CLASS_NAME.split('.')[2].toLowerCase();
114 if(!this.extract[type]) {
117 if (this.internalProjection && this.externalProjection) {
118 geometry = geometry.clone();
119 geometry.transform(this.internalProjection,
120 this.externalProjection);
122 data = this.extract[type].apply(this, [geometry]);
123 pieces.push(type.toUpperCase() + '(' + data + ')');
128 return pieces.join('');
132 * Object with properties corresponding to the geometry types.
133 * Property values are functions that do the actual data extraction.
137 * Return a space delimited string of point coordinates.
138 * @param {<OpenLayers.Geometry.Point>} point
139 * @returns {String} A string of coordinates representing the point
141 'point': function(point) {
142 return point.x + ' ' + point.y;
146 * Return a comma delimited string of point coordinates from a multipoint.
147 * @param {<OpenLayers.Geometry.MultiPoint>} multipoint
148 * @returns {String} A string of point coordinate strings representing
151 'multipoint': function(multipoint) {
153 for(var i=0, len=multipoint.components.length; i<len; ++i) {
154 array.push(this.extract.point.apply(this, [multipoint.components[i]]));
156 return array.join(',');
160 * Return a comma delimited string of point coordinates from a line.
161 * @param {<OpenLayers.Geometry.LineString>} linestring
162 * @returns {String} A string of point coordinate strings representing
165 'linestring': function(linestring) {
167 for(var i=0, len=linestring.components.length; i<len; ++i) {
168 array.push(this.extract.point.apply(this, [linestring.components[i]]));
170 return array.join(',');
174 * Return a comma delimited string of linestring strings from a multilinestring.
175 * @param {<OpenLayers.Geometry.MultiLineString>} multilinestring
176 * @returns {String} A string of of linestring strings representing
177 * the multilinestring
179 'multilinestring': function(multilinestring) {
181 for(var i=0, len=multilinestring.components.length; i<len; ++i) {
183 this.extract.linestring.apply(this, [multilinestring.components[i]]) +
186 return array.join(',');
190 * Return a comma delimited string of linear ring arrays from a polygon.
191 * @param {<OpenLayers.Geometry.Polygon>} polygon
192 * @returns {String} An array of linear ring arrays representing the polygon
194 'polygon': function(polygon) {
196 for(var i=0, len=polygon.components.length; i<len; ++i) {
198 this.extract.linestring.apply(this, [polygon.components[i]]) +
201 return array.join(',');
205 * Return an array of polygon arrays from a multipolygon.
206 * @param {<OpenLayers.Geometry.MultiPolygon>} multipolygon
207 * @returns {Array} An array of polygon arrays representing
210 'multipolygon': function(multipolygon) {
212 for(var i=0, len=multipolygon.components.length; i<len; ++i) {
214 this.extract.polygon.apply(this, [multipolygon.components[i]]) +
217 return array.join(',');
223 * Object with properties corresponding to the geometry types.
224 * Property values are functions that do the actual parsing.
228 * Return point feature given a point WKT fragment.
229 * @param {String} str A WKT fragment representing the point
230 * @returns {<OpenLayers.Feature.Vector>} A point feature
233 'point': function(str) {
234 var coords = OpenLayers.String.trim(str).split(this.regExes.spaces);
235 return new OpenLayers.Feature.Vector(
236 new OpenLayers.Geometry.Point(coords[0], coords[1])
241 * Return a multipoint feature given a multipoint WKT fragment.
242 * @param {String} A WKT fragment representing the multipoint
243 * @returns {<OpenLayers.Feature.Vector>} A multipoint feature
246 'multipoint': function(str) {
247 var points = OpenLayers.String.trim(str).split(',');
249 for(var i=0, len=points.length; i<len; ++i) {
250 components.push(this.parse.point.apply(this, [points[i]]).geometry);
252 return new OpenLayers.Feature.Vector(
253 new OpenLayers.Geometry.MultiPoint(components)
258 * Return a linestring feature given a linestring WKT fragment.
259 * @param {String} A WKT fragment representing the linestring
260 * @returns {<OpenLayers.Feature.Vector>} A linestring feature
263 'linestring': function(str) {
264 var points = OpenLayers.String.trim(str).split(',');
266 for(var i=0, len=points.length; i<len; ++i) {
267 components.push(this.parse.point.apply(this, [points[i]]).geometry);
269 return new OpenLayers.Feature.Vector(
270 new OpenLayers.Geometry.LineString(components)
275 * Return a multilinestring feature given a multilinestring WKT fragment.
276 * @param {String} A WKT fragment representing the multilinestring
277 * @returns {<OpenLayers.Feature.Vector>} A multilinestring feature
280 'multilinestring': function(str) {
282 var lines = OpenLayers.String.trim(str).split(this.regExes.parenComma);
284 for(var i=0, len=lines.length; i<len; ++i) {
285 line = lines[i].replace(this.regExes.trimParens, '$1');
286 components.push(this.parse.linestring.apply(this, [line]).geometry);
288 return new OpenLayers.Feature.Vector(
289 new OpenLayers.Geometry.MultiLineString(components)
294 * Return a polygon feature given a polygon WKT fragment.
295 * @param {String} A WKT fragment representing the polygon
296 * @returns {<OpenLayers.Feature.Vector>} A polygon feature
299 'polygon': function(str) {
300 var ring, linestring, linearring;
301 var rings = OpenLayers.String.trim(str).split(this.regExes.parenComma);
303 for(var i=0, len=rings.length; i<len; ++i) {
304 ring = rings[i].replace(this.regExes.trimParens, '$1');
305 linestring = this.parse.linestring.apply(this, [ring]).geometry;
306 linearring = new OpenLayers.Geometry.LinearRing(linestring.components);
307 components.push(linearring);
309 return new OpenLayers.Feature.Vector(
310 new OpenLayers.Geometry.Polygon(components)
315 * Return a multipolygon feature given a multipolygon WKT fragment.
316 * @param {String} A WKT fragment representing the multipolygon
317 * @returns {<OpenLayers.Feature.Vector>} A multipolygon feature
320 'multipolygon': function(str) {
322 var polygons = OpenLayers.String.trim(str).split(this.regExes.doubleParenComma);
324 for(var i=0, len=polygons.length; i<len; ++i) {
325 polygon = polygons[i].replace(this.regExes.trimParens, '$1');
326 components.push(this.parse.polygon.apply(this, [polygon]).geometry);
328 return new OpenLayers.Feature.Vector(
329 new OpenLayers.Geometry.MultiPolygon(components)
334 * Return an array of features given a geometrycollection WKT fragment.
335 * @param {String} A WKT fragment representing the geometrycollection
336 * @returns {Array} An array of OpenLayers.Feature.Vector
339 'geometrycollection': function(str) {
340 // separate components of the collection with |
341 str = str.replace(/,\s*([A-Za-z])/g, '|$1');
342 var wktArray = OpenLayers.String.trim(str).split('|');
344 for(var i=0, len=wktArray.length; i<len; ++i) {
345 components.push(OpenLayers.Format.WKT.prototype.read.apply(this,[wktArray[i]]));
352 CLASS_NAME: "OpenLayers.Format.WKT"