首先,看下本篇博客要达到的效果图:
下面逐步分析如何加载影像及高程文件。
1、WorldWind Java导入数据包
在src源码文件中找到dataimport包,这个包里面的示例代码演示了如何向WW上加载影像及高程文件。可以看到有import和install两种方式,import是简单的以图层的形式加载到WW上;install是指当文件较大时,将文件以本地缓存的方式加载,这里先以import方式导入影像及高程文件。源码比较简单,这里就不再过多解析了。
2、WWJ加载影像文件
直接给出源码,注释很清晰,不再赘述
/** * * @方法名称: importImagery ; * @方法描述: 导入影像文件 ; * @参数 :@param imageFilePath :影像文件路径 * @参数 :@param worlGlCanvas :WorldWind 画布对象 * @返回类型: void ; * @创建人:奔跑的鸡丝 ; * @创建时间:2014-12-2 下午3:12:30; * @throws */ private void importImagery(String imageFilePath, final WorldWindowGLCanvas worlGlCanvas) { try { // 读取数据并将其保存在一个缓存文件夹中 File sourceFile = ExampleUtil.saveResourceToTempFile(imageFilePath, ".tif"); /** * 首先创建一个raster reader读取栅格文件。raster reader由当前的栅格数据读取工作空间来创建 */ DataRasterReaderFactory readerFactory = (DataRasterReaderFactory) WorldWind.createConfigurationComponent(AVKey.DATA_RASTER_READER_FACTORY_CLASS_NAME); DataRasterReader reader = readerFactory.findReaderFor(sourceFile, null); // 读取栅格数据之前,先验证改文件包含imagery AVList metadata = reader.readMetadata(sourceFile, null); if (metadata == null || !AVKey.IMAGE.equals(metadata.getStringValue(AVKey.PIXEL_FORMAT))) throw new Exception("Not an image file."); /** * 将文件读取到DataRaster中,如果读取的源文件中中包含多种文件类型,read可能返回多种raster * 但是在这种情况下之使用返回的raster数组中的第一个元素 */ DataRaster[] rasters = reader.read(sourceFile, null); if (rasters == null || rasters.length == 0) throw new Exception("Can't read the image file."); DataRaster raster = rasters[0]; /** * 获取影像的经纬度范围;改信息在GeoTIFF文件或其附属文件中 */ final Sector sector = (Sector) raster.getValue(AVKey.SECTOR); if (sector == null) throw new Exception("No location specified with image."); /** * 获取包含整幅影像的子栅格。这一步是必须的,因为只有子栅格影像才可以重投影; */ int width = raster.getWidth(); int height = raster.getHeight(); /** * getSubRaster()方法返回一个特定范围的栅格影像;影像大小可以自定义 */ DataRaster subRaster = raster.getSubRaster(width, height, sector, null); /** * 删除原栅格数据 */ raster.dispose(); /** * 验证子栅格是否可以创建缓存影像,可以则创建一个缓存栅格影像 */ if (!(subRaster instanceof BufferedImageRaster)) throw new Exception("Cannot get BufferedImage."); BufferedImage image = ((BufferedImageRaster) subRaster).getBufferedImage(); /** * 删除子栅格影像 */ subRaster.dispose(); /** * 创建一个表面影像在指定的经纬度范围内显示该影像 */ final SurfaceImage surfaceImage = new SurfaceImage(image, sector); /** * 在新开启的线程中导入影像数据,作为一个surfaceLayer */ SwingUtilities.invokeLater(new Runnable() { public void run() { // 添加surfaceLayer SurfaceImageLayer surfaceImageLayer = new SurfaceImageLayer(); surfaceImageLayer.setName("Imported Surface Image"); surfaceImageLayer.setPickEnabled(false); surfaceImageLayer.addRenderable(surfaceImage); // 添加该图层到globe中 worldWindowGLCanvas.getModel().getLayers().add( surfaceImageLayer); // 飞行到当前影像视图内 ExampleUtil.goTo(worlGlCanvas, sector); } }); } catch (Exception e) { e.printStackTrace(); } }
这里栅格数据的读取类似ArcEngine中的工作空间的概念;另外需要注意Sector类是表述由经纬度包含的范围。
3、WWJ加载高程文件
/** * * @方法名称: importElevation ; * @方法描述: 导入高程数据 ; * @参数 :@param elevationFilePath :高程文件路径 * @参数 :@param wGlCanvas :WW画布对象 * @返回类型: void ; * @创建人:奔跑的鸡丝 ; * @创建时间:2014-12-2 下午4:42:26; * @throws */ private void importElevation(String elevationFilePath, WorldWindowGLCanvas wGlCanvas) { try { File sourceFile = ExampleUtil.saveResourceToTempFile( elevationFilePath, ".tif"); // 由数据源创建一个高程模型:LocalElevationModel final LocalElevationModel elevationModel = new LocalElevationModel(); elevationModel.addElevations(sourceFile); SwingUtilities.invokeLater(new Runnable() { public void run() { // 获取WW当前的高程模型 Globe globe = worldWindowGLCanvas.getModel().getGlobe(); ElevationModel currentElevationModel = globe.getElevationModel(); // 将新创建的高程模型加入Globe中(也可以是取代当前的高程模型) if (currentElevationModel instanceof CompoundElevationModel) ((CompoundElevationModel) currentElevationModel).addElevationModel(elevationModel); else globe.setElevationModel(elevationModel); // 飞行至当前视图 Sector modelSector = elevationModel.getSector(); ExampleUtil.goTo(worldWindowGLCanvas, modelSector); } }); } catch (Exception e) { e.printStackTrace(); } }
运行后,加载影像和相应的DEM文件即可构建三维场景。欢迎大家留言交流,需要的请留邮箱!
时间: 2024-10-09 22:45:28