Слой листов Geotools OSM Не удалось загрузить изображение, невозможно создать ImageInputStream - PullRequest
1 голос
/ 27 мая 2020

Я пытаюсь напечатать тайлы OSM в заданном ограничивающем прямоугольнике с помощью геоинструментов и клиента тайлов, я реализовал сервис wms, который может читать запрос wms и отображать изображение в заданном блоке рамки, слой OSM - используется в качестве базового слоя, у меня есть другие слои, которые являются векторными слоями, которые я могу добавить позже, векторный слой отображается правильно в заданном ограничивающем поле, но плитки osm не отображаются, 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]

the image represent the result of a wms request send from postman with a fake layer to have only osm tiles

the second image show a polygon layer that is displayed in the given bounding box but osm tile layer from the background is not displayed

для исходного кода вот как я добавляю слой тайлов osm:

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();
    }

1 Ответ

1 голос
/ 29 мая 2020

Проблема, похоже, в том, что OpenStreetMap вернет ошибку HTTP-429 (слишком много запросов), если вы не установите допустимый заголовок User-Agent в своих запросах .

Я предполагаю, что это новое требование, так как код плитки OSM использовался или тестировался в последний раз. Хотя, глядя на тест, он может не получить плитку для рендеринга.

Я обнаружил ошибку gt-tile-client в системе отслеживания проблем , и у меня есть a PR, чтобы исправить проблему , добавить заголовок, как это делает реализация WMTSTile .

Он должен быть доступен в основной ночной сборке сегодня 30 /5/2020.

...