openlayers构建离线地图

参考文档

http://linwei.xyz/ol3-primer/ch05/05-03.html
http://openlayers.vip/examples/line-arrows.html

项目需要使用内网环境,故无法使用百度地图等在线地图.采用openlayers实现构建离线地图

通过shp加载shp矢量地图文件

<template>
  <view style="width: 100%;height:100%">
    <view id="map" class="map"></view>
  </view>
</template>

<script>
import "ol/ol.css";
import {Map, View, Feature} from "ol";
import {Style, Icon} from 'ol/style';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import Point from 'ol/geom/Point';
import {defaults as defaultControls, MousePosition} from 'ol/control';
import config from '@/tools/config'
import {mapState} from "vuex";


// 示例: http://linwei.xyz/ol3-primer/ch05/05-03.html
// http://openlayers.vip/examples/line-arrows.html
export default {
  props:{
    robot_id: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      map: null, // map地图
      layer: null,
      zoom: 18, //缩放级别,范围5-18,越小,范围越广
      // 初始化中心点坐标
      longitude: 113.28618608029409,
      latitude: 23.376623652412462,
      styles: null,
    };
  },
  computed:{
    ...mapState([
      // 设备列表
      'robots',
      // 处理后的设备covers
      'covers',
    ]),
    // 当前设备信息
    robot: function(){
      return this.robots.find(item => item.id === this.robot_id)
    },
    // 当前选中 marker 索引
    cover_index: function(){
      return this.covers.findIndex(item => item.id === this.robot_id)
    },
    cover: function(){
      return this.covers.find(item => item.id === this.robot_id)
    }
  },
  watch:{
    // cover(newVal,oldVal){
    //   if (!newVal) return;
    //   // if(oldVal.length !== newVal.length){
    //   //   // 设置中心坐标
    //   //   if(this.map){
    //   //     console.log(this.cover.lng, this.cover.lat)
    //   //     this.map.getView().setCenter([this.cover.lng, this.cover.lat]);
    //   //     this.map.getView().setZoom(18);
    //   //   }
    //   // }
    // },
    covers: {
      handler(newVal,oldVal) {
        if(oldVal.length === newVal.length){
          // console.log('covers改变但长度没有发生变化,执行平移标记', newVal,oldVal)
          // 移动标记
          this.moveMarkers();
        }else{
          // 长度改变了,执行重置marker
          this.initMarkers();
        }
      },
      deep: true
    }
  },
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      this.target = document.getElementById('map');
      this.map = new Map({
        // 地图容器DIV层ID
        target: this.target,
        // 地图容器加载的图层
        // layers: [
        //   // 将瓦面图层Layer 添加到 Map 中
        //   // new TileLayer({
        //   //   // 给图层添加具体的数据源(这个是加载在线地图)
        //   //   source: new OSM({
        //   //     wrapX: true
        //   //   })
        //   // })
        // ],
        // 设置 Map 容器的视图
        view: new View({
          projection: "EPSG:4326", // 使用这个坐标系, WGS84坐标系
          center: [this.longitude, this.latitude],
          zoom: this.zoom
        }),
        // 加载控件
        controls: defaultControls().extend([
          // 加载鼠标位置控件
          new MousePosition()
        ]),

      });
      this.handleShp()
    },
    handleShp(){
      shp(config.baseURL+"/gz-shp.zip").then((data) => {
        if (data && data.length > 0) {
          data.map(item => {
            // 构建矢量图层
            let pointLayer = new VectorLayer({
              // 设置图层的数据源
              source: new VectorSource({
                features: (new GeoJSON()).readFeatures(item)
              }),
            })
            pointLayer.setZIndex(2);
            pointLayer.set('layer_name','shp')
            // 添加矢量图层到map
            this.map.addLayer(pointLayer);
          })
        }
      })
    },
    // 初始化makers
    initMarkers(){
      this.$nextTick(()=>{
        // 删除之前的图层
        if(this.layer){
          this.map.removeLayer(this.layer)
        }

        // 创建一个新的存放图标的图层
        this.layer = new VectorLayer({
          source: new VectorSource(),
        })
        this.layer.set('layer_name','marker')
        this.styles = {
          // 默认样式
          defaultStyle: new Style({
            image: new Icon({
              src: '/static/img/green_rob.png',
            }),
            zIndex: 1
          }),
          // 选中样式
          selectStyle: new Style({
            image: new Icon({
              src: '/static/img/red_rob.png',
            }),
            zIndex: 10
          })
        }
        this.covers.map(cover => {
          // 创建一个数据源(特征),并设置好在地图上的位置
          let feature = new Feature({
            geometry: new Point([cover.lng, cover.lat])
          });
          if(cover.id === this.robot_id){
            // 设置为选中样式
            feature.setStyle(this.styles.selectStyle);
          }else{
            // 设置未选中样式
            feature.setStyle(this.styles.defaultStyle);
          }
          // 设置ID
          feature.setId(cover.id);
          // 设置名称
          feature.set('name',cover.name);

          // 为feature注册自定义事件click的监听
          feature.on('click', this.onClickMarker);

          // 添加数据源到图层
          this.layer.getSource().addFeature(feature);


        })
        // 添加图层到map
        this.layer.setZIndex(3);
        this.map.addLayer(this.layer);

        // 添加自定义事件
        // 为地图注册点击事件的监听
        this.map.on('click', (event)=>{
          this.map.forEachFeatureAtPixel(event.pixel, (feature,layer)=>{
            // 给点击的marker触发事件
            feature.dispatchEvent({type: 'click', event: event});
            // 防止触发多个marker,需要返回值
            return true;
          },{
            // 根据图层名称,进行过滤
            layerFilter: (layer) => {
              return layer.get('layer_name') === 'marker';
            }
          });
        });
      })
    },
    // 移动makers
    moveMarkers(){
      if(this.layer){
        this.covers.map(cover => {
          // 根据ID获取到对应的marker
          const feature = this.layer.getSource().getFeatureById(cover.id);
          // 获取上次的坐标位置
          const oldPoint = feature.getGeometry().getCoordinates();
          // 移动坐标
          feature.getGeometry().translate(cover.lng - oldPoint[0],cover.lat - oldPoint[1])
        })
      }
    },
    // 点击选中
    onClickMarker(evt){
      const feature = evt.target
      if(this.robot_id != feature.getId()){
        // 选中当前设备
        this.$emit('change',feature.getId())
        // 设置当前marker样式为选中样式
        feature.setStyle(this.styles.selectStyle)
        // 设置之前选中的marker为默认样式
        this.layer.getSource().getFeatureById(this.robot_id).setStyle(this.styles.defaultStyle);
      }
    },
    // 移除地图
    removeMarkers(){
      // 删除之前的图层
      if(this.layer){
        this.map.removeLayer(this.layer)
      }
    }
  },
};
</script>

<style scoped>
.map {
  width: 100%;
  height: 100%;
}
</style>
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇