美文网首页
天地图按地名搜索+openlayer+vue3

天地图按地名搜索+openlayer+vue3

作者: 月下小酌_dbd5 | 来源:发表于2022-06-02 16:44 被阅读0次
  • 使用element-plus组件库
  • 安装ol
npm i ol -s
npm i axios -s
  • 主要代码
<template>
  <div class="my-add-maker-box">
    <div class="my-point-box">
      <span>经度lng:</span>
      <el-input v-model.trim="pointData.lng" :disabled="true" placeholder="请点击下面地图进行标注" />
      <span>纬度lat:</span>
      <el-input v-model.trim="pointData.lat" :disabled="true" placeholder="请点击下面地图进行标注" />
    </div>
    <div class="my-map-box" id="map" :key="keyMap">
      <div class="my-map-search">
        <el-input v-model="param.data.postStr.keyWord" placeholder="请输入地名">
          <template #append>
            <el-button :icon="Search" @click="searchHandle" />
          </template>
        </el-input>
        <div class="my-map-clear" @click="clearMarker">清除标注</div>
        <div class="my-search-result" v-if="searchShow">
          <div v-if="searchResult.data == null" style="margin-left: 150px; font-size: 20px; color: #888;">暂无数据</div>
          <div v-else class="my-search-result-item" v-for="(item, index) in  searchResult.data" :key="index"
            @click="clickMarker(item)">{{ item.name }}
          </div>

        </div>
      </div>
    </div>
  </div>
</template>
<script lang='ts' setup>
import { ref, reactive, onMounted } from 'vue'
//导入相关配置信息
import 'ol/css';
import { Map, View, Feature } from 'ol'
import { Style, Icon } from 'ol/style'
import { Point } from 'ol/geom';
import { Vector as SourceVec, XYZ, } from 'ol/source'
import { Vector as LayerVec } from 'ol/layer'
import TileLayer from 'ol/layer/Tile'
import { defaults as defaultControls, MousePosition, } from "ol/control"
import axios from 'axios'
import { Search } from '@element-plus/icons-vue'

let myMap: any = null
let myView: any = null
let keyMap: any = ref(Math.random())
let vectorLayer: any = null
let searchResult = reactive({ data: null })
let searchShow = ref(false)
let pointData = reactive({ lng: '', lat: '' })

// url
const url = ref('http://api.tianditu.gov.cn/v2/search')
// 参数
let param = reactive({
  data: {
    postStr: {
      keyWord: '',
      level: 18,
      mapBound: "116.02524,39.83833,116.65592,39.99185",
      queryType: 1,
      start: 0,
      count: 10
    },
    type: 'query',
    tk: '37c72a79fe4c6a1b3fa6b1435214b378'
  }
})
onMounted(() => {
  // console.log('initMap')
  setTimeout(() => {
    myMap = new Map({
      target: 'map',
      //图层数组 layers
      layers: [
        new TileLayer({
          source: new XYZ({
            crossOrigin: 'anonymous',
            url: 'https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=37c72a79fe4c6a1b3fa6b1435214b378'
          })
        }),
        new TileLayer({
          source: new XYZ({
            crossOrigin: 'anonymous',
            url: 'https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=37c72a79fe4c6a1b3fa6b1435214b378'
          })
        })
      ],
      //视图 View
      view: new View({
        projection: "EPSG:4326",
        center: [120.15373797456354, 30.291315691648734],
        zoom: 15,
        maxZoom: 17,
        minZoom: 3,
      }),
      //默认控件
      controls: defaultControls({
        zoom: false,
        rotate: false,
        attribution: false,
      }).extend([
        //添加新控件
        // new MousePosition(),
      ])
    })
    // 获取地图视图
    myView = myMap.getView()

    // setMarker([120.15373797456354, 30.291315691648734])
    myMap.on('singleclick', function (e: any) {
      setMarker(e.coordinate)
    })
  }, 1);
})
// 标注点
const setMarker = (point: any) => {
  //移出给定的图层
  myMap.removeLayer(vectorLayer)
  // 创建矢量容器
  let vectorSource = new SourceVec({})
  //创建图标特性
  let iconFeature = new Feature({
    geometry: new Point(point, "XY")
  })
  //将图标特性添加进矢量中
  vectorSource.addFeature(iconFeature)
  //创建图标样式
  let iconStyle = new Style({
    image: new Icon({
      opacity: 0.75,
      src: require('@/assets/images/marker-icon.png'),
      // offset: [-20, -40],
      // offsetOrigin: 'bottom-right',
      size: [30, 65]
    })
  })
  //创建矢量层
  vectorLayer = new LayerVec({
    source: vectorSource,
    style: iconStyle
  }); //添加进map
  // removeLayer
  myMap.addLayer(vectorLayer);
  param.data.postStr.keyWord = ''
  searchShow.value = false
  pointData.lng = point[0]
  pointData.lat = point[1]
}
// 清除标注点
const clearMarker = () => {
  //移出给定的图层
  myMap.removeLayer(vectorLayer)
  pointData.lng = ''
  pointData.lat = ''
}

// 点中某个结果
const clickMarker = (item: object) => {
  setMarker(item.lonlat.split(','))
  myView.setCenter(item.lonlat.split(','))
  param.data.postStr.keyWord = ''
  searchShow.value = false
}

//搜索
const searchHandle = () => {
  // 地名查询
  axios({
    method: 'GET',
    url: url.value,
    params: param.data
  }).then(function (res) {
    console.log(res.data.pois)
    searchShow.value = true
    if (res.data.pois) {
      searchResult.data = res.data.pois
    } else {
      searchResult.data = null
    }
    console.log(res.data)
  })
}

</script>
<style scoped lang='less'>
.my-add-maker-box {
  width: 100vw;

  // border: 1px solid #eee;
  .my-point-box {
    width: 900px;
    margin: auto;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 20px;

    span {
      display: inline-block;
      width: 200px;
    }
  }

  .my-map-box {
    width: 900px;
    height: 500px;
    margin: auto;
    position: relative;
    z-index: 1;

    .my-map-search {
      position: absolute;
      top: 5px;
      left: 10px;
      z-index: 99;

      .my-map-clear {
        position: absolute;
        top: 0;
        left: 380px;
        z-index: 999;
        width: 90px;
        text-align: center;
        line-height: 30px;
        border: 1px solid #dcdfe6;
        background-color: #f5f7fa;
        border-radius: 3px;
        cursor: pointer;
        color: #909399;

        &:hover {
          background-color: #ecf5ff;
          color: #409eff;
        }
      }

      .my-search-result {
        position: absolute;
        top: 31px;
        left: 0;
        z-index: 999;
        width: 371px;
        max-height: 260px;
        border: 1px solid #eee;
        box-sizing: border-box;
        background-color: #fff;
        overflow: auto;
        padding: 10px 0;

        .my-search-result-item {
          width: 100%;
          padding: 8px 15px;
          box-sizing: border-box;
          cursor: pointer;

          &:hover {
            background-color: #eee;
          }
        }
      }
    }

    /deep/ .el-input-group {
      width: 371px;
    }
  }
}
</style>
  • 结果
按地名搜索 选中并标注 也可以在地图上点中进行标注

相关文章

  • 天地图按地名搜索+openlayer+vue3

    使用element-plus组件库 安装ol 安装axios (调用天地图api http://lbs.ti...

  • 杨树港,我活成了你讨厌的模样

    杨树港,不是人名而是地名,是一个不需要太负责、太迁就、太讨好、太响亮的地名。即使用“高德地图”搜索,能给出的信息量...

  • 货比三家

    发现阅读用地图的好处后,新出现的问题也不免让人有小小的遗憾。那就是有些地名搜索不出来。 我用的是百度地图,...

  • 导航页 | 范例

    搜索站点 秘迹搜索百度一下搜狗搜索360搜索 地图站点 搜狗地图高德地图百度地图腾讯地图360地图地图窝_地图册高...

  • 母亲背我走过的山路

    作者:钱大江 理会特意将他珍藏的古旧的家乡地图按区域拍照给我,伴随着这一串串读起来非常耳熟的地名,...

  • DatistEQ之快速获取地区边界

    在WebMap地图浏览器中,集成了行政区边界搜索功能,可查到全国所有乡镇级上的行政边界。在搜索框中的输入关键字,按...

  • arcgis api for js入门开发系列十三地图最短路径分

    上一篇实现了demo的地图打印,本篇新增地图最短路径分析,截图如下: 具体实现的思路如下:1.点击地图获取地名,调...

  • iOS 一步一步实现百度地图范围搜索

    实现百度地图显示范围内搜索关键词 效果图: 实现原理: 首先,要实现范围内搜索,就得借助地图搜索类方法,去百度地图...

  • 左传

    闲翻史书,看到很多地名,需要一本历史地图。为什么这些史书不带地图呢。 在网上搜了下,找到不少春秋时的地图,上面这个...

  • linux命令 之 find

    忘记目录或文件的位置,用find就能轻松找到 find 按名称搜索 按路径搜索 按类型搜索 搜索空目录和文件 非搜...

网友评论

      本文标题:天地图按地名搜索+openlayer+vue3

      本文链接:https://www.haomeiwen.com/subject/nhvtprtx.html