Skip to content

Commit eed2491

Browse files
committed
Add Raster constructor for creating a new Raster from a matrix of values. Add pixelSize and blockSize methods
1 parent 61d0873 commit eed2491

File tree

3 files changed

+104
-6
lines changed

3 files changed

+104
-6
lines changed

doc/api/raster.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ Methods
5555

5656
A Raster is a spatial data set represented by a grid of cells organized in one or more bands.
5757

58+
Usually, Rasters are read from a Format, but you can create a new Raster from an array or array of numeric values
59+
and a geom.Bounds.
60+
5861
Properties
5962
----------
6063

@@ -99,6 +102,16 @@ Properties
99102
`Object` with min and max arrays with min and max values for each band
100103
Get the minimum and maximum values for each band.
101104

105+
.. attribute:: Raster.blockSize
106+
107+
`Array` with width and height of a pixel
108+
Get the block size
109+
110+
.. attribute:: Raster.pixelSize
111+
112+
`Array` with width and height of a pixel
113+
Get the pixel size
114+
102115
Methods
103116
-------
104117

src/main/java/org/geoscript/js/raster/Raster.java

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
import org.geoscript.js.geom.Geometry;
66
import org.geoscript.js.geom.Point;
77
import org.geoscript.js.proj.Projection;
8-
import org.geotools.coverage.grid.GridCoordinates2D;
9-
import org.geotools.coverage.grid.GridCoverage2D;
10-
import org.geotools.coverage.grid.GridEnvelope2D;
11-
import org.geotools.coverage.grid.GridGeometry2D;
8+
import org.geotools.coverage.Category;
9+
import org.geotools.coverage.GridSampleDimension;
10+
import org.geotools.coverage.grid.*;
1211
import org.geotools.coverage.processing.CoverageProcessor;
1312
import org.geotools.geometry.DirectPosition2D;
1413
import org.geotools.geometry.jts.ReferencedEnvelope;
1514
import org.geotools.process.raster.RangeLookupProcess;
15+
import org.geotools.util.NumberRange;
1616
import org.jaitools.numeric.Range;
1717
import org.mozilla.javascript.*;
1818
import org.mozilla.javascript.annotations.JSConstructor;
@@ -25,7 +25,12 @@
2525
import org.opengis.referencing.crs.CoordinateReferenceSystem;
2626
import org.opengis.referencing.operation.TransformException;
2727

28+
import javax.media.jai.RasterFactory;
29+
import java.awt.*;
30+
import java.awt.image.DataBuffer;
31+
import java.awt.image.WritableRaster;
2832
import java.util.*;
33+
import java.util.List;
2934

3035
public class Raster extends GeoObject implements Wrapper {
3136

@@ -218,6 +223,25 @@ public Object getMaxValue(int band) {
218223
return maxValue;
219224
}
220225

226+
@JSGetter
227+
public NativeArray getBlockSize() {
228+
int[] size = this.coverage.getOptimalDataBlockSizes();
229+
return (NativeArray) javaToJS(Arrays.asList(
230+
size[0],
231+
size[1]
232+
), this.getParentScope());
233+
}
234+
235+
@JSGetter
236+
public NativeArray getPixelSize() {
237+
Bounds bounds = this.getBounds();
238+
NativeArray size = this.getSize();
239+
return (NativeArray) javaToJS(Arrays.asList(
240+
((double) bounds.getWidth()) / ((int)size.get(0)),
241+
((double) bounds.getHeight()) / ((int)size.get(1))
242+
), this.getParentScope());
243+
}
244+
221245
private int getInt(Object obj) {
222246
if (obj instanceof Number) {
223247
return ((Number)obj).intValue();
@@ -238,10 +262,44 @@ public Object unwrap() {
238262

239263
@JSConstructor
240264
public static Object constructor(Context cx, Object[] args, Function ctorObj, boolean inNewExpr) {
265+
NativeArray data = (NativeArray) args[0];
266+
Bounds bounds = (Bounds) args[1];
267+
268+
double min = Double.MAX_VALUE;
269+
double max = Double.MIN_VALUE;
270+
float[][] matrix = new float[(int) data.getLength()][ (int) (data.getLength() > 0 ? ((NativeArray) data.get(0)).getLength() : 0)];
271+
for(int i = 0; i<data.getLength(); i++) {
272+
NativeArray datum = (NativeArray) data.get(i);
273+
for(int j = 0; j<datum.getLength(); j++) {
274+
float value = ((Number)datum.get(j)).floatValue();
275+
if (!Float.isNaN(value) && value < min) {
276+
min = value;
277+
}
278+
if (!Float.isNaN(value) && value > max) {
279+
max = value;
280+
}
281+
matrix[i][j] = value;
282+
}
283+
}
284+
285+
int width = matrix[0].length;
286+
int height = matrix.length;
287+
288+
WritableRaster writableRaster = RasterFactory.createBandedRaster(DataBuffer.TYPE_FLOAT, width, height, 1, null);
289+
for(int i = 0; i<width; i++) {
290+
for(int j = 0; j<height; j++) {
291+
writableRaster.setSample(i, j, 0, matrix[j][i]);
292+
}
293+
}
294+
295+
GridCoverageFactory gridCoverageFactory = new GridCoverageFactory();
296+
Category category = new Category("Raster", Color.BLACK, NumberRange.create(min, max));
297+
GridSampleDimension gridSampleDimension = new GridSampleDimension("Raster", new Category[]{category}, null);
298+
GridCoverage2D coverage = gridCoverageFactory.create("Raster", writableRaster, bounds.unwrap(), new GridSampleDimension[]{gridSampleDimension});
241299
if (inNewExpr) {
242-
return new Raster(null);
300+
return new Raster(coverage);
243301
} else {
244-
return new Raster(ctorObj.getParentScope(), null);
302+
return new Raster(ctorObj.getParentScope(), coverage);
245303
}
246304
}
247305

src/test/resources/org/geoscript/js/tests/geoscript/raster/test_raster.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ var raster = require("geoscript/raster");
55
var geom = require('geoscript/geom');
66
var proj = require('geoscript/proj');
77

8+
exports["test: create a raster from data"] = function() {
9+
var ras = new raster.Raster([
10+
[1,1,1,1,1],
11+
[1,2,2,2,1],
12+
[1,2,3,2,1]
13+
], new geom.Bounds([0,0,10,10]))
14+
assert.ok(ras instanceof raster.Raster, "instance should be Raster");
15+
assert.strictEqual(1, ras.getMinValue(), "Min value should be 1");
16+
assert.strictEqual(3, ras.getMaxValue(), "Max value should be 3");
17+
};
18+
819
exports["test: read a raster"] = function() {
920
var format = new raster.Format({source: admin.raster.source});
1021
var tif = format.read({});
@@ -136,6 +147,22 @@ exports["test: get min and max values for a raster band"] = function() {
136147
assert.strictEqual(255, tif.getMaxValue(0));
137148
};
138149

150+
exports["test: get block size"] = function() {
151+
var format = new raster.Format({source: admin.raster.source});
152+
var tif = format.read({});
153+
var blockSize = tif.blockSize;
154+
assert.strictEqual(900, blockSize[0], "Block Size Width should be 900");
155+
assert.strictEqual(9, blockSize[1], "Block Size Height should be 9 ");
156+
};
157+
158+
exports["test: get pixel size"] = function() {
159+
var format = new raster.Format({source: admin.raster.source});
160+
var tif = format.read({});
161+
var pixelSize = tif.pixelSize;
162+
assert.strictEqual(0.4, pixelSize[0], "Pixel Size Width should be 0.4");
163+
assert.strictEqual(0.4, pixelSize[1], "Pixel Size Height should be 0.4");
164+
};
165+
139166
exports["test: get extrema for all raster bands"] = function() {
140167
var format = new raster.Format({source: admin.raster.source});
141168
var tif = format.read({});

0 commit comments

Comments
 (0)