相关数据素材等来源于达内教育的陈老师,仅供学习参考!!!
第一天
项目内容
一、统一开发环境
- JDK ,1.8;
- Tomcat ,8.5;
- Maven,3.5.2;
- eclipse;
- Mariadb,MySQL的社会版,也可以直接选择用MySQL;
二、地图用例分析
-
学习场景越接近真实应用场景,记忆越持久
-
需求:实现一个和纽约市官方地图用例一样的功能
解决方案:先进行功能的拆分
(1)在页面上显示一个纽约市地图
(2)在地图上显示一个图标
(3)在地图上显示所有站点的图标:站点经纬度
(4)使用不同的图标显示站点:站点的存车数据
(5)点击任意一个站点,弹出站点详细信息
(6)缩放级别改变时,自动切换图标的类型
(7)在地图上添加按钮,实现桩和车图标之间的切换 -
在页面上显示纽约市地图
想要实现在浏览器页面上显示地图,需要使用第三方的地图插件。国内比较流行的地图插件有:百度地图、高德地图、腾讯地图等。为什么用该地图插件? 组件的选型问题:要根据你当前应用的特点去选择最合适的组件。你需要了解备选的这些组件的特点。
本项目中使用的是百度地图的插件。 原因: 1. 本案例显示的是纽约市地图,高德地图和腾讯地图均不支持显示纽约市地图。 2. 本案例后续使用ECharts作为前端数据可视化插件,该插件是百度的开源项目,与百度地图插件可以无缝整合。
百度地图提供了开发者学习使用插件的教学网站 http://lbsyun.baidu.com/index.php?title=jspopular3.0。
(1)注册成为百度地图开发者
(2)获取了百度地图的密钥
(3)在Eclipse中创建nybike项目
(4)在nybike项目的webapp目录下创建一个firstmap.html文件
(5)复制百度地图提供的入门地图案: http://lbsyun.baidu.com/index.php?title=jspopular3.0/guide/helloworld的代码,覆盖firstmap.html中所有的内容
(6)修改firstmap.html第12行的内容,将"您的密钥"替换成之前申请到的百度地图密钥,并保存
(7)右键项目->Run As -> Run on Server -> Finish,将项目部署到Tomcat上
(8)在谷歌浏览器上访问http://localhost:8080/nybike/firstmap.html,查看第一个地图用例
需求:在webapp目录下创建nymap.html,在该页面中显示纽约市地图,以帝国大厦为中心,缩放级别使用14。<div id="container"></div> <script type="text/javascript"> // 创建地图实例,绑定容器的id var map = new BMap.Map("container"); //创建点坐标,先经度后纬度 var point = new BMap.Point(-73.985669, 40.748405); //初始化地图,设置中心点坐标和地图级别 map.centerAndZoom(point, 35); </scrpit>
需求1:在nybike.html上开启鼠标滚轮缩放,并添加一个“平移缩放控件”
需求2:让“平移缩放控件”在地图的右下角显示//开启鼠标滚轮缩放 map.enableScrollWheelZoom(true); //添加一个“平移缩放控件”,位于地图的右下角 /* anchor和offset属性共同控制控件在地图上的位置。 anchor表示控件的停靠位置,即控件停靠在地图的哪个角。 当地图尺寸发生变化时,控件会根据停靠位置的不同来调整自己的位置。 */ var bottom_right_navigation = new BMap.NavigationControl({ anchor: BMAP_ANCHOR_BOTTOM_RIGHT, type: BMAP_NAVIGATION_CONTROL_LARGE}); map.addControl(bottom_right_navigation);
-
在地图上显示一个标注(Marker)
需求1:在nybike.html中,在帝国大厦位置添加一个百度地图的默认Marker//给帝国大厦交百度默认标注 // 创建标注 var marker = new BMap.Marker(point); // 将标注添加到地图中 map.addOverlay(marker);
需求2:在帝国大厦西南方向的Tous Les Jours(法式糕点店)(40.7479,-73.9869)上添加一个默认Marker,要求将添加Marker的代码封装成一个独立的方法,方法名叫addMarker()
function addMarkerLocation(lon,lat){ //lon:经度;lat:纬度。 var point = new BMap.Point(lon,lat); var marker = new BMap.Marker(point); map.addOverlay(marker); } addMarkerLocation(40.7479,-73.9869);
将重复代码抽取成一个方法的步骤:
写一个最简单的方法
(1)将重复的代码复制到该方法中
(2)将变量以方法参数的形式添加到方法的参数列表中 -
在地图上显示所有站点的Marker
分析:需要所有站点的经纬度信息,可以通过官方的数据接口https://gbfs.citibikenyc.com/gbfs/en/station_information.json获取保存了所有站点信息的json文件
通过什么方式可以在页面中把数据拿回来?AJAX(见下文的补充知识)
-
使用一张自定义图片显示所有的站点Marker
nybike项目中引入所需的图片:将课前资料/2.前端组件及素材包/img文件夹直接拷贝到nybike项目的webapp目录下需求:查询百度地图API,将所有Marker的图片替换成img/bi_0.png
function addMarkerOnePic(lon,lat){ var iconOpts = { anchor: new BMap.Size(23, 12.5), imageSize:new BMap.Size(23,25), } var myIcon = new BMap.icon("img/bi_0.png",new BMap.Size(23,25)); var point = new BMap.Point(lon,lat); var marker = new BMap.Marker(point, {icon: myIcon}); map.addOverlay(marker); } var info_url = "https://gbfs.citibikenyc.com/gbfs/en/station_information.json"; $.get(info_url,function(infoData){ var stations = infoData.data.stations; var lon,lat; for(var index in stations){ info_station_id = stations[index].station_id; lon = stations[index].lon; lat = stations[index].lat; addMarker(lon,lat); } });
-
使用不同图片来显示站点
(1)确定标准nba:num_bikes_available nda:num_docks_available abi=nba/(nba+nda) 0:红色:nba==0||nba+nda==0 1:黄色:nba<8 2:少绿:abi<0.5 3:多绿:abi<1 4:全绿:abi==1
需求:在nybike.html中声明一个getBikeLevel()方法,使用nba和nda作为参数,返回该站点的bikeLevel
(1)获取站点状态数据
通过官方网址https://gbfs.citibikenyc.com/gbfs/en/station_status.json可以获取到所有站点的状态数据
(2)通过编程实现功能
需求:在nymap.html中通过ajax请求站点的状态数据,在浏览器控制台输出每个站点的id,nba,nda和bikeLevel
需求:通过全局变量bikeLevelMap<sid,bikeLevel>将计算得到的站点bikeLevel共享给addMarker()方法的调用者,在addMarker()方法中使用bikeLevel拼接生成图片的url。
-
在地图缩放级别改变时,将站点图标切换成对应level的小圆点
分析:
(1) 确定一个标准当缩放级别改变为XXX时,将大图标换成小图标 当缩放级别改变为XXX时,将小图标换成大图标
需求:获取当前地图的缩放级别
确定标准:
1. 当前缩放级别小于15时,如果正在使用大图标,应该切换为小图标 2. 当前缩放级别大于14时,如果正在使用小图标,应该切换为大图标
如何切换图标?
1. 删除地图上所有的Marker,循环调用之前的代码,为所有站点生成新的Marker,Marker生成时使用新的imageUrl 2. 遍历当前地图上所有的站点Marker,想办法替换Marker使用的Icon中的imageUrl,还需要替换Icon的Size,auchor,imageSize 3. 遍历当前地图上所有的站点Marker,为每个Marker生成一个新的Icon,使用新的Size,auchor,imageSize, imageUrl
随着开发的进行,nymap.html中的js越来越多,现在将所有声明的js方法保存到js/nymap.js文件中,并在nymap.html中引入该文件。
采用这种方式开发代码,在调试用例时,可能因为浏览器缓存了nymap.js文件,导致你修改的代码不会生效。如果出现类似问题,不要急着修改代码,在浏览器上使用Ctrl+Shift+Delete快捷键清空浏览器缓存,再重新调试。
在为Marker创建新的Icon时,需要获取该Marker对应的bikeLevel,才能选择合适的图片。解决方案有2种:
1. 在addMarker()方法中,为每一个新创建的Marker对象直接添加一个新的属性bikeLevel,其值就是它对应的bikeLevel,后续只要拿到marker对象,就能直接获取它对应的bikeLevel 2. 拿到一个Marker之后,可以通过方法获取Marker中的Icon中的imageUrl属性的值,该值中包含了该Marker对应的bikeLevel // img/bi0.png var old=marker.getIcon().imageUrl; // img/si0.png 这里可以使用字符串替换的方式生成新的url
拓展:目前代码中有频繁的创建对象操作,实际上这部分代码可以通过全局变量的方式来优化,可以尝试对代码进行优化
var bigBikeIconArr=[];//存放所有大图标 var smallIconArr=[];//存放所有小图标 function initIcon(){ for(var index=0;index<5;index++){ var iconOpts = { anchor: new BMap.Size(21, 50), imageSize:new BMap.Size(42, 50) } // 创建应用小图标的Icon对象 var myIcon1 = new BMap.Icon("img/bi_"+index+".png" , new BMap.Size(42, 50), iconOpts); bigBikeIconArr[index]=myIcon1; // 声明Icon的配置,其中使用小图标对应的配置 var iconOpts = { anchor: new BMap.Size(5, 10), imageSize:new BMap.Size(10, 10) } // 创建应用小图标的Icon对象 var myIcon2 = new BMap.Icon("img/si_"+index+".png" , new BMap.Size(10, 10), iconOpts); smallIconArr[index]=myIcon2; }
}
-
点击一个站点的marker时,弹出信息窗,里面显示的是站点的实际信息
该需求的实现可以拆分成2步:(1)点击站点,弹出信息窗,信息窗的样式和官方样式相似,内容信息是预制的(假的)。
(2)点击站点,信息窗的内容是该站点的实际信息(真的)。
百度地图为Marker添加信息窗的API:
var sContent="信息窗的实际内容,以html形式提供"; var infoWindow = new BMap.InfoWindow(sContent); // 创建信息窗口对象 marker.addEventListener("click", function(){ this.openInfoWindow(infoWindow); });
需求1:结合“前端组件及素材包”中的mapbox.html和page.css文件,为nymap.html的所有Marker添加点击事件,单击marker时弹出固定内容的信息窗。
需求2:点击每个Marker,弹出的信息窗的内容不同,为当前Marker的实际name,nba,nda和short_name。
在map.addOverlay(marker);前添加 var infoWindow = getInfoWindow(infoItem); marker.addEventListener("click", function(){ this.openInfoWindow(infoWindow); });
百度地图API的bug:marker.addEventListener()的代码必须在map.addOverlay(marker)之前调用,不然所有marker显示的信息窗都是同一个
思考:当前地图用例的响应时间较长,用户访问页面后需要等待几秒,如何优化这个响应时间?
-
对地图服务的响应速度进行优化
分析:找到慢的原因 1. 地图可以很快显示出来,但是站点无法快速显示出来 2. 请求第三方的实时站点状态数据和信息数据,平均耗时加在一起约600ms,让用户有等待,这部分可以优化解决方案:缓存
缓存
将常用的数据提前保存在内存中,供反复使用。缓存的本质是 硬盘 和 内存 在数据读取速度上的差异。
数据缓存在哪?
浏览器:用户第一次访问时等待,启动一个计时器,在浏览器后台定时请求第三方数据,自动刷新数据。方案可行。
如何解决第一次访问的等待问题?
可以靠服务器来解决
具体如何实现?
基于该方案,现在请求站点信息数据和状态数据的总耗时平均在150ms左右,减少了等待时间。
在该解决方案中,涉及到1个线程向缓存中写入数据,另外多个线程从缓存中读取数据,是否有线程安全问题?
如果有线程安全问题?该如何解决?
10 走进数据分析
需求:
1.纽约市当前还有多少个共享单车站点?
select count(*) from tb1;
2.纽约市共享单车可用车总数是多少?可用桩总数是多少?
select sum(nba),sum(nda) from tb1;
3.纽约市站点abi指数的值小于0.5的站点有多少?
select count(*) from tb1 where abi<0.5;
4.如果按0.1为1个区间,那么纽约市929个站点的abi指数,在各区间中有多少个站点?
select count(*) from tb1 group by abi保留1位小数求低值
现在,我们希望使用关系型数据库(Mysql/Mariadb)来保存一条站点状态数据,然后利用SQL语句对该数据进行分析。
现在有一个问题:原始数据是json格式的,而关系型数据库中的数据一般是csv格式的。
csv格式: 一行表头 一条数据 一条数据 一条数据 字段与字段之间使用逗号进行分割
现在我们要做的是使用Java语言从json格式数据中解析出我们要的数据,存入到关系型数据库中。
JSON解析
Java语言默认并不支持解析JSON数据,必须使用第三方jar包来实现。
目前国内比较流行的json解析插件是阿里巴巴公司的fastjson。
第1步:使用Maven在nybike项目中引入fastjson对应的jar包。
需要在nybike的pom.xml中添加对fastjson的依赖(dependancy)
数据库连接池
原生的JDBC编程,每次程序运行前建立与数据库的连接,每次操作执行后,关闭与数据库的连接。在数据库操作中,平均约70%的资源是消耗在建立连接和关闭连接上。
为了减少建立连接和关闭连接对资源的消耗,人们开发了数据库连接池的解决方案。
原理:在应用启动时,一次性创建多个数据库连接,存入连接池容器(List),用户在需要连接时,从连接池容器中获取一个空闲连接,在使用之后不再关闭连接,而是将该连接对象归还给连接池容器。
常用的第三方连接池插件有DBCP/C3p0,Tomcat内部也内置的连接池工具。
使用dbcp的第一步:在项目中引入dbcp对应的jar包->在pom.xml中添加依赖
MariaDB:Mysql的社区版
作业:
1、marker的信息窗默认显示在point位置,会遮盖一部分marker的图标,用户体验不佳,可以适当上移。需要注意:使用大图标和小图标时,都可以点击弹出信息窗,信息窗上移的幅度是不同的。
2、仿造官方地图页面,在现有的nymap.html上添加2个按钮,用户通过点击按钮可以实现可用车图标和可用桩图标的切换。该作业不需要提交,会作为每组答辩中必须展示的一个用例。
其他知识
一、Maven
- 项目管理工具,可便捷实现项目的整合,打包,发布等操作;
- Maven下载jar包的方式
- 本项目中主要使用Maven的jar包管理功能。项目中还会用到Maven的快速创建项目功能。Maven中内置了大量的(800+)项目模板,可以快速的创建指定类型的项目。
二、AJAX
浏览器实现异步请求和响应内容局部刷新的技术,异步的JS和XML。
JS负责实现浏览器发送异步请求:XmlHttpRequest,并且负责响应内容的局部刷新
XML负责在浏览器和服务器之间传递结构化的数据,但是该功能目前基本上已经被JSON取代
有些人建议AJAX改名叫 AJAJ 或 AJ
发送AJAX的具体代码:
-
原生的JavaScript编程,一共4步,大概20多行代码
-
利用jQuery提供的便捷的API:
$.get(url,params,callback);
$.post(url,params,callback);
$(selecter).load(url,params);会自动将收到的响应内容填充到selecter选择的组件内部
$.ajax({ url: method: success: … });
三、eclipse配置相关路径
- eclipse与Maven和Tomcat相关联,故在eclipse中需要配置其相关路径;
- Tomcat相关路径的配置:
在Eclipse中选择Window->Preferences->server->选择Tomcat8.5->Edit->将路径修改为本地Tomcat实际的路径 - Maven相关路径的配置:
在Eclipse中选择Window->Preferences->Maven->User Settings-> 将Global Settings和User Settings的值都改为第一步修改的settings.xml文件的路径,并点击update settings,检查下面的路径是否自动修改成功;
- 编辑…/bigdata_shixun/maven3.5.2/conf/settings.xml文件,修改标签的值,改成本地实际的.m2文件夹的路径。
- 其他
eclipse中点击server中的Tomcat,在页面中设置
- timeout,调大数字,(加长项目开启的时间)
- serverLocation,选择第二个,设置成由Tomcat运行项目;若呈灰色不可点击的状态,点击server中的Tomcat,右键选择clean即可选择。
API
API:应用编程接口
面试知识
- 为什么用该地图插件? 组件的选型问题:要根据你当前应用的特点去选择最合适的组件。你需要了解备选的这些组件的特点。