Files
openlayers/lib/OpenLayers/Format/WKT.js
crschmidt 6d6c08fbef Formats now support reprojection using internalProjection and
externalProjection properties. These allow for the reprojection of data --
OpenLayers users with SphericalMercator get this built in for EPSG:900913, and
other users can use the external proj4js library available from MapBuilder SVN
to add support for any number of projections. This means that featres can be,
for example, transformed from a KML doc in 4326 to Spherical Mercator before
being added to a layer, making using SphericalMercator slightly more enticing. 
r=elemoine
(Closes #1039)


git-svn-id: http://svn.openlayers.org/trunk/openlayers@5516 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
2007-12-19 22:07:12 +00:00

350 lines
13 KiB
JavaScript

/* Copyright (c) 2006-2007 MetaCarta, Inc., 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 && typeof features == "object") {
for (var i = 0; i < features.length; 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; i<collection.length; ++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; i<multipoint.components.length; ++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; i<linestring.components.length; ++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; i<multilinestring.components.length; ++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; i<polygon.components.length; ++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; i<multipolygon.components.length; ++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 points = OpenLayers.String.trim(str).split(',');
var components = [];
for(var i=0; i<points.length; ++i) {
components.push(this.parse.point.apply(this, [points[i]]).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; i<points.length; ++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; i<lines.length; ++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; i<rings.length; ++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; i<polygons.length; ++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; i<wktArray.length; ++i) {
components.push(OpenLayers.Format.WKT.prototype.read.apply(this,[wktArray[i]]));
}
return components;
}
},
CLASS_NAME: "OpenLayers.Format.WKT"
});