forked from Turfjs/turf
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Turfjs#366 from miccferr/master
Add turf IDW package - issue Turfjs#329
- Loading branch information
Showing
9 changed files
with
19,088 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Inverse Distance Weighting (I.D.W.) | ||
|
||
Inverse Distance Weighting (IDW) is a type of deterministic, nonlinear interpolation method over a set of points. | ||
|
||
### `IDW(controlPoints, valueField, b, cellWidth, units)` | ||
|
||
Takes a [FeatureCollection](http://geojson.org/geojson-spec.html#feature-collection-objects)<[Point](http://geojson.org/geojson-spec.html#point)> of sampled points with a property of *known value* and returns a [FeatureCollection](http://geojson.org/geojson-spec.html#feature-collection-objects)<[Polygon](http://geojson.org/geojson-spec.html#polygon)> [grid](http://turfjs.org/docs/#squaregrid) with an *interpolated value* for each grid cell, according to a distance-decay exponent and a cell depth parameter (in the specified unit of measurement). | ||
|
||
It is based on the [Inverse Distance Weighting](https://en.wikipedia.org/wiki/Inverse_distance_weighting) interpolation algorithm as covered in the following resources: [1], [2]. | ||
|
||
It finds application when in need of creating a continuous surface (i.e. rainfall, temperature, chemical dispersion surface...) from a set of spatially scattered points. | ||
|
||
|
||
|
||
|
||
### Parameters | ||
|
||
| parameter | type | description | | ||
| ----------- | -------------- | ---------------------------------------- | | ||
| `controlPoints` | **[FeatureCollection](http://geojson.org/geojson-spec.html#feature-collection-objects)<[Point](http://geojson.org/geojson-spec.html#point)>** | Sampled points with known value | | ||
| `valueField` | **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** | GeoJSON field containing the known value to interpolate on | | ||
| `b` | **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** | Exponent regulating the distance-decay weighting | | ||
| `cellWidth` |**[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** | Width of each cell | | ||
| `units` |**[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** | Units to use for cellWidth ('miles' or 'kilometers')| | ||
|
||
### Example | ||
|
||
```js | ||
// load IDW | ||
var IDW = require('./index.js') | ||
|
||
// load a sample of test points | ||
var fs = require('fs'); | ||
var controlPoints = JSON.parse(fs.readFileSync('./data/data.geojson')); | ||
|
||
// produce an interpolated surface | ||
var IDWSurface = IDW(controlPoints,'value', 0.5, 0.1,'kilometers'); | ||
|
||
``` | ||
Returns a **[FeatureCollection](http://geojson.org/geojson-spec.html#feature-collection-objects)<[Polygon](http://geojson.org/geojson-spec.html#polygon)>** grid of polygons with a property field `IDW` | ||
|
||
|
||
## Installation & Use | ||
|
||
Requires [nodejs](http://nodejs.org/). | ||
|
||
`Git clone` this repo, then `require` it | ||
|
||
## Tests | ||
|
||
```sh | ||
$ npm test | ||
``` | ||
|
||
## Resources | ||
[1] _O’Sullivan, D., & Unwin, D. (2010). Geographic Information Analysis (2nd Edition). 432pp. Hoboken, New Jersey (USA): John Wiley & Sons, Inc._ | ||
|
||
[2] _Xiao, N. (2016). GIS Algorithms, 336pp. SAGE Publications Ltd._ | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
{ | ||
"type": "FeatureCollection", | ||
"features": [ | ||
{ | ||
"type": "Feature", | ||
"properties": { | ||
"marker-color": "#7e7e7e", | ||
"marker-size": "medium", | ||
"marker-symbol": "", | ||
"value": 4, | ||
"id": 4 | ||
}, | ||
"geometry": { | ||
"type": "Point", | ||
"coordinates": [ | ||
9.155731201171875, | ||
45.47216977418841 | ||
] | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"properties": { | ||
"marker-color": "#7e7e7e", | ||
"marker-size": "medium", | ||
"marker-symbol": "", | ||
"value": 99, | ||
"id": 2 | ||
}, | ||
"geometry": { | ||
"type": "Point", | ||
"coordinates": [ | ||
9.195213317871094, | ||
45.53689620055365 | ||
] | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"properties": { | ||
"marker-color": "#7e7e7e", | ||
"marker-size": "medium", | ||
"marker-symbol": "", | ||
"value": 10, | ||
"id": 1 | ||
}, | ||
"geometry": { | ||
"type": "Point", | ||
"coordinates": [ | ||
9.175300598144531, | ||
45.49912810913339 | ||
] | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"properties": { | ||
"marker-color": "#7e7e7e", | ||
"marker-size": "medium", | ||
"marker-symbol": "", | ||
"value": 6, | ||
"id": 3 | ||
}, | ||
"geometry": { | ||
"type": "Point", | ||
"coordinates": [ | ||
9.231605529785156, | ||
45.49190839157102 | ||
] | ||
} | ||
}, | ||
{ | ||
"type": "Feature", | ||
"properties": { | ||
"marker-color": "#7e7e7e", | ||
"marker-size": "medium", | ||
"marker-symbol": "", | ||
"value": 7, | ||
"id": 5 | ||
}, | ||
"geometry": { | ||
"type": "Point", | ||
"coordinates": [ | ||
9.116249084472656, | ||
45.4391764115696 | ||
] | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
var filter = require('turf-filter'); | ||
var distance = require('turf-distance'); | ||
var squareGrid = require('turf-square-grid'); | ||
var centroid = require('turf-centroid'); | ||
var extent = require('turf-extent'); | ||
|
||
/** | ||
* | ||
* Takes a FeatureCollection of points with known value, a power parameter, a cell depth, a unit of measurement | ||
* and returns a FeatureCollection of polygons in a square-grid with an interpolated value property "IDW" for each grid cell. | ||
* It finds application when in need of creating a continuous surface (i.e. rainfall, temperature, chemical dispersion surface...) | ||
* from a set of spatially scattered points. | ||
* | ||
* @param {FeatureCollection<Point>} controlPoints Sampled points with known value | ||
* @param {String} valueField GeoJSON field containing the known value to interpolate on | ||
* @param {Number} b Exponent regulating the distance-decay weighting | ||
* @param {Number} cellWidth The distance across each cell | ||
* @param {String} units Units to use for cellWidth ('miles' or 'kilometers') | ||
* @return {FeatureCollection<Polygon>} grid A grid of polygons with a property field "IDW" | ||
*/ | ||
module.exports = function (controlPoints, valueField, b, cellWidth, units) { | ||
// check if field containing data exists.. | ||
var filtered = filter(controlPoints, valueField); | ||
//alternative method | ||
// console.log(controlPoints.features.map(function (feat) { return valueField in feat.properties})); | ||
if (filtered.features.length === 0) { | ||
// create a sample square grid | ||
// compared to a point grid helps visualizing the output (like a raster..) | ||
var samplingGrid = squareGrid(extent(controlPoints), cellWidth, units); | ||
var N = samplingGrid.features.length; | ||
// for every sampling point.. | ||
var myFun = function (point, i, zw, sw) { | ||
var d = distance(centroid(samplingGrid.features[i]), point, units); | ||
if (d === 0) { | ||
zw = point.properties[valueField]; | ||
return zw; | ||
} | ||
var w = 1.0 / Math.pow(d, b); | ||
sw += w; | ||
zw += w * point.properties[valueField]; | ||
}; | ||
for (var i = 0; i < N; i++) { | ||
var zw = 0; | ||
var sw = 0; | ||
// calculate the distance from each control point to cell's centroid | ||
controlPoints.features.map(myFun); | ||
// write IDW value for each grid cell | ||
samplingGrid.features[i].properties.z = zw / sw; | ||
} | ||
return samplingGrid; | ||
|
||
} else { | ||
console.log('Specified Data Field is Missing'); | ||
} | ||
|
||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "idw-js", | ||
"version": "1.0.0", | ||
"description": "Today a plain IDW alg. implemented in JS. Tomorrow a Turf.js package? Maybe?", | ||
"main": "index.js", | ||
"directories": { | ||
"test": "tests" | ||
}, | ||
"dependencies": { | ||
"turf-centroid": "^1.1.3", | ||
"turf-distance": "^1.1.0", | ||
"turf-extent": "^1.0.4", | ||
"turf-filter": "^1.0.1", | ||
"turf-square-grid": "^1.0.1" | ||
}, | ||
"devDependencies": { | ||
"tape": "^4.5.1" | ||
}, | ||
"scripts": { | ||
"test": "node test.js" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/miccferr/idw-js.git" | ||
}, | ||
"author": "Michele Ferretti", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/miccferr/idw-js/issues" | ||
}, | ||
"homepage": "https://github.com/miccferr/idw-js#readme" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
var test = require('tape'); | ||
var idw = require('./'); | ||
var fs = require('fs'); | ||
|
||
test('idw', function (t) { | ||
var testPoints = JSON.parse(fs.readFileSync('./data/data.geojson')); | ||
|
||
var idw1 = idw(testPoints,'value' , 0.5 , 1, 'kilometers'); | ||
var idw2 = idw(testPoints,'value', 0.5 ,0.5, 'kilometers'); | ||
var idw3 = idw(testPoints,'value', 2 , 1, 'miles'); | ||
var idw4 = idw(testPoints, 'WRONGDataField', 0.5, 1, 'miles'); | ||
|
||
t.ok(idw1.features.length); | ||
t.ok(idw2.features.length); | ||
t.ok(idw3.features.length); | ||
t.error(idw4); | ||
|
||
fs.writeFileSync(__dirname+'/tests/idw1.geojson', JSON.stringify(idw1,null,2)); | ||
fs.writeFileSync(__dirname+'/tests/idw2.geojson', JSON.stringify(idw2,null,2)); | ||
fs.writeFileSync(__dirname+'/tests/idw3.geojson', JSON.stringify(idw3,null,2)); | ||
|
||
|
||
t.end(); | ||
}); |
Oops, something went wrong.