四十、openlayers官网示例External map解析——打开一个外部小窗口展示地图

官网demo地址:

External map 

这篇展示了外部窗口打开地图视图。

首先先初始化地图。

创建了一个UnusableMask类继承Control用来做主页面地图放进小窗口后的遮罩层,设置了自定义属性hidden来控制遮罩层的显隐。

initMap() {
      class UnusableMask extends Control {
        constructor() {
          super({
            element: document.createElement("div"),
          });
          this.element.setAttribute("hidden", "hidden");
          this.element.className = "ol-mask";
          this.element.innerHTML = "<div>地图不可用</div>";
        }
      }

      this.map = new Map({
        target: this.$refs.localMapTarget,
        controls: defaultControls().extend([
          new FullScreen(),
          new UnusableMask(),
        ]),
        layers: [
          new TileLayer({
            source: new StadiaMaps({
              layer: "stamen_watercolor",
            }),
          }),
        ],
        view: new View({
          center: fromLonLat([37.41, 8.82]),
          zoom: 4,
        }),
      });
    },

点击按钮时会触发openOutMap函数

使用window.open打开了一个html页面,使用window.open的参数对小窗窗口做一些设置。

 openOutMap() {
      this.$refs.btn.disabled = true;
      this.mapWindow = window.open(
        "resources/external-map-map.html",
        "MapWindow",
        "toolbar=0,location=0,menubar=0,width=800,height=600,top=130"
      );
    }

 这里的external-map-map.html页面我是从openlayers源码中复制出来放到了public下。文件中需要引入一下样式文件。

external-map-map.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Map</title>
    <link rel="stylesheet" type="text/css" href="./ol.css">
    <style>
      body {
        margin: 0;
      }
      .map {
        height: 100vh;
        width: 100vw;
      }
      .map.unusable .ol-mask {
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        user-select: none;
        background-color: rgba(0, 0, 0, .7);
        color: white;
        font: bold 3rem 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      }
      .map.unusable .ol-control {
        display: none;
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>
  </body>
</html>

openlayers源码下载地址: 

 GitHub - openlayers/openlayers: OpenLayers

 打开external-map-map.html页面之后需要监听一下DOMContentLoaded事件,使用setTarget把小窗口的map容器绑定到map实例上。

小窗关闭的时候需要重新加载一下大地图。

  //当初始的HTML文档被完全加载和解析完成后触发,不必等待样式表、图像和子框架的完全加载。
      this.mapWindow.addEventListener("DOMContentLoaded", () => {
        const externalMapTarget = this.mapWindow.document.getElementById("map");
        this.$refs.localMapTarget.style.height = "0px";
        this.map.setTarget(externalMapTarget);

        if (timeoutKey) {
          timeoutKey = clearTimeout(timeoutKey);
        }
        // 当用户离开当前页面时触发,例如关闭标签页、导航到其他页面或重新加载页面
        this.mapWindow.addEventListener("pagehide", () => {
          //重新加载大地图
          this.resetMapTarget();
          //关闭外部窗口
          this.closeMapWindow();
        });

        this.updateOverlay();
      });

写一个延时器,如果点击之后小窗口没有加载出来就显示异常文字提醒。 

//处理异常情况,点击之后没有打开外部窗口
      let timeoutKey = setTimeout(() => {
        this.closeMapWindow();
        this.resetMapTarget();
        blockerNotice.removeAttribute("hidden");
        timeoutKey = undefined;
      }, 3000);

完整代码:

<template>
  <div class="box">
    <h1>External map</h1>
    <div id="map" ref="localMapTarget"></div>
    <input
      id="external-map-button"
      type="button"
      ref="btn"
      @click="openOutMap"
      value="打开外部窗口"
    />
    <span id="blocker-notice" hidden
      >无法在外部窗口打开地图。如果您正在使用弹出窗口或广告拦截器,您可能需要禁用它。</span
    >
  </div>
</template>

<script>
import Map from "ol/Map.js";
import OSM from "ol/source/OSM.js";
import TileLayer from "ol/layer/Tile.js";
import View from "ol/View.js";
import StadiaMaps from "ol/source/StadiaMaps.js";
import {
  Control,
  FullScreen,
  defaults as defaultControls,
} from "ol/control.js";
import { fromLonLat } from "ol/proj.js";
export default {
  name: "",
  components: {},
  data() {
    return {
      map: null,
      mapWindow: "",
    };
  },
  computed: {},
  created() {},
  mounted() {
    this.initMap()
    // 当用户离开当前页面时触发,例如关闭标签页、导航到其他页面或重新加载页面
    window.addEventListener("pagehide", this.closeMapWindow);

    //当页面的可见状态发生变化时触发,例如用户切换到其他标签页或最小化浏览器。
    window.addEventListener("visibilitychange", this.updateOverlay);
  },
  methods: {
    initMap() {
      class UnusableMask extends Control {
        constructor() {
          super({
            element: document.createElement("div"),
          });
          this.element.setAttribute("hidden", "hidden");
          this.element.className = "ol-mask";
          this.element.innerHTML = "<div>地图不可用</div>";
        }
      }

      this.map = new Map({
        target: this.$refs.localMapTarget,
        controls: defaultControls().extend([
          new FullScreen(),
          new UnusableMask(),
        ]),
        layers: [
          new TileLayer({
            source: new StadiaMaps({
              layer: "stamen_watercolor",
            }),
          }),
        ],
        view: new View({
          center: fromLonLat([37.41, 8.82]),
          zoom: 4,
        }),
      });
    },
    //关闭小窗时触发
    closeMapWindow() {
      if (this.mapWindow) {
        this.mapWindow.close();
        this.mapWindow = undefined;
      }
    },
    resetMapTarget() {
      this.$refs.localMapTarget.style.height = "";
      this.map.setTarget(this.$refs.localMapTarget);
      this.$refs.btn.disabled = false;
    },
    updateOverlay() {
      if (!this.mapWindow) {
        return;
      }
      const externalMapTarget = this.mapWindow.document.getElementById("map");
      if (!externalMapTarget) {
        return;
      }
      if (document.visibilityState === "visible") {
        // 显示控件并启用键盘输入
        externalMapTarget.classList.remove("unusable");
        externalMapTarget.setAttribute("tabindex", "0");
        externalMapTarget.focus();
      } else {
        //隐藏所有控件并禁用键盘输入
        externalMapTarget.removeAttribute("tabindex");
        externalMapTarget.classList.add("unusable");
      }
    },
    openOutMap() {
      const blockerNotice = document.getElementById("blocker-notice");
      blockerNotice.setAttribute("hidden", "hidden");
      this.$refs.btn.disabled = true;

      //处理异常情况,点击之后没有打开外部窗口
      let timeoutKey = setTimeout(() => {
        this.closeMapWindow();
        this.resetMapTarget();
        blockerNotice.removeAttribute("hidden");
        timeoutKey = undefined;
      }, 3000);
      // return
      this.mapWindow = window.open(
        "resources/external-map-map.html",
        "MapWindow",
        "toolbar=0,location=0,menubar=0,width=800,height=600,top=130"
      );
      //当初始的HTML文档被完全加载和解析完成后触发,不必等待样式表、图像和子框架的完全加载。
      this.mapWindow.addEventListener("DOMContentLoaded", () => {
        const externalMapTarget = this.mapWindow.document.getElementById("map");
        this.$refs.localMapTarget.style.height = "0px";
        this.map.setTarget(externalMapTarget);

        if (timeoutKey) {
          timeoutKey = clearTimeout(timeoutKey);
        }
        // 当用户离开当前页面时触发,例如关闭标签页、导航到其他页面或重新加载页面
        this.mapWindow.addEventListener("pagehide", () => {
          //重新加载大地图
          this.resetMapTarget();
          //关闭外部窗口
          this.closeMapWindow();
        });

        this.updateOverlay();
      });
    },
  },
};
</script>

<style lang="scss" scoped>
#map {
  width: 100%;
  height: 500px;
}
.box {
  height: 100%;
}
::v-deep #map.unusable .ol-mask {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  font: bold 3rem "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
::v-deep #map.unusable .ol-control {
  display: none;
}
</style>

文件列表: OL3Demo\.DS_Store OL3Demo\css\base.css OL3Demo\css\js_demo.css OL3Demo\css\ol.css OL3Demo\demos\.DS_Store OL3Demo\demos\Controls\Animation.htm OL3Demo\demos\Controls\CanvasTiles.htm OL3Demo\demos\Controls\FullScreen.htm OL3Demo\demos\Controls\LayerControl.htm OL3Demo\demos\Controls\LayerSpy.htm OL3Demo\demos\Controls\Measure.htm OL3Demo\demos\Controls\MousePosition.htm OL3Demo\demos\Controls\Operation.htm OL3Demo\demos\Controls\OverviewMap.htm OL3Demo\demos\Controls\ScaleLine.htm OL3Demo\demos\Controls\ZoomSlider.htm OL3Demo\demos\data\geojson\countries-110m.json OL3Demo\demos\data\geojson\countries.geojson OL3Demo\demos\data\geojson\GeoJSON.json OL3Demo\demos\data\geojson\samples.json OL3Demo\demos\data\geolocation-orientation.json OL3Demo\demos\data\geolocation_marker_heading.png OL3Demo\demos\data\gml\gml.xml OL3Demo\demos\data\gml\topp-states-wfs.xml OL3Demo\demos\data\gpx\fells_loop.gpx OL3Demo\demos\data\kml\2012-02-10.kml OL3Demo\demos\data\kml\2012_Earthquakes_Mag5.kml OL3Demo\demos\data\kml\kml.xml OL3Demo\demos\DataHandler.ashx OL3Demo\demos\Drawing\DrawFeatures.htm OL3Demo\demos\Drawing\FeaturesStyle.htm OL3Demo\demos\Drawing\ModifyFeatures.htm OL3Demo\demos\Drawing\MoveFeatures.htm OL3Demo\demos\Drawing\SaveFeatures.htm OL3Demo\demos\Labels\AddClusterLabels.htm OL3Demo\demos\Labels\AddLabels.htm OL3Demo\demos\Labels\AddPopup.htm OL3Demo\demos\MultiData\LoadBasicMaps.htm OL3Demo\demos\MultiData\LoadOpenData.htm OL3Demo\demos\MultiData\LoadPublicMaps.htm OL3Demo\demos\MultiData\LoadTiandituMap.htm OL3Demo\demos\MultiData\MapExport.htm OL3Demo\demos\MultiData\OSM.htm OL3Demo\demos\MultiData\OverLayerMaps.htm OL3Demo\demos\OGC\LoadWCSMap.htm OL3Demo\demos\OGC\LoadWFSFeatrue.htm OL3Demo\demos\OGC\LoadWMSMap.htm OL3Demo\demos\OGC\LoadWMTSMap.htm OL3Demo\demos\OGC\WFS_Transaction.htm OL3Demo\demos\Others\AddPOI.htm OL3Demo\demos\Others\CreatCharts.htm OL3Demo\demos\Others\Geolocation.htm OL3Demo\demos\Others\Heatmap.htm OL3Demo\demos\Others\HotSpots.htm OL3Demo\demos\Others\LoadPublicMaps.htm OL3Demo\demos\Others\MilitaryPlotting.htm OL3Demo\demos\Others\MultiViewLinkage.htm OL3Demo\demos\Others\ProjectionTransformation.htm OL3Demo\demos\Others\SimulateGeolocation.htm OL3Demo\demos\Others\副本 LoadPublicMaps.htm OL3Demo\demos\RegDataHandler.ashx OL3Demo\demos\Web.config OL3Demo\images\ArrowIcon\arbitrary_area.png OL3Demo\images\ArrowIcon\arrow.png OL3Demo\images\ArrowIcon\arrow1.png OL3Demo\images\ArrowIcon\arrowcross.png OL3Demo\images\ArrowIcon\assembly.png OL3Demo\images\ArrowIcon\circle.png OL3Demo\images\ArrowIcon\CircleClosedangleCompass.png OL3Demo\images\ArrowIcon\closedangle.png OL3Demo\images\ArrowIcon\curve_flag.png OL3Demo\images\ArrowIcon\custom_arrow.png OL3Demo\images\ArrowIcon\custom_tail_arrow.png OL3Demo\images\ArrowIcon\custom_tail_arrow_.png OL3Demo\images\ArrowIcon\DoubleClosedangleCompass.png OL3Demo\images\ArrowIcon\double_arrow.png OL3Demo\images\ArrowIcon\fourstar.png OL3Demo\images\ArrowIcon\rect_flag.png OL3Demo\images\ArrowIcon\rhombus.png OL3Demo\images\ArrowIcon\SameDirectionClosedangleCompass.png OL3Demo\images\ArrowIcon\singleLine_arrow.png OL3Demo\images\ArrowIcon\smooth_curve.png OL3Demo\images\ArrowIcon\stright_arrow.png OL3Demo\images\ArrowIcon\tail_arrow.png OL3Demo\images\ArrowIcon\triangle.png OL3Demo\images\ArrowIcon\triangle_flag.png OL3Demo\images\ArrowIcon\VaneCompass.png OL3Demo\images\content\dotted.png OL3Demo\images\label\bj.png OL3Demo\images\label\blueIcon.png OL3Demo\images\label\icon.png OL3Demo\images\label\restaurant.png OL3Demo\images\label\国有企业.png OL3Demo\images\left\app.png OL3Demo\images\left\app_current.png OL3Demo\images\left\channel.png OL3Demo\images\left\channel_current.png OL3Demo\images\left\cloud.png OL3Demo\images\left\cloud_current.png OL3Demo\images\left\custom.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值