@terrestris/vectortiles
Version:
A simple library that makes use of free available world-wide terrestris vectortiles in MapBox MVT format from OpenStreetMap data
415 lines (338 loc) • 15.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.terrestrisVectorTiles = void 0;
var _styleRoads = require("./styles/style-roads");
var _styleBuildings = require("./styles/style-buildings");
var _styleBluebackground = require("./styles/style-bluebackground");
var _styleLandusage = require("./styles/style-landusage");
var _styleWaterways = require("./styles/style-waterways");
var _styleWaterareas = require("./styles/style-waterareas");
var _styleCountries = require("./styles/style-countries");
var _Style = _interopRequireDefault(require("ol/style/Style"));
var _Stroke = _interopRequireDefault(require("ol/style/Stroke"));
var _Text = _interopRequireDefault(require("ol/style/Text"));
var _Fill = _interopRequireDefault(require("ol/style/Fill"));
var _Icon = _interopRequireDefault(require("ol/style/Icon"));
var _Attribution = _interopRequireDefault(require("ol/control/Attribution"));
var _Point = _interopRequireDefault(require("ol/geom/Point"));
var _VectorTile = _interopRequireDefault(require("ol/layer/VectorTile"));
var _VectorTile2 = _interopRequireDefault(require("ol/source/VectorTile"));
var _MVT = _interopRequireDefault(require("ol/format/MVT"));
var _color = require("ol/color");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
/**
* @param {Object} config The config object used to generate the layer
* @example
* const layer = new terrestrisVectorTiles({
* declutter: false,
* usePlaceLabels: false,
* style_roads: [{
* ...
* }]
* })
*/
var terrestrisVectorTiles = function terrestrisVectorTiles(config) {
// should labels be decluttered?
var useDeclutter = config && config.declutter === false ? false : true; // should places and countries receive labels?
var usePlacesLabels = config && config.usePlacesLabels === false ? false : true; // resources like imagery for highway label signs
var babImg = document.createElement('img');
babImg.src = config && config.babImage ? config.babImage : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAbCAYAAADo' + 'OQYqAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4gIID' + 'jocExrEmgAAAlVJREFUWMPtmM1OE1EUx393vtoy7dDWpCBgVQJNrGhiYuI7GN2ZuPAdfAV9Bt' + '/BhWufwrAh0UBSQeRToUBhOlOZGWaOiylQjR9BWbRJ/5ubyZ2593fOvZOc/1EiMg68BW4BMSD' + '8oxIRkiQdRQRNKZQCTSk0TfEfUoAOLAGPlIjMA/cvskKcCEEYE0YJQRQThDFBELPQ2Gehscf8' + '0h7buz5TYza3p8vcnS1zr3aFopPBMnUypoZlpaOhaxcNYF6JiAfYv3vD9SPafki7E+F1IjwvZ' + 'O2rx4dPLZY+H7K42mK1cQDtADIGZHQwNVAKROAkgTCGIAZL5+pMmfp0ifrNEvUbRWanHAqOhZ' + '0zcWyTwoiFY5t/OhlfiYgLFPzjE740O+wfHbPb+obnBuwcHPNx84jlrTYrGy4rmy40fTC0FM7' + 'QQVfps/rLxTqdjxOIfwqmnGVy0qFWHWV6okDtmsNUxSY3YlEpZ6mUckxUbOysAdBWichRY+3Q' + 'efHqHdtuwHazw8aOT9j0081MDUwdNJUCnmZAuBwpIAGSnmCiGBKBUo7qeJ7qeJ6p0Qwvnz+gd' + 'r3oGiLCh+UWb16/h7E8aKRgxeyvN7ks2N71FKBr6a9m6YDZnRPWt9qsb7iw4/HkYY3Z6ijG2Y' + 'd5K81qP0mpNBBdpXzdhGk/3Ld+1umJnEEPmIbQQ+gh9BB6CD2EHkIPOHRPMdK36inqzqs8L4Q' + 'oSZ2F9EnJJ5IagyhJ+bqJNZRSzM2UePrsTn86l8lz5zI3U0IpxWB6xEF14wPZ9xjrdpjqA9Bh' + 'WgQefwcq3oy642N9sQAAAABJRU5ErkJggg=='; // the OSM-attribution
var attribution = config && config.attribution ? config.attribution : new _Attribution["default"]({
html: '© terrestris GmbH & Co. KG<br>' + 'Data © OpenStreetMap <a href="http://www.openstreetmap.org/copyright/en" ' + 'target="_blank">contributors</a>'
}); // the style template used for labels
var labelStyle = new _Style["default"]({
text: new _Text["default"]({
font: '13px sans-serif',
fill: new _Fill["default"]({
color: '#000'
}),
stroke: new _Stroke["default"]({
color: '#fff',
width: 3
}),
placement: 'line',
maxAngle: 0.4,
padding: [10, 10, 10, 10]
})
}); // the style template used for linestrings
var lineStringStyleBelow = new _Style["default"]({
stroke: new _Stroke["default"]({
color: 'black',
width: 2,
lineCap: 'butt',
lineDash: []
}),
zIndex: 0
}); // the style template used for linestrings
var lineStringStyleAbove = new _Style["default"]({
stroke: new _Stroke["default"]({
color: 'white',
width: 1,
lineCap: 'round',
lineDash: []
}),
zIndex: 1
}); // the style template used for polygons
var polygonStyleFill = new _Fill["default"]({
color: 'blue'
});
var polygonStyleStroke = new _Stroke["default"]({
color: 'blue',
width: 1,
lineCap: 'round'
});
var polygonStyle = new _Style["default"]({
fill: polygonStyleFill,
stroke: polygonStyleStroke,
zIndex: 0
}); // the style template used for highway icons
var iconStyle = new _Style["default"]({
image: new _Icon["default"]({
scale: 0.9,
imgSize: [45, 27],
img: babImg,
opacity: 0.8
}),
text: new _Text["default"]({
padding: [50, 50, 50, 50],
font: '12px sans-serif',
fill: new _Fill["default"]({
color: '#fff'
}),
stroke: new _Stroke["default"]({
color: '#fff',
width: 0.8
})
}),
zIndex: 0
});
/**
* Creates a style for labels of places like countries or cities
*
* @param {ol.Feature} feature The feature to style
* @param {Number} resolution The current maps resolution
* @return {ol.style.Style[]} The style to use for the given feature
*/
var buildLabelStyle = function buildLabelStyle(feature, resolution) {
var text = feature.get('name');
var type = feature.get('type');
var population = feature.get('population');
var fontString = 'px sans-serif';
var fontSize;
if (type === 'country') {
fontSize = 17;
} else if (type === 'city') {
fontSize = 16;
} else if (type === 'town' && resolution < 600) {
fontSize = 15;
} else if (type === 'village' && resolution < 75) {
fontSize = 14;
} else {
return null;
}
fontString = fontSize + fontString;
var olText = labelStyle.getText();
olText.getFill().setColor('#000');
olText.getStroke().setColor('#fff');
olText.getStroke().setWidth(5);
olText.setPlacement('point');
olText.setText(text);
olText.setFont(fontString);
var zIndex = population ? population : fontSize + 1000;
labelStyle.setZIndex(useDeclutter ? -zIndex : zIndex);
return [labelStyle];
};
/**
* [description]
* @param {ol.Feature} feature The feature to style
* @param {Number} resolution The current maps resolution
* @param {Object[]} styleArray The array of style objects to use
* @param {String} geom The geometry type, e.g. 'polygon'
* @return {ol.style.Style[]} The style to use for the given feature
*/
var buildStyle = function buildStyle(feature, resolution, styleArray, geom) {
if (!styleArray) {
return null;
}
var props = feature.getProperties();
var type = props.type || '';
var text = props.name || props.ref || null;
var isHighWay = (type.indexOf('motorway') > -1 || type.indexOf('trunk') > -1) && props["class"] === 'highway' && props.ref.indexOf('A') === 0;
var styleToUse;
styleArray.forEach(function (el) {
if (el.minResolution <= resolution && el.maxResolution >= resolution) {
styleToUse = el.style;
}
});
if (!styleToUse || !styleToUse[type]) {
return null;
}
var style = [];
var stroke;
var strokeAbove;
var fill;
if (geom === 'line') {
stroke = lineStringStyleBelow.getStroke();
stroke.setColor(styleToUse[type].colors[0] || 'black');
stroke.setWidth(styleToUse[type].widths[0] || 2);
stroke.setLineCap(styleToUse[type].caps[0] || 'butt');
stroke.setLineDash(styleToUse[type].dasharray ? styleToUse[type].dasharray.split(' ') : []);
lineStringStyleBelow.setZIndex(feature.get('z_order') || 0);
if (styleToUse[type].opacity) {
setOpacity(stroke, styleToUse[type].opacity);
}
style.push(lineStringStyleBelow); // check if we need a "outline" for this road
if (styleToUse[type].widths.length > 1) {
strokeAbove = lineStringStyleAbove.getStroke();
strokeAbove.setColor(styleToUse[type].colors[1] || 'white');
strokeAbove.setWidth(styleToUse[type].widths[1] || 1);
strokeAbove.setLineCap(styleToUse[type].caps[1] || 'round');
strokeAbove.setLineDash(styleToUse[type].dasharray ? styleToUse[type].dasharray.split(' ') : []);
lineStringStyleAbove.setZIndex(feature.get('z_order') + 1 || 1);
if (styleToUse[type].opacity) {
setOpacity(strokeAbove, styleToUse[type].opacity);
}
style.push(lineStringStyleAbove);
}
} else if (geom === 'polygon') {
var hasFill = styleToUse[type].fillColor || styleToUse[type].fillOpacity;
var hasStroke = styleToUse[type].strokeColor || styleToUse[type].strokeWidth;
if (hasFill) {
fill = polygonStyle.getFill();
if (!fill) {
fill = polygonStyleFill;
polygonStyle.setFill(fill);
}
fill.setColor(styleToUse[type].fillColor || 'blue');
} else {
polygonStyle.setFill(undefined);
}
if (hasStroke) {
stroke = polygonStyle.getStroke();
if (!stroke) {
stroke = polygonStyleStroke;
polygonStyle.setStroke(stroke);
}
stroke.setColor(styleToUse[type].strokeColor || 'blue');
stroke.setWidth(styleToUse[type].strokeWidth || 1);
stroke.setLineCap(styleToUse[type].lineCap || 'round');
} else {
polygonStyle.setStroke(undefined);
}
polygonStyle.setZIndex(styleToUse[type].zIndex || feature.get('z_order') || 0); // set the alpha values
if (fill && styleToUse[type].fillOpacity) {
setOpacity(fill, styleToUse[type].fillOpacity);
}
if (stroke && styleToUse[type].strokeOpacity) {
setOpacity(stroke, styleToUse[type].strokeOpacity);
}
style.push(polygonStyle);
}
if (styleToUse[type].useLabels !== false) {
if (isHighWay && resolution < 300) {
// try to extract coordinates from an ol.render.feature
var coords = feature.getGeometry().getFlatCoordinates();
if (coords && coords.length > 1) {
var point = new _Point["default"]([coords[0], coords[1]]);
iconStyle.setGeometry(point);
iconStyle.getText().setText(props.ref || props.name);
style.push(iconStyle);
}
} else if (resolution < 300) {
// care about labels for streets, buildings etc.
var olText = labelStyle.getText();
fill = olText.getFill();
stroke = olText.getStroke();
fill.setColor(styleToUse[type].textFillColor || 'black');
stroke.setColor(styleToUse[type].textStrokeColor || 'white');
stroke.setWidth(styleToUse[type].textStrokeWidth || 5);
olText.setPlacement(styleToUse[type].textPlacement || 'line');
olText.setText(text);
olText.setFont(styleToUse[type].font || '13px sans-serif');
var zIndex = feature.get('z_order') || 1;
labelStyle.setZIndex(useDeclutter ? -zIndex : zIndex);
style.push(labelStyle);
}
}
return style;
};
/**
* Sets the opacity on a style
* @param {OlStyleFill or OlStyleStroke} style The style to set the opacity on
* @param {Number} opacity The opacity value to set
*/
var setOpacity = function setOpacity(style, opacity) {
var color = (0, _color.asArray)(style.getColor());
color[3] = opacity;
style.setColor(color);
};
/**
* Creates and returns the terrestris OSM VectorTile layer
* @return {ol.layer.VectorTile} The terrestris OSM VectorTile layer
*/
var getOSMLayer = function getOSMLayer() {
var osmLayer = new _VectorTile["default"]({
name: 'terrestris-vectortiles',
declutter: useDeclutter,
source: new _VectorTile2["default"]({
format: new _MVT["default"](),
url: 'https://ows.terrestris.de/osm-vectortiles/' + 'osm:osm_world_vector' + '@mapbox-vector-tiles@pbf/{z}/{x}/{-y}.pbf',
attributions: [attribution]
}),
style: function style(feature, resolution) {
var l = feature.get('layer');
var style;
switch (l) {
case 'osm_roads':
style = buildStyle(feature, resolution, config && config.style_roads ? config.style_roads : _styleRoads.style_roads, 'line');
break;
case 'osm_roads_gen0':
style = buildStyle(feature, resolution, config && config.style_roads ? config.style_roads : _styleRoads.style_roads, 'line');
break;
case 'osm_roads_gen1':
style = buildStyle(feature, resolution, config && config.style_roads ? config.style_roads : _styleRoads.style_roads, 'line');
break;
case 'osm_buildings':
style = buildStyle(feature, resolution, config && config.style_buildings ? config.style_buildings : _styleBuildings.style_buildings, 'polygon');
break;
case 'bluebackground_no_limit':
style = buildStyle(feature, resolution, config && config.style_bluebackground ? config.style_bluebackground : _styleBluebackground.style_bluebackground, 'polygon');
break;
case 'osm_places':
if (usePlacesLabels) {
style = buildLabelStyle(feature, resolution);
}
break;
case 'osm_landusages':
style = buildStyle(feature, resolution, config && config.style_landusage ? config.style_landusage : _styleLandusage.style_landusage, 'polygon');
break;
case 'osm_landusages_gen0':
style = buildStyle(feature, resolution, config && config.style_landusage ? config.style_landusage : _styleLandusage.style_landusage, 'polygon');
break;
case 'osm_waterways':
style = buildStyle(feature, resolution, config && config.style_waterways ? config.style_waterways : _styleWaterways.style_waterways, 'line');
break;
case 'osm_waterareas':
style = buildStyle(feature, resolution, config && config.style_waterareas ? config.style_waterareas : _styleWaterareas.style_waterareas, 'polygon');
break;
case 'osm_waterareas_gen0':
style = buildStyle(feature, resolution, config && config.style_waterareas ? config.style_waterareas : _styleWaterareas.style_waterareas, 'polygon');
break;
case 'world_boundaries_labels':
style = buildStyle(feature, resolution, config && config.style_countries ? config.style_countries : _styleCountries.style_countries, 'polygon');
break;
default:
break;
}
return style;
}
});
return osmLayer;
};
return getOSMLayer(config);
};
exports.terrestrisVectorTiles = terrestrisVectorTiles;
var _default = terrestrisVectorTiles;
exports["default"] = _default;