Openlayers3实战(二)

来源:互联网 发布:修图软件app 编辑:程序博客网 时间:2024/06/01 08:33

译自:http://openlayers.org/

2.图层与资源

2.1网络地图服务图层

当你向你的地图中添加一个图层时,图层的资源负责获取要显示的数据。请求的数据可以是栅格数据也可以是矢量数据。你可把栅格数据想想成在服务端渲染而成的图片。矢量数据是服务端传递过来的结构化信息并且在客户端(你的浏览器)渲染显示。

提供栅格地图数据的服务有很多种。本章节讨论符合OGC网络地图服务(WMS)规范的方式。

2.1.1创建图层

我们将从一个完成的地图实例开始,通过修改图层来了解它如何运转。

让我看一下下面一段代码:

<!doctype html>

<htmllang="en">

  <head>

    <linkrel="stylesheet"href="ol3/ol.css"type="text/css">

    <style>

     #map {

       height:256px;

       width:512px;

     }

    </style>

    <scriptsrc="ol3/ol.js"type="text/javascript"></script>

    <title>OpenLayers 3 example</title>

  </head>

  <body>

    <h1>My Map</h1>

    <divid="map"></div>

    <scripttype="text/javascript">

     var map=new ol.Map({

       target:'map',

       layers: [

         new ol.layer.Tile({

           title:"Global Imagery",

           source:newol.source.TileWMS({

              url:'http://maps.opengeo.org/geowebcache/service/wms',

              params:{LAYERS:'bluemarble', VERSION:'1.1.1'}

           })

         })

       ],

       view:newol.View({

         projection:'EPSG:4326',

         center: [0,0],

         zoom:0,

         maxResolution:0.703125

       })

     });

    </script>

  </body>

</html>

任务:

1.      如果你还没有成功,把这段代码拷贝到你的map.html文件中,并放在项目的根目录中。

2.      在浏览器中访问的页面地址http://localhost:8000/ol_workshop/map.html

2.1.2ol.layer.Tile构建函数

ol.layer.Tile构造函数需要一个olx.layer.TileOptions的参数:http://openlayers.org/en/master/apidoc/ol.layer.Tile.html在这个例子我们给出了ol.source.TikeWMS资源的关键选项。给图层一个人类可读性高的标题,当然可以指定任意的标题名字。在ol3中图层与资源是分离的,然而在ol2中则都包含在图层之中。

ol.layer.Tile代表一个规则的由许多图片组成的网格,ol.layer.Image代表一个图片。根据不同的图层的类型,你要使用不同的资源(ol.source.TileWMS与ol.source.ImageWMS)。

2.1.3ol.source.TileWMS构造函数

ol.source.TileWMS构造函数只有一个参数,可以看一下它的API文档:http://openlayers.org/en/master/apidoc/ol.source.TileWMS.html。这个url是WMS服务的在线资源,参数是一个由参数名和值构成的文字对象。Openlayers中的WMS默认版本是1.3.0,如果你的WMS不支持此版本那你要在参数中选择小版本。

layers: [
  new ol.layer.Tile({
    title:"Global Imagery",
    source:new ol.source.TileWMS({
      url:'http://maps.opengeo.org/geowebcache/service/wms',
      params: {LAYERS:'bluemarble', VERSION:'1.1.1'}
    })
  })
]

任务:

1.      同一个WMS提供了一个“openstreetmap”的图层。把上面例子中的bluemarble换为openstreetmap。如下:

new ol.layer.Tile({
  title:"Global Imagery",
  source:new ol.source.TileWMS({
    url:'http://maps.opengeo.org/geowebcache/service/wms',
    params: {LAYERS:'openstreetmap', VERSION:'1.1.1'}
  })
})

 

2.      将你的图层和资源换成单图片的方式,看一下它的API文档:http://openlayers.org/en/master/apidoc/ol.layer.Image.htmlhttp://openlayers.org/en/master/apidoc/ol.source.ImageWMS.html。把url改为http://suite.opengeo.org/geoserver/wms把图层名称改为opengeo:countries。在浏览器里面访问一下:

地图以image/png的方式显示OpenStreetMap图层。

 

2.2缓存瓦片

默认情况下,瓦片图层通过请求的256x256的瓦片填充我们的地图试图。当你在你的地图平移和缩放图像,更多的请求去获取瓦片来填补之前没有访问过的区域。当你的浏览器将要请求的缓存图像时,大量处理工作通常是服务器处理的。

当瓦片图层请求的图片在一个规则的网格中,那么服务器会缓存本次访问的图片资源,如果下次有同样的请求,那么就返回上次缓存的图片。这样有利于服务器性能的提升。

2.2.1ol.source.XYZ

无论在哪一个客户端可以请求,Web地图服务规范有很大的灵活性。如果没有约束,这使得缓存在实践中很难或不可能。

在另一个极端,一个服务可以只在一个固定的缩放级别和只针对一个规则的网格提供瓦片。这些可以概括为一个以xyz作为资源的瓦片图层,通过x表示列用y表示行,用z表示缩放级别。

2.2.2ol.source.OSM

OpenStreetMapOSM)是一个努力收集和做免费的世界地图数据项目。OSM提供一些不同的效果的缓存瓦片数据。这些数据符合基本的XYZ网格布置,可以用在OpenLayers地图之中。ol.source.osm图层资源访问OpenStreetMap的瓦片。

任务:

1.    用文本编辑器打开map.html文件,改变里面地图初始化的代码如下:

<script>
  var map =new ol.Map({
    target:'map',
    layers: [
      new ol.layer.Tile({
        source:new ol.source.OSM()
      })
    ],
    view:new ol.View({
      center: ol.proj.transform([-93.27,44.98],'EPSG:4326','EPSG:3857'),
      zoom:9
    }),
    controls: ol.control.defaults({
      attributionOptions: {
        collapsible:false
      }
    })
  });
</script>

2.    <head>标签元素中加入下面的样式,用来控制图层属性:

<style>
    #map {
        width:512px;
        height:256px;
    }
    .ol-attributiona {
        color:black;
    }
</style>

3.    保存后在浏览器中访问http://localhost:8000/ol_workshop/map.html

一个用OpenStreetMap的地图。

2.2.2.1仔细看看

2.2.2.1.1投影

看一下地图中view的定义:

view:new ol.View({
  center: ol.proj.transform([-93.27,44.98],'EPSG:4326','EPSG:3857'),
  zoom:9
})

地理空间数据可以存在于坐标系统的数值中。一个数据集可以用以经纬度表示的地理坐标系(经度与维度),也可用一个以米为单位的投影坐标。详细的讨论坐标系系统超出了本章节的范围,但理解一些基本概念是必须的。

OpenLayers 3需要知道你数据的坐标系统。在内部,坐标系用一个ol.proj.Projection对象表示。ol.proj命名空间中的transform函数也是读取字符串格式的配置参数,这个字符串参数表示了坐标系统("EPSG:4326" and "EPSG:3857")。

OpenStreetMap瓦片用的是墨卡托投影。因此,我们需要设置墨卡托坐标系的初始中心点坐标。因为在地理坐标系中找到一个兴趣所在的坐标是比较容易的,我们利用ol.proj.transform法将地理坐标(” EPSG:4326”)转为墨卡托坐标(”EPSG:3857”)。

2.2.2.1.1.1可选择的投影方式(两种)

OpenLayers 3包含了地理坐标系” EPSG:4326”)与网络墨卡托坐标系”EPSG:3857”)的转换机制。因此,我们只需用ol.proj.transform函数,不需要任何额外工作。如果你想用其他坐标系的数据,你只要用ol.proj.transform函数把投影信息加载进来就ok了。

举个例子,如果你先够用“EPSG:21781”坐标系的数据,那么在你代码中要引入下面两个脚本:

<script src="http://cdnjs.cloudflare.com/ajax/libs/proj4js/2.2.1/proj4.js"type="text/javascript"></script>
<script src="http://epsg.io/21781-1753.js"type="text/javascript"></script>

在你的程序代码中,你才能够注册投影并且为他设置范围,如下:

// This creates a projection object for the EPSG:21781 projection
// and sets a "validity extent" in that projection object.
var projection = ol.proj.get('EPSG:21781');
projection.setExtent([485869.5728,76443.1884,837076.5648,299941.7864]);

更多信息请去这里查看: http://epsg.io/

2.2.2.1.1.2图层创建

layers: [
  new ol.layer.Tile({
    source:new ol.source.OSM()
  })
],

正如之前所述,我们创建一个图层并将其添加到地图配置文件的列表中。这次我们默认所有图层的资源属性。

2.2.2.1.1.3样式

.ol-attributiona {
  color:black;
}

如何设置地图的外部属性也不是本章节要讨论的问题,但是这个样式设置先给你一个预览。默认情况下,一个ol.control.attribution控件已经添加到所有的地图之中。这些图层资源在地图试图中显示属性信息。上面的样式声明会改变我们的地图属性样式。

2.2.2.1.1.4属性控制配置

默认情况下,ol.control.Attribution在地图上添加一个i按钮,点击可按实际显示归属地信息。遵守 OpenStreetMap使用条款,并且显示OpenStreetMap属性信息,看下面一个例子:

controls: ol.control.defaults({
  attributionOptions: {
    collapsible:false
  }
})

在地图上去除i按钮,并且总是隐藏OpenStreetMap属性信息。

2.3专有的栅格图层

在上一章节中,我们展示的图层是基于标准的兼容WMS和自定瓦片格式的图层。在线地图很大程度上是被专有栅格地图服务推广的。OpenLayers 提供的图层类型可以基于其的API使用。

在本章节中,我们将用Bing地图做一个例子。

想了解OpenLayers 3Google Map如何整合,可以访问:http://openlayers.org/en/master/examples/google-map.html

2.3.1Bing!

让我们来加载一个Bing图层。

任务:

1.       在你的map.html文件中,找到OSM资源,然后将他替换为 an ol.source.BingMaps

source:new ol.source.BingMaps({
  imagerySet:'Road',
  key:'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3'
})

注意:Bing的瓦片API要求你注册一个API密钥,这样才能在您的地图应用中使用。上面代码中key你不可以用于产品之中,如果要使用请您去注册一个: https://www.bingmapsportal.com/

2.      保存页面,并访问它: http://localhost:8000/ol_workshop/map.html

2.3.1完整的示例

你的代码应该是这样的

<!doctype html>
<htmllang="en">
  <head>
    <linkrel="stylesheet"href="ol3/ol.css"type="text/css">
    <style>
      #map {
        height:256px;
        width:512px;
      }
      .ol-attributiona {
        color:black;
      }
    </style>
    <script src="ol3/ol.js"type="text/javascript"></script>
    <title>OpenLayers 3 example</title>
  </head>
  <body>
    <h1>My Map</h1>
    <divid="map"class="map"></div>
    <script type="text/javascript">
      var map =new ol.Map({
        target:'map',
        layers: [
          new ol.layer.Tile({
            source:new ol.source.BingMaps({
              imagerySet:'Road',
              key:'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3'
            })
          })
        ],
        view:new ol.View({
          center: ol.proj.transform([-93.27,44.98],'EPSG:4326','EPSG:3857'),
          zoom:9
        })
      });
    </script>
  </body>
</html>

 

2.4矢量图层                     

矢量图层用ol.layer.Vector表示,是在客户端渲染的。目前Openlayers3支持在画布渲染器中进行渲染矢量数据。

2.4.1客户端渲染要素

让我们回归WMS例子来获取一个基础的地图。然后我们在这个图层上添加一些矢量元素

<!doctype html>
<htmllang="en">
  <head>
    <linkrel="stylesheet"href="ol3/ol.css"type="text/css">
    <style>
      #map {
        height:256px;
        width:512px;
      }
    </style>
    <title>OpenLayers 3 example</title>
    <script src="ol3/ol.js"type="text/javascript"></script>
  </head>
  <body>
    <h1>My Map</h1>
    <divid="map"></div>
    <script type="text/javascript">
      var map =new ol.Map({
        target:'map',
        layers: [
          new ol.layer.Tile({
            title:"Global Imagery",
            source:new ol.source.TileWMS({
              url:'http://maps.opengeo.org/geowebcache/service/wms',
              params: {LAYERS:'bluemarble', VERSION:'1.1.1'}
            })
          })
        ],
        view:new ol.View({
          projection:'EPSG:4326',
          center: [0,0],
          zoom:0,
          maxResolution:0.703125
        })
      });
    </script>
  </body>
</html>

任务:

1.      打开你的map.html文件,把上面的代码拷贝进去,然后保存运行。

2.      打开你的map.html文件,在初始化代码里面加入另一个图层(如下)。这个同层会添加进去一些存储在GeoJSON中的矢量元素。

new ol.layer.Vector({
  title:'Earthquakes',
  source:new ol.source.GeoJSON({
    url:'data/layers/7day-M2.5.json'
  }),
  style:new ol.style.Style({
    image:new ol.style.Circle({
      radius:3,
      fill:new ol.style.Fill({color:'white'})
    })
  })
})

带有地震点位置的世界地图。

2.4.1.1仔细看看

让我们检查矢量图层的创建过程,从中得到它是怎么运行的

new ol.layer.Vector({
   title:'Earthquakes',
   source:new ol.source.GeoJSON({
    url:'data/layers/7day-M2.5.json'
  }),
  style:new ol.style.Style({
    image:new ol.style.Circle({
      radius:3,
      fill:new ol.style.Fill({color:'white'})
    })
  })
})

图层给出了title'Earthquakes'和自定义属性。在选项中,通过source指定了ol.source.GeoJSON格式的url。

注意:你不能像之前定义vector样式那样指定样式了,你需要用样式函数来实现。

额外任务:

1.      矢量图层中每一个白点都是一个ol.Feature对象。每一个对象都有title 与summary 属性。在地图上注册一个叫做forEachFeatureAtPixel的单击事件,在地图试图下方实现地震点的属性。

2.      矢量图层的数据来自美国地质调查局公布的地震资料(http://earthquake.usgs.gov/earthquakes/catalogs/)

2.5矢量图片

你可以看到,在前使用ol.layer.vector的例子中,在图层动画缩放的过程中,元素在不断的重新渲染(点符号的大小保持不变)。用矢量图层,在每一帧动画中OpenLayers将重新渲染数据来源。线杆、点图片以及标注的渲染结果是一致的。

另一个渲染策略是在视图转换时避免重新绘制数据,并且取代重定位与前一视图的尺度变化。可以用使用带有ol.source.ImageVectorol.layer.Image图层解决。与此相结合,在你的试图不动时你的数据的快照就被渲染了,并且试图切换时这些快照可以重用。

下面的例子使用了带有ol.source.ImageVectorol.layer.Image图层。这个例子只是用了一个小范围的数据,不过可以提供思路,你可以将这个方式用在大范围的数据上面。

2.5.1ol.source.ImageVector

让我回归上一矢量图层的例子

<!doctype html>
<htmllang="en">
  <head>
    <linkrel="stylesheet"href="ol3/ol.css"type="text/css">
    <style>
      #map {
        height:256px;
        width:512px;
      }
    </style>
    <title>OpenLayers 3 example</title>
    <script src="ol3/ol.js"type="text/javascript"></script>
  </head>
  <body>
    <h1>My Map</h1>
    <divid="map"></div>
    <script type="text/javascript">
      var map =new ol.Map({
        target:'map',
        layers: [
          new ol.layer.Tile({
            title:"Global Imagery",
            source:new ol.source.TileWMS({
              url:'http://maps.opengeo.org/geowebcache/service/wms',
              params: {LAYERS:'bluemarble', VERSION:'1.1.1'}
            })
          }),
          new ol.layer.Vector({
            title:'Earthquakes',
            source:new ol.source.GeoJSON({
              url:'data/layers/7day-M2.5.json'
            }),
            style:new ol.style.Style({
              image:new ol.style.Circle({
                radius:3,
                fill:new ol.style.Fill({color:'white'})
              })
            })
          })
        ],
        view:new ol.View({
          projection:'EPSG:4326',
          center: [0,0],
          zoom:0,
          maxResolution:0.703125
        })
      });
    </script>
  </body>
</html>

任务:

1.      打开map.html文件,将上面的代码拷贝进去,保存运行。

2.      改变矢量图层

new ol.layer.Image({
  title:'Earthquakes',
  source:new ol.source.ImageVector({
    source:new ol.source.GeoJSON({
      url:'data/layers/7day-M2.5.json'
    }),
    style:new ol.style.Style({
      image:new ol.style.Circle({
      radius:3,
        fill:new ol.style.Fill({color:'white'})
      })
    })
  })
})

 

3.      刷新浏览器

0 0