vue2 + leaflet+ openstreetMap +天地图实现地图开发

  • Post author:
  • Post category:vue


功能:地图标记,标记点信息显示,地区搜索等,后续功能待开发

一、leaflet + openstreetMap使用

leaflet官网:

Tutorials – Leaflet – a JavaScript library for interactive maps (leafletjs.com)

openStreetMap官网:

OpenStreetMap

(1)leaflet安装

yarn 安装

	yarn add leaflet --save

引入相关包

​import "leaflet/dist/leaflet.css";

​import "leaflet.pm";

​import "leaflet.pm/dist/leaflet.pm.css";

(2) openstreetMap引入

2.1创建地图

<div class="map" id="map"></div>  //放地图的地方

2.2 创建地图实例

leaflet官方文档:

1.初始化地图并将其视图设置为所选的地理坐标和缩放级别:

var map = L.map('map').setView([51.505, -0.09], 13);

2.添加一个要添加到地图中的切片图层,在本例中为 OpenStreetMap 切片图层

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '© OpenStreetMap'
}).addTo(map);

本次项目开发:

 //1、定义图层样式openstreetmap
 var layer = L.tileLayer(
      "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      );
  //2、创建地图
 
  layer.options.maxZoom = 20;
  layer.options.maxNativeZoom = 25;

  let map = L.map("map", {
    center: this.latlng, //中心坐标格式[纬度,经度]
    zoom: 12, //缩放级别
    minZoom: 11,
    maxZoom: 19,
    zoomControl: false, //缩放组件
    attributionControl: false, //去掉右下角logo
    layers: [layer], //图层
    // boxZoom: true,
    // zoomAnimation: true,
  });
  this.map = map;

部分解释:在leaflet中,默认maxZoom为18,当值设置大于18后,地图依然能缩放,但会变成空白。如果需要加载高于zoom:18的瓦片,需要追加参数maxNativeZoom,这个参数允许你设置超过18的zoom值,例如layer.options.maxNativeZoom = 25;则在leaflet加载到18后继续放大,直到20

2.3 地图点击事件

本次项目开发:

 this.map.on("click", (i) => {
​        console.log("我被点击了");
​        // 点击获取地图上的经纬度
​        console.log(i.latlng);
​        this.latlng = i.latlng;
​        this.map.setView(this.latlng);
​      });

2.4 地图图标

项目要求:根据数据库信息显示不同样式的图标

leaflet官方文档:

1.添加标记:

var marker = L.marker([51.5, -0.09]).addTo(map);

本次项目开发:

1.创建两个不同的图标,定义大小

// 图标1
var icon1 = new L.Icon({
        className: "lmap-icon",
        iconUrl: require("./assets/img/machine.png"),
        iconSize: [15, 50],
      });
// 图标2
      var icon2 = new L.Icon({
        className: "lmap-icon",
        iconUrl: require("./assets/img/Omachine.png"),
        iconSize: [15, 55],
        iconAnchor: [24, 32],
      });

2.根据条件,插入不同的图标

//this.mapinfo是我自己创建的数据库表,item.loaction为标记点的经纬度
for (let item of this.mapinfo) {
        var marker2 = "";
        if (item.name.includes("SCHOOL")) {
          marker2 = L.marker(item.location, {
            icon: icon1,
            riseOnHover: true,
          }).addTo(this.map);
        } else {
          marker2 = L.marker(item.location, {
            icon: icon2,
            riseOnHover: true,
          }).addTo(this.map);
        }
      }

2.4 标记点信息(弹出窗口)

leaflet官方文档:

1.在标记点上添加弹出窗口

marker.bindPopup("<b>Hello world!</b><br>I am a popup.").openPopup();

2.在任意位置添加弹出窗口

var popup = L.popup()
    .setLatLng([51.513, -0.09])
    .setContent("I am a standalone popup.")
    .openOn(map);

本次项目:

项目要求:点击标记点动态显示标记点的信息,因此,弹窗内容另外写一个组件,因此,需要一个点击事件,通过点击标记点传递该标记点的信息给组件,再由.setContent(‘组件内容’)显示该组件

1.标记点点击事件

  //marker2为创建的标记点 this.infopane为标记点信息显示的方法,item为传输的标记点信息
  marker2.on("click", () => {
          this.infopane(item);
        });

2.标记点信息显示方法

 // 标记点信息
    infopane(item) {
   var dom = this.$refs.infomation2.$el;  //infomation2为插入的组件 $el为组件内的元素
      this.infoitem = item;			//标记点信息
      if (this.infoitem.name.includes("SCHOOL")) { //根据标记点信息显示不同图片
        this.infoitem.image = require("./assets/img/machine.png");
      } else {
        this.infoitem.image = require("./assets/img/Omachine.png");
      }
      new L.popup({
        // 是否自动调整窗体到视野内(当信息窗体超出视野范围时,通过该属性设置是否自动平移地图,使信息窗体完全显示)
        autoPaning: true,
        keepInView: true,
        // 弹出位置偏移量,可根据标记点图标大小修
        offset: new L.point(-15, -26),
      })
        .setLatLng(item.location)
        .setContent(dom)   //弹出框显示组件内容
        .openOn(this.map);
    },

二、天地图的使用

(1)key的创建

天地图官网:

国家地理信息公共服务平台 服务资源 (tianditu.gov.cn)

创建好后会生成key

(2)搜索框

跟据项目需求,使用elementui插件实现搜索框

elmenetui安装(vue2版本)

yarn add element-ui -S

使用elementui中的input输入框中的远程搜索

//elementui官方文档
<el-autocomplete
  v-model="state"
  :fetch-suggestions="querySearchAsync"
  placeholder="请输入内容"
  @select="handleSelect"
></el-autocomplete>
//我的项目
data(){
   return{
input:""
  }
}
    <el-autocomplete
        class="inline-input"
        v-model="input"
        :fetch-suggestions="querySearch"
        placeholder="请输入地址"
        :trigger-on-focus="false"
        @select="handleSelect"
      ></el-autocomplete>
//搜索
 querySearch(queryString, cb) {
      var addresses = [];
      let add =
        `http://api.tianditu.gov.cn/search?postStr={"keyWord":"` +
        this.input +
 `","level":"11","mapBound":"搜索的区域范围","queryType":"1","count":"20","start":"0"}&type=query&tk=key`;
      axios({
        url: add,
      }).then((res) => {
        if (res.data.pois) {
          res.data.pois.forEach((item) => {
            item.value = item.name;
            addresses.push(item);
          });
        } else if (res.data.area) {
          res.data.area.value = res.data.area.name;
          addresses.push(res.data.area);
        }
        console.log(addresses);
        cb(addresses);   //返回address的值
      });
    },



版权声明:本文为weixin_44693550原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。