add Image source imageSmoothing option

Add Image smoothing checkbox to example

Test imageSmoothing option
This commit is contained in:
mike-000
2020-05-06 21:56:11 +01:00
parent 24c453c6b8
commit 9a8b9d8ade
16 changed files with 130 additions and 20 deletions
+1
View File
@@ -7,3 +7,4 @@ docs: >
tags: "reprojection, projection, proj4js, image, imagestatic" tags: "reprojection, projection, proj4js, image, imagestatic"
--- ---
<div id="map" class="map"></div> <div id="map" class="map"></div>
<div><input type="checkbox" id="imageSmoothing" checked />Image smoothing</div>
+20 -10
View File
@@ -18,22 +18,14 @@ proj4.defs(
register(proj4); register(proj4);
const imageExtent = [0, 0, 700000, 1300000]; const imageExtent = [0, 0, 700000, 1300000];
const imageLayer = new ImageLayer();
const map = new Map({ const map = new Map({
layers: [ layers: [
new TileLayer({ new TileLayer({
source: new OSM(), source: new OSM(),
}), }),
new ImageLayer({ imageLayer,
source: new Static({
url:
'https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/' +
'British_National_Grid.svg/2000px-British_National_Grid.svg.png',
crossOrigin: '',
projection: 'EPSG:27700',
imageExtent: imageExtent,
}),
}),
], ],
target: 'map', target: 'map',
view: new View({ view: new View({
@@ -41,3 +33,21 @@ const map = new Map({
zoom: 4, zoom: 4,
}), }),
}); });
const imageSmoothing = document.getElementById('imageSmoothing');
function setSource() {
const source = new Static({
url:
'https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/' +
'British_National_Grid.svg/2000px-British_National_Grid.svg.png',
crossOrigin: '',
projection: 'EPSG:27700',
imageExtent: imageExtent,
imageSmoothing: imageSmoothing.checked,
});
imageLayer.setSource(source);
}
setSource();
imageSmoothing.addEventListener('change', setSource);
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@@ -0,0 +1,29 @@
import ImageLayer from '../../../src/ol/layer/Image.js';
import Map from '../../../src/ol/Map.js';
import Static from '../../../src/ol/source/ImageStatic.js';
import View from '../../../src/ol/View.js';
import {fromLonLat, transformExtent} from '../../../src/ol/proj.js';
const source = new Static({
url: '/data/tiles/osm/5/5/12.png',
imageExtent: transformExtent([-123, 37, -122, 38], 'EPSG:4326', 'EPSG:3857'),
imageSmoothing: false,
});
new Map({
pixelRatio: 1,
target: 'map',
layers: [
new ImageLayer({
source: source,
}),
],
view: new View({
center: fromLonLat([-122.416667, 37.783333]),
zoom: 12,
}),
});
render({
tolerance: 0.001,
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -0,0 +1,31 @@
import ImageLayer from '../../../src/ol/layer/Image.js';
import Map from '../../../src/ol/Map.js';
import Static from '../../../src/ol/source/ImageStatic.js';
import View from '../../../src/ol/View.js';
import {get as getProjection, transformExtent} from '../../../src/ol/proj.js';
const source = new Static({
url: '/data/tiles/osm/5/5/12.png',
imageExtent: transformExtent([-123, 37, -122, 38], 'EPSG:4326', 'EPSG:3857'),
imageSmoothing: false,
projection: getProjection('EPSG:3857'),
});
new Map({
pixelRatio: 1,
target: 'map',
layers: [
new ImageLayer({
source: source,
}),
],
view: new View({
center: [-122.416667, 37.783333],
zoom: 12,
projection: 'EPSG:4326',
}),
});
render({
tolerance: 0.001,
});
+2
View File
@@ -4,6 +4,7 @@
import CanvasLayerRenderer from './Layer.js'; import CanvasLayerRenderer from './Layer.js';
import ViewHint from '../../ViewHint.js'; import ViewHint from '../../ViewHint.js';
import {ENABLE_RASTER_REPROJECTION} from '../../reproj/common.js'; import {ENABLE_RASTER_REPROJECTION} from '../../reproj/common.js';
import {assign} from '../../obj.js';
import {compose as composeTransform, makeInverse} from '../../transform.js'; import {compose as composeTransform, makeInverse} from '../../transform.js';
import {containsExtent, intersects} from '../../extent.js'; import {containsExtent, intersects} from '../../extent.js';
import {createTransformString} from '../../render/canvas.js'; import {createTransformString} from '../../render/canvas.js';
@@ -180,6 +181,7 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
const dw = img.width * transform[0]; const dw = img.width * transform[0];
const dh = img.height * transform[3]; const dh = img.height * transform[3];
assign(context, this.getLayer().getSource().getContextOptions());
this.preRender(context, frameState); this.preRender(context, frameState);
if (dw >= 0.5 && dh >= 0.5) { if (dw >= 0.5 && dh >= 0.5) {
const opacity = layerState.opacity; const opacity = layerState.opacity;
+12 -2
View File
@@ -32,6 +32,7 @@ class ReprojImage extends ImageBase {
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
* @param {FunctionType} getImageFunction * @param {FunctionType} getImageFunction
* Function returning source images (extent, resolution, pixelRatio). * Function returning source images (extent, resolution, pixelRatio).
* @param {object=} opt_contextOptions Properties to set on the canvas context.
*/ */
constructor( constructor(
sourceProj, sourceProj,
@@ -39,7 +40,8 @@ class ReprojImage extends ImageBase {
targetExtent, targetExtent,
targetResolution, targetResolution,
pixelRatio, pixelRatio,
getImageFunction getImageFunction,
opt_contextOptions
) { ) {
const maxSourceExtent = sourceProj.getExtent(); const maxSourceExtent = sourceProj.getExtent();
const maxTargetExtent = targetProj.getExtent(); const maxTargetExtent = targetProj.getExtent();
@@ -120,6 +122,12 @@ class ReprojImage extends ImageBase {
*/ */
this.sourcePixelRatio_ = sourcePixelRatio; this.sourcePixelRatio_ = sourcePixelRatio;
/**
* @private
* @type {object}
*/
this.contextOptions_ = opt_contextOptions;
/** /**
* @private * @private
* @type {HTMLCanvasElement} * @type {HTMLCanvasElement}
@@ -181,7 +189,9 @@ class ReprojImage extends ImageBase {
image: this.sourceImage_.getImage(), image: this.sourceImage_.getImage(),
}, },
], ],
0 0,
undefined,
this.contextOptions_
); );
} }
this.state = sourceState; this.state = sourceState;
+18 -1
View File
@@ -6,6 +6,7 @@ import ImageState from '../ImageState.js';
import ReprojImage from '../reproj/Image.js'; import ReprojImage from '../reproj/Image.js';
import Source from './Source.js'; import Source from './Source.js';
import {ENABLE_RASTER_REPROJECTION} from '../reproj/common.js'; import {ENABLE_RASTER_REPROJECTION} from '../reproj/common.js';
import {IMAGE_SMOOTHING_DISABLED} from './common.js';
import {abstract} from '../util.js'; import {abstract} from '../util.js';
import {equals} from '../extent.js'; import {equals} from '../extent.js';
import {equivalent} from '../proj.js'; import {equivalent} from '../proj.js';
@@ -62,6 +63,7 @@ export class ImageSourceEvent extends Event {
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] * @property {import("./Source.js").AttributionLike} [attributions]
* @property {boolean} [imageSmoothing=true] Enable image smoothing.
* @property {import("../proj.js").ProjectionLike} [projection] * @property {import("../proj.js").ProjectionLike} [projection]
* @property {Array<number>} [resolutions] * @property {Array<number>} [resolutions]
* @property {import("./State.js").default} [state] * @property {import("./State.js").default} [state]
@@ -105,6 +107,13 @@ class ImageSource extends Source {
* @type {number} * @type {number}
*/ */
this.reprojectedRevision_ = 0; this.reprojectedRevision_ = 0;
/**
* @private
* @type {object|undefined}
*/
this.contextOptions_ =
options.imageSmoothing === false ? IMAGE_SMOOTHING_DISABLED : undefined;
} }
/** /**
@@ -114,6 +123,13 @@ class ImageSource extends Source {
return this.resolutions_; return this.resolutions_;
} }
/**
* @return {Object|undefined} Context options.
*/
getContextOptions() {
return this.contextOptions_;
}
/** /**
* @protected * @protected
* @param {number} resolution Resolution. * @param {number} resolution Resolution.
@@ -173,7 +189,8 @@ class ImageSource extends Source {
pixelRatio, pixelRatio,
sourceProjection sourceProjection
); );
}.bind(this) }.bind(this),
this.contextOptions_
); );
this.reprojectedRevision_ = this.getRevision(); this.reprojectedRevision_ = this.getRevision();
+2
View File
@@ -20,6 +20,7 @@ import {containsExtent, getHeight, getWidth} from '../extent.js';
* the remote server. * the remote server.
* @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given * @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given
* a URL. * a URL.
* @property {boolean} [imageSmoothing=true] Enable image smoothing.
* @property {Object<string,*>} [params] ArcGIS Rest parameters. This field is optional. Service * @property {Object<string,*>} [params] ArcGIS Rest parameters. This field is optional. Service
* defaults will be used for any fields not specified. `FORMAT` is `PNG32` by default. `F` is * defaults will be used for any fields not specified. `FORMAT` is `PNG32` by default. `F` is
* `IMAGE` by default. `TRANSPARENT` is `true` by default. `BBOX`, `SIZE`, `BBOXSR`, and `IMAGESR` * `IMAGE` by default. `TRANSPARENT` is `true` by default. `BBOX`, `SIZE`, `BBOXSR`, and `IMAGESR`
@@ -56,6 +57,7 @@ class ImageArcGISRest extends ImageSource {
super({ super({
attributions: options.attributions, attributions: options.attributions,
imageSmoothing: options.imageSmoothing,
projection: options.projection, projection: options.projection,
resolutions: options.resolutions, resolutions: options.resolutions,
}); });
+2
View File
@@ -36,6 +36,7 @@ import {
* the value returned by the function is later changed then * the value returned by the function is later changed then
* `changed` should be called on the source for the source to * `changed` should be called on the source for the source to
* invalidate the current cached image. See: {@link module:ol/Observable~Observable#changed} * invalidate the current cached image. See: {@link module:ol/Observable~Observable#changed}
* @property {boolean} [imageSmoothing=true] Enable image smoothing.
* @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection. * @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
* @property {number} [ratio=1.5] Ratio. 1 means canvases are the size of the map viewport, 2 means twice the * @property {number} [ratio=1.5] Ratio. 1 means canvases are the size of the map viewport, 2 means twice the
* width and height of the map viewport, and so on. Must be `1` or higher. * width and height of the map viewport, and so on. Must be `1` or higher.
@@ -58,6 +59,7 @@ class ImageCanvasSource extends ImageSource {
super({ super({
attributions: options.attributions, attributions: options.attributions,
imageSmoothing: options.imageSmoothing,
projection: options.projection, projection: options.projection,
resolutions: options.resolutions, resolutions: options.resolutions,
state: options.state, state: options.state,
+2
View File
@@ -32,6 +32,7 @@ import {
* @property {Array<number>} [resolutions] Resolutions. * @property {Array<number>} [resolutions] Resolutions.
* If specified, requests will be made for these resolutions only. * If specified, requests will be made for these resolutions only.
* @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given a URL. * @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given a URL.
* @property {boolean} [imageSmoothing=true] Enable image smoothing.
* @property {Object} [params] Additional parameters. * @property {Object} [params] Additional parameters.
*/ */
@@ -48,6 +49,7 @@ class ImageMapGuide extends ImageSource {
*/ */
constructor(options) { constructor(options) {
super({ super({
imageSmoothing: options.imageSmoothing,
projection: options.projection, projection: options.projection,
resolutions: options.resolutions, resolutions: options.resolutions,
}); });
+2
View File
@@ -19,6 +19,7 @@ import {get as getProjection} from '../proj.js';
* @property {import("../extent.js").Extent} [imageExtent] Extent of the image in map coordinates. * @property {import("../extent.js").Extent} [imageExtent] Extent of the image in map coordinates.
* This is the [left, bottom, right, top] map coordinates of your image. * This is the [left, bottom, right, top] map coordinates of your image.
* @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given a URL. * @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given a URL.
* @property {boolean} [imageSmoothing=true] Enable image smoothing.
* @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection. * @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
* @property {import("../size.js").Size} [imageSize] Size of the image in pixels. Usually the image size is auto-detected, so this * @property {import("../size.js").Size} [imageSize] Size of the image in pixels. Usually the image size is auto-detected, so this
* only needs to be set if auto-detection fails for some reason. * only needs to be set if auto-detection fails for some reason.
@@ -45,6 +46,7 @@ class Static extends ImageSource {
super({ super({
attributions: options.attributions, attributions: options.attributions,
imageSmoothing: options.imageSmoothing,
projection: getProjection(options.projection), projection: getProjection(options.projection),
}); });
+2
View File
@@ -39,6 +39,7 @@ const GETFEATUREINFO_IMAGE_SIZE = [101, 101];
* @property {import("./WMSServerType.js").default|string} [serverType] The type of * @property {import("./WMSServerType.js").default|string} [serverType] The type of
* the remote WMS server: `mapserver`, `geoserver` or `qgis`. Only needed if `hidpi` is `true`. * the remote WMS server: `mapserver`, `geoserver` or `qgis`. Only needed if `hidpi` is `true`.
* @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given a URL. * @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given a URL.
* @property {boolean} [imageSmoothing=true] Enable image smoothing.
* @property {Object<string,*>} params WMS request parameters. * @property {Object<string,*>} params WMS request parameters.
* At least a `LAYERS` param is required. `STYLES` is * At least a `LAYERS` param is required. `STYLES` is
* `''` by default. `VERSION` is `1.3.0` by default. `WIDTH`, `HEIGHT`, `BBOX` * `''` by default. `VERSION` is `1.3.0` by default. `WIDTH`, `HEIGHT`, `BBOX`
@@ -68,6 +69,7 @@ class ImageWMS extends ImageSource {
super({ super({
attributions: options.attributions, attributions: options.attributions,
imageSmoothing: options.imageSmoothing,
projection: options.projection, projection: options.projection,
resolutions: options.resolutions, resolutions: options.resolutions,
}); });
+7
View File
@@ -140,6 +140,13 @@ class Source extends BaseObject {
return this.wrapX_; return this.wrapX_;
} }
/**
* @return {Object|undefined} Context options.
*/
getContextOptions() {
return undefined;
}
/** /**
* Refreshes the source. The source will be cleared, and data from the server will be reloaded. * Refreshes the source. The source will be cleared, and data from the server will be reloaded.
* @api * @api
-7
View File
@@ -173,13 +173,6 @@ class TileSource extends Source {
return covered; return covered;
} }
/**
* @return {Object|undefined} Context options.
*/
getContextOptions() {
return undefined;
}
/** /**
* @param {import("../proj/Projection.js").default} projection Projection. * @param {import("../proj/Projection.js").default} projection Projection.
* @return {number} Gutter. * @return {number} Gutter.