Merge pull request #11267 from ahocevar/vectortile-label-rotation
Fix upright labels on vector tiles
This commit is contained in:
BIN
rendering/cases/layer-vectortile-rotate-text/expected.png
Normal file
BIN
rendering/cases/layer-vectortile-rotate-text/expected.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
44
rendering/cases/layer-vectortile-rotate-text/main.js
Normal file
44
rendering/cases/layer-vectortile-rotate-text/main.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import MVT from '../../../src/ol/format/MVT.js';
|
||||||
|
import Map from '../../../src/ol/Map.js';
|
||||||
|
import VectorTileLayer from '../../../src/ol/layer/VectorTile.js';
|
||||||
|
import VectorTileSource from '../../../src/ol/source/VectorTile.js';
|
||||||
|
import View from '../../../src/ol/View.js';
|
||||||
|
import {Stroke, Style, Text} from '../../../src/ol/style.js';
|
||||||
|
import {createXYZ} from '../../../src/ol/tilegrid.js';
|
||||||
|
|
||||||
|
new Map({
|
||||||
|
layers: [
|
||||||
|
new VectorTileLayer({
|
||||||
|
style: function (feature, resolution) {
|
||||||
|
const name = feature.get('name');
|
||||||
|
if (feature.getGeometry().getType() === 'LineString' && name) {
|
||||||
|
return new Style({
|
||||||
|
stroke: new Stroke({
|
||||||
|
width: 2,
|
||||||
|
color: 'red',
|
||||||
|
}),
|
||||||
|
text: new Text({
|
||||||
|
text: name,
|
||||||
|
font: 'italic bold 18px Ubuntu',
|
||||||
|
placement: 'line',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
source: new VectorTileSource({
|
||||||
|
format: new MVT(),
|
||||||
|
tileGrid: createXYZ(),
|
||||||
|
url: '/data/tiles/mapbox-streets-v6/{z}/{x}/{y}.vector.pbf',
|
||||||
|
transition: 0,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
target: 'map',
|
||||||
|
view: new View({
|
||||||
|
center: [1825927.7316762917, 6143091.089223046],
|
||||||
|
rotation: Math.PI / 2,
|
||||||
|
zoom: 14,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
render({message: 'Vector tile layer has upright labels', tolerance: 0.01});
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
* @module ol/geom/flat/textpath
|
* @module ol/geom/flat/textpath
|
||||||
*/
|
*/
|
||||||
import {lerp} from '../../math.js';
|
import {lerp} from '../../math.js';
|
||||||
|
import {rotate} from './transform.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array<number>} flatCoordinates Path to put text on.
|
* @param {Array<number>} flatCoordinates Path to put text on.
|
||||||
@@ -15,6 +16,7 @@ import {lerp} from '../../math.js';
|
|||||||
* @param {function(string, string, Object<string, number>):number} measureAndCacheTextWidth Measure and cache text width.
|
* @param {function(string, string, Object<string, number>):number} measureAndCacheTextWidth Measure and cache text width.
|
||||||
* @param {string} font The font.
|
* @param {string} font The font.
|
||||||
* @param {Object<string, number>} cache A cache of measured widths.
|
* @param {Object<string, number>} cache A cache of measured widths.
|
||||||
|
* @param {number} rotation Rotation to apply to the flatCoordinates to determine whether text needs to be reversed.
|
||||||
* @return {Array<Array<*>>} The result array (or null if `maxAngle` was
|
* @return {Array<Array<*>>} The result array (or null if `maxAngle` was
|
||||||
* exceeded). Entries of the array are x, y, anchorX, angle, chunk.
|
* exceeded). Entries of the array are x, y, anchorX, angle, chunk.
|
||||||
*/
|
*/
|
||||||
@@ -29,12 +31,28 @@ export function drawTextOnPath(
|
|||||||
scale,
|
scale,
|
||||||
measureAndCacheTextWidth,
|
measureAndCacheTextWidth,
|
||||||
font,
|
font,
|
||||||
cache
|
cache,
|
||||||
|
rotation
|
||||||
) {
|
) {
|
||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
// Keep text upright
|
// Keep text upright
|
||||||
const reverse = flatCoordinates[offset] > flatCoordinates[end - stride];
|
let reverse;
|
||||||
|
if (rotation) {
|
||||||
|
const rotatedCoordinates = rotate(
|
||||||
|
flatCoordinates,
|
||||||
|
offset,
|
||||||
|
end,
|
||||||
|
stride,
|
||||||
|
rotation,
|
||||||
|
[flatCoordinates[offset], flatCoordinates[offset + 1]]
|
||||||
|
);
|
||||||
|
reverse =
|
||||||
|
rotatedCoordinates[0] >
|
||||||
|
rotatedCoordinates[rotatedCoordinates.length - stride];
|
||||||
|
} else {
|
||||||
|
reverse = flatCoordinates[offset] > flatCoordinates[end - stride];
|
||||||
|
}
|
||||||
|
|
||||||
const numChars = text.length;
|
const numChars = text.length;
|
||||||
|
|
||||||
|
|||||||
@@ -957,7 +957,8 @@ class Executor {
|
|||||||
Math.abs(textScale[0]),
|
Math.abs(textScale[0]),
|
||||||
measureAndCacheTextWidth,
|
measureAndCacheTextWidth,
|
||||||
font,
|
font,
|
||||||
cachedWidths
|
cachedWidths,
|
||||||
|
viewRotationFromTransform ? 0 : this.viewRotation_
|
||||||
);
|
);
|
||||||
if (parts) {
|
if (parts) {
|
||||||
let rendered = false;
|
let rendered = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user