根据不同的GeoJSON 图形 裁剪地图 展示需要的地图区域

418 阅读1分钟

效果展示

clipMap.gif

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 coords = highlight.getGeometry().getCoordinates();
      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);
        }
      });
    }
   }