6

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.

2 Answers 2

3

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')

0

Found the solution:

First: I can do it in just one step:

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

Sending the file is enough to create the store.

Other: The file name mustbe file.geotiff. I don't know why. So I changed to

String serverRESTAPI = geoserverURL + "rest/workspaces/" + workspaceName + 
                "/coveragestores/" + storeName + "/file.geotiff"; 

All working now.

5
  • 1
    because if you use the parameter file.tif it tells GeoServer you are sending a tif file - if you used file.png it would expect a png file
    – Ian Turton
    Commented Nov 18, 2016 at 11:42
  • I'm thinking the Content-type is controlling this. But makes sense.
    – Magno C
    Commented Nov 18, 2016 at 11:45
  • 1
    content-type could be application/zip for example
    – Ian Turton
    Commented Nov 18, 2016 at 11:47
  • Oh yes? Can I pass a zipped geotiff file when creating the coverage store? Cool!
    – Magno C
    Commented Nov 18, 2016 at 13:07
  • Zipping should make no difference to a compressed tif, but could package a tif plus world file.
    – Ian Turton
    Commented Nov 18, 2016 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.