diff --git a/examples/layer/map.layer.idw.html b/examples/layer/map.layer.idw.html index caa09d16..0f6cf207 100644 --- a/examples/layer/map.layer.idw.html +++ b/examples/layer/map.layer.idw.html @@ -134,6 +134,7 @@

ol-ext: IDW layer

}, /**/ // scale: 8, + // maxD: 1000000, // Source that contains the data source: new ol.source.Vector(), // Use val as weight property diff --git a/src/source/IDW.js b/src/source/IDW.js index d16c74b1..96cb28d3 100644 --- a/src/source/IDW.js +++ b/src/source/IDW.js @@ -16,6 +16,7 @@ import ol_ext_Worker from '../util/Worker.js' * @param {boolean} [options.useWorker=false] use worker to calculate the distance map (may cause flickering on small data sets). Source will fire drawstart, drawend while calculating * @param {Object} [options.lib] Functions that will be made available to operations run in a worker * @param {number} [options.scale=4] scale factor, use large factor to enhance performances (but minor accuracy) + * @param {number} [options.maxD] maximum distance in proj units to compute (default +Infinity). * @param {string|function} options.weight The feature attribute to use for the weight or a function that returns a weight from a feature. Weight values should range from 0 to 100. Default use the weight attribute of the feature. */ var ol_source_IDW = class olsourceIDW extends ol_source_ImageCanvas { @@ -50,7 +51,8 @@ var ol_source_IDW = class olsourceIDW extends ol_source_ImageCanvas { }); } this._position = { extent: [], resolution: 0 }; - this.set('scale', options.scale || 4); + this.set('scale', parseFloat(options.scale) || 4); + this.set('maxD', parseFloat(options.maxD) || 0) this._weight = typeof (options.weight) === 'function' ? options.weight : function (f) { return f.get(options.weight || 'weight'); }; } /** Get the source @@ -104,6 +106,7 @@ var ol_source_IDW = class olsourceIDW extends ol_source_ImageCanvas { var width = e.data.width; var height = e.data.height; var imageData = new Uint8ClampedArray(width * height * 4); + var dm = e.data.maxD * e.data.maxD; // Compute image var x, y; for (y = 0; y < height; y++) { @@ -114,6 +117,10 @@ var ol_source_IDW = class olsourceIDW extends ol_source_ImageCanvas { var dy = y - pts[i][1]; var d = dx * dx + dy * dy; + if (dm && d > dm) { + continue; + } + // Inverse distance weighting - Shepard's method if (d === 0) { b = 1; @@ -124,14 +131,16 @@ var ol_source_IDW = class olsourceIDW extends ol_source_ImageCanvas { t += inv * pts[i][2]; b += inv; } - // Set color - var color = this.getColor(t / b); - // Convert to RGB - var pos = (y * width + x) * 4; - imageData[pos] = color[0]; - imageData[pos + 1] = color[1]; - imageData[pos + 2] = color[2]; - imageData[pos + 3] = color[3]; + if (t>0) { + // Set color + var color = this.getColor(t / b); + // Convert to RGB + var pos = (y * width + x) * 4; + imageData[pos] = color[0]; + imageData[pos + 1] = color[1]; + imageData[pos + 2] = color[2]; + imageData[pos + 3] = color[3]; + } } } return { type: 'image', data: imageData, width: width, height: height }; @@ -171,9 +180,16 @@ var ol_source_IDW = class olsourceIDW extends ol_source_ImageCanvas { pts.push(tr(f.getGeometry().getFirstCoordinate(), this._weight(f))); }.bind(this)); + var message = { + pts: pts, + width: width, + height: height, + maxD: this.get('maxD') ? this.get('maxD') / this.get('scale') / resolution : 0, + resolution: resolution + }; if (this.worker) { // kill old worker and star new one - this.worker.postMessage({ pts: pts, width: width, height: height }, true); + this.worker.postMessage(message, true); this.dispatchEvent({ type: 'drawstart' }); // Move the canvas position meanwhile if (this._canvas.width !== Math.round(size[0]) @@ -189,7 +205,7 @@ var ol_source_IDW = class olsourceIDW extends ol_source_ImageCanvas { } else { this._canvas.width = Math.round(size[0]); this._canvas.height = Math.round(size[1]); - var imageData = this.computeImage({ data: { pts: pts, width: width, height: height } }); + var imageData = this.computeImage({ data: message }); this.onImageData(imageData); }