Only create custom style for text we actually render
This commit is contained in:
@@ -28,20 +28,18 @@ var style = new ol.style.Style({
|
|||||||
renderer: function(coords, context) {
|
renderer: function(coords, context) {
|
||||||
var feature = context.feature;
|
var feature = context.feature;
|
||||||
var text = feature.get('name');
|
var text = feature.get('name');
|
||||||
if (text) {
|
// Only create label when geometry has a long and straight segment
|
||||||
// Only create label when geometry has a long and straight segment
|
var path = labelSegment(coords, Math.PI / 8, measureText(text));
|
||||||
var path = labelSegment(coords, Math.PI / 8, measureText(text));
|
if (path) {
|
||||||
if (path) {
|
extent = ol.extent.createEmpty();
|
||||||
extent = ol.extent.createEmpty();
|
letters = [];
|
||||||
letters = [];
|
textPath(text, path, measureText, collectDrawData);
|
||||||
textPath(text, path, measureText, collectDrawData);
|
ol.extent.buffer(extent, 5 * pixelRatio, extent);
|
||||||
ol.extent.buffer(extent, 5 * pixelRatio, extent);
|
var bounds = {
|
||||||
var bounds = {
|
bottomLeft: ol.extent.getBottomLeft(extent),
|
||||||
bottomLeft: ol.extent.getBottomLeft(extent),
|
topRight: ol.extent.getTopRight(extent)
|
||||||
topRight: ol.extent.getTopRight(extent)
|
};
|
||||||
};
|
labelEngine.ingestLabel(bounds, feature.getId(), 1, letters, text, false);
|
||||||
labelEngine.ingestLabel(bounds, feature.getId(), 1, letters, text, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -70,7 +68,7 @@ fetch('https://overpass-api.de/api/interpreter', {
|
|||||||
var vectorLayer = new ol.layer.Vector({
|
var vectorLayer = new ol.layer.Vector({
|
||||||
source: source,
|
source: source,
|
||||||
style: function(feature) {
|
style: function(feature) {
|
||||||
if (feature.getGeometry().getType() == 'LineString') {
|
if (feature.getGeometry().getType() == 'LineString' && feature.get('text')) {
|
||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ goog.require('ol.Map');
|
|||||||
goog.require('ol.View');
|
goog.require('ol.View');
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.format.GeoJSON');
|
goog.require('ol.format.GeoJSON');
|
||||||
goog.require('ol.geom.Point');
|
|
||||||
goog.require('ol.layer.Vector');
|
goog.require('ol.layer.Vector');
|
||||||
goog.require('ol.source.Vector');
|
goog.require('ol.source.Vector');
|
||||||
goog.require('ol.style.Fill');
|
goog.require('ol.style.Fill');
|
||||||
@@ -58,26 +57,43 @@ function sortByWidth(a, b) {
|
|||||||
return ol.extent.getWidth(b.getExtent()) - ol.extent.getWidth(a.getExtent());
|
return ol.extent.getWidth(b.getExtent()) - ol.extent.getWidth(a.getExtent());
|
||||||
}
|
}
|
||||||
|
|
||||||
var resolution; // This is set by the map's precompose listener
|
var labelStyle = new ol.style.Style({
|
||||||
var styles = [
|
renderer: function(coords, state) {
|
||||||
new ol.style.Style({
|
var text = state.feature.get('name');
|
||||||
fill: new ol.style.Fill({
|
createLabel(textCache[text], text, coords);
|
||||||
color: 'rgba(255, 255, 255, 0.6)'
|
}
|
||||||
}),
|
});
|
||||||
stroke: new ol.style.Stroke({
|
var countryStyle = new ol.style.Style({
|
||||||
color: '#319FD3',
|
fill: new ol.style.Fill({
|
||||||
width: 1
|
color: 'rgba(255, 255, 255, 0.6)'
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
new ol.style.Style({
|
stroke: new ol.style.Stroke({
|
||||||
renderer: function(coords, state) {
|
color: '#319FD3',
|
||||||
var pixelRatio = state.pixelRatio;
|
width: 1
|
||||||
var text = state.feature.get('name');
|
})
|
||||||
var canvas = textCache[text];
|
});
|
||||||
if (!canvas) {
|
var styleWithLabel = [countryStyle, labelStyle];
|
||||||
|
var styleWithoutLabel = [countryStyle];
|
||||||
|
|
||||||
|
var pixelRatio; // This is set by the map's precompose listener
|
||||||
|
var vectorLayer = new ol.layer.Vector({
|
||||||
|
source: new ol.source.Vector({
|
||||||
|
url: 'data/geojson/countries.geojson',
|
||||||
|
format: new ol.format.GeoJSON()
|
||||||
|
}),
|
||||||
|
style: function(feature, resolution) {
|
||||||
|
var text = feature.get('name');
|
||||||
|
var width = textMeasureContext.measureText(text).width;
|
||||||
|
var geometry = feature.getGeometry();
|
||||||
|
if (geometry.getType() == 'MultiPolygon') {
|
||||||
|
geometry = geometry.getPolygons().sort(sortByWidth)[0];
|
||||||
|
}
|
||||||
|
var extentWidth = ol.extent.getWidth(geometry.getExtent());
|
||||||
|
if (extentWidth / resolution > width) {
|
||||||
|
// Only consider label when it fits its geometry's extent
|
||||||
|
if (!(text in textCache)) {
|
||||||
// Draw the label to its own canvas and cache it.
|
// Draw the label to its own canvas and cache it.
|
||||||
var width = textMeasureContext.measureText(text).width;
|
var canvas = textCache[text] = document.createElement('CANVAS');
|
||||||
canvas = textCache[text] = document.createElement('CANVAS');
|
|
||||||
canvas.width = width * pixelRatio;
|
canvas.width = width * pixelRatio;
|
||||||
canvas.height = height * pixelRatio;
|
canvas.height = height * pixelRatio;
|
||||||
var context = canvas.getContext('2d');
|
var context = canvas.getContext('2d');
|
||||||
@@ -86,38 +102,15 @@ var styles = [
|
|||||||
context.strokeText(text, 0, 0);
|
context.strokeText(text, 0, 0);
|
||||||
context.fillText(text, 0, 0);
|
context.fillText(text, 0, 0);
|
||||||
}
|
}
|
||||||
// The 3rd value of the coordinate is the measure of the extent width
|
labelStyle.setGeometry(geometry.getInteriorPoint());
|
||||||
var extentWidth = state.geometry.getCoordinates()[2] / resolution * pixelRatio;
|
return styleWithLabel;
|
||||||
if (extentWidth > canvas.width) {
|
} else {
|
||||||
// Only consider labels not wider than their country's bounding box
|
return styleWithoutLabel;
|
||||||
createLabel(canvas, text, coord);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Geometry function to determine label positions
|
|
||||||
geometry: function(feature) {
|
|
||||||
var geometry = feature.getGeometry();
|
|
||||||
if (geometry.getType() == 'MultiPolygon') {
|
|
||||||
var geometries = geometry.getPolygons();
|
|
||||||
geometry = geometries.sort(sortByWidth)[0];
|
|
||||||
}
|
|
||||||
var coordinates = geometry.getInteriorPoint().getCoordinates();
|
|
||||||
var extentWidth = ol.extent.getWidth(geometry.getExtent());
|
|
||||||
// We are using the extentWidth as measure value of the geometry
|
|
||||||
coordinates.push(extentWidth);
|
|
||||||
return new ol.geom.Point(coordinates, 'XYM');
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
];
|
|
||||||
|
|
||||||
var vectorLayer = new ol.layer.Vector({
|
|
||||||
source: new ol.source.Vector({
|
|
||||||
url: 'data/geojson/countries.geojson',
|
|
||||||
format: new ol.format.GeoJSON()
|
|
||||||
}),
|
|
||||||
style: styles
|
|
||||||
});
|
});
|
||||||
vectorLayer.on('precompose', function(e) {
|
vectorLayer.on('precompose', function(e) {
|
||||||
resolution = e.frameState.viewState.resolution;
|
pixelRatio = e.frameState.pixelRatio;
|
||||||
labelEngine.destroy();
|
labelEngine.destroy();
|
||||||
});
|
});
|
||||||
vectorLayer.on('postcompose', function(e) {
|
vectorLayer.on('postcompose', function(e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user