diff --git a/src/ol/format/kml.js b/src/ol/format/kml.js index 0950e94150..33f40c5a62 100644 --- a/src/ol/format/kml.js +++ b/src/ol/format/kml.js @@ -5,7 +5,6 @@ goog.provide('ol.format.KML'); -goog.require('goog.object'); goog.require('ol'); goog.require('ol.Feature'); goog.require('ol.array'); @@ -25,7 +24,6 @@ goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); goog.require('ol.math'); -goog.require('ol.obj'); goog.require('ol.proj'); goog.require('ol.style.Fill'); goog.require('ol.style.Icon'); @@ -223,6 +221,13 @@ ol.format.KML.createStyleDefaults_ = function() { src: ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_ }); + /** + * @const + * @type {string} + * @private + */ + ol.format.KML.DEFAULT_NO_IMAGE_STYLE_ = 'NO_IMAGE'; + /** * @const * @type {ol.style.Stroke} @@ -302,27 +307,45 @@ ol.format.KML.createNameStyleFunction_ = function(foundStyle, name) { var textAlign = 'start'; if (foundStyle.getImage()) { var imageSize = foundStyle.getImage().getImageSize(); - if (imageSize && imageSize.length == 2) { + if (imageSize === null) { + imageSize = ol.format.KML.DEFAULT_IMAGE_STYLE_SIZE_; + } + var imageScale = foundStyle.getImage().getScale(); + if (isNaN(imageScale)) { + imageScale = ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_; + } + if (imageSize.length == 2) { // Offset the label to be centered to the right of the icon, if there is // one. - textOffset[0] = foundStyle.getImage().getScale() * imageSize[0] / 2; - textOffset[1] = -foundStyle.getImage().getScale() * imageSize[1] / 2; + textOffset[0] = imageScale * imageSize[0] / 2; + textOffset[1] = -imageScale * imageSize[1] / 2; textAlign = 'left'; } } - if (!ol.obj.isEmpty(foundStyle.getText())) { - textStyle = /** @type {ol.style.Text} */ - (goog.object.clone(foundStyle.getText())); - textStyle.setText(name); - textStyle.setTextAlign(textAlign); - textStyle.setOffsetX(textOffset[0]); - textStyle.setOffsetY(textOffset[1]); + if (foundStyle.getText() !== null) { + // clone the text style, customizing it with name, alignments and offset. + // Note that kml does not support many text options that OpenLayers does (rotation, textBaseline). + var foundText = foundStyle.getText(); + textStyle = new ol.style.Text({ + text: name, + textAlign: textAlign, + offsetX: textOffset[0], + offsetY: textOffset[1], + font: foundText.getFont() || ol.format.KML.DEFAULT_TEXT_STYLE_.getFont(), + scale: foundText.getScale() || ol.format.KML.DEFAULT_TEXT_STYLE_.getScale(), + fill: foundText.getFill() || ol.format.KML.DEFAULT_TEXT_STYLE_.getFill(), + stroke: foundText.getStroke() || ol.format.KML.DEFAULT_TEXT_STROKE_STYLE_ + }); } else { textStyle = new ol.style.Text({ text: name, offsetX: textOffset[0], offsetY: textOffset[1], - textAlign: textAlign + textAlign: textAlign, + font: ol.format.KML.DEFAULT_TEXT_STYLE_.getFont(), + scale: ol.format.KML.DEFAULT_TEXT_STYLE_.getScale(), + fill: ol.format.KML.DEFAULT_TEXT_STYLE_.getFill(), + stroke: ol.format.KML.DEFAULT_TEXT_STROKE_STYLE_ }); } var nameStyle = new ol.style.Style({ @@ -514,12 +537,7 @@ ol.format.KML.readVec2_ = function(node) { * @return {number|undefined} Scale. */ ol.format.KML.readScale_ = function(node) { - var number = ol.format.XSD.readDecimal(node); - if (number !== undefined) { - return Math.sqrt(number); - } else { - return undefined; - } + return ol.format.XSD.readDecimal(node); }; @@ -558,12 +576,13 @@ ol.format.KML.IconStyleParser_ = function(node, objectStack) { } var styleObject = /** @type {Object} */ (objectStack[objectStack.length - 1]); var IconObject = 'Icon' in object ? object['Icon'] : {}; + var drawIcon = (!('Icon' in object) || Object.keys(IconObject).length > 0); var src; var href = /** @type {string|undefined} */ (IconObject['href']); if (href) { src = href; - } else { + } else if (drawIcon) { src = ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_; } var anchor, anchorXUnits, anchorYUnits; @@ -610,27 +629,38 @@ ol.format.KML.IconStyleParser_ = function(node, objectStack) { var scale = /** @type {number|undefined} */ (object['scale']); - if (src == ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_) { - size = ol.format.KML.DEFAULT_IMAGE_STYLE_SIZE_; - if (scale === undefined) { - scale = ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_; - } + if (isNaN(scale) || scale === undefined) { + scale = ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_; + } else { + scale = scale * ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_; } - var imageStyle = new ol.style.Icon({ - anchor: anchor, - anchorOrigin: ol.style.IconOrigin.BOTTOM_LEFT, - anchorXUnits: anchorXUnits, - anchorYUnits: anchorYUnits, - crossOrigin: 'anonymous', // FIXME should this be configurable? - offset: offset, - offsetOrigin: ol.style.IconOrigin.BOTTOM_LEFT, - rotation: rotation, - scale: scale, - size: size, - src: src - }); - styleObject['imageStyle'] = imageStyle; + if (drawIcon) { + if (src == ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_) { + size = ol.format.KML.DEFAULT_IMAGE_STYLE_SIZE_; + if (scale === undefined) { + scale = ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_; + } + } + + var imageStyle = new ol.style.Icon({ + anchor: anchor, + anchorOrigin: ol.style.IconOrigin.BOTTOM_LEFT, + anchorXUnits: anchorXUnits, + anchorYUnits: anchorYUnits, + crossOrigin: 'anonymous', // FIXME should this be configurable? + offset: offset, + offsetOrigin: ol.style.IconOrigin.BOTTOM_LEFT, + rotation: rotation, + scale: scale, + size: size, + src: src + }); + styleObject['imageStyle'] = imageStyle; + } else { + // handle the case when we explicitly want to draw no icon. + styleObject['imageStyle'] = ol.format.KML.DEFAULT_NO_IMAGE_STYLE_; + } }; @@ -1079,6 +1109,9 @@ ol.format.KML.readStyle_ = function(node, objectStack) { var imageStyle = /** @type {ol.style.Image} */ ('imageStyle' in styleObject ? styleObject['imageStyle'] : ol.format.KML.DEFAULT_IMAGE_STYLE_); + if (imageStyle == ol.format.KML.DEFAULT_NO_IMAGE_STYLE_) { + imageStyle = undefined; + } var textStyle = /** @type {ol.style.Text} */ ('textStyle' in styleObject ? styleObject['textStyle'] : ol.format.KML.DEFAULT_TEXT_STYLE_); diff --git a/test/spec/ol/format/kml.test.js b/test/spec/ol/format/kml.test.js index b770a25522..b60a0664a7 100644 --- a/test/spec/ol/format/kml.test.js +++ b/test/spec/ol/format/kml.test.js @@ -1394,7 +1394,7 @@ describe('ol.format.KML', function() { expect(imageStyle.getOrigin()).to.be(null); expect(imageStyle.getRotation()).to.eql(0); expect(imageStyle.getSize()).to.be(null); - expect(imageStyle.getScale()).to.be(1); + expect(imageStyle.getScale()).to.be(ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_); expect(style.getText()).to.be(ol.format.KML.DEFAULT_TEXT_STYLE_); expect(style.getZIndex()).to.be(undefined); }); @@ -1439,7 +1439,7 @@ describe('ol.format.KML', function() { expect(imageStyle.getAnchor()).to.eql([24, 36]); expect(imageStyle.getOrigin()).to.eql([24, 108]); expect(imageStyle.getRotation()).to.eql(0); - expect(imageStyle.getScale()).to.eql(Math.sqrt(3)); + expect(imageStyle.getScale()).to.eql(ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_ * 3.0); expect(style.getText()).to.be(ol.format.KML.DEFAULT_TEXT_STYLE_); expect(style.getZIndex()).to.be(undefined); }); @@ -1472,7 +1472,7 @@ describe('ol.format.KML', function() { expect(style.getStroke()).to.be(ol.format.KML.DEFAULT_STROKE_STYLE_); var textStyle = style.getText(); expect(textStyle).to.be.an(ol.style.Text); - expect(textStyle.getScale()).to.be(0.5); + expect(textStyle.getScale()).to.be(0.25); var textFillStyle = textStyle.getFill(); expect(textFillStyle).to.be.an(ol.style.Fill); expect(textFillStyle.getColor()).to.eql([0x78, 0x56, 0x34, 0x12 / 255]);