效果展示

HTML结构
<div id="Clipping" class="showPage-demo">
<div class="area_box">
<el-radio-group v-model="mapShow" @change="mapChange">
<el-radio label="gaodeMap01">中国</el-radio>
<el-radio label="gaodeMap02">四川省</el-radio>
</el-radio-group>
</div>
</div>
获取数据生成GeoJSON 和 地图TileLayer
const gaodeMap01 = new TileLayer({
source: new XYZ({
url: "http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
}),
name: "gaodeMap01",
visible: true,
});
const gaodeMap02 = new TileLayer({
source: new XYZ({
url: "http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
}),
name: "gaodeMap02",
visible: false,
});
const zgGeom = new GeoJSON({
geometryName: "zg",
}).readFeatures(zg);
const glGeom = new GeoJSON({
geometryName: "sc",
}).readFeatures(sc);
初始化地图
data() {
return {
map: null,
mapShow: "gaodeMap01",
view: new View({
center: centerPoint,
zoom: 5,
minZoom: 1,
maxZoom: 25,
projection: "EPSG:4326",
rotation: 0,
}),
};
},
mounted() {
this.initMap();
},
methods:{
initMap() {
let { view } = this;
const map = new Map({
layers: [gaodeMap01, gaodeMap02, centerMark],
target: "Clipping",
view,
});
this.ininClip01(map);
this.ininClip02(map);
this.map = map;
}
}
裁剪地图
methods:{
ininClip02(map) {
let _this = this;
gaodeMap02.on("prerender", (ev) => {
let coords = [];
glGeom.forEach((highlight) => {
coords = [...coords, ...highlight.getGeometry().getCoordinates()];
});
_this.clip(ev, glGeom[0].getGeometry().getType(), map, coords);
});
gaodeMap02.on("postrender", function (event) {
var ctx = event.context;
ctx.restore();
});
},
ininClip01(map) {
let _this = this;
gaodeMap01.on("prerender", (ev) => {
let coords = [];
zgGeom.forEach((highlight) => {
coords = [...coords, ...highlight.getGeometry().getCoordinates()];
});
_this.clip(ev, zgGeom[0].getGeometry().getType(), map, coords);
});
gaodeMap01.on("postrender", function (event) {
var ctx = event.context;
ctx.restore();
});
},
clip(evt, type, map, coords) {
var canvas = evt.context;
canvas.save();
var frameState = evt.frameState;
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
this.center = viewState.center;
var resolution = viewState.resolution;
this.rotation = viewState.rotation;
var size = frameState.size;
var size1 = map.getSize();
this.offsetX = Math.round((pixelRatio * size[0]) / 2);
this.offsetY = Math.round((pixelRatio * size[1]) / 2);
this.pixelScale = pixelRatio / resolution;
canvas.beginPath();
if (type == "MultiPolygon") {
for (var i = 0; i < coords.length; i++) {
this.createClip(coords[i][0], canvas);
}
} else if (type == "Polygon") {
this.createClip(coords[0], canvas);
}
canvas.clip();
},
createClip(coords, canvas) {
let { offsetX, offsetY, pixelScale, center, rotation } = this;
for (var i = 0, cout = coords.length; i < cout; i++) {
var xLen = Math.round((coords[i][0] - center[0]) * pixelScale);
var yLen = Math.round((center[1] - coords[i][1]) * pixelScale);
var x = offsetX;
var y = offsetY;
if (rotation) {
x = xLen * Math.cos(rotation) - yLen * Math.sin(rotation) + offsetX;
y = xLen * Math.sin(rotation) + yLen * Math.cos(rotation) + offsetY;
} else {
x = xLen + offsetX;
y = yLen + offsetY;
}
if (i == 0) {
canvas.moveTo(x, y);
} else {
canvas.lineTo(x, y);
}
}
canvas.closePath();
},
}
切换GeoJSON数据
methods: {
mapChange(val) {
let { map, view } = this,
layers = map.getLayers().getArray();
layers.forEach((layer) => {
if (!layer.get("name")) {
return;
}
if (layer.get("name") === val) {
layer.setVisible(true);
} else {
layer.setVisible(false);
}
});
}
}