0

I have been trying to retrieve image from WMS in Java using the Geotools and save the image locally. I have simply followed this link https://gitlab.com/-/snippets/1883964 by Ian Turton and from the official documentation https://docs.geotools.org/latest/userguide/extension/wms/wms.html

My code is

package wmsexplore;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;

import org.apache.commons.io.IOUtils;
import org.geotools.ows.ServiceException;
import org.geotools.ows.wms.WebMapServer;
import org.geotools.ows.wms.request.GetMapRequest;
import org.geotools.ows.wms.response.GetMapResponse;

public class WMSConnector {
  public static void main(String[] args) {


    URL url = null;
    try {
      url = new URL("http://maps.heigit.org/osm-wms/service?service=WMS&request=GetCapabilities&version=1.1.0");
    } catch (MalformedURLException e) {
      // will not happen
    }

    WebMapServer wms = null;
    try {
      wms = new WebMapServer(url);
      GetMapRequest request = wms.createGetMapRequest();
      request.addLayer("osm_auto:all", "");
      String format = "image/png";
      request.setFormat(format);
      request.setDimensions("1000", "1000"); // sets the dimensions of the image
                                           // to be returned from the server
      request.setTransparent(true);
      request.setSRS("EPSG:4326");
      request.setBBox("-71.13,42.32,-71.03,42.42");

      try {
        GetMapResponse response = (GetMapResponse) wms.issueRequest(request);
        if (response.getContentType().equalsIgnoreCase(format)) {
          BufferedImage image = ImageIO.read(response.getInputStream());
          File outputfile = new File("saved.png");
          ImageIO.write(image, "png", outputfile);
        } else {
          StringWriter writer = new StringWriter();
          IOUtils.copy(response.getInputStream(), writer);
          String error = writer.toString();
          System.out.println(error);

        }
      } catch (ServiceException | IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

      }
    } catch (IOException e) {
      // There was an error communicating with the server
      // For example, the server is down
    } catch (ServiceException e) {
      // The server returned a ServiceException (unusual in this case)
    }

  }
}

The error I have been getting is :

Feb 09, 2022 2:09:36 AM org.geotools.xml.XMLSAXHandler fatalError
SEVERE: FATAL White spaces are required between publicId and systemId.
Feb 09, 2022 2:09:36 AM org.geotools.xml.XMLSAXHandler fatalError
SEVERE: col 50, line 1
Feb 09, 2022 2:09:36 AM org.geotools.data.ows.AbstractOpenWebService internalIssueRequest
SEVERE: Failed to execute request http://maps.heigit.org/osm-wms/service?REQUEST=GetCapabilities&VERSION=1.1.0&SERVICE=WMS
Feb 09, 2022 2:09:36 AM org.geotools.xml.XMLSAXHandler fatalError
SEVERE: FATAL White spaces are required between publicId and systemId.
Feb 09, 2022 2:09:36 AM org.geotools.xml.XMLSAXHandler fatalError
SEVERE: col 50, line 1
Feb 09, 2022 2:09:36 AM org.geotools.data.ows.AbstractOpenWebService internalIssueRequest
SEVERE: Failed to execute request http://maps.heigit.org/osm-wms/service?request=capabilities&service=WMS&wmtver=1.0.0

What might have gone wrong here? Thanks for the help in advance !!

weltweit
  • 1
  • 1

2 Answers2

0

From a quick check (and a google of the error message) it looks like the XML document returned by that server is "invalid" as it has no systemId set.

I've not seen this error before so it might be due to a recent upgrade of the XML parser used by GeoTools or some other change, or a change in MapServer behaviour. Technically, this isn't a GeoTools bug, but it would be nice to find a way to fix it so we can continue to use MapServer WMS.

Ian Turton
  • 10,018
  • 1
  • 28
  • 47
0

I think the problem is as the error message indicates.

In the code snippet below the << LF >> character sequence is to indicate a LF character. And any white space present is white space. Between the DTD URL string and the VendorSpecificCapabilities element there is no white space. Unless the LF character is considered white space; which I think is an edge case in an implementation. It is this that could be the cause of the problem.

<?xml version="1.0"?><<LF>>
<!DOCTYPE WMT_MS_Capabilities SYSTEM 
"http://schemas.opengis.net/wms/1.1.0/capabilities_1_1_0.dtd"<<LF>>
[<<LF>>
 <!ELEMENT VendorSpecificCapabilities EMPTY><<LF>>
 ]>  <!-- end of DOCTYPE declaration --><<LF>>
<WMT_MS_Capabilities version="1.1.0"><<LF>>
<Service><<LF>>
...

The line wrapping between the SYSTEM word and the DTD URL string is an artifact of stackoverflow

Brett Walker
  • 3,566
  • 1
  • 18
  • 36