Skip to content

Commit

Permalink
[ADD] IDW max distance #1092
Browse files Browse the repository at this point in the history
  • Loading branch information
Viglino committed Aug 2, 2024
1 parent f111a80 commit 1786e97
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
1 change: 1 addition & 0 deletions examples/layer/map.layer.idw.html
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ <h1>ol-ext: IDW layer</h1>
},
/**/
// scale: 8,
// maxD: 1000000,
// Source that contains the data
source: new ol.source.Vector(),
// Use val as weight property
Expand Down
38 changes: 27 additions & 11 deletions src/source/IDW.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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++) {
Expand All @@ -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;
Expand All @@ -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 };
Expand Down Expand Up @@ -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])
Expand All @@ -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);
}

Expand Down

0 comments on commit 1786e97

Please sign in to comment.