# 六.失量图层

# 1.矢量层命中检测

查看代码详情
<template>
  <div>
    <div ref="map" class="map"></div>
    <div id="info">&nbsp;</div>
  </div>
</template>

<script>
export default {
  mounted() {
    let {
      format: { GeoJSON },
      Map,
      View,
      layer: { Vector: VectorLayer },
      source: { Vector: VectorSource },
      style: { Fill, Stroke, Style },
    } = ol;

    const style = new Style({
      fill: new Fill({
        color: "#eeeeee",
      }),
    });

    const vectorLayer = new VectorLayer({
      background: "#1a2b39",
      source: new VectorSource({
        url: "https://openlayers.org/data/vector/ecoregions.json",
        format: new GeoJSON(),
      }),
      style: function (feature) {
        const color = feature.get("COLOR_NNH") || "#eeeeee";
        style.getFill().setColor(color);
        return style;
      },
    });

    const map = new Map({
      layers: [vectorLayer],
      target: this.$refs.map,
      view: new View({
        center: [12579156, 3274244],
        zoom: 1,
      }),
    });

    const highlightStyle = new Style({
      stroke: new Stroke({
        color: "rgba(255, 255, 255, 0.7)",
        width: 2,
      }),
    });

    const featureOverlay = new VectorLayer({
      source: new VectorSource(),
      map: map,
      style: highlightStyle,
    });

    let highlight;
    const displayFeatureInfo = function (pixel) {
      vectorLayer.getFeatures(pixel).then(function (features) {
        const feature = features.length ? features[0] : undefined;
        const info = document.getElementById("info");
        if (features.length) {
          info.innerHTML =
            feature.get("ECO_NAME") + ": " + feature.get("NNH_NAME");
        } else {
          info.innerHTML = "&nbsp;";
        }

        if (feature !== highlight) {
          if (highlight) {
            featureOverlay.getSource().removeFeature(highlight);
          }
          if (feature) {
            featureOverlay.getSource().addFeature(feature);
          }
          highlight = feature;
        }
      });
    };

    map.on("pointermove", function (evt) {
      if (evt.dragging) {
        return;
      }
      const pixel = map.getEventPixel(evt.originalEvent);
      displayFeatureInfo(pixel);
    });

    map.on("click", function (evt) {
      displayFeatureInfo(evt.pixel);
    });
  },
};
</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

# 2.矢量瓦片信息

查看代码详情
<template>
  <div ref="map" class="map">
    <pre id="info" />
  </div>
</template>

<script>
export default {
  mounted() {
    let {
      format: { MVT },
      Map,
      View,
      layer: { Vector: VectorLayer, VectorTile: VectorTileLayer },
      source: { Vector: VectorSource, VectorTile: VectorTileSource },
    } = ol
    const map = new Map({
      target: this.$refs.map,
      view: new View({
        center: [12579156, 3274244],
        zoom: 2,
      }),
      layers: [
        new VectorTileLayer({
          source: new VectorTileSource({
            format: new MVT(),
            url: "https://basemaps.arcgis.com/v1/arcgis/rest/services/World_Basemap/VectorTileServer/tile/{z}/{y}/{x}.pbf",
          }),
        }),
      ],
    })

    map.on("pointermove", showInfo)

    const info = document.getElementById("info")
    function showInfo(event) {
      const features = map.getFeaturesAtPixel(event.pixel)
      if (features.length == 0) {
        info.innerText = ""
        info.style.opacity = 0
        return
      }
      const properties = features[0].getProperties()
      info.innerText = JSON.stringify(properties, null, 2)
      info.style.opacity = 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
44
45
46
47
48

# 3.矢量瓦片选择

查看代码详情
<template>
  <div>
    <div ref="map" class="map"></div>
    <form class="form-inline">
      <label for="type">Action type &nbsp;</label>
      <select id="type" class="form-control">
        <option value="singleselect" selected>Single Select</option>
        <option value="multiselect">Multi Select</option>
        <option value="singleselect-hover">Single Select on hover</option>
      </select>
    </form>
  </div>
</template>

<script>
export default {
  mounted() {
    let {
      format: { MVT },
      Map,
      View,
      layer: { Tile: TileLayer, VectorTile: VectorTileLayer },
      source: { VectorTile: VectorTileSource },
      style: { Fill, Stroke, Style },
    } = ol;

    // lookup for selection objects
    let selection = {};

    const country = new Style({
      stroke: new Stroke({
        color: "gray",
        width: 1,
      }),
      fill: new Fill({
        color: "rgba(20,20,20,0.9)",
      }),
    });
    const selectedCountry = new Style({
      stroke: new Stroke({
        color: "rgba(200,20,20,0.8)",
        width: 2,
      }),
      fill: new Fill({
        color: "rgba(200,20,20,0.4)",
      }),
    });

    const vtLayer = new VectorTileLayer({
      declutter: true,
      source: new VectorTileSource({
        maxZoom: 15,
        format: new MVT({
          idProperty: "iso_a3",
        }),
        url:
          "https://ahocevar.com/geoserver/gwc/service/tms/1.0.0/" +
          "ne:ne_10m_admin_0_countries@EPSG%3A900913@pbf/{z}/{x}/{-y}.pbf",
      }),
      style: country,
    });

    const map = new Map({
      layers: [vtLayer],
      target: this.$refs.map,
      view: new View({
        center: [12579156, 3274244],
        zoom: 2,
        multiWorld: true,
      }),
    });

    // Selection
    const selectionLayer = new VectorTileLayer({
      map: map,
      renderMode: "vector",
      source: vtLayer.getSource(),
      style: function (feature) {
        if (feature.getId() in selection) {
          return selectedCountry;
        }
      },
    });

    const selectElement = document.getElementById("type");

    map.on(["click", "pointermove"], function (event) {
      if (
        (selectElement.value === "singleselect-hover" &&
          event.type !== "pointermove") ||
        (selectElement.value !== "singleselect-hover" &&
          event.type === "pointermove")
      ) {
        return;
      }
      vtLayer.getFeatures(event.pixel).then(function (features) {
        if (!features.length) {
          selection = {};
          selectionLayer.changed();
          return;
        }
        const feature = features[0];
        if (!feature) {
          return;
        }
        const fid = feature.getId();

        if (selectElement.value.indexOf("singleselect") === 0) {
          selection = {};
        }
        // add selected feature to lookup
        selection[fid] = feature;

        selectionLayer.changed();
      });
    });
  },
};
</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
105
106
107
108
109
110
111
112
113
114
115
116
117
118

# 4.从 Mapbox 样式对象创建的矢量瓦片

查看代码详情
<template>
  <div ref="map" class="map"></div>
</template>

<script>
export default {
  mounted() {
    let {
      control: { FullScreen },
    } = ol
    // import olms from 'ol-mapbox-style';
    olms(
      "map",
      "https://api.maptiler.com/maps/topo/style.json?key=Get your own API key at https://www.maptiler.com/cloud/"
    ).then(function (map) {
      map.addControl(new FullScreen())
    })
  },
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 5.EPSG:4326 中的矢量瓦片

查看代码详情
<template>
  <div ref="map" class="map" style="background:none;"></div>
</template>

<script>
export default {
  mounted() {
    let {
      format: { MVT },
      View,
      source: { VectorTile: VectorTileSource },
      tilegrid: { TileGrid },
    } = ol
    const maxResolution = 360 / 512
    defaultResolutions.length = 14
    for (let i = 0; i < 14; ++i) {
      defaultResolutions[i] = maxResolution / Math.pow(2, i + 1)
    }

    olms(
      "map",
      "https://api.maptiler.com/maps/basic-4326/style.json?key=" +
        mapkeys.maptiler
    ).then(function (map) {
      // Custom tile grid for the EPSG:4326 projection
      const tileGrid = new TileGrid({
        extent: [-180, -90, 180, 90],
        tileSize: 512,
        resolutions: defaultResolutions,
      })

      const mapboxStyle = map.get("mapbox-style")

      // Replace the source with a EPSG:4326 projection source for each vector tile layer
      map.getLayers().forEach(function (layer) {
        const mapboxSource = layer.get("mapbox-source")
        if (
          mapboxSource &&
          mapboxStyle.sources[mapboxSource].type === "vector"
        ) {
          const source = layer.getSource()
          layer.setSource(
            new VectorTileSource({
              format: new MVT(),
              projection: "EPSG:4326",
              urls: source.getUrls(),
              tileGrid: tileGrid,
            })
          )
        }
      })

      // Configure the map with a view with EPSG:4326 projection
      map.setView(
        new View({
          projection: "EPSG:4326",
          zoom: mapboxStyle.zoom,
          center: mapboxStyle.center,
        })
      )
    })
  },
}
</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