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

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

2015-02-05 11:39 676 查看
数据是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
{
// 请求地图的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源码如下:
/*
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐