This commit is contained in:
1029
node_modules/ol-mapbox-style/src/apply.js
generated
vendored
Normal file
1029
node_modules/ol-mapbox-style/src/apply.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
16
node_modules/ol-mapbox-style/src/index.js
generated
vendored
Normal file
16
node_modules/ol-mapbox-style/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
export {
|
||||
stylefunction,
|
||||
recordStyleLayer,
|
||||
renderTransparent,
|
||||
} from './stylefunction.js';
|
||||
export {
|
||||
apply as default,
|
||||
apply,
|
||||
applyBackground,
|
||||
applyStyle,
|
||||
getFeatureState,
|
||||
setFeatureState,
|
||||
getLayer,
|
||||
getLayers,
|
||||
getSource,
|
||||
} from './apply.js';
|
||||
80
node_modules/ol-mapbox-style/src/mapbox.js
generated
vendored
Normal file
80
node_modules/ol-mapbox-style/src/mapbox.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
const mapboxBaseUrl = 'https://api.mapbox.com';
|
||||
|
||||
/**
|
||||
* Gets the path from a mapbox:// URL.
|
||||
* @param {string} url The Mapbox URL.
|
||||
* @return {string} The path.
|
||||
* @private
|
||||
*/
|
||||
export function getMapboxPath(url) {
|
||||
const startsWith = 'mapbox://';
|
||||
if (url.indexOf(startsWith) !== 0) {
|
||||
return '';
|
||||
}
|
||||
return url.slice(startsWith.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns mapbox:// sprite URLs into resolvable URLs.
|
||||
* @param {string} url The sprite URL.
|
||||
* @param {string} token The access token.
|
||||
* @param {string} styleUrl The style URL.
|
||||
* @return {string} A resolvable URL.
|
||||
* @private
|
||||
*/
|
||||
export function normalizeSpriteUrl(url, token, styleUrl) {
|
||||
const mapboxPath = getMapboxPath(url);
|
||||
if (!mapboxPath) {
|
||||
return decodeURI(new URL(url, styleUrl).href);
|
||||
}
|
||||
const startsWith = 'sprites/';
|
||||
if (mapboxPath.indexOf(startsWith) !== 0) {
|
||||
throw new Error(`unexpected sprites url: ${url}`);
|
||||
}
|
||||
const sprite = mapboxPath.slice(startsWith.length);
|
||||
|
||||
return `${mapboxBaseUrl}/styles/v1/${sprite}/sprite?access_token=${token}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns mapbox:// style URLs into resolvable URLs.
|
||||
* @param {string} url The style URL.
|
||||
* @param {string} token The access token.
|
||||
* @return {string} A resolvable URL.
|
||||
* @private
|
||||
*/
|
||||
export function normalizeStyleUrl(url, token) {
|
||||
const mapboxPath = getMapboxPath(url);
|
||||
if (!mapboxPath) {
|
||||
return decodeURI(new URL(url, location.href).href);
|
||||
}
|
||||
const startsWith = 'styles/';
|
||||
if (mapboxPath.indexOf(startsWith) !== 0) {
|
||||
throw new Error(`unexpected style url: ${url}`);
|
||||
}
|
||||
const style = mapboxPath.slice(startsWith.length);
|
||||
|
||||
return `${mapboxBaseUrl}/styles/v1/${style}?&access_token=${token}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns mapbox:// source URLs into vector tile URL templates.
|
||||
* @param {string} url The source URL.
|
||||
* @param {string} token The access token.
|
||||
* @param {string} tokenParam The access token key.
|
||||
* @param {string} styleUrl The style URL.
|
||||
* @return {string} A vector tile template.
|
||||
* @private
|
||||
*/
|
||||
export function normalizeSourceUrl(url, token, tokenParam, styleUrl) {
|
||||
const urlObject = new URL(url, styleUrl);
|
||||
const mapboxPath = getMapboxPath(url);
|
||||
if (!mapboxPath) {
|
||||
if (!token) {
|
||||
return decodeURI(urlObject.href);
|
||||
}
|
||||
urlObject.searchParams.set(tokenParam, token);
|
||||
return decodeURI(urlObject.href);
|
||||
}
|
||||
return `https://{a-d}.tiles.mapbox.com/v4/${mapboxPath}/{z}/{x}/{y}.vector.pbf?access_token=${token}`;
|
||||
}
|
||||
1406
node_modules/ol-mapbox-style/src/stylefunction.js
generated
vendored
Normal file
1406
node_modules/ol-mapbox-style/src/stylefunction.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
201
node_modules/ol-mapbox-style/src/text.js
generated
vendored
Normal file
201
node_modules/ol-mapbox-style/src/text.js
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
import mb2css from 'mapbox-to-css-font';
|
||||
import {checkedFonts, registerFont} from 'ol/render/canvas.js';
|
||||
import {createCanvas} from './util.js';
|
||||
|
||||
const hairSpacePool = Array(256).join('\u200A');
|
||||
export function applyLetterSpacing(text, letterSpacing) {
|
||||
if (letterSpacing >= 0.05) {
|
||||
let textWithLetterSpacing = '';
|
||||
const lines = text.split('\n');
|
||||
const joinSpaceString = hairSpacePool.slice(
|
||||
0,
|
||||
Math.round(letterSpacing / 0.1)
|
||||
);
|
||||
for (let l = 0, ll = lines.length; l < ll; ++l) {
|
||||
if (l > 0) {
|
||||
textWithLetterSpacing += '\n';
|
||||
}
|
||||
textWithLetterSpacing += lines[l].split('').join(joinSpaceString);
|
||||
}
|
||||
return textWithLetterSpacing;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
let measureContext;
|
||||
function getMeasureContext() {
|
||||
if (!measureContext) {
|
||||
measureContext = createCanvas(1, 1).getContext('2d');
|
||||
}
|
||||
return measureContext;
|
||||
}
|
||||
|
||||
function measureText(text, letterSpacing) {
|
||||
return (
|
||||
getMeasureContext().measureText(text).width +
|
||||
(text.length - 1) * letterSpacing
|
||||
);
|
||||
}
|
||||
|
||||
const measureCache = {};
|
||||
export function wrapText(text, font, em, letterSpacing) {
|
||||
if (text.indexOf('\n') !== -1) {
|
||||
const hardLines = text.split('\n');
|
||||
const lines = [];
|
||||
for (let i = 0, ii = hardLines.length; i < ii; ++i) {
|
||||
lines.push(wrapText(hardLines[i], font, em, letterSpacing));
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
const key = em + ',' + font + ',' + text + ',' + letterSpacing;
|
||||
let wrappedText = measureCache[key];
|
||||
if (!wrappedText) {
|
||||
const words = text.split(' ');
|
||||
if (words.length > 1) {
|
||||
const ctx = getMeasureContext();
|
||||
ctx.font = font;
|
||||
const oneEm = ctx.measureText('M').width;
|
||||
const maxWidth = oneEm * em;
|
||||
let line = '';
|
||||
const lines = [];
|
||||
// Pass 1 - wrap lines to not exceed maxWidth
|
||||
for (let i = 0, ii = words.length; i < ii; ++i) {
|
||||
const word = words[i];
|
||||
const testLine = line + (line ? ' ' : '') + word;
|
||||
if (measureText(testLine, letterSpacing) <= maxWidth) {
|
||||
line = testLine;
|
||||
} else {
|
||||
if (line) {
|
||||
lines.push(line);
|
||||
}
|
||||
line = word;
|
||||
}
|
||||
}
|
||||
if (line) {
|
||||
lines.push(line);
|
||||
}
|
||||
// Pass 2 - add lines with a width of less than 30% of maxWidth to the previous or next line
|
||||
for (let i = 0, ii = lines.length; i < ii && ii > 1; ++i) {
|
||||
const line = lines[i];
|
||||
if (measureText(line, letterSpacing) < maxWidth * 0.35) {
|
||||
const prevWidth =
|
||||
i > 0 ? measureText(lines[i - 1], letterSpacing) : Infinity;
|
||||
const nextWidth =
|
||||
i < ii - 1 ? measureText(lines[i + 1], letterSpacing) : Infinity;
|
||||
lines.splice(i, 1);
|
||||
ii -= 1;
|
||||
if (prevWidth < nextWidth) {
|
||||
lines[i - 1] += ' ' + line;
|
||||
i -= 1;
|
||||
} else {
|
||||
lines[i] = line + ' ' + lines[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Pass 3 - try to fill 80% of maxWidth for each line
|
||||
for (let i = 0, ii = lines.length - 1; i < ii; ++i) {
|
||||
const line = lines[i];
|
||||
const next = lines[i + 1];
|
||||
if (
|
||||
measureText(line, letterSpacing) > maxWidth * 0.7 &&
|
||||
measureText(next, letterSpacing) < maxWidth * 0.6
|
||||
) {
|
||||
const lineWords = line.split(' ');
|
||||
const lastWord = lineWords.pop();
|
||||
if (measureText(lastWord, letterSpacing) < maxWidth * 0.2) {
|
||||
lines[i] = lineWords.join(' ');
|
||||
lines[i + 1] = lastWord + ' ' + next;
|
||||
}
|
||||
ii -= 1;
|
||||
}
|
||||
}
|
||||
wrappedText = lines.join('\n');
|
||||
} else {
|
||||
wrappedText = text;
|
||||
}
|
||||
wrappedText = applyLetterSpacing(wrappedText, letterSpacing);
|
||||
measureCache[key] = wrappedText;
|
||||
}
|
||||
return wrappedText;
|
||||
}
|
||||
|
||||
const fontFamilyRegEx = /font-family: ?([^;]*);/;
|
||||
const stripQuotesRegEx = /("|')/g;
|
||||
let loadedFontFamilies;
|
||||
function hasFontFamily(family) {
|
||||
if (!loadedFontFamilies) {
|
||||
loadedFontFamilies = {};
|
||||
const styleSheets = document.styleSheets;
|
||||
for (let i = 0, ii = styleSheets.length; i < ii; ++i) {
|
||||
const styleSheet = /** @type {CSSStyleSheet} */ (styleSheets[i]);
|
||||
try {
|
||||
const cssRules = styleSheet.rules || styleSheet.cssRules;
|
||||
if (cssRules) {
|
||||
for (let j = 0, jj = cssRules.length; j < jj; ++j) {
|
||||
const cssRule = cssRules[j];
|
||||
if (cssRule.type == 5) {
|
||||
const match = cssRule.cssText.match(fontFamilyRegEx);
|
||||
loadedFontFamilies[match[1].replace(stripQuotesRegEx, '')] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// empty catch block
|
||||
}
|
||||
}
|
||||
}
|
||||
return family in loadedFontFamilies;
|
||||
}
|
||||
|
||||
const processedFontFamilies = {};
|
||||
|
||||
/**
|
||||
* @param {Array} fonts Fonts.
|
||||
* @return {Array} Processed fonts.
|
||||
* @private
|
||||
*/
|
||||
export function getFonts(fonts) {
|
||||
const fontsKey = fonts.toString();
|
||||
if (fontsKey in processedFontFamilies) {
|
||||
return processedFontFamilies[fontsKey];
|
||||
}
|
||||
const googleFontDescriptions = [];
|
||||
for (let i = 0, ii = fonts.length; i < ii; ++i) {
|
||||
fonts[i] = fonts[i].replace('Arial Unicode MS', 'Arial');
|
||||
const font = fonts[i];
|
||||
const cssFont = mb2css(font, 1);
|
||||
registerFont(cssFont);
|
||||
const parts = cssFont.split(' ');
|
||||
googleFontDescriptions.push([
|
||||
parts.slice(3).join(' ').replace(/"/g, ''),
|
||||
parts[1],
|
||||
parts[0],
|
||||
]);
|
||||
}
|
||||
for (let i = 0, ii = googleFontDescriptions.length; i < ii; ++i) {
|
||||
const googleFontDescription = googleFontDescriptions[i];
|
||||
const family = googleFontDescription[0];
|
||||
if (!hasFontFamily(family)) {
|
||||
if (
|
||||
checkedFonts.get(
|
||||
`${googleFontDescription[2]}\n${googleFontDescription[1]} \n${family}`
|
||||
) !== 100
|
||||
) {
|
||||
const fontUrl =
|
||||
'https://fonts.googleapis.com/css?family=' +
|
||||
family.replace(/ /g, '+') +
|
||||
':' +
|
||||
googleFontDescription[1] +
|
||||
googleFontDescription[2];
|
||||
if (!document.querySelector('link[href="' + fontUrl + '"]')) {
|
||||
const markup = document.createElement('link');
|
||||
markup.href = fontUrl;
|
||||
markup.rel = 'stylesheet';
|
||||
document.head.appendChild(markup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
processedFontFamilies[fontsKey] = fonts;
|
||||
return fonts;
|
||||
}
|
||||
180
node_modules/ol-mapbox-style/src/util.js
generated
vendored
Normal file
180
node_modules/ol-mapbox-style/src/util.js
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
import {normalizeSourceUrl, normalizeStyleUrl} from './mapbox.js';
|
||||
|
||||
export function deg2rad(degrees) {
|
||||
return (degrees * Math.PI) / 180;
|
||||
}
|
||||
|
||||
export const defaultResolutions = (function () {
|
||||
const resolutions = [];
|
||||
for (let res = 78271.51696402048; resolutions.length <= 24; res /= 2) {
|
||||
resolutions.push(res);
|
||||
}
|
||||
return resolutions;
|
||||
})();
|
||||
|
||||
/**
|
||||
* @param {number} width Width of the canvas.
|
||||
* @param {number} height Height of the canvas.
|
||||
* @return {HTMLCanvasElement} Canvas.
|
||||
*/
|
||||
export function createCanvas(width, height) {
|
||||
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope && typeof OffscreenCanvas !== 'undefined') { // eslint-disable-line
|
||||
return /** @type {?} */ (new OffscreenCanvas(width, height));
|
||||
} else {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
return canvas;
|
||||
}
|
||||
}
|
||||
|
||||
export function getZoomForResolution(resolution, resolutions) {
|
||||
let i = 0;
|
||||
const ii = resolutions.length;
|
||||
for (; i < ii; ++i) {
|
||||
const candidate = resolutions[i];
|
||||
if (candidate < resolution && i + 1 < ii) {
|
||||
const zoomFactor = resolutions[i] / resolutions[i + 1];
|
||||
return i + Math.log(resolutions[i] / resolution) / Math.log(zoomFactor);
|
||||
}
|
||||
}
|
||||
return ii - 1;
|
||||
}
|
||||
|
||||
const pendingRequests = {};
|
||||
/**
|
||||
* @param {ResourceType} resourceType Type of resource to load.
|
||||
* @param {string} url Url of the resource.
|
||||
* @param {Options} [options={}] Options.
|
||||
* @return {Promise<Object|Response>} Promise that resolves with the loaded resource
|
||||
* or rejects with the Response object.
|
||||
* @private
|
||||
*/
|
||||
export function fetchResource(resourceType, url, options = {}) {
|
||||
if (url in pendingRequests) {
|
||||
return pendingRequests[url];
|
||||
} else {
|
||||
const request = options.transformRequest
|
||||
? options.transformRequest(url, resourceType) || new Request(url)
|
||||
: new Request(url);
|
||||
if (!request.headers.get('Accept')) {
|
||||
request.headers.set('Accept', 'application/json');
|
||||
}
|
||||
const pendingRequest = fetch(request)
|
||||
.then(function (response) {
|
||||
delete pendingRequests[url];
|
||||
return response.ok
|
||||
? response.json()
|
||||
: Promise.reject(new Error('Error fetching source ' + url));
|
||||
})
|
||||
.catch(function (error) {
|
||||
delete pendingRequests[url];
|
||||
return Promise.reject(new Error('Error fetching source ' + url));
|
||||
});
|
||||
pendingRequests[url] = pendingRequest;
|
||||
return pendingRequest;
|
||||
}
|
||||
}
|
||||
|
||||
export function getGlStyle(glStyleOrUrl, options) {
|
||||
if (typeof glStyleOrUrl === 'string') {
|
||||
if (glStyleOrUrl.trim().startsWith('{')) {
|
||||
try {
|
||||
const glStyle = JSON.parse(glStyleOrUrl);
|
||||
return Promise.resolve(glStyle);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
} else {
|
||||
glStyleOrUrl = normalizeStyleUrl(glStyleOrUrl, options.accessToken);
|
||||
return fetchResource('Style', glStyleOrUrl, options);
|
||||
}
|
||||
} else {
|
||||
return Promise.resolve(glStyleOrUrl);
|
||||
}
|
||||
}
|
||||
|
||||
const tilejsonCache = {};
|
||||
/**
|
||||
* @param {Object} glSource glStyle source object.
|
||||
* @param {string} styleUrl Style URL.
|
||||
* @param {Options} options Options.
|
||||
* @return {Object} TileJson
|
||||
*/
|
||||
export function getTileJson(glSource, styleUrl, options = {}) {
|
||||
const cacheKey = [styleUrl, JSON.stringify(glSource)].toString();
|
||||
let promise = tilejsonCache[cacheKey];
|
||||
if (!promise || options.transformRequest) {
|
||||
const url = glSource.url;
|
||||
if (url && !glSource.tiles) {
|
||||
let normalizedSourceUrl = normalizeSourceUrl(
|
||||
url,
|
||||
options.accessToken,
|
||||
options.accessTokenParam || 'access_token',
|
||||
styleUrl || location.href
|
||||
);
|
||||
if (url.startsWith('mapbox://')) {
|
||||
promise = Promise.resolve(
|
||||
Object.assign({}, glSource, {
|
||||
url: undefined,
|
||||
tiles: normalizedSourceUrl,
|
||||
})
|
||||
);
|
||||
} else {
|
||||
promise = fetchResource('Source', normalizedSourceUrl, options).then(
|
||||
function (tileJson) {
|
||||
for (let i = 0, ii = tileJson.tiles.length; i < ii; ++i) {
|
||||
const tileUrl = tileJson.tiles[i];
|
||||
if (options.transformRequest) {
|
||||
const request = options.transformRequest(
|
||||
normalizedSourceUrl,
|
||||
'Source'
|
||||
);
|
||||
if (request) {
|
||||
normalizedSourceUrl = request.url;
|
||||
}
|
||||
}
|
||||
let normalizedTileUrl = normalizeSourceUrl(
|
||||
tileUrl,
|
||||
options.accessToken,
|
||||
options.accessTokenParam || 'access_token',
|
||||
normalizedSourceUrl
|
||||
);
|
||||
if (options.transformRequest) {
|
||||
const transformedRequest = options.transformRequest(
|
||||
normalizedTileUrl,
|
||||
'Tiles'
|
||||
);
|
||||
if (transformedRequest instanceof Request) {
|
||||
normalizedTileUrl = decodeURI(transformedRequest.url);
|
||||
}
|
||||
}
|
||||
tileJson.tiles[i] = normalizedTileUrl;
|
||||
}
|
||||
return Promise.resolve(tileJson);
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
glSource = Object.assign({}, glSource, {
|
||||
tiles: glSource.tiles.map(function (tileUrl) {
|
||||
return normalizeSourceUrl(
|
||||
tileUrl,
|
||||
options.accessToken,
|
||||
options.accessTokenParam || 'access_token',
|
||||
styleUrl || location.href
|
||||
);
|
||||
}),
|
||||
});
|
||||
promise = Promise.resolve(Object.assign({}, glSource));
|
||||
}
|
||||
tilejsonCache[cacheKey] = promise;
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import("./apply.js").Options} Options
|
||||
* @typedef {import('./apply.js').ResourceType} ResourceType
|
||||
* @private
|
||||
*/
|
||||
Reference in New Issue
Block a user