共享单车之数据可视化

文章目录

  • 第1关:绘制地图
  • 第2关:绘制流量最高的五条线路的路程图


第1关:绘制地图

任务描述
本关任务:使用JSP在百度地图上绘制一条共享单车起始路程。

相关知识
为了完成本关任务,你需要掌握:

如何创建地图实例;
如何在地图上绘制路程线。
创建地图实例
我们需要先在jsp中引入百度地图api。

myMap
引入之后我们便可使用api中BMap对象来创建地图实例:

经过上述设置我们访问jsp则为如下效果:

在地图上绘制路径线
首先我们需要绘制路径必须知道起始点的经纬度及终点的经纬度才能够绘制成线,现提供起始点经纬度为(116.44516,39.925338),终点经纬度为(116.403838,39.919141),通过这两个点来绘制路径线:

var start_longitude=116.44516;//开始经度
var start_latitude=39.925338;//开始纬度
var stop_longitude=116.403838;//结束经度
var stop_latitude=39.919141;//结束纬度
var polyline = new BMap.Polyline([
new BMap.Point(start_longitude, start_latitude),
new BMap.Point(stop_longitude, stop_latitude)
],{strokeColor:“red”,strokeWeight:3,strokeOpacity:0.5});//创建一条宽度为3外边框透明度为0.5的红色线
map.addOverlay(polyline);//将线添加到地图上
效果如下:

给路程线设置标注和添加箭头
上图可以看到路程,但只有一条线并无法详细的向我们展示信息,因此我们可以通过给路程线添加标注位置和方向箭头。

添加标注
var address=“北京市朝阳区朝外街道三丰里社区”;
var marker = new BMap.Marker(new BMap.Point(start_longitude,start_latitude)); //创建开始位置标注
var label = new BMap.Label(address, {offset: new BMap.Size(20, 0)});//给标注设置文字描述
marker.setLabel(label);//将文字描述设置到标注上
map.addOverlay(marker);//将标注添加到地图中
通过鼠标滚轮将地图放大,可得到如下效果:

绘制箭头

上图中,线段AB是路程线,只要绘制出CBD就可以实现箭头效果,为了灵活绘制箭头,需要用户自定义箭头的长度(r)和角度(angle)。
实现步骤如下:
变量定义:pixelStart(路程线起点坐标)、pixelEnd(路程线终点坐标)、r:(单位像素,并不是CB对应的箭头的长度,而是橘色线段对应的距离)、angle:箭头线((CB或者DB)与AB的夹角),函数定义为addArrow(polyline,r,angel):

首先要将AB两点的经纬度坐标转化成屏幕坐标
然后根据AB两点屏幕坐标以及r长度,计算绿色小绿点的屏幕坐标pixelTem。
再根据B点、小绿点的屏幕坐标及angle角度,计算出C,D两点的屏幕坐标
利用map的坐标转换方法,将C,D两点的屏幕坐标转成经纬度表示的坐标。
利用画线方法,绘制CBD折线。
代码我们已为你提供,在右侧任务代码中addArrow函数中体现。

编程要求
在右侧编辑器补充代码,绘制出一条河北省保定市雄县(经纬度为116.10,38.98)一共享单车使用的路程线,具体信息如下:

起点经纬度为(39.04607,116.233093);
终点经纬度为(39.041691,116.235352);
要求设置路程线为红色,宽度为3,透明度为0.5;
给起点和终点都创建标注,描述起点为乡里乡情铁锅炖南228米,终点为擎天矿用材料有限公司北609米,要求设置的字体大小为20
调用提供绘制箭头函数addArrow函数添加r=10,angle=Math.PI/7的箭头。
注意:直接使用已定义的变量,且已定义的变量名不要私自修改。

最终实现效果如下:

测试说明
平台会对你编写的代码进行测试:

测试输入:无
预期输出:测试通过

开始你的任务吧,祝你成功!

示例代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><style type="text/css">body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;}</style><script type="text/javascript" src="http://api.map.baidu.com/api?v=1.4"></script><title>step1</title>
</head>
<body>
<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">var map = new BMap.Map("allmap");// 创建地图实例var point = new BMap.Point(116.10 ,38.98);// 创建点坐标map.centerAndZoom(point, 13);//设初始化地图。 如果center类型为Point时,zoom必须赋值,范围3-19级,若调用高清底图(针对移动端开发)时,zoom可赋值范围为3-18级。如果center类型为字符串时,比如“北京”,zoom可以忽略,地图将自动根据center适配最佳zoom级别map.addControl(new BMap.NavigationControl());//缩放平移控件map.enableScrollWheelZoom();//利用鼠标滚轮控制大小var start_longitude=116.233093;//开始经度var start_latitude=39.04607;//开始纬度var stop_longitude=116.235352;//结束经度var stop_latitude=39.041691;//结束纬度var address=["乡里乡情铁锅炖南228米","擎天矿用材料有限公司北609米"];/**********  Begin  **********///1.初始化路程线var polyline = new BMap.Polyline([new BMap.Point(start_longitude, start_latitude),new BMap.Point(stop_longitude, stop_latitude)], {strokeColor:"red", strokeWeight:3, strokeOpacity:0.5});//2.将线添加到地图上map.addOverlay(polyline);//3.调用绘制箭头线函数addArrow(polyline,10,Math.PI/7);//4.设置起始点标注var marker = new BMap.Marker(new BMap.Point(start_longitude,start_latitude));var label = new BMap.Label(address[0],{offset: new BMap.Size(20, 0)});marker.setLabel(label);map.addOverlay(marker);var marker = new BMap.Marker(new BMap.Point(stop_longitude,stop_latitude));var label = new BMap.Label(address[1], {offset: new BMap.Size(20, 0)});marker.setLabel(label);map.addOverlay(marker);/**********  End  **********///绘制箭头的函数function addArrow(polyline,r,angle){var linePoint=polyline.getPath();//线的坐标串(里面存的就是起始点的坐标点)var arrowCount=linePoint.length;for(var i =1;i<arrowCount;i++){ //在拐点处绘制箭头var pixelStart=map.pointToPixel(linePoint[i-1]);var pixelEnd=map.pointToPixel(linePoint[i]);var pixelTemX,pixelTemY;//临时点坐标var pixelX,pixelY,pixelX1,pixelY1;//定义箭头两个点坐标var delta=(pixelEnd.y-pixelStart.y)/(pixelEnd.x-pixelStart.x);//主线斜率,垂直时无斜率var param=Math.sqrt(delta*delta+1);//代码简洁考虑if((pixelEnd.x-pixelStart.x)<0){ //第二、三象限pixelTemX=pixelEnd.x+ r/param;pixelTemY=pixelEnd.y+delta*r/param;}else{ //第一、四象限pixelTemX=pixelEnd.x- r/param;pixelTemY=pixelEnd.y-delta*r/param;}//已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法pixelX=pixelTemX+ Math.tan(angle)*r*delta/param;pixelY=pixelTemY-Math.tan(angle)*r/param;pixelX1=pixelTemX- Math.tan(angle)*r*delta/param;pixelY1=pixelTemY+Math.tan(angle)*r/param;var pointArrow=map.pixelToPoint(new BMap.Pixel(pixelX,pixelY));var pointArrow1=map.pixelToPoint(new BMap.Pixel(pixelX1,pixelY1));var Arrow = new BMap.Polyline([pointArrow,linePoint[i],pointArrow1], {strokeColor:"blue", strokeWeight:3, strokeOpacity:0.5});map.addOverlay(Arrow);return Arrow;}}
</script>

在这里插入图片描述

第2关:绘制流量最高的五条线路的路程图

任务描述
本关任务:在地图上绘制共享单车中流量最高的五条路线的路程。

相关知识
本实训数据基于共享单车之数据分析最后一关的数据(流量最高的五条数据)。

为了完成本关任务,你需要掌握:

如何在后台传数据给JSP页面;
JSP页面中如何获取后台传的数据;
如何在地图上绘制多条路程线。
如何在后台传数据给JSP页面
我们可以通过直接访问servlet在其doGet或doPost方法中将值传递到jsp中,示例如下:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute(“key”,“value”);//以键值对的形势存值
request.getRequestDispatcher(“index.jsp”).forward(request,response);//使用转发将数据带到页面中
}
JSP获取后台传过来的数据

但若传的数据类型为集合,则直接获取会被当成字符串,因此需要做一些数据处理,如:

List list=new ArrayList<>();
list.add(“abc”);
list.add(“ABC”);
request.setAttribute(“key”,list);

如何在地图上绘制多条路程线
上一章节我们学习了如何绘制一条路程线,现在我们要绘制多条,本质上是一样的操作,只需将后端获取的数据进行循环遍历即可:

为了方便存取数据,我们将之前章节中HbaseUtil类中用来扫描表显示结果的scanTable方法做了修改,改为将流量最高的五条路程线数据存到了自定义的BickMap对象中,(上诉的相关类和方法都可在右侧文件夹中进行查看)具体操作如下:

servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BickMap bickMap = HBaseUtil.scanTable();//获取存进去的五条数据
for (String key : bickMap.getKeys()) {
request.setAttribute(key,bickMap.get(key));//遍历将最高五条流量的数据以“字段名-结果集合”形式传到后台
}
request.getRequestDispatcher(“step2.jsp”).forward(request,response);
}
jsp

编程要求
在右侧编辑器补充代码,绘制流量最高的五条数据的路程线,具体要求如下:

在servlet中将字段名为key,bickMap.get(key)为value作为键值对方式传值给jsp;
绘制路程线样式为红色,宽度为3,透明度为0.5;
调用提供绘制箭头函数addArrow,绘制以r=10,angle=Math.PI/7的箭头;
绘制起始地点的标注信息,文字大小仍为20。
最终实现效果如下:

注意:为了方便测试,右侧编辑器中已有的变量名请勿私自改动。

测试说明
平台会对你编写的代码进行测试:

测试输入:无
预期输出:测试通过

开始你的任务吧,祝你成功!

说点什么
示例代码如下:
在该位置选择代码文件
在这里插入图片描述
BickMapServlet:

package com.educoder.servlet;
import com.educoder.util.HBaseUtil;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class BickMapServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");/**********   Begin   **********///1.通过HbaseUtil类获取数据BickMap bickMap =HBaseUtil.scanTable();//2.遍历将数据以键值对的方式传给jspfor (String key : bickMap.getKeys()) {request.setAttribute(key, bickMap.get(key));}/**********   End    **********/request.getRequestDispatcher("step2.jsp").forward(request,response);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}
}

step2.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><style type="text/css">body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;}</style><script type="text/javascript" src="http://api.map.baidu.com/api?v=1.4"></script><title>step2</title>
</head>
<body>
<div id="allmap"></div>
</body>
</html>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">var map = new BMap.Map("allmap");// 创建地图实例var point = new BMap.Point(116.10 ,38.98);// 创建点坐标map.centerAndZoom(point, 13);//设初始化地图。 如果center类型为Point时,zoom必须赋值,范围3-19级,若调用高清底图(针对移动端开发)时,zoom可赋值范围为3-18级。如果center类型为字符串时,比如“北京”,zoom可以忽略,地图将自动根据center适配最佳zoom级别map.addControl(new BMap.NavigationControl());//缩放平移控件map.enableScrollWheelZoom();//利用鼠标滚轮控制大小/**********   Begin  **********///1.获取后台传过来的数据 调用已写好的change函数清理数据var start_longitude = change('<%=request.getAttribute("start_longitude") %>');var start_latitude = change('<%=request.getAttribute("start_latitude") %>');var stop_longitude = change('<%=request.getAttribute("stop_longitude") %>');var stop_latitude = change('<%=request.getAttribute("stop_latitude") %>');var start_address = change('<%=request.getAttribute("start_address") %>');var stop_address = change('<%=request.getAttribute("stop_address") %>');//2.初始化路程线for (var i=0;i<start_latitude.length;i++){var polyline = new BMap.Polyline([new BMap.Point(start_longitude[i], start_latitude[i]),new BMap.Point(stop_longitude[i], stop_latitude[i])], {strokeColor:"red", strokeWeight:3, strokeOpacity:0.5});//3.将线添加到地图上map.addOverlay(polyline);//4.调用绘制箭头线函数addArrow(polyline,10,Math.PI/7);//5.设置起始点标注var marker = new BMap.Marker(new BMap.Point(start_longitude[i],start_latitude[i]));var label = new BMap.Label(start_address[i],{offset: new BMap.Size(20, 0)});marker.setLabel(label);map.addOverlay(marker);var marker = new BMap.Marker(new BMap.Point(stop_longitude[i],stop_latitude[i]));var label = new BMap.Label(stop_address[i], {offset: new BMap.Size(20, 0)});marker.setLabel(label);map.addOverlay(marker);}/**********   End   **********///数据转化函数function change(obj) {obj = obj.substring(1,obj.length - 1).split(",");return obj;}//绘制箭头的函数function addArrow(polyline,r,angle){var linePoint=polyline.getPath();//线的坐标串(里面存的就是起始点的坐标点)var arrowCount=linePoint.length;for(var i =1;i<arrowCount;i++){ //在拐点处绘制箭头var pixelStart=map.pointToPixel(linePoint[i-1]);var pixelEnd=map.pointToPixel(linePoint[i]);var pixelTemX,pixelTemY;//临时点坐标var pixelX,pixelY,pixelX1,pixelY1;//定义箭头两个点坐标var delta=(pixelEnd.y-pixelStart.y)/(pixelEnd.x-pixelStart.x);//主线斜率,垂直时无斜率var param=Math.sqrt(delta*delta+1);//代码简洁考虑if((pixelEnd.x-pixelStart.x)<0){ //第二、三象限pixelTemX=pixelEnd.x+ r/param;pixelTemY=pixelEnd.y+delta*r/param;}else{ //第一、四象限pixelTemX=pixelEnd.x- r/param;pixelTemY=pixelEnd.y-delta*r/param;}//已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法pixelX=pixelTemX+ Math.tan(angle)*r*delta/param;pixelY=pixelTemY-Math.tan(angle)*r/param;pixelX1=pixelTemX- Math.tan(angle)*r*delta/param;pixelY1=pixelTemY+Math.tan(angle)*r/param;var pointArrow=map.pixelToPoint(new BMap.Pixel(pixelX,pixelY));var pointArrow1=map.pixelToPoint(new BMap.Pixel(pixelX1,pixelY1));var Arrow = new BMap.Polyline([pointArrow,linePoint[i],pointArrow1], {strokeColor:"blue", strokeWeight:3, strokeOpacity:0.5});map.addOverlay(Arrow);return Arrow;}}
</script>

在这里插入图片描述


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

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

相关文章

进阶学习——Linux系统服务器硬件认识与RAID磁盘

目录 一、服务器知识补充 1.硬件 2.服务器常见故障 二、认识RAID 1.什么是RAID 2.RAID的优点 3.RAID的实现方式 三、RAID磁盘陈列 1.RAID 0 磁盘陈列介绍——RAID 0 2.RAID 1 磁盘陈列介绍——RAID 1 3.RAID 5 磁盘陈列介绍——RAID 5 4.RAID 6 磁盘陈列介绍——RA…

vr体验馆用什么软件计时计费,如遇到停电软件程序如何恢复时间

vr体验馆用什么软件计时计费&#xff0c;如遇到停电软件程序如何恢复时间 一、软件程序问答 如下图&#xff0c;软件以 佳易王vr体验馆计时计费软件V17.9为例说明 1、软件如何计时间&#xff1f; 点击相应编号的开始计时按钮即可 2、遇到停电再打开软件时间可以恢复吗&…

【开源】基于Vue+SpringBoot的公司货物订单管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 客户管理模块2.2 商品维护模块2.3 供应商管理模块2.4 订单管理模块 三、系统展示四、核心代码4.1 查询供应商信息4.2 新增商品信息4.3 查询客户信息4.4 新增订单信息4.5 添加跟进子订单 五、免责说明 一、摘要 1.1 项目…

Redis经典五大类型源码及底层实现(一)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

Linux CPU 数据 Metrics 指标解读

过去从未仔细了解过使用 top 和 htop 等命令时显式的CPU信息&#xff0c;本文我们详解解读和标注一下各个数据项的含义&#xff0c;同时和 Ganglia 显式的数据做一个映射。开始前介绍一个小知识&#xff0c;很多查看CPU的命令行工具都是 cat /proc/stat 里的数据&#xff0c;所…

Spring-6-事务管理

事务是构建可靠企业级应用程序的最关键部分之一。 最常见的事务类型是数据库操作。 在典型的数据库更新操作中&#xff0c;首先数据库事务开始&#xff0c;然后数据被更新&#xff0c;最后提交或回滚事务(根据数据库操作的结果而定)。但是&#xff0c;在很多情况下&#xff0…

java中的缓冲类HeapByteBuffer和DirectByteBuffer的区别

使用之前写的文章里的例子 https://blog.csdn.net/zlpzlpzyd/article/details/135292683 HeapByteBuffer import java.io.File; import java.io.FileInputStream; import java.io.Serializable; import java.nio.ByteBuffer; import java.nio.channels.FileChannel;public clas…

【hcie-cloud】【12】华为云Stack故障处理【故障处理通用处理原则、常见华为云Stack故障处理(计算域故障场景)】【上】

文章目录 前言故障处理通用处理原则故障处理流程故障信息收集及故障范围、类型识别ManageOne运维面收集告警信息AutoOps工具故障场景信息收集AutoOps工具自动化采集HCS信息 (1)AutoOps工具自动化采集HCS信息 (2)故障初期定位方向故障恢复例行维护讨论: 哪一环比较重要&#xff…

关于表格太大了jupyter无法单次处理的问题

记录下自己的心路历程…耗时耗精力 我用的数据库单个表格就很大&#xff0c;一个表格有30多G&#xff0c;jupyter无法处理这么大的表格&#xff0c;会直接把电脑的进程全部结束掉&#xff0c;结束掉要是能运行成功倒也行啊&#xff0c;然鹅…给我报错说处理不了&#xff0c;罢工…

【SpringCloud】从实际业务问题出发去分析Eureka-Server端源码

文章目录 前言1.EnableEurekaServer2.初始化缓存3.jersey应用程序构建3.1注册jeseryFilter3.2构建JerseyApplication 4.处理注册请求5.registry&#xff08;&#xff09; 前言 前段时间遇到了一个业务问题就是k8s滚动发布Eureka微服务的过程中接口会有很多告警&#xff0c;当时…

next.js 开发网站的hello world

本文介绍建立一个简单的next.js 工程&#xff0c;以及简单修改。然后也简单说了2种路由方式的选择。 开始next.js工程前需要node.js &#xff0c; 还需要编辑器&#xff0c;我这里选择的是visual code。如果没有安装node.js 请参考下&#xff1a; visual code 下的node.js的he…

PathWave Device Modeling (IC-CAP) 建模系统——IC-CAP概述

建模系统 PathWave Device Modeling&#xff08;IC-CAP&#xff09;建模系统用于测量半导体器件并分析器件的电路建模特性以及分析所得数据。 要使用PathWave Device Modeling&#xff08;IC-CAP&#xff09;&#xff0c;您需要以下设置&#xff1a; 一台工作站执行直流、电…

今年近三万人报考北大研究生,最高学费80多万!

全国硕士研究生招生考试已经接近尾声&#xff0c;今年总共有近3万名考生报考北京大学硕士研究生。而北大计划招生的研究生是7349人&#xff0c;按这个比例计算的话相当于4:1&#xff0c;也就是平均 4 个人当中会有一个人被录取&#xff0c;我感觉这比高考容易多了。 2023年北大…

基于ElementUI二次封装el-table与el-pagination分页组件[实际项目使用]

效果&#xff1a; 二次封装el-table组件 <template><div><!-- showHeader:是否显示头部size:表格的大小height:表格的高度isStripe:表格是否为斑马纹类型tableData:表格数据源isBorder:是否表格边框handleSelectionChange:行选中&#xff0c;多选内容发生变化回…

Zama TFHE-rs白皮书(2)

前序博客有&#xff1a; 基于[Discretized] Torus的全同态加密指引&#xff08;1&#xff09;基于[Discretized] Torus的全同态加密指引&#xff08;2&#xff09;TFHE——基于[Discretized] Torus的全同态加密 代码解析Zama TFHE-rsZama TFHE-rs白皮书&#xff08;1&#xff…

推荐系统/电商中的 业务指标GMV

GMV&#xff08;Gross Merchandise Volume&#xff09;是指在一定时间内&#xff0c;一个电商平台上所有商品的总销售价值&#xff0c;通常以货币单位&#xff08;例如美元、人民币等&#xff09;表示。GMV是一个关键的电商业务指标&#xff0c;用于衡量平台的交易规模和业务增…

Linux:apache优化(5)—— 隐藏版本号

防盗链&#xff1a;就是防止别人盗取你们公司的图片、文件、视频 作用&#xff1a;防盗链就是防止别人盗用服务器中的图片、文件、视频等相关资源。运维人员可以通过apache提供rewrite模块进行优化。 配置项&#xff1a; RewriteEngine ON ##打开网页重写功能 RewriteCond …

修改源码,element的el-table合并,处理合并产生的hover样式问题

1、确认自己element-ui的版本号 2、此element-ui下的lib包是修改过hover样式的包,如何替换自己文件下的node_modules中的包 修改后将lib文件夹中文件替换你项目中/node_module/element-ui/Lib中的文件问题??如果替换开发环境中的node_module的包无法升级到测试环境,因为nod…

联合办公靠谱吗?

提起联合办公&#xff0c;许多人可能会想到喧嚣的开放式办公区、精巧的咖啡吧台以及随处可见的共享会议室。随着工作模式的更新迭代&#xff0c;联合办公无疑已经成为了现代办公室文化的热门趋势。但面对这种浪潮&#xff0c;不少人仍然保持着观望的态度&#xff0c;不免产生疑…

无表情包不MEME,PADD 最具潜力的BRC20 meme

BRC20 出圈&#xff0c;PADD 埋伏正当时 近期&#xff0c;市场向好&#xff0c;BRC20 在一定程度上推动了牛市的进程&#xff0c;基于BRC20的生态正在蓬勃发展&#xff0c;meme coin 已经成为生态中不可或缺的一部分&#xff01; 投资 meme coin 要的是以小博大&#xff0c;sat…