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,一经查实,立即删除!

相关文章

只谈C++11新特性 - 显式虚函数重写

显式虚函数重写 背景说明 在 C++11 之前,C++ 的虚函数机制虽然非常强大,但也带来了一些潜在问题。特别是对于大型代码库,当派生类需要重写基类的虚函数时,可能会因为疏忽而引入错误: 拼写错误:如果派生类的函数签名不完全匹配基类的虚函数签名,那么派生类的函数并不会…

MyBatisSQL优化

MyBatis 是一款流行的 Java 持久层框架&#xff0c;它简化了数据库操作&#xff0c;并且能够灵活地映射 Java 对象与数据库表之间的关系。在使用 MyBatis 进行数据库操作时&#xff0c;SQL 性能优化是至关重要的&#xff0c;特别是在面对复杂查询、大规模数据处理或高并发场景时…

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

推荐链接&#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…

【js】URL处理

背景 有这样子一个url&#xff0c;search部分的value可能包含空格&#xff0c;也可能是一个对象&#xff0c;如何正确解析这样子的url呢&#xff1f; search如下&#xff0c;?accountId144115188076933939&accountNamemock name&xxx {"accountId": "…

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

文章目录 享元模式&#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 生成的动态剧情和事件丰富的物品系统(功法、丹药、灵宝等)社交…

Android 常用布局

在Android中&#xff0c;ViewGroup是布局的基类&#xff0c;用于管理和组织其他视图。除了ViewGroup本身&#xff0c;还有一些其他的ViewGroup子类&#xff0c;它们提供了不同的布局和视图管理功能。以下是一些常见的ViewGroup子类&#xff1a; AdapterViewFlipper&#xff1a…

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

文章目录 网站常见安全漏洞—服务端漏洞介绍引言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…

NS3学习——队列管理机制

目录 1.介绍 2.被动式队列管理机制 2.1 优缺点 2.1.1 TCP全局同步现象 3.主动式队列管理机制 3.1 RED算法概述 3.2 RED具体算法 3.2.1 计算队列平均长度 3.2.2 计算丢弃包的概率 1.介绍 由于路由器是基于包交换的设备&#xff0c;为了处理多个数据包同时向同一端口…

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 #下图所示处新增一行配置 用户名需要输入自己当前主机的用户名

大语言模型中的Agent;常见的Agent开发工具或框架

大语言模型中的Agent 大语言模型中的Agent是指以大语言模型为核心驱动,具有自主理解、感知、规划、记忆和使用工具等能力,能够自动化执行复杂任务的系统.以下是一些例子: AutoGPT:它相当于一个完整的工具包,可以为各种项目构建和运行自定义AI Agent。使用OpenAI的GPT-4和…

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

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

Android10 rk3399 以太网接入流程分析

Netd守护进程服务 Netd模块是Android中专门负责网络管理和控制的后台守护进程开发板路径./etc/init/netd.rc service netd /system/bin/netdclass mainsocket dnsproxyd stream 0660 root inetsocket mdns stream 0660 root systemsocket fwmarkd stream 0660 root inetonres…

框架专题:反射

1. 什么是反射&#xff1f; 简单来说&#xff0c;反射是一种程序自省的能力&#xff0c;即在程序运行时动态地获取其结构信息或操作其行为。这包括类、方法、属性等元信息。反射的核心在于让代码变得更加动态化&#xff0c;从而突破静态语言的限制。 以Java为例&#xff0c;反…