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


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

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

    1、添加天地图地图服务

    由于上篇转载的平常心的博客对WMSTiledImageLayer已经讲的非常清楚了,这里不再赘述了,看代码:
    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    1. public static WMSTiledImageLayer addTianDiTuImage() throws Exception  
    2. {  
    3.     // 请求地图的URL  
    4.     String uri = "http://www.scgis.net.cn/imap/iMapServer/defaultRest/services/newtianditudom/WMS";  
    5.     // WMS  
    6.     WMSCapabilities caps;  
    7.     URI serverURI;  
    8.     serverURI = new URI(uri);  
    9.     // 获得WMSCapabilities对象  
    10.     caps = WMSCapabilities.retrieve(serverURI);  
    11.     // 解析WMSCapabilities数据  
    12.     caps.parse();  
    13.   
    14.     // // 输出wms元数据信息  
    15.     // System.out.println(caps.getCapabilityInformation().toString());  
    16.     // 获取所有图层(这里只有一个,自己用geoserver发布的则可能有很多)  
    17.     final List<WMSLayerCapabilities> namedLayerCaps = caps.getNamedLayers();  
    18.     String layerName = null;  
    19.     for (WMSLayerCapabilities wmsLayerCapabilities : namedLayerCaps)  
    20.     {  
    21.         layerName = wmsLayerCapabilities.getName();  
    22.     }  
    23.     AVList params = new AVListImpl();  
    24.     // 图层的名称  
    25.     params.setValue(AVKey.LAYER_NAMES, layerName);  
    26.     // 地图服务的协议,这里是OGC:WMS  
    27.     params.setValue(AVKey.SERVICE_NAME, "OGC:WMS");  
    28.     // 获得地图的uri,也就是上面定义的uri  
    29.     params.setValue(AVKey.GET_MAP_URL, uri);  
    30.     // 在本地缓存文件的名称  
    31.     params.setValue(AVKey.DATA_CACHE_NAME, layerName);  
    32.     params.setValue(AVKey.TILE_URL_BUILDER,  
    33.             new WMSTiledImageLayer.URLBuilder(params));  
    34.   
    35.     WMSTiledImageLayer layer = new WMSTiledImageLayer(caps, params);  
    36.     return layer;  
    37. }  

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

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

    这里加载的效果要比天地图的在线三维球的效果要好,有兴趣的可以去对比下。另外天地图的在线三维体验还是比较差的,只是单纯的浏览,单是这个体验效果还不是很好,毕竟这是政府的东东,不像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?在CODE上查看代码片派生到我的代码片
    1. /* 
    2. Copyright (C) 2001, 2006 United States Government 
    3. as represented by the Administrator of the 
    4. National Aeronautics and Space Administration. 
    5. All Rights Reserved. 
    6.  */  
    7. package gov.nasa.worldwindx.examples;  
    8.   
    9. import gov.nasa.worldwind.*;  
    10. import gov.nasa.worldwind.avlist.*;  
    11. import gov.nasa.worldwind.globes.ElevationModel;  
    12. import gov.nasa.worldwind.layers.*;  
    13. import gov.nasa.worldwind.ogc.wms.*;  
    14. import gov.nasa.worldwind.terrain.CompoundElevationModel;  
    15. import gov.nasa.worldwind.util.WWUtil;  
    16. import gov.nasa.worldwindx.examples.WMSLayersPanel.LayerInfo;  
    17.   
    18. import javax.swing.*;  
    19. import javax.swing.border.*;  
    20.   
    21. import java.awt.*;  
    22. import java.awt.event.*;  
    23. import java.net.*;  
    24. import java.util.*;  
    25. import java.util.List;  
    26.   
    27. /** 
    28.  *  
    29.  * @项目名称:worldwind-1.5.0 
    30.  * @类名称:SmartScopeWMSLayersPanel 
    31.  * @类描述: WMS服务图层管理面板 
    32.  * @创建人:bluce 
    33.  * @创建时间:2015年2月4日 下午5:09:31 
    34.  * @修改备注: 
    35.  * @版本: 
    36.  */  
    37. public class SmartScopeWMSLayersPanel extends JPanel  
    38. {  
    39.   
    40.     /** 
    41.      * @Fields serialVersionUID : TODO 
    42.      */  
    43.   
    44.     private static final long serialVersionUID = 1L;  
    45.   
    46.     protected static class LayerInfo  
    47.     {  
    48.         protected WMSCapabilities caps;  
    49.         protected AVListImpl params = new AVListImpl();  
    50.   
    51.         protected String getTitle()  
    52.         {  
    53.             return params.getStringValue(AVKey.DISPLAY_NAME);  
    54.         }  
    55.   
    56.         protected String getName()  
    57.         {  
    58.             return params.getStringValue(AVKey.LAYER_NAMES);  
    59.         }  
    60.   
    61.         protected String getAbstract()  
    62.         {  
    63.             return params.getStringValue(AVKey.LAYER_ABSTRACT);  
    64.         }  
    65.     }  
    66.   
    67.     // 所有图层元数据信息  
    68.     protected String[] servers;  
    69.     protected List<WMSLayerCapabilities> namedLayerCaps;  
    70.     protected WorldWindow wwd;  
    71.     protected URI serverURI;  
    72.     protected Dimension size;  
    73.     protected Thread loadingThread;  
    74.     protected TreeSet<LayerInfo> layerInfos = new TreeSet<LayerInfo>(  
    75.             new Comparator<LayerInfo>()  
    76.             {  
    77.                 public int compare(LayerInfo infoA, LayerInfo infoB)  
    78.                 {  
    79.                     String nameA = infoA.getName();  
    80.                     String nameB = infoB.getName();  
    81.                     return nameA.compareTo(nameB);  
    82.                 }  
    83.             });  
    84.   
    85.       
    86.       
    87.     public  SmartScopeWMSLayersPanel(String[] servers)  
    88.     {  
    89.           
    90.           
    91.     }  
    92.   
    93.     /** 
    94.      *  
    95.      * 创建一个新的实例 SmartScopeWMSLayersPanel. 
    96.      *  
    97.      * @param wwd 
    98.      * @param server 
    99.      * @param size 
    100.      * @throws URISyntaxException 
    101.      */  
    102.     public SmartScopeWMSLayersPanel(WorldWindow wwd, String[] server,  
    103.             Dimension size) throws URISyntaxException  
    104.     {  
    105.         super(new BorderLayout());  
    106.   
    107.         this.servers = server;  
    108.         this.wwd = wwd;  
    109.         this.size = size;  
    110.         this.setPreferredSize(this.size);  
    111.   
    112.         this.makeProgressPanel();  
    113.   
    114.         // Thread off a retrieval of the server's capabilities document and  
    115.         // update of this panel.  
    116.         this.loadingThread = new Thread(new Runnable()  
    117.         {  
    118.             public void run()  
    119.             {  
    120.                 load();  
    121.             }  
    122.         });  
    123.         this.loadingThread.setPriority(Thread.MIN_PRIORITY);  
    124.         this.loadingThread.start();  
    125.     }  
    126.   
    127.     /** 
    128.      *  
    129.      * @方法名称: load ; 
    130.      * @方法描述: 加载服务 ; 
    131.      * @参数 : 
    132.      * @返回类型: void ; 
    133.      * @创建人:bluce; 
    134.      * @创建时间:2015年2月5日 上午9:33:23; 
    135.      * @throws 
    136.      */  
    137.     protected void load()  
    138.     {  
    139.         WMSCapabilities caps = null;  
    140.         try  
    141.         {  
    142.             for (int i = 0; i < servers.length; i++)  
    143.             {  
    144.   
    145.                 this.serverURI = new URI(servers[i].trim());  
    146.                 caps = WMSCapabilities.retrieve(this.serverURI);  
    147.                 caps.parse();  
    148.                 // 获取该服务下的所有图层元数据描述  
    149.                 namedLayerCaps = caps.getNamedLayers();  
    150.   
    151.                 if (namedLayerCaps == null) return;  
    152.   
    153.                 try  
    154.                 {  
    155.                     for (WMSLayerCapabilities lc : namedLayerCaps)  
    156.                     {  
    157.                         Set<WMSLayerStyle> styles = lc.getStyles();  
    158.                         if (styles == null || styles.size() == 0)  
    159.                         {  
    160.                             LayerInfo layerInfo = createLayerInfo(caps, lc,  
    161.                                     null);  
    162.                             SmartScopeWMSLayersPanel.this.layerInfos  
    163.                                     .add(layerInfo);  
    164.                         }  
    165.                         else  
    166.                         {  
    167.                             for (WMSLayerStyle style : styles)  
    168.                             {  
    169.                                 LayerInfo layerInfo = createLayerInfo(caps, lc,  
    170.                                         style);  
    171.                                 SmartScopeWMSLayersPanel.this.layerInfos  
    172.                                         .add(layerInfo);  
    173.                             }  
    174.                         }  
    175.                     }  
    176.                 }  
    177.                 catch (Exception e)  
    178.                 {  
    179.                     e.printStackTrace();  
    180.                     return;  
    181.                 }  
    182.   
    183.                 // 在面板上显示所有图层的名称  
    184.                 EventQueue.invokeLater(new Runnable()  
    185.                 {  
    186.                     public void run()  
    187.                     {  
    188.                         SmartScopeWMSLayersPanel.this.removeAll();  
    189.                         makeLayerInfosPanel(layerInfos);  
    190.                     }  
    191.                 });  
    192.   
    193.             }  
    194.   
    195.         }  
    196.         catch (Exception e)  
    197.         {  
    198.             e.printStackTrace();  
    199.         }  
    200.   
    201.         // Gather up all the named layers and make a world wind layer for each.  
    202.   
    203.     }  
    204.   
    205.     public String getServerDisplayString()  
    206.     {  
    207.         return this.serverURI.getHost();  
    208.     }  
    209.   
    210.     protected LayerInfo createLayerInfo(WMSCapabilities caps,  
    211.             WMSLayerCapabilities layerCaps, WMSLayerStyle style)  
    212.     {  
    213.         // Create the layer info specified by the layer's capabilities entry and  
    214.         // the selected style.  
    215.         LayerInfo linfo = new LayerInfo();  
    216.         linfo.caps = caps;  
    217.         linfo.params = new AVListImpl();  
    218.         linfo.params.setValue(AVKey.LAYER_NAMES, layerCaps.getName());  
    219.         if (style != null) linfo.params.setValue(AVKey.STYLE_NAMES,  
    220.                 style.getName());  
    221.         String abs = layerCaps.getLayerAbstract();  
    222.         if (!WWUtil.isEmpty(abs)) linfo.params.setValue(AVKey.LAYER_ABSTRACT,  
    223.                 abs);  
    224.   
    225.         linfo.params.setValue(AVKey.DISPLAY_NAME, makeTitle(caps, linfo));  
    226.   
    227.         return linfo;  
    228.     }  
    229.   
    230.     protected void makeLayerInfosPanel(Collection<LayerInfo> layerInfos)  
    231.     {  
    232.         // JPanel layersPanel = new JPanel(new GridLayout(0, 1, 0, 4));  
    233.         // layersPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));  
    234.         JPanel layersPanel = new JPanel();  
    235.         BoxLayout layout = new BoxLayout(layersPanel, BoxLayout.Y_AXIS);  
    236.         layersPanel.setLayout(layout);  
    237.         layersPanel.setFont(new Font("宋体", Font.PLAIN, 10));  
    238.         // Add the server's layers to the panel.  
    239.         for (LayerInfo layerInfo : layerInfos)  
    240.         {  
    241.             addLayerInfoPanel(layersPanel, SmartScopeWMSLayersPanel.this.wwd,  
    242.                     layerInfo);  
    243.         }  
    244.   
    245.         // Put the name panel in a scroll bar.  
    246.         JScrollPane scrollPane = new JScrollPane(layersPanel);  
    247.         scrollPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));  
    248.         scrollPane.setPreferredSize(size);  
    249.   
    250.         // Add the scroll bar and name panel to a titled panel that will resize  
    251.         // with the main window.  
    252.         // JPanel westPanel = new JPanel(new GridLayout(0, 1, 0, 10));  
    253.         // westPanel.setBorder(new  
    254.         // CompoundBorder(BorderFactory.createEmptyBorder(  
    255.         // 9, 9, 9, 9), new TitledBorder("Layers")));  
    256.         // westPanel.add(scrollPane);  
    257.         this.add(scrollPane, BorderLayout.CENTER);  
    258.   
    259.         this.revalidate();  
    260.     }  
    261.   
    262.     protected void addLayerInfoPanel(JPanel layersPanel, WorldWindow wwd,  
    263.             LayerInfo linfo)  
    264.     {  
    265.         // Give a layer a button and label and add it to the layer names panel.  
    266.   
    267.         LayerInfoAction action = new LayerInfoAction(linfo, wwd);  
    268.         if (linfo.getAbstract() != null)  
    269.         {  
    270.             action.putValue(Action.SHORT_DESCRIPTION, linfo.getAbstract());  
    271.             JCheckBox jcb = new JCheckBox(action);  
    272.             jcb.setFont(new Font("宋体", Font.PLAIN, 14));  
    273.             jcb.setSelected(false);  
    274.             layersPanel.add(jcb);  
    275.         }  
    276.   
    277.     }  
    278.   
    279.     protected class LayerInfoAction extends AbstractAction  
    280.     {  
    281.         protected WorldWindow wwd;  
    282.         protected LayerInfo layerInfo;  
    283.         protected Object component;  
    284.   
    285.         public LayerInfoAction(LayerInfo linfo, WorldWindow wwd)  
    286.         {  
    287.             super(linfo.getTitle());  
    288.   
    289.             // Capture info we'll need later to control the layer.  
    290.             this.wwd = wwd;  
    291.             this.layerInfo = linfo;  
    292.         }  
    293.   
    294.         public void actionPerformed(ActionEvent actionEvent)  
    295.         {  
    296.             // If the layer is selected, add it to the world window's current  
    297.             // model, else remove it from the model.  
    298.             if (((JCheckBox) actionEvent.getSource()).isSelected())  
    299.             {  
    300.                 if (this.component == null) this.component = createComponent(  
    301.                         layerInfo.caps, layerInfo.params);  
    302.   
    303.                 updateComponent(this.component, true);  
    304.             }  
    305.             else  
    306.             {  
    307.                 if (this.component != null) updateComponent(this.component,  
    308.                         false);  
    309.             }  
    310.   
    311.             // Tell the world window to update.  
    312.             wwd.redraw();  
    313.         }  
    314.     }  
    315.   
    316.     protected void updateComponent(Object component, boolean enable)  
    317.     {  
    318.         if (component instanceof Layer)  
    319.         {  
    320.             Layer layer = (Layer) component;  
    321.             LayerList layers = this.wwd.getModel().getLayers();  
    322.   
    323.             layer.setEnabled(enable);  
    324.   
    325.             if (enable)  
    326.             {  
    327.                 if (!layers.contains(layer))  
    328.                 {  
    329.                     ApplicationTemplate.insertBeforePlacenames(this.wwd, layer);  
    330.                     ApplicationTemplate.insertBeforeLayerName(wwd, layer,  
    331.                             "Landsat");  
    332.                     this.firePropertyChange("LayersPanelUpdated", null, layer);  
    333.                 }  
    334.             }  
    335.             else  
    336.             {  
    337.                 layers.remove(layer);  
    338.                 this.firePropertyChange("LayersPanelUpdated", layer, null);  
    339.             }  
    340.         }  
    341.         else if (component instanceof ElevationModel)  
    342.         {  
    343.             ElevationModel model = (ElevationModel) component;  
    344.             CompoundElevationModel compoundModel = (CompoundElevationModel) this.wwd  
    345.                     .getModel().getGlobe().getElevationModel();  
    346.   
    347.             if (enable)  
    348.             {  
    349.                 if (!compoundModel.getElevationModels().contains(model)) compoundModel  
    350.                         .addElevationModel(model);  
    351.             }  
    352.         }  
    353.     }  
    354.   
    355.     protected static Object createComponent(WMSCapabilities caps, AVList params)  
    356.     {  
    357.         AVList configParams = params.copy(); // Copy to insulate changes from  
    358.                                                 // the caller.  
    359.   
    360.         // Some wms servers are slow, so increase the timeouts and limits used  
    361.         // by world wind's retrievers.  
    362.         configParams.setValue(AVKey.URL_CONNECT_TIMEOUT, 30000);  
    363.         configParams.setValue(AVKey.URL_READ_TIMEOUT, 30000);  
    364.         configParams.setValue(AVKey.RETRIEVAL_QUEUE_STALE_REQUEST_LIMIT, 60000);  
    365.   
    366.         try  
    367.         {  
    368.             String factoryKey = getFactoryKeyForCapabilities(caps);  
    369.             Factory factory = (Factory) WorldWind  
    370.                     .createConfigurationComponent(factoryKey);  
    371.             return factory.createFromConfigSource(caps, configParams);  
    372.         }  
    373.         catch (Exception e)  
    374.         {  
    375.             // Ignore the exception, and just return null.  
    376.         }  
    377.   
    378.         return null;  
    379.     }  
    380.   
    381.     protected static String getFactoryKeyForCapabilities(WMSCapabilities caps)  
    382.     {  
    383.         boolean hasApplicationBilFormat = false;  
    384.   
    385.         Set<String> formats = caps.getImageFormats();  
    386.         for (String s : formats)  
    387.         {  
    388.             if (s.contains("application/bil"))  
    389.             {  
    390.                 hasApplicationBilFormat = true;  
    391.                 break;  
    392.             }  
    393.         }  
    394.   
    395.         return hasApplicationBilFormat ? AVKey.ELEVATION_MODEL_FACTORY  
    396.                 : AVKey.LAYER_FACTORY;  
    397.     }  
    398.   
    399.     protected static String makeTitle(WMSCapabilities caps, LayerInfo layerInfo)  
    400.     {  
    401.         String layerNames = layerInfo.params.getStringValue(AVKey.LAYER_NAMES);  
    402.         String styleNames = layerInfo.params.getStringValue(AVKey.STYLE_NAMES);  
    403.         String[] lNames = layerNames.split(",");  
    404.         String[] sNames = styleNames != null ? styleNames.split(",") : null;  
    405.   
    406.         StringBuilder sb = new StringBuilder();  
    407.         for (int i = 0; i < lNames.length; i++)  
    408.         {  
    409.             if (sb.length() > 0) sb.append(", ");  
    410.   
    411.             String layerName = lNames[i];  
    412.             WMSLayerCapabilities lc = caps.getLayerByName(layerName);  
    413.             String layerTitle = lc.getTitle();  
    414.             sb.append(layerTitle != null ? layerTitle : layerName);  
    415.   
    416.             if (sNames == null || sNames.length <= i) continue;  
    417.   
    418.             String styleName = sNames[i];  
    419.             WMSLayerStyle style = lc.getStyleByName(styleName);  
    420.             if (style == null) continue;  
    421.   
    422.             sb.append(" : ");  
    423.             String styleTitle = style.getTitle();  
    424.             sb.append(styleTitle != null ? styleTitle : styleName);  
    425.         }  
    426.   
    427.         return sb.toString();  
    428.     }  
    429.   
    430.     protected void makeProgressPanel()  
    431.     {  
    432.         // Create the panel holding the progress bar during loading.  
    433.   
    434.         JPanel outerPanel = new JPanel(new BorderLayout());  
    435.         outerPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));  
    436.         outerPanel.setPreferredSize(this.size);  
    437.   
    438.         JPanel innerPanel = new JPanel(new BorderLayout());  
    439.         innerPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));  
    440.         JProgressBar progressBar = new JProgressBar();  
    441.         progressBar.setIndeterminate(true);  
    442.         innerPanel.add(progressBar, BorderLayout.CENTER);  
    443.   
    444.         JButton cancelButton = new JButton("Cancel");  
    445.         innerPanel.add(cancelButton, BorderLayout.EAST);  
    446.         cancelButton.addActionListener(new AbstractAction()  
    447.         {  
    448.             public void actionPerformed(ActionEvent actionEvent)  
    449.             {  
    450.                 if (loadingThread.isAlive()) loadingThread.interrupt();  
    451.   
    452.                 Container c = SmartScopeWMSLayersPanel.this.getParent();  
    453.                 c.remove(SmartScopeWMSLayersPanel.this);  
    454.             }  
    455.         });  
    456.   
    457.         outerPanel.add(innerPanel, BorderLayout.NORTH);  
    458.         this.add(outerPanel, BorderLayout.CENTER);  
    459.         this.revalidate();  
    460.     }  
    461. }  
    数据下载地址:http://download.csdn.net/detail/liushuo_whu/8426723
  • 相关阅读:
    deeplearning.ai 卷积神经网络 Week 1 卷积神经网络
    deeplearning.ai 构建机器学习项目 Week 2 机器学习策略 II
    deeplearning.ai 构建机器学习项目 Week 1 机器学习策略 I
    deeplearning.ai 改善深层神经网络 week3 超参数调试、Batch Normalization和程序框架
    deeplearning.ai 改善深层神经网络 week2 优化算法
    deeplearning.ai 改善深层神经网络 week1 深度学习的实用层面
    cs231n spring 2017 lecture8 Deep Learning Networks
    cs231n spring 2017 lecture7 Training Neural Networks II
    cs231n spring 2017 lecture6 Training Neural Networks I
    cs231n spring 2017 Python/Numpy基础
  • 原文地址:https://www.cnblogs.com/telwanggs/p/6774741.html
Copyright © 2020-2023  润新知