【OpenLayer : 语法】OpenLayers 比较有用的对象和属性
转载:OpenLayers 比较有用的对象和属性
1.ol.interaction.Pointer
是管理地图down、move、up事件的基类,也用于管理地图拖拽事件。
构造函数结构如下:
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级别控制。代码如下:
map = ol.Map({ target: 'map', layers: [ ol.layer.Tile({ source: ol.source.TileWMS({ url: 'http://demo.opengeo.org/geoserver/wms', params: { layers: 'ne_50m_land', format: 'image/png' }, wrapX: false }), name: 'Natural Earth Land' ol.layer.Vector({ source: ol.source.Vector({ format: ol.format.GeoJSON({ defaultDataProjection: 'EPSG:4326' }), url: '../../res/world_countries.geojson', wrapX: false }), name: 'World Countries', headers: { pop_est: 'integer', gdp_md_est: 'integer' }, type: 'polygon', updateWhileAnimating: false, updateWhileInteracting: false }) ], view: ol.View({ center: [0, 0], zoom: 2, extent: ol.proj.get('EPSG:3857').getExtent() }), loadTilesWhileAnimating: , loadTilesWhileInteracting:
3.限制地图大小属性
只要继承至ol.layer.Base对象的图层都可通过wrapX:false限制图层在x轴方向重复;另外也可通过设置view的extend属性。
wrapX限制
map = ol.Map({ […] ol.layer.Tile({ source: ol.source.TileWMS({ […] wrapX: false ol.layer.Vector({ source: ol.source.Vector({ […] wrapX: false
extent显示
view: ol.View({ […] extent: ol.proj.get('EPSG:3857').getExtent() }),
4.分辨率resolution运算
在web地图中,分辨率表示一个像素点表示的单位长度。下面通过一个计算中心点的例如来说明resolution的运算。
map.getView().on('propertychange', function (evt) { projExtent = .getProjection().getExtent(); (projExtent) { currentCenter = .getCenter(); currentResolution = .getResolution(); mapSize = map.getSize(); newExtent = [projExtent[0] + currentResolution * mapSize[0] / 2, projExtent[1] + currentResolution * mapSize[1] / 2, projExtent[2] - currentResolution * mapSize[0] / 2, projExtent[3] - currentResolution * mapSize[1] / 2 (!( ol.geom.Point(currentCenter).intersectsExtent(newExtent))) { currentCenter[0] = Math.min(Math.max(currentCenter[0], newExtent[0]), newExtent[2]); currentCenter[1] = Math.min(Math.max(currentCenter[1], newExtent[1]), newExtent[3.setCenter(currentCenter); } } });
说明:上面是view各个属性发生变化时触发的事件,view.getProjection()获取投影系对象proj,proj.getExtent()获取投影系的边界。view.getResolution()获取当前视图的分辨率,currentResolution*mapSize[0]表示整个视图在经度方向的总长度。geom.intersectsExtent判断geom是否在extent边界总。
5.使用unByKey注销事件
在很多ol.control.Control控件中我们会注册一些事件,但经常忽略注销,下面的方式是比较通用的注销事件方式:
ol.control.NavigationHistory.prototype.setMap = function (map) { ol.control.Control.prototype.setMap.call(, map); (map === ) { ol.Observable.unByKey(.get('eventId'.set('eventId', map.on('moveend', function (evt) { (.get('shouldSave' view = map.getView(); viewStatus = { center: view.getCenter(), resolution: view.getResolution(), rotation: view.getRotation() }; historyArray = .get('history' currIndex = .get('index'); historyArray.splice(currIndex + 1, historyArray.length - currIndex - 1 (historyArray.length === .get('maxSize')) { historyArray.splice(0, 1 { currIndex += 1; } historyArray.push(viewStatus); .set('index', currIndex); } .set('shouldSave', ); } }, )); } };
当控件和地图分离时,map会被设置为null,这个时候可调用ol.Observable.unByKey方法取消对事件的监听。
6.如何改变地图的投影系
首先要创建一个新的视图View,设置view的center、zoom、projection、extent属性。然后调用map的setView重新替换地图的视图。
view = _this.getMap().getView(); oldProj = view.getProjection(); newProj = ol.proj.get(.value); newView = ol.View({ center: ol.proj.transform(view.getCenter(), oldProj, newProj), zoom: view.getZoom(), projection: newProj, extent: newProj.getExtent() }); _this.getMap().setView(newView);
其次需要替换所有图层的投影系,遍历所有的图层,按照图层的类型采用不同的替换方式。
_this.getMap().getLayers().forEach(function (layer) { _this.changeLayerProjection(layer, oldProj, newProj); });
这里的changeLayerProjection是自定义的一个函数,用来处理当个图层的坐标系。
ol.control.Projection.prototype.changeLayerProjection = function (layer, oldProj, newProj) { (layer instanceof ol.layer.Group) { layer.getLayers().forEach(function (subLayer) { .changeLayerProjection(subLayer, oldProj, newProj); }); } (layer instanceof ol.layer.Tile) { tileLoadFunc = layer.getSource().getTileLoadFunction(); layer.getSource().setTileLoadFunction(tileLoadFunc); } (layer instanceof ol.layer.Vector) { features = layer.getSource().getFeatures(); ( i = 0; i < features.length; i += 1) { features[i].getGeometry().transform(oldProj, newProj); } } };
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,如果我们想导出地图图片,必须要设置这个参数:
ol.layer.Tile({ source: ol.source.TileWMS({ url: 'http://demo.opengeo.org/geoserver/wms', params: { layers: 'nlcd', format: 'image/png' }, wrapX: false, crossOrigin: 'anonymous' }), name: 'Land Cover'
9.WEBGL
https://webglfundamentals.org/
10.ol.Geolocation
获取地理位置对象,一个HTML5的帮助类,提供HTML5 Geolocation功能。跟踪终端设备的位置。例如:
geoloc = ol.Geolocation({ projection: map.getView().getProjection(), tracking: geoCaching = ol.layer.Vector({ source: ol.source.Vector() }); map.addLayer(geoCaching); geoloc.once('change:position', function (evt) { altitude = .getAltitude() || 100 myPos = .getPosition(); map.getView().setCenter(myPos); map.getView().setZoom(17 ( i = 0; i < 50; i += 1) { geoCaching.getSource().addFeature( ol.Feature({ geometry: ol.geom.Point([myPos[0] - 500 + Math.random() * 1000, myPos[1] - 500 + Math.random() * 1000, altitude - 150 + Math.random() * 300]), loot: 'Treasures of the Seven Seas' })); } });
说明:geoloc不需要添加到地图对象上,只需要设置投影系参数。如果想监听实时位置,可注册change: position事件。geoloc的getAltitude方法获取海拔高度。
Geolocation对象除projection、tracking参数外,还有一个trackingOptions参数,可设置如下:
geoloc = ol.Geolocation({ projection: map.getView().getProjection(), tracking: , trackingOptions: { enableHighAccuracy: , maximumAge: 2000
enableHighAccuracy允许高精准定位,maximumAge设置定位间隔时间,单位为毫秒。
11.Openlayers 3 shp插件使用
shp插件支持导入shp文件到openlayers上直接展示。代码如下:
layerTree.prototype.addVectorLayer = function (form) { file = form.file.files[0 currentProj = .map.getView().getProjection(); fr = FileReader(); sourceFormat = ol.format.GeoJSON(); source = ol.source.Vector(); fr.onload = function (evt) { vectorData = evt.target.result; dataProjection = form.projection.value || sourceFormat.readProjection(vectorData) || currentProj; shp(vectorData).then(function (geojson) { source.addFeatures(sourceFormat.readFeatures(geojson, { dataProjection: dataProjection, featureProjection: currentProj })); }); }; fr.readAsArrayBuffer(file); layer = ol.layer.Vector({ source: source, name: form.displayname.value }); .addBufferIcon(layer); .map.addLayer(layer); .messages.textContent = 'Vector layer added successfully.'return
12.ol.style.Icon
如何定位图标,参考下面代码:
style: ol.style.Style({ image: ol.style.Icon({ anchor: [0.5, 46], anchorXUnits: 'fraction', anchorYUnits: 'pixels','../../res/marker.png'
13.Cesium使用
openlayers团队封装了ol3cesium js库,ol3cesium包含了ol.js代码,所有我们在使用ol3cesium的时候不用再引用ol.js了。例如:
<script type="text/javascript" src="../../js/ol3-cesium- 1.10.0/Cesium/Cesium.js"></script> <script type="text/javascript" src="../../js/ol3-cesium- 1.10.0/ol3cesium.js"></script>
如果我们自定义了ol.js,我们可以在ol3cesium.js引用的后面再引用ol.js即可。例如:
<script type="text/javascript" src="../../js/ol3-cesium-1.10.0/ol3cesium.js"></script> <script type="text/javascript" src="../../ol/ol.js"></script>
Cesium场景的可视化非常智能,我们仅仅需要额外定义一个海拔瓦图源即可。创建代码如下:
setTimeout(function ol3d = olcs.OLCesium({map: _this.getMap()}); scene = ol3d.getCesiumScene(); scene.terrainProvider = Cesium.CesiumTerrainProvider({ url: 'http://assets.agi.com/stk-terrain/world' }); _this.set('cesium', ol3d); }, 0);
可调用cesium.setEnabled方法设置是否可用,setBlockCesiumRendering方法设置是否在后台渲染。 可通过这两个方法在2D和3D之间切换。
controlButton.addEventListener('click', function (evt) { cesium = _this.get('cesium' (cesium.getEnabled()) { cesium.setBlockCesiumRendering(); cesium.setEnabled(false { cesium.setBlockCesiumRendering(false); cesium.setEnabled(); } });
14.openlayers 编译环境
phtyon必须是2.*的版本,并且配置PYTHON环境变量
转载自:https://blog.csdn.net/weitaming1/article/details/87859692