Search code examples
postgiscontourgeoserver

How to store a grid of values in a PostGIS database such that it can be contoured by GeoServer?


I'm planning to use GeoServer with a PostGIS database to provide contours over a Web Mapping Service.

I have a simple lat-long grid of values which I want to store in the database and have contoured. Whilst the GeoServer user manual implies that it is possible in this example...

https://docs.geoserver.org/stable/en/user/styling/sld/extensions/rendering-transform.html#contour-extraction

...it does not talk about what format the data should be in. Please can anyone suggest a suitable PostGIS database schema I can use that GeoServer will understand and be able to contour? Preferably one which will work with the GeoServer example from the link above.

Thanks for your help.


Solution

  • Since your data is already in a Java program, I would dive into GeoTools which is the underlying library that GeoServer uses to do the actual work.

    Looking at ContourProcess what you actually need is a GridCoverage2D which is basic access to grid data values backed by a two-dimensional rendered image. Each band in an image is represented as a sample dimension.

    So you'd want to take your data array and do something like this:

    WritableRaster raster2 = RasterFactory.createBandedRaster(java.awt.image.DataBuffer.TYPE_INT, w,
        h, 1, null);
    for (int i = 0; i < w; i++) {//width...
         for (int j = 0; j < h; j++) {
             raster2.setSample(i, j, 0, myData[i*w+j]);
         }
    }
    GridCoverageFactory gcf = new GridCoverageFactory();
    // Here I'm using OSGB as I live in the UK you would be using something else
    CoordinateReferenceSystem crs = CRS.decode("EPSG:27700");
    // Position of Lower Left Corner of grid
    int llx = 500000;
    int lly = 105000;
    // Pixel size in projection units
    int resolution = 10;
    ReferencedEnvelope referencedEnvelope = new ReferencedEnvelope(llx, llx + (w * resolution), lly, lly + (h * resolution),
        crs);
    GridCoverage2D gc = gcf.create("name", raster2, referencedEnvelope);
    

    You can either then write it out as a GeoTiff or wrap all the above up into a new Process which returns contours.