Merge pull request #4316 from marcjansen/clean-4306

Render name labels if the geometry is a point in KML format (@tamarmot)
This commit is contained in:
Marc Jansen
2015-10-25 19:52:22 +01:00
4 changed files with 232 additions and 10 deletions

View File

@@ -2,6 +2,17 @@
### v3.11.0
#### `ol.format.KML` changes
KML icons are scaled 50% so that the rendering better matches Google Earth rendering.
If a KML placemark has a name and is a point, an `ol.style.Text` is created with the name displayed to the right of the icon (if there is an icon).
This can be controlled with the showPointNames option which defaults to true.
To disable rendering of the point names for placemarks, use the option:
new ol.format.KML({ showPointNames: false });
#### `ol.interaction.DragBox` and `ol.interaction.DragZoom` changes
Styling is no longer done with `ol.Style`, but with pure CSS. The `style` constructor option is no longer required, and no longer available. Instead, there is a `className` option for the CSS selector. The default for `ol.interaction.DragBox` is `ol-dragbox`, and `ol.interaction.DragZoom` uses `ol-dragzoom`. If you previously had

View File

@@ -1744,7 +1744,8 @@ olx.format.IGCOptions.prototype.altitudeMode;
/**
* @typedef {{extractStyles: (boolean|undefined),
* defaultStyle: (Array.<ol.style.Style>|undefined)}}
* defaultStyle: (Array.<ol.style.Style>|undefined),
* showPointNames: (boolean|undefined)}}
* @api
*/
olx.format.KMLOptions;
@@ -1758,6 +1759,14 @@ olx.format.KMLOptions;
olx.format.KMLOptions.prototype.extractStyles;
/**
* Show names as labels for placemarks which contain points. Default is `true`.
* @type {boolean|undefined}
* @api stable
*/
olx.format.KMLOptions.prototype.showPointNames;
/**
* Default style. The default default style is the same as Google Earth.
* @type {Array.<ol.style.Style>|undefined}

View File

@@ -10,6 +10,7 @@ goog.require('goog.Uri');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.dom.NodeType');
goog.require('goog.object');
goog.require('ol');
goog.require('ol.Feature');
goog.require('ol.FeatureStyleFunction');
@@ -97,6 +98,13 @@ ol.format.KML = function(opt_options) {
*/
this.sharedStyles_ = {};
/**
* @private
* @type {boolean}
*/
this.showPointNames_ = options.showPointNames !== undefined ?
options.showPointNames : true;
};
goog.inherits(ol.format.KML, ol.format.XMLFeature);
@@ -240,16 +248,27 @@ ol.format.KML.DEFAULT_STROKE_STYLE_ = new ol.style.Stroke({
});
/**
* @const
* @type {ol.style.Stroke}
* @private
*/
ol.format.KML.DEFAULT_TEXT_STROKE_STYLE_ = new ol.style.Stroke({
color: [51, 51, 51, 1],
width: 2
});
/**
* @const
* @type {ol.style.Text}
* @private
*/
ol.format.KML.DEFAULT_TEXT_STYLE_ = new ol.style.Text({
font: 'normal 16px Helvetica',
font: 'bold 16px Helvetica',
fill: ol.format.KML.DEFAULT_FILL_STYLE_,
stroke: ol.format.KML.DEFAULT_STROKE_STYLE_,
scale: 1
stroke: ol.format.KML.DEFAULT_TEXT_STROKE_STYLE_,
scale: 0.8
});
@@ -286,17 +305,67 @@ ol.format.KML.ICON_ANCHOR_UNITS_MAP_ = {
};
/**
* @param {ol.style.Style|undefined} foundStyle Style.
* @param {string} name Name.
* @return {ol.style.Style} style Style.
* @private
*/
ol.format.KML.createNameStyleFunction_ = function(foundStyle, name) {
/** @type {?ol.style.Text} */
var textStyle = null;
var textOffset = [0, 0];
var textAlign = 'start';
if (foundStyle.getImage()) {
var imageSize = foundStyle.getImage().getImageSize();
if (imageSize && 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;
textAlign = 'left';
}
}
if (!goog.object.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]);
} else {
textStyle = new ol.style.Text({
text: name,
offsetX: textOffset[0],
offsetY: textOffset[1],
textAlign: textAlign
});
}
var nameStyle = new ol.style.Style({
fill: undefined,
image: undefined,
text: textStyle,
stroke: undefined,
zIndex: undefined
});
return nameStyle;
};
/**
* @param {Array.<ol.style.Style>|undefined} style Style.
* @param {string} styleUrl Style URL.
* @param {Array.<ol.style.Style>} defaultStyle Default style.
* @param {Object.<string, (Array.<ol.style.Style>|string)>} sharedStyles
* Shared styles.
* @param {Object.<string, (Array.<ol.style.Style>|string)>} sharedStyles Shared
* styles.
* @param {boolean|undefined} showPointNames true to show names for point
* placemarks.
* @return {ol.FeatureStyleFunction} Feature style function.
* @private
*/
ol.format.KML.createFeatureStyleFunction_ = function(
style, styleUrl, defaultStyle, sharedStyles) {
ol.format.KML.createFeatureStyleFunction_ = function(style, styleUrl,
defaultStyle, sharedStyles, showPointNames) {
return (
/**
* @param {number} resolution Resolution.
@@ -304,11 +373,45 @@ ol.format.KML.createFeatureStyleFunction_ = function(
* @this {ol.Feature}
*/
function(resolution) {
var drawName = showPointNames;
/** @type {ol.style.Style|undefined} */
var nameStyle;
/** @type {string} */
var name = '';
if (drawName) {
if (this.getGeometry()) {
drawName = (this.getGeometry().getType() ===
ol.geom.GeometryType.POINT);
}
}
if (drawName) {
name = /** @type {string} */ (this.getProperties()['name']);
drawName = drawName && name;
}
if (style) {
if (drawName) {
nameStyle = ol.format.KML.createNameStyleFunction_(style[0],
name);
return [style, nameStyle];
}
return style;
}
if (styleUrl) {
return ol.format.KML.findStyle_(styleUrl, defaultStyle, sharedStyles);
var foundStyle = ol.format.KML.findStyle_(styleUrl, defaultStyle,
sharedStyles);
if (drawName) {
nameStyle = ol.format.KML.createNameStyleFunction_(foundStyle[0],
name);
return foundStyle.concat(nameStyle);
}
return foundStyle;
}
if (drawName) {
nameStyle = ol.format.KML.createNameStyleFunction_(defaultStyle[0],
name);
return defaultStyle.concat(nameStyle);
}
return defaultStyle;
});
@@ -1702,7 +1805,8 @@ ol.format.KML.prototype.readPlacemark_ = function(node, objectStack) {
var style = object['Style'];
var styleUrl = object['styleUrl'];
var styleFunction = ol.format.KML.createFeatureStyleFunction_(
style, styleUrl, this.defaultStyle_, this.sharedStyles_);
style, styleUrl, this.defaultStyle_, this.sharedStyles_,
this.showPointNames_);
feature.setStyle(styleFunction);
}
delete object['Style'];

View File

@@ -1633,6 +1633,104 @@ describe('ol.format.KML', function() {
expect(style.getZIndex()).to.be(undefined);
});
it('can create text style for named point placemarks', function() {
var text =
'<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' +
' https://developers.google.com/kml/schema/kml22gx.xsd">' +
' <Style id="sh_ylw-pushpin">' +
' <IconStyle>' +
' <scale>0.3</scale>' +
' <Icon>' +
' <href>http://maps.google.com/mapfiles/kml/pushpin/' +
'ylw-pushpin.png</href>' +
' </Icon>' +
' <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>' +
' </IconStyle>' +
' </Style>' +
' <StyleMap id="msn_ylw-pushpin0">' +
' <Pair>' +
' <key>normal</key>' +
' <styleUrl>#sn_ylw-pushpin</styleUrl>' +
' </Pair>' +
' <Pair>' +
' <key>highlight</key>' +
' <styleUrl>#sh_ylw-pushpin</styleUrl>' +
' </Pair>' +
' </StyleMap>' +
' <Placemark>' +
' <name>Test</name>' +
' <styleUrl>#msn_ylw-pushpin0</styleUrl>' +
' <Point>' +
' <coordinates>1,2</coordinates>' +
' </Point>' +
' </Placemark>' +
'</kml>';
var fs = format.readFeatures(text);
expect(fs).to.have.length(1);
var f = fs[0];
expect(f).to.be.an(ol.Feature);
var styleFunction = f.getStyleFunction();
expect(styleFunction).not.to.be(undefined);
var styleArray = styleFunction.call(f, 0);
expect(styleArray).to.be.an(Array);
expect(styleArray).to.have.length(2);
var style = styleArray[1];
expect(style).to.be.an(ol.style.Style);
expect(style.getText().getText()).to.eql(f.getProperties()['name']);
});
it('can create text style for named point placemarks', function() {
var text =
'<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' +
' https://developers.google.com/kml/schema/kml22gx.xsd">' +
' <Style id="sh_ylw-pushpin">' +
' <IconStyle>' +
' <scale>0.3</scale>' +
' <Icon>' +
' <href>http://maps.google.com/mapfiles/kml/pushpin/' +
'ylw-pushpin.png</href>' +
' </Icon>' +
' <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>' +
' </IconStyle>' +
' </Style>' +
' <StyleMap id="msn_ylw-pushpin0">' +
' <Pair>' +
' <key>normal</key>' +
' <styleUrl>#sn_ylw-pushpin</styleUrl>' +
' </Pair>' +
' <Pair>' +
' <key>highlight</key>' +
' <styleUrl>#sh_ylw-pushpin</styleUrl>' +
' </Pair>' +
' </StyleMap>' +
' <Placemark>' +
' <name>Test</name>' +
' <styleUrl>#msn_ylw-pushpin0</styleUrl>' +
' <Point>' +
' <coordinates>1,2</coordinates>' +
' </Point>' +
' </Placemark>' +
'</kml>';
var fs = format.readFeatures(text);
expect(fs).to.have.length(1);
var f = fs[0];
expect(f).to.be.an(ol.Feature);
var styleFunction = f.getStyleFunction();
expect(styleFunction).not.to.be(undefined);
var styleArray = styleFunction.call(f, 0);
expect(styleArray).to.be.an(Array);
expect(styleArray).to.have.length(2);
var style = styleArray[1];
expect(style).to.be.an(ol.style.Style);
expect(style.getText().getText()).to.eql(f.getProperties()['name']);
});
it('can write an feature\'s icon style', function() {
var style = new ol.style.Style({
image: new ol.style.Icon({