http://blog.csdn.net/giser_whu/article/details/43017881

1、AnalyticSurfaceDemo

ArcGIS下对栅格的各种分级渲染效果是非常好的,可以做出很漂亮的图,现在在WW下也可以做出同样的效果了,看到这里是不是有点小兴奋呢。先看下WW自带的AnalyticSurfaceDemo的运行效果图:

通过看源代码可以知道给出了三种渲染示例,其中两种是动态的,这里我需要的是对dem数据或者是单波段影像的渲染,也就是左上方的渲染效果。

2、AnalyticSurface类

下面来看下主要用到的类:

主要用到的方法:

[java] view plaincopy print?
  1. // 创建AnalyticSurface并设置其属性
  2. final AnalyticSurface surface = new AnalyticSurface();
  3. surface.setSector(raster.getSector());
  4. surface.setDimensions(raster.getWidth(), raster.getHeight());
  5. surface.setValues(AnalyticSurface.createColorGradientValues(
  6. raster.getBuffer(), raster.getTransparentValue(), extremes[0],
  7. extremes[1], minHue, maxHue));
  8. // surface.setVerticalScale(5e3);
  9. // 设置表面渲染方式为 CLAMP_TO_GROUND
  10. surface.setAltitudeMode(WorldWind.CLAMP_TO_GROUND);

根据自己的需要可以查阅开发文档设置其他属性。

3、DEM渲染实例

将demo中的代码稍加修改封装为AnalyticSurfaceUtil类以供后面所有栅格数据的渲染使用,目前比较简单,后面陆续扩充该类。
WW下渲染效果:
ArcMap下渲染效果:

可以看到WW下渲染的效果丝毫不逊色,图是不是很漂亮呢。

4、洪涝模拟渲染

这是对之前洪涝模拟的改进,对洪涝模拟输出的范围图和深度图进行渲染。
(1)范围图
(2)深度图
这幅渲染的深度图是不是有种火山喷发的感觉,很有艺术美感,非常喜欢这个渲染的效果。改一下配色再看下另一种渲染效果:

5、源码。

下面是自己封装的AnalyticSurfaceUtil类,供大家参考:
[java] view plaincopy print?
  1. /**
  2. * @Copyright 2014-2020 @刘硕
  3. **/
  4. package edu.whu.vge.util;
  5. import gov.nasa.worldwind.WorldWind;
  6. import gov.nasa.worldwind.avlist.AVKey;
  7. import gov.nasa.worldwind.avlist.AVList;
  8. import gov.nasa.worldwind.data.BufferWrapperRaster;
  9. import gov.nasa.worldwind.data.DataRaster;
  10. import gov.nasa.worldwind.data.DataRasterReader;
  11. import gov.nasa.worldwind.data.DataRasterReaderFactory;
  12. import gov.nasa.worldwind.exception.WWRuntimeException;
  13. import gov.nasa.worldwind.geom.Extent;
  14. import gov.nasa.worldwind.geom.Sector;
  15. import gov.nasa.worldwind.layers.RenderableLayer;
  16. import gov.nasa.worldwind.render.DrawContext;
  17. import gov.nasa.worldwind.render.Renderable;
  18. import gov.nasa.worldwind.util.Logging;
  19. import gov.nasa.worldwind.util.WWBufferUtil;
  20. import gov.nasa.worldwind.util.WWIO;
  21. import gov.nasa.worldwind.util.WWMath;
  22. import gov.nasa.worldwindx.examples.analytics.AnalyticSurface;
  23. import gov.nasa.worldwindx.examples.analytics.AnalyticSurfaceAttributes;
  24. import gov.nasa.worldwindx.examples.analytics.AnalyticSurfaceLegend;
  25. import gov.nasa.worldwindx.examples.util.ExampleUtil;
  26. import java.awt.Point;
  27. import java.io.File;
  28. import java.text.DecimalFormat;
  29. import java.text.FieldPosition;
  30. import java.text.Format;
  31. import javax.swing.SwingUtilities;
  32. /**
  33. * @项目名称:SmartScope
  34. * @类名称:AnalyticSurfaceUtil
  35. * @类描述:
  36. * @创建人:刘硕
  37. * @创建时间:2015-1-21 下午3:40:54
  38. * @修改备注:
  39. * @版本:
  40. */
  41. public class AnalyticSurfaceUtil
  42. {
  43. /**
  44. * 创建一个新的实例 AnalyticSurfaceUtil.
  45. *
  46. */
  47. public AnalyticSurfaceUtil()
  48. {
  49. // TODO Auto-generated constructor stub
  50. }
  51. public static void createPrecipitationSurface(double minHue, double maxHue,
  52. final RenderableLayer outLayer)
  53. {
  54. String DATA_PATH = "J:/data/wwj/FloodDepth.tif";
  55. BufferWrapperRaster raster = loadRasterElevations(DATA_PATH);
  56. if (raster == null)
  57. return;
  58. // 获取像元最大值与最小值
  59. double[] extremes = WWBufferUtil.computeExtremeValues(
  60. raster.getBuffer(), raster.getTransparentValue());
  61. if (extremes == null)
  62. return;
  63. // 创建AnalyticSurface并设置其属性
  64. final AnalyticSurface surface = new AnalyticSurface();
  65. surface.setSector(raster.getSector());
  66. surface.setDimensions(raster.getWidth(), raster.getHeight());
  67. surface.setValues(AnalyticSurface.createColorGradientValues(
  68. raster.getBuffer(), raster.getTransparentValue(), extremes[0],
  69. extremes[1], minHue, maxHue));
  70. // surface.setVerticalScale(5e3);
  71. // 设置表面渲染方式为 CLAMP_TO_GROUND
  72. surface.setAltitudeMode(WorldWind.CLAMP_TO_GROUND);
  73. AnalyticSurfaceAttributes attr = new AnalyticSurfaceAttributes();
  74. attr.setDrawOutline(false);
  75. attr.setDrawShadow(false);
  76. attr.setInteriorOpacity(0.6);
  77. surface.setSurfaceAttributes(attr);
  78. // 设置图例样式
  79. Format legendLabelFormat = new DecimalFormat("# m")
  80. {
  81. public StringBuffer format(double number, StringBuffer result,
  82. FieldPosition fieldPosition)
  83. {
  84. double valueInFeet = number;
  85. return super.format(valueInFeet, result, fieldPosition);
  86. }
  87. };
  88. // 创建图例
  89. final AnalyticSurfaceLegend legend = AnalyticSurfaceLegend.fromColorGradient(
  90. extremes[0], extremes[1], minHue, maxHue,
  91. AnalyticSurfaceLegend.createDefaultColorGradientLabels(
  92. extremes[0], extremes[1], legendLabelFormat),
  93. AnalyticSurfaceLegend.createDefaultTitle("Legend"));
  94. legend.setOpacity(0.8);
  95. legend.setScreenLocation(new Point(100, 300));
  96. SwingUtilities.invokeLater(new Runnable()
  97. {
  98. public void run()
  99. {
  100. surface.setClientLayer(outLayer);
  101. outLayer.addRenderable(surface);
  102. outLayer.addRenderable(createLegendRenderable(surface, 600,
  103. legend));
  104. }
  105. });
  106. }
  107. /**
  108. *
  109. * @方法名称: loadRasterElevations ;
  110. * @方法描述: 读取数据(单波段) ;
  111. * @参数 :@param path
  112. * @参数 :@return
  113. * @返回类型: BufferWrapperRaster ;
  114. * @创建人:刘硕;
  115. * @创建时间:2015-1-22 上午11:25:40;
  116. * @throws
  117. */
  118. public static BufferWrapperRaster loadRasterElevations(String path)
  119. {
  120. // Download the data and save it in a temp file.
  121. File file = ExampleUtil.saveResourceToTempFile(path,
  122. "." + WWIO.getSuffix(path));
  123. // Create a raster reader for the file type.
  124. DataRasterReaderFactory readerFactory = (DataRasterReaderFactory) WorldWind.createConfigurationComponent(AVKey.DATA_RASTER_READER_FACTORY_CLASS_NAME);
  125. DataRasterReader reader = readerFactory.findReaderFor(file, null);
  126. try
  127. {
  128. // Before reading the raster, verify that the file contains
  129. // elevations.
  130. AVList metadata = reader.readMetadata(file, null);
  131. if (metadata == null
  132. || !AVKey.ELEVATION.equals(metadata.getStringValue(AVKey.PIXEL_FORMAT)))
  133. {
  134. String msg = Logging.getMessage(
  135. "ElevationModel.SourceNotElevations",
  136. file.getAbsolutePath());
  137. Logging.logger().severe(msg);
  138. throw new IllegalArgumentException(msg);
  139. }
  140. // Read the file into the raster.
  141. DataRaster[] rasters = reader.read(file, null);
  142. if (rasters == null || rasters.length == 0)
  143. {
  144. String msg = Logging.getMessage(
  145. "ElevationModel.CannotReadElevations",
  146. file.getAbsolutePath());
  147. Logging.logger().severe(msg);
  148. throw new WWRuntimeException(msg);
  149. }
  150. // Determine the sector covered by the elevations. This
  151. // information
  152. // is in the GeoTIFF file or auxiliary
  153. // files associated with the elevations file.
  154. Sector sector = (Sector) rasters[0].getValue(AVKey.SECTOR);
  155. if (sector == null)
  156. {
  157. String msg = Logging.getMessage("DataRaster.MissingMetadata",
  158. AVKey.SECTOR);
  159. Logging.logger().severe(msg);
  160. throw new IllegalArgumentException(msg);
  161. }
  162. // Request a sub-raster that contains the whole file. This step
  163. // is
  164. // necessary because only sub-rasters
  165. // are reprojected (if necessary); primary rasters are not.
  166. int width = rasters[0].getWidth();
  167. int height = rasters[0].getHeight();
  168. DataRaster subRaster = rasters[0].getSubRaster(width, height,
  169. sector, rasters[0]);
  170. // Verify that the sub-raster can create a ByteBuffer, then
  171. // create
  172. // one.
  173. if (!(subRaster instanceof BufferWrapperRaster))
  174. {
  175. String msg = Logging.getMessage(
  176. "ElevationModel.CannotCreateElevationBuffer", path);
  177. Logging.logger().severe(msg);
  178. throw new WWRuntimeException(msg);
  179. }
  180. return (BufferWrapperRaster) subRaster;
  181. }
  182. catch (Exception e)
  183. {
  184. e.printStackTrace();
  185. return null;
  186. }
  187. }
  188. /**
  189. *
  190. * @方法名称: createLegendRenderable ;
  191. * @方法描述: 创建图例 ;
  192. * @参数 :@param surface
  193. * @参数 :@param surfaceMinScreenSize
  194. * @参数 :@param legend
  195. * @参数 :@return
  196. * @返回类型: Renderable ;
  197. * @创建人:刘硕;
  198. * @创建时间:2015-1-22 上午11:26:07;
  199. * @throws
  200. */
  201. protected static Renderable createLegendRenderable(
  202. final AnalyticSurface surface, final double surfaceMinScreenSize,
  203. final AnalyticSurfaceLegend legend)
  204. {
  205. return new Renderable()
  206. {
  207. public void render(DrawContext dc)
  208. {
  209. Extent extent = surface.getExtent(dc);
  210. if (!extent.intersects(dc.getView().getFrustumInModelCoordinates()))
  211. return;
  212. if (WWMath.computeSizeInWindowCoordinates(dc, extent) < surfaceMinScreenSize)
  213. return;
  214. legend.render(dc);
  215. }
  216. };
  217. }
  218. }

目前还很不完善,后面有需要的话打算做一个类似于ArcGIS的分级渲染工具,对于降雨量蒸散发量等数据都可以很方便的进行渲染。

转载于:https://www.cnblogs.com/telwanggs/p/6774690.html

World Wind Java开发之十——AnalyticSurface栅格渲染(转)相关推荐

  1. java开发surface,World Wind Java开发之十――AnalyticSurface栅格渲染

    1.AnalyticSurfaceDemo ArcGIS下对栅格的各种分级渲染效果是非常好的,可以做出很漂亮的图,现在在WW下也能够做出一样的效果了,看到这里是否是有点小兴奋呢.先看下WW自带的Ana ...

  2. World Wind Java开发之十五——加载三维模型(转)

    之前的一篇博客是关于加载粗三维模型的,见http://blog.csdn.net/giser_whu/article/details/43452703,这个地方还存在着不能加载纹理的问题,一直没呢解决 ...

  3. World Wind Java开发之十四——添加WMS地图服务资源(转)

    数据是GIS的核心,没有数据一切无从谈起,Internet上有很多在线WMS地图服务资源,我们可以好好利用这些数据资源,比如天地图.必应地图.NASA.OGC数据服务等等. 在我们国家常用的还是天地图 ...

  4. World Wind Java开发之七——读取本地栅格文件(影像+高程)构建三维场景(转)...

    http://blog.csdn.net/giser_whu/article/details/41679515 首先,看下本篇博客要达到的效果图: 下面逐步分析如何加载影像及高程文件. 1.World ...

  5. world wind java开发_World Wind Java开发之十五

    之前的一篇博客是关于加载粗三维模型的,见http://blog.csdn.net/giser_whu/article/details/43452703,这个地方还存在着不能加载纹理的问题,一直没呢解决 ...

  6. World Wind Java开发之十二——加载粗制三维模型(ExtrudedPolygon)(转)

    ww可以根据DLG图批量生成假三维模型,这对于小区等特征相似的建筑物模型的构建是非常有用的.下面来看如何一步步实现假三维模型的加载: 1.Shp文件的制作 首先在arcmap下数字化几个建筑物,并新建 ...

  7. World Wind Java开发之六——解析shape文件(转)

    http://blog.csdn.net/giser_whu/article/details/41647117 最近一直忙于导师项目的事情了,几天没更新了,昨天和今天研究了下WWJ解析shp文件的源代 ...

  8. World Wind Java开发之一(转)

    http://blog.csdn.net/giser_whu/article/details/40477235 参照<World wind Java三维地理信息系统开发指南随书光盘>以及官 ...

  9. java的getshape()_World Wind Java开发之六——解析shape文件(转)

    http://blog.csdn.net/giser_whu/article/details/41647117 最近一直忙于导师项目的事情了,几天没更新了,昨天和今天研究了下WWJ解析shp文件的源代 ...

最新文章

  1. Python使用numpy函数vsplit垂直(行角度)拆分numpy数组(返回拆分后的numpy数组列表)实战:垂直拆分二维numpy数组、split函数垂直拆分二维numpy数组
  2. python面试-Python面试常问的10个问题
  3. 超想做一个网络游戏!有兴趣的人进来讨论讨论!
  4. 改变MATLAB仿真出来的图的线条颜色表
  5. 手把手教你Tomcat配置环境变量以及验证方法
  6. C语言实现AVL树(附完整源码)
  7. 你真的会使用XMLHttpRequest吗?
  8. 阿里一面 —— 什么是多线程?
  9. pythons实现信号分帧
  10. 关于Windows高DPI的一些简单总结
  11. 智慧校园供水系统智能管理
  12. WikiExtractor.py(维基百科抽取器)
  13. 常用web服务器架构理解
  14. AD域组策略安全管理
  15. 计算机内存国产,拼多多上买的纯国产内存条会不会翻车?雷赤 内存条评测
  16. 谈谈如何写好一份简历
  17. 移动端页面性能优化方案
  18. echarts高度自适应
  19. 今日头条李航:深度学习NLP的现有优势与未来挑战
  20. 前端项目运行错误提示及解决proble (1 error, 0 warnings) m1 error and 0 warnings potentially fixable with the `--fi

热门文章

  1. ElasticSearch核心基础之聚合
  2. Java 并发编程 基础
  3. (50)IO的延迟约束(输入延迟约束)
  4. STC51-C51基础知识
  5. 数字图像处理(作业一)——matlab工具箱初探
  6. mlock家族:锁定物理内存
  7. I帧、P帧和B帧的特点
  8. java main传入参数_Main方法中传入参数
  9. mp3播放程序c语言,Go语言音乐播放器
  10. 70打印位置调整_闵行公司做账发票打印不全该如何调整?