Skip to content

Commit

Permalink
Fix: Rescale vector tiles depending on dpi in print (#1911)
Browse files Browse the repository at this point in the history
* Rescale vector tiles depending on dpi in print

Added rescaling functionality in the olms extension.
The extension creates one style for each configured
print resolution, which is then applied when
said print resolution is chosen.

* Remove extensions.js from PR

Remove extensions.js which was mistakenly added from the PR.

* Created general method for scaling mapbox vector tiles

Created a general method for scaling mapbox vector tiles
to avoid duplicated almost identical code.

The method is only used if the layer is of format 'mvt'
to avoid applying it to regular vector tile layers.

* Use style-type to determine if layer should use olms rescaling

Style-type is now used instead of layer format to determine
how to rescale the style of a mapbox vector tile.

* Rescaling of circles in mapbox style added

Circles in the mapbox vector tile style is now rescaled
in the same way as other style elements.

* Removed  unnecessary null argument

Removed null as argument from ScaleMapboxLayer
  • Loading branch information
sweco-seguro authored Dec 12, 2023
1 parent 9707c1d commit e026d3b
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 8 deletions.
36 changes: 36 additions & 0 deletions src/controls/print/print-resize.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ImageLayer from 'ol/layer/Image';
import TileLayer from 'ol/layer/Tile';
import VectorLayer from 'ol/layer/Vector';
import VectorImageLayer from 'ol/layer/VectorImage';
import VectorTileLayer from 'ol/layer/VectorTile';
import { OSM, WMTS, XYZ, ImageWMS, ImageArcGISRest, Cluster } from 'ol/source';
import TileArcGISRest from 'ol/source/TileArcGISRest';
import agsMap from '../../layer/agsmap';
Expand Down Expand Up @@ -106,6 +107,10 @@ export default function PrintResize(options = {}) {
return layer instanceof VectorLayer || layer instanceof VectorImageLayer;
};

const isVectorTile = function isVectorTile(layer) {
return layer instanceof VectorTileLayer;
};

const isImage = function isImage(layer) {
return layer instanceof TileLayer || layer instanceof ImageLayer;
};
Expand Down Expand Up @@ -381,6 +386,21 @@ export default function PrintResize(options = {}) {
}
};

const scaleMapboxLayer = function scaleMapboxLayer(layer, styleName, styles, scaleToDpi) {
const newStyle = Style.createStyle({
style: styleName,
viewer,
type: 'mapbox',
scaleToDpi,
file: styles[0][0].custom.file,
layer,
source: styles[0][0].custom.source
});
if (newStyle) {
layer.setStyle(newStyle);
}
};

// Alters layer in map, if vector then set scale for feature, if image set DPI parameter for source
const setLayerScale = function setLayerScale(layer) {
const source = layer.getSource();
Expand Down Expand Up @@ -422,6 +442,14 @@ export default function PrintResize(options = {}) {
}
}

if (isVectorTile(layer)) {
const styleName = layer.get('styleName');
const styles = viewer.getStyle(styleName);
if (styles && styles[0][0].custom.type === 'mapbox') {
scaleMapboxLayer(layer, styleName, styles, resolution);
}
}

if (isImage(layer) && isValidSource(source)) {
const params = source.getParams();
if (getSourceType(layer) === 'Geoserver') {
Expand Down Expand Up @@ -468,6 +496,14 @@ export default function PrintResize(options = {}) {
}
}

if (isVectorTile(layer)) {
const styleName = layer.get('styleName');
const styles = viewer.getStyle(styleName);
if (styles && styles[0][0].custom.type === 'mapbox') {
scaleMapboxLayer(layer, styleName, styles);
}
}

if (isImage(layer) && isValidSource(source)) {
const params = source.getParams();

Expand Down
69 changes: 63 additions & 6 deletions src/extensions/olms.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,74 @@
import { applyStyle } from 'ol-mapbox-style';
import Style from '../style';

const Olms = function Olms() {
let baseStyle = null;
const dpiStyles = {};

const Olms = function Olms(options = {}) {
const {
resolutions = [
{ label: 'Låg', value: 75 },
{ label: 'Mellan', value: 150 },
{ label: 'Hög', value: 300 }
]
} = options;

function scaleStyleToDpi(style, dpi) {
const layers = style.layers;
const scaledLayers = layers.map((layer) => {
const paint = layer.paint;
const layout = layer.layout;
if (paint) {
const lineWidth = paint['line-width'];
if (lineWidth) {
paint['line-width'] = Style.multiplyByFactor(lineWidth, dpi);
}
const circleRadius = paint['circle-radius'];
if (circleRadius) {
paint['circle-radius'] = Style.multiplyByFactor(circleRadius, dpi);
}
const circleStrokeWidth = paint['circle-stroke-width'];
if (circleStrokeWidth) {
paint['circle-stroke-width'] = Style.multiplyByFactor(circleStrokeWidth, dpi);
}
}
if (layout) {
const textSize = layout['text-size'];
if (textSize) {
layout['text-size'] = Style.multiplyByFactor(textSize, dpi);
}
const iconSize = layout['icon-size'];
if (iconSize) {
layout['icon-size'] = Style.multiplyByFactor(iconSize, dpi);
}
}
return { ...layer, paint, layout };
});
const scaledStyle = { ...style, layers: scaledLayers };
return scaledStyle;
}

const olmsStyle = function olmsStyle({
layer,
file,
source
source,
scaleToDpi = 150
}) {
fetch(file).then((response) => {
response.json().then((glStyle) => {
applyStyle(layer, glStyle, source);
if (baseStyle == null) {
fetch(file).then((response) => {
response.json().then((glStyle) => {
baseStyle = glStyle;
applyStyle(layer, baseStyle, source);
resolutions.forEach((resolution) => {
let scaledStyle = JSON.parse(JSON.stringify(glStyle));
scaledStyle = scaleStyleToDpi(scaledStyle, resolution.value);
dpiStyles[resolution.value] = scaledStyle;
});
});
});
});
} else {
applyStyle(layer, dpiStyles[scaleToDpi], source);
}
return false;
};
Style.addStyleType('mapbox', olmsStyle);
Expand Down
5 changes: 3 additions & 2 deletions src/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ function createStyle({
style = getCustomStyle('stylefunction', { name: styleSettings[0][0].custom, params: styleSettings[0][0].params });
} else if (typeof styleSettings[0][0].custom === 'object') {
style = getCustomStyle(type, {
layer, file, source, name
layer, file, source, name, scaleToDpi
});
}
return style || stylefunctions('default');
Expand Down Expand Up @@ -434,5 +434,6 @@ export default {
styleFunction,
createEditStyle,
createGeometryStyle,
addStyleType
addStyleType,
multiplyByFactor
};

0 comments on commit e026d3b

Please sign in to comment.