当前位置:   article > 正文

OpenLayers 实用属性方法及代码实例_new ol.interaction.pointer

new ol.interaction.pointer

1.ol.interaction.Pointer

    是管理地图down、move、up事件的基类,也用于管理地图拖拽事件。

    构造函数结构如下:

new ol.interaction.Pointer(opt_options)

    options包括的属性有:
    handleDownEvent:处理地图的down事件。如果该事件返回true,drag队列开始执行。

    handleDragEvent:处理地图的drag事件。当down事件返回true,鼠标在拖拽过程中该事件一直被触发。

    handleEvent:当地图通知浏览器触发交互时调用该函数,通过返回FALSE,可终止其他交互事件的传播。

    handleMoveEvent:在拖拽的过程中触发move事件。

    handleUpEvent:捕获鼠标up事件。

2.updateWhileAnimating和updateWhileInteracting属性

    默认情况下,当在和地图交互或者动画过程中,tile和vector图层会等待这些过程执行完后才会更新。我们可以通过两个属性禁止这样的现象,在vector图层中,必须在layer级别控制。而像tiled图层可以直接通过map级别控制。代码如下:

  1. var map = new ol.Map({
  2. target: 'map',
  3. layers: [
  4. new ol.layer.Tile({
  5. source: new ol.source.TileWMS({
  6. url: 'http://demo.opengeo.org/geoserver/wms',
  7. params: {
  8. layers: 'ne_50m_land',
  9. format: 'image/png'
  10. },
  11. wrapX: false
  12. }),
  13. name: 'Natural Earth Land'
  14. }),
  15. new ol.layer.Vector({
  16. source: new ol.source.Vector({
  17. format: new ol.format.GeoJSON({
  18. defaultDataProjection: 'EPSG:4326'
  19. }),
  20. url: '../../res/world_countries.geojson',
  21. wrapX: false
  22. }),
  23. name: 'World Countries',
  24. headers: {
  25. pop_est: 'integer',
  26. gdp_md_est: 'integer'
  27. },
  28. type: 'polygon',
  29. updateWhileAnimating: false,
  30. updateWhileInteracting: false
  31. })
  32. ],
  33. view: new ol.View({
  34. center: [0, 0],
  35. zoom: 2,
  36. extent: ol.proj.get('EPSG:3857').getExtent()
  37. }),
  38. loadTilesWhileAnimating: true,
  39. loadTilesWhileInteracting: true
  40. });

3.限制地图大小属性

    只要继承至ol.layer.Base对象的图层都可通过wrapX:false限制图层在x轴方向重复;另外也可通过设置view的extend属性。

    wrapX限制

  1. var map = new ol.Map({
  2. […]
  3. new ol.layer.Tile({
  4. source: new ol.source.TileWMS({
  5. […]
  6. wrapX: false
  7. […]
  8. new ol.layer.Vector({
  9. source: new ol.source.Vector({
  10. […]
  11. wrapX: false
  12. }),

    extent显示

  1. view: new ol.View({
  2. […]
  3. extent: ol.proj.get('EPSG:3857').getExtent()
  4. }),

4.分辨率resolution运算

    在web地图中,分辨率表示一个像素点表示的单位长度。下面通过一个计算中心点的例如来说明resolution的运算。

  1. map.getView().on('propertychange', function (evt) {
  2. var projExtent = this.getProjection().getExtent();
  3. if (projExtent) {
  4. var currentCenter = this.getCenter();
  5. var currentResolution = this.getResolution();
  6. var mapSize = map.getSize();
  7. var newExtent = [projExtent[0] + currentResolution * mapSize[0] / 2,
  8. projExtent[1] + currentResolution * mapSize[1] / 2,
  9. projExtent[2] - currentResolution * mapSize[0] / 2,
  10. projExtent[3] - currentResolution * mapSize[1] / 2];
  11. if (!(new ol.geom.Point(currentCenter).intersectsExtent(newExtent))) {
  12. currentCenter[0] = Math.min(Math.max(currentCenter[0], newExtent[0]), newExtent[2]);
  13. currentCenter[1] = Math.min(Math.max(currentCenter[1], newExtent[1]), newExtent[3]);
  14. this.setCenter(currentCenter);
  15. }
  16. }
  17. });

    说明:上面是view各个属性发生变化时触发的事件,view.getProjection()获取投影系对象proj,proj.getExtent()获取投影系的边界。view.getResolution()获取当前视图的分辨率,currentResolution*mapSize[0]表示整个视图在经度方向的总长度。geom.intersectsExtent判断geom是否在extent边界总。

5.使用unByKey注销事件

    在很多ol.control.Control控件中我们会注册一些事件,但经常忽略注销,下面的方式是比较通用的注销事件方式:

  1. ol.control.NavigationHistory.prototype.setMap = function (map) {
  2. ol.control.Control.prototype.setMap.call(this, map);
  3. if (map === null) {
  4. ol.Observable.unByKey(this.get('eventId'));
  5. } else {
  6. this.set('eventId', map.on('moveend', function (evt) {
  7. if (this.get('shouldSave')) {
  8. var view = map.getView();
  9. var viewStatus = {
  10. center: view.getCenter(),
  11. resolution: view.getResolution(),
  12. rotation: view.getRotation()
  13. };
  14. var historyArray = this.get('history');
  15. var currIndex = this.get('index');
  16. historyArray.splice(currIndex + 1, historyArray.length - currIndex - 1);
  17. if (historyArray.length === this.get('maxSize')) {
  18. historyArray.splice(0, 1);
  19. } else {
  20. currIndex += 1;
  21. }
  22. historyArray.push(viewStatus);
  23. this.set('index', currIndex);
  24. } else {
  25. this.set('shouldSave', true);
  26. }
  27. }, this));
  28. }
  29. };

    当控件和地图分离时,map会被设置为null,这个时候可调用ol.Observable.unByKey方法取消对事件的监听。

6.如何改变地图的投影系

    首先要创建一个新的视图View,设置view的center、zoom、projection、extent属性。然后调用map的setView重新替换地图的视图。

  1. var view = _this.getMap().getView();
  2. var oldProj = view.getProjection();
  3. var newProj = ol.proj.get(this.value);
  4. var newView = new ol.View({
  5. center: ol.proj.transform(view.getCenter(), oldProj, newProj),
  6. zoom: view.getZoom(),
  7. projection: newProj,
  8. extent: newProj.getExtent()
  9. });
  10. _this.getMap().setView(newView);

    其次需要替换所有图层的投影系,遍历所有的图层,按照图层的类型采用不同的替换方式。

  1. _this.getMap().getLayers().forEach(function (layer) {
  2. _this.changeLayerProjection(layer, oldProj, newProj);
  3. });

    这里的changeLayerProjection是自定义的一个函数,用来处理当个图层的坐标系。

  1. ol.control.Projection.prototype.changeLayerProjection = function (layer, oldProj, newProj) {
  2. if (layer instanceof ol.layer.Group) {
  3. layer.getLayers().forEach(function (subLayer) {
  4. this.changeLayerProjection(subLayer, oldProj, newProj);
  5. });
  6. } else if (layer instanceof ol.layer.Tile) {
  7. var tileLoadFunc = layer.getSource().getTileLoadFunction();
  8. layer.getSource().setTileLoadFunction(tileLoadFunc);
  9. } else if (layer instanceof ol.layer.Vector) {
  10. var features = layer.getSource().getFeatures();
  11. for (var i = 0; i < features.length; i += 1) {
  12. features[i].getGeometry().transform(oldProj, newProj);
  13. }
  14. }
  15. };

    layer存在多种类型,所有需要判断类型分别处理。如果是ol.layer.Group类型,则继续遍历分组中的每个图层;如果图层类型为ol.layer.Tile瓦片类型,这需要getTileLoadFunction获取加载函数,重新设置下(由于瓦片图层有缓存,如果不重新设置加载方式,瓦片图层还是会从老的坐标系加载瓦片,通过setTileLoadFunction重新设置下加载函数可清理掉瓦片缓存);如果图层类型为ol.layer.Vector,需要遍历source中的所有feature,调用feature下geometry的tranform把老坐标系的坐标转换为新坐标系的坐标。

7.openlayers三种渲染方式

    DOM渲染
    DOM渲染是一种支持预THML5浏览器的传统渲染方式。主要限制在于不能显示vector图层,因为vector图层是使用canvas渲染的。仅仅tile和image图层能被DOM元素创建。如果必须支持传统的浏览器(不支持canvas),那么openlayers 2是一个不错的选择。
    Canvas渲染
    是openlayers 3默认的渲染方式,每个图层画在单独的canvas元素上。
    WEBGL
    WEBGL是浏览器对OpenGL的一个现实,浏览器有能力使用硬件加速渲染。该技术广泛用在3D客户端应用。

8.导出图层的必备参数

    crossOrigin,ol.source.TileWMS的构造函数有一个参数叫做crossOrigin,如果我们想导出地图图片,必须要设置这个参数:

  1. new ol.layer.Tile({
  2. source: new ol.source.TileWMS({
  3. url: 'http://demo.opengeo.org/geoserver/wms',
  4. params: {
  5. layers: 'nlcd',
  6. format: 'image/png'
  7. },
  8. wrapX: false,
  9. crossOrigin: 'anonymous'
  10. }),
  11. name: 'Land Cover'
  12. })

9.WEBGL

    WebGL Fundamentals

10.ol.Geolocation

    获取地理位置对象,一个HTML5的帮助类,提供HTML5 Geolocation功能。跟踪终端设备的位置。例如:

  1. var geoloc = new ol.Geolocation({
  2. projection: map.getView().getProjection(),
  3. tracking: true
  4. });
  5. var geoCaching = new ol.layer.Vector({
  6. source: new ol.source.Vector()
  7. });
  8. map.addLayer(geoCaching);
  9. geoloc.once('change:position', function (evt) {
  10. var altitude = this.getAltitude() || 100;
  11. var myPos = this.getPosition();
  12. map.getView().setCenter(myPos);
  13. map.getView().setZoom(17);
  14. for (var i = 0; i < 50; i += 1) {
  15. geoCaching.getSource().addFeature(new ol.Feature({
  16. geometry: new ol.geom.Point([myPos[0] - 500 + Math.random() * 1000, myPos[1] - 500 + Math.random() * 1000, altitude - 150 + Math.random() * 300]),
  17. loot: 'Treasures of the Seven Seas'
  18. }));
  19. }
  20. });

    说明:geoloc不需要添加到地图对象上,只需要设置投影系参数。如果想监听实时位置,可注册change: position事件。geoloc的getAltitude方法获取海拔高度。

    Geolocation对象除projection、tracking参数外,还有一个trackingOptions参数,可设置如下:

  1. var geoloc = new ol.Geolocation({
  2. projection: map.getView().getProjection(),
  3. tracking: true,
  4. trackingOptions: {
  5. enableHighAccuracy: true,
  6. maximumAge: 2000
  7. }
  8. });

    enableHighAccuracy允许高精准定位,maximumAge设置定位间隔时间,单位为毫秒。

11.Openlayers 3 shp插件使用

    shp插件支持导入shp文件到openlayers上直接展示。代码如下:

  1. layerTree.prototype.addVectorLayer = function (form) {
  2. var file = form.file.files[0];
  3. var currentProj = this.map.getView().getProjection();
  4. var fr = new FileReader();
  5. var sourceFormat = new ol.format.GeoJSON();
  6. var source = new ol.source.Vector();
  7. fr.onload = function (evt) {
  8. var vectorData = evt.target.result;
  9. var dataProjection = form.projection.value ||
  10. sourceFormat.readProjection(vectorData) || currentProj;
  11. shp(vectorData).then(function (geojson) {
  12. source.addFeatures(sourceFormat.readFeatures(geojson, {
  13. dataProjection: dataProjection,
  14. featureProjection: currentProj
  15. }));
  16. });
  17. };
  18. fr.readAsArrayBuffer(file);
  19. var layer = new ol.layer.Vector({
  20. source: source,
  21. name: form.displayname.value
  22. });
  23. this.addBufferIcon(layer);
  24. this.map.addLayer(layer);
  25. this.messages.textContent = 'Vector layer added successfully.';
  26. return this;
  27. };

12.ol.style.Icon

    如何定位图标,参考下面代码:

  1. style: new ol.style.Style({
  2. image: new ol.style.Icon({
  3. /*anchor: [0.5, 46],
  4. anchorXUnits: 'fraction',
  5. anchorYUnits: 'pixels',*/
  6. src: '../../res/marker.png'
  7. })
  8. })

13.Cesium使用

    openlayers团队封装了ol3cesium js库,ol3cesium包含了ol.js代码,所有我们在使用ol3cesium的时候不用再引用ol.js了。例如:

  1. <script type="text/javascript" src="../../js/ol3-cesium-1.10.0/Cesium/Cesium.js"></script>
  2. <script type="text/javascript" src="../../js/ol3-cesium-1.10.0/ol3cesium.js"></script>

    如果我们自定义了ol.js,我们可以在ol3cesium.js引用的后面再引用ol.js即可。例如:

  1. <script type="text/javascript" src="../../js/ol3-cesium-1.10.0/ol3cesium.js"></script>
  2. <script type="text/javascript" src="../../ol/ol.js"></script>

   Cesium场景的可视化非常智能,我们仅仅需要额外定义一个海拔瓦图源即可。创建代码如下:

  1. setTimeout(function () {
  2. var ol3d = new olcs.OLCesium({map: _this.getMap()});
  3. var scene = ol3d.getCesiumScene();
  4. scene.terrainProvider = new Cesium.CesiumTerrainProvider({
  5. url: 'http://assets.agi.com/stk-terrain/world'
  6. });
  7. _this.set('cesium', ol3d);
  8. }, 0);

    可调用cesium.setEnabled方法设置是否可用,setBlockCesiumRendering方法设置是否在后台渲染。 可通过这两个方法在2D和3D之间切换。

  1. controlButton.addEventListener('click', function (evt) {
  2. var cesium = _this.get('cesium');
  3. if (cesium.getEnabled()) {
  4. cesium.setBlockCesiumRendering(true);
  5. cesium.setEnabled(false);
  6. } else {
  7. cesium.setBlockCesiumRendering(false);
  8. cesium.setEnabled(true);
  9. }
  10. });

14.openlayers 编译环境

    phtyon必须是2.*的版本,并且配置PYTHON环境变量

转载于 OpenLayers 比较有用的对象和属性 - heavi - 博客园 (cnblogs.com) 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/155779
推荐阅读
相关标签
  

闽ICP备14008679号