Make code prettier
This updates ESLint and our shared eslint-config-openlayers to use Prettier. Most formatting changes were automatically applied with this:
npm run lint -- --fix
A few manual changes were required:
* In `examples/offscreen-canvas.js`, the `//eslint-disable-line` comment needed to be moved to the appropriate line to disable the error about the `'worker-loader!./offscreen-canvas.worker.js'` import.
* In `examples/webpack/exapmle-builder.js`, spaces could not be added after a couple `function`s for some reason. While editing this, I reworked `ExampleBuilder` to be a class.
* In `src/ol/format/WMSGetFeatureInfo.js`, the `// @ts-ignore` comment needed to be moved down one line so it applied to the `parsersNS` argument.
This commit is contained in:
@@ -2,15 +2,14 @@
|
||||
* @module ol/source/BingMaps
|
||||
*/
|
||||
|
||||
import {createFromTileUrlFunctions} from '../tileurlfunction.js';
|
||||
import {applyTransform, intersects} from '../extent.js';
|
||||
import {jsonp as requestJSONP} from '../net.js';
|
||||
import {get as getProjection, getTransformFromProjections} from '../proj.js';
|
||||
import SourceState from './State.js';
|
||||
import TileImage from './TileImage.js';
|
||||
import {applyTransform, intersects} from '../extent.js';
|
||||
import {createFromTileUrlFunctions} from '../tileurlfunction.js';
|
||||
import {createOrUpdate} from '../tilecoord.js';
|
||||
import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
||||
|
||||
import {get as getProjection, getTransformFromProjections} from '../proj.js';
|
||||
import {jsonp as requestJSONP} from '../net.js';
|
||||
|
||||
/**
|
||||
* @param {import('../tilecoord.js').TileCoord} tileCoord Tile coord.
|
||||
@@ -36,17 +35,16 @@ export function quadKey(tileCoord) {
|
||||
return digits.join('');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The attribution containing a link to the Microsoft® Bing™ Maps Platform APIs’
|
||||
* Terms Of Use.
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
const TOS_ATTRIBUTION = '<a class="ol-attribution-bing-tos" ' +
|
||||
'href="https://www.microsoft.com/maps/product/terms.html" target="_blank">' +
|
||||
'Terms of Use</a>';
|
||||
|
||||
const TOS_ATTRIBUTION =
|
||||
'<a class="ol-attribution-bing-tos" ' +
|
||||
'href="https://www.microsoft.com/maps/product/terms.html" target="_blank">' +
|
||||
'Terms of Use</a>';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -70,7 +68,6 @@ const TOS_ATTRIBUTION = '<a class="ol-attribution-bing-tos" ' +
|
||||
* To disable the opacity transition, pass `transition: 0`.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} BingMapsImageryMetadataResponse
|
||||
* @property {number} statusCode The response status code
|
||||
@@ -79,13 +76,11 @@ const TOS_ATTRIBUTION = '<a class="ol-attribution-bing-tos" ' +
|
||||
* @property {Array<ResourceSet>} resourceSets The array of resource sets
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} ResourceSet
|
||||
* @property {Array<Resource>} resources
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Resource
|
||||
* @property {number} imageHeight The image height
|
||||
@@ -97,14 +92,12 @@ const TOS_ATTRIBUTION = '<a class="ol-attribution-bing-tos" ' +
|
||||
* @property {Array<ImageryProvider>} [imageryProviders] The array of ImageryProviders
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} ImageryProvider
|
||||
* @property {Array<CoverageArea>} coverageAreas The coverage areas
|
||||
* @property {string} [attribution] The attribution
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} CoverageArea
|
||||
* @property {number} zoomMin The minimum zoom
|
||||
@@ -112,7 +105,6 @@ const TOS_ATTRIBUTION = '<a class="ol-attribution-bing-tos" ' +
|
||||
* @property {Array<number>} bbox The coverage bounding box
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source for Bing Maps tile data.
|
||||
@@ -123,7 +115,6 @@ class BingMaps extends TileImage {
|
||||
* @param {Options} options Bing Maps options.
|
||||
*/
|
||||
constructor(options) {
|
||||
|
||||
const hidpi = options.hidpi !== undefined ? options.hidpi : false;
|
||||
|
||||
super({
|
||||
@@ -137,7 +128,7 @@ class BingMaps extends TileImage {
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
tilePixelRatio: hidpi ? 2 : 1,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true,
|
||||
transition: options.transition
|
||||
transition: options.transition,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -146,7 +137,6 @@ class BingMaps extends TileImage {
|
||||
*/
|
||||
this.hidpi_ = hidpi;
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
@@ -171,14 +161,20 @@ class BingMaps extends TileImage {
|
||||
*/
|
||||
this.imagerySet_ = options.imagerySet;
|
||||
|
||||
const url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/' +
|
||||
this.imagerySet_ +
|
||||
'?uriScheme=https&include=ImageryProviders&key=' + this.apiKey_ +
|
||||
'&c=' + this.culture_;
|
||||
|
||||
requestJSONP(url, this.handleImageryMetadataResponse.bind(this), undefined,
|
||||
'jsonp');
|
||||
const url =
|
||||
'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/' +
|
||||
this.imagerySet_ +
|
||||
'?uriScheme=https&include=ImageryProviders&key=' +
|
||||
this.apiKey_ +
|
||||
'&c=' +
|
||||
this.culture_;
|
||||
|
||||
requestJSONP(
|
||||
url,
|
||||
this.handleImageryMetadataResponse.bind(this),
|
||||
undefined,
|
||||
'jsonp'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,11 +201,13 @@ class BingMaps extends TileImage {
|
||||
* @param {BingMapsImageryMetadataResponse} response Response.
|
||||
*/
|
||||
handleImageryMetadataResponse(response) {
|
||||
if (response.statusCode != 200 ||
|
||||
response.statusDescription != 'OK' ||
|
||||
response.authenticationResultCode != 'ValidCredentials' ||
|
||||
response.resourceSets.length != 1 ||
|
||||
response.resourceSets[0].resources.length != 1) {
|
||||
if (
|
||||
response.statusCode != 200 ||
|
||||
response.statusDescription != 'OK' ||
|
||||
response.authenticationResultCode != 'ValidCredentials' ||
|
||||
response.resourceSets.length != 1 ||
|
||||
response.resourceSets[0].resources.length != 1
|
||||
) {
|
||||
this.setState(SourceState.ERROR);
|
||||
return;
|
||||
}
|
||||
@@ -220,22 +218,23 @@ class BingMaps extends TileImage {
|
||||
const sourceProjection = this.getProjection();
|
||||
const extent = extentFromProjection(sourceProjection);
|
||||
const scale = this.hidpi_ ? 2 : 1;
|
||||
const tileSize = resource.imageWidth == resource.imageHeight ?
|
||||
resource.imageWidth / scale :
|
||||
[resource.imageWidth / scale, resource.imageHeight / scale];
|
||||
const tileSize =
|
||||
resource.imageWidth == resource.imageHeight
|
||||
? resource.imageWidth / scale
|
||||
: [resource.imageWidth / scale, resource.imageHeight / scale];
|
||||
|
||||
const tileGrid = createXYZ({
|
||||
extent: extent,
|
||||
minZoom: resource.zoomMin,
|
||||
maxZoom: maxZoom,
|
||||
tileSize: tileSize
|
||||
tileSize: tileSize,
|
||||
});
|
||||
this.tileGrid = tileGrid;
|
||||
|
||||
const culture = this.culture_;
|
||||
const hidpi = this.hidpi_;
|
||||
this.tileUrlFunction = createFromTileUrlFunctions(
|
||||
resource.imageUrlSubdomains.map(function(subdomain) {
|
||||
resource.imageUrlSubdomains.map(function (subdomain) {
|
||||
/** @type {import('../tilecoord.js').TileCoord} */
|
||||
const quadKeyTileCoord = [0, 0, 0];
|
||||
const imageUrl = resource.imageUrl
|
||||
@@ -248,11 +247,16 @@ class BingMaps extends TileImage {
|
||||
* @param {import("../proj/Projection.js").default} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
function (tileCoord, pixelRatio, projection) {
|
||||
if (!tileCoord) {
|
||||
return undefined;
|
||||
} else {
|
||||
createOrUpdate(tileCoord[0], tileCoord[1], tileCoord[2], quadKeyTileCoord);
|
||||
createOrUpdate(
|
||||
tileCoord[0],
|
||||
tileCoord[1],
|
||||
tileCoord[2],
|
||||
quadKeyTileCoord
|
||||
);
|
||||
let url = imageUrl;
|
||||
if (hidpi) {
|
||||
url += '&dpi=d1&device=mobile';
|
||||
@@ -261,42 +265,56 @@ class BingMaps extends TileImage {
|
||||
}
|
||||
}
|
||||
);
|
||||
}));
|
||||
})
|
||||
);
|
||||
|
||||
if (resource.imageryProviders) {
|
||||
const transform = getTransformFromProjections(
|
||||
getProjection('EPSG:4326'), this.getProjection());
|
||||
getProjection('EPSG:4326'),
|
||||
this.getProjection()
|
||||
);
|
||||
|
||||
this.setAttributions(function(frameState) {
|
||||
const attributions = [];
|
||||
const viewState = frameState.viewState;
|
||||
const tileGrid = this.getTileGrid();
|
||||
const z = tileGrid.getZForResolution(viewState.resolution, this.zDirection);
|
||||
const tileCoord = tileGrid.getTileCoordForCoordAndZ(viewState.center, z);
|
||||
const zoom = tileCoord[0];
|
||||
resource.imageryProviders.map(function(imageryProvider) {
|
||||
let intersecting = false;
|
||||
const coverageAreas = imageryProvider.coverageAreas;
|
||||
for (let i = 0, ii = coverageAreas.length; i < ii; ++i) {
|
||||
const coverageArea = coverageAreas[i];
|
||||
if (zoom >= coverageArea.zoomMin && zoom <= coverageArea.zoomMax) {
|
||||
const bbox = coverageArea.bbox;
|
||||
const epsg4326Extent = [bbox[1], bbox[0], bbox[3], bbox[2]];
|
||||
const extent = applyTransform(epsg4326Extent, transform);
|
||||
if (intersects(extent, frameState.extent)) {
|
||||
intersecting = true;
|
||||
break;
|
||||
this.setAttributions(
|
||||
function (frameState) {
|
||||
const attributions = [];
|
||||
const viewState = frameState.viewState;
|
||||
const tileGrid = this.getTileGrid();
|
||||
const z = tileGrid.getZForResolution(
|
||||
viewState.resolution,
|
||||
this.zDirection
|
||||
);
|
||||
const tileCoord = tileGrid.getTileCoordForCoordAndZ(
|
||||
viewState.center,
|
||||
z
|
||||
);
|
||||
const zoom = tileCoord[0];
|
||||
resource.imageryProviders.map(function (imageryProvider) {
|
||||
let intersecting = false;
|
||||
const coverageAreas = imageryProvider.coverageAreas;
|
||||
for (let i = 0, ii = coverageAreas.length; i < ii; ++i) {
|
||||
const coverageArea = coverageAreas[i];
|
||||
if (
|
||||
zoom >= coverageArea.zoomMin &&
|
||||
zoom <= coverageArea.zoomMax
|
||||
) {
|
||||
const bbox = coverageArea.bbox;
|
||||
const epsg4326Extent = [bbox[1], bbox[0], bbox[3], bbox[2]];
|
||||
const extent = applyTransform(epsg4326Extent, transform);
|
||||
if (intersects(extent, frameState.extent)) {
|
||||
intersecting = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (intersecting) {
|
||||
attributions.push(imageryProvider.attribution);
|
||||
}
|
||||
});
|
||||
if (intersecting) {
|
||||
attributions.push(imageryProvider.attribution);
|
||||
}
|
||||
});
|
||||
|
||||
attributions.push(TOS_ATTRIBUTION);
|
||||
return attributions;
|
||||
}.bind(this));
|
||||
attributions.push(TOS_ATTRIBUTION);
|
||||
return attributions;
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
this.setState(SourceState.READY);
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
* @module ol/source/CartoDB
|
||||
*/
|
||||
|
||||
import {assign} from '../obj.js';
|
||||
import SourceState from './State.js';
|
||||
import XYZ from './XYZ.js';
|
||||
import {assign} from '../obj.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -29,7 +29,6 @@ import XYZ from './XYZ.js';
|
||||
* @property {string} account If using named maps, this will be the name of the template to load.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} CartoDBLayerInfo
|
||||
* @property {string} layergroupid The layer group ID
|
||||
@@ -53,7 +52,7 @@ class CartoDB extends XYZ {
|
||||
maxZoom: options.maxZoom !== undefined ? options.maxZoom : 18,
|
||||
minZoom: options.minZoom,
|
||||
projection: options.projection,
|
||||
wrapX: options.wrapX
|
||||
wrapX: options.wrapX,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -132,7 +131,10 @@ class CartoDB extends XYZ {
|
||||
}
|
||||
|
||||
const client = new XMLHttpRequest();
|
||||
client.addEventListener('load', this.handleInitResponse_.bind(this, paramHash));
|
||||
client.addEventListener(
|
||||
'load',
|
||||
this.handleInitResponse_.bind(this, paramHash)
|
||||
);
|
||||
client.addEventListener('error', this.handleInitError_.bind(this));
|
||||
client.open('POST', mapUrl);
|
||||
client.setRequestHeader('Content-type', 'application/json');
|
||||
@@ -149,10 +151,12 @@ class CartoDB extends XYZ {
|
||||
handleInitResponse_(paramHash, event) {
|
||||
const client = /** @type {XMLHttpRequest} */ (event.target);
|
||||
// status will be 0 for file:// urls
|
||||
if (!client.status || client.status >= 200 && client.status < 300) {
|
||||
if (!client.status || (client.status >= 200 && client.status < 300)) {
|
||||
let response;
|
||||
try {
|
||||
response = /** @type {CartoDBLayerInfo} */(JSON.parse(client.responseText));
|
||||
response = /** @type {CartoDBLayerInfo} */ (JSON.parse(
|
||||
client.responseText
|
||||
));
|
||||
} catch (err) {
|
||||
this.setState(SourceState.ERROR);
|
||||
return;
|
||||
@@ -179,11 +183,16 @@ class CartoDB extends XYZ {
|
||||
* @private
|
||||
*/
|
||||
applyTemplate_(data) {
|
||||
const tilesUrl = 'https://' + data.cdn_url.https + '/' + this.account_ +
|
||||
'/api/v1/map/' + data.layergroupid + '/{z}/{x}/{y}.png';
|
||||
const tilesUrl =
|
||||
'https://' +
|
||||
data.cdn_url.https +
|
||||
'/' +
|
||||
this.account_ +
|
||||
'/api/v1/map/' +
|
||||
data.layergroupid +
|
||||
'/{z}/{x}/{y}.png';
|
||||
this.setUrl(tilesUrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default CartoDB;
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
* @module ol/source/Cluster
|
||||
*/
|
||||
|
||||
import {getUid} from '../util.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import Feature from '../Feature.js';
|
||||
import GeometryType from '../geom/GeometryType.js';
|
||||
import {scale as scaleCoordinate, add as addCoordinate} from '../coordinate.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {buffer, createEmpty, createOrUpdateFromCoordinate} from '../extent.js';
|
||||
import Point from '../geom/Point.js';
|
||||
import VectorSource from './Vector.js';
|
||||
import {add as addCoordinate, scale as scaleCoordinate} from '../coordinate.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import {buffer, createEmpty, createOrUpdateFromCoordinate} from '../extent.js';
|
||||
import {getUid} from '../util.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -33,7 +33,6 @@ import VectorSource from './Vector.js';
|
||||
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source to cluster vector data. Works out of the box with point
|
||||
@@ -52,7 +51,7 @@ class Cluster extends VectorSource {
|
||||
constructor(options) {
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
wrapX: options.wrapX
|
||||
wrapX: options.wrapX,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -78,12 +77,13 @@ class Cluster extends VectorSource {
|
||||
* @return {Point} Cluster calculation point.
|
||||
* @protected
|
||||
*/
|
||||
this.geometryFunction = options.geometryFunction || function(feature) {
|
||||
const geometry = feature.getGeometry();
|
||||
assert(geometry.getType() == GeometryType.POINT,
|
||||
10); // The default `geometryFunction` can only handle `Point` geometries
|
||||
return geometry;
|
||||
};
|
||||
this.geometryFunction =
|
||||
options.geometryFunction ||
|
||||
function (feature) {
|
||||
const geometry = feature.getGeometry();
|
||||
assert(geometry.getType() == GeometryType.POINT, 10); // The default `geometryFunction` can only handle `Point` geometries
|
||||
return geometry;
|
||||
};
|
||||
|
||||
this.boundRefresh_ = this.refresh.bind(this);
|
||||
|
||||
@@ -194,7 +194,7 @@ class Cluster extends VectorSource {
|
||||
buffer(extent, mapDistance, extent);
|
||||
|
||||
let neighbors = this.source.getFeaturesInExtent(extent);
|
||||
neighbors = neighbors.filter(function(neighbor) {
|
||||
neighbors = neighbors.filter(function (neighbor) {
|
||||
const uid = getUid(neighbor);
|
||||
if (!(uid in clustered)) {
|
||||
clustered[uid] = true;
|
||||
@@ -232,5 +232,4 @@ class Cluster extends VectorSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default Cluster;
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
* @module ol/source/IIIF
|
||||
*/
|
||||
|
||||
import {DEFAULT_TILE_SIZE} from '../tilegrid/common.js';
|
||||
import {getTopLeft} from '../extent.js';
|
||||
import {CustomTile} from './Zoomify.js';
|
||||
import {Versions} from '../format/IIIFInfo.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import TileGrid from '../tilegrid/TileGrid.js';
|
||||
import TileImage from './TileImage.js';
|
||||
import {CustomTile} from './Zoomify.js';
|
||||
import {DEFAULT_TILE_SIZE} from '../tilegrid/common.js';
|
||||
import {Versions} from '../format/IIIFInfo.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import {getTopLeft} from '../extent.js';
|
||||
import {toSize} from '../size.js';
|
||||
|
||||
/**
|
||||
@@ -58,66 +58,99 @@ function formatPercentage(percentage) {
|
||||
* @api
|
||||
*/
|
||||
class IIIF extends TileImage {
|
||||
|
||||
/**
|
||||
* @param {Options=} opt_options Tile source options. Use {@link import("../format/IIIFInfo.js").IIIFInfo}
|
||||
* to parse Image API service information responses into constructor options.
|
||||
* @api
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
/**
|
||||
* @type {Partial<Options>}
|
||||
*/
|
||||
const options = opt_options || {};
|
||||
|
||||
let baseUrl = options.url || '';
|
||||
baseUrl = baseUrl + (baseUrl.lastIndexOf('/') === baseUrl.length - 1 || baseUrl === '' ? '' : '/');
|
||||
baseUrl =
|
||||
baseUrl +
|
||||
(baseUrl.lastIndexOf('/') === baseUrl.length - 1 || baseUrl === ''
|
||||
? ''
|
||||
: '/');
|
||||
const version = options.version || Versions.VERSION2;
|
||||
const sizes = options.sizes || [];
|
||||
const size = options.size;
|
||||
assert(size != undefined && Array.isArray(size) && size.length == 2 &&
|
||||
!isNaN(size[0]) && size[0] > 0 && !isNaN(size[1]) && size[1] > 0, 60);
|
||||
assert(
|
||||
size != undefined &&
|
||||
Array.isArray(size) &&
|
||||
size.length == 2 &&
|
||||
!isNaN(size[0]) &&
|
||||
size[0] > 0 &&
|
||||
!isNaN(size[1]) &&
|
||||
size[1] > 0,
|
||||
60
|
||||
);
|
||||
const width = size[0];
|
||||
const height = size[1];
|
||||
const tileSize = options.tileSize;
|
||||
const tilePixelRatio = options.tilePixelRatio || 1;
|
||||
const format = options.format || 'jpg';
|
||||
const quality = options.quality || (options.version == Versions.VERSION1 ? 'native' : 'default');
|
||||
const quality =
|
||||
options.quality ||
|
||||
(options.version == Versions.VERSION1 ? 'native' : 'default');
|
||||
let resolutions = options.resolutions || [];
|
||||
const supports = options.supports || [];
|
||||
const extent = options.extent || [0, -height, width, 0];
|
||||
|
||||
const supportsListedSizes = sizes != undefined && Array.isArray(sizes) && sizes.length > 0;
|
||||
const supportsListedTiles = tileSize !== undefined && (typeof tileSize === 'number' && Number.isInteger(tileSize) && tileSize > 0 || Array.isArray(tileSize) && tileSize.length > 0);
|
||||
const supportsArbitraryTiling = supports != undefined && Array.isArray(supports) &&
|
||||
const supportsListedSizes =
|
||||
sizes != undefined && Array.isArray(sizes) && sizes.length > 0;
|
||||
const supportsListedTiles =
|
||||
tileSize !== undefined &&
|
||||
((typeof tileSize === 'number' &&
|
||||
Number.isInteger(tileSize) &&
|
||||
tileSize > 0) ||
|
||||
(Array.isArray(tileSize) && tileSize.length > 0));
|
||||
const supportsArbitraryTiling =
|
||||
supports != undefined &&
|
||||
Array.isArray(supports) &&
|
||||
(supports.includes('regionByPx') || supports.includes('regionByPct')) &&
|
||||
(supports.includes('sizeByWh') || supports.includes('sizeByH') ||
|
||||
supports.includes('sizeByW') || supports.includes('sizeByPct'));
|
||||
(supports.includes('sizeByWh') ||
|
||||
supports.includes('sizeByH') ||
|
||||
supports.includes('sizeByW') ||
|
||||
supports.includes('sizeByPct'));
|
||||
|
||||
let tileWidth,
|
||||
tileHeight,
|
||||
maxZoom;
|
||||
let tileWidth, tileHeight, maxZoom;
|
||||
|
||||
resolutions.sort(function(a, b) {
|
||||
resolutions.sort(function (a, b) {
|
||||
return b - a;
|
||||
});
|
||||
|
||||
if (supportsListedTiles || supportsArbitraryTiling) {
|
||||
if (tileSize != undefined) {
|
||||
if (typeof tileSize === 'number' && Number.isInteger(tileSize) && tileSize > 0) {
|
||||
if (
|
||||
typeof tileSize === 'number' &&
|
||||
Number.isInteger(tileSize) &&
|
||||
tileSize > 0
|
||||
) {
|
||||
tileWidth = tileSize;
|
||||
tileHeight = tileSize;
|
||||
} else if (Array.isArray(tileSize) && tileSize.length > 0) {
|
||||
if (tileSize.length == 1 || tileSize[1] == undefined && Number.isInteger(tileSize[0])) {
|
||||
if (
|
||||
tileSize.length == 1 ||
|
||||
(tileSize[1] == undefined && Number.isInteger(tileSize[0]))
|
||||
) {
|
||||
tileWidth = tileSize[0];
|
||||
tileHeight = tileSize[0];
|
||||
}
|
||||
if (tileSize.length == 2) {
|
||||
if (Number.isInteger(tileSize[0]) && Number.isInteger(tileSize[1])) {
|
||||
if (
|
||||
Number.isInteger(tileSize[0]) &&
|
||||
Number.isInteger(tileSize[1])
|
||||
) {
|
||||
tileWidth = tileSize[0];
|
||||
tileHeight = tileSize[1];
|
||||
} else if (tileSize[0] == undefined && Number.isInteger(tileSize[1])) {
|
||||
} else if (
|
||||
tileSize[0] == undefined &&
|
||||
Number.isInteger(tileSize[1])
|
||||
) {
|
||||
tileWidth = tileSize[1];
|
||||
tileHeight = tileSize[1];
|
||||
}
|
||||
@@ -151,14 +184,17 @@ class IIIF extends TileImage {
|
||||
* 'sizes' provided. Use full region in different resolutions. Every
|
||||
* resolution has only one tile.
|
||||
*/
|
||||
sizes.sort(function(a, b) {
|
||||
sizes.sort(function (a, b) {
|
||||
return a[0] - b[0];
|
||||
});
|
||||
maxZoom = -1;
|
||||
const ignoredSizesIndex = [];
|
||||
for (let i = 0; i < sizes.length; i++) {
|
||||
const resolution = width / sizes[i][0];
|
||||
if (resolutions.length > 0 && resolutions[resolutions.length - 1] == resolution) {
|
||||
if (
|
||||
resolutions.length > 0 &&
|
||||
resolutions[resolutions.length - 1] == resolution
|
||||
) {
|
||||
ignoredSizesIndex.push(i);
|
||||
continue;
|
||||
}
|
||||
@@ -182,31 +218,36 @@ class IIIF extends TileImage {
|
||||
tileSize: [tileWidth, tileHeight],
|
||||
extent: extent,
|
||||
origin: getTopLeft(extent),
|
||||
resolutions: resolutions
|
||||
resolutions: resolutions,
|
||||
});
|
||||
|
||||
const tileUrlFunction = function(tileCoord, pixelRatio, projection) {
|
||||
let regionParam,
|
||||
sizeParam;
|
||||
const tileUrlFunction = function (tileCoord, pixelRatio, projection) {
|
||||
let regionParam, sizeParam;
|
||||
const zoom = tileCoord[0];
|
||||
if (zoom > maxZoom) {
|
||||
return;
|
||||
}
|
||||
const tileX = tileCoord[1],
|
||||
tileY = tileCoord[2],
|
||||
scale = resolutions[zoom];
|
||||
if (tileX === undefined || tileY === undefined || scale === undefined ||
|
||||
tileX < 0 || Math.ceil(width / scale / tileWidth) <= tileX ||
|
||||
tileY < 0 || Math.ceil(height / scale / tileHeight) <= tileY) {
|
||||
tileY = tileCoord[2],
|
||||
scale = resolutions[zoom];
|
||||
if (
|
||||
tileX === undefined ||
|
||||
tileY === undefined ||
|
||||
scale === undefined ||
|
||||
tileX < 0 ||
|
||||
Math.ceil(width / scale / tileWidth) <= tileX ||
|
||||
tileY < 0 ||
|
||||
Math.ceil(height / scale / tileHeight) <= tileY
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (supportsArbitraryTiling || supportsListedTiles) {
|
||||
const regionX = tileX * tileWidth * scale,
|
||||
regionY = tileY * tileHeight * scale;
|
||||
regionY = tileY * tileHeight * scale;
|
||||
let regionW = tileWidth * scale,
|
||||
regionH = tileHeight * scale,
|
||||
sizeW = tileWidth,
|
||||
sizeH = tileHeight;
|
||||
regionH = tileHeight * scale,
|
||||
sizeW = tileWidth,
|
||||
sizeH = tileHeight;
|
||||
if (regionX + regionW > width) {
|
||||
regionW = width - regionX;
|
||||
}
|
||||
@@ -219,19 +260,30 @@ class IIIF extends TileImage {
|
||||
if (regionY + tileHeight * scale > height) {
|
||||
sizeH = Math.floor((height - regionY + scale - 1) / scale);
|
||||
}
|
||||
if (regionX == 0 && regionW == width && regionY == 0 && regionH == height) {
|
||||
if (
|
||||
regionX == 0 &&
|
||||
regionW == width &&
|
||||
regionY == 0 &&
|
||||
regionH == height
|
||||
) {
|
||||
// canonical full image region parameter is 'full', not 'x,y,w,h'
|
||||
regionParam = 'full';
|
||||
} else if (!supportsArbitraryTiling || supports.includes('regionByPx')) {
|
||||
} else if (
|
||||
!supportsArbitraryTiling ||
|
||||
supports.includes('regionByPx')
|
||||
) {
|
||||
regionParam = regionX + ',' + regionY + ',' + regionW + ',' + regionH;
|
||||
} else if (supports.includes('regionByPct')) {
|
||||
const pctX = formatPercentage(regionX / width * 100),
|
||||
pctY = formatPercentage(regionY / height * 100),
|
||||
pctW = formatPercentage(regionW / width * 100),
|
||||
pctH = formatPercentage(regionH / height * 100);
|
||||
const pctX = formatPercentage((regionX / width) * 100),
|
||||
pctY = formatPercentage((regionY / height) * 100),
|
||||
pctW = formatPercentage((regionW / width) * 100),
|
||||
pctH = formatPercentage((regionH / height) * 100);
|
||||
regionParam = 'pct:' + pctX + ',' + pctY + ',' + pctW + ',' + pctH;
|
||||
}
|
||||
if (version == Versions.VERSION3 && (!supportsArbitraryTiling || supports.includes('sizeByWh'))) {
|
||||
if (
|
||||
version == Versions.VERSION3 &&
|
||||
(!supportsArbitraryTiling || supports.includes('sizeByWh'))
|
||||
) {
|
||||
sizeParam = sizeW + ',' + sizeH;
|
||||
} else if (!supportsArbitraryTiling || supports.includes('sizeByW')) {
|
||||
sizeParam = sizeW + ',';
|
||||
@@ -246,7 +298,7 @@ class IIIF extends TileImage {
|
||||
regionParam = 'full';
|
||||
if (supportsListedSizes) {
|
||||
const regionWidth = sizes[zoom][0],
|
||||
regionHeight = sizes[zoom][1];
|
||||
regionHeight = sizes[zoom][1];
|
||||
if (version == Versions.VERSION3) {
|
||||
if (regionWidth == width && regionHeight == height) {
|
||||
sizeParam = 'max';
|
||||
@@ -264,12 +316,17 @@ class IIIF extends TileImage {
|
||||
sizeParam = version == Versions.VERSION3 ? 'max' : 'full';
|
||||
}
|
||||
}
|
||||
return baseUrl + regionParam + '/' + sizeParam + '/0/' + quality + '.' + format;
|
||||
return (
|
||||
baseUrl + regionParam + '/' + sizeParam + '/0/' + quality + '.' + format
|
||||
);
|
||||
};
|
||||
|
||||
const IiifTileClass = CustomTile.bind(null, toSize(tileSize || 256).map(function(size) {
|
||||
return size * tilePixelRatio;
|
||||
}));
|
||||
const IiifTileClass = CustomTile.bind(
|
||||
null,
|
||||
toSize(tileSize || 256).map(function (size) {
|
||||
return size * tilePixelRatio;
|
||||
})
|
||||
);
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
@@ -284,16 +341,14 @@ class IIIF extends TileImage {
|
||||
tileGrid: tileGrid,
|
||||
tilePixelRatio: options.tilePixelRatio,
|
||||
tileUrlFunction: tileUrlFunction,
|
||||
transition: options.transition
|
||||
transition: options.transition,
|
||||
});
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.zDirection = options.zDirection;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default IIIF;
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
/**
|
||||
* @module ol/source/Image
|
||||
*/
|
||||
import {abstract} from '../util.js';
|
||||
import {ENABLE_RASTER_REPROJECTION} from '../reproj/common.js';
|
||||
import ImageState from '../ImageState.js';
|
||||
import {linearFindNearest} from '../array.js';
|
||||
import Event from '../events/Event.js';
|
||||
import {equals} from '../extent.js';
|
||||
import {equivalent} from '../proj.js';
|
||||
import ImageState from '../ImageState.js';
|
||||
import ReprojImage from '../reproj/Image.js';
|
||||
import Source from './Source.js';
|
||||
|
||||
import {ENABLE_RASTER_REPROJECTION} from '../reproj/common.js';
|
||||
import {abstract} from '../util.js';
|
||||
import {equals} from '../extent.js';
|
||||
import {equivalent} from '../proj.js';
|
||||
import {linearFindNearest} from '../array.js';
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
export const ImageSourceEventType = {
|
||||
|
||||
/**
|
||||
* Triggered when an image starts loading.
|
||||
* @event module:ol/source/Image.ImageSourceEvent#imageloadstart
|
||||
@@ -36,11 +34,9 @@ export const ImageSourceEventType = {
|
||||
* @event module:ol/source/Image.ImageSourceEvent#imageloaderror
|
||||
* @api
|
||||
*/
|
||||
IMAGELOADERROR: 'imageloaderror'
|
||||
|
||||
IMAGELOADERROR: 'imageloaderror',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/source/Image~ImageSource} instances are instances of this
|
||||
@@ -52,7 +48,6 @@ export class ImageSourceEvent extends Event {
|
||||
* @param {import("../Image.js").default} image The image.
|
||||
*/
|
||||
constructor(type, image) {
|
||||
|
||||
super(type);
|
||||
|
||||
/**
|
||||
@@ -61,12 +56,9 @@ export class ImageSourceEvent extends Event {
|
||||
* @api
|
||||
*/
|
||||
this.image = image;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("./Source.js").AttributionLike} [attributions]
|
||||
@@ -75,7 +67,6 @@ export class ImageSourceEvent extends Event {
|
||||
* @property {import("./State.js").default} [state]
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Abstract base class; normally only used for creating subclasses and not
|
||||
@@ -93,16 +84,15 @@ class ImageSource extends Source {
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
projection: options.projection,
|
||||
state: options.state
|
||||
state: options.state,
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array<number>}
|
||||
*/
|
||||
this.resolutions_ = options.resolutions !== undefined ?
|
||||
options.resolutions : null;
|
||||
|
||||
this.resolutions_ =
|
||||
options.resolutions !== undefined ? options.resolutions : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -110,7 +100,6 @@ class ImageSource extends Source {
|
||||
*/
|
||||
this.reprojectedImage_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
@@ -147,21 +136,24 @@ class ImageSource extends Source {
|
||||
*/
|
||||
getImage(extent, resolution, pixelRatio, projection) {
|
||||
const sourceProjection = this.getProjection();
|
||||
if (!ENABLE_RASTER_REPROJECTION ||
|
||||
!sourceProjection ||
|
||||
!projection ||
|
||||
equivalent(sourceProjection, projection)) {
|
||||
if (
|
||||
!ENABLE_RASTER_REPROJECTION ||
|
||||
!sourceProjection ||
|
||||
!projection ||
|
||||
equivalent(sourceProjection, projection)
|
||||
) {
|
||||
if (sourceProjection) {
|
||||
projection = sourceProjection;
|
||||
}
|
||||
return this.getImageInternal(extent, resolution, pixelRatio, projection);
|
||||
} else {
|
||||
if (this.reprojectedImage_) {
|
||||
if (this.reprojectedRevision_ == this.getRevision() &&
|
||||
equivalent(
|
||||
this.reprojectedImage_.getProjection(), projection) &&
|
||||
this.reprojectedImage_.getResolution() == resolution &&
|
||||
equals(this.reprojectedImage_.getExtent(), extent)) {
|
||||
if (
|
||||
this.reprojectedRevision_ == this.getRevision() &&
|
||||
equivalent(this.reprojectedImage_.getProjection(), projection) &&
|
||||
this.reprojectedImage_.getResolution() == resolution &&
|
||||
equals(this.reprojectedImage_.getExtent(), extent)
|
||||
) {
|
||||
return this.reprojectedImage_;
|
||||
}
|
||||
this.reprojectedImage_.dispose();
|
||||
@@ -169,11 +161,20 @@ class ImageSource extends Source {
|
||||
}
|
||||
|
||||
this.reprojectedImage_ = new ReprojImage(
|
||||
sourceProjection, projection, extent, resolution, pixelRatio,
|
||||
function(extent, resolution, pixelRatio) {
|
||||
return this.getImageInternal(extent, resolution,
|
||||
pixelRatio, sourceProjection);
|
||||
}.bind(this));
|
||||
sourceProjection,
|
||||
projection,
|
||||
extent,
|
||||
resolution,
|
||||
pixelRatio,
|
||||
function (extent, resolution, pixelRatio) {
|
||||
return this.getImageInternal(
|
||||
extent,
|
||||
resolution,
|
||||
pixelRatio,
|
||||
sourceProjection
|
||||
);
|
||||
}.bind(this)
|
||||
);
|
||||
this.reprojectedRevision_ = this.getRevision();
|
||||
|
||||
return this.reprojectedImage_;
|
||||
@@ -204,28 +205,27 @@ class ImageSource extends Source {
|
||||
case ImageState.LOADING:
|
||||
this.loading = true;
|
||||
this.dispatchEvent(
|
||||
new ImageSourceEvent(ImageSourceEventType.IMAGELOADSTART,
|
||||
image));
|
||||
new ImageSourceEvent(ImageSourceEventType.IMAGELOADSTART, image)
|
||||
);
|
||||
break;
|
||||
case ImageState.LOADED:
|
||||
this.loading = false;
|
||||
this.dispatchEvent(
|
||||
new ImageSourceEvent(ImageSourceEventType.IMAGELOADEND,
|
||||
image));
|
||||
new ImageSourceEvent(ImageSourceEventType.IMAGELOADEND, image)
|
||||
);
|
||||
break;
|
||||
case ImageState.ERROR:
|
||||
this.loading = false;
|
||||
this.dispatchEvent(
|
||||
new ImageSourceEvent(ImageSourceEventType.IMAGELOADERROR,
|
||||
image));
|
||||
new ImageSourceEvent(ImageSourceEventType.IMAGELOADERROR, image)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
// pass
|
||||
// pass
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default image load function for image sources that use import("../Image.js").Image image
|
||||
* instances.
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
* @module ol/source/ImageArcGISRest
|
||||
*/
|
||||
|
||||
import ImageWrapper from '../Image.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {containsExtent, getHeight, getWidth} from '../extent.js';
|
||||
import {assign} from '../obj.js';
|
||||
import ImageSource, {defaultImageLoadFunction} from './Image.js';
|
||||
import ImageWrapper from '../Image.js';
|
||||
import {appendParams} from '../uri.js';
|
||||
|
||||
import {assert} from '../asserts.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {containsExtent, getHeight, getWidth} from '../extent.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -36,7 +35,6 @@ import {appendParams} from '../uri.js';
|
||||
* should include /MapServer or /ImageServer.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Source for data from ArcGIS Rest services providing single, untiled images.
|
||||
@@ -54,13 +52,12 @@ class ImageArcGISRest extends ImageSource {
|
||||
* @param {Options=} opt_options Image ArcGIS Rest Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
projection: options.projection,
|
||||
resolutions: options.resolutions
|
||||
resolutions: options.resolutions,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -68,7 +65,7 @@ class ImageArcGISRest extends ImageSource {
|
||||
* @type {?string}
|
||||
*/
|
||||
this.crossOrigin_ =
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -86,9 +83,10 @@ class ImageArcGISRest extends ImageSource {
|
||||
* @private
|
||||
* @type {import("../Image.js").LoadFunction}
|
||||
*/
|
||||
this.imageLoadFunction_ = options.imageLoadFunction !== undefined ?
|
||||
options.imageLoadFunction : defaultImageLoadFunction;
|
||||
|
||||
this.imageLoadFunction_ =
|
||||
options.imageLoadFunction !== undefined
|
||||
? options.imageLoadFunction
|
||||
: defaultImageLoadFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -108,7 +106,6 @@ class ImageArcGISRest extends ImageSource {
|
||||
*/
|
||||
this.imageSize_ = [0, 0];
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
@@ -120,7 +117,6 @@ class ImageArcGISRest extends ImageSource {
|
||||
* @type {number}
|
||||
*/
|
||||
this.ratio_ = options.ratio !== undefined ? options.ratio : 1.5;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +137,6 @@ class ImageArcGISRest extends ImageSource {
|
||||
* @return {import("../Image.js").default} Single image.
|
||||
*/
|
||||
getImageInternal(extent, resolution, pixelRatio, projection) {
|
||||
|
||||
if (this.url_ === undefined) {
|
||||
return null;
|
||||
}
|
||||
@@ -150,18 +145,20 @@ class ImageArcGISRest extends ImageSource {
|
||||
pixelRatio = this.hidpi_ ? pixelRatio : 1;
|
||||
|
||||
const image = this.image_;
|
||||
if (image &&
|
||||
this.renderedRevision_ == this.getRevision() &&
|
||||
image.getResolution() == resolution &&
|
||||
image.getPixelRatio() == pixelRatio &&
|
||||
containsExtent(image.getExtent(), extent)) {
|
||||
if (
|
||||
image &&
|
||||
this.renderedRevision_ == this.getRevision() &&
|
||||
image.getResolution() == resolution &&
|
||||
image.getPixelRatio() == pixelRatio &&
|
||||
containsExtent(image.getExtent(), extent)
|
||||
) {
|
||||
return image;
|
||||
}
|
||||
|
||||
const params = {
|
||||
'F': 'image',
|
||||
'FORMAT': 'PNG32',
|
||||
'TRANSPARENT': true
|
||||
'TRANSPARENT': true,
|
||||
};
|
||||
assign(params, this.params_);
|
||||
|
||||
@@ -169,8 +166,8 @@ class ImageArcGISRest extends ImageSource {
|
||||
const centerX = (extent[0] + extent[2]) / 2;
|
||||
const centerY = (extent[1] + extent[3]) / 2;
|
||||
if (this.ratio_ != 1) {
|
||||
const halfWidth = this.ratio_ * getWidth(extent) / 2;
|
||||
const halfHeight = this.ratio_ * getHeight(extent) / 2;
|
||||
const halfWidth = (this.ratio_ * getWidth(extent)) / 2;
|
||||
const halfHeight = (this.ratio_ * getHeight(extent)) / 2;
|
||||
extent[0] = centerX - halfWidth;
|
||||
extent[1] = centerY - halfHeight;
|
||||
extent[2] = centerX + halfWidth;
|
||||
@@ -184,26 +181,39 @@ class ImageArcGISRest extends ImageSource {
|
||||
const height = Math.ceil(getHeight(extent) / imageResolution);
|
||||
|
||||
// Modify the extent to match the integer width and height.
|
||||
extent[0] = centerX - imageResolution * width / 2;
|
||||
extent[2] = centerX + imageResolution * width / 2;
|
||||
extent[1] = centerY - imageResolution * height / 2;
|
||||
extent[3] = centerY + imageResolution * height / 2;
|
||||
extent[0] = centerX - (imageResolution * width) / 2;
|
||||
extent[2] = centerX + (imageResolution * width) / 2;
|
||||
extent[1] = centerY - (imageResolution * height) / 2;
|
||||
extent[3] = centerY + (imageResolution * height) / 2;
|
||||
|
||||
this.imageSize_[0] = width;
|
||||
this.imageSize_[1] = height;
|
||||
|
||||
const url = this.getRequestUrl_(extent, this.imageSize_, pixelRatio,
|
||||
projection, params);
|
||||
const url = this.getRequestUrl_(
|
||||
extent,
|
||||
this.imageSize_,
|
||||
pixelRatio,
|
||||
projection,
|
||||
params
|
||||
);
|
||||
|
||||
this.image_ = new ImageWrapper(extent, resolution, pixelRatio,
|
||||
url, this.crossOrigin_, this.imageLoadFunction_);
|
||||
this.image_ = new ImageWrapper(
|
||||
extent,
|
||||
resolution,
|
||||
pixelRatio,
|
||||
url,
|
||||
this.crossOrigin_,
|
||||
this.imageLoadFunction_
|
||||
);
|
||||
|
||||
this.renderedRevision_ = this.getRevision();
|
||||
|
||||
this.image_.addEventListener(EventType.CHANGE, this.handleImageChange.bind(this));
|
||||
this.image_.addEventListener(
|
||||
EventType.CHANGE,
|
||||
this.handleImageChange.bind(this)
|
||||
);
|
||||
|
||||
return this.image_;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,5 +300,4 @@ class ImageArcGISRest extends ImageSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default ImageArcGISRest;
|
||||
|
||||
@@ -3,9 +3,13 @@
|
||||
*/
|
||||
|
||||
import ImageCanvas from '../ImageCanvas.js';
|
||||
import {containsExtent, getHeight, getWidth, scaleFromCenter} from '../extent.js';
|
||||
import ImageSource from './Image.js';
|
||||
|
||||
import {
|
||||
containsExtent,
|
||||
getHeight,
|
||||
getWidth,
|
||||
scaleFromCenter,
|
||||
} from '../extent.js';
|
||||
|
||||
/**
|
||||
* A function returning the canvas element (`{HTMLCanvasElement}`)
|
||||
@@ -20,7 +24,6 @@ import ImageSource from './Image.js';
|
||||
* number, import("../size.js").Size, import("../proj/Projection.js").default): HTMLCanvasElement} FunctionType
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
|
||||
@@ -41,7 +44,6 @@ import ImageSource from './Image.js';
|
||||
* @property {import("./State.js").default} [state] Source state.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Base class for image sources where a canvas element is the image.
|
||||
@@ -52,41 +54,38 @@ class ImageCanvasSource extends ImageSource {
|
||||
* @param {Options=} opt_options ImageCanvas options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
projection: options.projection,
|
||||
resolutions: options.resolutions,
|
||||
state: options.state
|
||||
state: options.state,
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {FunctionType}
|
||||
*/
|
||||
* @private
|
||||
* @type {FunctionType}
|
||||
*/
|
||||
this.canvasFunction_ = options.canvasFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../ImageCanvas.js").default}
|
||||
*/
|
||||
* @private
|
||||
* @type {import("../ImageCanvas.js").default}
|
||||
*/
|
||||
this.canvas_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.renderedRevision_ = 0;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.ratio_ = options.ratio !== undefined ?
|
||||
options.ratio : 1.5;
|
||||
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.ratio_ = options.ratio !== undefined ? options.ratio : 1.5;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,11 +99,13 @@ class ImageCanvasSource extends ImageSource {
|
||||
resolution = this.findNearestResolution(resolution);
|
||||
|
||||
let canvas = this.canvas_;
|
||||
if (canvas &&
|
||||
this.renderedRevision_ == this.getRevision() &&
|
||||
canvas.getResolution() == resolution &&
|
||||
canvas.getPixelRatio() == pixelRatio &&
|
||||
containsExtent(canvas.getExtent(), extent)) {
|
||||
if (
|
||||
canvas &&
|
||||
this.renderedRevision_ == this.getRevision() &&
|
||||
canvas.getResolution() == resolution &&
|
||||
canvas.getPixelRatio() == pixelRatio &&
|
||||
containsExtent(canvas.getExtent(), extent)
|
||||
) {
|
||||
return canvas;
|
||||
}
|
||||
|
||||
@@ -115,7 +116,13 @@ class ImageCanvasSource extends ImageSource {
|
||||
const size = [width * pixelRatio, height * pixelRatio];
|
||||
|
||||
const canvasElement = this.canvasFunction_.call(
|
||||
this, extent, resolution, pixelRatio, size, projection);
|
||||
this,
|
||||
extent,
|
||||
resolution,
|
||||
pixelRatio,
|
||||
size,
|
||||
projection
|
||||
);
|
||||
if (canvasElement) {
|
||||
canvas = new ImageCanvas(extent, resolution, pixelRatio, canvasElement);
|
||||
}
|
||||
@@ -126,5 +133,4 @@ class ImageCanvasSource extends ImageSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default ImageCanvasSource;
|
||||
|
||||
@@ -2,12 +2,18 @@
|
||||
* @module ol/source/ImageMapGuide
|
||||
*/
|
||||
|
||||
import ImageWrapper from '../Image.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {containsExtent, getCenter, getHeight, getWidth, scaleFromCenter} from '../extent.js';
|
||||
import {assign} from '../obj.js';
|
||||
import ImageSource, {defaultImageLoadFunction} from './Image.js';
|
||||
import ImageWrapper from '../Image.js';
|
||||
import {appendParams} from '../uri.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {
|
||||
containsExtent,
|
||||
getCenter,
|
||||
getHeight,
|
||||
getWidth,
|
||||
scaleFromCenter,
|
||||
} from '../extent.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -29,7 +35,6 @@ import {appendParams} from '../uri.js';
|
||||
* @property {Object} [params] Additional parameters.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Source for images from Mapguide servers
|
||||
@@ -42,10 +47,9 @@ class ImageMapGuide extends ImageSource {
|
||||
* @param {Options} options ImageMapGuide options.
|
||||
*/
|
||||
constructor(options) {
|
||||
|
||||
super({
|
||||
projection: options.projection,
|
||||
resolutions: options.resolutions
|
||||
resolutions: options.resolutions,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -53,14 +57,14 @@ class ImageMapGuide extends ImageSource {
|
||||
* @type {?string}
|
||||
*/
|
||||
this.crossOrigin_ =
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.displayDpi_ = options.displayDpi !== undefined ?
|
||||
options.displayDpi : 96;
|
||||
this.displayDpi_ =
|
||||
options.displayDpi !== undefined ? options.displayDpi : 96;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -78,8 +82,10 @@ class ImageMapGuide extends ImageSource {
|
||||
* @private
|
||||
* @type {import("../Image.js").LoadFunction}
|
||||
*/
|
||||
this.imageLoadFunction_ = options.imageLoadFunction !== undefined ?
|
||||
options.imageLoadFunction : defaultImageLoadFunction;
|
||||
this.imageLoadFunction_ =
|
||||
options.imageLoadFunction !== undefined
|
||||
? options.imageLoadFunction
|
||||
: defaultImageLoadFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -91,8 +97,8 @@ class ImageMapGuide extends ImageSource {
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.metersPerUnit_ = options.metersPerUnit !== undefined ?
|
||||
options.metersPerUnit : 1;
|
||||
this.metersPerUnit_ =
|
||||
options.metersPerUnit !== undefined ? options.metersPerUnit : 1;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -104,8 +110,8 @@ class ImageMapGuide extends ImageSource {
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.useOverlay_ = options.useOverlay !== undefined ?
|
||||
options.useOverlay : false;
|
||||
this.useOverlay_ =
|
||||
options.useOverlay !== undefined ? options.useOverlay : false;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -118,7 +124,6 @@ class ImageMapGuide extends ImageSource {
|
||||
* @type {number}
|
||||
*/
|
||||
this.renderedRevision_ = 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,11 +148,13 @@ class ImageMapGuide extends ImageSource {
|
||||
pixelRatio = this.hidpi_ ? pixelRatio : 1;
|
||||
|
||||
let image = this.image_;
|
||||
if (image &&
|
||||
this.renderedRevision_ == this.getRevision() &&
|
||||
image.getResolution() == resolution &&
|
||||
image.getPixelRatio() == pixelRatio &&
|
||||
containsExtent(image.getExtent(), extent)) {
|
||||
if (
|
||||
image &&
|
||||
this.renderedRevision_ == this.getRevision() &&
|
||||
image.getResolution() == resolution &&
|
||||
image.getPixelRatio() == pixelRatio &&
|
||||
containsExtent(image.getExtent(), extent)
|
||||
) {
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -160,12 +167,25 @@ class ImageMapGuide extends ImageSource {
|
||||
const size = [width * pixelRatio, height * pixelRatio];
|
||||
|
||||
if (this.url_ !== undefined) {
|
||||
const imageUrl = this.getUrl(this.url_, this.params_, extent, size,
|
||||
projection);
|
||||
image = new ImageWrapper(extent, resolution, pixelRatio,
|
||||
imageUrl, this.crossOrigin_,
|
||||
this.imageLoadFunction_);
|
||||
image.addEventListener(EventType.CHANGE, this.handleImageChange.bind(this));
|
||||
const imageUrl = this.getUrl(
|
||||
this.url_,
|
||||
this.params_,
|
||||
extent,
|
||||
size,
|
||||
projection
|
||||
);
|
||||
image = new ImageWrapper(
|
||||
extent,
|
||||
resolution,
|
||||
pixelRatio,
|
||||
imageUrl,
|
||||
this.crossOrigin_,
|
||||
this.imageLoadFunction_
|
||||
);
|
||||
image.addEventListener(
|
||||
EventType.CHANGE,
|
||||
this.handleImageChange.bind(this)
|
||||
);
|
||||
} else {
|
||||
image = null;
|
||||
}
|
||||
@@ -203,11 +223,12 @@ class ImageMapGuide extends ImageSource {
|
||||
* @return {string} The mapagent map image request URL.
|
||||
*/
|
||||
getUrl(baseUrl, params, extent, size, projection) {
|
||||
const scale = getScale(extent, size,
|
||||
this.metersPerUnit_, this.displayDpi_);
|
||||
const scale = getScale(extent, size, this.metersPerUnit_, this.displayDpi_);
|
||||
const center = getCenter(extent);
|
||||
const baseParams = {
|
||||
'OPERATION': this.useOverlay_ ? 'GETDYNAMICMAPOVERLAYIMAGE' : 'GETMAPIMAGE',
|
||||
'OPERATION': this.useOverlay_
|
||||
? 'GETDYNAMICMAPOVERLAYIMAGE'
|
||||
: 'GETMAPIMAGE',
|
||||
'VERSION': '2.0.0',
|
||||
'LOCALE': 'en',
|
||||
'CLIENTAGENT': 'ol/source/ImageMapGuide source',
|
||||
@@ -217,7 +238,7 @@ class ImageMapGuide extends ImageSource {
|
||||
'SETDISPLAYHEIGHT': Math.round(size[1]),
|
||||
'SETVIEWSCALE': scale,
|
||||
'SETVIEWCENTERX': center[0],
|
||||
'SETVIEWCENTERY': center[1]
|
||||
'SETVIEWCENTERY': center[1],
|
||||
};
|
||||
assign(baseParams, params);
|
||||
return appendParams(baseUrl, baseParams);
|
||||
@@ -235,7 +256,6 @@ class ImageMapGuide extends ImageSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {import("../extent.js").Extent} extent The map extents.
|
||||
* @param {import("../size.js").Size} size The viewport size.
|
||||
@@ -250,11 +270,10 @@ function getScale(extent, size, metersPerUnit, dpi) {
|
||||
const devH = size[1];
|
||||
const mpp = 0.0254 / dpi;
|
||||
if (devH * mcsW > devW * mcsH) {
|
||||
return mcsW * metersPerUnit / (devW * mpp); // width limited
|
||||
return (mcsW * metersPerUnit) / (devW * mpp); // width limited
|
||||
} else {
|
||||
return mcsH * metersPerUnit / (devH * mpp); // height limited
|
||||
return (mcsH * metersPerUnit) / (devH * mpp); // height limited
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default ImageMapGuide;
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
* @module ol/source/ImageStatic
|
||||
*/
|
||||
|
||||
import ImageWrapper from '../Image.js';
|
||||
import ImageState from '../ImageState.js';
|
||||
import {createCanvasContext2D} from '../dom.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {intersects, getHeight, getWidth} from '../extent.js';
|
||||
import {get as getProjection} from '../proj.js';
|
||||
import ImageSource, {defaultImageLoadFunction} from './Image.js';
|
||||
import ImageState from '../ImageState.js';
|
||||
import ImageWrapper from '../Image.js';
|
||||
import {createCanvasContext2D} from '../dom.js';
|
||||
import {getHeight, getWidth, intersects} from '../extent.js';
|
||||
import {get as getProjection} from '../proj.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -25,7 +25,6 @@ import ImageSource, {defaultImageLoadFunction} from './Image.js';
|
||||
* @property {string} url Image URL.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* A layer source for displaying a single, static image.
|
||||
@@ -36,16 +35,17 @@ class Static extends ImageSource {
|
||||
* @param {Options} options ImageStatic options.
|
||||
*/
|
||||
constructor(options) {
|
||||
const crossOrigin = options.crossOrigin !== undefined ?
|
||||
options.crossOrigin : null;
|
||||
const crossOrigin =
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
|
||||
const /** @type {import("../Image.js").LoadFunction} */ imageLoadFunction =
|
||||
options.imageLoadFunction !== undefined ?
|
||||
options.imageLoadFunction : defaultImageLoadFunction;
|
||||
options.imageLoadFunction !== undefined
|
||||
? options.imageLoadFunction
|
||||
: defaultImageLoadFunction;
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
projection: getProjection(options.projection)
|
||||
projection: getProjection(options.projection),
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -64,7 +64,14 @@ class Static extends ImageSource {
|
||||
* @private
|
||||
* @type {import("../Image.js").default}
|
||||
*/
|
||||
this.image_ = new ImageWrapper(this.imageExtent_, undefined, 1, this.url_, crossOrigin, imageLoadFunction);
|
||||
this.image_ = new ImageWrapper(
|
||||
this.imageExtent_,
|
||||
undefined,
|
||||
1,
|
||||
this.url_,
|
||||
crossOrigin,
|
||||
imageLoadFunction
|
||||
);
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -72,8 +79,10 @@ class Static extends ImageSource {
|
||||
*/
|
||||
this.imageSize_ = options.imageSize ? options.imageSize : null;
|
||||
|
||||
this.image_.addEventListener(EventType.CHANGE, this.handleImageChange.bind(this));
|
||||
|
||||
this.image_.addEventListener(
|
||||
EventType.CHANGE,
|
||||
this.handleImageChange.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,8 +137,17 @@ class Static extends ImageSource {
|
||||
if (targetWidth != imageWidth) {
|
||||
const context = createCanvasContext2D(targetWidth, imageHeight);
|
||||
const canvas = context.canvas;
|
||||
context.drawImage(image, 0, 0, imageWidth, imageHeight,
|
||||
0, 0, canvas.width, canvas.height);
|
||||
context.drawImage(
|
||||
image,
|
||||
0,
|
||||
0,
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
0,
|
||||
0,
|
||||
canvas.width,
|
||||
canvas.height
|
||||
);
|
||||
this.image_.setImage(canvas);
|
||||
}
|
||||
}
|
||||
@@ -137,5 +155,4 @@ class Static extends ImageSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default Static;
|
||||
|
||||
@@ -4,18 +4,23 @@
|
||||
|
||||
import {DEFAULT_WMS_VERSION} from './common.js';
|
||||
|
||||
import ImageWrapper from '../Image.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {containsExtent, getCenter, getForViewAndSize, getHeight, getWidth} from '../extent.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {get as getProjection, transform} from '../proj.js';
|
||||
import {calculateSourceResolution} from '../reproj.js';
|
||||
import ImageSource, {defaultImageLoadFunction} from './Image.js';
|
||||
import ImageWrapper from '../Image.js';
|
||||
import WMSServerType from './WMSServerType.js';
|
||||
import {compareVersions} from '../string.js';
|
||||
import {appendParams} from '../uri.js';
|
||||
|
||||
import {assert} from '../asserts.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {calculateSourceResolution} from '../reproj.js';
|
||||
import {compareVersions} from '../string.js';
|
||||
import {
|
||||
containsExtent,
|
||||
getCenter,
|
||||
getForViewAndSize,
|
||||
getHeight,
|
||||
getWidth,
|
||||
} from '../extent.js';
|
||||
import {get as getProjection, transform} from '../proj.js';
|
||||
|
||||
/**
|
||||
* @const
|
||||
@@ -23,7 +28,6 @@ import {appendParams} from '../uri.js';
|
||||
*/
|
||||
const GETFEATUREINFO_IMAGE_SIZE = [101, 101];
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
|
||||
@@ -48,7 +52,6 @@ const GETFEATUREINFO_IMAGE_SIZE = [101, 101];
|
||||
* @property {string} url WMS service URL.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Source for WMS servers providing single, untiled images.
|
||||
@@ -61,13 +64,12 @@ class ImageWMS extends ImageSource {
|
||||
* @param {Options=} [opt_options] ImageWMS options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
projection: options.projection,
|
||||
resolutions: options.resolutions
|
||||
resolutions: options.resolutions,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -75,7 +77,7 @@ class ImageWMS extends ImageSource {
|
||||
* @type {?string}
|
||||
*/
|
||||
this.crossOrigin_ =
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -87,8 +89,10 @@ class ImageWMS extends ImageSource {
|
||||
* @private
|
||||
* @type {import("../Image.js").LoadFunction}
|
||||
*/
|
||||
this.imageLoadFunction_ = options.imageLoadFunction !== undefined ?
|
||||
options.imageLoadFunction : defaultImageLoadFunction;
|
||||
this.imageLoadFunction_ =
|
||||
options.imageLoadFunction !== undefined
|
||||
? options.imageLoadFunction
|
||||
: defaultImageLoadFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -138,7 +142,6 @@ class ImageWMS extends ImageSource {
|
||||
* @type {number}
|
||||
*/
|
||||
this.ratio_ = options.ratio !== undefined ? options.ratio : 1.5;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,12 +166,21 @@ class ImageWMS extends ImageSource {
|
||||
const sourceProjectionObj = this.getProjection();
|
||||
|
||||
if (sourceProjectionObj && sourceProjectionObj !== projectionObj) {
|
||||
resolution = calculateSourceResolution(sourceProjectionObj, projectionObj, coordinate, resolution);
|
||||
resolution = calculateSourceResolution(
|
||||
sourceProjectionObj,
|
||||
projectionObj,
|
||||
coordinate,
|
||||
resolution
|
||||
);
|
||||
coordinate = transform(coordinate, projectionObj, sourceProjectionObj);
|
||||
}
|
||||
|
||||
const extent = getForViewAndSize(coordinate, resolution, 0,
|
||||
GETFEATUREINFO_IMAGE_SIZE);
|
||||
const extent = getForViewAndSize(
|
||||
coordinate,
|
||||
resolution,
|
||||
0,
|
||||
GETFEATUREINFO_IMAGE_SIZE
|
||||
);
|
||||
|
||||
const baseParams = {
|
||||
'SERVICE': 'WMS',
|
||||
@@ -176,7 +188,7 @@ class ImageWMS extends ImageSource {
|
||||
'REQUEST': 'GetFeatureInfo',
|
||||
'FORMAT': 'image/png',
|
||||
'TRANSPARENT': true,
|
||||
'QUERY_LAYERS': this.params_['LAYERS']
|
||||
'QUERY_LAYERS': this.params_['LAYERS'],
|
||||
};
|
||||
assign(baseParams, this.params_, params);
|
||||
|
||||
@@ -186,8 +198,12 @@ class ImageWMS extends ImageSource {
|
||||
baseParams[this.v13_ ? 'J' : 'Y'] = y;
|
||||
|
||||
return this.getRequestUrl_(
|
||||
extent, GETFEATUREINFO_IMAGE_SIZE,
|
||||
1, sourceProjectionObj || projectionObj, baseParams);
|
||||
extent,
|
||||
GETFEATUREINFO_IMAGE_SIZE,
|
||||
1,
|
||||
sourceProjectionObj || projectionObj,
|
||||
baseParams
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,7 +229,7 @@ class ImageWMS extends ImageSource {
|
||||
'SERVICE': 'WMS',
|
||||
'VERSION': DEFAULT_WMS_VERSION,
|
||||
'REQUEST': 'GetLegendGraphic',
|
||||
'FORMAT': 'image/png'
|
||||
'FORMAT': 'image/png',
|
||||
};
|
||||
|
||||
if (params === undefined || params['LAYER'] === undefined) {
|
||||
@@ -226,7 +242,9 @@ class ImageWMS extends ImageSource {
|
||||
}
|
||||
|
||||
if (resolution !== undefined) {
|
||||
const mpu = this.getProjection() ? this.getProjection().getMetersPerUnit() : 1;
|
||||
const mpu = this.getProjection()
|
||||
? this.getProjection().getMetersPerUnit()
|
||||
: 1;
|
||||
const dpi = 25.4 / 0.28;
|
||||
const inchesPerMeter = 39.37;
|
||||
baseParams['SCALE'] = resolution * mpu * inchesPerMeter * dpi;
|
||||
@@ -255,7 +273,6 @@ class ImageWMS extends ImageSource {
|
||||
* @return {import("../Image.js").default} Single image.
|
||||
*/
|
||||
getImageInternal(extent, resolution, pixelRatio, projection) {
|
||||
|
||||
if (this.url_ === undefined) {
|
||||
return null;
|
||||
}
|
||||
@@ -271,19 +288,29 @@ class ImageWMS extends ImageSource {
|
||||
const center = getCenter(extent);
|
||||
const viewWidth = Math.ceil(getWidth(extent) / imageResolution);
|
||||
const viewHeight = Math.ceil(getHeight(extent) / imageResolution);
|
||||
const viewExtent = getForViewAndSize(center, imageResolution, 0,
|
||||
[viewWidth, viewHeight]);
|
||||
const requestWidth = Math.ceil(this.ratio_ * getWidth(extent) / imageResolution);
|
||||
const requestHeight = Math.ceil(this.ratio_ * getHeight(extent) / imageResolution);
|
||||
const requestExtent = getForViewAndSize(center, imageResolution, 0,
|
||||
[requestWidth, requestHeight]);
|
||||
const viewExtent = getForViewAndSize(center, imageResolution, 0, [
|
||||
viewWidth,
|
||||
viewHeight,
|
||||
]);
|
||||
const requestWidth = Math.ceil(
|
||||
(this.ratio_ * getWidth(extent)) / imageResolution
|
||||
);
|
||||
const requestHeight = Math.ceil(
|
||||
(this.ratio_ * getHeight(extent)) / imageResolution
|
||||
);
|
||||
const requestExtent = getForViewAndSize(center, imageResolution, 0, [
|
||||
requestWidth,
|
||||
requestHeight,
|
||||
]);
|
||||
|
||||
const image = this.image_;
|
||||
if (image &&
|
||||
this.renderedRevision_ == this.getRevision() &&
|
||||
image.getResolution() == resolution &&
|
||||
image.getPixelRatio() == pixelRatio &&
|
||||
containsExtent(image.getExtent(), viewExtent)) {
|
||||
if (
|
||||
image &&
|
||||
this.renderedRevision_ == this.getRevision() &&
|
||||
image.getResolution() == resolution &&
|
||||
image.getPixelRatio() == pixelRatio &&
|
||||
containsExtent(image.getExtent(), viewExtent)
|
||||
) {
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -292,25 +319,38 @@ class ImageWMS extends ImageSource {
|
||||
'VERSION': DEFAULT_WMS_VERSION,
|
||||
'REQUEST': 'GetMap',
|
||||
'FORMAT': 'image/png',
|
||||
'TRANSPARENT': true
|
||||
'TRANSPARENT': true,
|
||||
};
|
||||
assign(params, this.params_);
|
||||
|
||||
this.imageSize_[0] = Math.round(getWidth(requestExtent) / imageResolution);
|
||||
this.imageSize_[1] = Math.round(getHeight(requestExtent) / imageResolution);
|
||||
|
||||
const url = this.getRequestUrl_(requestExtent, this.imageSize_, pixelRatio,
|
||||
projection, params);
|
||||
const url = this.getRequestUrl_(
|
||||
requestExtent,
|
||||
this.imageSize_,
|
||||
pixelRatio,
|
||||
projection,
|
||||
params
|
||||
);
|
||||
|
||||
this.image_ = new ImageWrapper(requestExtent, resolution, pixelRatio,
|
||||
url, this.crossOrigin_, this.imageLoadFunction_);
|
||||
this.image_ = new ImageWrapper(
|
||||
requestExtent,
|
||||
resolution,
|
||||
pixelRatio,
|
||||
url,
|
||||
this.crossOrigin_,
|
||||
this.imageLoadFunction_
|
||||
);
|
||||
|
||||
this.renderedRevision_ = this.getRevision();
|
||||
|
||||
this.image_.addEventListener(EventType.CHANGE, this.handleImageChange.bind(this));
|
||||
this.image_.addEventListener(
|
||||
EventType.CHANGE,
|
||||
this.handleImageChange.bind(this)
|
||||
);
|
||||
|
||||
return this.image_;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -332,7 +372,6 @@ class ImageWMS extends ImageSource {
|
||||
* @private
|
||||
*/
|
||||
getRequestUrl_(extent, size, pixelRatio, projection, params) {
|
||||
|
||||
assert(this.url_ !== undefined, 9); // `url` must be configured or set using `#setUrl()`
|
||||
|
||||
params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode();
|
||||
@@ -433,5 +472,4 @@ class ImageWMS extends ImageSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default ImageWMS;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
import XYZ from './XYZ.js';
|
||||
|
||||
|
||||
/**
|
||||
* The attribution containing a link to the OpenStreetMap Copyright and License
|
||||
* page.
|
||||
@@ -12,10 +11,10 @@ import XYZ from './XYZ.js';
|
||||
* @type {string}
|
||||
* @api
|
||||
*/
|
||||
export const ATTRIBUTION = '© ' +
|
||||
'<a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> ' +
|
||||
'contributors.';
|
||||
|
||||
export const ATTRIBUTION =
|
||||
'© ' +
|
||||
'<a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> ' +
|
||||
'contributors.';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -40,7 +39,6 @@ export const ATTRIBUTION = '© ' +
|
||||
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source for the OpenStreetMap tile server.
|
||||
@@ -51,7 +49,6 @@ class OSM extends XYZ {
|
||||
* @param {Options=} [opt_options] Open Street Map options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
|
||||
let attributions;
|
||||
@@ -61,11 +58,13 @@ class OSM extends XYZ {
|
||||
attributions = [ATTRIBUTION];
|
||||
}
|
||||
|
||||
const crossOrigin = options.crossOrigin !== undefined ?
|
||||
options.crossOrigin : 'anonymous';
|
||||
const crossOrigin =
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : 'anonymous';
|
||||
|
||||
const url = options.url !== undefined ?
|
||||
options.url : 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
const url =
|
||||
options.url !== undefined
|
||||
? options.url
|
||||
: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
|
||||
super({
|
||||
attributions: attributions,
|
||||
@@ -78,11 +77,9 @@ class OSM extends XYZ {
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
url: url,
|
||||
wrapX: options.wrapX,
|
||||
attributionsCollapsible: false
|
||||
attributionsCollapsible: false,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default OSM;
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
/**
|
||||
* @module ol/source/Raster
|
||||
*/
|
||||
import ImageCanvas from '../ImageCanvas.js';
|
||||
import TileQueue from '../TileQueue.js';
|
||||
import {createCanvasContext2D} from '../dom.js';
|
||||
import Event from '../events/Event.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {Processor} from 'pixelworks/lib/index.js';
|
||||
import {equals, getCenter, getHeight, getWidth} from '../extent.js';
|
||||
import ImageCanvas from '../ImageCanvas.js';
|
||||
import ImageLayer from '../layer/Image.js';
|
||||
import TileLayer from '../layer/Tile.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {create as createTransform} from '../transform.js';
|
||||
import ImageSource from './Image.js';
|
||||
import TileSource from './Tile.js';
|
||||
import SourceState from './State.js';
|
||||
import Source from './Source.js';
|
||||
|
||||
import SourceState from './State.js';
|
||||
import TileLayer from '../layer/Tile.js';
|
||||
import TileQueue from '../TileQueue.js';
|
||||
import TileSource from './Tile.js';
|
||||
import {Processor} from 'pixelworks/lib/index.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {createCanvasContext2D} from '../dom.js';
|
||||
import {create as createTransform} from '../transform.js';
|
||||
import {equals, getCenter, getHeight, getWidth} from '../extent.js';
|
||||
|
||||
/**
|
||||
* A function that takes an array of input data, performs some operation, and
|
||||
@@ -36,7 +35,6 @@ import Source from './Source.js';
|
||||
* (Array<number>|ImageData)} Operation
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
@@ -53,20 +51,18 @@ const RasterEventType = {
|
||||
* @event module:ol/source/Raster.RasterSourceEvent#afteroperations
|
||||
* @api
|
||||
*/
|
||||
AFTEROPERATIONS: 'afteroperations'
|
||||
AFTEROPERATIONS: 'afteroperations',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Raster operation type. Supported values are `'pixel'` and `'image'`.
|
||||
* @enum {string}
|
||||
*/
|
||||
const RasterOperationType = {
|
||||
PIXEL: 'pixel',
|
||||
IMAGE: 'image'
|
||||
IMAGE: 'image',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/source/Raster} instances are instances of this
|
||||
@@ -102,9 +98,7 @@ export class RasterSourceEvent extends Event {
|
||||
* @api
|
||||
*/
|
||||
this.data = data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,7 +121,6 @@ export class RasterSourceEvent extends Event {
|
||||
* be called with an array of ImageData objects from input sources.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* A source that transforms data from any number of input sources using an
|
||||
@@ -143,7 +136,7 @@ class RasterSource extends ImageSource {
|
||||
*/
|
||||
constructor(options) {
|
||||
super({
|
||||
projection: null
|
||||
projection: null,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -156,8 +149,10 @@ class RasterSource extends ImageSource {
|
||||
* @private
|
||||
* @type {RasterOperationType}
|
||||
*/
|
||||
this.operationType_ = options.operationType !== undefined ?
|
||||
options.operationType : RasterOperationType.PIXEL;
|
||||
this.operationType_ =
|
||||
options.operationType !== undefined
|
||||
? options.operationType
|
||||
: RasterOperationType.PIXEL;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -180,7 +175,7 @@ class RasterSource extends ImageSource {
|
||||
* @private
|
||||
* @type {import("../TileQueue.js").default}
|
||||
*/
|
||||
this.tileQueue_ = new TileQueue(function() {
|
||||
this.tileQueue_ = new TileQueue(function () {
|
||||
return 1;
|
||||
}, this.changed.bind(this));
|
||||
|
||||
@@ -223,18 +218,25 @@ class RasterSource extends ImageSource {
|
||||
time: Date.now(),
|
||||
usedTiles: {},
|
||||
viewState: /** @type {import("../View.js").State} */ ({
|
||||
rotation: 0
|
||||
rotation: 0,
|
||||
}),
|
||||
viewHints: [],
|
||||
wantedTiles: {},
|
||||
declutterItems: []
|
||||
declutterItems: [],
|
||||
};
|
||||
|
||||
this.setAttributions(function(frameState) {
|
||||
this.setAttributions(function (frameState) {
|
||||
const attributions = [];
|
||||
for (let index = 0, iMax = options.sources.length; index < iMax; ++index) {
|
||||
for (
|
||||
let index = 0, iMax = options.sources.length;
|
||||
index < iMax;
|
||||
++index
|
||||
) {
|
||||
const sourceOrLayer = options.sources[index];
|
||||
const source = sourceOrLayer instanceof Source ? sourceOrLayer : sourceOrLayer.getSource();
|
||||
const source =
|
||||
sourceOrLayer instanceof Source
|
||||
? sourceOrLayer
|
||||
: sourceOrLayer.getSource();
|
||||
const attributionGetter = source.getAttributions();
|
||||
if (typeof attributionGetter === 'function') {
|
||||
const sourceAttribution = attributionGetter(frameState);
|
||||
@@ -247,7 +249,6 @@ class RasterSource extends ImageSource {
|
||||
if (options.operation !== undefined) {
|
||||
this.setOperation(options.operation, options.lib);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,7 +264,7 @@ class RasterSource extends ImageSource {
|
||||
imageOps: this.operationType_ === RasterOperationType.IMAGE,
|
||||
queue: 1,
|
||||
lib: opt_lib,
|
||||
threads: this.threads_
|
||||
threads: this.threads_,
|
||||
});
|
||||
this.changed();
|
||||
}
|
||||
@@ -277,10 +278,15 @@ class RasterSource extends ImageSource {
|
||||
* @private
|
||||
*/
|
||||
updateFrameState_(extent, resolution, projection) {
|
||||
const frameState = /** @type {import("../PluggableMap.js").FrameState} */ (assign(
|
||||
{},
|
||||
this.frameState_
|
||||
));
|
||||
|
||||
const frameState = /** @type {import("../PluggableMap.js").FrameState} */ (assign({}, this.frameState_));
|
||||
|
||||
frameState.viewState = /** @type {import("../View.js").State} */ (assign({}, frameState.viewState));
|
||||
frameState.viewState = /** @type {import("../View.js").State} */ (assign(
|
||||
{},
|
||||
frameState.viewState
|
||||
));
|
||||
|
||||
const center = getCenter(extent);
|
||||
|
||||
@@ -333,12 +339,18 @@ class RasterSource extends ImageSource {
|
||||
if (this.renderedImageCanvas_) {
|
||||
const renderedResolution = this.renderedImageCanvas_.getResolution();
|
||||
const renderedExtent = this.renderedImageCanvas_.getExtent();
|
||||
if (resolution !== renderedResolution || !equals(extent, renderedExtent)) {
|
||||
if (
|
||||
resolution !== renderedResolution ||
|
||||
!equals(extent, renderedExtent)
|
||||
) {
|
||||
this.renderedImageCanvas_ = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.renderedImageCanvas_ || this.getRevision() !== this.renderedRevision_) {
|
||||
if (
|
||||
!this.renderedImageCanvas_ ||
|
||||
this.getRevision() !== this.renderedRevision_
|
||||
) {
|
||||
this.processSources_();
|
||||
}
|
||||
|
||||
@@ -370,8 +382,14 @@ class RasterSource extends ImageSource {
|
||||
}
|
||||
|
||||
const data = {};
|
||||
this.dispatchEvent(new RasterSourceEvent(RasterEventType.BEFOREOPERATIONS, frameState, data));
|
||||
this.worker_.process(imageDatas, data, this.onWorkerComplete_.bind(this, frameState));
|
||||
this.dispatchEvent(
|
||||
new RasterSourceEvent(RasterEventType.BEFOREOPERATIONS, frameState, data)
|
||||
);
|
||||
this.worker_.process(
|
||||
imageDatas,
|
||||
data,
|
||||
this.onWorkerComplete_.bind(this, frameState)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -390,8 +408,10 @@ class RasterSource extends ImageSource {
|
||||
// do nothing if extent or resolution changed
|
||||
const extent = frameState.extent;
|
||||
const resolution = frameState.viewState.resolution;
|
||||
if (resolution !== this.requestedFrameState_.viewState.resolution ||
|
||||
!equals(extent, this.requestedFrameState_.extent)) {
|
||||
if (
|
||||
resolution !== this.requestedFrameState_.viewState.resolution ||
|
||||
!equals(extent, this.requestedFrameState_.extent)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -402,14 +422,21 @@ class RasterSource extends ImageSource {
|
||||
const width = Math.round(getWidth(extent) / resolution);
|
||||
const height = Math.round(getHeight(extent) / resolution);
|
||||
context = createCanvasContext2D(width, height);
|
||||
this.renderedImageCanvas_ = new ImageCanvas(extent, resolution, 1, context.canvas);
|
||||
this.renderedImageCanvas_ = new ImageCanvas(
|
||||
extent,
|
||||
resolution,
|
||||
1,
|
||||
context.canvas
|
||||
);
|
||||
}
|
||||
context.putImageData(output, 0, 0);
|
||||
|
||||
this.changed();
|
||||
this.renderedRevision_ = this.getRevision();
|
||||
|
||||
this.dispatchEvent(new RasterSourceEvent(RasterEventType.AFTEROPERATIONS, frameState, data));
|
||||
this.dispatchEvent(
|
||||
new RasterSourceEvent(RasterEventType.AFTEROPERATIONS, frameState, data)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -420,7 +447,6 @@ class RasterSource extends ImageSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A reusable canvas context.
|
||||
* @type {CanvasRenderingContext2D}
|
||||
@@ -428,7 +454,6 @@ class RasterSource extends ImageSource {
|
||||
*/
|
||||
let sharedContext = null;
|
||||
|
||||
|
||||
/**
|
||||
* Get image data from a layer.
|
||||
* @param {import("../layer/Layer.js").default} layer Layer to render.
|
||||
@@ -473,19 +498,17 @@ function getImageData(layer, frameState) {
|
||||
return sharedContext.getImageData(0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of layer states from a list of layers.
|
||||
* @param {Array<import("../layer/Layer.js").default>} layers Layers.
|
||||
* @return {Array<import("../layer/Layer.js").State>} The layer states.
|
||||
*/
|
||||
function getLayerStatesArray(layers) {
|
||||
return layers.map(function(layer) {
|
||||
return layers.map(function (layer) {
|
||||
return layer.getLayerState();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create layers for all sources.
|
||||
* @param {Array<import("./Source.js").default|import("../layer/Layer.js").default>} sources The sources.
|
||||
@@ -500,7 +523,6 @@ function createLayers(sources) {
|
||||
return layers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a layer for the provided source.
|
||||
* @param {import("./Source.js").default|import("../layer/Layer.js").default} layerOrSource The layer or source.
|
||||
@@ -521,5 +543,4 @@ function createLayer(layerOrSource) {
|
||||
return layer;
|
||||
}
|
||||
|
||||
|
||||
export default RasterSource;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/**
|
||||
* @module ol/source/Source
|
||||
*/
|
||||
import {abstract} from '../util.js';
|
||||
import BaseObject from '../Object.js';
|
||||
import {get as getProjection} from '../proj.js';
|
||||
import SourceState from './State.js';
|
||||
|
||||
import {abstract} from '../util.js';
|
||||
import {get as getProjection} from '../proj.js';
|
||||
|
||||
/**
|
||||
* A function that returns a string or an array of strings representing source
|
||||
@@ -14,7 +13,6 @@ import SourceState from './State.js';
|
||||
* @typedef {function(import("../PluggableMap.js").FrameState): (string|Array<string>)} Attribution
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A type that can be used to provide attribution information for data sources.
|
||||
*
|
||||
@@ -26,7 +24,6 @@ import SourceState from './State.js';
|
||||
* @typedef {string|Array<string>|Attribution} AttributionLike
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {AttributionLike} [attributions]
|
||||
@@ -36,7 +33,6 @@ import SourceState from './State.js';
|
||||
* @property {boolean} [wrapX=false]
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Abstract base class; normally only used for creating subclasses and not
|
||||
@@ -52,7 +48,6 @@ class Source extends BaseObject {
|
||||
* @param {Options} options Source options.
|
||||
*/
|
||||
constructor(options) {
|
||||
|
||||
super();
|
||||
|
||||
/**
|
||||
@@ -71,8 +66,10 @@ class Source extends BaseObject {
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.attributionsCollapsible_ = options.attributionsCollapsible !== undefined ?
|
||||
options.attributionsCollapsible : true;
|
||||
this.attributionsCollapsible_ =
|
||||
options.attributionsCollapsible !== undefined
|
||||
? options.attributionsCollapsible
|
||||
: true;
|
||||
|
||||
/**
|
||||
* This source is currently loading data. Sources that defer loading to the
|
||||
@@ -85,15 +82,14 @@ class Source extends BaseObject {
|
||||
* @private
|
||||
* @type {SourceState}
|
||||
*/
|
||||
this.state_ = options.state !== undefined ?
|
||||
options.state : SourceState.READY;
|
||||
this.state_ =
|
||||
options.state !== undefined ? options.state : SourceState.READY;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.wrapX_ = options.wrapX !== undefined ? options.wrapX : false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,7 +171,6 @@ class Source extends BaseObject {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Turns the attributions option into an attributions function.
|
||||
* @param {AttributionLike|undefined} attributionLike The attribution option.
|
||||
@@ -186,7 +181,7 @@ function adaptAttributions(attributionLike) {
|
||||
return null;
|
||||
}
|
||||
if (Array.isArray(attributionLike)) {
|
||||
return function(frameState) {
|
||||
return function (frameState) {
|
||||
return attributionLike;
|
||||
};
|
||||
}
|
||||
@@ -195,10 +190,9 @@ function adaptAttributions(attributionLike) {
|
||||
return attributionLike;
|
||||
}
|
||||
|
||||
return function(frameState) {
|
||||
return function (frameState) {
|
||||
return [attributionLike];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export default Source;
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
* @module ol/source/Stamen
|
||||
*/
|
||||
|
||||
import {ATTRIBUTION as OSM_ATTRIBUTION} from './OSM.js';
|
||||
import XYZ from './XYZ.js';
|
||||
|
||||
import {ATTRIBUTION as OSM_ATTRIBUTION} from './OSM.js';
|
||||
|
||||
/**
|
||||
* @const
|
||||
@@ -12,82 +11,79 @@ import XYZ from './XYZ.js';
|
||||
*/
|
||||
const ATTRIBUTIONS = [
|
||||
'Map tiles by <a href="https://stamen.com/" target="_blank">Stamen Design</a>, ' +
|
||||
'under <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC BY' +
|
||||
' 3.0</a>.',
|
||||
OSM_ATTRIBUTION
|
||||
'under <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC BY' +
|
||||
' 3.0</a>.',
|
||||
OSM_ATTRIBUTION,
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @type {Object<string, {extension: string, opaque: boolean}>}
|
||||
*/
|
||||
const LayerConfig = {
|
||||
'terrain': {
|
||||
extension: 'jpg',
|
||||
opaque: true
|
||||
opaque: true,
|
||||
},
|
||||
'terrain-background': {
|
||||
extension: 'jpg',
|
||||
opaque: true
|
||||
opaque: true,
|
||||
},
|
||||
'terrain-labels': {
|
||||
extension: 'png',
|
||||
opaque: false
|
||||
opaque: false,
|
||||
},
|
||||
'terrain-lines': {
|
||||
extension: 'png',
|
||||
opaque: false
|
||||
opaque: false,
|
||||
},
|
||||
'toner-background': {
|
||||
extension: 'png',
|
||||
opaque: true
|
||||
opaque: true,
|
||||
},
|
||||
'toner': {
|
||||
extension: 'png',
|
||||
opaque: true
|
||||
opaque: true,
|
||||
},
|
||||
'toner-hybrid': {
|
||||
extension: 'png',
|
||||
opaque: false
|
||||
opaque: false,
|
||||
},
|
||||
'toner-labels': {
|
||||
extension: 'png',
|
||||
opaque: false
|
||||
opaque: false,
|
||||
},
|
||||
'toner-lines': {
|
||||
extension: 'png',
|
||||
opaque: false
|
||||
opaque: false,
|
||||
},
|
||||
'toner-lite': {
|
||||
extension: 'png',
|
||||
opaque: true
|
||||
opaque: true,
|
||||
},
|
||||
'watercolor': {
|
||||
extension: 'jpg',
|
||||
opaque: true
|
||||
}
|
||||
opaque: true,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {Object<string, {minZoom: number, maxZoom: number}>}
|
||||
*/
|
||||
const ProviderConfig = {
|
||||
'terrain': {
|
||||
minZoom: 0,
|
||||
maxZoom: 18
|
||||
maxZoom: 18,
|
||||
},
|
||||
'toner': {
|
||||
minZoom: 0,
|
||||
maxZoom: 20
|
||||
maxZoom: 20,
|
||||
},
|
||||
'watercolor': {
|
||||
minZoom: 0,
|
||||
maxZoom: 18
|
||||
}
|
||||
maxZoom: 18,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
|
||||
@@ -110,7 +106,6 @@ const ProviderConfig = {
|
||||
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source for the Stamen tile server.
|
||||
@@ -127,27 +122,31 @@ class Stamen extends XYZ {
|
||||
|
||||
const layerConfig = LayerConfig[options.layer];
|
||||
|
||||
const url = options.url !== undefined ? options.url :
|
||||
'https://stamen-tiles-{a-d}.a.ssl.fastly.net/' + options.layer +
|
||||
'/{z}/{x}/{y}.' + layerConfig.extension;
|
||||
const url =
|
||||
options.url !== undefined
|
||||
? options.url
|
||||
: 'https://stamen-tiles-{a-d}.a.ssl.fastly.net/' +
|
||||
options.layer +
|
||||
'/{z}/{x}/{y}.' +
|
||||
layerConfig.extension;
|
||||
|
||||
super({
|
||||
attributions: ATTRIBUTIONS,
|
||||
cacheSize: options.cacheSize,
|
||||
crossOrigin: 'anonymous',
|
||||
imageSmoothing: options.imageSmoothing,
|
||||
maxZoom: options.maxZoom != undefined ? options.maxZoom : providerConfig.maxZoom,
|
||||
minZoom: options.minZoom != undefined ? options.minZoom : providerConfig.minZoom,
|
||||
maxZoom:
|
||||
options.maxZoom != undefined ? options.maxZoom : providerConfig.maxZoom,
|
||||
minZoom:
|
||||
options.minZoom != undefined ? options.minZoom : providerConfig.minZoom,
|
||||
opaque: layerConfig.opaque,
|
||||
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
transition: options.transition,
|
||||
url: url,
|
||||
wrapX: options.wrapX
|
||||
wrapX: options.wrapX,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Stamen;
|
||||
|
||||
@@ -10,5 +10,5 @@ export default {
|
||||
UNDEFINED: 'undefined',
|
||||
LOADING: 'loading',
|
||||
READY: 'ready',
|
||||
ERROR: 'error'
|
||||
ERROR: 'error',
|
||||
};
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
/**
|
||||
* @module ol/source/Tile
|
||||
*/
|
||||
import {abstract} from '../util.js';
|
||||
import Event from '../events/Event.js';
|
||||
import Source from './Source.js';
|
||||
import TileCache from '../TileCache.js';
|
||||
import TileState from '../TileState.js';
|
||||
import Event from '../events/Event.js';
|
||||
import {abstract} from '../util.js';
|
||||
import {equivalent} from '../proj.js';
|
||||
import {toSize, scale as scaleSize} from '../size.js';
|
||||
import Source from './Source.js';
|
||||
import {getKeyZXY, withinExtentAndZ} from '../tilecoord.js';
|
||||
import {wrapX, getForProjection as getTileGridForProjection} from '../tilegrid.js';
|
||||
import {
|
||||
getForProjection as getTileGridForProjection,
|
||||
wrapX,
|
||||
} from '../tilegrid.js';
|
||||
import {scale as scaleSize, toSize} from '../size.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -27,7 +30,6 @@ import {wrapX, getForProjection as getTileGridForProjection} from '../tilegrid.j
|
||||
* @property {number} [zDirection=0]
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Abstract base class; normally only used for creating subclasses and not
|
||||
@@ -41,13 +43,12 @@ class TileSource extends Source {
|
||||
* @param {Options} options SourceTile source options.
|
||||
*/
|
||||
constructor(options) {
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
attributionsCollapsible: options.attributionsCollapsible,
|
||||
projection: options.projection,
|
||||
state: options.state,
|
||||
wrapX: options.wrapX
|
||||
wrapX: options.wrapX,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -60,8 +61,8 @@ class TileSource extends Source {
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.tilePixelRatio_ = options.tilePixelRatio !== undefined ?
|
||||
options.tilePixelRatio : 1;
|
||||
this.tilePixelRatio_ =
|
||||
options.tilePixelRatio !== undefined ? options.tilePixelRatio : 1;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
@@ -75,15 +76,18 @@ class TileSource extends Source {
|
||||
toSize(tileGrid.getTileSize(tileGrid.getMinZoom()), tileSize);
|
||||
}
|
||||
const canUseScreen = typeof screen !== 'undefined';
|
||||
const width = canUseScreen ? (screen.availWidth || screen.width) : 1920;
|
||||
const height = canUseScreen ? (screen.availHeight || screen.height) : 1080;
|
||||
const minCacheSize = 4 * Math.ceil(width / tileSize[0]) * Math.ceil(height / tileSize[1]);
|
||||
const width = canUseScreen ? screen.availWidth || screen.width : 1920;
|
||||
const height = canUseScreen ? screen.availHeight || screen.height : 1080;
|
||||
const minCacheSize =
|
||||
4 * Math.ceil(width / tileSize[0]) * Math.ceil(height / tileSize[1]);
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {import("../TileCache.js").default}
|
||||
*/
|
||||
this.tileCache = new TileCache(Math.max(minCacheSize, options.cacheSize || 0));
|
||||
this.tileCache = new TileCache(
|
||||
Math.max(minCacheSize, options.cacheSize || 0)
|
||||
);
|
||||
|
||||
/**
|
||||
* @protected
|
||||
@@ -153,10 +157,12 @@ class TileSource extends Source {
|
||||
tileCoordKey = getKeyZXY(z, x, y);
|
||||
loaded = false;
|
||||
if (tileCache.containsKey(tileCoordKey)) {
|
||||
tile = /** @type {!import("../Tile.js").default} */ (tileCache.get(tileCoordKey));
|
||||
tile = /** @type {!import("../Tile.js").default} */ (tileCache.get(
|
||||
tileCoordKey
|
||||
));
|
||||
loaded = tile.getState() === TileState.LOADED;
|
||||
if (loaded) {
|
||||
loaded = (callback(tile) !== false);
|
||||
loaded = callback(tile) !== false;
|
||||
}
|
||||
}
|
||||
if (!loaded) {
|
||||
@@ -304,8 +310,8 @@ class TileSource extends Source {
|
||||
* null if no tile URL should be created for the passed `tileCoord`.
|
||||
*/
|
||||
getTileCoordForTileUrlFunction(tileCoord, opt_projection) {
|
||||
const projection = opt_projection !== undefined ?
|
||||
opt_projection : this.getProjection();
|
||||
const projection =
|
||||
opt_projection !== undefined ? opt_projection : this.getProjection();
|
||||
const tileGrid = this.getTileGridForProjection(projection);
|
||||
if (this.getWrapX() && projection.isGlobal()) {
|
||||
tileCoord = wrapX(tileGrid, tileCoord, projection);
|
||||
@@ -335,10 +341,8 @@ class TileSource extends Source {
|
||||
* @param {import("../proj/Projection.js").default} projection Projection.
|
||||
*/
|
||||
useTile(z, x, y, projection) {}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/source/Tile~TileSource} instances are instances of this
|
||||
@@ -350,7 +354,6 @@ export class TileSourceEvent extends Event {
|
||||
* @param {import("../Tile.js").default} tile The tile.
|
||||
*/
|
||||
constructor(type, tile) {
|
||||
|
||||
super(type);
|
||||
|
||||
/**
|
||||
@@ -359,9 +362,7 @@ export class TileSourceEvent extends Event {
|
||||
* @api
|
||||
*/
|
||||
this.tile = tile;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default TileSource;
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
* @module ol/source/TileArcGISRest
|
||||
*/
|
||||
|
||||
import TileImage from './TileImage.js';
|
||||
import {appendParams} from '../uri.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {createEmpty} from '../extent.js';
|
||||
import {modulo} from '../math.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {toSize, scale as scaleSize} from '../size.js';
|
||||
import TileImage from './TileImage.js';
|
||||
import {scale as scaleSize, toSize} from '../size.js';
|
||||
import {hash as tileCoordHash} from '../tilecoord.js';
|
||||
import {appendParams} from '../uri.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -51,7 +51,6 @@ import {appendParams} from '../uri.js';
|
||||
* Service supports multiple urls for export requests.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source for tile data from ArcGIS Rest services. Map and Image
|
||||
@@ -66,7 +65,6 @@ class TileArcGISRest extends TileImage {
|
||||
* @param {Options=} opt_options Tile ArcGIS Rest options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
super({
|
||||
@@ -82,7 +80,7 @@ class TileArcGISRest extends TileImage {
|
||||
url: options.url,
|
||||
urls: options.urls,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true,
|
||||
transition: options.transition
|
||||
transition: options.transition,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -139,8 +137,14 @@ class TileArcGISRest extends TileImage {
|
||||
* @return {string|undefined} Request URL.
|
||||
* @private
|
||||
*/
|
||||
getRequestUrl_(tileCoord, tileSize, tileExtent, pixelRatio, projection, params) {
|
||||
|
||||
getRequestUrl_(
|
||||
tileCoord,
|
||||
tileSize,
|
||||
tileExtent,
|
||||
pixelRatio,
|
||||
projection,
|
||||
params
|
||||
) {
|
||||
const urls = this.urls;
|
||||
if (!urls) {
|
||||
return undefined;
|
||||
@@ -199,7 +203,6 @@ class TileArcGISRest extends TileImage {
|
||||
* @this {TileArcGISRest}
|
||||
*/
|
||||
function tileUrlFunction(tileCoord, pixelRatio, projection) {
|
||||
|
||||
let tileGrid = this.getTileGrid();
|
||||
if (!tileGrid) {
|
||||
tileGrid = this.getTileGridForProjection(projection);
|
||||
@@ -213,10 +216,8 @@ function tileUrlFunction(tileCoord, pixelRatio, projection) {
|
||||
pixelRatio = 1;
|
||||
}
|
||||
|
||||
const tileExtent = tileGrid.getTileCoordExtent(
|
||||
tileCoord, this.tmpExtent_);
|
||||
let tileSize = toSize(
|
||||
tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
|
||||
const tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
|
||||
let tileSize = toSize(tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
|
||||
|
||||
if (pixelRatio != 1) {
|
||||
tileSize = scaleSize(tileSize, pixelRatio, this.tmpSize);
|
||||
@@ -226,13 +227,18 @@ function tileUrlFunction(tileCoord, pixelRatio, projection) {
|
||||
const baseParams = {
|
||||
'F': 'image',
|
||||
'FORMAT': 'PNG32',
|
||||
'TRANSPARENT': true
|
||||
'TRANSPARENT': true,
|
||||
};
|
||||
assign(baseParams, this.params_);
|
||||
|
||||
return this.getRequestUrl_(tileCoord, tileSize, tileExtent,
|
||||
pixelRatio, projection, baseParams);
|
||||
return this.getRequestUrl_(
|
||||
tileCoord,
|
||||
tileSize,
|
||||
tileExtent,
|
||||
pixelRatio,
|
||||
projection,
|
||||
baseParams
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export default TileArcGISRest;
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
|
||||
import Tile from '../Tile.js';
|
||||
import TileState from '../TileState.js';
|
||||
import {createCanvasContext2D} from '../dom.js';
|
||||
import {toSize} from '../size.js';
|
||||
import XYZ from './XYZ.js';
|
||||
import {createCanvasContext2D} from '../dom.js';
|
||||
import {getKeyZXY} from '../tilecoord.js';
|
||||
|
||||
import {toSize} from '../size.js';
|
||||
|
||||
class LabeledTile extends Tile {
|
||||
/**
|
||||
@@ -17,33 +16,31 @@ class LabeledTile extends Tile {
|
||||
* @param {string} text Text.
|
||||
*/
|
||||
constructor(tileCoord, tileSize, text) {
|
||||
|
||||
super(tileCoord, TileState.LOADED);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../size.js").Size}
|
||||
*/
|
||||
* @private
|
||||
* @type {import("../size.js").Size}
|
||||
*/
|
||||
this.tileSize_ = tileSize;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.text_ = text;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvas_ = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the image element for this tile.
|
||||
* @return {HTMLCanvasElement} Image.
|
||||
*/
|
||||
* Get the image element for this tile.
|
||||
* @return {HTMLCanvasElement} Image.
|
||||
*/
|
||||
getImage() {
|
||||
if (this.canvas_) {
|
||||
return this.canvas_;
|
||||
@@ -60,8 +57,18 @@ class LabeledTile extends Tile {
|
||||
context.textBaseline = 'middle';
|
||||
context.font = '24px sans-serif';
|
||||
context.lineWidth = 4;
|
||||
context.strokeText(this.text_, tileSize[0] / 2, tileSize[1] / 2, tileSize[0]);
|
||||
context.fillText(this.text_, tileSize[0] / 2, tileSize[1] / 2, tileSize[0]);
|
||||
context.strokeText(
|
||||
this.text_,
|
||||
tileSize[0] / 2,
|
||||
tileSize[1] / 2,
|
||||
tileSize[0]
|
||||
);
|
||||
context.fillText(
|
||||
this.text_,
|
||||
tileSize[0] / 2,
|
||||
tileSize[1] / 2,
|
||||
tileSize[0]
|
||||
);
|
||||
|
||||
this.canvas_ = context.canvas;
|
||||
return context.canvas;
|
||||
@@ -71,7 +78,6 @@ class LabeledTile extends Tile {
|
||||
load() {}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Optional projection.
|
||||
@@ -84,7 +90,6 @@ class LabeledTile extends Tile {
|
||||
* nearest higher resolution will be used.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* A pseudo tile source, which does not fetch tiles from a server, but renders
|
||||
@@ -109,9 +114,8 @@ class TileDebug extends XYZ {
|
||||
projection: options.projection,
|
||||
tileGrid: options.tileGrid,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true,
|
||||
zDirection: options.zDirection
|
||||
zDirection: options.zDirection,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +134,13 @@ class TileDebug extends XYZ {
|
||||
const textTileCoord = this.getTileCoordForTileUrlFunction(tileCoord);
|
||||
let text;
|
||||
if (textTileCoord) {
|
||||
text = 'z:' + textTileCoord[0] + ' x:' + textTileCoord[1] + ' y:' + textTileCoord[2];
|
||||
text =
|
||||
'z:' +
|
||||
textTileCoord[0] +
|
||||
' x:' +
|
||||
textTileCoord[1] +
|
||||
' y:' +
|
||||
textTileCoord[2];
|
||||
} else {
|
||||
text = 'none';
|
||||
}
|
||||
@@ -141,5 +151,4 @@ class TileDebug extends XYZ {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default TileDebug;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* @enum {string}
|
||||
*/
|
||||
export default {
|
||||
|
||||
/**
|
||||
* Triggered when a tile starts loading.
|
||||
* @event module:ol/source/Tile.TileSourceEvent#tileloadstart
|
||||
@@ -27,6 +26,5 @@ export default {
|
||||
* @event module:ol/source/Tile.TileSourceEvent#tileloaderror
|
||||
* @api
|
||||
*/
|
||||
TILELOADERROR: 'tileloaderror'
|
||||
|
||||
TILELOADERROR: 'tileloaderror',
|
||||
};
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/**
|
||||
* @module ol/source/TileImage
|
||||
*/
|
||||
import {ENABLE_RASTER_REPROJECTION} from '../reproj/common.js';
|
||||
import {getUid} from '../util.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import ImageTile from '../ImageTile.js';
|
||||
import ReprojTile from '../reproj/Tile.js';
|
||||
import TileCache from '../TileCache.js';
|
||||
import TileState from '../TileState.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {equivalent, get as getProjection} from '../proj.js';
|
||||
import ReprojTile from '../reproj/Tile.js';
|
||||
import UrlTile from './UrlTile.js';
|
||||
import {ENABLE_RASTER_REPROJECTION} from '../reproj/common.js';
|
||||
import {IMAGE_SMOOTHING_DISABLED} from './common.js';
|
||||
import {equivalent, get as getProjection} from '../proj.js';
|
||||
import {getKey, getKeyZXY} from '../tilecoord.js';
|
||||
import {getForProjection as getTileGridForProjection} from '../tilegrid.js';
|
||||
import {getUid} from '../util.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -59,7 +59,6 @@ import {getForProjection as getTileGridForProjection} from '../tilegrid.js';
|
||||
* will be used. If -1, the nearest higher resolution will be used.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Base class for sources providing images divided into a tile grid.
|
||||
@@ -72,7 +71,6 @@ class TileImage extends UrlTile {
|
||||
* @param {!Options} options Image tile options.
|
||||
*/
|
||||
constructor(options) {
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
cacheSize: options.cacheSize,
|
||||
@@ -80,8 +78,9 @@ class TileImage extends UrlTile {
|
||||
projection: options.projection,
|
||||
state: options.state,
|
||||
tileGrid: options.tileGrid,
|
||||
tileLoadFunction: options.tileLoadFunction ?
|
||||
options.tileLoadFunction : defaultTileLoadFunction,
|
||||
tileLoadFunction: options.tileLoadFunction
|
||||
? options.tileLoadFunction
|
||||
: defaultTileLoadFunction,
|
||||
tilePixelRatio: options.tilePixelRatio,
|
||||
tileUrlFunction: options.tileUrlFunction,
|
||||
url: options.url,
|
||||
@@ -90,7 +89,7 @@ class TileImage extends UrlTile {
|
||||
transition: options.transition,
|
||||
key: options.key,
|
||||
attributionsCollapsible: options.attributionsCollapsible,
|
||||
zDirection: options.zDirection
|
||||
zDirection: options.zDirection,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -98,14 +97,14 @@ class TileImage extends UrlTile {
|
||||
* @type {?string}
|
||||
*/
|
||||
this.crossOrigin =
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
options.crossOrigin !== undefined ? options.crossOrigin : null;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {typeof ImageTile}
|
||||
*/
|
||||
this.tileClass = options.tileClass !== undefined ?
|
||||
options.tileClass : ImageTile;
|
||||
this.tileClass =
|
||||
options.tileClass !== undefined ? options.tileClass : ImageTile;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
@@ -129,8 +128,8 @@ class TileImage extends UrlTile {
|
||||
* @private
|
||||
* @type {object|undefined}
|
||||
*/
|
||||
this.contextOptions_ = options.imageSmoothing === false ?
|
||||
IMAGE_SMOOTHING_DISABLED : undefined;
|
||||
this.contextOptions_ =
|
||||
options.imageSmoothing === false ? IMAGE_SMOOTHING_DISABLED : undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -169,7 +168,9 @@ class TileImage extends UrlTile {
|
||||
}
|
||||
const usedTileCache = this.getTileCacheForProjection(projection);
|
||||
|
||||
this.tileCache.expireCache(this.tileCache == usedTileCache ? usedTiles : {});
|
||||
this.tileCache.expireCache(
|
||||
this.tileCache == usedTileCache ? usedTiles : {}
|
||||
);
|
||||
for (const id in this.tileCacheForProjection) {
|
||||
const tileCache = this.tileCacheForProjection[id];
|
||||
tileCache.expireCache(tileCache == usedTileCache ? usedTiles : {});
|
||||
@@ -188,8 +189,12 @@ class TileImage extends UrlTile {
|
||||
* @return {number} Gutter.
|
||||
*/
|
||||
getGutterForProjection(projection) {
|
||||
if (ENABLE_RASTER_REPROJECTION &&
|
||||
this.getProjection() && projection && !equivalent(this.getProjection(), projection)) {
|
||||
if (
|
||||
ENABLE_RASTER_REPROJECTION &&
|
||||
this.getProjection() &&
|
||||
projection &&
|
||||
!equivalent(this.getProjection(), projection)
|
||||
) {
|
||||
return 0;
|
||||
} else {
|
||||
return this.getGutter();
|
||||
@@ -208,8 +213,12 @@ class TileImage extends UrlTile {
|
||||
* @return {boolean} Opaque.
|
||||
*/
|
||||
getOpaque(projection) {
|
||||
if (ENABLE_RASTER_REPROJECTION &&
|
||||
this.getProjection() && projection && !equivalent(this.getProjection(), projection)) {
|
||||
if (
|
||||
ENABLE_RASTER_REPROJECTION &&
|
||||
this.getProjection() &&
|
||||
projection &&
|
||||
!equivalent(this.getProjection(), projection)
|
||||
) {
|
||||
return false;
|
||||
} else {
|
||||
return super.getOpaque(projection);
|
||||
@@ -230,7 +239,9 @@ class TileImage extends UrlTile {
|
||||
} else {
|
||||
const projKey = getUid(projection);
|
||||
if (!(projKey in this.tileGridForProjection)) {
|
||||
this.tileGridForProjection[projKey] = getTileGridForProjection(projection);
|
||||
this.tileGridForProjection[projKey] = getTileGridForProjection(
|
||||
projection
|
||||
);
|
||||
}
|
||||
return this.tileGridForProjection[projKey];
|
||||
}
|
||||
@@ -244,12 +255,15 @@ class TileImage extends UrlTile {
|
||||
if (!ENABLE_RASTER_REPROJECTION) {
|
||||
return super.getTileCacheForProjection(projection);
|
||||
}
|
||||
const thisProj = this.getProjection(); if (!thisProj || equivalent(thisProj, projection)) {
|
||||
const thisProj = this.getProjection();
|
||||
if (!thisProj || equivalent(thisProj, projection)) {
|
||||
return this.tileCache;
|
||||
} else {
|
||||
const projKey = getUid(projection);
|
||||
if (!(projKey in this.tileCacheForProjection)) {
|
||||
this.tileCacheForProjection[projKey] = new TileCache(this.tileCache.highWaterMark);
|
||||
this.tileCacheForProjection[projKey] = new TileCache(
|
||||
this.tileCache.highWaterMark
|
||||
);
|
||||
}
|
||||
return this.tileCacheForProjection[projKey];
|
||||
}
|
||||
@@ -268,16 +282,20 @@ class TileImage extends UrlTile {
|
||||
createTile_(z, x, y, pixelRatio, projection, key) {
|
||||
const tileCoord = [z, x, y];
|
||||
const urlTileCoord = this.getTileCoordForTileUrlFunction(
|
||||
tileCoord, projection);
|
||||
const tileUrl = urlTileCoord ?
|
||||
this.tileUrlFunction(urlTileCoord, pixelRatio, projection) : undefined;
|
||||
tileCoord,
|
||||
projection
|
||||
);
|
||||
const tileUrl = urlTileCoord
|
||||
? this.tileUrlFunction(urlTileCoord, pixelRatio, projection)
|
||||
: undefined;
|
||||
const tile = new this.tileClass(
|
||||
tileCoord,
|
||||
tileUrl !== undefined ? TileState.IDLE : TileState.EMPTY,
|
||||
tileUrl !== undefined ? tileUrl : '',
|
||||
this.crossOrigin,
|
||||
this.tileLoadFunction,
|
||||
this.tileOptions);
|
||||
this.tileOptions
|
||||
);
|
||||
tile.key = key;
|
||||
tile.addEventListener(EventType.CHANGE, this.handleTileChange.bind(this));
|
||||
return tile;
|
||||
@@ -293,9 +311,19 @@ class TileImage extends UrlTile {
|
||||
*/
|
||||
getTile(z, x, y, pixelRatio, projection) {
|
||||
const sourceProjection = this.getProjection();
|
||||
if (!ENABLE_RASTER_REPROJECTION ||
|
||||
!sourceProjection || !projection || equivalent(sourceProjection, projection)) {
|
||||
return this.getTileInternal(z, x, y, pixelRatio, sourceProjection || projection);
|
||||
if (
|
||||
!ENABLE_RASTER_REPROJECTION ||
|
||||
!sourceProjection ||
|
||||
!projection ||
|
||||
equivalent(sourceProjection, projection)
|
||||
) {
|
||||
return this.getTileInternal(
|
||||
z,
|
||||
x,
|
||||
y,
|
||||
pixelRatio,
|
||||
sourceProjection || projection
|
||||
);
|
||||
} else {
|
||||
const cache = this.getTileCacheForProjection(projection);
|
||||
const tileCoord = [z, x, y];
|
||||
@@ -310,17 +338,26 @@ class TileImage extends UrlTile {
|
||||
} else {
|
||||
const sourceTileGrid = this.getTileGridForProjection(sourceProjection);
|
||||
const targetTileGrid = this.getTileGridForProjection(projection);
|
||||
const wrappedTileCoord =
|
||||
this.getTileCoordForTileUrlFunction(tileCoord, projection);
|
||||
const wrappedTileCoord = this.getTileCoordForTileUrlFunction(
|
||||
tileCoord,
|
||||
projection
|
||||
);
|
||||
const newTile = new ReprojTile(
|
||||
sourceProjection, sourceTileGrid,
|
||||
projection, targetTileGrid,
|
||||
tileCoord, wrappedTileCoord, this.getTilePixelRatio(pixelRatio),
|
||||
sourceProjection,
|
||||
sourceTileGrid,
|
||||
projection,
|
||||
targetTileGrid,
|
||||
tileCoord,
|
||||
wrappedTileCoord,
|
||||
this.getTilePixelRatio(pixelRatio),
|
||||
this.getGutter(),
|
||||
function(z, x, y, pixelRatio) {
|
||||
function (z, x, y, pixelRatio) {
|
||||
return this.getTileInternal(z, x, y, pixelRatio, sourceProjection);
|
||||
}.bind(this), this.reprojectionErrorThreshold_,
|
||||
this.renderReprojectionEdges_, this.contextOptions_);
|
||||
}.bind(this),
|
||||
this.reprojectionErrorThreshold_,
|
||||
this.renderReprojectionEdges_,
|
||||
this.contextOptions_
|
||||
);
|
||||
newTile.key = key;
|
||||
|
||||
if (tile) {
|
||||
@@ -380,8 +417,10 @@ class TileImage extends UrlTile {
|
||||
* @api
|
||||
*/
|
||||
setRenderReprojectionEdges(render) {
|
||||
if (!ENABLE_RASTER_REPROJECTION ||
|
||||
this.renderReprojectionEdges_ == render) {
|
||||
if (
|
||||
!ENABLE_RASTER_REPROJECTION ||
|
||||
this.renderReprojectionEdges_ == render
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.renderReprojectionEdges_ = render;
|
||||
@@ -416,7 +455,6 @@ class TileImage extends UrlTile {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {ImageTile} imageTile Image tile.
|
||||
* @param {string} src Source.
|
||||
|
||||
@@ -7,16 +7,14 @@
|
||||
* See https://mapbox.com/developers/api/.
|
||||
*/
|
||||
|
||||
|
||||
import {createFromTemplates} from '../tileurlfunction.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import {applyTransform, intersects} from '../extent.js';
|
||||
import {jsonp as requestJSONP} from '../net.js';
|
||||
import {get as getProjection, getTransformFromProjections} from '../proj.js';
|
||||
import SourceState from './State.js';
|
||||
import TileImage from './TileImage.js';
|
||||
import {applyTransform, intersects} from '../extent.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import {createFromTemplates} from '../tileurlfunction.js';
|
||||
import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
||||
|
||||
import {get as getProjection, getTransformFromProjections} from '../proj.js';
|
||||
import {jsonp as requestJSONP} from '../net.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Config
|
||||
@@ -35,7 +33,6 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
||||
* @property {Array<number>} [center] Optional center.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
|
||||
@@ -64,7 +61,6 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
||||
* To disable the opacity transition, pass `transition: 0`.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source for tile data in TileJSON format.
|
||||
@@ -85,7 +81,7 @@ class TileJSON extends TileImage {
|
||||
state: SourceState.LOADING,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true,
|
||||
transition: options.transition
|
||||
transition: options.transition,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -100,11 +96,13 @@ class TileJSON extends TileImage {
|
||||
*/
|
||||
this.tileSize_ = options.tileSize;
|
||||
|
||||
|
||||
if (options.url) {
|
||||
if (options.jsonp) {
|
||||
requestJSONP(options.url, this.handleTileJSONResponse.bind(this),
|
||||
this.handleTileJSONError.bind(this));
|
||||
requestJSONP(
|
||||
options.url,
|
||||
this.handleTileJSONResponse.bind(this),
|
||||
this.handleTileJSONError.bind(this)
|
||||
);
|
||||
} else {
|
||||
const client = new XMLHttpRequest();
|
||||
client.addEventListener('load', this.onXHRLoad_.bind(this));
|
||||
@@ -117,7 +115,6 @@ class TileJSON extends TileImage {
|
||||
} else {
|
||||
assert(false, 51); // Either `url` or `tileJSON` options must be provided
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,10 +124,10 @@ class TileJSON extends TileImage {
|
||||
onXHRLoad_(event) {
|
||||
const client = /** @type {XMLHttpRequest} */ (event.target);
|
||||
// status will be 0 for file:// urls
|
||||
if (!client.status || client.status >= 200 && client.status < 300) {
|
||||
if (!client.status || (client.status >= 200 && client.status < 300)) {
|
||||
let response;
|
||||
try {
|
||||
response = /** @type {TileJSON} */(JSON.parse(client.responseText));
|
||||
response = /** @type {TileJSON} */ (JSON.parse(client.responseText));
|
||||
} catch (err) {
|
||||
this.handleTileJSONError();
|
||||
return;
|
||||
@@ -162,14 +159,15 @@ class TileJSON extends TileImage {
|
||||
* @param {Config} tileJSON Tile JSON.
|
||||
*/
|
||||
handleTileJSONResponse(tileJSON) {
|
||||
|
||||
const epsg4326Projection = getProjection('EPSG:4326');
|
||||
|
||||
const sourceProjection = this.getProjection();
|
||||
let extent;
|
||||
if (tileJSON['bounds'] !== undefined) {
|
||||
const transform = getTransformFromProjections(
|
||||
epsg4326Projection, sourceProjection);
|
||||
epsg4326Projection,
|
||||
sourceProjection
|
||||
);
|
||||
extent = applyTransform(tileJSON['bounds'], transform);
|
||||
}
|
||||
|
||||
@@ -179,27 +177,25 @@ class TileJSON extends TileImage {
|
||||
extent: extentFromProjection(sourceProjection),
|
||||
maxZoom: maxZoom,
|
||||
minZoom: minZoom,
|
||||
tileSize: this.tileSize_
|
||||
tileSize: this.tileSize_,
|
||||
});
|
||||
this.tileGrid = tileGrid;
|
||||
|
||||
this.tileUrlFunction = createFromTemplates(tileJSON['tiles'], tileGrid);
|
||||
|
||||
if (tileJSON['attribution'] !== undefined && !this.getAttributions()) {
|
||||
const attributionExtent = extent !== undefined ?
|
||||
extent : epsg4326Projection.getExtent();
|
||||
const attributionExtent =
|
||||
extent !== undefined ? extent : epsg4326Projection.getExtent();
|
||||
|
||||
this.setAttributions(function(frameState) {
|
||||
this.setAttributions(function (frameState) {
|
||||
if (intersects(attributionExtent, frameState.extent)) {
|
||||
return [tileJSON['attribution']];
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
}
|
||||
this.tileJSON_ = tileJSON;
|
||||
this.setState(SourceState.READY);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,5 +206,4 @@ class TileJSON extends TileImage {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default TileJSON;
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
|
||||
import {DEFAULT_WMS_VERSION} from './common.js';
|
||||
|
||||
import {assert} from '../asserts.js';
|
||||
import {buffer, createEmpty} from '../extent.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {modulo} from '../math.js';
|
||||
import {get as getProjection, transform, transformExtent} from '../proj.js';
|
||||
import {calculateSourceResolution} from '../reproj.js';
|
||||
import {toSize, buffer as bufferSize, scale as scaleSize} from '../size.js';
|
||||
import TileImage from './TileImage.js';
|
||||
import WMSServerType from './WMSServerType.js';
|
||||
import {hash as tileCoordHash} from '../tilecoord.js';
|
||||
import {compareVersions} from '../string.js';
|
||||
import {appendParams} from '../uri.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {buffer, createEmpty} from '../extent.js';
|
||||
import {buffer as bufferSize, scale as scaleSize, toSize} from '../size.js';
|
||||
import {calculateSourceResolution} from '../reproj.js';
|
||||
import {compareVersions} from '../string.js';
|
||||
import {get as getProjection, transform, transformExtent} from '../proj.js';
|
||||
import {modulo} from '../math.js';
|
||||
import {hash as tileCoordHash} from '../tilecoord.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -70,7 +70,6 @@ import {appendParams} from '../uri.js';
|
||||
* To disable the opacity transition, pass `transition: 0`.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source for tile data from WMS servers.
|
||||
@@ -81,7 +80,6 @@ class TileWMS extends TileImage {
|
||||
* @param {Options=} [opt_options] Tile WMS options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : /** @type {Options} */ ({});
|
||||
|
||||
const params = options.params || {};
|
||||
@@ -103,7 +101,7 @@ class TileWMS extends TileImage {
|
||||
url: options.url,
|
||||
urls: options.urls,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true,
|
||||
transition: options.transition
|
||||
transition: options.transition,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -144,7 +142,6 @@ class TileWMS extends TileImage {
|
||||
|
||||
this.updateV13_();
|
||||
this.setKey(this.getKeyForParams_());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +178,6 @@ class TileWMS extends TileImage {
|
||||
let tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
|
||||
let tileSize = toSize(tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
|
||||
|
||||
|
||||
const gutter = this.gutter_;
|
||||
if (gutter !== 0) {
|
||||
tileSize = bufferSize(tileSize, gutter, this.tmpSize);
|
||||
@@ -189,8 +185,17 @@ class TileWMS extends TileImage {
|
||||
}
|
||||
|
||||
if (sourceProjectionObj && sourceProjectionObj !== projectionObj) {
|
||||
tileResolution = calculateSourceResolution(sourceProjectionObj, projectionObj, coordinate, tileResolution);
|
||||
tileExtent = transformExtent(tileExtent, projectionObj, sourceProjectionObj);
|
||||
tileResolution = calculateSourceResolution(
|
||||
sourceProjectionObj,
|
||||
projectionObj,
|
||||
coordinate,
|
||||
tileResolution
|
||||
);
|
||||
tileExtent = transformExtent(
|
||||
tileExtent,
|
||||
projectionObj,
|
||||
sourceProjectionObj
|
||||
);
|
||||
coordinate = transform(coordinate, projectionObj, sourceProjectionObj);
|
||||
}
|
||||
|
||||
@@ -200,7 +205,7 @@ class TileWMS extends TileImage {
|
||||
'REQUEST': 'GetFeatureInfo',
|
||||
'FORMAT': 'image/png',
|
||||
'TRANSPARENT': true,
|
||||
'QUERY_LAYERS': this.params_['LAYERS']
|
||||
'QUERY_LAYERS': this.params_['LAYERS'],
|
||||
};
|
||||
assign(baseParams, this.params_, params);
|
||||
|
||||
@@ -210,8 +215,14 @@ class TileWMS extends TileImage {
|
||||
baseParams[this.v13_ ? 'I' : 'X'] = x;
|
||||
baseParams[this.v13_ ? 'J' : 'Y'] = y;
|
||||
|
||||
return this.getRequestUrl_(tileCoord, tileSize, tileExtent,
|
||||
1, sourceProjectionObj || projectionObj, baseParams);
|
||||
return this.getRequestUrl_(
|
||||
tileCoord,
|
||||
tileSize,
|
||||
tileExtent,
|
||||
1,
|
||||
sourceProjectionObj || projectionObj,
|
||||
baseParams
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -237,7 +248,7 @@ class TileWMS extends TileImage {
|
||||
'SERVICE': 'WMS',
|
||||
'VERSION': DEFAULT_WMS_VERSION,
|
||||
'REQUEST': 'GetLegendGraphic',
|
||||
'FORMAT': 'image/png'
|
||||
'FORMAT': 'image/png',
|
||||
};
|
||||
|
||||
if (params === undefined || params['LAYER'] === undefined) {
|
||||
@@ -250,7 +261,9 @@ class TileWMS extends TileImage {
|
||||
}
|
||||
|
||||
if (resolution !== undefined) {
|
||||
const mpu = this.getProjection() ? this.getProjection().getMetersPerUnit() : 1;
|
||||
const mpu = this.getProjection()
|
||||
? this.getProjection().getMetersPerUnit()
|
||||
: 1;
|
||||
const dpi = 25.4 / 0.28;
|
||||
const inchesPerMeter = 39.37;
|
||||
baseParams['SCALE'] = resolution * mpu * inchesPerMeter * dpi;
|
||||
@@ -288,8 +301,14 @@ class TileWMS extends TileImage {
|
||||
* @return {string|undefined} Request URL.
|
||||
* @private
|
||||
*/
|
||||
getRequestUrl_(tileCoord, tileSize, tileExtent, pixelRatio, projection, params) {
|
||||
|
||||
getRequestUrl_(
|
||||
tileCoord,
|
||||
tileSize,
|
||||
tileExtent,
|
||||
pixelRatio,
|
||||
projection,
|
||||
params
|
||||
) {
|
||||
const urls = this.urls;
|
||||
if (!urls) {
|
||||
return undefined;
|
||||
@@ -356,7 +375,7 @@ class TileWMS extends TileImage {
|
||||
* @return {number} Tile pixel ratio.
|
||||
*/
|
||||
getTilePixelRatio(pixelRatio) {
|
||||
return (!this.hidpi_ || this.serverType_ === undefined) ? 1 : pixelRatio;
|
||||
return !this.hidpi_ || this.serverType_ === undefined ? 1 : pixelRatio;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -400,7 +419,6 @@ class TileWMS extends TileImage {
|
||||
* @this {TileWMS}
|
||||
*/
|
||||
function tileUrlFunction(tileCoord, pixelRatio, projection) {
|
||||
|
||||
let tileGrid = this.getTileGrid();
|
||||
if (!tileGrid) {
|
||||
tileGrid = this.getTileGridForProjection(projection);
|
||||
@@ -416,8 +434,7 @@ function tileUrlFunction(tileCoord, pixelRatio, projection) {
|
||||
|
||||
const tileResolution = tileGrid.getResolution(tileCoord[0]);
|
||||
let tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
|
||||
let tileSize = toSize(
|
||||
tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
|
||||
let tileSize = toSize(tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
|
||||
|
||||
const gutter = this.gutter_;
|
||||
if (gutter !== 0) {
|
||||
@@ -434,13 +451,18 @@ function tileUrlFunction(tileCoord, pixelRatio, projection) {
|
||||
'VERSION': DEFAULT_WMS_VERSION,
|
||||
'REQUEST': 'GetMap',
|
||||
'FORMAT': 'image/png',
|
||||
'TRANSPARENT': true
|
||||
'TRANSPARENT': true,
|
||||
};
|
||||
assign(baseParams, this.params_);
|
||||
|
||||
return this.getRequestUrl_(tileCoord, tileSize, tileExtent,
|
||||
pixelRatio, projection, baseParams);
|
||||
return this.getRequestUrl_(
|
||||
tileCoord,
|
||||
tileSize,
|
||||
tileExtent,
|
||||
pixelRatio,
|
||||
projection,
|
||||
baseParams
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export default TileWMS;
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
* @module ol/source/UTFGrid
|
||||
*/
|
||||
|
||||
import Tile from '../Tile.js';
|
||||
import TileState from '../TileState.js';
|
||||
import {createFromTemplates, nullTileUrlFunction} from '../tileurlfunction.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import {listenOnce} from '../events.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {applyTransform, intersects} from '../extent.js';
|
||||
import {jsonp as requestJSONP} from '../net.js';
|
||||
import {get as getProjection, getTransformFromProjections} from '../proj.js';
|
||||
import SourceState from './State.js';
|
||||
import Tile from '../Tile.js';
|
||||
import TileSource from './Tile.js';
|
||||
import {getKeyZXY} from '../tilecoord.js';
|
||||
import TileState from '../TileState.js';
|
||||
import {applyTransform, intersects} from '../extent.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import {createFromTemplates, nullTileUrlFunction} from '../tileurlfunction.js';
|
||||
import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
||||
import {getKeyZXY} from '../tilecoord.js';
|
||||
import {get as getProjection, getTransformFromProjections} from '../proj.js';
|
||||
import {listenOnce} from '../events.js';
|
||||
import {jsonp as requestJSONP} from '../net.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} UTFGridJSON
|
||||
@@ -23,9 +23,7 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
||||
* @property {Object<string, Object>} [data] Optional data.
|
||||
*/
|
||||
|
||||
|
||||
export class CustomTile extends Tile {
|
||||
|
||||
/**
|
||||
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
|
||||
* @param {TileState} state State.
|
||||
@@ -35,7 +33,6 @@ export class CustomTile extends Tile {
|
||||
* @param {boolean} jsonp Load the tile as a script.
|
||||
*/
|
||||
constructor(tileCoord, state, src, extent, preemptive, jsonp) {
|
||||
|
||||
super(tileCoord, state);
|
||||
|
||||
/**
|
||||
@@ -74,13 +71,11 @@ export class CustomTile extends Tile {
|
||||
*/
|
||||
this.data_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.jsonp_ = jsonp;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +86,6 @@ export class CustomTile extends Tile {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Synchronously returns data at given coordinate (if available).
|
||||
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
|
||||
@@ -101,10 +95,10 @@ export class CustomTile extends Tile {
|
||||
if (!this.grid_ || !this.keys_) {
|
||||
return null;
|
||||
}
|
||||
const xRelative = (coordinate[0] - this.extent_[0]) /
|
||||
(this.extent_[2] - this.extent_[0]);
|
||||
const yRelative = (coordinate[1] - this.extent_[1]) /
|
||||
(this.extent_[3] - this.extent_[1]);
|
||||
const xRelative =
|
||||
(coordinate[0] - this.extent_[0]) / (this.extent_[2] - this.extent_[0]);
|
||||
const yRelative =
|
||||
(coordinate[1] - this.extent_[1]) / (this.extent_[3] - this.extent_[1]);
|
||||
|
||||
const row = this.grid_[Math.floor((1 - yRelative) * this.grid_.length)];
|
||||
|
||||
@@ -133,7 +127,6 @@ export class CustomTile extends Tile {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls the callback (synchronously by default) with the available data
|
||||
* for given coordinate (or `null` if not yet loaded).
|
||||
@@ -145,22 +138,29 @@ export class CustomTile extends Tile {
|
||||
forDataAtCoordinate(coordinate, callback, opt_request) {
|
||||
if (this.state == TileState.EMPTY && opt_request === true) {
|
||||
this.state = TileState.IDLE;
|
||||
listenOnce(this, EventType.CHANGE, function(e) {
|
||||
callback(this.getData(coordinate));
|
||||
}, this);
|
||||
listenOnce(
|
||||
this,
|
||||
EventType.CHANGE,
|
||||
function (e) {
|
||||
callback(this.getData(coordinate));
|
||||
},
|
||||
this
|
||||
);
|
||||
this.loadInternal_();
|
||||
} else {
|
||||
if (opt_request === true) {
|
||||
setTimeout(function() {
|
||||
callback(this.getData(coordinate));
|
||||
}.bind(this), 0);
|
||||
setTimeout(
|
||||
function () {
|
||||
callback(this.getData(coordinate));
|
||||
}.bind(this),
|
||||
0
|
||||
);
|
||||
} else {
|
||||
callback(this.getData(coordinate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the key to be used for all tiles in the source.
|
||||
* @return {string} The key for all tiles.
|
||||
@@ -169,7 +169,6 @@ export class CustomTile extends Tile {
|
||||
return this.src_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -178,7 +177,6 @@ export class CustomTile extends Tile {
|
||||
this.changed();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {!UTFGridJSON} json UTFGrid data.
|
||||
* @private
|
||||
@@ -192,7 +190,6 @@ export class CustomTile extends Tile {
|
||||
this.changed();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -200,8 +197,11 @@ export class CustomTile extends Tile {
|
||||
if (this.state == TileState.IDLE) {
|
||||
this.state = TileState.LOADING;
|
||||
if (this.jsonp_) {
|
||||
requestJSONP(this.src_, this.handleLoad_.bind(this),
|
||||
this.handleError_.bind(this));
|
||||
requestJSONP(
|
||||
this.src_,
|
||||
this.handleLoad_.bind(this),
|
||||
this.handleError_.bind(this)
|
||||
);
|
||||
} else {
|
||||
const client = new XMLHttpRequest();
|
||||
client.addEventListener('load', this.onXHRLoad_.bind(this));
|
||||
@@ -212,7 +212,6 @@ export class CustomTile extends Tile {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} event The load event.
|
||||
@@ -220,10 +219,12 @@ export class CustomTile extends Tile {
|
||||
onXHRLoad_(event) {
|
||||
const client = /** @type {XMLHttpRequest} */ (event.target);
|
||||
// status will be 0 for file:// urls
|
||||
if (!client.status || client.status >= 200 && client.status < 300) {
|
||||
if (!client.status || (client.status >= 200 && client.status < 300)) {
|
||||
let response;
|
||||
try {
|
||||
response = /** @type {!UTFGridJSON} */(JSON.parse(client.responseText));
|
||||
response = /** @type {!UTFGridJSON} */ (JSON.parse(
|
||||
client.responseText
|
||||
));
|
||||
} catch (err) {
|
||||
this.handleError_();
|
||||
return;
|
||||
@@ -234,7 +235,6 @@ export class CustomTile extends Tile {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} event The error event.
|
||||
@@ -243,7 +243,6 @@ export class CustomTile extends Tile {
|
||||
this.handleError_();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
load() {
|
||||
@@ -255,7 +254,6 @@ export class CustomTile extends Tile {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {boolean} [preemptive=true]
|
||||
@@ -272,7 +270,6 @@ export class CustomTile extends Tile {
|
||||
* Request will be made through JSONP. If not provided, `tileJSON` must be configured.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source for UTFGrid interaction data loaded from TileJSON format.
|
||||
@@ -285,15 +282,15 @@ class UTFGrid extends TileSource {
|
||||
constructor(options) {
|
||||
super({
|
||||
projection: getProjection('EPSG:3857'),
|
||||
state: SourceState.LOADING
|
||||
state: SourceState.LOADING,
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.preemptive_ = options.preemptive !== undefined ?
|
||||
options.preemptive : true;
|
||||
this.preemptive_ =
|
||||
options.preemptive !== undefined ? options.preemptive : true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -315,8 +312,11 @@ class UTFGrid extends TileSource {
|
||||
|
||||
if (options.url) {
|
||||
if (this.jsonp_) {
|
||||
requestJSONP(options.url, this.handleTileJSONResponse.bind(this),
|
||||
this.handleTileJSONError.bind(this));
|
||||
requestJSONP(
|
||||
options.url,
|
||||
this.handleTileJSONResponse.bind(this),
|
||||
this.handleTileJSONError.bind(this)
|
||||
);
|
||||
} else {
|
||||
const client = new XMLHttpRequest();
|
||||
client.addEventListener('load', this.onXHRLoad_.bind(this));
|
||||
@@ -329,10 +329,8 @@ class UTFGrid extends TileSource {
|
||||
} else {
|
||||
assert(false, 51); // Either `url` or `tileJSON` options must be provided
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} event The load event.
|
||||
@@ -340,10 +338,12 @@ class UTFGrid extends TileSource {
|
||||
onXHRLoad_(event) {
|
||||
const client = /** @type {XMLHttpRequest} */ (event.target);
|
||||
// status will be 0 for file:// urls
|
||||
if (!client.status || client.status >= 200 && client.status < 300) {
|
||||
if (!client.status || (client.status >= 200 && client.status < 300)) {
|
||||
let response;
|
||||
try {
|
||||
response = /** @type {import("./TileJSON.js").Config} */(JSON.parse(client.responseText));
|
||||
response = /** @type {import("./TileJSON.js").Config} */ (JSON.parse(
|
||||
client.responseText
|
||||
));
|
||||
} catch (err) {
|
||||
this.handleTileJSONError();
|
||||
return;
|
||||
@@ -354,7 +354,6 @@ class UTFGrid extends TileSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} event The error event.
|
||||
@@ -363,7 +362,6 @@ class UTFGrid extends TileSource {
|
||||
this.handleTileJSONError();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the template from TileJSON.
|
||||
* @return {string|undefined} The template from TileJSON.
|
||||
@@ -373,7 +371,6 @@ class UTFGrid extends TileSource {
|
||||
return this.template_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls the callback (synchronously by default) with the available data
|
||||
* for given coordinate and resolution (or `null` if not yet loaded or
|
||||
@@ -386,16 +383,25 @@ class UTFGrid extends TileSource {
|
||||
* @api
|
||||
*/
|
||||
forDataAtCoordinateAndResolution(
|
||||
coordinate, resolution, callback, opt_request) {
|
||||
coordinate,
|
||||
resolution,
|
||||
callback,
|
||||
opt_request
|
||||
) {
|
||||
if (this.tileGrid) {
|
||||
const z = this.tileGrid.getZForResolution(resolution, this.zDirection);
|
||||
const tileCoord = this.tileGrid.getTileCoordForCoordAndZ(coordinate, z);
|
||||
const tile = /** @type {!CustomTile} */(this.getTile(
|
||||
tileCoord[0], tileCoord[1], tileCoord[2], 1, this.getProjection()));
|
||||
const tile = /** @type {!CustomTile} */ (this.getTile(
|
||||
tileCoord[0],
|
||||
tileCoord[1],
|
||||
tileCoord[2],
|
||||
1,
|
||||
this.getProjection()
|
||||
));
|
||||
tile.forDataAtCoordinate(coordinate, callback, opt_request);
|
||||
} else {
|
||||
if (opt_request === true) {
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
callback(null);
|
||||
}, 0);
|
||||
} else {
|
||||
@@ -404,7 +410,6 @@ class UTFGrid extends TileSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
@@ -412,21 +417,21 @@ class UTFGrid extends TileSource {
|
||||
this.setState(SourceState.ERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO: very similar to ol/source/TileJSON#handleTileJSONResponse
|
||||
* @protected
|
||||
* @param {import("./TileJSON.js").Config} tileJSON Tile JSON.
|
||||
*/
|
||||
handleTileJSONResponse(tileJSON) {
|
||||
|
||||
const epsg4326Projection = getProjection('EPSG:4326');
|
||||
|
||||
const sourceProjection = this.getProjection();
|
||||
let extent;
|
||||
if (tileJSON['bounds'] !== undefined) {
|
||||
const transform = getTransformFromProjections(
|
||||
epsg4326Projection, sourceProjection);
|
||||
epsg4326Projection,
|
||||
sourceProjection
|
||||
);
|
||||
extent = applyTransform(tileJSON['bounds'], transform);
|
||||
}
|
||||
|
||||
@@ -435,7 +440,7 @@ class UTFGrid extends TileSource {
|
||||
const tileGrid = createXYZ({
|
||||
extent: extentFromProjection(sourceProjection),
|
||||
maxZoom: maxZoom,
|
||||
minZoom: minZoom
|
||||
minZoom: minZoom,
|
||||
});
|
||||
this.tileGrid = tileGrid;
|
||||
|
||||
@@ -450,10 +455,10 @@ class UTFGrid extends TileSource {
|
||||
this.tileUrlFunction_ = createFromTemplates(grids, tileGrid);
|
||||
|
||||
if (tileJSON['attribution'] !== undefined) {
|
||||
const attributionExtent = extent !== undefined ?
|
||||
extent : epsg4326Projection.getExtent();
|
||||
const attributionExtent =
|
||||
extent !== undefined ? extent : epsg4326Projection.getExtent();
|
||||
|
||||
this.setAttributions(function(frameState) {
|
||||
this.setAttributions(function (frameState) {
|
||||
if (intersects(attributionExtent, frameState.extent)) {
|
||||
return [tileJSON['attribution']];
|
||||
}
|
||||
@@ -462,10 +467,8 @@ class UTFGrid extends TileSource {
|
||||
}
|
||||
|
||||
this.setState(SourceState.READY);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} z Tile coordinate z.
|
||||
* @param {number} x Tile coordinate x.
|
||||
@@ -480,22 +483,28 @@ class UTFGrid extends TileSource {
|
||||
return this.tileCache.get(tileCoordKey);
|
||||
} else {
|
||||
const tileCoord = [z, x, y];
|
||||
const urlTileCoord =
|
||||
this.getTileCoordForTileUrlFunction(tileCoord, projection);
|
||||
const tileUrl = this.tileUrlFunction_(urlTileCoord, pixelRatio, projection);
|
||||
const urlTileCoord = this.getTileCoordForTileUrlFunction(
|
||||
tileCoord,
|
||||
projection
|
||||
);
|
||||
const tileUrl = this.tileUrlFunction_(
|
||||
urlTileCoord,
|
||||
pixelRatio,
|
||||
projection
|
||||
);
|
||||
const tile = new CustomTile(
|
||||
tileCoord,
|
||||
tileUrl !== undefined ? TileState.IDLE : TileState.EMPTY,
|
||||
tileUrl !== undefined ? tileUrl : '',
|
||||
this.tileGrid.getTileCoordExtent(tileCoord),
|
||||
this.preemptive_,
|
||||
this.jsonp_);
|
||||
this.jsonp_
|
||||
);
|
||||
this.tileCache.set(tileCoordKey, tile);
|
||||
return tile;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Marks a tile coord as being used, without triggering a load.
|
||||
* @param {number} z Tile coordinate z.
|
||||
@@ -510,5 +519,4 @@ class UTFGrid extends TileSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default UTFGrid;
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
/**
|
||||
* @module ol/source/UrlTile
|
||||
*/
|
||||
import {getUid} from '../util.js';
|
||||
import TileState from '../TileState.js';
|
||||
import {expandUrl, createFromTemplates, nullTileUrlFunction} from '../tileurlfunction.js';
|
||||
import TileSource, {TileSourceEvent} from './Tile.js';
|
||||
import TileEventType from './TileEventType.js';
|
||||
import TileSource, {TileSourceEvent} from './Tile.js';
|
||||
import TileState from '../TileState.js';
|
||||
import {
|
||||
createFromTemplates,
|
||||
expandUrl,
|
||||
nullTileUrlFunction,
|
||||
} from '../tileurlfunction.js';
|
||||
import {getKeyZXY} from '../tilecoord.js';
|
||||
import {getUid} from '../util.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -28,7 +32,6 @@ import {getKeyZXY} from '../tilecoord.js';
|
||||
* @property {number} [zDirection=0]
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Base class for sources providing tiles divided into a tile grid over http.
|
||||
@@ -40,7 +43,6 @@ class UrlTile extends TileSource {
|
||||
* @param {Options} options Image tile options.
|
||||
*/
|
||||
constructor(options) {
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
cacheSize: options.cacheSize,
|
||||
@@ -53,7 +55,7 @@ class UrlTile extends TileSource {
|
||||
transition: options.transition,
|
||||
key: options.key,
|
||||
attributionsCollapsible: options.attributionsCollapsible,
|
||||
zDirection: options.zDirection
|
||||
zDirection: options.zDirection,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -72,7 +74,9 @@ class UrlTile extends TileSource {
|
||||
* @protected
|
||||
* @type {import("../Tile.js").UrlFunction}
|
||||
*/
|
||||
this.tileUrlFunction = options.tileUrlFunction ? options.tileUrlFunction.bind(this) : nullTileUrlFunction;
|
||||
this.tileUrlFunction = options.tileUrlFunction
|
||||
? options.tileUrlFunction.bind(this)
|
||||
: nullTileUrlFunction;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
@@ -91,7 +95,6 @@ class UrlTile extends TileSource {
|
||||
* @type {!Object<string, boolean>}
|
||||
*/
|
||||
this.tileLoadingKeys_ = {};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,9 +141,12 @@ class UrlTile extends TileSource {
|
||||
type = TileEventType.TILELOADSTART;
|
||||
} else if (uid in this.tileLoadingKeys_) {
|
||||
delete this.tileLoadingKeys_[uid];
|
||||
type = tileState == TileState.ERROR ? TileEventType.TILELOADERROR :
|
||||
tileState == TileState.LOADED ?
|
||||
TileEventType.TILELOADEND : undefined;
|
||||
type =
|
||||
tileState == TileState.ERROR
|
||||
? TileEventType.TILELOADERROR
|
||||
: tileState == TileState.LOADED
|
||||
? TileEventType.TILELOADEND
|
||||
: undefined;
|
||||
}
|
||||
if (type != undefined) {
|
||||
this.dispatchEvent(new TileSourceEvent(type, tile));
|
||||
@@ -214,5 +220,4 @@ class UrlTile extends TileSource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default UrlTile;
|
||||
|
||||
@@ -2,24 +2,24 @@
|
||||
* @module ol/source/Vector
|
||||
*/
|
||||
|
||||
import {getUid} from '../util.js';
|
||||
import Collection from '../Collection.js';
|
||||
import CollectionEventType from '../CollectionEventType.js';
|
||||
import ObjectEventType from '../ObjectEventType.js';
|
||||
import {extend} from '../array.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import {listen, unlistenByKey} from '../events.js';
|
||||
import Event from '../events/Event.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {containsExtent, equals} from '../extent.js';
|
||||
import {xhr} from '../featureloader.js';
|
||||
import {TRUE, VOID} from '../functions.js';
|
||||
import {all as allStrategy} from '../loadingstrategy.js';
|
||||
import {isEmpty, getValues} from '../obj.js';
|
||||
import ObjectEventType from '../ObjectEventType.js';
|
||||
import RBush from '../structs/RBush.js';
|
||||
import Source from './Source.js';
|
||||
import SourceState from './State.js';
|
||||
import VectorEventType from './VectorEventType.js';
|
||||
import RBush from '../structs/RBush.js';
|
||||
import {TRUE, VOID} from '../functions.js';
|
||||
import {all as allStrategy} from '../loadingstrategy.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import {containsExtent, equals} from '../extent.js';
|
||||
import {extend} from '../array.js';
|
||||
import {getUid} from '../util.js';
|
||||
import {getValues, isEmpty} from '../obj.js';
|
||||
import {listen, unlistenByKey} from '../events.js';
|
||||
import {xhr} from '../featureloader.js';
|
||||
|
||||
/**
|
||||
* A function that takes an {@link module:ol/extent~Extent} and a resolution as arguments, and
|
||||
@@ -30,7 +30,6 @@ import RBush from '../structs/RBush.js';
|
||||
* @api
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/source/Vector} instances are instances of this
|
||||
@@ -38,13 +37,11 @@ import RBush from '../structs/RBush.js';
|
||||
* @template {import("../geom/Geometry.js").default} Geometry
|
||||
*/
|
||||
export class VectorSourceEvent extends Event {
|
||||
|
||||
/**
|
||||
* @param {string} type Type.
|
||||
* @param {import("../Feature.js").default<Geometry>=} opt_feature Feature.
|
||||
*/
|
||||
constructor(type, opt_feature) {
|
||||
|
||||
super(type);
|
||||
|
||||
/**
|
||||
@@ -53,12 +50,9 @@ export class VectorSourceEvent extends Event {
|
||||
* @api
|
||||
*/
|
||||
this.feature = opt_feature;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
|
||||
@@ -148,7 +142,6 @@ export class VectorSourceEvent extends Event {
|
||||
* resulting geometry coordinates will then exceed the world bounds.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Provides a source of features for vector layers. Vector features provided
|
||||
@@ -164,14 +157,13 @@ class VectorSource extends Source {
|
||||
* @param {Options=} opt_options Vector source options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
projection: undefined,
|
||||
state: SourceState.READY,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -203,17 +195,21 @@ class VectorSource extends Source {
|
||||
} else if (this.url_ !== undefined) {
|
||||
assert(this.format_, 7); // `format` must be set when `url` is set
|
||||
// create a XHR feature loader for "url" and "format"
|
||||
this.loader_ = xhr(this.url_, /** @type {import("../format/Feature.js").default} */ (this.format_));
|
||||
this.loader_ = xhr(
|
||||
this.url_,
|
||||
/** @type {import("../format/Feature.js").default} */ (this.format_)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {LoadingStrategy}
|
||||
*/
|
||||
this.strategy_ = options.strategy !== undefined ? options.strategy : allStrategy;
|
||||
this.strategy_ =
|
||||
options.strategy !== undefined ? options.strategy : allStrategy;
|
||||
|
||||
const useSpatialIndex =
|
||||
options.useSpatialIndex !== undefined ? options.useSpatialIndex : true;
|
||||
options.useSpatialIndex !== undefined ? options.useSpatialIndex : true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -275,7 +271,6 @@ class VectorSource extends Source {
|
||||
if (collection !== undefined) {
|
||||
this.bindFeaturesCollection_(collection);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,7 +290,6 @@ class VectorSource extends Source {
|
||||
this.changed();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a feature without firing a `change` event.
|
||||
* @param {import("../Feature.js").default<Geometry>} feature Feature.
|
||||
@@ -324,10 +318,10 @@ class VectorSource extends Source {
|
||||
}
|
||||
|
||||
this.dispatchEvent(
|
||||
new VectorSourceEvent(VectorEventType.ADDFEATURE, feature));
|
||||
new VectorSourceEvent(VectorEventType.ADDFEATURE, feature)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} featureKey Unique identifier for the feature.
|
||||
* @param {import("../Feature.js").default<Geometry>} feature The feature.
|
||||
@@ -335,14 +329,16 @@ class VectorSource extends Source {
|
||||
*/
|
||||
setupChangeEvents_(featureKey, feature) {
|
||||
this.featureChangeKeys_[featureKey] = [
|
||||
listen(feature, EventType.CHANGE,
|
||||
this.handleFeatureChange_, this),
|
||||
listen(feature, ObjectEventType.PROPERTYCHANGE,
|
||||
this.handleFeatureChange_, this)
|
||||
listen(feature, EventType.CHANGE, this.handleFeatureChange_, this),
|
||||
listen(
|
||||
feature,
|
||||
ObjectEventType.PROPERTYCHANGE,
|
||||
this.handleFeatureChange_,
|
||||
this
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} featureKey Unique identifier for the feature.
|
||||
* @param {import("../Feature.js").default<Geometry>} feature The feature.
|
||||
@@ -361,14 +357,12 @@ class VectorSource extends Source {
|
||||
}
|
||||
}
|
||||
if (valid) {
|
||||
assert(!(featureKey in this.uidIndex_),
|
||||
30); // The passed `feature` was already added to the source
|
||||
assert(!(featureKey in this.uidIndex_), 30); // The passed `feature` was already added to the source
|
||||
this.uidIndex_[featureKey] = feature;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a batch of features to the source.
|
||||
* @param {Array<import("../Feature.js").default<Geometry>>} features Features to add.
|
||||
@@ -379,7 +373,6 @@ class VectorSource extends Source {
|
||||
this.changed();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add features without firing a `change` event.
|
||||
* @param {Array<import("../Feature.js").default<Geometry>>} features Features.
|
||||
@@ -417,65 +410,77 @@ class VectorSource extends Source {
|
||||
}
|
||||
|
||||
for (let i = 0, length = newFeatures.length; i < length; i++) {
|
||||
this.dispatchEvent(new VectorSourceEvent(VectorEventType.ADDFEATURE, newFeatures[i]));
|
||||
this.dispatchEvent(
|
||||
new VectorSourceEvent(VectorEventType.ADDFEATURE, newFeatures[i])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Collection<import("../Feature.js").default<Geometry>>} collection Collection.
|
||||
* @private
|
||||
*/
|
||||
bindFeaturesCollection_(collection) {
|
||||
let modifyingCollection = false;
|
||||
this.addEventListener(VectorEventType.ADDFEATURE,
|
||||
this.addEventListener(
|
||||
VectorEventType.ADDFEATURE,
|
||||
/**
|
||||
* @param {VectorSourceEvent<Geometry>} evt The vector source event
|
||||
*/
|
||||
function(evt) {
|
||||
function (evt) {
|
||||
if (!modifyingCollection) {
|
||||
modifyingCollection = true;
|
||||
collection.push(evt.feature);
|
||||
modifyingCollection = false;
|
||||
}
|
||||
});
|
||||
this.addEventListener(VectorEventType.REMOVEFEATURE,
|
||||
}
|
||||
);
|
||||
this.addEventListener(
|
||||
VectorEventType.REMOVEFEATURE,
|
||||
/**
|
||||
* @param {VectorSourceEvent<Geometry>} evt The vector source event
|
||||
*/
|
||||
function(evt) {
|
||||
function (evt) {
|
||||
if (!modifyingCollection) {
|
||||
modifyingCollection = true;
|
||||
collection.remove(evt.feature);
|
||||
modifyingCollection = false;
|
||||
}
|
||||
});
|
||||
collection.addEventListener(CollectionEventType.ADD,
|
||||
}
|
||||
);
|
||||
collection.addEventListener(
|
||||
CollectionEventType.ADD,
|
||||
/**
|
||||
* @param {import("../Collection.js").CollectionEvent} evt The collection event
|
||||
*/
|
||||
function(evt) {
|
||||
function (evt) {
|
||||
if (!modifyingCollection) {
|
||||
modifyingCollection = true;
|
||||
this.addFeature(/** @type {import("../Feature.js").default<Geometry>} */ (evt.element));
|
||||
this.addFeature(
|
||||
/** @type {import("../Feature.js").default<Geometry>} */ (evt.element)
|
||||
);
|
||||
modifyingCollection = false;
|
||||
}
|
||||
}.bind(this));
|
||||
collection.addEventListener(CollectionEventType.REMOVE,
|
||||
}.bind(this)
|
||||
);
|
||||
collection.addEventListener(
|
||||
CollectionEventType.REMOVE,
|
||||
/**
|
||||
* @param {import("../Collection.js").CollectionEvent} evt The collection event
|
||||
*/
|
||||
function(evt) {
|
||||
function (evt) {
|
||||
if (!modifyingCollection) {
|
||||
modifyingCollection = true;
|
||||
this.removeFeature(/** @type {import("../Feature.js").default<Geometry>} */ (evt.element));
|
||||
this.removeFeature(
|
||||
/** @type {import("../Feature.js").default<Geometry>} */ (evt.element)
|
||||
);
|
||||
modifyingCollection = false;
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this)
|
||||
);
|
||||
this.featuresCollection_ = collection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove all features from the source.
|
||||
* @param {boolean=} opt_fast Skip dispatching of {@link module:ol/source/Vector.VectorSourceEvent#removefeature} events.
|
||||
@@ -514,7 +519,6 @@ class VectorSource extends Source {
|
||||
this.changed();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate through all features on the source, calling the provided callback
|
||||
* with each one. If the callback returns any "truthy" value, iteration will
|
||||
@@ -535,7 +539,6 @@ class VectorSource extends Source {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate through all features whose geometries contain the provided
|
||||
* coordinate, calling the callback with each feature. If the callback returns
|
||||
@@ -550,7 +553,7 @@ class VectorSource extends Source {
|
||||
*/
|
||||
forEachFeatureAtCoordinateDirect(coordinate, callback) {
|
||||
const extent = [coordinate[0], coordinate[1], coordinate[0], coordinate[1]];
|
||||
return this.forEachFeatureInExtent(extent, function(feature) {
|
||||
return this.forEachFeatureInExtent(extent, function (feature) {
|
||||
const geometry = feature.getGeometry();
|
||||
if (geometry.intersectsCoordinate(coordinate)) {
|
||||
return callback(feature);
|
||||
@@ -560,7 +563,6 @@ class VectorSource extends Source {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate through all features whose bounding box intersects the provided
|
||||
* extent (note that the feature's geometry may not intersect the extent),
|
||||
@@ -588,7 +590,6 @@ class VectorSource extends Source {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate through all features whose geometry intersects the provided extent,
|
||||
* calling the callback with each feature. If the callback returns a "truthy"
|
||||
@@ -605,12 +606,13 @@ class VectorSource extends Source {
|
||||
* @api
|
||||
*/
|
||||
forEachFeatureIntersectingExtent(extent, callback) {
|
||||
return this.forEachFeatureInExtent(extent,
|
||||
return this.forEachFeatureInExtent(
|
||||
extent,
|
||||
/**
|
||||
* @param {import("../Feature.js").default<Geometry>} feature Feature.
|
||||
* @return {T|undefined} The return value from the last call to the callback.
|
||||
*/
|
||||
function(feature) {
|
||||
function (feature) {
|
||||
const geometry = feature.getGeometry();
|
||||
if (geometry.intersectsExtent(extent)) {
|
||||
const result = callback(feature);
|
||||
@@ -618,10 +620,10 @@ class VectorSource extends Source {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the features collection associated with this source. Will be `null`
|
||||
* unless the source was configured with `useSpatialIndex` set to `false`, or
|
||||
@@ -633,7 +635,6 @@ class VectorSource extends Source {
|
||||
return this.featuresCollection_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all features on the source in random order.
|
||||
* @return {Array<import("../Feature.js").default<Geometry>>} Features.
|
||||
@@ -649,12 +650,9 @@ class VectorSource extends Source {
|
||||
extend(features, getValues(this.nullGeometryFeatures_));
|
||||
}
|
||||
}
|
||||
return (
|
||||
/** @type {Array<import("../Feature.js").default<Geometry>>} */ (features)
|
||||
);
|
||||
return /** @type {Array<import("../Feature.js").default<Geometry>>} */ (features);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all features whose geometry intersects the provided coordinate.
|
||||
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
|
||||
@@ -663,13 +661,12 @@ class VectorSource extends Source {
|
||||
*/
|
||||
getFeaturesAtCoordinate(coordinate) {
|
||||
const features = [];
|
||||
this.forEachFeatureAtCoordinateDirect(coordinate, function(feature) {
|
||||
this.forEachFeatureAtCoordinateDirect(coordinate, function (feature) {
|
||||
features.push(feature);
|
||||
});
|
||||
return features;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all features whose bounding box intersects the provided extent. Note that this returns an array of
|
||||
* all features intersecting the given extent in random order (so it may include
|
||||
@@ -692,7 +689,6 @@ class VectorSource extends Source {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the closest feature to the provided coordinate.
|
||||
*
|
||||
@@ -720,16 +716,21 @@ class VectorSource extends Source {
|
||||
let minSquaredDistance = Infinity;
|
||||
const extent = [-Infinity, -Infinity, Infinity, Infinity];
|
||||
const filter = opt_filter ? opt_filter : TRUE;
|
||||
this.featuresRtree_.forEachInExtent(extent,
|
||||
this.featuresRtree_.forEachInExtent(
|
||||
extent,
|
||||
/**
|
||||
* @param {import("../Feature.js").default<Geometry>} feature Feature.
|
||||
*/
|
||||
function(feature) {
|
||||
function (feature) {
|
||||
if (filter(feature)) {
|
||||
const geometry = feature.getGeometry();
|
||||
const previousMinSquaredDistance = minSquaredDistance;
|
||||
minSquaredDistance = geometry.closestPointXY(
|
||||
x, y, closestPoint, minSquaredDistance);
|
||||
x,
|
||||
y,
|
||||
closestPoint,
|
||||
minSquaredDistance
|
||||
);
|
||||
if (minSquaredDistance < previousMinSquaredDistance) {
|
||||
closestFeature = feature;
|
||||
// This is sneaky. Reduce the extent that it is currently being
|
||||
@@ -743,11 +744,11 @@ class VectorSource extends Source {
|
||||
extent[3] = y + minDistance;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
return closestFeature;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the extent of the features currently in the source.
|
||||
*
|
||||
@@ -762,7 +763,6 @@ class VectorSource extends Source {
|
||||
return this.featuresRtree_.getExtent(opt_extent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a feature by its identifier (the value returned by feature.getId()).
|
||||
* Note that the index treats string and numeric identifiers as the same. So
|
||||
@@ -777,7 +777,6 @@ class VectorSource extends Source {
|
||||
return feature !== undefined ? feature : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a feature by its internal unique identifier (using `getUid`).
|
||||
*
|
||||
@@ -789,7 +788,6 @@ class VectorSource extends Source {
|
||||
return feature !== undefined ? feature : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the format associated with this source.
|
||||
*
|
||||
@@ -800,7 +798,6 @@ class VectorSource extends Source {
|
||||
return this.format_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} The source can have overlapping geometries.
|
||||
*/
|
||||
@@ -808,7 +805,6 @@ class VectorSource extends Source {
|
||||
return this.overlaps_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the url associated with this source.
|
||||
*
|
||||
@@ -819,7 +815,6 @@ class VectorSource extends Source {
|
||||
return this.url_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {Event} event Event.
|
||||
* @private
|
||||
@@ -860,8 +855,9 @@ class VectorSource extends Source {
|
||||
this.uidIndex_[featureKey] = feature;
|
||||
}
|
||||
this.changed();
|
||||
this.dispatchEvent(new VectorSourceEvent(
|
||||
VectorEventType.CHANGEFEATURE, feature));
|
||||
this.dispatchEvent(
|
||||
new VectorSourceEvent(VectorEventType.CHANGEFEATURE, feature)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -886,7 +882,6 @@ class VectorSource extends Source {
|
||||
return this.featuresRtree_.isEmpty() && isEmpty(this.nullGeometryFeatures_);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {import("../extent.js").Extent} extent Extent.
|
||||
* @param {number} resolution Resolution.
|
||||
@@ -898,14 +893,16 @@ class VectorSource extends Source {
|
||||
this.loading = false;
|
||||
for (let i = 0, ii = extentsToLoad.length; i < ii; ++i) {
|
||||
const extentToLoad = extentsToLoad[i];
|
||||
const alreadyLoaded = loadedExtentsRtree.forEachInExtent(extentToLoad,
|
||||
const alreadyLoaded = loadedExtentsRtree.forEachInExtent(
|
||||
extentToLoad,
|
||||
/**
|
||||
* @param {{extent: import("../extent.js").Extent}} object Object.
|
||||
* @return {boolean} Contains.
|
||||
*/
|
||||
function(object) {
|
||||
function (object) {
|
||||
return containsExtent(object.extent, extentToLoad);
|
||||
});
|
||||
}
|
||||
);
|
||||
if (!alreadyLoaded) {
|
||||
this.loader_.call(this, extentToLoad, resolution, projection);
|
||||
loadedExtentsRtree.insert(extentToLoad, {extent: extentToLoad.slice()});
|
||||
@@ -920,7 +917,6 @@ class VectorSource extends Source {
|
||||
super.refresh();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove an extent from the list of loaded extents.
|
||||
* @param {import("../extent.js").Extent} extent Extent.
|
||||
@@ -929,7 +925,7 @@ class VectorSource extends Source {
|
||||
removeLoadedExtent(extent) {
|
||||
const loadedExtentsRtree = this.loadedExtentsRtree_;
|
||||
let obj;
|
||||
loadedExtentsRtree.forEachInExtent(extent, function(object) {
|
||||
loadedExtentsRtree.forEachInExtent(extent, function (object) {
|
||||
if (equals(object.extent, extent)) {
|
||||
obj = object;
|
||||
return true;
|
||||
@@ -940,7 +936,6 @@ class VectorSource extends Source {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a single feature from the source. If you want to remove all features
|
||||
* at once, use the {@link module:ol/source/Vector~VectorSource#clear #clear()} method
|
||||
@@ -961,7 +956,6 @@ class VectorSource extends Source {
|
||||
this.changed();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove feature without firing a `change` event.
|
||||
* @param {import("../Feature.js").default<Geometry>} feature Feature.
|
||||
@@ -976,11 +970,11 @@ class VectorSource extends Source {
|
||||
delete this.idIndex_[id.toString()];
|
||||
}
|
||||
delete this.uidIndex_[featureKey];
|
||||
this.dispatchEvent(new VectorSourceEvent(
|
||||
VectorEventType.REMOVEFEATURE, feature));
|
||||
this.dispatchEvent(
|
||||
new VectorSourceEvent(VectorEventType.REMOVEFEATURE, feature)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a feature from the id index. Called internally when the feature id
|
||||
* may have changed.
|
||||
@@ -1000,7 +994,6 @@ class VectorSource extends Source {
|
||||
return removed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the new loader of the source. The next render cycle will use the
|
||||
* new loader.
|
||||
@@ -1020,8 +1013,6 @@ class VectorSource extends Source {
|
||||
assert(this.format_, 7); // `format` must be set when `url` is set
|
||||
this.setLoader(xhr(url, this.format_));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default VectorSource;
|
||||
|
||||
@@ -33,5 +33,5 @@ export default {
|
||||
* @event module:ol/source/Vector.VectorSourceEvent#removefeature
|
||||
* @api
|
||||
*/
|
||||
REMOVEFEATURE: 'removefeature'
|
||||
REMOVEFEATURE: 'removefeature',
|
||||
};
|
||||
|
||||
@@ -2,18 +2,26 @@
|
||||
* @module ol/source/VectorTile
|
||||
*/
|
||||
|
||||
import TileState from '../TileState.js';
|
||||
import VectorRenderTile from '../VectorRenderTile.js';
|
||||
import Tile from '../VectorTile.js';
|
||||
import {toSize} from '../size.js';
|
||||
import UrlTile from './UrlTile.js';
|
||||
import {getKeyZXY, fromKey} from '../tilecoord.js';
|
||||
import {createXYZ, extentFromProjection, createForProjection} from '../tilegrid.js';
|
||||
import {buffer as bufferExtent, getIntersection, intersects} from '../extent.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {loadFeaturesXhr} from '../featureloader.js';
|
||||
import {equals} from '../array.js';
|
||||
import Tile from '../VectorTile.js';
|
||||
import TileCache from '../TileCache.js';
|
||||
import TileState from '../TileState.js';
|
||||
import UrlTile from './UrlTile.js';
|
||||
import VectorRenderTile from '../VectorRenderTile.js';
|
||||
import {
|
||||
buffer as bufferExtent,
|
||||
getIntersection,
|
||||
intersects,
|
||||
} from '../extent.js';
|
||||
import {
|
||||
createForProjection,
|
||||
createXYZ,
|
||||
extentFromProjection,
|
||||
} from '../tilegrid.js';
|
||||
import {equals} from '../array.js';
|
||||
import {fromKey, getKeyZXY} from '../tilecoord.js';
|
||||
import {loadFeaturesXhr} from '../featureloader.js';
|
||||
import {toSize} from '../size.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -81,7 +89,6 @@ import TileCache from '../TileCache.js';
|
||||
* will be used. If -1, the nearest higher resolution will be used.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Class for layer sources providing vector data divided into a tile grid, to be
|
||||
@@ -104,13 +111,15 @@ class VectorTile extends UrlTile {
|
||||
|
||||
const extent = options.extent || extentFromProjection(projection);
|
||||
|
||||
const tileGrid = options.tileGrid || createXYZ({
|
||||
extent: extent,
|
||||
maxResolution: options.maxResolution,
|
||||
maxZoom: options.maxZoom !== undefined ? options.maxZoom : 22,
|
||||
minZoom: options.minZoom,
|
||||
tileSize: options.tileSize || 512
|
||||
});
|
||||
const tileGrid =
|
||||
options.tileGrid ||
|
||||
createXYZ({
|
||||
extent: extent,
|
||||
maxResolution: options.maxResolution,
|
||||
maxZoom: options.maxZoom !== undefined ? options.maxZoom : 22,
|
||||
minZoom: options.minZoom,
|
||||
tileSize: options.tileSize || 512,
|
||||
});
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
@@ -120,13 +129,15 @@ class VectorTile extends UrlTile {
|
||||
projection: projection,
|
||||
state: options.state,
|
||||
tileGrid: tileGrid,
|
||||
tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : defaultLoadFunction,
|
||||
tileLoadFunction: options.tileLoadFunction
|
||||
? options.tileLoadFunction
|
||||
: defaultLoadFunction,
|
||||
tileUrlFunction: options.tileUrlFunction,
|
||||
url: options.url,
|
||||
urls: options.urls,
|
||||
wrapX: options.wrapX === undefined ? true : options.wrapX,
|
||||
transition: options.transition,
|
||||
zDirection: options.zDirection === undefined ? 1 : options.zDirection
|
||||
zDirection: options.zDirection === undefined ? 1 : options.zDirection,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -163,7 +174,6 @@ class VectorTile extends UrlTile {
|
||||
* @type {Object<string, import("../tilegrid/TileGrid.js").default>}
|
||||
*/
|
||||
this.tileGrids_ = {};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,7 +196,7 @@ class VectorTile extends UrlTile {
|
||||
}
|
||||
const z = fromKey(tileCache.peekFirstKey())[0];
|
||||
const tileGrid = this.tileGrid;
|
||||
tileCache.forEach(function(tile) {
|
||||
tileCache.forEach(function (tile) {
|
||||
if (tile.tileCoord[0] !== z || tile.getState() !== TileState.LOADED) {
|
||||
return;
|
||||
}
|
||||
@@ -260,7 +270,11 @@ class VectorTile extends UrlTile {
|
||||
|
||||
const previousSourceTiles = tile.sourceTiles;
|
||||
let sourceTiles, covered, loadedZ;
|
||||
if (previousSourceTiles && previousSourceTiles.length > 0 && previousSourceTiles[0].tileCoord[0] === sourceZ) {
|
||||
if (
|
||||
previousSourceTiles &&
|
||||
previousSourceTiles.length > 0 &&
|
||||
previousSourceTiles[0].tileCoord[0] === sourceZ
|
||||
) {
|
||||
sourceTiles = previousSourceTiles;
|
||||
covered = true;
|
||||
loadedZ = sourceZ;
|
||||
@@ -270,55 +284,92 @@ class VectorTile extends UrlTile {
|
||||
do {
|
||||
--loadedZ;
|
||||
covered = true;
|
||||
sourceTileGrid.forEachTileCoord(extent, loadedZ, function(sourceTileCoord) {
|
||||
const tileUrl = this.tileUrlFunction(sourceTileCoord, pixelRatio, projection);
|
||||
let sourceTile;
|
||||
if (tileUrl !== undefined) {
|
||||
if (this.sourceTileCache.containsKey(tileUrl)) {
|
||||
sourceTile = this.sourceTileCache.get(tileUrl);
|
||||
const state = sourceTile.getState();
|
||||
if (state === TileState.LOADED || state === TileState.ERROR || state === TileState.EMPTY) {
|
||||
sourceTiles.push(sourceTile);
|
||||
return;
|
||||
sourceTileGrid.forEachTileCoord(
|
||||
extent,
|
||||
loadedZ,
|
||||
function (sourceTileCoord) {
|
||||
const tileUrl = this.tileUrlFunction(
|
||||
sourceTileCoord,
|
||||
pixelRatio,
|
||||
projection
|
||||
);
|
||||
let sourceTile;
|
||||
if (tileUrl !== undefined) {
|
||||
if (this.sourceTileCache.containsKey(tileUrl)) {
|
||||
sourceTile = this.sourceTileCache.get(tileUrl);
|
||||
const state = sourceTile.getState();
|
||||
if (
|
||||
state === TileState.LOADED ||
|
||||
state === TileState.ERROR ||
|
||||
state === TileState.EMPTY
|
||||
) {
|
||||
sourceTiles.push(sourceTile);
|
||||
return;
|
||||
}
|
||||
} else if (loadedZ === sourceZ) {
|
||||
sourceTile = new this.tileClass(
|
||||
sourceTileCoord,
|
||||
TileState.IDLE,
|
||||
tileUrl,
|
||||
this.format_,
|
||||
this.tileLoadFunction
|
||||
);
|
||||
sourceTile.extent = sourceTileGrid.getTileCoordExtent(
|
||||
sourceTileCoord
|
||||
);
|
||||
sourceTile.projection = projection;
|
||||
sourceTile.resolution = sourceTileGrid.getResolution(
|
||||
sourceTileCoord[0]
|
||||
);
|
||||
this.sourceTileCache.set(tileUrl, sourceTile);
|
||||
sourceTile.addEventListener(
|
||||
EventType.CHANGE,
|
||||
this.handleTileChange.bind(this)
|
||||
);
|
||||
sourceTile.load();
|
||||
}
|
||||
} else if (loadedZ === sourceZ) {
|
||||
sourceTile = new this.tileClass(sourceTileCoord, TileState.IDLE, tileUrl,
|
||||
this.format_, this.tileLoadFunction);
|
||||
sourceTile.extent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);
|
||||
sourceTile.projection = projection;
|
||||
sourceTile.resolution = sourceTileGrid.getResolution(sourceTileCoord[0]);
|
||||
this.sourceTileCache.set(tileUrl, sourceTile);
|
||||
sourceTile.addEventListener(EventType.CHANGE, this.handleTileChange.bind(this));
|
||||
sourceTile.load();
|
||||
}
|
||||
}
|
||||
covered = covered && sourceTile && sourceTile.getState() === TileState.LOADED;
|
||||
if (!sourceTile) {
|
||||
return;
|
||||
}
|
||||
if (sourceTile.getState() !== TileState.EMPTY && tile.getState() === TileState.IDLE) {
|
||||
tile.loadingSourceTiles++;
|
||||
sourceTile.addEventListener(EventType.CHANGE, function listenChange() {
|
||||
const state = sourceTile.getState();
|
||||
const sourceTileKey = sourceTile.getKey();
|
||||
if (state === TileState.LOADED || state === TileState.ERROR) {
|
||||
if (state === TileState.LOADED) {
|
||||
sourceTile.removeEventListener(EventType.CHANGE, listenChange);
|
||||
tile.loadingSourceTiles--;
|
||||
delete tile.errorSourceTileKeys[sourceTileKey];
|
||||
} else if (state === TileState.ERROR) {
|
||||
tile.errorSourceTileKeys[sourceTileKey] = true;
|
||||
covered =
|
||||
covered &&
|
||||
sourceTile &&
|
||||
sourceTile.getState() === TileState.LOADED;
|
||||
if (!sourceTile) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
sourceTile.getState() !== TileState.EMPTY &&
|
||||
tile.getState() === TileState.IDLE
|
||||
) {
|
||||
tile.loadingSourceTiles++;
|
||||
sourceTile.addEventListener(
|
||||
EventType.CHANGE,
|
||||
function listenChange() {
|
||||
const state = sourceTile.getState();
|
||||
const sourceTileKey = sourceTile.getKey();
|
||||
if (state === TileState.LOADED || state === TileState.ERROR) {
|
||||
if (state === TileState.LOADED) {
|
||||
sourceTile.removeEventListener(
|
||||
EventType.CHANGE,
|
||||
listenChange
|
||||
);
|
||||
tile.loadingSourceTiles--;
|
||||
delete tile.errorSourceTileKeys[sourceTileKey];
|
||||
} else if (state === TileState.ERROR) {
|
||||
tile.errorSourceTileKeys[sourceTileKey] = true;
|
||||
}
|
||||
const errorTileCount = Object.keys(tile.errorSourceTileKeys)
|
||||
.length;
|
||||
if (tile.loadingSourceTiles - errorTileCount === 0) {
|
||||
tile.hifi = errorTileCount === 0;
|
||||
tile.sourceZ = sourceZ;
|
||||
tile.setState(TileState.LOADED);
|
||||
}
|
||||
}
|
||||
}
|
||||
const errorTileCount = Object.keys(tile.errorSourceTileKeys).length;
|
||||
if (tile.loadingSourceTiles - errorTileCount === 0) {
|
||||
tile.hifi = errorTileCount === 0;
|
||||
tile.sourceZ = sourceZ;
|
||||
tile.setState(TileState.LOADED);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}.bind(this));
|
||||
);
|
||||
}
|
||||
}.bind(this)
|
||||
);
|
||||
if (!covered) {
|
||||
sourceTiles.length = 0;
|
||||
}
|
||||
@@ -333,7 +384,10 @@ class VectorTile extends UrlTile {
|
||||
tile.sourceZ = loadedZ;
|
||||
if (tile.getState() < TileState.LOADED) {
|
||||
tile.setState(TileState.LOADED);
|
||||
} else if (!previousSourceTiles || !equals(sourceTiles, previousSourceTiles)) {
|
||||
} else if (
|
||||
!previousSourceTiles ||
|
||||
!equals(sourceTiles, previousSourceTiles)
|
||||
) {
|
||||
tile.sourceTiles = sourceTiles;
|
||||
}
|
||||
}
|
||||
@@ -359,7 +413,10 @@ class VectorTile extends UrlTile {
|
||||
}
|
||||
}
|
||||
const tileCoord = [z, x, y];
|
||||
let urlTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection);
|
||||
let urlTileCoord = this.getTileCoordForTileUrlFunction(
|
||||
tileCoord,
|
||||
projection
|
||||
);
|
||||
const sourceExtent = this.getTileGrid().getExtent();
|
||||
const tileGrid = this.getTileGridForProjection(projection);
|
||||
if (urlTileCoord && sourceExtent) {
|
||||
@@ -378,15 +435,22 @@ class VectorTile extends UrlTile {
|
||||
// make extent 1 pixel smaller so we don't load tiles for < 0.5 pixel render space
|
||||
const extent = tileGrid.getTileCoordExtent(urlTileCoord);
|
||||
bufferExtent(extent, -resolution, extent);
|
||||
sourceTileGrid.forEachTileCoord(extent, sourceZ, function(sourceTileCoord) {
|
||||
empty = empty && !this.tileUrlFunction(sourceTileCoord, pixelRatio, projection);
|
||||
}.bind(this));
|
||||
sourceTileGrid.forEachTileCoord(
|
||||
extent,
|
||||
sourceZ,
|
||||
function (sourceTileCoord) {
|
||||
empty =
|
||||
empty &&
|
||||
!this.tileUrlFunction(sourceTileCoord, pixelRatio, projection);
|
||||
}.bind(this)
|
||||
);
|
||||
}
|
||||
const newTile = new VectorRenderTile(
|
||||
tileCoord,
|
||||
empty ? TileState.EMPTY : TileState.IDLE,
|
||||
urlTileCoord,
|
||||
this.getSourceTiles.bind(this, pixelRatio, projection));
|
||||
this.getSourceTiles.bind(this, pixelRatio, projection)
|
||||
);
|
||||
|
||||
newTile.key = key;
|
||||
if (tile) {
|
||||
@@ -410,8 +474,13 @@ class VectorTile extends UrlTile {
|
||||
// A tile grid that matches the tile size of the source tile grid is more
|
||||
// likely to have 1:1 relationships between source tiles and rendered tiles.
|
||||
const sourceTileGrid = this.tileGrid;
|
||||
tileGrid = createForProjection(projection, undefined,
|
||||
sourceTileGrid ? sourceTileGrid.getTileSize(sourceTileGrid.getMinZoom()) : undefined);
|
||||
tileGrid = createForProjection(
|
||||
projection,
|
||||
undefined,
|
||||
sourceTileGrid
|
||||
? sourceTileGrid.getTileSize(sourceTileGrid.getMinZoom())
|
||||
: undefined
|
||||
);
|
||||
this.tileGrids_[code] = tileGrid;
|
||||
}
|
||||
return tileGrid;
|
||||
@@ -435,20 +504,26 @@ class VectorTile extends UrlTile {
|
||||
getTilePixelSize(z, pixelRatio, projection) {
|
||||
const tileGrid = this.getTileGridForProjection(projection);
|
||||
const tileSize = toSize(tileGrid.getTileSize(z), this.tmpSize);
|
||||
return [Math.round(tileSize[0] * pixelRatio), Math.round(tileSize[1] * pixelRatio)];
|
||||
return [
|
||||
Math.round(tileSize[0] * pixelRatio),
|
||||
Math.round(tileSize[1] * pixelRatio),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default VectorTile;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the loader for a tile.
|
||||
* @param {import("../VectorTile.js").default} tile Vector tile.
|
||||
* @param {string} url URL.
|
||||
*/
|
||||
export function defaultLoadFunction(tile, url) {
|
||||
const loader = loadFeaturesXhr(url, tile.getFormat(), tile.onLoad.bind(tile), tile.onError.bind(tile));
|
||||
const loader = loadFeaturesXhr(
|
||||
url,
|
||||
tile.getFormat(),
|
||||
tile.onLoad.bind(tile),
|
||||
tile.onError.bind(tile)
|
||||
);
|
||||
tile.setLoader(loader);
|
||||
}
|
||||
|
||||
@@ -28,5 +28,5 @@ export default {
|
||||
* HiDPI support for [QGIS](https://qgis.org/)
|
||||
* @api
|
||||
*/
|
||||
QGIS: 'qgis'
|
||||
QGIS: 'qgis',
|
||||
};
|
||||
|
||||
@@ -2,14 +2,18 @@
|
||||
* @module ol/source/WMTS
|
||||
*/
|
||||
|
||||
import {expandUrl, createFromTileUrlFunctions, nullTileUrlFunction} from '../tileurlfunction.js';
|
||||
import {find, findIndex, includes} from '../array.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {get as getProjection, equivalent} from '../proj.js';
|
||||
import TileImage from './TileImage.js';
|
||||
import WMTSRequestEncoding from './WMTSRequestEncoding.js';
|
||||
import {createFromCapabilitiesMatrixSet} from '../tilegrid/WMTS.js';
|
||||
import {appendParams} from '../uri.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {createFromCapabilitiesMatrixSet} from '../tilegrid/WMTS.js';
|
||||
import {
|
||||
createFromTileUrlFunctions,
|
||||
expandUrl,
|
||||
nullTileUrlFunction,
|
||||
} from '../tileurlfunction.js';
|
||||
import {equivalent, get as getProjection} from '../proj.js';
|
||||
import {find, findIndex, includes} from '../array.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -54,7 +58,6 @@ import {appendParams} from '../uri.js';
|
||||
* To disable the opacity transition, pass `transition: 0`.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source for tile data from WMTS servers.
|
||||
@@ -65,12 +68,12 @@ class WMTS extends TileImage {
|
||||
* @param {Options} options WMTS options.
|
||||
*/
|
||||
constructor(options) {
|
||||
|
||||
// TODO: add support for TileMatrixLimits
|
||||
|
||||
const requestEncoding = options.requestEncoding !== undefined ?
|
||||
/** @type {import("./WMTSRequestEncoding.js").default} */ (options.requestEncoding) :
|
||||
WMTSRequestEncoding.KVP;
|
||||
const requestEncoding =
|
||||
options.requestEncoding !== undefined
|
||||
? /** @type {import("./WMTSRequestEncoding.js").default} */ (options.requestEncoding)
|
||||
: WMTSRequestEncoding.KVP;
|
||||
|
||||
// FIXME: should we create a default tileGrid?
|
||||
// we could issue a getCapabilities xhr to retrieve missing configuration
|
||||
@@ -95,7 +98,7 @@ class WMTS extends TileImage {
|
||||
tileUrlFunction: nullTileUrlFunction,
|
||||
urls: urls,
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : false,
|
||||
transition: options.transition
|
||||
transition: options.transition,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -114,7 +117,8 @@ class WMTS extends TileImage {
|
||||
* @private
|
||||
* @type {!Object}
|
||||
*/
|
||||
this.dimensions_ = options.dimensions !== undefined ? options.dimensions : {};
|
||||
this.dimensions_ =
|
||||
options.dimensions !== undefined ? options.dimensions : {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -146,9 +150,10 @@ class WMTS extends TileImage {
|
||||
this.setKey(this.getKeyForDimensions_());
|
||||
|
||||
if (urls && urls.length > 0) {
|
||||
this.tileUrlFunction = createFromTileUrlFunctions(urls.map(createFromWMTSTemplate.bind(this)));
|
||||
this.tileUrlFunction = createFromTileUrlFunctions(
|
||||
urls.map(createFromWMTSTemplate.bind(this))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,7 +164,10 @@ class WMTS extends TileImage {
|
||||
setUrls(urls) {
|
||||
this.urls = urls;
|
||||
const key = urls.join('\n');
|
||||
this.setTileUrlFunction(createFromTileUrlFunctions(urls.map(createFromWMTSTemplate.bind(this))), key);
|
||||
this.setTileUrlFunction(
|
||||
createFromTileUrlFunctions(urls.map(createFromWMTSTemplate.bind(this))),
|
||||
key
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,7 +181,6 @@ class WMTS extends TileImage {
|
||||
return this.dimensions_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the image format of the WMTS source.
|
||||
* @return {string} Format.
|
||||
@@ -183,7 +190,6 @@ class WMTS extends TileImage {
|
||||
return this.format_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the layer of the WMTS source.
|
||||
* @return {string} Layer.
|
||||
@@ -193,7 +199,6 @@ class WMTS extends TileImage {
|
||||
return this.layer_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the matrix set of the WMTS source.
|
||||
* @return {string} MatrixSet.
|
||||
@@ -203,7 +208,6 @@ class WMTS extends TileImage {
|
||||
return this.matrixSet_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the request encoding, either "KVP" or "REST".
|
||||
* @return {import("./WMTSRequestEncoding.js").default} Request encoding.
|
||||
@@ -213,7 +217,6 @@ class WMTS extends TileImage {
|
||||
return this.requestEncoding_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the style of the WMTS source.
|
||||
* @return {string} Style.
|
||||
@@ -223,7 +226,6 @@ class WMTS extends TileImage {
|
||||
return this.style_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the version of the WMTS source.
|
||||
* @return {string} Version.
|
||||
@@ -233,7 +235,6 @@ class WMTS extends TileImage {
|
||||
return this.version_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {string} The key for the current dimensions.
|
||||
@@ -247,7 +248,6 @@ class WMTS extends TileImage {
|
||||
return res.join('/');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the dimensions.
|
||||
* @param {Object} dimensions Dimensions.
|
||||
@@ -257,7 +257,6 @@ class WMTS extends TileImage {
|
||||
assign(this.dimensions_, dimensions);
|
||||
this.setKey(this.getKeyForDimensions_());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default WMTS;
|
||||
@@ -288,7 +287,7 @@ export default WMTS;
|
||||
*/
|
||||
export function optionsFromCapabilities(wmtsCap, config) {
|
||||
const layers = wmtsCap['Contents']['Layer'];
|
||||
const l = find(layers, function(elt, index, array) {
|
||||
const l = find(layers, function (elt, index, array) {
|
||||
return elt['Identifier'] == config['layer'];
|
||||
});
|
||||
if (l === null) {
|
||||
@@ -298,26 +297,26 @@ export function optionsFromCapabilities(wmtsCap, config) {
|
||||
let idx;
|
||||
if (l['TileMatrixSetLink'].length > 1) {
|
||||
if ('projection' in config) {
|
||||
idx = findIndex(l['TileMatrixSetLink'],
|
||||
function(elt, index, array) {
|
||||
const tileMatrixSet = find(tileMatrixSets, function(el) {
|
||||
return el['Identifier'] == elt['TileMatrixSet'];
|
||||
});
|
||||
const supportedCRS = tileMatrixSet['SupportedCRS'];
|
||||
const proj1 = getProjection(supportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3')) ||
|
||||
getProjection(supportedCRS);
|
||||
const proj2 = getProjection(config['projection']);
|
||||
if (proj1 && proj2) {
|
||||
return equivalent(proj1, proj2);
|
||||
} else {
|
||||
return supportedCRS == config['projection'];
|
||||
}
|
||||
idx = findIndex(l['TileMatrixSetLink'], function (elt, index, array) {
|
||||
const tileMatrixSet = find(tileMatrixSets, function (el) {
|
||||
return el['Identifier'] == elt['TileMatrixSet'];
|
||||
});
|
||||
const supportedCRS = tileMatrixSet['SupportedCRS'];
|
||||
const proj1 =
|
||||
getProjection(
|
||||
supportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3')
|
||||
) || getProjection(supportedCRS);
|
||||
const proj2 = getProjection(config['projection']);
|
||||
if (proj1 && proj2) {
|
||||
return equivalent(proj1, proj2);
|
||||
} else {
|
||||
return supportedCRS == config['projection'];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
idx = findIndex(l['TileMatrixSetLink'],
|
||||
function(elt, index, array) {
|
||||
return elt['TileMatrixSet'] == config['matrixSet'];
|
||||
});
|
||||
idx = findIndex(l['TileMatrixSetLink'], function (elt, index, array) {
|
||||
return elt['TileMatrixSet'] == config['matrixSet'];
|
||||
});
|
||||
}
|
||||
} else {
|
||||
idx = 0;
|
||||
@@ -325,16 +324,18 @@ export function optionsFromCapabilities(wmtsCap, config) {
|
||||
if (idx < 0) {
|
||||
idx = 0;
|
||||
}
|
||||
const matrixSet = /** @type {string} */
|
||||
const matrixSet =
|
||||
/** @type {string} */
|
||||
(l['TileMatrixSetLink'][idx]['TileMatrixSet']);
|
||||
const matrixLimits = /** @type {Array<Object>} */
|
||||
const matrixLimits =
|
||||
/** @type {Array<Object>} */
|
||||
(l['TileMatrixSetLink'][idx]['TileMatrixSetLimits']);
|
||||
|
||||
let format = /** @type {string} */ (l['Format'][0]);
|
||||
if ('format' in config) {
|
||||
format = config['format'];
|
||||
}
|
||||
idx = findIndex(l['Style'], function(elt, index, array) {
|
||||
idx = findIndex(l['Style'], function (elt, index, array) {
|
||||
if ('style' in config) {
|
||||
return elt['Title'] == config['style'];
|
||||
} else {
|
||||
@@ -348,7 +349,7 @@ export function optionsFromCapabilities(wmtsCap, config) {
|
||||
|
||||
const dimensions = {};
|
||||
if ('Dimension' in l) {
|
||||
l['Dimension'].forEach(function(elt, index, array) {
|
||||
l['Dimension'].forEach(function (elt, index, array) {
|
||||
const key = elt['Identifier'];
|
||||
let value = elt['Default'];
|
||||
if (value === undefined) {
|
||||
@@ -359,15 +360,17 @@ export function optionsFromCapabilities(wmtsCap, config) {
|
||||
}
|
||||
|
||||
const matrixSets = wmtsCap['Contents']['TileMatrixSet'];
|
||||
const matrixSetObj = find(matrixSets, function(elt, index, array) {
|
||||
const matrixSetObj = find(matrixSets, function (elt, index, array) {
|
||||
return elt['Identifier'] == matrixSet;
|
||||
});
|
||||
|
||||
let projection;
|
||||
const code = matrixSetObj['SupportedCRS'];
|
||||
if (code) {
|
||||
projection = getProjection(code.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3')) ||
|
||||
getProjection(code);
|
||||
projection =
|
||||
getProjection(
|
||||
code.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3')
|
||||
) || getProjection(code);
|
||||
}
|
||||
if ('projection' in config) {
|
||||
const projConfig = getProjection(config['projection']);
|
||||
@@ -382,9 +385,10 @@ export function optionsFromCapabilities(wmtsCap, config) {
|
||||
|
||||
const matrix0 = matrixSetObj.TileMatrix[0];
|
||||
const resolution = matrix0.ScaleDenominator * 0.00028; // WMTS 1.0.0: standardized rendering pixel size
|
||||
const origin = projection === getProjection('EPSG:4326')
|
||||
? [matrix0.TopLeftCorner[1], matrix0.TopLeftCorner[0]]
|
||||
: matrix0.TopLeftCorner;
|
||||
const origin =
|
||||
projection === getProjection('EPSG:4326')
|
||||
? [matrix0.TopLeftCorner[1], matrix0.TopLeftCorner[0]]
|
||||
: matrix0.TopLeftCorner;
|
||||
const tileSpanX = matrix0.TileWidth * resolution;
|
||||
const tileSpanY = matrix0.TileHeight * resolution;
|
||||
|
||||
@@ -392,26 +396,33 @@ export function optionsFromCapabilities(wmtsCap, config) {
|
||||
origin[0],
|
||||
origin[1] - tileSpanY * matrix0.MatrixHeight,
|
||||
origin[0] + tileSpanX * matrix0.MatrixWidth,
|
||||
origin[1]
|
||||
origin[1],
|
||||
];
|
||||
|
||||
if (projection.getExtent() === null) {
|
||||
projection.setExtent(extent);
|
||||
}
|
||||
|
||||
const tileGrid = createFromCapabilitiesMatrixSet(matrixSetObj, extent, matrixLimits);
|
||||
const tileGrid = createFromCapabilitiesMatrixSet(
|
||||
matrixSetObj,
|
||||
extent,
|
||||
matrixLimits
|
||||
);
|
||||
|
||||
/** @type {!Array<string>} */
|
||||
const urls = [];
|
||||
let requestEncoding = config['requestEncoding'];
|
||||
requestEncoding = requestEncoding !== undefined ? requestEncoding : '';
|
||||
|
||||
if ('OperationsMetadata' in wmtsCap && 'GetTile' in wmtsCap['OperationsMetadata']) {
|
||||
if (
|
||||
'OperationsMetadata' in wmtsCap &&
|
||||
'GetTile' in wmtsCap['OperationsMetadata']
|
||||
) {
|
||||
const gets = wmtsCap['OperationsMetadata']['GetTile']['DCP']['HTTP']['Get'];
|
||||
|
||||
for (let i = 0, ii = gets.length; i < ii; ++i) {
|
||||
if (gets[i]['Constraint']) {
|
||||
const constraint = find(gets[i]['Constraint'], function(element) {
|
||||
const constraint = find(gets[i]['Constraint'], function (element) {
|
||||
return element['name'] == 'GetEncoding';
|
||||
});
|
||||
const encodings = constraint['AllowedValues']['Value'];
|
||||
@@ -435,7 +446,7 @@ export function optionsFromCapabilities(wmtsCap, config) {
|
||||
}
|
||||
if (urls.length === 0) {
|
||||
requestEncoding = WMTSRequestEncoding.REST;
|
||||
l['ResourceURL'].forEach(function(element) {
|
||||
l['ResourceURL'].forEach(function (element) {
|
||||
if (element['resourceType'] === 'tile') {
|
||||
format = element['format'];
|
||||
urls.push(/** @type {string} */ (element['template']));
|
||||
@@ -454,7 +465,7 @@ export function optionsFromCapabilities(wmtsCap, config) {
|
||||
style: style,
|
||||
dimensions: dimensions,
|
||||
wrapX: wrapX,
|
||||
crossOrigin: config['crossOrigin']
|
||||
crossOrigin: config['crossOrigin'],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -471,7 +482,7 @@ function createFromWMTSTemplate(template) {
|
||||
const context = {
|
||||
'layer': this.layer_,
|
||||
'style': this.style_,
|
||||
'tilematrixset': this.matrixSet_
|
||||
'tilematrixset': this.matrixSet_,
|
||||
};
|
||||
|
||||
if (requestEncoding == WMTSRequestEncoding.KVP) {
|
||||
@@ -479,7 +490,7 @@ function createFromWMTSTemplate(template) {
|
||||
'Service': 'WMTS',
|
||||
'Request': 'GetTile',
|
||||
'Version': this.version_,
|
||||
'Format': this.format_
|
||||
'Format': this.format_,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -487,14 +498,15 @@ function createFromWMTSTemplate(template) {
|
||||
// order conforms to wmts spec guidance, and so that we can avoid to escape
|
||||
// special template params
|
||||
|
||||
template = (requestEncoding == WMTSRequestEncoding.KVP) ?
|
||||
appendParams(template, context) :
|
||||
template.replace(/\{(\w+?)\}/g, function(m, p) {
|
||||
return (p.toLowerCase() in context) ? context[p.toLowerCase()] : m;
|
||||
});
|
||||
template =
|
||||
requestEncoding == WMTSRequestEncoding.KVP
|
||||
? appendParams(template, context)
|
||||
: template.replace(/\{(\w+?)\}/g, function (m, p) {
|
||||
return p.toLowerCase() in context ? context[p.toLowerCase()] : m;
|
||||
});
|
||||
|
||||
const tileGrid = /** @type {import("../tilegrid/WMTS.js").default} */ (
|
||||
this.tileGrid);
|
||||
const tileGrid = /** @type {import("../tilegrid/WMTS.js").default} */ (this
|
||||
.tileGrid);
|
||||
const dimensions = this.dimensions_;
|
||||
|
||||
return (
|
||||
@@ -504,21 +516,21 @@ function createFromWMTSTemplate(template) {
|
||||
* @param {import("../proj/Projection.js").default} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
function (tileCoord, pixelRatio, projection) {
|
||||
if (!tileCoord) {
|
||||
return undefined;
|
||||
} else {
|
||||
const localContext = {
|
||||
'TileMatrix': tileGrid.getMatrixId(tileCoord[0]),
|
||||
'TileCol': tileCoord[1],
|
||||
'TileRow': tileCoord[2]
|
||||
'TileRow': tileCoord[2],
|
||||
};
|
||||
assign(localContext, dimensions);
|
||||
let url = template;
|
||||
if (requestEncoding == WMTSRequestEncoding.KVP) {
|
||||
url = appendParams(url, localContext);
|
||||
} else {
|
||||
url = url.replace(/\{(\w+?)\}/g, function(m, p) {
|
||||
url = url.replace(/\{(\w+?)\}/g, function (m, p) {
|
||||
return localContext[p];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
*/
|
||||
export default {
|
||||
KVP: 'KVP', // see spec §8
|
||||
REST: 'REST' // see spec §10
|
||||
REST: 'REST', // see spec §10
|
||||
};
|
||||
|
||||
@@ -50,7 +50,6 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
||||
* will be used. If -1, the nearest higher resolution will be used.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source for tile data with URLs in a set XYZ format that are
|
||||
@@ -75,17 +74,19 @@ class XYZ extends TileImage {
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
const options = opt_options || {};
|
||||
const projection = options.projection !== undefined ?
|
||||
options.projection : 'EPSG:3857';
|
||||
const projection =
|
||||
options.projection !== undefined ? options.projection : 'EPSG:3857';
|
||||
|
||||
const tileGrid = options.tileGrid !== undefined ? options.tileGrid :
|
||||
createXYZ({
|
||||
extent: extentFromProjection(projection),
|
||||
maxResolution: options.maxResolution,
|
||||
maxZoom: options.maxZoom,
|
||||
minZoom: options.minZoom,
|
||||
tileSize: options.tileSize
|
||||
});
|
||||
const tileGrid =
|
||||
options.tileGrid !== undefined
|
||||
? options.tileGrid
|
||||
: createXYZ({
|
||||
extent: extentFromProjection(projection),
|
||||
maxResolution: options.maxResolution,
|
||||
maxZoom: options.maxZoom,
|
||||
minZoom: options.minZoom,
|
||||
tileSize: options.tileSize,
|
||||
});
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
@@ -104,11 +105,9 @@ class XYZ extends TileImage {
|
||||
wrapX: options.wrapX !== undefined ? options.wrapX : true,
|
||||
transition: options.transition,
|
||||
attributionsCollapsible: options.attributionsCollapsible,
|
||||
zDirection: options.zDirection
|
||||
zDirection: options.zDirection,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default XYZ;
|
||||
|
||||
@@ -4,27 +4,24 @@
|
||||
import {DEFAULT_TILE_SIZE} from '../tilegrid/common.js';
|
||||
|
||||
import ImageTile from '../ImageTile.js';
|
||||
import TileGrid from '../tilegrid/TileGrid.js';
|
||||
import TileImage from './TileImage.js';
|
||||
import TileState from '../TileState.js';
|
||||
import {expandUrl, createFromTileUrlFunctions} from '../tileurlfunction.js';
|
||||
import {assert} from '../asserts.js';
|
||||
import {createCanvasContext2D} from '../dom.js';
|
||||
import {toSize} from '../size.js';
|
||||
import TileImage from './TileImage.js';
|
||||
import TileGrid from '../tilegrid/TileGrid.js';
|
||||
import {createFromTileUrlFunctions, expandUrl} from '../tileurlfunction.js';
|
||||
import {getCenter} from '../extent.js';
|
||||
|
||||
import {toSize} from '../size.js';
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
const TierSizeCalculation = {
|
||||
DEFAULT: 'default',
|
||||
TRUNCATED: 'truncated'
|
||||
TRUNCATED: 'truncated',
|
||||
};
|
||||
|
||||
|
||||
export class CustomTile extends ImageTile {
|
||||
|
||||
/**
|
||||
* @param {import("../size.js").Size} tileSize Full tile size.
|
||||
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
|
||||
@@ -34,8 +31,15 @@ export class CustomTile extends ImageTile {
|
||||
* @param {import("../Tile.js").LoadFunction} tileLoadFunction Tile load function.
|
||||
* @param {import("../Tile.js").Options=} opt_options Tile options.
|
||||
*/
|
||||
constructor(tileSize, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {
|
||||
|
||||
constructor(
|
||||
tileSize,
|
||||
tileCoord,
|
||||
state,
|
||||
src,
|
||||
crossOrigin,
|
||||
tileLoadFunction,
|
||||
opt_options
|
||||
) {
|
||||
super(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options);
|
||||
|
||||
/**
|
||||
@@ -48,7 +52,6 @@ export class CustomTile extends ImageTile {
|
||||
* @type {import("../size.js").Size}
|
||||
*/
|
||||
this.tileSize_ = tileSize;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,10 +78,8 @@ export class CustomTile extends ImageTile {
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
|
||||
@@ -118,7 +119,6 @@ export class CustomTile extends ImageTile {
|
||||
* will be used. If -1, the nearest higher resolution will be used.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Layer source for tile data in Zoomify format (both Zoomify and Internet
|
||||
@@ -126,18 +126,17 @@ export class CustomTile extends ImageTile {
|
||||
* @api
|
||||
*/
|
||||
class Zoomify extends TileImage {
|
||||
|
||||
/**
|
||||
* @param {Options} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options;
|
||||
|
||||
const size = options.size;
|
||||
const tierSizeCalculation = options.tierSizeCalculation !== undefined ?
|
||||
options.tierSizeCalculation :
|
||||
TierSizeCalculation.DEFAULT;
|
||||
const tierSizeCalculation =
|
||||
options.tierSizeCalculation !== undefined
|
||||
? options.tierSizeCalculation
|
||||
: TierSizeCalculation.DEFAULT;
|
||||
|
||||
const tilePixelRatio = options.tilePixelRatio || 1;
|
||||
const imageWidth = size[0];
|
||||
@@ -148,10 +147,13 @@ class Zoomify extends TileImage {
|
||||
|
||||
switch (tierSizeCalculation) {
|
||||
case TierSizeCalculation.DEFAULT:
|
||||
while (imageWidth > tileSizeForTierSizeCalculation || imageHeight > tileSizeForTierSizeCalculation) {
|
||||
while (
|
||||
imageWidth > tileSizeForTierSizeCalculation ||
|
||||
imageHeight > tileSizeForTierSizeCalculation
|
||||
) {
|
||||
tierSizeInTiles.push([
|
||||
Math.ceil(imageWidth / tileSizeForTierSizeCalculation),
|
||||
Math.ceil(imageHeight / tileSizeForTierSizeCalculation)
|
||||
Math.ceil(imageHeight / tileSizeForTierSizeCalculation),
|
||||
]);
|
||||
tileSizeForTierSizeCalculation += tileSizeForTierSizeCalculation;
|
||||
}
|
||||
@@ -159,10 +161,13 @@ class Zoomify extends TileImage {
|
||||
case TierSizeCalculation.TRUNCATED:
|
||||
let width = imageWidth;
|
||||
let height = imageHeight;
|
||||
while (width > tileSizeForTierSizeCalculation || height > tileSizeForTierSizeCalculation) {
|
||||
while (
|
||||
width > tileSizeForTierSizeCalculation ||
|
||||
height > tileSizeForTierSizeCalculation
|
||||
) {
|
||||
tierSizeInTiles.push([
|
||||
Math.ceil(width / tileSizeForTierSizeCalculation),
|
||||
Math.ceil(height / tileSizeForTierSizeCalculation)
|
||||
Math.ceil(height / tileSizeForTierSizeCalculation),
|
||||
]);
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
@@ -190,11 +195,15 @@ class Zoomify extends TileImage {
|
||||
const tileGrid = new TileGrid({
|
||||
tileSize: tileSize,
|
||||
extent: options.extent || [0, -imageHeight, imageWidth, 0],
|
||||
resolutions: resolutions
|
||||
resolutions: resolutions,
|
||||
});
|
||||
|
||||
let url = options.url;
|
||||
if (url && url.indexOf('{TileGroup}') == -1 && url.indexOf('{tileIndex}') == -1) {
|
||||
if (
|
||||
url &&
|
||||
url.indexOf('{TileGroup}') == -1 &&
|
||||
url.indexOf('{tileIndex}') == -1
|
||||
) {
|
||||
url += '{TileGroup}/{z}-{x}-{y}.jpg';
|
||||
}
|
||||
const urls = expandUrl(url);
|
||||
@@ -206,7 +215,6 @@ class Zoomify extends TileImage {
|
||||
* @return {import("../Tile.js").UrlFunction} Tile URL function.
|
||||
*/
|
||||
function createFromTemplate(template) {
|
||||
|
||||
return (
|
||||
/**
|
||||
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile Coordinate.
|
||||
@@ -214,7 +222,7 @@ class Zoomify extends TileImage {
|
||||
* @param {import("../proj/Projection.js").default} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
function (tileCoord, pixelRatio, projection) {
|
||||
if (!tileCoord) {
|
||||
return undefined;
|
||||
} else {
|
||||
@@ -222,17 +230,17 @@ class Zoomify extends TileImage {
|
||||
const tileCoordX = tileCoord[1];
|
||||
const tileCoordY = tileCoord[2];
|
||||
const tileIndex =
|
||||
tileCoordX +
|
||||
tileCoordY * tierSizeInTiles[tileCoordZ][0];
|
||||
const tileGroup = ((tileIndex + tileCountUpToTier[tileCoordZ]) / tileWidth) | 0;
|
||||
tileCoordX + tileCoordY * tierSizeInTiles[tileCoordZ][0];
|
||||
const tileGroup =
|
||||
((tileIndex + tileCountUpToTier[tileCoordZ]) / tileWidth) | 0;
|
||||
const localContext = {
|
||||
'z': tileCoordZ,
|
||||
'x': tileCoordX,
|
||||
'y': tileCoordY,
|
||||
'tileIndex': tileIndex,
|
||||
'TileGroup': 'TileGroup' + tileGroup
|
||||
'TileGroup': 'TileGroup' + tileGroup,
|
||||
};
|
||||
return template.replace(/\{(\w+?)\}/g, function(m, p) {
|
||||
return template.replace(/\{(\w+?)\}/g, function (m, p) {
|
||||
return localContext[p];
|
||||
});
|
||||
}
|
||||
@@ -240,9 +248,14 @@ class Zoomify extends TileImage {
|
||||
);
|
||||
}
|
||||
|
||||
const tileUrlFunction = createFromTileUrlFunctions(urls.map(createFromTemplate));
|
||||
const tileUrlFunction = createFromTileUrlFunctions(
|
||||
urls.map(createFromTemplate)
|
||||
);
|
||||
|
||||
const ZoomifyTileClass = CustomTile.bind(null, toSize(tileSize * tilePixelRatio));
|
||||
const ZoomifyTileClass = CustomTile.bind(
|
||||
null,
|
||||
toSize(tileSize * tilePixelRatio)
|
||||
);
|
||||
|
||||
super({
|
||||
attributions: options.attributions,
|
||||
@@ -255,7 +268,7 @@ class Zoomify extends TileImage {
|
||||
tileClass: ZoomifyTileClass,
|
||||
tileGrid: tileGrid,
|
||||
tileUrlFunction: tileUrlFunction,
|
||||
transition: options.transition
|
||||
transition: options.transition,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -267,17 +280,21 @@ class Zoomify extends TileImage {
|
||||
// Try loading the center tile for the highest resolution. If it is not
|
||||
// available, we are dealing with retina tiles, and need to adjust the
|
||||
// tile url calculation.
|
||||
const tileUrl = tileGrid.getTileCoordForCoordAndResolution(getCenter(tileGrid.getExtent()), resolutions[resolutions.length - 1]);
|
||||
const tileUrl = tileGrid.getTileCoordForCoordAndResolution(
|
||||
getCenter(tileGrid.getExtent()),
|
||||
resolutions[resolutions.length - 1]
|
||||
);
|
||||
const testTileUrl = tileUrlFunction(tileUrl, 1, null);
|
||||
const image = new Image();
|
||||
image.addEventListener('error', function() {
|
||||
tileWidth = tileSize;
|
||||
this.changed();
|
||||
}.bind(this));
|
||||
image.addEventListener(
|
||||
'error',
|
||||
function () {
|
||||
tileWidth = tileSize;
|
||||
this.changed();
|
||||
}.bind(this)
|
||||
);
|
||||
image.src = testTileUrl;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Zoomify;
|
||||
|
||||
@@ -14,5 +14,5 @@ export const DEFAULT_WMS_VERSION = '1.3.0';
|
||||
*/
|
||||
export const IMAGE_SMOOTHING_DISABLED = {
|
||||
imageSmoothingEnabled: false,
|
||||
msImageSmoothingEnabled: false
|
||||
msImageSmoothingEnabled: false,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user