webgis入门实战案例——智慧校园

本文通过利用高德地图的JS API做一个关于智慧校园的小案例,主要内容有地图展示、地图控件的添加、标注点添加、地点打卡、驾车路径规划动画展示,文章末尾附有完整代码。后续将继续跟进其他学习案例。

目录
    • 前置工作
    • 地图展示
    • 地图控件的添加
    • 实现点击某个地方进行标注、打卡
    • 实现简单的驾车路径规划动画
    • 上面案例的完整代码

前置工作

  • HTML页面的准备:创建一个id为container的地图容器

    <div id="container"></div>

    对html、body、container设置宽高:

  • 引入高德地图相关的CSS资源

    <link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />

  • 在高德开放平台上申请JS API的key和安全密钥,引入高德js相关的资源(将下面代码中的安全密钥和key替换即可)

地图展示

  • 在js中创建地图对象(这样就会在界面上显示地图)

    var map=new AMap.Map(‘container’,{
    center:[118.91125,32.10296],//表示地图界面中心显示的位置
    zoom:16,//表示地图级别
    viewMode:‘3D’,//表示地图显示模式为3D,默认是2D
    pitch:45,//初识地图俯仰角度
    })

其他AMap.Map属性和方法参照:

AMap.Map属性和方法

地图控件的添加

// 异步加载工具条插件,在回调函数中实例化插件,并使用插件功能
AMap.plugin(['AMap.ToolBar','AMap.Scale','AMap.ControlBar','AMap.GeoJSON','AMap.MoveAnimation'],function(){// 添加缩放控件插件到地图页面map.addControl(new AMap.ToolBar({position:{top:'80px',right:'40px',},}));// 添加比例尺map.addControl(new AMap.Scale());// 添加控制罗盘控件map.addControl(new AMap.ControlBar());})

其他插件的使用参照:

插件列表

实现点击某个地方进行标注、打卡

监听地图的点击事件,当点击时调用函数

```html
map.on('click',function(e){// 先创建标注对象var marker=new AMap.Marker({position:e.lnglat,// 获取点击事件的位置(经纬度)}})map.add(marker);// 将标注添加到地图
})
```
  • 进阶:实现点击事件打卡,保存数据,再次打开页面时,旧数据依然在,切可以继续打卡,并在页面上显示该地点打卡了几次。

    // 定义一个全局变量,保存geojson
    var geojson = new AMap.GeoJSON({geoJSON:null,
    })
    
    • 新数据打卡

      map.on(‘click’,function(e){
      var marker=new AMap.Marker({
      position:e.lnglat,
      extData:{
      // 自定义属性
      _geoJsonProperties:{
      gid:geojson.getOverlays().length+1,// 打卡地点数+1
      click:0,// 初始的点击数为0
      }
      }
      })

      // 对标注点进行点击时:实现对新旧点击事件标记打卡
      marker.on('click',function(e){var ext=marker.getExtData();// 先得到属性var click = ++ext._geoJsonProperties.click;// 将该标注地点的点击事件自增然后存到click变量中// 使用信息提示框显示打卡信息var infowindow=new AMap.InfoWindow({anchor:'top-center',// 提示框显示的位置content:`<div>打卡了${click}次</div>`,})// 显示窗口信息:在地图上点击的标注位置上显示信息infowindow.open(map,marker.getPosition());// 将新数据重新保存;若没有保存,则下次加载进来的数据还是没有自增的click属性值// 将其转为geojson格式再保存saveData(geojson.toGeoJSON());
      })
      // 通过geojson来管理覆盖物
      geojson.addOverlay(marker);
      // 保存数据(将geojson对象转换成标准的GeoJSON格式对象)
      saveData(geojson.toGeoJSON())
      map.add(marker);
      

      })

    • 旧数据打卡

      // 读取和存储数据函数
      // 从Localstorage中读取数据
      function getData(){
      //如果本地local storage中不存在数据
      if(!localStorage.getItem(‘geojson’)){
      //设置一个空的初始数据,即数据初始化
      localStorage.setItem(‘geojson’,‘[]’)
      }
      //反之,因为localStorage中存放的是字符串数据,所以将字符串数据转换成JSON对象返回
      return JSON.parse(localStorage.getItem(‘geojson’))
      }

      // 将数据保存到Localstorage中
      function saveData(data){
      //需要将数据转换成字符串类型才能存入localStorage中
      localStorage.setItem(‘geojson’,JSON.stringify(data))
      }

      // 导入数据,当数据为空的时候,会报错,所以在数据不为空的时候才导入
      // 因为getData()返回的是对象,所以需要先将其转为字符串,判断其是否为空字符串,即空数组
      if(JSON.stringify(getData())!=‘[]’){
      geojson.importData(getData())// 将得到的对象导入geojson变量中
      // 恢复旧数据的点击事件:拿到geojson数据中的每一个点,对拿到的每一个标注点(覆盖物)设置点击监听
      geojson.eachOverlay(function(item){
      // 对每个标注点的点击事件进行监听
      item.on(‘click’,function(e){
      var ext=item.getExtData();
      var click = ++ext._geoJsonProperties.click;

              var infowindow=new AMap.InfoWindow({anchor:'top-center',content:`<div>打卡了${click}次</div>`,})infowindow.open(map,item.getPosition());saveData(geojson.toGeoJSON());// 同样保存数据})
      })
      

      }
      // 将导入的数据添加到地图上面;这样,刷新浏览器的时候数据就不会消失(相当于加载地图的时候就将原来存储的数据加进来)
      map.add(geojson);

实现简单的驾车路径规划动画

先设置起点和终点,然后建立一个对象存储途径点经纬度坐标,然后将始末点和途径点传入driving.search函数中,遍历结果result.routes[0].steps中的每一个步骤,设置小车标注,实现动画效果

function starts(){//首先引用驾车规划插件AMap.plugin('AMap.Driving',function(){// 创建驾车规划对象var driving =new AMap.Driving({map:map,// 显示在地图上// policy:AMap.DrivingPolicy.LEAST_TIME,policy:2,// 按照距离最短规划})// 设置起点和终点var st=new AMap.LngLat(118.903607, 32.096752);var end=new AMap.LngLat(118.918165, 32.098677);// 通过geojson得到每一个点的坐标var obs={waypoints:[],}// 将geojson中每一个点数据的坐标添加到obs对象中geojson.eachOverlay(function(item){obs.waypoints.push(item.getPosition());})// 将点的对象传入driving.search(st,end,obs,function(status,result){if(status=='complete'){// 路径规划成功,则接下来实现动画效果// console.log(result);var lineArr=[];// 创建存放路径的变量result.routes[0].steps.forEach(function(item){lineArr.push(...item.path);//遍历路线的每一个步骤,将其路径展开放入lineArr中})// console.log(lineArr);//首先设置小车标记的起始位置var marker=new AMap.Marker({map:map,position:st,// 导入小车图标icon:'https://webapi.amap.com/images/car.png',// 为了不让小车压到路面,为其设置偏移量offset:new AMap.Pixel(-26,-13),// 小车在转弯的时候自动转头autoRotation:true,// 小车初始的摆放角度angle:-180,})// 构造折线变量var passedPolyline=new AMap.Polyline({map:map,strokeColor:'#AF5',strokeWeight:6,})// 监听小车移动事件,根据移动事件为折线变量设置路径marker.on('moving',function(e){passedPolyline.setPath(e.passedPath);})map.setFitView();// 让地图自适应marker.moveAlong(lineArr,{duration:500,//更新频率autoRotation:true,})}else{console.log('error');}})})
}

上面案例的完整代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>智慧校园</title><!-- 引入高德地图相关的CSS资源 --><link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" /><style>html,body,#container{width: 100%;height: 100%;}</style><!-- 引入高德js相关的资源 --><!-- 密钥和key --><script type="text/javascript">window._AMapSecurityConfig = {securityJsCode: "9497fb6552130d5d26e90c0c1082ca2a",};</script><script src="https://webapi.amap.com/loader.js"></script><script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=85aaa8a9d92f5a244271e3bc7494072f"></script><script src="./js/store.js"></script>
</head>
<body>//创建地图容器<div id="container"></div><!-- 高德地图css中自带有info样式 --><div class="info">点击地图,可标注地点;点击地点,可以打卡</div><!-- 高德css模板 --><div class="input-card" style="width: 17rem"><h4>推荐浏览路线</h4><div class="input-item"><button class="btn" onclick="starts()">开始动画</button></div></div>
</body>
<script>//创建地图对象var map=new AMap.Map('container',{center:[118.91125,32.10296],zoom:16,viewMode:'3D',pitch:45,})//使用地图控件AMap.plugin(['AMap.ToolBar','AMap.Scale','AMap.ControlBar','AMap.GeoJSON','AMap.MoveAnimation'],function(){map.addControl(new AMap.ToolBar({position:{top:'80px',right:'40px',},}));map.addControl(new AMap.Scale());map.addControl(new AMap.ControlBar());})// 定义一个全局变量,保存geojsonvar geojson = new AMap.GeoJSON({geoJSON:null,})// 导入数据,当数据为空的时候,会报错,所以在数据不为空的时候才导入// 因为getData()返回的是对象,所以需要先将其转为字符串,判断其是否为空字符串,即空数组if(JSON.stringify(getData())!='[]'){geojson.importData(getData())// 将得到的对象导入geojson文件中// 恢复旧数据的点击事件:拿到geojson数据中的每一个点,对拿到的每一个点(覆盖物)设置点击监听(随着点击事件的发生,调用后面的函数)geojson.eachOverlay(function(item){item.on('click',function(e){var ext=item.getExtData();var click = ++ext._geoJsonProperties.click;var infowindow=new AMap.InfoWindow({anchor:'top-center',content:`<div>打卡了${click}次</div>`,})infowindow.open(map,item.getPosition());saveData(geojson.toGeoJSON())})})}// 将导入的数据添加到地图上面;这样,刷新浏览器的时候数据就不会消失map.add(geojson);   //实现点击某个地方的标注效果,即监听地图的点击事件,当点击时调用函数map.on('click',function(e){var marker=new AMap.Marker({position:e.lnglat,extData:{// 自定义属性_geoJsonProperties:{gid:geojson.getOverlays().length+1,click:0,}}})// 使用覆盖物的点击事件:实现对新旧点击事件标记打卡marker.on('click',function(e){var ext=marker.getExtData();// 先得到属性var click = ++ext._geoJsonProperties.click;// 使用信息提示框显示打卡信息var infowindow=new AMap.InfoWindow({anchor:'top-center',//提示框显示的位置content:`<div>打卡了${click}次</div>`,})//显示窗口信息:在地图上的marker上显示信息infowindow.open(map,marker.getPosition());saveData(geojson.toGeoJSON());//将新数据重新保存;因为没有保存读取数据的时候还是原来的值})// 通过geojson来管理覆盖物geojson.addOverlay(marker);// 保存数据(将geojson对象转换成标准的GeoJSON格式对象)saveData(geojson.toGeoJSON())map.add(marker);})function starts(){AMap.plugin('AMap.Driving',function(){var driving =new AMap.Driving({map:map,// policy:AMap.DrivingPolicy.LEAST_TIME,policy:2,})// 设置起点和终点var st=new AMap.LngLat(118.903607, 32.096752);var end=new AMap.LngLat(118.918165, 32.098677);// 通过geojson得到每一个点的坐标var obs={waypoints:[],}geojson.eachOverlay(function(item){obs.waypoints.push(item.getPosition());})// 将点的对象传入driving.search(st,end,obs,function(status,result){if(status=='complete'){// 路径规划成功,则接下来实现动画效果// console.log(result);var lineArr=[];result.routes[0].steps.forEach(function(item){lineArr.push(...item.path);//遍历路线的每一个步骤,将其路径展开放入lineArr中})// console.log(lineArr);//首先设置小车标记的起始位置var marker=new AMap.Marker({map:map,position:st,icon:'https://webapi.amap.com/images/car.png',// 为了不让小车压到路面,为其设置偏移量offset:new AMap.Pixel(-26,-13),// 小车在转弯的时候转头autoRotation:true,angle:-180,})// 构造折线对象var passedPolyline=new AMap.Polyline({map:map,strokeColor:'#AF5',strokeWeight:6,})// 监听小车移动事件,根据折线事件来建立移动轨迹marker.on('moving',function(e){passedPolyline.setPath(e.passedPath);})map.setFitView();// 让地图自适应marker.moveAlong(lineArr,{duration:500,//更新频率autoRotation:true,})}else{console.log('error');}})})}</script>
</html>

js代码

// 从Localstorage中读取数据
function getData(){//如果本地local storage中不存在数据if(!localStorage.getItem('geojson')){//设置一个空的初始数据,即数据初始化localStorage.setItem('geojson','[]')}//反之,因为localStorage中存放的是字符串数据,所以将字符串数据转换成JSON对象返回return JSON.parse(localStorage.getItem('geojson'))
}// 将数据保存到Localstorage中
function saveData(data){//需要将数据转换成字符串类型才能存入localStorage中localStorage.setItem('geojson',JSON.stringify(data))
}

本文参考的学习视频:GIS | 零基础入门WebGIS开发,《智慧校园》项目实战

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

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

相关文章

【笔记】深度学习模型评估指标

推荐链接&#xff1a; &#xff08;0&#xff09;多分类器的评价指标 &#xff08;1&#xff09;泛化误差的评价方法&#xff1a;【机器学习】模型评估与选择&#xff08;留出法、交叉验证法、查全率、查准率、偏差、方差&#xff09; &#xff08;2&#xff09;机器学习&…

Linux运维常见命令

vi/vim快捷键使用 1)拷贝当前行 yy ,拷贝当前行向下的5行 5yy&#xff0c;并粘贴&#xff08;输入p&#xff09;。 2)删除当前行 dd ,删除当前行向下的5行5dd 3)在文件中查找某个单词 [命令行下 /关键字&#xff0c;回车查找 ,输入n就是查找下一个 ] 4)设置文件的行号&…

评估大语言模型在药物基因组学问答任务中的表现:PGxQA

​这篇文献主要介绍了一个名为PGxQA的资源&#xff0c;用于评估大语言模型&#xff08;LLM&#xff09;在药物基因组学问答任务中的表现。 研究背景 药物基因组学&#xff08;Pharmacogenomics, PGx&#xff09;是精准医学中最有前景的领域之一&#xff0c;通过基因指导的治疗…

AI芯片常见概念

文章目录 AI芯片常见概念前言常见概念AI芯片分类按照芯片的技术架构分GPU半定制化的 FPGA全定制化 ASIC神经拟态芯片 按应用场景分训练卡推理卡 按部署位置分国产AI卡资料汇总 AI芯片算力和能效比AI芯片算力AI芯片能效比 封装相关Chiplet技术3DIC三星多芯片集成联盟&#xff08…

SpringBoot中使用AOP切面编程实现登录拦截

使用AOP切面编程实现登录拦截 1. 首先实现一个登录注册功能 以下代码仅供参考 控制层 RestController RequestMapping("/user") public class UserController {Autowiredprivate UserService userService;PostMapping("/register")public Result regis…

重温设计模式--享元模式

文章目录 享元模式&#xff08;Flyweight Pattern&#xff09;概述享元模式的结构C 代码示例1应用场景C示例代码2 享元模式&#xff08;Flyweight Pattern&#xff09;概述 定义&#xff1a; 运用共享技术有效地支持大量细粒度的对象。 享元模式是一种结构型设计模式&#xff0…

用python ollama qwen2.5 开发一个AI修仙游戏

用 Python Ollama (Qwen2.5) 开发一个 AI 修仙游戏 简介 本文将介绍如何使用 Python 和 Ollama (Qwen2.5 模型) 开发一个文字版修仙游戏。这个游戏具有以下特点&#xff1a; 完整的修仙世界观和成长体系基于 AI 生成的动态剧情和事件丰富的物品系统(功法、丹药、灵宝等)社交…

【网络安全】网站常见安全漏洞—服务端漏洞介绍

文章目录 网站常见安全漏洞—服务端漏洞介绍引言1. 第三方组件漏洞什么是第三方组件漏洞&#xff1f;如何防范&#xff1f; 2. SQL 注入什么是SQL注入&#xff1f;如何防范&#xff1f; 3. 命令执行漏洞什么是命令执行漏洞&#xff1f;如何防范&#xff1f; 4. 越权漏洞什么是越…

Linux驱动开发 IIC I2C驱动 编写APP访问EEPROM AT24C02

在嵌入式开发中&#xff0c;I2C&#xff08;Inter-Integrated Circuit&#xff09;是一种常用的串行通信协议&#xff0c;广泛应用于与外设&#xff08;如 EEPROM、传感器、显示屏等&#xff09;进行数据交换。AT24C02 是一种常见的 I2C EEPROM 存储器&#xff0c;它提供 2Kbit…

HDR视频技术之十一:HEVCH.265 的 HDR 编码方案

前文我们对 HEVC 的 HDR 编码优化技术做了介绍&#xff0c;侧重编码性能的提升。 本章主要阐述 HEVC 中 HDR/WCG 相关的整体编码方案&#xff0c; 包括不同应用场景下的 HEVC 扩展编码技术。 1 背景 HDR 信号一般意味着使用更多比特&#xff0c;一般的 HDR 信号倾向于使用 10…

linux普通用户使用sudo不需要输密码

1.root用户如果没有密码&#xff0c;先给root用户设置密码 sudo passwd root #设置密码 2.修改visudo配置 su #切换到root用户下 sudo visudo #修改visudo配置文件 用户名 ALL(ALL) NOPASSWD: ALL #下图所示处新增一行配置 用户名需要输入自己当前主机的用户名

【时间之外】IT人求职和创业应知【74】-运维机器人

目录 OpenAI最强推理模型o3发布&#xff0c;AGI测试能力暴涨 英伟达宣布收购以色列AI初创企业Runai 汤姆猫首款AI机器人产品明日发售 心勿贪&#xff0c;贵知足。 感谢所有打开这个页面的朋友。人生不如意&#xff0c;开越野车去撒野&#xff0c;会害了自己&#xff0c;不如…

C#调用WebService的方法

一、前言 在日常工作中&#xff0c;如果涉及到与第三方进行接口对接&#xff0c;有的会使用WebService的方式&#xff0c;这篇文章主要讲解在.NET Framework中如何调用WebService。 1.创建WebService &#xff08;1&#xff09;新建项目——模板选择ASP.NET Web 应用程序 &a…

Qt creator ,语言家功能缺失解决方法

1、找到工具->外部->配置 2、添加目录&#xff0c;双击命名语言家 3、在语言家目录下&#xff0c;添加工具 双击重命名lupdate&#xff0c;即更新翻译 %{CurrentDocument:Project:QT_INSTALL_BINS}\lupdate%{CurrentDocument:Project:FilePath}%{CurrentDocument:Projec…

Taro小程序开发性能优化实践

我们团队在利用Taro进行秒送频道小程序的同时&#xff0c;一直在探索性能优化的最佳实践。随着需求的不断迭代&#xff0c;项目中的性能问题难免日积月累&#xff0c;逐渐暴露出来影响用户体验。适逢双十一大促&#xff0c;我们趁着这个机会统一进行了Taro性能优化实践&#xf…

springboot471基于协同过滤算法商品推荐系统(论文+源码)_kaic

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装协同过滤算法商品推荐系统软件来发挥其高效地信息处理的作用…

进程间关系与守护进程

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 进程间关系与守护进程 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. 进程组 什…

【NLP 16、实践 ③ 找出特定字符在字符串中的位置】

看着父亲苍老的白发和渐渐老态的面容 希望时间再慢一些 —— 24.12.19 一、定义模型 1.初始化模型 ① 初始化父类 super(TorchModel, self).__init__()&#xff1a; 调用父类 nn.Module 的初始化方法&#xff0c;确保模型能够正确初始化。 ② 创建嵌入层 self.embedding n…

javaEE-多线程编程-3

目录 java 常见的包 : 回调函数: 什么是线程: 第一个线程: 验证多线程执行: 内核: 调用sleep()方法: 执行结果分析: 线程创建的几种方式: 1.继承Thread类,重写run()方法. 2.实现Runnable接口,重写run()方法. 3.继承Thread类,重写run()方法.但使用匿名内部类 4.实现…

怎么在idea中创建springboot项目

最近想系统学习下springboot&#xff0c;尝试一下全栈路线 从零开始&#xff0c;下面将叙述下如何创建项目 环境 首先确保自己环境没问题 jdkMavenidea 创建springboot项目 1.打开idea&#xff0c;选择file->New->Project 2.选择Spring Initializr->设置JDK->…