openlayers 基础功能实现

337 阅读2分钟

效果展示

GIF.gif

公共文件方法

  • utils/MapLayer.js
//高德瓦片
const gaodeMapLayer = 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: "高德地图",
});
const gaodeGrid = new TileLayer({
  source: new TileDebug({
    projection: "EPSG:3857",
    tileGrid: 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}",
    }).getTileGrid(),
  }),
});
//OSM
const osmMapLayer = new TileLayer({
  source: new OSM(),
  name: "世界地图(OSM)",
});
// OSM
const OsmOverviewMap = new TileLayer({
  source: new OSM({
    url: "http://{a-c}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png",
  }),
});
const osmGrid = new TileLayer({
  source: new TileDebug({
    projection: "EPSG:3857",
    tileGrid: new OSM().getTileGrid(),
  }),
});
//高德地图
const gaodeMapLayer2 = new TileLayer({
  source: new XYZ({
    url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=7",
  }),
  name: "高德地图(矢量图 含路网、不含标注)",
});
//影像底图 不含路网,不含注记
const gaodeMapLayer3 = new TileLayer({
  source: new XYZ({
    url: "http://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
  }),
  name: "高德地图(影像底图 不含路网,不含注记)",
});
//影像路网 含路网,不含注记
const gaodeMapLayer4 = new TileLayer({
  source: new XYZ({
    url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=8",
  }),
  name: "高德地图(影像路网 含路网,不含注记)",
});
//google地图
const googleMapLayer = new TileLayer({
  source: new XYZ({
    url: "http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i380072576!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0!5m1!1e0",
  }),
  name: "google地图",
});

const BingMapRoad = new TileLayer({
  source: new BingMaps({
    key: "AuUKioHoVzV-16Ep0yv6ay21ixWZ5OZ7jDs-k7g03fiUMbN6GSH97IpRcQ_s_s3-",
    imagerySet: "Road",
  }),
  name: "BingMap的道路图层",
});
const BingMapAerial = new TileLayer({
  source: new BingMaps({
    key: "AuUKioHoVzV-16Ep0yv6ay21ixWZ5OZ7jDs-k7g03fiUMbN6GSH97IpRcQ_s_s3-",
    imagerySet: "Aerial",
  }),
  name: "BingMap的影像图层",
});

HTML 结构

 <div id="appMap" style="width: 100%" class="dynamic-component-demo">
    <!-- 比例尺 -->
    <div class="scale-line" id="scale-line"></div>
    <!-- 鼠标位置 -->
    <div class="mouse-postions" id="mouse-postions"></div>
    <!-- 功能操作 -->
    <div class="openrate">
      <div @click="zoomIn">放大</div>
      <div @click="zoomOut">缩小</div>
      <div @click="pamto">成都</div>
      <div @click="restore">复位</div>
      <div @click="Rote">旋转</div>
    </div>
    <!-- 瓦片图 -->
    <div class="tree">
      <div class="title">图层列表</div>
      <ul>
        <li v-for="(item, index) in layerMessage" :key="index">
          <input
            type="checkbox"
            :name="item.name"
            :value="item.name"
            :checked="item.isVisibility"
            @click="layerChange(item)"
          />{{ item.name }}
        </li>
      </ul>
    </div>
  </div>
  • utils/control.js
const slider = new ZoomSlider();
const ToExtent = new ZoomToExtent({
  extent: [13100000, 429000, 13200000, 5210000],
});
let MousePositionControl = (target) => {
  return new MousePosition({
    className: "qc-mouse-position",
    coordinateFormat: createStringXY(4),
    projection: "EPSG:4326",
    target,
    undefinedHTML: "暂无数据",
  });
};
/**
 *
 * @param {比例尺单位} type degrees、imperial、us、nautical、metric
 * @returns
 */
const scale = (units, target) => {
  return new ScaleLine({
    className: "qc-scale-line",
    //设置比例尺单位,(度量单位)
    units,
    target,
    bar: true,
    steps: 1,
  });
};

const full = (target) => {
  return new FullScreen({
    target,
  });
};

Map 实例化

mounted() {
    let map = new Map({
      // 设置地图图层
      layers: [
        osmMapLayer,
        gaodeMapLayer2,
        gaodeMapLayer3,
        gaodeMapLayer4,
        gaodeMapLayer,
      ],
      // 设置显示地图的视图
      view: new View({
        center: transform([104.06, 30.67], "EPSG:4326", "EPSG:3857"),
        zoom: 9,
        minZoom: 1,
        maxZoom: 21,
        //  projection: "EPSG:4326",
        rotation: 0,
      }),
      // 让id为map的div作为地图的容器
      target: "appMap",
      controls: defaults().extend([
        MousePositionControl(document.getElementById("mouse-postions")),
        slider,
        ToExtent,
        scale("metric", document.getElementById("scale-line")),
        full(),
      ]),
    });
    //计算layer数量
    this.loadLayerControl(map);
    //当前的地图参数
    var view = map.getView();
    this.view = map.getView();
    this.Zoom = view.getZoom();
    this.rotation = view.getRotation();
    this.center = view.getCenter();
    this.map = map;
  },

事件监听方法

    methods:{
       //添加Control
    addSilder(map) {
      map.addControl(slider);
      map.addControl(ToExtent);
      map.addControl(
        MousePositionControl(document.getElementById("mouse-postions"))
      );
    },
    //图层变化的事件监听
    layerChange(layer) {
      let { layerMessage } = this;
      layerMessage.forEach((element, index) => {
        if (element.id == layer.id) {
          //console.log(element,index)
          layer.item.setVisible(!element.isVisibility);
          //改变data原始数据
          this.$set(
            this.layerMessage[index],
            "isVisibility",
            !element.isVisibility
          );
        }
      });
    },
    //渲染层级计算
    loadLayerControl(map, id) {
      var layerMessage = [],
        layers = map.getLayers();
      for (let i = 0, len = layers.getLength(); i < len; i++) {
        layerMessage.push({
          id: Symbol(layers.item(i).get("name")),
          item: layers.item(i),
          name: layers.item(i).get("name"),
          isVisibility: layers.item(i).getVisible(),
        });
      }
      this.layerMessage = layerMessage;
    },
    //选择
    Rote() {
      let { map } = this,
        rote = Math.random() * 9;
      map.getView().setRotation(Math.PI / rote);
    },
    zoomIn() {
      let { map } = this;
      map.getView().setZoom(map.getView().getZoom() + 1);
    },
    zoomOut() {
      let { map } = this;
      map.getView().setZoom(map.getView().getZoom() - 1);
    },
    restore() {
      let { map, center, Zoom, rotation } = this;
      map.getView().setZoom(Zoom);
      map.getView().setCenter(center);
      map.getView().setRotation(rotation);
    },
    pamto() {
      let { map } = this;
      map
        .getView()
        .setCenter(transform([104.06, 30.67], "EPSG:4326", "EPSG:3857"));
    },
  },
    }

特别提醒:这些都是openlayers 基础api ,使用这些API的时候应该关注options参数的含义和各参数展现的前端界面效果,让自己吃透API的用法,运用自如