Geotools OSM Tile 层无法加载图像,无法创建 ImageInputStream
Geotools OSM Tile layer Failed to load image, can't create an ImageInputStream
我正在尝试使用 geotools 和图块客户端在给定的边界框中打印 OSM 图块,我已经实现了一个 wms 服务,可以读取 wms 请求并在给定的边界框中渲染图像,OSM图层用作基础层,我还有其他图层是我可以稍后添加的矢量图层,矢量图层在给定的边界框中正确显示但未显示 osm tiles,用于发送请求的 Url到 osm 服务器没有得到任何响应?我有以下错误:
2020-05-27 16:03:00.291 ERROR 26094 --- [pool-6-thread-1] org.geotools.tile : Failed to load image: https://tile.openstreetmap.org/8/123/106.png
java.io.IOException: Can't create an ImageInputStream!
at org.geotools.image.io.ImageIOExt.read(ImageIOExt.java:339) ~[gt-coverage-22.2.jar:na]
at org.geotools.image.io.ImageIOExt.readBufferedImage(ImageIOExt.java:402) ~[gt-coverage-22.2.jar:na]
at org.geotools.tile.Tile.loadImageTileImage(Tile.java:175) ~[gt-tile-client-22.2.jar:na]
at org.geotools.tile.Tile.getBufferedImage(Tile.java:163) ~[gt-tile-client-22.2.jar:na]
at org.geotools.tile.util.TileLayer.getTileImage(TileLayer.java:143) [gt-tile-client-22.2.jar:na]
at org.geotools.tile.util.TileLayer.renderTile(TileLayer.java:131) [gt-tile-client-22.2.jar:na]
at org.geotools.tile.util.TileLayer.renderTiles(TileLayer.java:125) [gt-tile-client-22.2.jar:na]
at org.geotools.tile.util.TileLayer.draw(TileLayer.java:86) [gt-tile-client-22.2.jar:na]
at org.geotools.renderer.lite.CompositingGroup$WrappingDirectLayer.draw(CompositingGroup.java:228) [gt-render-22.2.jar:na]
at org.geotools.renderer.lite.StreamingRenderer$RenderDirectLayerRequest.execute(StreamingRenderer.java:3850) [gt-render-22.2.jar:na]
at org.geotools.renderer.lite.StreamingRenderer$PainterThread.run(StreamingRenderer.java:3911) [gt-render-22.2.jar:na]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_232]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_232]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_232]
对于源代码,这些是我添加 osm tile 层的方式:
MapContent mapContent = new MapContent();
String baseURL = "https://tile.openstreetmap.org/";
TileService service = new OSMService("OSM", baseURL);
mapContent.addLayer(new TileLayer(service));
稍后我使用 gt-render 打印它:
StreamingRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
ReferencedEnvelope mapBounds = mapRequest.getReferencedEnvelope();
Rectangle imageBounds = new Rectangle(0, 0, mapRequest.getWidth(), mapRequest.getHeight());
map.getViewport().setScreenArea(imageBounds);
map.getViewport().setBounds( mapBounds );
BufferedImage image = new BufferedImage(mapRequest.getWidth(), mapRequest.getHeight(),BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D gr = image.createGraphics();
gr.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
int threads = Runtime.getRuntime().availableProcessors();
ExecutorService fixedPool = Executors.newFixedThreadPool(threads - 1);
renderer.setThreadPool(fixedPool);
try {
renderer.paint(gr, imageBounds, mapBounds);
ImageIO.write(image, imageExtension, os);
}
catch (IOException e) {
throw new RuntimeException(e);
}
gr.dispose();
map.dispose();
我有源代码的硬编码版本来测试它:
public void test(OutputStream os) throws NoSuchAuthorityCodeException, FactoryException {
MapContent map = new MapContent();
String baseURL = "https://tile.openstreetmap.org/";
TileService service = new OSMService("OSM", baseURL);
map.addLayer(new TileLayer(service));
StreamingRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
CoordinateReferenceSystem crs = CRS.decode("EPSG:3857");
ReferencedEnvelope mapBounds = new ReferencedEnvelope(-939258.203568246,-626172.1357121639,3130860.67856082,3443946.746416902,crs);
Rectangle imageBounds = new Rectangle(0, 0, 256, 256);
map.getViewport().setScreenArea(imageBounds);
map.getViewport().setBounds( mapBounds );
BufferedImage image = new BufferedImage(256, 256,
BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D gr = image.createGraphics();
gr.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
try {
renderer.paint(gr, imageBounds, mapBounds);
ImageIO.write(image, imageExtension, os);
} catch (IOException e) {
throw new RuntimeException(e);
}
gr.dispose();
map.dispose();
}
问题似乎是,如果您不设置 valid User-Agent header in your requests,OpenStreetMap 将 return 出现 HTTP-429 错误(请求过多)。
我假设这是自上次使用或测试 OSM 磁贴代码以来的新要求。尽管查看测试,它可能实际上并没有获取要渲染的图块。
我 raised a bug against gt-tile-client
at the issue tracker and I have a PR to fix the issue, to add a header in as the WMTSTile
implementation 做过。
它应该在今天晚些时候 2020 年 5 月 30 日的主夜间构建中可用。
我正在尝试使用 geotools 和图块客户端在给定的边界框中打印 OSM 图块,我已经实现了一个 wms 服务,可以读取 wms 请求并在给定的边界框中渲染图像,OSM图层用作基础层,我还有其他图层是我可以稍后添加的矢量图层,矢量图层在给定的边界框中正确显示但未显示 osm tiles,用于发送请求的 Url到 osm 服务器没有得到任何响应?我有以下错误:
2020-05-27 16:03:00.291 ERROR 26094 --- [pool-6-thread-1] org.geotools.tile : Failed to load image: https://tile.openstreetmap.org/8/123/106.png
java.io.IOException: Can't create an ImageInputStream!
at org.geotools.image.io.ImageIOExt.read(ImageIOExt.java:339) ~[gt-coverage-22.2.jar:na]
at org.geotools.image.io.ImageIOExt.readBufferedImage(ImageIOExt.java:402) ~[gt-coverage-22.2.jar:na]
at org.geotools.tile.Tile.loadImageTileImage(Tile.java:175) ~[gt-tile-client-22.2.jar:na]
at org.geotools.tile.Tile.getBufferedImage(Tile.java:163) ~[gt-tile-client-22.2.jar:na]
at org.geotools.tile.util.TileLayer.getTileImage(TileLayer.java:143) [gt-tile-client-22.2.jar:na]
at org.geotools.tile.util.TileLayer.renderTile(TileLayer.java:131) [gt-tile-client-22.2.jar:na]
at org.geotools.tile.util.TileLayer.renderTiles(TileLayer.java:125) [gt-tile-client-22.2.jar:na]
at org.geotools.tile.util.TileLayer.draw(TileLayer.java:86) [gt-tile-client-22.2.jar:na]
at org.geotools.renderer.lite.CompositingGroup$WrappingDirectLayer.draw(CompositingGroup.java:228) [gt-render-22.2.jar:na]
at org.geotools.renderer.lite.StreamingRenderer$RenderDirectLayerRequest.execute(StreamingRenderer.java:3850) [gt-render-22.2.jar:na]
at org.geotools.renderer.lite.StreamingRenderer$PainterThread.run(StreamingRenderer.java:3911) [gt-render-22.2.jar:na]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_232]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_232]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_232]
对于源代码,这些是我添加 osm tile 层的方式:
MapContent mapContent = new MapContent();
String baseURL = "https://tile.openstreetmap.org/";
TileService service = new OSMService("OSM", baseURL);
mapContent.addLayer(new TileLayer(service));
稍后我使用 gt-render 打印它:
StreamingRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
ReferencedEnvelope mapBounds = mapRequest.getReferencedEnvelope();
Rectangle imageBounds = new Rectangle(0, 0, mapRequest.getWidth(), mapRequest.getHeight());
map.getViewport().setScreenArea(imageBounds);
map.getViewport().setBounds( mapBounds );
BufferedImage image = new BufferedImage(mapRequest.getWidth(), mapRequest.getHeight(),BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D gr = image.createGraphics();
gr.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
int threads = Runtime.getRuntime().availableProcessors();
ExecutorService fixedPool = Executors.newFixedThreadPool(threads - 1);
renderer.setThreadPool(fixedPool);
try {
renderer.paint(gr, imageBounds, mapBounds);
ImageIO.write(image, imageExtension, os);
}
catch (IOException e) {
throw new RuntimeException(e);
}
gr.dispose();
map.dispose();
我有源代码的硬编码版本来测试它:
public void test(OutputStream os) throws NoSuchAuthorityCodeException, FactoryException {
MapContent map = new MapContent();
String baseURL = "https://tile.openstreetmap.org/";
TileService service = new OSMService("OSM", baseURL);
map.addLayer(new TileLayer(service));
StreamingRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
CoordinateReferenceSystem crs = CRS.decode("EPSG:3857");
ReferencedEnvelope mapBounds = new ReferencedEnvelope(-939258.203568246,-626172.1357121639,3130860.67856082,3443946.746416902,crs);
Rectangle imageBounds = new Rectangle(0, 0, 256, 256);
map.getViewport().setScreenArea(imageBounds);
map.getViewport().setBounds( mapBounds );
BufferedImage image = new BufferedImage(256, 256,
BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D gr = image.createGraphics();
gr.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
try {
renderer.paint(gr, imageBounds, mapBounds);
ImageIO.write(image, imageExtension, os);
} catch (IOException e) {
throw new RuntimeException(e);
}
gr.dispose();
map.dispose();
}
问题似乎是,如果您不设置 valid User-Agent header in your requests,OpenStreetMap 将 return 出现 HTTP-429 错误(请求过多)。
我假设这是自上次使用或测试 OSM 磁贴代码以来的新要求。尽管查看测试,它可能实际上并没有获取要渲染的图块。
我 raised a bug against gt-tile-client
at the issue tracker and I have a PR to fix the issue, to add a header in as the WMTSTile
implementation 做过。
它应该在今天晚些时候 2020 年 5 月 30 日的主夜间构建中可用。