最近来实习的地方,然后具体是好是坏也不知道,和自己想象的不一样,不知道是去是留,关于GIS开发的问题感觉不再是多大难度的问题,自己也也可以快速对api适应。平时遇到一些OL3的琐碎知识点进行整理。
一、关于加载天地图的函数封装
代码封装:
function getTdtLayer(lyr) {
var url = "http://t{0-7}.tianditu.com/DataServer?T=" + lyr + "&tk='你申请的tk值'&X={x}&Y={y}&L={z}";
var layer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: url
})
});
return layer;
}
调用示例:
var vec_c = getTdtLayer("vec_w");
var cva_c = getTdtLayer("cva_w");
参数说明:
二、关于GeoJson数据的读取
代码示例:
$.get("data/province.geojson",null,function(result){
var features = (new ol.format.GeoJSON()).readFeatures(result);
var vectorSource = new ol.source.Vector();
vectorSource.addFeatures(features);
三、关于坐标系的介绍
1、'EPSG:4326'-经纬度坐标-WGS84
2、'EPSG:3857'- xy坐标-web墨卡托
3、ol3默认的坐标系为3857,即在创建ol.map的时候,若不指定projection,则默认为EPSG:3857
4、代码示例:
var m_center=[116.35,39.9];//地图中心点-经纬度坐标
//经纬度转至xy
m_center = ol.proj.transform(m_center,'EPSG:4326', 'EPSG:3857' );
//反过来
var m_center=[12914838.35,4814529.9];//地图中心点-xy坐标
//经纬度转至经纬度
m_center = ol.proj.transform(m_center, 'EPSG:3857' ,'EPSG:4326');
四、关于ol.Extend的代码表达式的含义
ol.Extent的表达式 [minx, miny, maxx, maxy].
五、forEachFeatureAtPixel方法
该方法主要和一些事件一块用,例如Click,SingleClick等,有回调函数,回调函数有两个参数feature,layer,这里面有个hitTolerance(容差)参数,可以根据不同的值获取一定像素范围的feature.
使用案例需求:鼠标悬浮到Vector改变鼠标样式
代码示例:
map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
var pixel = map.getEventPixel(evt.originalEvent);
var hit = map.forEachFeatureAtPixel(pixel, function() {
return true;
});
map.getTargetElement().style.cursor = hit ? 'pointer' : '';
})
forEachLayerAtPixel同样效果
map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
var pixel = map.getEventPixel(evt.originalEvent);
var hit = map.forEachLayerAtPixel(pixel, function() {
return true;
});
map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
getFeaturesAtPixel也可以做到这样的效果,其实用getFeaturesAtPixel我觉得更好点
容差参数示例:
map.on('singleclick', function(e) {
var hit = false;
map.forEachFeatureAtPixel(e.pixel, function() {
hit = true;
}, {
hitTolerance: hitTolerance
});
if (hit) {
style.getStroke().setColor('green');
statusElement.innerHTML = ' A feature got hit!';
} else {
style.getStroke().setColor('black');
statusElement.innerHTML = ' No feature got hit.';
}
feature.changed();
});
六、关于判断一个是否位于一个矩形、圆形、直线上解决方法
ol.geom.Geometry类,该类是一一些,点,线,圆的=基类,该类中有一个intersectsCoordinate方法,判断是否与几何图形相交或者是否位于那个图形范围之内。
七、关于在控件的添加
1、代码示例:
controls: ol.control.defaults().extend([
new ol.control.FullScreen()
]),
至于为什么这么添加的原因,默认的有一些控件,我们是在默认控件基础上进行添加,不是要覆盖原来的控件。
八、OL4.x和OL3.X改变鼠标样式
代码示例:
map.getTargetElement().style.cursor='pointer';
九、修改对象的封装
//定义修改几何图形功能控件
var Modify = {
init: function () {
//初始化一个交互选择控件,并添加到地图容器中
this.select = new ol.interaction.Select();
map.addInteraction(this.select);
//初始化一个交互编辑控件,并添加到地图容器中
this.modify = new ol.interaction.Modify({
features: this.select.getFeatures()//选中的要素
});
map.addInteraction(this.modify);
//设置几何图形变更的处理
this.setEvents();
},
setEvents: function () {
var selectedFeatures = this.select.getFeatures(); //选中的要素
//添加选中要素变更事件
this.select.on('change:active', function () {
selectedFeatures.forEach(selectedFeatures.remove, selectedFeatures);
});
},
setActive: function (active) {
this.select.setActive(active);//激活选择要素控件
this.modify.setActive(active);//激活修改要素控件
}
};
Modify.init(); //初始化几何图形修改控件
Modify.setActive(true); //激活几何图形修改控件;
十、ol实现在线编辑的一个思路
1、geoserver+postgis以wfs服务中Transaction(编辑要素)来进行在线编辑。
2、postgis 通过ajax方式进行异步提交数据到数据库采用draw控件或者modify控件修改geometry将gemetry借助ol.format.WKT的writeGeometry(geometry, opt_options)方法转换成WKT,最后提交到数据库。
十一、地图打印
js文件引入:
HTML代码:
js代码:
//地图打印
$("#bPrint").click(function () {
map.once('postcompose', function (event) {
var canvas = event.context.canvas;
if (navigator.msSaveBlob) {
navigator.msSaveBlob(canvas.msToBlob(), 'map.png');
} else {
canvas.toBlob(function (blob) {
saveAs(blob, 'map.png');
});
}
});
map.renderSync();
});
十二、新手平时易踩的坑
作为map容器,有几个参数必须设置,
在View中必须设置zoom,projection不设置默认EPSG:3857,还有div需要设置width和height
十三、关于投影坐标系
注意 OpenLayers 的 new ol.source.MapQuest({layer: 'sat'}) 这个图层的默认投影坐标系是 'EPSG:3857', 而一般我们用的比较广泛的是 'EPSG:4326',也就是传说中的 WGS84坐标系。
所以当使用 map.setView(view)和overlay.setPosition(coordinate)时候,要注意将我们使用的坐标转换到相应的参考系之下: ol.proj.transform(coordinates, 'EPSG:4326', 'EPSG:3857');。
投影方式也多种多样,其中有一种投影叫墨卡托投影(Mercator Projection),广泛使用于网页地图,对于OpenLayers 3的开发者而言,尤其重要,详情参见墨卡托投影。
extent: [102, 29, 104, 31]这里的参数数字表达的含义是经纬度
十四、条件样式
条件样式是将样式配置为一个回调函数,其参数包含要素本身和分辨率,可以根据要素本身的属性和地图的分辨率,显示动态的样式,形式如 style: function(feature, resolution) {}。
例如,以下代码段配置当分辨率小于 5000 时候,在要素上显示一个标签,标识要素名称:
style: function(feature, resolution) {
style.getText().setText(resolution < 5000 ? feature.get('name') : '');
return styles;
}
十四、3857坐标下计算每一个层级的分辨率
ol.tilegrid.resolutionsFromExtent = function(extent, opt_maxZoom, opt_tileSize) {
var maxZoom = opt_maxZoom !== undefined ?
opt_maxZoom : ol.DEFAULT_MAX_ZOOM;
var height = ol.extent.getHeight(extent);
var width = ol.extent.getWidth(extent);
var tileSize = ol.size.toSize(opt_tileSize !== undefined ?
opt_tileSize : ol.DEFAULT_TILE_SIZE);
var maxResolution = Math.max(
width / tileSize[0], height / tileSize[1]);
var length = maxZoom + 1;
var resolutions = new Array(length);
for (var z = 0; z < length; ++z) {
resolutions[z] = maxResolution / Math.pow(2, z);
}
return resolutions;
};
十五、比例尺分类
小比例尺地形图:1:1000000、1:500000、1:200000
中比例尺地形图:1:100000、1:50000、1:25000
大比例尺地形图:1:10000、1:5000、1:2000、1:1000、1:500
十六、获取当前map的Extent
function getCurrentExtent(map) {
let view = map.getView();
let size = map.getSize();
let extent = view.calculateExtent(size);
return extent;
}
十七、判断坐标是否在当前视窗内
function checkCoordinateIsOrNotInCurrentExtent(map, coordinate) {
let view = map.getView();
let size = map.getSize();
let extent = view.calculateExtent(size);//上述三行代码可换成getCurrentExtent
return extent.containsCoordinate(coordinate);
}