|
/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for |
|
* full list of contributors). Published under the Clear BSD license. |
|
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the |
|
* full text of the license. */ |
|
|
|
/** |
|
* @requires OpenLayers/Format.js |
|
* @requires OpenLayers/Feature/Vector.js |
|
*/ |
|
|
|
/** |
|
* Class: OpenLayers.Format.WKT |
|
* Class for reading and writing Well-Known Text. Create a new instance |
|
* with the <OpenLayers.Format.WKT> constructor. |
|
* |
|
* Inherits from: |
|
* - <OpenLayers.Format> |
|
*/ |
|
OpenLayers.Format.WKT = OpenLayers.Class(OpenLayers.Format, { |
|
|
|
/** |
|
* Constructor: OpenLayers.Format.WKT |
|
* Create a new parser for WKT |
|
* |
|
* Parameters: |
|
* options - {Object} An optional object whose properties will be set on |
|
* this instance |
|
* |
|
* Returns: |
|
* {<OpenLayers.Format.WKT>} A new WKT parser. |
|
*/ |
|
initialize: function(options) { |
|
this.regExes = { |
|
'typeStr': /^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/, |
|
'spaces': /\s+/, |
|
'parenComma': /\)\s*,\s*\(/, |
|
'doubleParenComma': /\)\s*\)\s*,\s*\(\s*\(/, // can't use {2} here |
|
'trimParens': /^\s*\(?(.*?)\)?\s*$/ |
|
}; |
|
OpenLayers.Format.prototype.initialize.apply(this, [options]); |
|
}, |
|
|
|
/** |
|
* Method: read |
|
* Deserialize a WKT string and return a vector feature or an |
|
* array of vector features. Supports WKT for POINT, MULTIPOINT, |
|
* LINESTRING, MULTILINESTRING, POLYGON, MULTIPOLYGON, and |
|
* GEOMETRYCOLLECTION. |
|
* |
|
* Parameters: |
|
* wkt - {String} A WKT string |
|
* |
|
* Returns: |
|
* {<OpenLayers.Feature.Vector>|Array} A feature or array of features for |
|
* GEOMETRYCOLLECTION WKT. |
|
*/ |
|
read: function(wkt) { |
|
var features, type, str; |
|
var matches = this.regExes.typeStr.exec(wkt); |
|
if(matches) { |
|
type = matches[1].toLowerCase(); |
|
str = matches[2]; |
|
if(this.parse[type]) { |
|
features = this.parse[type].apply(this, [str]); |
|
} |
|
if (this.internalProjection && this.externalProjection) { |
|
if (features && |
|
features.CLASS_NAME == "OpenLayers.Feature.Vector") { |
|
features.geometry.transform(this.externalProjection, |
|
this.internalProjection); |
|
} else if (features && |
|
type != "geometrycollection" && |
|
typeof features == "object") { |
|
for (var i=0, len=features.length; i<len; i++) { |
|
var component = features[i]; |
|
component.geometry.transform(this.externalProjection, |
|
this.internalProjection); |
|
} |
|
} |
|
} |
|
} |
|
return features; |
|
}, |
|
|
|
/** |
|
* Method: write |
|
* Serialize a feature or array of features into a WKT string. |
|
* |
|
* Parameters: |
|
* features - {<OpenLayers.Feature.Vector>|Array} A feature or array of |
|
* features |
|
* |
|
* Returns: |
|
* {String} The WKT string representation of the input geometries |
|
*/ |
|
write: function(features) { |
|
var collection, geometry, type, data, isCollection; |
|
if(features.constructor == Array) { |
|
collection = features; |
|
isCollection = true; |
|
} else { |
|
collection = [features]; |
|
isCollection = false; |
|
} |
|
var pieces = []; |
|
if(isCollection) { |
|
pieces.push('GEOMETRYCOLLECTION('); |
|
} |
|
for(var i=0, len=collection.length; i<len; ++i) { |
|
if(isCollection && i>0) { |
|
pieces.push(','); |
|
} |
|
geometry = collection[i].geometry; |
|
type = geometry.CLASS_NAME.split('.')[2].toLowerCase(); |
|
if(!this.extract[type]) { |
|
return null; |
|
} |
|
if (this.internalProjection && this.externalProjection) { |
|
geometry = geometry.clone(); |
|
geometry.transform(this.internalProjection, |
|
this.externalProjection); |
|
} |
|
data = this.extract[type].apply(this, [geometry]); |
|
pieces.push(type.toUpperCase() + '(' + data + ')'); |
|
} |
|
if(isCollection) { |
|
pieces.push(')'); |
|
} |
|
return pieces.join(''); |
|
}, |
|
|
|
/** |
|
* Object with properties corresponding to the geometry types. |
|
* Property values are functions that do the actual data extraction. |
|
*/ |
|
extract: { |
|
/** |
|
* Return a space delimited string of point coordinates. |
|
* @param {<OpenLayers.Geometry.Point>} point |
|
* @returns {String} A string of coordinates representing the point |
|
*/ |
|
'point': function(point) { |
|
return point.x + ' ' + point.y; |
|
}, |
|
|
|
/** |
|
* Return a comma delimited string of point coordinates from a multipoint. |
|
* @param {<OpenLayers.Geometry.MultiPoint>} multipoint |
|
* @returns {String} A string of point coordinate strings representing |
|
* the multipoint |
|
*/ |
|
'multipoint': function(multipoint) { |
|
var array = []; |
|
for(var i=0, len=multipoint.components.length; i<len; ++i) { |
|
array.push('(' + |
|
this.extract.point.apply(this, [multipoint.components[i]]) + |
|
')'); |
|
} |
|
return array.join(','); |
|
}, |
|
|
|
/** |
|
* Return a comma delimited string of point coordinates from a line. |
|
* @param {<OpenLayers.Geometry.LineString>} linestring |
|
* @returns {String} A string of point coordinate strings representing |
|
* the linestring |
|
*/ |
|
'linestring': function(linestring) { |
|
var array = []; |
|
for(var i=0, len=linestring.components.length; i<len; ++i) { |
|
array.push(this.extract.point.apply(this, [linestring.components[i]])); |
|
} |
|
return array.join(','); |
|
}, |
|
|
|
/** |
|
* Return a comma delimited string of linestring strings from a multilinestring. |
|
* @param {<OpenLayers.Geometry.MultiLineString>} multilinestring |
|
* @returns {String} A string of of linestring strings representing |
|
* the multilinestring |
|
*/ |
|
'multilinestring': function(multilinestring) { |
|
var array = []; |
|
for(var i=0, len=multilinestring.components.length; i<len; ++i) { |
|
array.push('(' + |
|
this.extract.linestring.apply(this, [multilinestring.components[i]]) + |
|
')'); |
|
} |
|
return array.join(','); |
|
}, |
|
|
|
/** |
|
* Return a comma delimited string of linear ring arrays from a polygon. |
|
* @param {<OpenLayers.Geometry.Polygon>} polygon |
|
* @returns {String} An array of linear ring arrays representing the polygon |
|
*/ |
|
'polygon': function(polygon) { |
|
var array = []; |
|
for(var i=0, len=polygon.components.length; i<len; ++i) { |
|
array.push('(' + |
|
this.extract.linestring.apply(this, [polygon.components[i]]) + |
|
')'); |
|
} |
|
return array.join(','); |
|
}, |
|
|
|
/** |
|
* 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, len=multipolygon.components.length; i<len; ++i) { |
|
array.push('(' + |
|
this.extract.polygon.apply(this, [multipolygon.components[i]]) + |
|
')'); |
|
} |
|
return array.join(','); |
|
} |
|
|
|
}, |
|
|
|
/** |
|
* Object with properties corresponding to the geometry types. |
|
* Property values are functions that do the actual parsing. |
|
*/ |
|
parse: { |
|
/** |
|
* Return point feature given a point WKT fragment. |
|
* @param {String} str A WKT fragment representing the point |
|
* @returns {<OpenLayers.Feature.Vector>} A point feature |
|
* @private |
|
*/ |
|
'point': function(str) { |
|
var coords = OpenLayers.String.trim(str).split(this.regExes.spaces); |
|
return new OpenLayers.Feature.Vector( |
|
new OpenLayers.Geometry.Point(coords[0], coords[1]) |
|
); |
|
}, |
|
|
|
/** |
|
* Return a multipoint feature given a multipoint WKT fragment. |
|
* @param {String} A WKT fragment representing the multipoint |
|
* @returns {<OpenLayers.Feature.Vector>} A multipoint feature |
|
* @private |
|
*/ |
|
'multipoint': function(str) { |
|
var point; |
|
var points = OpenLayers.String.trim(str).split(this.regExes.parenComma); |
|
var components = []; |
|
for(var i=0, len=points.length; i<len; ++i) { |
|
point = points[i].replace(this.regExes.trimParens, '$1'); |
|
components.push(this.parse.point.apply(this, [point]).geometry); |
|
} |
|
return new OpenLayers.Feature.Vector( |
|
new OpenLayers.Geometry.MultiPoint(components) |
|
); |
|
}, |
|
|
|
/** |
|
* Return a linestring feature given a linestring WKT fragment. |
|
* @param {String} A WKT fragment representing the linestring |
|
* @returns {<OpenLayers.Feature.Vector>} A linestring feature |
|
* @private |
|
*/ |
|
'linestring': function(str) { |
|
var points = OpenLayers.String.trim(str).split(','); |
|
var components = []; |
|
for(var i=0, len=points.length; i<len; ++i) { |
|
components.push(this.parse.point.apply(this, [points[i]]).geometry); |
|
} |
|
return new OpenLayers.Feature.Vector( |
|
new OpenLayers.Geometry.LineString(components) |
|
); |
|
}, |
|
|
|
/** |
|
* Return a multilinestring feature given a multilinestring WKT fragment. |
|
* @param {String} A WKT fragment representing the multilinestring |
|
* @returns {<OpenLayers.Feature.Vector>} A multilinestring feature |
|
* @private |
|
*/ |
|
'multilinestring': function(str) { |
|
var line; |
|
var lines = OpenLayers.String.trim(str).split(this.regExes.parenComma); |
|
var components = []; |
|
for(var i=0, len=lines.length; i<len; ++i) { |
|
line = lines[i].replace(this.regExes.trimParens, '$1'); |
|
components.push(this.parse.linestring.apply(this, [line]).geometry); |
|
} |
|
return new OpenLayers.Feature.Vector( |
|
new OpenLayers.Geometry.MultiLineString(components) |
|
); |
|
}, |
|
|
|
/** |
|
* Return a polygon feature given a polygon WKT fragment. |
|
* @param {String} A WKT fragment representing the polygon |
|
* @returns {<OpenLayers.Feature.Vector>} A polygon feature |
|
* @private |
|
*/ |
|
'polygon': function(str) { |
|
var ring, linestring, linearring; |
|
var rings = OpenLayers.String.trim(str).split(this.regExes.parenComma); |
|
var components = []; |
|
for(var i=0, len=rings.length; i<len; ++i) { |
|
ring = rings[i].replace(this.regExes.trimParens, '$1'); |
|
linestring = this.parse.linestring.apply(this, [ring]).geometry; |
|
linearring = new OpenLayers.Geometry.LinearRing(linestring.components); |
|
components.push(linearring); |
|
} |
|
return new OpenLayers.Feature.Vector( |
|
new OpenLayers.Geometry.Polygon(components) |
|
); |
|
}, |
|
|
|
/** |
|
* Return a multipolygon feature given a multipolygon WKT fragment. |
|
* @param {String} A WKT fragment representing the multipolygon |
|
* @returns {<OpenLayers.Feature.Vector>} A multipolygon feature |
|
* @private |
|
*/ |
|
'multipolygon': function(str) { |
|
var polygon; |
|
var polygons = OpenLayers.String.trim(str).split(this.regExes.doubleParenComma); |
|
var components = []; |
|
for(var i=0, len=polygons.length; i<len; ++i) { |
|
polygon = polygons[i].replace(this.regExes.trimParens, '$1'); |
|
components.push(this.parse.polygon.apply(this, [polygon]).geometry); |
|
} |
|
return new OpenLayers.Feature.Vector( |
|
new OpenLayers.Geometry.MultiPolygon(components) |
|
); |
|
}, |
|
|
|
/** |
|
* Return an array of features given a geometrycollection WKT fragment. |
|
* @param {String} A WKT fragment representing the geometrycollection |
|
* @returns {Array} An array of OpenLayers.Feature.Vector |
|
* @private |
|
*/ |
|
'geometrycollection': function(str) { |
|
// separate components of the collection with | |
|
str = str.replace(/,\s*([A-Za-z])/g, '|$1'); |
|
var wktArray = OpenLayers.String.trim(str).split('|'); |
|
var components = []; |
|
for(var i=0, len=wktArray.length; i<len; ++i) { |
|
components.push(OpenLayers.Format.WKT.prototype.read.apply(this,[wktArray[i]])); |
|
} |
|
return components; |
|
} |
|
|
|
}, |
|
|
|
CLASS_NAME: "OpenLayers.Format.WKT" |
|
}); |
|
|