2

I am trying to display an OSM layer as background layer in a map for a Java application which uses GeoTools.

My starting point is the Maven quickstart tutorial and the Tile Client user guide.

Therefore my class to reproduce my problem is quite simple:

public class OsmMapFrame
{
  public static void main(String args[])
  {
    String baseURL = "https://tile.openstreetmap.org/";
    TileService service = new OSMService("OSM", baseURL);
    MapContent map = new MapContent();
    map.addLayer(new TileLayer(service));
    JMapFrame.showMap(map);
  }
}

When I run this I get the following error:

2019-10-28T13:44:15.809+0100  SEVERE  Failed to load image: https://tile.openstreetmap.org/2/3/0.png
java.io.IOException: Can't create an ImageInputStream!
    at org.geotools.image.io.ImageIOExt.read(ImageIOExt.java:339)
    at org.geotools.image.io.ImageIOExt.readBufferedImage(ImageIOExt.java:402)
    at org.geotools.tile.Tile.loadImageTileImage(Tile.java:175)
    at org.geotools.tile.Tile.getBufferedImage(Tile.java:163)
    at org.geotools.tile.util.TileLayer.getTileImage(TileLayer.java:143)
    at org.geotools.tile.util.TileLayer.renderTile(TileLayer.java:131)
    at org.geotools.tile.util.TileLayer.renderTiles(TileLayer.java:125)
    at org.geotools.tile.util.TileLayer.draw(TileLayer.java:86)
    at org.geotools.renderer.lite.CompositingGroup$WrappingDirectLayer.draw(CompositingGroup.java:228)
    at org.geotools.renderer.lite.StreamingRenderer$RenderDirectLayerRequest.execute(StreamingRenderer.java:3850)
    at org.geotools.renderer.lite.StreamingRenderer$PainterThread.run(StreamingRenderer.java:3911)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

I assume that in my pom a dependency is missing? At the moment I use the following GeoTools dependencies in my pom.xml.

...
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-tile-client</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>${geotools.version}</version>
        </dependency>
...

I tried this with GeoTools 22.0 and 23-SNAPSHOT but in both cases I get the following picture:

GeoTools Screenshot

gillesB
  • 1,061
  • 1
  • 14
  • 30

1 Answers1

2

I just tried your code and an old tileviewer of mine that used to work and I get the same error that you get. I tried turning the logging level up but that made no difference to the unhelpful error message!

It looks as if something has changed either in Java 8 ImageIO or the way OSM serves tiles.

I tried the following code:

URL url = new URL("https://tile.openstreetmap.org/1/1/0.png");

Iterator<ImageReader> itr = ImageIO.getImageReadersByFormatName("png");
while (itr.hasNext()) {
  ImageReader next = itr.next();
  System.out.println(next.getFormatName());

  next.setInput(url.openStream());
  BufferedImage img = next.read(0);
}

which gives me:

Oct 30, 2019 5:45:18 PM sun.net.www.protocol.http.HttpURLConnection writeRequests
FINE: sun.net.www.MessageHeader@2974f2215 pairs: {GET /1/1/0.png HTTP/1.1: null}{User-Agent: Java/1.8.0_222}{Host: tile.openstreetmap.org}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}
Oct 30, 2019 5:45:18 PM sun.net.www.protocol.http.HttpURLConnection getInputStream0
FINE: sun.net.www.MessageHeader@58fe04997 pairs: {null: HTTP/1.1 429 Too Many Requests}{Server: nginx}{Date: Wed, 30 Oct 2019 17:45:18 GMT}{Content-Type: text/html}{Content-Length: 162}{Connection: keep-alive}{Strict-Transport-Security: max-age=31536000; includeSubDomains; preload}
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 429 for URL: https://tile.openstreetmap.org/1/1/0.png
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1900)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:268)
    at java.net.URL.openStream(URL.java:1057)
    at spike.OsmMapFrame.main(OsmMapFrame.java:32)

So clearly, something is up but I'm not sure what.

Ian Turton
  • 10,018
  • 1
  • 28
  • 47
  • 2
    Looks like your request is being [rate limited](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429), maybe due to the OSM servers suspecting your bulk downloading? Could be due to the user agent string or lack of referer? – walkermatt Oct 30 '19 at 20:31