您的位置:首页 > 编程语言 > Java开发

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

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

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

1、添加天地图地图服务

由于上篇转载的平常心的博客对WMSTiledImageLayer已经讲的非常清楚了,这里不再赘述了,看代码:

[java] view plain copy

print?





public static WMSTiledImageLayer addTianDiTuImage() throws Exception

{

// 请求地图的URL

String uri = "http://www.scgis.net.cn/imap/iMapServer/defaultRest/services/newtianditudom/WMS";

// WMS

WMSCapabilities 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:WMS

params.setValue(AVKey.SERVICE_NAME, "OGC:WMS");

// 获得地图的uri,也就是上面定义的uri

params.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源码如下:

[java] view plain copy

print?





/*

Copyright (C) 2001, 2006 United States Government

as represented by the Administrator of the

National 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐