项目需求
项目中需要鼠标在栅格地图上移动时显示每个像元的DN值(即像元像素值)
项目构想
由于栅格地图在geoserver发布我发现能通过坐标信息提供接口获取red、green、blue三通道颜色值。但没有发现获取DN值。所以我思考通过矢量数据获取属性表方面入手。思路如下
1、将栅格数据借助arcmap工具转为点矢量,为之增加DN值及xy坐标信息。
2、在geoserver上发布栅格及矢量服务。栅格作为显示,而矢量数据设置图层透明度很低,通过鼠标移动获取属性信息,添加label显示。
3、由于鼠标移动服务请求较大,所以我给他添加边界界定,超出设置区域,则不请求数据。
项目实现
- 数据准备及处理
在arcmap中执行步骤如下
复制栅格->栅格转点->添加X\Y字段->计算几何->导出数据即可
1、将栅格数据在arcmap中打开->复制栅格
2、执行栅格转点
3、打开矢量数据属性表->添加XY字段
4、执行计算几何导出数据
5、导出GeoJson河流边界文件
打开在线转geojson的网站,导入数据转为geojson即可。
6、数据发布
打开geoserver,分别发布栅格矢量的数据存储方式
- 代码实现
1、加载栅格切片
import WMTS from "ol/source/WMTS";
import TileLayer from "ol/layer/Tile";
loadbottommap(){
var gridsetName = 'EPSG:4326';
var gridNames = ['EPSG:4326:0', 'EPSG:4326:1', 'EPSG:4326:2', 'EPSG:4326:3', 'EPSG:4326:4', 'EPSG:4326:5', 'EPSG:4326:6', 'EPSG:4326:7', 'EPSG:4326:8', 'EPSG:4326:9', 'EPSG:4326:10', 'EPSG:4326:11', 'EPSG:4326:12', 'EPSG:4326:13', 'EPSG:4326:14', 'EPSG:4326:15', 'EPSG:4326:16', 'EPSG:4326:17', 'EPSG:4326:18', 'EPSG:4326:19', 'EPSG:4326:20', 'EPSG:4326:21'];
var format= 'image/jpeg';
var style = '';
var layerNames="waterEutrophication:2016TP"
var base_url="http://localhost:8080/geoserver/gwc/service/wmts"
var resolutions = [0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625, 0.010986328125, 0.0054931640625, 0.00274658203125, 0.001373291015625, 6.866455078125E-4, 3.4332275390625E-4, 1.71661376953125E-4, 8.58306884765625E-5, 4.291534423828125E-5, 2.1457672119140625E-5, 1.0728836059570312E-5, 5.364418029785156E-6, 2.682209014892578E-6, 1.341104507446289E-6, 6.705522537231445E-7, 3.3527612686157227E-7];
var baseParams = ['VERSION','LAYER','STYLE','TILEMATRIX','TILEMATRIXSET','SERVICE','FORMAT'];
var params = {
'VERSION': '1.0.0',
'LAYER': layerNames,//layerName,
'STYLE': style,
'TILEMATRIX': gridNames,
'TILEMATRIXSET': gridsetName,
'SERVICE': 'WMTS',
'FORMAT': format
};
function constructSource(){
var url =base_url +'?'
for (var param in params) {
if (baseParams.indexOf(param.toUpperCase()) < 0) {
url = url + param + '=' + params[param] + '&';
}
}
url = url.slice(0, -1);
var source = new WMTS({
url: url,
layer: params['LAYER'],
matrixSet: params['TILEMATRIXSET'],
format: params['FORMAT'],
projection: projection,
tileGrid: new WMTSTileGrid({
tileSize: [256,256],
extent: [-180.0,-90.0,180.0,90.0],
origin: [-180.0, 90.0],
resolutions: resolutions,
matrixIds: gridNames
}),
style: params['STYLE'],
wrapX: true
});
return source;
}
var layer2016 = new TileLayer({
source: constructSource()
});
return layer2016
}
2、加载矢量数据
import ImageWMS from 'ol/source/ImageWMS'
import Image from 'ol/layer/Image'
loadvector(){
var format = 'image/png';
var bounds = [375599.8540000012, 3386915.9619999994,
386213.8540000003, 3412573.9619999994];
var source=new ImageWMS({
ratio: 1,
url: 'http://localhost:8080/geoserver/waterEutrophication/wms',
params: {'FORMAT': format,
'VERSION': '1.1.1',
"LAYERS": 'waterEutrophication:2018TLITPpoint',//图层名
"exceptions": 'application/vnd.ogc.se_inimage',
}
})
layerclassindex = new Image({
opacity:0.1,
source: source,
});
map.addLayer(layerclassindex)
this.addEventMouseMove(layerclassindex,map.getView())//给图层添加鼠标移动事件
}
3、鼠标移动事件
addEventMouseMove(layer,view){//接受图层和当前视图两个参数
event= map.on('pointermove', (evt)=> {
//判断点的位置
if(this.removeaker(evt.coordinate)==1) {//调用了一个判断当前点击位置是否在区域内的方法,若在则请求服务反之拒绝。。为了减少前端压力,减少服务器压力
var resolution = view.getResolution();
var source = layer.getSource();
var url = source.getGetFeatureInfoUrl(
evt.coordinate, resolution, view.getProjection(),
{'INFO_FORMAT': 'application/json', 'FEATURE_COUNT': 50});
if (url) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = () => {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
//太多了还是切片好
if (JSON.parse(xmlhttp.responseText).features.length !== 0) {
this.addmaker(JSON.parse(xmlhttp.responseText).features[0].properties.grid_code, evt.coordinate)//调用添加点要素的方法。传入要素属性中的dn值
}
}
else {
}
}
}
xmlhttp.open('GET', url, true);
xmlhttp.send();
}
}
else{//若在区域外则移除要素
//否则移除要素
if(markVector_Res.getFeatures().length !==0){
markVector_Res.removeFeature(singleiconFeature)
map.removeLayer(singleLayer_Mark);
}
}
})
}
4、添加点要素
import VectorSource1 from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
markVector_Res = new VectorSource1({
wrapX: false,
});
singleLayer_Mark = new VectorLayer({
source: markVector_Res
});
addmaker(title,coordinate){
if(markVector_Res.getFeatures().length !==0){//移除前一个要素
markVector_Res.removeFeature(singleiconFeature)
map.removeLayer(singleLayer_Mark);
}
singleiconFeature = new Feature({
geometry: new Point(coordinate)
});
var iconStyle = new Style({
text:new Text({
text:`${title}`,
font:'bold 24px serif',
offsetY:-20,//竖直偏移
// fill:`${style_highlighted}`
// stroke:
})
});
singleiconFeature.setStyle(iconStyle);
markVector_Res.addFeature(singleiconFeature);
map.addLayer(singleLayer_Mark);
}
5、边界限制
import bounderyJson from '../../assets/FeaturesData/clip_water_16.GeoJson'//导出矢量数据的geojson文件
let markVector_Res1 = new VectorSource1({
wrapX: false,
format: new GeoJSON(),
});
markVector_Res1.addFeatures(
markVector_Res1.getFormat().readFeatures(bounderyJson),{
dataProjection: 'EPSG:4326', // 设定JSON数据使用的坐标系
featureProjection: 'EPSG:4326' // 设定当前地图使用的feature的坐标系
});//读取geojson文件
removeaker(coordinate){
//遍历要素,查找几何有无该点
for (let i = 0; i < markVector_Res1.getFeatures().length; i++) {
if (markVector_Res1.getFeatures()[i].getGeometry().intersectsCoordinate(coordinate)) {
return 1
}
else {
return 0
}
}
6、事件移除
import {unByKey} from 'ol/Observable';
removeEvent(){
unByKey(event)//移除鼠标移动事件
}
- 效果展示