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

news2024/11/25 22:55:41
  • 使用element-plus组件库
  • 安装ol
  • npm i ol -s
  • 安装axios (调用天地图api http://lbs.tianditu.gov.cn/server/search.html)
  • 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>
  • 结果 
  • 按地名搜索

 选中并标注

也可以在地图上点中进行标注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1985966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

直接用文件方式安装Cuda版本的Pytorch

先查看当前安装好的Cuda版本&#xff1a; 采用pip install 文件 方式安装本地的whl文件&#xff1a; 注意whl文件已经提前下载好了&#xff1a; 然后开始安装&#xff1a; 解压安装途中&#xff0c;相关的包也重新下载&#xff1a; 继续安装&#xff1a; 安装完毕了&#xff1…

【多线程-从零开始-伍】volatile关键字和内存可见性问题

volatile 关键字 import java.util.Scanner; public class Demo2 { private static int n 0; public static void main(String[] args) { Thread t1 new Thread(() -> { while(n 0){ //啥都不写 } System.out.println("t1 线程结束循环"); }, "…

基于STM32的智能灌溉系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 初始化代码传感器读取和控制代码应用场景 农业灌溉花园自动灌溉常见问题及解决方案 常见问题解决方案结论 1. 引言 智能灌溉系统通过实时监测土壤湿度和环境温度&#xff0c;自动控制灌溉设…

【画流程图工具】

画流程图工具 draw.io draw.io&#xff08;现称为 diagrams.net&#xff09;是一款在线图表绘制工具&#xff0c;可以用于创建各种类型的图表&#xff0c;如流程图、网络图、组织结构图、UML图、思维导图等。以下是关于它的一些优点、应用场景及使用方法&#xff1a; 优点&a…

Linux(初学)

一.Linux历史 1.计算机发展历史 1945.2.14 埃尼阿克(第一台计算机)(军事用途) 摩尔定律(计算机小型化,高性能化) 摩尔定律是英特尔创始人之一戈登摩尔的经验之谈&#xff0c;其核心内容为&#xff1a;集成电路上可以容纳的晶体管数目在大约每经过18个月到24个月便会增加…

理解Android framework之AOSP:从内核到应用层

一、AOSP Android framework确保设备的各个部件和程序顺利协同工作。对于想要全面了解 Android 设备内部工作原理、开发高质量应用、优化设备性能以及充分利用 Android 生态系统潜力的人来说&#xff0c;了解 Android 框架也是必不可少的。它是连接用户、开发者和 Android 平台…

高效录屏指南:四大电脑录屏必备工具推荐!

在数字化时代&#xff0c;无论是工作汇报、在线教育还是游戏直播&#xff0c;电脑录屏已经成为了一项不可或缺的技能。今天&#xff0c;我们就来探索一下市面上几款备受好评的录屏工具&#xff1a;福昕录屏大师、转转大师录屏、爱拍录屏、嗨格式录屏大师&#xff0c;看看它们各…

基于RFID技术的智能压缩机装配线优化方案

基于RFID技术的智能压缩机装配线优化方案 传统压缩机装配线往往存在诸多痛点&#xff0c;如生产线单一、无法满足多元化和个性化的市场需求&#xff1b;生产数据滞后&#xff0c;导致产品统计的及时性和准确性无法得到保证&#xff1b;质量问题追溯困难&#xff0c;无法快速准…

c/c++ 为数组整体赋初值

目录 声明 一.整体赋值为0、“”或‘ ’ 二.整体赋值为其他 1.利用for循环赋值 2.逐个赋值 声明 为让c/c的朋友都看懂&#xff0c;本文将采取c语言为大家讲解 一.整体赋值为0、“”或‘ ’ 为什么把0、“”或‘ ’这三种情况单独调出来呢&#xff0c;因为如果将数组定义…

日股暴涨暴跌,港股恐将遭受波及!

近日海外市场波动较大&#xff0c;比如美国、日本等市场的走势可谓是“上蹿下跳”。港股市场也因此受到影响。众所周知&#xff0c;影响股票市场走势的重要因素之一是资金面&#xff0c;这一表现影响大盘及个股的走势。在港股市场&#xff0c;卖空数据作为关键指标备受关注。 …

铲屎官的好帮手,去猫咪浮毛神器——宠物空气净化器分享

养猫的家庭普遍面临一个共同的挑战&#xff1a;即便是刚经过一番精心打扫的居住环境&#xff0c;不出两日&#xff0c;家具表面、地板乃至家中各个缝隙便悄无声息地被一层细腻柔软的猫毛轻轻覆盖。这一现象&#xff0c;很大程度上归咎于猫咪的日常活跃与季节性的换毛过程。不仅…

ACL 2024 Oral | 大模型也会被忽悠?揭秘AI的信念之旅

地球是平的吗&#xff1f; 当然不是。自古希腊数学家毕达哥拉斯首次提出地圆说以来&#xff0c;现代科学技术已经证明了地球是圆形这一事实。 但是&#xff0c;你有没有想过&#xff0c;如果 AI 被误导性信息 “忽悠” 了&#xff0c;会发生什么&#xff1f; 来自清华、上海…

网络面经

1.TCP头格式有哪些&#xff1f; 图解TCP头部格式 详情 源端口和目的端口 端口的作用是什么&#xff1f; 端口的作用是在网络中唯一表示一台主机中的一个进程 序列号 什么是序列号&#xff1f; 用来给传输的字节标号的 比如要传10个字节 那么给第一个字节标号为1001 那么第十…

周鸿祎哈佛演讲摘要:大模型创业要抓住中国机会

时间:2024/04/13(美东时间) 地点:美国波士顿哈佛大学 *演讲语言为中文&#xff0c;“因为我的英文就比are you OK 的水平高一点点”。 1、无论你是一个创业者&#xff0c;还是一个企业家&#xff0c;最重要的一点说要跟用户保持接触&#xff0c;要去聊天&#xff0c;跟用户对话…

测试环境搭建整套大数据系统(十八:ubuntu镜像源进行更新)

镜像源更新为清华源 报错显示 解决方案 做好备份 cp /etc/apt/sources.list /etc/apt/sources.list.bak查看配置信息 sudo vim /etc/apt/sources.listsudo sed -i s/cn.archive.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list sudo apt update

Java学习Day22:基础篇12

异常 1.什么是异常 2.继承体系 3.异常和错误的区别 4.异常处理 1.抛出异常throw public class err { public static void main(String[] args) { add(1,0); } static void add(int a,int b){ if (b0) { throw new ArithmeticExcepti…

【Linux】Linux重定向指南:探索输出重定向与追加重定向的奥秘!

欢迎来到 CILMY23 的博客 &#x1f3c6;本篇主题为&#xff1a;Linux重定向指南&#xff1a;探索输出重定向与追加重定向的奥秘&#xff01; &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | 贪…

css水波浪动画效果

为缩小gif大小&#xff0c;动画效果做了加速&#xff0c;效果如下&#xff1a; <!DOCTYPE html> <html> <head> <style> *{padding:0;margin:0;}/*清除默认填充及边距*/.water{position:relative;width:100vw;height:100vh;overflow:hidden;background…

std::string 的特性

s1是自己实现的string std的string里面有一个——Buf的数组大小为16通过内存对齐之后就是28个字节 如果存储的字符串大小不超过Buf数组的大小就存在里面&#xff0c;如果字符串的大小超过16字节就会重新开辟空间就会把Buf的空间浪费掉这是一种空间换时间的设计。

标准IO和文件IO

标准IO 接上节 函数接口 &#xff08;1&#xff09;fseek函数&#xff1a; 1.功能&#xff1a;将文件流中的文件指针从指定的起始位置开始偏移指定的字节数。 2.参数&#xff1a;&#xff08;目标文件&#xff0c;偏移量&#xff0c;参考点&#xff09; stream&#xff1a;…