World Wind Java开发之十四——添加WMS地图服务资源

来源:互联网 发布:知乎暨南大学临床医学 编辑:程序博客网 时间:2024/06/05 03:17

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

在我们国家常用的还是天地图的地图服务资源,详见:http://blog.3snews.net/space.php?uid=6955280&do=blog&id=67981,这篇博客列举了一些常用的在线地图服务资源,读者可以自行试下。

1、添加天地图地图服务

由于上篇转载的平常心的博客对WMSTiledImageLayer已经讲的非常清楚了,这里不再赘述了,看代码:
public static WMSTiledImageLayer addTianDiTuImage() throws Exception{// 请求地图的URLString uri = "http://www.scgis.net.cn/imap/iMapServer/defaultRest/services/newtianditudom/WMS";// WMSWMSCapabilities caps;URI serverURI;serverURI = new URI(uri);// 获得WMSCapabilities对象caps = WMSCapabilities.retrieve(serverURI);// 解析WMSCapabilities数据caps.parse();// // 输出wms元数据信息// System.out.println(caps.getCapabilityInformation().toString());// 获取所有图层(这里只有一个,自己用geoserver发布的则可能有很多)final List<WMSLayerCapabilities> namedLayerCaps = caps.getNamedLayers();String layerName = null;for (WMSLayerCapabilities wmsLayerCapabilities : namedLayerCaps){layerName = wmsLayerCapabilities.getName();}AVList params = new AVListImpl();// 图层的名称params.setValue(AVKey.LAYER_NAMES, layerName);// 地图服务的协议,这里是OGC:WMSparams.setValue(AVKey.SERVICE_NAME, "OGC:WMS");// 获得地图的uri,也就是上面定义的uriparams.setValue(AVKey.GET_MAP_URL, uri);// 在本地缓存文件的名称params.setValue(AVKey.DATA_CACHE_NAME, layerName);params.setValue(AVKey.TILE_URL_BUILDER,new WMSTiledImageLayer.URLBuilder(params));WMSTiledImageLayer layer = new WMSTiledImageLayer(caps, params);return layer;}

这里添加天地图影像作为底图,效果还是不错的,看下效果图:



另外,天地图还提供了在线注记底图服务,只需改动上面的地图请求地址即可,看下效果图:


这里加载的效果要比天地图的在线三维球的效果要好,有兴趣的可以去对比下。另外天地图的在线三维体验还是比较差的,只是单纯的浏览,单是这个体验效果还不是很好,毕竟这是政府的东东,不像Google财大气粗,全球几十万台服务器,天地图的商业化发展之路任重道远啊。

2、添加Geoserver发布的地图服务

这里暂时只发布了世界国界和中国县界数据(面和线),这些数据稍后会打包发到我的CSDN资源,大家有需要的可以去下载。为了方便服务资源的管理,在右边添加了一个简单的WMS服务器管理面板,后面仿照ArcCatalog做一个WMS服务器管理的模块。


3、WMS服务器管理面板

examples中有个WMSLayerManager,这个demo实现了wms服务的基本管理,只需根据自己的需要修改源代码即可。这里说下我自己修改源代码的方法,首先将需要修改的java文件在改目录下copy一份,名字自取,这样做的好处是不破坏源代码的完整性,因为其他的demo也可能用到这个java文件,避免了大量的修改,改完只需将src导出jar包即可。如下图所示:

改动的不多,都加了注释,可以对比原WMSLayersPanel.java文件看下不同,修改后的SmartScopeWMSLayersPanel源码如下:
/*Copyright (C) 2001, 2006 United States Governmentas represented by the Administrator of theNational Aeronautics and Space Administration.All Rights Reserved. */package gov.nasa.worldwindx.examples;import gov.nasa.worldwind.*;import gov.nasa.worldwind.avlist.*;import gov.nasa.worldwind.globes.ElevationModel;import gov.nasa.worldwind.layers.*;import gov.nasa.worldwind.ogc.wms.*;import gov.nasa.worldwind.terrain.CompoundElevationModel;import gov.nasa.worldwind.util.WWUtil;import gov.nasa.worldwindx.examples.WMSLayersPanel.LayerInfo;import javax.swing.*;import javax.swing.border.*;import java.awt.*;import java.awt.event.*;import java.net.*;import java.util.*;import java.util.List;/** *  * @项目名称:worldwind-1.5.0 * @类名称:SmartScopeWMSLayersPanel * @类描述: WMS服务图层管理面板 * @创建人:bluce * @创建时间:2015年2月4日 下午5:09:31 * @修改备注: * @版本: */public class SmartScopeWMSLayersPanel extends JPanel{/** * @Fields serialVersionUID : TODO */private static final long serialVersionUID = 1L;protected static class LayerInfo{protected WMSCapabilities caps;protected AVListImpl params = new AVListImpl();protected String getTitle(){return params.getStringValue(AVKey.DISPLAY_NAME);}protected String getName(){return params.getStringValue(AVKey.LAYER_NAMES);}protected String getAbstract(){return params.getStringValue(AVKey.LAYER_ABSTRACT);}}// 所有图层元数据信息protected String[] servers;protected List<WMSLayerCapabilities> namedLayerCaps;protected WorldWindow wwd;protected URI serverURI;protected Dimension size;protected Thread loadingThread;protected TreeSet<LayerInfo> layerInfos = new TreeSet<LayerInfo>(new Comparator<LayerInfo>(){public int compare(LayerInfo infoA, LayerInfo infoB){String nameA = infoA.getName();String nameB = infoB.getName();return nameA.compareTo(nameB);}});public  SmartScopeWMSLayersPanel(String[] servers){}/** *  * 创建一个新的实例 SmartScopeWMSLayersPanel. *  * @param wwd * @param server * @param size * @throws URISyntaxException */public SmartScopeWMSLayersPanel(WorldWindow wwd, String[] server,Dimension size) throws URISyntaxException{super(new BorderLayout());this.servers = server;this.wwd = wwd;this.size = size;this.setPreferredSize(this.size);this.makeProgressPanel();// Thread off a retrieval of the server's capabilities document and// update of this panel.this.loadingThread = new Thread(new Runnable(){public void run(){load();}});this.loadingThread.setPriority(Thread.MIN_PRIORITY);this.loadingThread.start();}/** *  * @方法名称: load ; * @方法描述: 加载服务 ; * @参数 : * @返回类型: void ; * @创建人:bluce; * @创建时间:2015年2月5日 上午9:33:23; * @throws */protected void load(){WMSCapabilities caps = null;try{for (int i = 0; i < servers.length; i++){this.serverURI = new URI(servers[i].trim());caps = WMSCapabilities.retrieve(this.serverURI);caps.parse();// 获取该服务下的所有图层元数据描述namedLayerCaps = caps.getNamedLayers();if (namedLayerCaps == null) return;try{for (WMSLayerCapabilities lc : namedLayerCaps){Set<WMSLayerStyle> styles = lc.getStyles();if (styles == null || styles.size() == 0){LayerInfo layerInfo = createLayerInfo(caps, lc,null);SmartScopeWMSLayersPanel.this.layerInfos.add(layerInfo);}else{for (WMSLayerStyle style : styles){LayerInfo layerInfo = createLayerInfo(caps, lc,style);SmartScopeWMSLayersPanel.this.layerInfos.add(layerInfo);}}}}catch (Exception e){e.printStackTrace();return;}// 在面板上显示所有图层的名称EventQueue.invokeLater(new Runnable(){public void run(){SmartScopeWMSLayersPanel.this.removeAll();makeLayerInfosPanel(layerInfos);}});}}catch (Exception e){e.printStackTrace();}// Gather up all the named layers and make a world wind layer for each.}public String getServerDisplayString(){return this.serverURI.getHost();}protected LayerInfo createLayerInfo(WMSCapabilities caps,WMSLayerCapabilities layerCaps, WMSLayerStyle style){// Create the layer info specified by the layer's capabilities entry and// the selected style.LayerInfo linfo = new LayerInfo();linfo.caps = caps;linfo.params = new AVListImpl();linfo.params.setValue(AVKey.LAYER_NAMES, layerCaps.getName());if (style != null) linfo.params.setValue(AVKey.STYLE_NAMES,style.getName());String abs = layerCaps.getLayerAbstract();if (!WWUtil.isEmpty(abs)) linfo.params.setValue(AVKey.LAYER_ABSTRACT,abs);linfo.params.setValue(AVKey.DISPLAY_NAME, makeTitle(caps, linfo));return linfo;}protected void makeLayerInfosPanel(Collection<LayerInfo> layerInfos){// JPanel layersPanel = new JPanel(new GridLayout(0, 1, 0, 4));// layersPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));JPanel layersPanel = new JPanel();BoxLayout layout = new BoxLayout(layersPanel, BoxLayout.Y_AXIS);layersPanel.setLayout(layout);layersPanel.setFont(new Font("宋体", Font.PLAIN, 10));// Add the server's layers to the panel.for (LayerInfo layerInfo : layerInfos){addLayerInfoPanel(layersPanel, SmartScopeWMSLayersPanel.this.wwd,layerInfo);}// Put the name panel in a scroll bar.JScrollPane scrollPane = new JScrollPane(layersPanel);scrollPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));scrollPane.setPreferredSize(size);// Add the scroll bar and name panel to a titled panel that will resize// with the main window.// JPanel westPanel = new JPanel(new GridLayout(0, 1, 0, 10));// westPanel.setBorder(new// CompoundBorder(BorderFactory.createEmptyBorder(// 9, 9, 9, 9), new TitledBorder("Layers")));// westPanel.add(scrollPane);this.add(scrollPane, BorderLayout.CENTER);this.revalidate();}protected void addLayerInfoPanel(JPanel layersPanel, WorldWindow wwd,LayerInfo linfo){// Give a layer a button and label and add it to the layer names panel.LayerInfoAction action = new LayerInfoAction(linfo, wwd);if (linfo.getAbstract() != null){action.putValue(Action.SHORT_DESCRIPTION, linfo.getAbstract());JCheckBox jcb = new JCheckBox(action);jcb.setFont(new Font("宋体", Font.PLAIN, 14));jcb.setSelected(false);layersPanel.add(jcb);}}protected class LayerInfoAction extends AbstractAction{protected WorldWindow wwd;protected LayerInfo layerInfo;protected Object component;public LayerInfoAction(LayerInfo linfo, WorldWindow wwd){super(linfo.getTitle());// Capture info we'll need later to control the layer.this.wwd = wwd;this.layerInfo = linfo;}public void actionPerformed(ActionEvent actionEvent){// If the layer is selected, add it to the world window's current// model, else remove it from the model.if (((JCheckBox) actionEvent.getSource()).isSelected()){if (this.component == null) this.component = createComponent(layerInfo.caps, layerInfo.params);updateComponent(this.component, true);}else{if (this.component != null) updateComponent(this.component,false);}// Tell the world window to update.wwd.redraw();}}protected void updateComponent(Object component, boolean enable){if (component instanceof Layer){Layer layer = (Layer) component;LayerList layers = this.wwd.getModel().getLayers();layer.setEnabled(enable);if (enable){if (!layers.contains(layer)){ApplicationTemplate.insertBeforePlacenames(this.wwd, layer);ApplicationTemplate.insertBeforeLayerName(wwd, layer,"Landsat");this.firePropertyChange("LayersPanelUpdated", null, layer);}}else{layers.remove(layer);this.firePropertyChange("LayersPanelUpdated", layer, null);}}else if (component instanceof ElevationModel){ElevationModel model = (ElevationModel) component;CompoundElevationModel compoundModel = (CompoundElevationModel) this.wwd.getModel().getGlobe().getElevationModel();if (enable){if (!compoundModel.getElevationModels().contains(model)) compoundModel.addElevationModel(model);}}}protected static Object createComponent(WMSCapabilities caps, AVList params){AVList configParams = params.copy(); // Copy to insulate changes from// the caller.// Some wms servers are slow, so increase the timeouts and limits used// by world wind's retrievers.configParams.setValue(AVKey.URL_CONNECT_TIMEOUT, 30000);configParams.setValue(AVKey.URL_READ_TIMEOUT, 30000);configParams.setValue(AVKey.RETRIEVAL_QUEUE_STALE_REQUEST_LIMIT, 60000);try{String factoryKey = getFactoryKeyForCapabilities(caps);Factory factory = (Factory) WorldWind.createConfigurationComponent(factoryKey);return factory.createFromConfigSource(caps, configParams);}catch (Exception e){// Ignore the exception, and just return null.}return null;}protected static String getFactoryKeyForCapabilities(WMSCapabilities caps){boolean hasApplicationBilFormat = false;Set<String> formats = caps.getImageFormats();for (String s : formats){if (s.contains("application/bil")){hasApplicationBilFormat = true;break;}}return hasApplicationBilFormat ? AVKey.ELEVATION_MODEL_FACTORY: AVKey.LAYER_FACTORY;}protected static String makeTitle(WMSCapabilities caps, LayerInfo layerInfo){String layerNames = layerInfo.params.getStringValue(AVKey.LAYER_NAMES);String styleNames = layerInfo.params.getStringValue(AVKey.STYLE_NAMES);String[] lNames = layerNames.split(",");String[] sNames = styleNames != null ? styleNames.split(",") : null;StringBuilder sb = new StringBuilder();for (int i = 0; i < lNames.length; i++){if (sb.length() > 0) sb.append(", ");String layerName = lNames[i];WMSLayerCapabilities lc = caps.getLayerByName(layerName);String layerTitle = lc.getTitle();sb.append(layerTitle != null ? layerTitle : layerName);if (sNames == null || sNames.length <= i) continue;String styleName = sNames[i];WMSLayerStyle style = lc.getStyleByName(styleName);if (style == null) continue;sb.append(" : ");String styleTitle = style.getTitle();sb.append(styleTitle != null ? styleTitle : styleName);}return sb.toString();}protected void makeProgressPanel(){// Create the panel holding the progress bar during loading.JPanel outerPanel = new JPanel(new BorderLayout());outerPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));outerPanel.setPreferredSize(this.size);JPanel innerPanel = new JPanel(new BorderLayout());innerPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));JProgressBar progressBar = new JProgressBar();progressBar.setIndeterminate(true);innerPanel.add(progressBar, BorderLayout.CENTER);JButton cancelButton = new JButton("Cancel");innerPanel.add(cancelButton, BorderLayout.EAST);cancelButton.addActionListener(new AbstractAction(){public void actionPerformed(ActionEvent actionEvent){if (loadingThread.isAlive()) loadingThread.interrupt();Container c = SmartScopeWMSLayersPanel.this.getParent();c.remove(SmartScopeWMSLayersPanel.this);}});outerPanel.add(innerPanel, BorderLayout.NORTH);this.add(outerPanel, BorderLayout.CENTER);this.revalidate();}}
数据下载地址:http://download.csdn.net/detail/liushuo_whu/8426723

2 0
原创粉丝点击