[GIS] Creating Coveragestore GeoTIFF using REST API

geoservergeoserver-rest-api

I need to create a layer by uploading a GeoTIFF file.

After reading Adding a new Coveragestore in a certain Workspace by REST and Programming Geoserver 2.0.2 to add a raster data store and layer without the UI I create a method to do this using Java.

My problem is after creating the workspace and when trying to create the store (using PUT) my server returns error 500. The Geoserver Log:

        Version = 1.3.0
        Request = GetMap
        Get = true
        RawKvp = {REQUEST=GetMap, FORMAT=image/png, CRS=EPSG:3857, BBOX=-4852834.05176927,-2661231.576776698,-4696291.017841228,-2504688.5428486574, VERSION=1.3.0, STYLES=, SERVICE=WMS, WIDTH=256, HEIGHT=256, TRANSPARENT=true, LAYERS=osm:AA_OpenStreetMap}
        BaseUrl = http://10.5.115.122:80/geoserver/
        RequestCharset = UTF-8
2016-11-17 11:21:41,742 ERROR [geoserver.rest] - No such layer: Carta_puntarenas
2016-11-17 11:21:41,742 ERROR [geoserver.rest] -
org.geoserver.rest.RestletException
        at org.geoserver.catalog.rest.LayerFinder.findTarget(LayerFinder.java:39)
        at org.restlet.Finder.handle(Finder.java:268)
        at org.geoserver.rest.BeanDelegatingRestlet.handle(BeanDelegatingRestlet.java:38)
        at org.restlet.Filter.doHandle(Filter.java:105)
        at org.restlet.Filter.handle(Filter.java:134)
        at org.restlet.Router.handle(Router.java:444)
        at org.geoserver.rest.RESTDispatcher$1.handle(RESTDispatcher.java:205)
        at com.noelios.restlet.ext.servlet.ServletConverter.service(ServletConverter.java:129)

The 3 steps method in second post is more convenient but I have no way to send the file to the server and can't fill the URL store attribute.

The 2 steps of first post is what I'm doing since I can send a PUT and hope the Geoserver can resolve the URL itself (don't know where the file will be stored) but the create layer part was not shown.

The ported Java code to PUT is like this:

public int doPutFile( File file, String contentType, String url, String content, String geoUser, String geoPassword ) throws Exception {
    int code = 0;

    String geoCreds = geoUser + ":" + geoPassword;
    String encodedAuth = new String( Base64.encodeBase64( geoCreds.getBytes() ) );
    HttpURLConnection con = (HttpURLConnection) new URL( url ).openConnection();
    con.setRequestMethod( "PUT" );
    con.setRequestProperty("Authorization", "Basic " + encodedAuth );
    con.setRequestProperty("User-Agent", USER_AGENT);
    con.setRequestProperty("Content-type", contentType);
    con.setConnectTimeout( 120000 );

    con.setDoOutput(true);
    OutputStream outputStream = con.getOutputStream();
    FileInputStream streamFileInputStream = new FileInputStream( file );
    BufferedInputStream streamFileBufferedInputStream = new BufferedInputStream(streamFileInputStream);     

    byte[] streamFileBytes = new byte[ 512 ];
    int bytesRead = 0;

    while ((bytesRead = streamFileBufferedInputStream.read(streamFileBytes)) > 0) {
        outputStream.write(streamFileBytes, 0, bytesRead);
    }       
    outputStream.flush();

    code = con.getResponseCode();

    try {
        InputStream inputStream = con.getInputStream();
        StringWriter writer = new StringWriter();
        IOUtils.copy(inputStream, writer, "UTF-8");
        String theString = writer.toString();
        inputStream.close();

        System.out.println( theString );

    } catch ( Exception e ) {
        e.printStackTrace();
    }       

    con.disconnect();
    streamFileBufferedInputStream.close();
    return code;        
}

and the code to POST:

public int doRESTRequest( String requestMethod, String url, String content, String geoUser, String geoPassword ) throws Exception {
    int code = 0;

    String geoCreds = geoUser + ":" + geoPassword;
    String encodedAuth = new String( Base64.encodeBase64( geoCreds.getBytes() ) );
    HttpURLConnection con = (HttpURLConnection) new URL( url ).openConnection();
    con.setRequestMethod( requestMethod );
    con.setRequestProperty("Authorization", "Basic " + encodedAuth );
    con.setRequestProperty("User-Agent", USER_AGENT);
    con.setRequestProperty("Content-type", "text/xml");

    con.setDoOutput(true);
    con.getOutputStream().write( content.getBytes("UTF-8") );
    code = con.getResponseCode();

    // To use with GET method
    try {
        InputStream inputStream = con.getInputStream();
        StringWriter writer = new StringWriter();
        IOUtils.copy(inputStream, writer, "UTF-8");
        String theString = writer.toString();
        inputStream.close();
        //System.out.println( "WebClient:doPostStream >>> " + theString );
    } catch ( Exception e ) {
        //e.printStackTrace();
    }

    con.disconnect();
    return code;

}

… and to upload and create the TIFF Layer:

StringBuilder postData = new StringBuilder();
postData.append("<coverageStore>");
postData.append("<name>" + storeName + "</name>");
postData.append("<workspace>" + workspaceName + "</workspace>");
postData.append("<enabled>true</enabled>");
postData.append("<description>Some description</description>");
postData.append("<type>GeoTIFF</type>");
postData.append("<srs>EPSG:4326</srs><projectionPolicy>REPROJECT_TO_DECLARED</projectionPolicy>");
postData.append("</coverageStore>");

String serverRESTAPIStore = geoserverURL + "rest/workspaces/" + workspaceName + "/coveragestores";
WebClient wc = new WebClient();
resp = wc.doRESTRequest( "POST", serverRESTAPIStore, postData.toString(), geoUser, geoPassword );           



String serverRESTAPI = geoserverURL + "rest/workspaces/" + workspaceName + "/coveragestores/" + storeName + "/external.geotiff?configure=first&coverageName=" + storeName;
int result = wc.doPutFile( file, "geotif/geotiff", serverRESTAPI, "", geoUser, geoPassword );

The tiff file is named Carta_puntarenas.tif and have 75MB.

Best Answer

2020 update,

Using geoserver-rest library(pip install geoserver-rest). The example case is below,

#import and initialize library
from geo.Geoserver import Geoserver
geo = Geoserver('http://localhost:8080/geoserver', username='admin', password='geoserver')


#Create/upload coveragestore (raster data)
geo.create_coveragestore(lyr_name='layer1' path=r'path\to\raster\file.tif', workspace='demo')