2012-11-02 19 views
3

我想用例子http://docs.geotools.org/latest/userguide/tutorial/raster/image.html來覆蓋wms層上的shp文件。當代碼嘗試讀取WMS圖像地理工具 - 在WMS和OSM上繪製特徵

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) 

我不斷得到錯誤。

我的代碼如下所示:

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/PNG將圖像/ GeoTIFF文件,這現在工作部分(即所產生的最終圖像geotools是黑色&白色)。爲什麼發生這種情況?爲什麼它不適用於PNG?

+0

可以打印出請求的URL,然後檢查它的工作原理在瀏覽器中。嘗試使用瀏覽器打開磁盤上的圖像。您可能會收到錯誤而不是圖像。 –

+0

這是網址和圖片對我來說OK [link](http://184.106.187.247:8080/geoserver/rg/wms?SERVICE=WMS&LAYERS=rg%3Aparcels&ISBASELAYER=false&FORMAT=image%2Fpng&OPACITY=.2&HEIGHT=420&TRANSPARENT = TRUE&REQUEST = GetMap&BBOX = -13019428.542822,3922163.1648461,-13013051.407366,3929863.8567165&WIDTH = 583&STYLES =&SRS = EPSG:900913&VERSION = 1.1.1) – Qedrix

回答

4

檢查是否有JAI和ImageIO可用。無論是通過Maven依賴關係,還是將它們安裝爲快速入門中概述的Java擴展。

更新:

我能夠追趕上的GeoTools IRC頻道,並確認這是一個環境問題。在課堂上適用於我時尚我能夠使用WMSLab教程示例連接到有問題的WMS並顯示結果。

所以,讓我們檢查出 「問題」 的環境::

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

結果::

GeoTools版本9快照(從ree5a6830d2c774ee9a4eb9e024d989c2a1bcdfe3建) Java版本:1.7.0_09 操作系統:Windows 7 6.1 GeoTools類路徑罐子:

一對夫婦的想法:

  • 查看ImageLab確認JAI/ImageIO是否可用?

這工作!

  • 保存在瀏覽器中檢索到的圖像,並嘗試加載它使用從WorldImageReader直線上升的Java

例::

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

顯然,這不是成功的?

  • GeoTools還沒有通過Java 7的質量保證,但降級到Java 6?

最近有一個Java 7 build box已經被自願提供。當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(); 
     } 
    } 
+0

我嘗試使用JDK 1.6 x86再次運行java文件,並使用代碼'if(System。 getProperty(「os.arch」)。toLowerCase()。equals(「x86」)){ \t \t \t System.out.println(「---」); \t \t \t ImageUtilities.allowNativeCodec(「png」,ImageReaderSpi.class,false); // $ NON-NLS-1 $ \t \t}'禁用本地實施。沒有工作 - 相同的錯誤信息。 – Qedrix

+0

我也觀察了一些事情。當我嘗試閱讀在相同文件夾中具有隨附的.jgw文件的jpg文件時(我從示例文件中挑選了這些文件),我的代碼完美無缺。當我嘗試運行沒有.jgw文件的代碼時,會引發相同的錯誤。爲什麼我們需要這個.jgw文件?我應該如何創建一個WMS圖像? – Qedrix

+0

@Qedrix強烈建議不要在評論中提問。請張貼在單獨的問題上,以便其他人也可以從您的經驗中學習。 –