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:
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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'];
|
||||
|
||||
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user