3

我正在尝试使用示例http://docs.geotools.org/latest/userguide/tutorial/raster/image.html在 wms 层上覆盖 shp 文件。

我不断收到错误:

Exception in thread "main" java.lang.UnsupportedOperationException: Trying to get a reader from an unknown format.
at org.geotools.coverage.grid.io.UnknownFormat.getReader(UnknownFormat.java:62)
at com.qedrix.map.maplotr.Demo1.displayLayers(Demo1.java:121)
at com.qedrix.map.maplotr.Demo1.main(Demo1.java:229)

当代码尝试读取 WMS 图像时。

我的代码如下所示:

public class Demo1 {

private AbstractGridCoverage2DReader reader = null;

private StyleFactory sf = CommonFactoryFinder.getStyleFactory();
private FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();

/**
 * This method examines the names of the sample dimensions in the provided
 * coverage looking for "red...", "green..." and "blue..." (case insensitive
 * match). If these names are not found it uses bands 1, 2, and 3 for the
 * red, green and blue channels. It then sets up a raster symbolizer and
 * returns this wrapped in a Style.
 * 
 * @return a new Style object containing a raster symbolizer set up for RGB
 *         image
 */
private Style createRGBStyle() {
    GridCoverage2D cov = null;
    try {
        cov = reader.read(null);
    } catch (IOException giveUp) {
        throw new RuntimeException(giveUp);
    }
    // We need at least three bands to create an RGB style
    int numBands = cov.getNumSampleDimensions();
    if (numBands < 3) {
        return null;
    }
    // Get the names of the bands
    String[] sampleDimensionNames = new String[numBands];
    for (int i = 0; i < numBands; i++) {
        GridSampleDimension dim = cov.getSampleDimension(i);
        sampleDimensionNames[i] = dim.getDescription().toString();
    }
    final int RED = 0, GREEN = 1, BLUE = 2;
    int[] channelNum = { -1, -1, -1 };
    // We examine the band names looking for "red...", "green...",
    // "blue...".
    // Note that the channel numbers we record are indexed from 1, not 0.
    for (int i = 0; i < numBands; i++) {
        String name = sampleDimensionNames[i].toLowerCase();
        if (name != null) {
            if (name.matches("red.*")) {
                channelNum[RED] = i + 1;
            } else if (name.matches("green.*")) {
                channelNum[GREEN] = i + 1;
            } else if (name.matches("blue.*")) {
                channelNum[BLUE] = i + 1;
            }
        }
    }
    // If we didn't find named bands "red...", "green...", "blue..."
    // we fall back to using the first three bands in order
    if (channelNum[RED] < 0 || channelNum[GREEN] < 0 || channelNum[BLUE] < 0) {
        channelNum[RED] = 1;
        channelNum[GREEN] = 2;
        channelNum[BLUE] = 3;
    }
    // Now we create a RasterSymbolizer using the selected channels
    SelectedChannelType[] sct = new SelectedChannelType[cov.getNumSampleDimensions()];
    ContrastEnhancement ce = sf.contrastEnhancement(ff.literal(1.0), ContrastMethod.NORMALIZE);
    for (int i = 0; i < 3; i++) {
        sct[i] = sf.createSelectedChannelType(String.valueOf(channelNum[i]), ce);
    }
    RasterSymbolizer sym = sf.getDefaultRasterSymbolizer();
    ChannelSelection sel = sf.channelSelection(sct[RED], sct[GREEN], sct[BLUE]);
    sym.setChannelSelection(sel);

    return SLD.wrapSymbolizers(sym);
}

public void displayLayers() {

    File rasterFile = fetchWmsImage();

    AbstractGridFormat format = GridFormatFinder.findFormat(rasterFile);

    this.reader = format.getReader(rasterFile);

    // Initially display the raster in greyscale using the
    // data from the first image band
    Style rasterStyle = createRGBStyle();

    // Create a basic style with yellow lines and no fill
    Style shpStyle = SLD.createPointStyle("point", Color.YELLOW, Color.GRAY, 0.0f, 1.5f);

    MapContent map = new MapContent();
    map.setTitle("ImageLab");

    MapViewport vp = new MapViewport();

    org.geotools.map.Layer rasterLayer = new GridReaderLayer(reader, rasterStyle);
    map.addLayer(rasterLayer);

    saveImage(map, "final.jpeg", 583);

}

public File fetchWmsImage() {

    URL url = null;
    try {
        url = new URL("http://184.106.187.247:8080/geoserver/rg/wms?version=1.1.0");
    } catch (MalformedURLException e) {
        // will not happen
    }

    WebMapServer wms = null;
    try {
        wms = new WebMapServer(url);

        WMSCapabilities capabilities = wms.getCapabilities();
        Layer[] layers = WMSUtils.getNamedLayers(capabilities);

        GetMapRequest request = wms.createGetMapRequest();

        request.setFormat("image/png");
        request.setDimensions("583", "420");
        request.setTransparent(true);
        request.setSRS("EPSG:900913");
        request.setBBox("-13019428.542822,3922163.1648461,-13013051.407366,3929863.8567165");
        request.setProperty("isBaseLayer", "false");
        request.setProperty("opacity", ".2");

        for (Layer layer : WMSUtils.getNamedLayers(capabilities)) {
            if (layer.getName().equals("rg:parcels"))
                request.addLayer(layer);
        }

        GetMapResponse response = (GetMapResponse) wms.issueRequest(request);
        BufferedImage image = ImageIO.read(response.getInputStream());

        File rasterFile = new File("C:\\Users\\samabhik\\Workspace\\MAP\\data\\out.png");
        ImageIO.write(image, "png", rasterFile);

        return rasterFile;

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

    }

    return null;
}

public void saveImage(final MapContent map, final String file, final int imageWidth) {

    GTRenderer renderer = new StreamingRenderer();
    renderer.setMapContent(map);

    Rectangle imageBounds = null;
    ReferencedEnvelope mapBounds = null;
    try {
        mapBounds = map.getMaxBounds();
        double heightToWidth = mapBounds.getSpan(1) / mapBounds.getSpan(0);
        imageBounds = new Rectangle(0, 0, imageWidth, (int) Math.round(imageWidth * heightToWidth));

    } catch (Exception e) {
        // failed to access map layers
        throw new RuntimeException(e);
    }

    BufferedImage image = new BufferedImage(imageBounds.width, imageBounds.height, BufferedImage.TYPE_INT_RGB);

    Graphics2D gr = image.createGraphics();
    gr.setPaint(Color.WHITE);
    gr.fill(imageBounds);

    try {
        renderer.paint(gr, imageBounds, mapBounds);
        File fileToSave = new File(file);
        ImageIO.write(image, "jpeg", fileToSave);

    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

public static void main(String[] args) {
    Demo1 demo = new Demo1();
    demo.displayLayers();
}

}

我的 pom 依赖项如下所示:

<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-epsg-hsql</artifactId>
  <version>${geotools.version}</version>
</dependency>
<dependency>
  <groupId>org.geotools</groupId>
  <artifactId>gt-geotiff</artifactId>
  <version>${geotools.version}</version>
</dependency>
<dependency>
  <groupId>org.geotools</groupId>
  <artifactId>gt-image</artifactId>
  <version>${geotools.version}</version>
</dependency>
<dependency>
  <groupId>org.geotools</groupId>
  <artifactId>gt-wms</artifactId>
  <version>${geotools.version}</version>
</dependency>
<dependency>
  <groupId>org.geotools</groupId>
  <artifactId>gt-coverage</artifactId>
  <version>${geotools.version}</version>
</dependency>

我在某处读到它可能是 GDAL 问题。但我不知道如何解决它。我在 64 JDK 1.6 和 Win 7 amd64 上使用 eclipse。

请帮助,有人..

刚刚使用 GDAL 本机库路径中的 gdalinfo.exe 测试了图像文件。这是报告:

Driver: PNG/Portable Network Graphics
Files: ..\..\Workspace\MAP\data\out2.png
Size is 583, 420
Coordinate System is `'
Image Structure Metadata:
  INTERLEAVE=PIXEL
Corner Coordinates:
Upper Left  (    0.0,    0.0)
Lower Left  (    0.0,  420.0)
Upper Right (  583.0,    0.0)
Lower Right (  583.0,  420.0)
Center      (  291.5,  210.0)
Band 1 Block=583x1 Type=Byte, ColorInterp=Red
  Mask Flags: PER_DATASET ALPHA
Band 2 Block=583x1 Type=Byte, ColorInterp=Green
  Mask Flags: PER_DATASET ALPHA
Band 3 Block=583x1 Type=Byte, ColorInterp=Blue
  Mask Flags: PER_DATASET ALPHA
Band 4 Block=583x1 Type=Byte, ColorInterp=Alpha

进一步更新

我刚刚尝试将 WMS 的输出格式从 images/png 更改为 images/geotiff,现在这部分工作(geotools 生成的最终图像是黑白)。为什么会这样?为什么它不适用于PNG?

4

1 回答 1

4

检查您是否有可用的 JAI 和 ImageIO。通过 maven 依赖项,或者按照快速入门中所述将它们安装为 Java 扩展。

更新:

我能够赶上 GeoTools IRC 频道并确认这是一个环境问题。在课堂上为我工作的时尚我能够使用 WMSLab 教程示例连接到有问题的 WMS 并显示结果。

因此,让我们检查一下“问题”环境:

System.out.println(GeoTools.getAboutInfo());

结果::

GeoTools 版本 9-SNAPSHOT(由 ree5a6830d2c774ee9a4eb9e024d989c2a1bcdfe3 构建) Java 版本:1.7.0_09 操作系统:Windows 7 6.1 类路径上的 GeoTools jar:

几个想法:

  • 查看 ImageLab 以确认 JAI / ImageIO 是否可用?

这行得通!

  • 保存从浏览器检索到的图像并尝试使用直接 Java 加载它

来自 WorldImageReader 的示例::

File input = ...
ImageInputStreamSpi inStreamSPI= ImageIOExt.getImageInputStreamSPI( input );
if (inStreamSPI == null) throw new IllegalStateException("Unsuppported");

显然这不成功?

  • GeoTools 还没有通过 Java 7 的 QA,降级到 Java 6?

最近自愿提供了一个 Java 7 构建盒。当 GeoTools 在 Java 7 中工作时,发行说明和教程将被更新。

  • 特别是在 Windows 上,PNG 支持的实现是可疑的。

来自 uDig 项目的以下代码禁用了本机实现,允许纯 Java 实现对其进行破解:

 if (Platform.getOS().equals(Platform.OS_WIN32)) {
        try {
            // PNG native support is not very good .. this turns it off
            ImageUtilities.allowNativeCodec("png", ImageReaderSpi.class, false); //$NON-NLS-1$
        } catch (Throwable t) {
            // we should not die if JAI is missing; we have a warning for that...
            System.out.println("Difficulty turnning windows native PNG support (which will result in scrambled images from WMS servers)"); //$NON-NLS-1$
            t.printStackTrace();
        }
    }
于 2012-11-04T04:31:37.683 回答