# 二.Map 事件

# 1.鼠标触发事件

# 1.2 singleclick

鼠标单击地图触发的事件(鼠标若在 250ms 内连续单击地图,则不会触发该事件)

查看代码详情

<template>
  <WebOLChina
    type="china"
    @singleclick="singleclick"
    @oLMounted="oLMounted"
  ></WebOLChina>
</template>
  
<script>
export default {
  data() {
    return {
      selected: [],
      style: "",
    };
  },
  methods: {
    oLMounted({ has, style: { Fill, Stroke, Style } }) {
      var canvas = document.createElement("canvas");
      var pixelRatio = has.DEVICE_PIXEL_RATIO;
      var context = canvas.getContext("2d");
      var grad = context.createLinearGradient(0, 0, 512 * pixelRatio, 0);
      grad.addColorStop(0, "rgba(66,99,232,1)");
      grad.addColorStop(1, "rgba(55,183,249,1)");
      this.style = new Style({
        fill: new Fill({
          color: grad,
        }),
        stroke: new Stroke({
          color: grad,
          width: 2,
        }),
      });
    },
    singleclick(f) {
      const selIndex = this.selected.indexOf(f);
      if (selIndex < 0) {
        this.selected.push(f);
        f.setStyle(this.style);
      } else {
        this.selected.splice(selIndex, 1);
        f.setStyle(undefined);
      }
    },
  },
};
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

# 1.3 dbclick

鼠标双击地图触发的事件(鼠标在 250ms 内单击两次地图)

# 1.4 pointermove

on 方法 作用 配置
click 鼠标单击地图触发的事件(鼠标单击多少次地图,该事件就触发多少次)
pointermove 鼠标指针在地图上移动触发的事件
getView 获取地图视图
查看代码详情
<template>
  <div>
    <div ref="map" class="map">
      <div ref="popup"></div>
    </div>
    <div ref="info"></div>
  </div>
</template>

<script>
export default {
  mounted() {
    let {
      format: { GeoJSON },
      geom: { Point },
      Feature,
      Map,
      Overlay,
      View,
      layer: { Tile: TileLayer, Vector: VectorLayer },
      source: { Vector: VectorSource },
      style: { Circle, Fill, Style },
      proj: { useGeographic, fromLonLat },
    } = ol;
    const place = [108.522097, 37.272848];
    const point = new Point(place);
    const map = new Map({
      target: this.$refs.map,
      view: new View({
        center: fromLonLat([108.522097, 37.272848]),
        zoom: 4,
        multiWorld: false,
      }),
      layers: [
        new VectorLayer({
          source: new VectorSource({
            url: "./data/100000_full.json",
            format: new GeoJSON(),
          }),
        }),
        new VectorLayer({
          source: new VectorSource({
            features: [new Feature(point)],
          }),
          style: new Style({
            image: new Circle({
              radius: 9,
              fill: new Fill({ color: "red" }),
            }),
          }),
        }),
      ],
    });
    const element = this.$refs.popup;
    const popup = new Overlay({
      element: element,
      positioning: "bottom-center",
      stopEvent: false,
      offset: [0, -10],
    });
    map.addOverlay(popup);
    function formatCoordinate(coordinate) {
      return `
        <table>
          <tbody>
            <tr><th>lon</th><td>${coordinate[0].toFixed(2)}</td></tr>
            <tr><th>lat</th><td>${coordinate[1].toFixed(2)}</td></tr>
          </tbody>
        </table>
      `;
    }
    const info = this.$refs.info;
    map.on("moveend", function () {
      const view = map.getView();
      const center = view.getCenter();
      info.innerHTML = formatCoordinate(center);
    });
    map.on("click", function (event) {
      const feature = map.getFeaturesAtPixel(event.pixel)[0];
      if (feature) {
        const coordinate = feature.getGeometry().getCoordinates();
        popup.setPosition([
          coordinate[0] + Math.round(event.coordinate[0] / 360) * 360,
          coordinate[1],
        ]);
        info.innerHTML = formatCoordinate(coordinate);
      }
    });
    map.on("pointermove", function (event) {
      if (map.hasFeatureAtPixel(event.pixel)) {
        map.getViewport().style.cursor = "pointer";
      } else {
        map.getViewport().style.cursor = "inherit";
      }
    });
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

# 1.5 pointerdrag

鼠标按下拖动地图触发的事件

# 2.地图移动事件

# 2.1 movestart

地图开始移动时触发的事件(包括平移和缩放)

查看代码详情
<template>
  <WebOLChina type="china" @movestart="movestart">
    <label>left: <input v-model="left" type="text" /></label>
    <label>right: <input v-model="right" type="text" /></label>
    <label>bottom: <input v-model="bottom" type="text" /></label>
    <label>top: <input v-model="top" type="text" /></label>
  </WebOLChina>
</template>
  
<script>
export default {
  data() {
    return {
      style: "",
      left: "",
      right: "",
      bottom: "",
      top: "",
    };
  },
  methods: {
    movestart({
      evt,
      ol: {
        extent: { getBottomLeft, getTopRight },
        proj: { toLonLat },
      },
    }) {
      function wrapLon(value) {
        const worlds = Math.floor((value + 180) / 360);
        return value * worlds * 360;
      }
      const map = evt.map;
      const extent = map.getView().calculateExtent(map.getSize());
      const bottomLeft = toLonLat(getBottomLeft(extent));
      const topRight = toLonLat(getTopRight(extent));
      this.left = wrapLon(bottomLeft[0]);
      this.bottom = bottomLeft[1];
      this.right = wrapLon(topRight[0]);
      this.top = topRight[1];
    },
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 2.2 moveend

地图结束移动时触发的事件(包括平移和缩放)

查看代码详情
<template>
  <WebOLChina type="china" @moveend="moveend">
    <label>left: <input v-model="left" type="text" /></label>
    <label>right: <input v-model="right" type="text" /></label>
    <label>bottom: <input v-model="bottom" type="text" /></label>
    <label>top: <input v-model="top" type="text" /></label>
  </WebOLChina>
</template>
  
<script>
export default {
  data() {
    return {
      style: "",
      left: "",
      right: "",
      bottom: "",
      top: "",
    };
  },
  methods: {
    moveend({
      evt,
      ol: {
        extent: { getBottomLeft, getTopRight },
        proj: { toLonLat },
      },
    }) {
      function wrapLon(value) {
        const worlds = Math.floor((value + 180) / 360);
        return value * worlds * 360;
      }
      const map = evt.map;
      const extent = map.getView().calculateExtent(map.getSize());
      const bottomLeft = toLonLat(getBottomLeft(extent));
      const topRight = toLonLat(getTopRight(extent));
      this.left = wrapLon(bottomLeft[0]);
      this.bottom = bottomLeft[1];
      this.right = wrapLon(topRight[0]);
      this.top = topRight[1];
    },
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 3.图层渲染事件

# 3.1 precompose

一个图层渲染前触发的事件

# 3.2 postcompose

一个图层渲染时触发的事件

  • 天地图+加涟漪效果案例
查看代码详情
<template>
  <div ref="map" class="map"></div>
</template>

<script>
export default {
  mounted() {
    let {
      Map,
      View,
      layer: { Tile: TileLayer },
      source: { XYZ },
      proj: { fromLonLat },
    } = ol;
    const key = "get_your_own_D6rA4zTHduk6KOKTXzGB";
    const attributions = "";
    const map = new Map({
      layers: [
        new TileLayer({
          source: new XYZ({
            attributions: attributions,
            url: "http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=5a257cd2df1b3311723bd77b0de14baf",
            tileSize: 512,
          }),
        }),
      ],
      target: this.$refs.map,
      view: new View({
        center: fromLonLat([112.91, 28.21], "EPSG:4326", "EPSG:3857"),
        zoom: 5,
      }),
    });
    map.on("loadstart", function () {
      map.getTargetElement().classList.add("spinner");
    });
    map.on("loadend", function () {
      map.getTargetElement().classList.remove("spinner");
    });
    var source = new ol.source.Vector({
      wrapX: false,
    });
    map.addLayer(
      new ol.layer.Vector({
        source: source,
      })
    );

    function addRandomFeature() {
      var geom = new ol.geom.Point(ol.proj.fromLonLat([112.91, 28.21]));
      var feature = new ol.Feature(geom);
      source.addFeature(feature);
    }

    var duration = 1000;

    function flash(feature) {
      var start = new Date().getTime();
      //进行地图水波渲染
      var listenerKey = map.on("postcompose", animate);

      function animate(event) {
        //获取几何图形
        var vectorContext = event.vectorContext;
        //获取当前渲染帧状态
        var frameState = event.frameState;
        //添加一个OpenLayers.Geometry几何对象
        var flashGeom = feature.getGeometry().clone();
        //渲染帧状已占时间
        var elapsed = frameState.time - start;
        //已占比率
        var elapsedRatio = elapsed / duration;
        // radius半径为5结束为30
        var radius = ol.easing.easeOut(elapsedRatio) * 25 + 5;
        //不透渐变消失
        var opacity = ol.easing.easeOut(1 - elapsedRatio);
        //Circle样式
        var style = new ol.style.Style({
          image: new ol.style.Circle({
            radius: radius,
            stroke: new ol.style.Stroke({
              color: "rgba(255, 0, 0, " + opacity + ")",
              width: 1 + opacity,
            }),
          }),
        });
        //给几何图形添加样式
        vectorContext.setStyle(style);
        //将几何体渲染到画布中
        vectorContext.drawGeometry(flashGeom);
        if (elapsed > duration) {
          start = frameState.time;
        }
        //请求地图渲染(在下一个动画帧处)
        map.render();
      }
    }
    //数据源添加图层
    source.on("addfeature", function (e) {
      flash(e.feature);
    });

    addRandomFeature();
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

# 3.3 postrender

一个图层渲染完成后触发的事件

# 3.4 rendercomplete

所有的渲染都完成后触发的事件(所有的图层、瓦片都完成了在当前视图的加载)

# 4.change 事件

# 4.1 change

地图出现改变时触发的事件(改变可以是任何地图事件)

# 4.2 change

layerGroup 地图的图层发生改变时触发的事件(例如图层的增加、删除)

# 4.3 change

size 可供地图显示的窗口大小发生改变时触发的事件(例如将浏览器窗口缩小化)

# 4.4 change

target 地图所在 div 块发生改变时触发的事件(例如切换地图的显示位置)

# 4.5 change

view 地图视图发生改变时触发的事件(例如视图中心的变化)

# 5.其它事件

# 5.1 propertychange

地图属性更改时触发的事件

# 5.2 error

地图运行发生错误时触发事件