GMLCov in JSON Implementing JSON GeoJSON in an OGC Standard Engineering Report
Copyright © 2015 Open Geospatial Consortium.
63 Here we are applying the XML to JSON general rules to convert the GMLCov into a
JSON file with some exceptions. We are also proposing an example based on a dataset called etopo20 that presents the elevation and bathymetry:
http:www.monsoondata.org:9090dodstoporoseetopo20.info
Figure 8: ETOPO20 dataset
The structure of the coverage JSON is:
{ type: GridCoverage,
id: http:www.someserver.comexamplesC0001, bbox: [-180, -90, 180, 90],
domainSet: {...} rangeSet: {...}
rangeType: {...} }
The domainSet allow us to define the axis
and their units, the pixel size
, the origin
and the number of
rows and columns of the image. Please note the use of GeoJSON in some
part.
domainSet: {
type:: RectifiedGrid, id: http:www.someserver.comexamplesrg0001_C0001,
dimension: 2, axisLabels: [Long, Lat],
origin: {
geometry: {
crs: http:www.opengis.netdefcrsOGC1.3CRS84,
64
Copyright © 2015 Open Geospatial Consortium.
type: Point, coordinates: [ -180, -90]
} },
offsetVectors: [ { geometry:{
crs: http:www.opengis.netdefcrsOGC1.3CRS84,
type: Point, coordinates: [ 0.0,
0.333333333333334 ]
}, properties:{
axisLabel: Long, low: 0,
high: 1080
}},{ geometry:{
crs: http:www.opengis.netdefcrsOGC1.3CRS84,
type: Point, coordinates: [
-0.333333333333334 , 0.0]
}, properties:{
axisLabel: Lat, low: 0,
high: 540
} }]
},
The rangeType is useful for defining the semantics of the values in the coverage, its units and, also, the expected
range of values .
rangeType: {
fields: [{ name: elevation,
type: quantity, definition: https:schema.orgelevation,
description: Height, uom:
{ id: http:www.opengis.netdefuomOGC1.0metre,
code: m, title: meters
}, allowedValues:
{
Copyright © 2015 Open Geospatial Consortium.
65
low: -7810, high: 7000,
significantFigures: 4 }
}] }
}
For the rangeSet one immediate possibility could be to include the values directly as an array. We all know this is not a very efficient encoding so we could include a scale and
translate values to scale and translate the values to a numeric range that is more compact in the same way that is suggested in topoJSON for the coordinates array.
rangeSet: {
dataBlocks:[ {
name: elevation, scale: 1,
translate: 0, values: [-4115,-4114,-4113,-4113,...,2783,2782,2782]
}] },
We could wonder if this encoding is useful. The answer lies on the new characteristics of HTML5. The canvas new object allows for editing the individual pixel values of the
canvas. This way it is possible to inject the coverage JSON values array into the canvas object and represent the data as an image without any client intervention. The following
code fragment shows the data in a coverage JSON called “image” in a gray scale into a “map” canvas.
function DrawCoveragemap, image {
var i_cell=0, i_data=0, j, i, value256, a;
var c=document.getElementByIdmap; if c==null
{ alertNo support for canvas detected;
return; }
c.width = image.domainSet.offsetVectors[0].properties.high- image.domainSet.offsetVectors[0].properties.low;
c.height = image.domainSet.offsetVectors[1].properties.high- image.domainSet.offsetVectors[1].properties.low;
var ctx=c.getContext2d; ctx.clearRect 0, 0, ctx.canvas.width, ctx.canvas.height;
66
Copyright © 2015 Open Geospatial Consortium.
var imgData=ctx.createImageDatac.width,c.height; a=256image.rangeType.fields[0].allowedValues.high –
image.rangeType.fields[0].allowedValues.low; for j=0;jimgData.height;j++
{ for i=0;iimgData.width;i++
{ value256=Math.floora
image.rangeSet.dataBlocks[0].values[i_cell] - image.rangeType.fields[0].allowedValues.low;
imgData.data[i_data+0]=value256; imgData.data[i_data+1]=value256;
imgData.data[i_data+2]=value256; imgData.data[i_data+3]=256;
i_cell++; i_data+=4;
} }
ctx.putImageDataimgData,0,0; }
As we already said, encoding raster values as text is not very efficient. Binary encodings are better. We can modify the rangeSet fragment to include a link to a binary file.
rangeSet: {
files:[ {
name: elevation, scale: 1,
translate: 0, fileName: http:www.server.combinaryetopo20.img
}] },
We could wonder if this encoding can be of any use in an Internet browser. Again there is an answer the new characteristics of HTML5. HTML5 has extended JavaScript capability
with binary arrays. This means that it is now possible to download a binary file using AJAX, load it into a buffer array and then interpret it. The following function is able to
download a binary file and deliver it:
function loadCoverageFilepath, success, error {
var xhr = new XMLHttpRequest;
Copyright © 2015 Open Geospatial Consortium.
67
xhr.onreadystatechange = function {
if xhr.readyState === XMLHttpRequest.DONE { if xhr.status === 200 {
if success successxhr.response;
} else { if error
errorxhr.statusText; }
} };
xhr.openGET, path, true;
xhr.responseType = arraybuffer; xhr.send;
}
The following function loads it in the JavaScript representation of the coverage JSON:
function FileToDrawCoverageab {
if image.rangeSet.dataBlocks==null image.rangeSet.dataBlocks=new Array1;
if image.rangeSet.dataBlocks[0]==null image.rangeSet.dataBlocks[0]=new Object;
image.rangeSet.dataBlocks[0].arrayBuffer=ab; }
The following function uses its values and sends them to the canvas. In this code we assume that the file has only int16 values singed short int for the values of the cells with
no header and no compression. We use little endian byte order.
function DrawCoveragemap, image, palette, filter {
var i_cell=0, i_data=0, j, i, value, value256, a;
var c=document.getElementByIdmap; if c==null
{ alertNo support for canvas detected;
return; }
c.width = image.domainSet.offsetVectors[0].properties.high- image.domainSet.offsetVectors[0].properties.low;
c.height = image.domainSet.offsetVectors[1].properties.high- image.domainSet.offsetVectors[1].properties.low;
var ctx=c.getContext2d; ctx.clearRect 0, 0, ctx.canvas.width, ctx.canvas.height;
68
Copyright © 2015 Open Geospatial Consortium.
var imgData=ctx.createImageDatac.width,c.height; var dv=new DataViewimage.rangeSet.dataBlocks[0].arrayBuffer;
a=256image.rangeType.fields[0].allowedValues.high – image.rangeType.fields[0].allowedValues.low;
for j=0;jimgData.height;j++ {
for i=0;iimgData.width;i++ {
value=dv.getInt16i_cell2, littleEndian; value256=Math.flooravalue-
image.rangeType.fields[0].allowedValues.low; imgData.data[i_data+0]=value256;
imgData.data[i_data+1]=value256; imgData.data[i_data+2]=value256;
imgData.data[i_data+3]=256; i_cell++;
i_data+=4; }
} ctx.putImageDataimgData,0,0;
}
A small demonstration based on the previous code is available at http:www.creaf.uab.catjoanmacoveragejson.
Coverage JSON in combination with HTML5 opens the possibility that a WCS serving coverage JSON can be used by a web browser client to show fragments of coverage data
without the need of an intermediate image file or a WMS interface. The client will be able to change visualization options of even to make operations between coverages
directly in the web browser because it has the actual data instead of a simple image.
Recommendation 23: Elaborate a converge JSON as a new standard encoding for GMLCov. Target: WCS.SWG
10 JSON in Web Services