Merge pull request #517 from bartvde/kmlfresh3

Add a parser for reading and writing KML (r=@tschaub,@fredj,@twpayne)
This commit is contained in:
Bart van den Eijnden
2013-04-11 23:50:44 -07:00
23 changed files with 3162 additions and 23 deletions

View File

@@ -326,37 +326,48 @@ ol.layer.Vector.prototype.parseFeatures = function(data, parser, projection) {
var callback = function(feature, type) {
return lookup[type];
};
var addFeatures = function(features) {
var sourceProjection = this.getSource().getProjection();
var transform = ol.projection.getTransform(sourceProjection, projection);
transform(
this.pointVertices_.coordinates,
this.pointVertices_.coordinates,
this.pointVertices_.getDimension());
transform(
this.lineVertices_.coordinates,
this.lineVertices_.coordinates,
this.lineVertices_.getDimension());
transform(
this.polygonVertices_.coordinates,
this.polygonVertices_.coordinates,
this.polygonVertices_.getDimension());
this.addFeatures(features);
};
if (goog.isString(data)) {
goog.asserts.assert(goog.isFunction(parser.readFeaturesFromString),
'Expected a parser with readFeaturesFromString method.');
features = parser.readFeaturesFromString(data, {callback: callback});
addFeatures.call(this, features);
} else if (goog.isObject(data)) {
goog.asserts.assert(goog.isFunction(parser.readFeaturesFromObject),
'Expected a parser with a readFeaturesFromObject method.');
features = parser.readFeaturesFromObject(data, {callback: callback});
if (goog.isFunction(parser.readFeaturesFromObjectAsync)) {
parser.readFeaturesFromObjectAsync(data, goog.bind(addFeatures, this),
{callback: callback});
} else {
goog.asserts.assert(goog.isFunction(parser.readFeaturesFromObject),
'Expected a parser with a readFeaturesFromObject method.');
features = parser.readFeaturesFromObject(data, {callback: callback});
addFeatures.call(this, features);
}
} else {
// TODO: parse more data types
throw new Error('Data type not supported: ' + data);
}
var sourceProjection = this.getSource().getProjection();
var transform = ol.projection.getTransform(sourceProjection, projection);
transform(
this.pointVertices_.coordinates,
this.pointVertices_.coordinates,
this.pointVertices_.getDimension());
transform(
this.lineVertices_.coordinates,
this.lineVertices_.coordinates,
this.lineVertices_.getDimension());
transform(
this.polygonVertices_.coordinates,
this.polygonVertices_.coordinates,
this.polygonVertices_.getDimension());
this.addFeatures(features);
};

View File

@@ -1,3 +1,4 @@
goog.provide('ol.parser.AsyncObjectFeatureParser');
goog.provide('ol.parser.DomFeatureParser');
goog.provide('ol.parser.ObjectFeatureParser');
goog.provide('ol.parser.ReadFeaturesOptions');
@@ -54,6 +55,23 @@ ol.parser.StringFeatureParser.prototype.readFeaturesFromString =
goog.abstractMethod;
/**
* @interface
*/
ol.parser.AsyncObjectFeatureParser = function() {};
/**
* @param {Object} obj Object representing features.
* @param {function(Array.<ol.Feature>)} callback Callback which is called
* after parsing.
* @param {ol.parser.ReadFeaturesOptions=} opt_options Feature reading options.
*/
ol.parser.AsyncObjectFeatureParser.prototype.readFeaturesFromObjectAsync =
goog.abstractMethod;
/**
* @typedef {function(ol.Feature, ol.geom.GeometryType):ol.geom.SharedVertices}
*/

View File

@@ -0,0 +1,3 @@
@exportSymbol ol.parser.KML
@exportProperty ol.parser.KML.prototype.read
@exportProperty ol.parser.KML.prototype.write

1042
src/ol/parser/kml.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,9 @@ goog.require('ol.parser.Parser');
* @extends {ol.parser.Parser}
*/
ol.parser.XML = function() {
if (goog.global.ActiveXObject) {
this.xmldom = new ActiveXObject('Microsoft.XMLDOM');
}
this.regExes = {
trimSpace: (/^\s*|\s*$/g),
removeSpace: (/\s*/g),
@@ -149,3 +152,97 @@ ol.parser.XML.prototype.getAttributeNS = function(node, uri, name) {
}
return attributeValue;
};
/**
* Create a new element with namespace. This node can be appended to
* another node with the standard node.appendChild method. For
* cross-browser support, this method must be used instead of
* document.createElementNS.
*
* @param {string} name The qualified name of the element (prefix:localname).
* @param {string=} opt_uri Namespace URI for the element.
* @return {Element} A DOM element with namespace.
*/
ol.parser.XML.prototype.createElementNS = function(name, opt_uri) {
var uri = opt_uri ? opt_uri : this.defaultNamespaceURI;
var element;
if (this.xmldom) {
element = this.xmldom.createNode(1, name, uri);
} else {
element = document.createElementNS(uri, name);
}
return element;
};
/**
* Shorthand for applying one of the named writers and appending the
* results to a node.
*
* @param {string} name The name of a node to generate. Only use a local name.
* @param {Object} obj Structure containing data for the writer.
* @param {string=} opt_uri The name space uri to which the node belongs.
* @param {Element=} opt_parent Result will be appended to this node. If no
* parent is supplied, the node will not be appended to anything.
* @return {?Element} The child node.
*/
ol.parser.XML.prototype.writeNode = function(name, obj, opt_uri, opt_parent) {
var child = null;
if (goog.isDef(this.writers)) {
var uri = opt_uri ? opt_uri : this.defaultNamespaceURI;
child = this.writers[uri][name].apply(this, [obj]);
if (opt_parent && child) {
opt_parent.appendChild(child);
}
}
return child;
};
/**
* Create a text node. This node can be appended to another node with
* the standard node.appendChild method. For cross-browser support,
* this method must be used instead of document.createTextNode.
*
* @param {string} text The text of the node.
* @return {Element} A DOM text node.
*/
ol.parser.XML.prototype.createTextNode = function(text) {
var node;
if (this.xmldom) {
node = this.xmldom.createTextNode(text);
} else {
node = document.createTextNode(text);
}
return node;
};
/**
* Adds a new attribute or changes the value of an attribute with the given
* namespace and name.
*
* @param {Element} node Element node on which to set the attribute.
* @param {string} uri Namespace URI for the attribute.
* @param {string} name Qualified name (prefix:localname) for the attribute.
* @param {string} value Attribute value.
*/
ol.parser.XML.prototype.setAttributeNS = function(node, uri, name, value) {
if (node.setAttributeNS) {
node.setAttributeNS(uri, name, value);
} else {
if (this.xmldom) {
if (uri) {
var attribute = node.ownerDocument.createNode(
2, name, uri);
attribute.nodeValue = value;
node.setAttributeNode(attribute);
} else {
node.setAttribute(name, value);
}
} else {
throw new Error('setAttributeNS not implemented');
}
}
};

View File

@@ -119,7 +119,7 @@ ol.style.Icon = function(options) {
* @return {ol.style.IconLiteral} Literal shape symbolizer.
*/
ol.style.Icon.prototype.createLiteral = function(feature) {
var attrs = feature.getAttributes();
var attrs = feature && feature.getAttributes();
var url = /** @type {string} */ (this.url_.evaluate(feature, attrs));
goog.asserts.assert(goog.isString(url) && url != '#', 'url must be a string');