在Openlayers地图上根据地图分幅规则,绘制分幅网格,需要注意的有几点:
1确认什么比例尺时展示什么1:100万、1:50万...比例尺的分幅
2根据地图当前视窗位置,动态绘制注记和网络,因为全部绘制的话,网格和注意太多,严重影像运行速度
3绘制经线和纬线,不绘制网格,网格严重内存更多
代码如下:
addSheetNumber(number){
getLayerByName(this.$map2d, "drawLayer")
.getSource()
.clear();
var d1=6;
var d2=4;
switch (number) {
case 1000000:
d1=6;
d2=4;
break;
case 500000:
d1=3;
d2=2;
break;
case 250000:
d1=1.5;
d2=1;
break;
case 100000:
d1=0.5;
d2=0.3333;
break;
default:
break;
}
for (let index = 0; index < 88/d2+1; index++) {
if(index==0){this.outLine(index*d2,-180,index*d2,180)}else{
this.outLine(index*d2,-180,index*d2,180);
this.outLine(-index*d2,-180,-index*d2,180);
}
}
//画经线
for (let i = 0; i < 360/d1; i++) {
this.outLine(-88,-180+i*d1,88,-180+i*d1);
}
},
toggleSheetNumber(){
const that=this;
var view=this.$map2d.getView();
if(this.sheetType!=0){
//第二次点击清除网络
view.un('change:resolution',that.changeListener);
view.un('change',that.resetNumberText);
getLayerByName(this.$map2d, "drawLayer")
.getSource()
.clear();
getLayerByName(this.$map2d, "textLayer").getSource()
.clear();
this.sheetType=0;
return;
}
view.on('change:resolution',that.changeListener);
view.on('change',that.resetNumberText);
this.changeListener();
},
changeListener(e){
var view=this.$map2d.getView();
var ruler=view.getResolution();
if(ruler>0.02197&&this.sheetType!=1000000){
this.sheetType=1000000;
this.addSheetNumber(1000000);
}
else if(ruler<0.02197&&ruler>0.00549&&this.sheetType!=500000){
this.sheetType=500000;
this.addSheetNumber(500000);
}else if(ruler<0.00549&&ruler>0.00297&&this.sheetType!=250000){
this.sheetType=250000;
this.addSheetNumber(250000);
}else if(ruler<0.00297&&this.sheetType!=100000){
this.sheetType=100000;
this.addSheetNumber(100000);
}
},
resetNumberText(e){
getLayerByName(this.$map2d, "textLayer").getSource()
.clear();
let view=e.target;
var extent=view.calculateExtent();
if(extent[0]<-180){extent[0]=-180}
if(extent[1]<-88){extent[1]=-88}
if(extent[2]>180){extent[2]=180}
if(extent[3]>88){extent[3]=88}
let ruler=view.getResolution();
var d1=6;
var d2=4;
switch (this.sheetType) {
case 1000000:
d1=6;
d2=4;
break;
case 500000:
d1=3;
d2=2;
break;
case 250000:
d1=1.5;
d2=1;
break;
case 100000:
d1=0.5;
d2=0.3333;
break;
default:
break;
}
var i1=Math.floor((extent[0]+180)/d1);
if((extent[0]-i1*d1-d1/2)>0){i1++}
var i2=Math.floor((extent[2]+180)/d1);
if((extent[2]-i2*d1-d1/2)>0){i2++}
var j1=Math.floor((extent[1]+88)/d2);
if((extent[1]-j1*d2-d2/2)>0){j1++}
var j2=Math.floor((extent[3]+88)/d2);
if((extent[3]-j2*d2-d2/2)>0){j2++}
for (let index = i1; index < i2; index++) {
this.outLabel(index*d1-180+d1/2,extent[3],String(index+1))
}
for (let h = j1; h < j2; h++) {
var text=h;
if(h<88/d2){
text="S"+Math.round(88/d2-h)
}
else{text="N"+Math.round(h-88/d2+1)}
this.outLabel(extent[0],h*d2-88+d2/2,text)
}
},
outLabel(lon,lat,text){
var geom = new ol.geom.Point([lon, lat]);
var feature = new ol.Feature({
geometry: geom,
labelPoint: geom,
name: text
});
feature.setStyle(this.createLabelStyle(feature));
var vectorLayer = getLayerByName(this.$map2d, "textLayer");
var vectorSource = vectorLayer.getSource();
vectorSource.addFeature(feature);
},
//生成样式
createLineStyle(feature) {
return new ol.style.Style({
stroke: new ol.style.Stroke({
color: "red", //边框颜色
width: 2 // 边框宽度
})
});
},
createLabelStyle(feature) {
return new ol.style.Style({
text: new ol.style.Text({
textAlign: "center",
textBaseLine: "start",
offsetX:10,
offsetY:5,
font: "bold 10px 微软雅黑",
text: feature.get("name"),
fill: new ol.style.Fill({
color: "red"
})
})
});
},
最后结果如下图所示:
缺点:无法在每一个网格里添加文字