Merge pull request #1063 from oterral/parsing_stylemap
Parsing styleMap (r=@bartvde)
This commit is contained in:
@@ -262,14 +262,22 @@
|
|||||||
-112.2626894973474,36.10149062823369,630 </coordinates>
|
-112.2626894973474,36.10149062823369,630 </coordinates>
|
||||||
</LineString>
|
</LineString>
|
||||||
</Placemark>
|
</Placemark>
|
||||||
<Placemark>
|
<Placemark>
|
||||||
<name>Blue Icon</name>
|
<name>Blue Icon</name>
|
||||||
<description>Just another blue icon.</description>
|
<description>Just another blue icon.</description>
|
||||||
<styleUrl>data/kml/styles.kml#blueIcons</styleUrl>
|
<styleUrl>data/kml/styles.kml#blueIcons</styleUrl>
|
||||||
<Point>
|
<Point>
|
||||||
<coordinates>-112.292238941097,36.09520916122063,630</coordinates>
|
<coordinates>-112.292238941097,36.09520916122063,630</coordinates>
|
||||||
</Point>
|
</Point>
|
||||||
</Placemark>
|
</Placemark>
|
||||||
|
<Placemark>
|
||||||
|
<name>Sun Icon</name>
|
||||||
|
<description>Just another sun icon.</description>
|
||||||
|
<styleUrl>data/kml/styles.kml#sunIconMap</styleUrl>
|
||||||
|
<Point>
|
||||||
|
<coordinates>-112.292238941097,36.15520916122063,630</coordinates>
|
||||||
|
</Point>
|
||||||
|
</Placemark>
|
||||||
</Folder>
|
</Folder>
|
||||||
</Document>
|
</Document>
|
||||||
</kml>
|
</kml>
|
||||||
|
|||||||
@@ -17,5 +17,16 @@ http://kml-samples.googlecode.com/svn/trunk/kml/Style/styles.kml
|
|||||||
</IconStyle>
|
</IconStyle>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<StyleMap id="sunIconMap">
|
||||||
|
<Pair>
|
||||||
|
<key>normal</key>
|
||||||
|
<styleUrl>#blueIcons</styleUrl>
|
||||||
|
</Pair>
|
||||||
|
<Pair>
|
||||||
|
<key>highlight</key>
|
||||||
|
<styleUrl>#blueIcons</styleUrl>
|
||||||
|
</Pair>
|
||||||
|
</StyleMap>
|
||||||
|
|
||||||
</Document>
|
</Document>
|
||||||
</kml>
|
</kml>
|
||||||
|
|||||||
+124
-15
@@ -135,12 +135,8 @@ ol.parser.KML = function(opt_options) {
|
|||||||
obj.features.push(feature);
|
obj.features.push(feature);
|
||||||
}
|
}
|
||||||
} else if (goog.isDef(container.geometry)) {
|
} else if (goog.isDef(container.geometry)) {
|
||||||
var styleUrl = container.properties['styleUrl'];
|
this.parseStyleUrl(obj, container.properties['styleUrl']);
|
||||||
if (goog.isDef(styleUrl)) {
|
|
||||||
if (!goog.string.startsWith(styleUrl, '#')) {
|
|
||||||
obj.links.push({href: styleUrl});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
feature = new ol.Feature(container.properties);
|
feature = new ol.Feature(container.properties);
|
||||||
if (!goog.isNull(id)) {
|
if (!goog.isNull(id)) {
|
||||||
feature.setId(id);
|
feature.setId(id);
|
||||||
@@ -152,10 +148,26 @@ ol.parser.KML = function(opt_options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var symbolizers = undefined;
|
var symbolizers = undefined;
|
||||||
if (goog.isDef(container.styles)) {
|
if (goog.isDef(container['styles'])) {
|
||||||
symbolizers = container.styles[0].symbolizers;
|
symbolizers = container['styles'][0]['symbolizers'];
|
||||||
|
|
||||||
|
} else if (goog.isDef(container['styleMaps'])) {
|
||||||
|
var styleMap = container['styleMaps'][0];
|
||||||
|
for (var i = 0, ii = styleMap['pairs'].length; i < ii; i++) {
|
||||||
|
var pair = styleMap['pairs'][i];
|
||||||
|
if (pair.key === 'normal') {
|
||||||
|
if (goog.isDef(pair['styleUrl'])) {
|
||||||
|
this.parseStyleUrl(obj, pair['styleUrl']);
|
||||||
|
feature.set('styleUrl', pair['styleUrl']);
|
||||||
|
} else if (goog.isDef(pair['styles'])) {
|
||||||
|
symbolizers = pair['styles'][0]['symbolizers'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.applyStyle_(feature, obj['styles'], symbolizers);
|
|
||||||
|
this.applyStyle_(feature, obj['styles'], obj['styleMaps'],
|
||||||
|
symbolizers);
|
||||||
obj.features.push(feature);
|
obj.features.push(feature);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -312,6 +324,29 @@ ol.parser.KML = function(opt_options) {
|
|||||||
var name = node.nodeName.split(':').pop();
|
var name = node.nodeName.split(':').pop();
|
||||||
container.attributes[name].push(this.getChildValue(node));
|
container.attributes[name].push(this.getChildValue(node));
|
||||||
},
|
},
|
||||||
|
'StyleMap': function(node, obj) {
|
||||||
|
if (this.extractStyles === true) {
|
||||||
|
if (!obj['styleMaps']) {
|
||||||
|
obj['styleMaps'] = [];
|
||||||
|
}
|
||||||
|
var styleMap = {'pairs': []};
|
||||||
|
var id = node.getAttribute('id');
|
||||||
|
if (!goog.isNull(id)) {
|
||||||
|
styleMap['id'] = id;
|
||||||
|
}
|
||||||
|
this.readChildNodes(node, styleMap);
|
||||||
|
obj['styleMaps'].push(styleMap);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Pair': function(node, obj) {
|
||||||
|
var pair = {};
|
||||||
|
var id = node.getAttribute('id');
|
||||||
|
if (!goog.isNull(id)) {
|
||||||
|
pair['id'] = id;
|
||||||
|
}
|
||||||
|
this.readChildNodes(node, pair);
|
||||||
|
obj['pairs'].push(pair);
|
||||||
|
},
|
||||||
'Style': function(node, obj) {
|
'Style': function(node, obj) {
|
||||||
if (this.extractStyles === true) {
|
if (this.extractStyles === true) {
|
||||||
if (!obj['styles']) {
|
if (!obj['styles']) {
|
||||||
@@ -579,6 +614,11 @@ ol.parser.KML = function(opt_options) {
|
|||||||
this.writeNode('_style', options.styles[i], null, node);
|
this.writeNode('_style', options.styles[i], null, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (goog.isDef(options.styleMaps)) {
|
||||||
|
for (i = 0, ii = options.styleMaps.length; i < ii; ++i) {
|
||||||
|
this.writeNode('_styleMap', options.styleMaps[i], null, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (i = 0, ii = options.features.length; i < ii; ++i) {
|
for (i = 0, ii = options.features.length; i < ii; ++i) {
|
||||||
this.writeNode('_feature', options.features[i], null, node);
|
this.writeNode('_feature', options.features[i], null, node);
|
||||||
}
|
}
|
||||||
@@ -597,6 +637,16 @@ ol.parser.KML = function(opt_options) {
|
|||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
|
'_styleMap': function(styleMap) {
|
||||||
|
var node = this.createElementNS('StyleMap');
|
||||||
|
if (goog.isDef(styleMap.id)) {
|
||||||
|
this.setAttributeNS(node, null, 'id', styleMap.id);
|
||||||
|
}
|
||||||
|
for (var i = 0, ii = styleMap.pairs.length; i < ii; ++i) {
|
||||||
|
this.writeNode('Pair', styleMap.pairs[i], null, node);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
},
|
||||||
'_symbolizer': function(obj) {
|
'_symbolizer': function(obj) {
|
||||||
var symbolizer = obj.symbolizer;
|
var symbolizer = obj.symbolizer;
|
||||||
if (symbolizer instanceof ol.style.Icon) {
|
if (symbolizer instanceof ol.style.Icon) {
|
||||||
@@ -607,6 +657,28 @@ ol.parser.KML = function(opt_options) {
|
|||||||
return this.writeNode('PolyStyle', obj);
|
return this.writeNode('PolyStyle', obj);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'Pair': function(pair) {
|
||||||
|
var node = this.createElementNS('Pair');
|
||||||
|
if (goog.isDef(pair.id)) {
|
||||||
|
this.setAttributeNS(node, null, 'id', pair.id);
|
||||||
|
}
|
||||||
|
if (goog.isDef(pair.key)) {
|
||||||
|
this.writeNode('key', pair.key, null, node);
|
||||||
|
}
|
||||||
|
if (goog.isDef(pair.styleUrl)) {
|
||||||
|
this.writeNode('styleUrl', pair.styleUrl, null, node);
|
||||||
|
} else if (goog.isDef(pair.styles)) {
|
||||||
|
for (var i = 0, ii = pair.styles.length; i < ii; ++i) {
|
||||||
|
this.writeNode('_style', pair.styles[i], null, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
},
|
||||||
|
'key': function(key) {
|
||||||
|
var node = this.createElementNS('key');
|
||||||
|
node.appendChild(this.createTextNode(key));
|
||||||
|
return node;
|
||||||
|
},
|
||||||
'PolyStyle': function(obj) {
|
'PolyStyle': function(obj) {
|
||||||
/**
|
/**
|
||||||
* In KML, if a PolyStyle has <outline>1</outline>
|
* In KML, if a PolyStyle has <outline>1</outline>
|
||||||
@@ -706,7 +778,7 @@ ol.parser.KML = function(opt_options) {
|
|||||||
this.writeNode('name', feature, null, node);
|
this.writeNode('name', feature, null, node);
|
||||||
this.writeNode('description', feature, null, node);
|
this.writeNode('description', feature, null, node);
|
||||||
if (goog.isDef(feature.get('styleUrl'))) {
|
if (goog.isDef(feature.get('styleUrl'))) {
|
||||||
this.writeNode('styleUrl', feature, null, node);
|
this.writeNode('styleUrl', feature.get('styleUrl'), null, node);
|
||||||
} else {
|
} else {
|
||||||
// inline style
|
// inline style
|
||||||
var symbolizers = feature.getSymbolizers();
|
var symbolizers = feature.getSymbolizers();
|
||||||
@@ -733,8 +805,7 @@ ol.parser.KML = function(opt_options) {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'styleUrl': function(feature) {
|
'styleUrl': function(styleUrl) {
|
||||||
var styleUrl = feature.get('styleUrl');
|
|
||||||
var node = this.createElementNS('styleUrl');
|
var node = this.createElementNS('styleUrl');
|
||||||
node.appendChild(this.createTextNode(styleUrl));
|
node.appendChild(this.createTextNode(styleUrl));
|
||||||
return node;
|
return node;
|
||||||
@@ -874,6 +945,20 @@ ol.parser.KML.prototype.readFeaturesFromObject = function(obj) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the link contained in styleUrl, if it exists.
|
||||||
|
* @param {Object} obj The returned object from the parser.
|
||||||
|
* @param {string} styleUrl The style url to parse.
|
||||||
|
*/
|
||||||
|
ol.parser.KML.prototype.parseStyleUrl = function(obj, styleUrl) {
|
||||||
|
if (goog.isDef(styleUrl)) {
|
||||||
|
if (!goog.string.startsWith(styleUrl, '#')) {
|
||||||
|
obj.links.push({href: styleUrl});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array} deferreds List of deferred instances.
|
* @param {Array} deferreds List of deferred instances.
|
||||||
* @param {Object} obj The returned object from the parser.
|
* @param {Object} obj The returned object from the parser.
|
||||||
@@ -947,7 +1032,7 @@ ol.parser.KML.prototype.read = function(data, opt_callback) {
|
|||||||
function(datas) {
|
function(datas) {
|
||||||
for (var i = 0, ii = obj.features.length; i < ii; ++i) {
|
for (var i = 0, ii = obj.features.length; i < ii; ++i) {
|
||||||
var feature = obj.features[i];
|
var feature = obj.features[i];
|
||||||
this.applyStyle_(feature, obj['styles']);
|
this.applyStyle_(feature, obj['styles'], obj['styleMaps']);
|
||||||
}
|
}
|
||||||
opt_callback.call(null, obj);
|
opt_callback.call(null, obj);
|
||||||
}, function() {
|
}, function() {
|
||||||
@@ -964,17 +1049,40 @@ ol.parser.KML.prototype.read = function(data, opt_callback) {
|
|||||||
* @private
|
* @private
|
||||||
* @param {ol.Feature} feature The feature to apply the style to.
|
* @param {ol.Feature} feature The feature to apply the style to.
|
||||||
* @param {Array} styles The style list to search in.
|
* @param {Array} styles The style list to search in.
|
||||||
|
* @param {Array} styleMaps The styleMap list to search in.
|
||||||
* @param {Array.<ol.style.Symbolizer>=} opt_symbolizers Optional symbolizers.
|
* @param {Array.<ol.style.Symbolizer>=} opt_symbolizers Optional symbolizers.
|
||||||
*/
|
*/
|
||||||
ol.parser.KML.prototype.applyStyle_ = function(feature, styles,
|
ol.parser.KML.prototype.applyStyle_ = function(feature, styles, styleMaps,
|
||||||
opt_symbolizers) {
|
opt_symbolizers) {
|
||||||
var symbolizers = opt_symbolizers;
|
var symbolizers = opt_symbolizers;
|
||||||
var i, ii;
|
var i, ii;
|
||||||
if (feature.get('styleUrl') && feature.getSymbolizers() === null) {
|
if (feature.get('styleUrl') && feature.getSymbolizers() === null) {
|
||||||
var styleUrl = feature.get('styleUrl');
|
var styleUrl = feature.get('styleUrl');
|
||||||
styleUrl = styleUrl.substring(styleUrl.indexOf('#') + 1);
|
styleUrl = styleUrl.substring(styleUrl.indexOf('#') + 1);
|
||||||
|
|
||||||
|
// look for the styleMap and set in the feature
|
||||||
|
if (goog.isDef(styleMaps)) {
|
||||||
|
for (i = 0, ii = styleMaps.length; i < ii; ++i) {
|
||||||
|
var styleMap = styleMaps[i];
|
||||||
|
if (styleMap['id'] === styleUrl) {
|
||||||
|
for (var j = 0, jj = styleMap['pairs'].length; j < jj; j++) {
|
||||||
|
var pair = styleMap['pairs'][j];
|
||||||
|
if (pair.key === 'normal') {
|
||||||
|
if (goog.isDef(pair['styleUrl'])) {
|
||||||
|
styleUrl = pair['styleUrl'];
|
||||||
|
styleUrl = styleUrl.substring(styleUrl.indexOf('#') + 1);
|
||||||
|
} else if (goog.isDef(pair['styles'])) {
|
||||||
|
symbolizers = pair['styles'][0]['symbolizers'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// look for the style and set in the feature
|
// look for the style and set in the feature
|
||||||
if (goog.isDef(styles)) {
|
if (!goog.isDef(symbolizers) && goog.isDef(styles)) {
|
||||||
for (i = 0, ii = styles.length; i < ii; ++i) {
|
for (i = 0, ii = styles.length; i < ii; ++i) {
|
||||||
if (styles[i]['id'] === styleUrl) {
|
if (styles[i]['id'] === styleUrl) {
|
||||||
symbolizers = styles[i]['symbolizers'];
|
symbolizers = styles[i]['symbolizers'];
|
||||||
@@ -982,6 +1090,7 @@ ol.parser.KML.prototype.applyStyle_ = function(feature, styles,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (goog.isDef(symbolizers)) {
|
if (goog.isDef(symbolizers)) {
|
||||||
feature.setSymbolizers(symbolizers);
|
feature.setSymbolizers(symbolizers);
|
||||||
|
|||||||
@@ -280,6 +280,31 @@ describe('ol.parser.KML', function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handles styleMap (read / write)', function(done) {
|
||||||
|
var url = 'spec/ol/parser/kml/stylemap.kml';
|
||||||
|
afterLoadXml(url, function(xml) {
|
||||||
|
var p = new ol.parser.KML({extractStyles: true});
|
||||||
|
var obj = p.read(xml);
|
||||||
|
var output = p.write(obj);
|
||||||
|
expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
|
||||||
|
|
||||||
|
var symbolizers = obj.features[0].getSymbolizers();
|
||||||
|
expect(symbolizers).to.have.length(1);
|
||||||
|
|
||||||
|
var symbolizer = symbolizers[0];
|
||||||
|
expect(symbolizer).to.be.a(ol.style.Icon);
|
||||||
|
|
||||||
|
var literal = symbolizer.createLiteral(ol.geom.GeometryType.POINT);
|
||||||
|
expect(literal).to.be.a(ol.style.IconLiteral);
|
||||||
|
|
||||||
|
var url = 'http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png';
|
||||||
|
expect(literal.url).to.eql(url);
|
||||||
|
expect(literal.width).to.eql(32);
|
||||||
|
expect(literal.height).to.eql(32);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('parsing states.kml', function() {
|
describe('parsing states.kml', function() {
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/kml/2.2 http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd">
|
||||||
|
<Document>
|
||||||
|
<Style id="pushpin">
|
||||||
|
<IconStyle id="mystyle">
|
||||||
|
<Icon>
|
||||||
|
<href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
|
||||||
|
</Icon>
|
||||||
|
</IconStyle>
|
||||||
|
</Style>
|
||||||
|
<StyleMap id="pushpinStyleMap">
|
||||||
|
<Pair>
|
||||||
|
<key>normal</key>
|
||||||
|
<styleUrl>#pushpin</styleUrl>
|
||||||
|
</Pair>
|
||||||
|
<Pair>
|
||||||
|
<key>highlight</key>
|
||||||
|
<styleUrl>#pushpin</styleUrl>
|
||||||
|
</Pair>
|
||||||
|
</StyleMap>
|
||||||
|
<Placemark>
|
||||||
|
<name>Pin on a mountaintop</name>
|
||||||
|
<styleUrl>#pushpinStyleMap</styleUrl>
|
||||||
|
<Point>
|
||||||
|
<coordinates>170.1435558771009,-43.60505741890396,0</coordinates>
|
||||||
|
</Point>
|
||||||
|
</Placemark>
|
||||||
|
</Document>
|
||||||
|
</kml>
|
||||||
Reference in New Issue
Block a user