天天看點

World Wind Java開發之七——讀取本地栅格檔案(影像+高程)建構三維場景(轉)

首先,看下本篇部落格要達到的效果圖:

World Wind Java開發之七——讀取本地栅格檔案(影像+高程)建構三維場景(轉)
下面逐漸分析如何加載影像及高程檔案。

1、WorldWind Java導入資料包

在src源碼檔案中找到dataimport包,這個包裡面的示例代碼示範了如何向WW上加載影像及高程檔案。可以看到有import和install兩種方式,import是簡單的以圖層的形式加載到WW上;install是指當檔案較大時,将檔案以本地緩存的方式加載,這裡先以import方式導入影像及高程檔案。源碼比較簡單,這裡就不再過多解析了。

World Wind Java開發之七——讀取本地栅格檔案(影像+高程)建構三維場景(轉)

2、WWJ加載影像檔案

直接給出源碼,注釋很清晰,不再贅述

[java] view plain copy

 print?​

​​

  1. /** 
  2.      *  
  3.      * @方法名稱: importImagery ; 
  4.      * @方法描述: 導入影像檔案 ; 
  5.      * @參數 :@param imageFilePath :影像檔案路徑 
  6.      * @參數 :@param worlGlCanvas :WorldWind 畫布對象 
  7.      * @傳回類型: void ; 
  8.      * @建立人:奔跑的雞絲 ; 
  9.      * @建立時間:2014-12-2 下午3:12:30; 
  10.      * @throws 
  11.      */  
  12.     private void importImagery(String imageFilePath,  
  13.             final WorldWindowGLCanvas worlGlCanvas)  
  14.     {  
  15.         try  
  16.         {  
  17.             // 讀取資料并将其儲存在一個緩存檔案夾中  
  18.             File sourceFile = ExampleUtil.saveResourceToTempFile(imageFilePath,  
  19.                     ".tif");  
  20.             /** 
  21.              * 首先建立一個raster reader讀取栅格檔案。raster reader由目前的栅格資料讀取工作空間來建立 
  22.              */  
  23.             DataRasterReaderFactory readerFactory = (DataRasterReaderFactory) WorldWind.createConfigurationComponent(AVKey.DATA_RASTER_READER_FACTORY_CLASS_NAME);  
  24.             DataRasterReader reader = readerFactory.findReaderFor(sourceFile,  
  25.                     null);  
  26.             // 讀取栅格資料之前,先驗證改檔案包含imagery  
  27.             AVList metadata = reader.readMetadata(sourceFile, null);  
  28.             if (metadata == null  
  29.                     || !AVKey.IMAGE.equals(metadata.getStringValue(AVKey.PIXEL_FORMAT)))  
  30.                 throw new Exception("Not an image file.");  
  31.              * 将檔案讀取到DataRaster中,如果讀取的源檔案中中包含多種檔案類型,read可能傳回多種raster 
  32.              * 但是在這種情況下之使用傳回的raster數組中的第一個元素 
  33.             DataRaster[] rasters = reader.read(sourceFile, null);  
  34.             if (rasters == null || rasters.length == 0)  
  35.                 throw new Exception("Can't read the image file.");  
  36.             DataRaster raster = rasters[0];  
  37.              * 擷取影像的經緯度範圍;改資訊在GeoTIFF檔案或其附屬檔案中 
  38.             final Sector sector = (Sector) raster.getValue(AVKey.SECTOR);  
  39.             if (sector == null)  
  40.                 throw new Exception("No location specified with image.");  
  41.              * 擷取包含整幅影像的子栅格。這一步是必須的,因為隻有子栅格影像才可以重投影; 
  42.             int width = raster.getWidth();  
  43.             int height = raster.getHeight();  
  44.              * getSubRaster()方法傳回一個特定範圍的栅格影像;影像大小可以自定義 
  45.             DataRaster subRaster = raster.getSubRaster(width, height, sector,  
  46.              * 删除原栅格資料 
  47.             raster.dispose();  
  48.              * 驗證子栅格是否可以建立緩存影像,可以則建立一個緩存栅格影像 
  49.             if (!(subRaster instanceof BufferedImageRaster))  
  50.                 throw new Exception("Cannot get BufferedImage.");  
  51.             BufferedImage image = ((BufferedImageRaster) subRaster).getBufferedImage();  
  52.              * 删除子栅格影像 
  53.             subRaster.dispose();  
  54.              * 建立一個表面影像在指定的經緯度範圍内顯示該影像 
  55.             final SurfaceImage surfaceImage = new SurfaceImage(image, sector);  
  56.              * 在新開啟的線程中導入影像資料,作為一個surfaceLayer 
  57.             SwingUtilities.invokeLater(new Runnable()  
  58.             {  
  59.                 public void run()  
  60.                 {  
  61.                     // 添加surfaceLayer  
  62.                     SurfaceImageLayer surfaceImageLayer = new SurfaceImageLayer();  
  63.                     surfaceImageLayer.setName("Imported Surface Image");  
  64.                     surfaceImageLayer.setPickEnabled(false);  
  65.                     surfaceImageLayer.addRenderable(surfaceImage);  
  66.                     // 添加該圖層到globe中  
  67.                     worldWindowGLCanvas.getModel().getLayers().add(  
  68.                             surfaceImageLayer);  
  69.                     // 飛行到目前影像視圖内  
  70.                     ExampleUtil.goTo(worlGlCanvas, sector);  
  71.                 }  
  72.             });  
  73.         }  
  74.         catch (Exception e)  
  75.             e.printStackTrace();  
  76.     }  

這裡栅格資料的讀取類似ArcEngine中的工作空間的概念;另外需要注意Sector類是表述由經緯度包含的範圍。

3、WWJ加載高程檔案

  1.      * @方法名稱: importElevation ; 
  2.      * @方法描述: 導入高程資料 ; 
  3.      * @參數 :@param elevationFilePath :高程檔案路徑 
  4.      * @參數 :@param wGlCanvas :WW畫布對象 
  5.      * @建立時間:2014-12-2 下午4:42:26; 
  6.     private void importElevation(String elevationFilePath,  
  7.             WorldWindowGLCanvas wGlCanvas)  
  8.             File sourceFile = ExampleUtil.saveResourceToTempFile(  
  9.                     elevationFilePath, ".tif");  
  10.             // 由資料源建立一個高程模型:LocalElevationModel  
  11.             final LocalElevationModel elevationModel = new LocalElevationModel();  
  12.             elevationModel.addElevations(sourceFile);  
  13.                     // 擷取WW目前的高程模型  
  14.                     Globe globe = worldWindowGLCanvas.getModel().getGlobe();  
  15.                     ElevationModel currentElevationModel = globe.getElevationModel();  
  16.                     // 将新建立的高程模型加入Globe中(也可以是取代目前的高程模型)  
  17.                     if (currentElevationModel instanceof CompoundElevationModel)  
  18.                         ((CompoundElevationModel) currentElevationModel).addElevationModel(elevationModel);  
  19.                     else  
  20.                         globe.setElevationModel(elevationModel);  
  21.                     // 飛行至目前視圖  
  22.                     Sector modelSector = elevationModel.getSector();  
  23.                     ExampleUtil.goTo(worldWindowGLCanvas, modelSector);  

運作後,加載影像和相應的DEM檔案即可建構三維場景。歡迎大家留言交流,需要的請留郵箱!