1. 交互流程1、用户进入首页,看到热门公交线路列表。 2、输入关键词,可以搜索到相关公交线路。 3、单击选择公交线路,进入线路方向选择页面。 4、单击选择线路方向,进入百度地图。 5、在初始化百度地图时,传入线路方向。
2. 技术架构前端技术:jquery和art-template。 后端技术:servlet、freemarker、jdbc和mysql。
3. 详细设计3.1. 前端3.1.1. 响应式本系统适用于移动端,为了适应不同的屏幕,所以前端使用响应式布局。
1 2 3 4 5 6 7 8 9 10 11 12 13 html {font-size :10px }@media screen and (min-width :321px ) and (max-width :375px ){html {font-size :11px }}@media screen and (min-width :376px ) and (max-width :414px ){html {font-size :12px }}@media screen and (min-width :415px ) and (max-width :639px ){html {font-size :15px }}@media screen and (min-width :640px ) and (max-width :719px ){html {font-size :20px }}@media screen and (min-width :720px ) and (max-width :749px ){html {font-size :22.5px }}@media screen and (min-width :750px ) and (max-width :799px ){html {font-size :23.5px }}@media screen and (min-width :800px ){html {font-size :25px }}*{ margin : 0 ; padding : 0 ; }
3.1.2. 模板引擎搜索后,搜索结果要显示在页面上。这里,我们选用art-template模板引擎,把搜索请求得到的数据渲染到页面上。
1 2 3 4 5 6 7 8 9 <script id ="line-template" type ="text/html" > <ul > {{each lineList as line}} <a href ="${basePath}/Direction?busName= {{line.busName }} " > <li > {{line.fullName }} ( {{line.firstStop }} - {{line.lastStop }} )</li > </a > {{/each }} </ul > </script >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $('#search' ).click(function (event ) { var basePath = $('#basePath' ).val(); var key = $('#key' ).val(); $.ajax({ url : basePath+'/Search' , type : 'POST' , dataType : 'json' , data : {key : key}, success : function (data ){ console .log (data); var html = template('line-template' , data); $('.content' ).html(html); }, error : function (xhr ){ console .log (xhr); } }); });
3.1.3. 百度地图最终结果,以百度地图的方式展示,需要用到百度地图api。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <script type="text/javascript" > function init ( ) { window.busName = document.getElementById('busName' ).value; window.firstStop = document.getElementById('firstStop' ).value; } var map = new BMap.Map ("l-map" ); map .centerAndZoom(new BMap.Point (125.434025 ,43.83246 ), 12 ); var busline = new BMap.BusLineSearch(map ,{ renderOptions :{map :map ,panel :"r-result" }, onGetBusListComplete : function (result ){ var directionArr = result.PA; console .log (result); if (result) { var line = result.getBusListItem(0 ); var backLine = result.getBusListItem(1 ); console .log (line); var regx = /\([\u4E00-\u9FA5\uF900-\uFA2D]*-/ ; var str = line.name; console .log (str); var rs = str.match(regx)[0 ]; rs = rs.slice (1 ,-1 ); console .log (rs); if (rs == window.firstStop){ busline.getBusLine(line); }else { busline.getBusLine(backLine); } } } }); function busSearch ( ){ busline.getBusList(window.busName); } init(); setTimeout(function ( ){ busSearch(); },1500 ); </script>
3.2. 后端3.2.1. servlet鉴于本系统业务简单,所以使用servlet就够用了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package com.voidking.servlet;import java.io.IOException ;import javax.servlet.ServletException ;import javax.servlet.annotation.WebServlet ;import javax.servlet.http.HttpServlet ;import javax.servlet.http.HttpServletRequest ;import javax.servlet.http.HttpServletResponse ;@WebServlet ("/Home" )public class Home extends HttpServlet { public Home () { super (); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException , IOException { response.getWriter().append("Served at: " ).append(request.getContextPath()); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException , IOException { doGet(request, response); } }
3.2.2. freemarker进入首页时,查询出的数据需要渲染到页面上。这里,我们要选择一个后端模板引擎。不习惯使用jsp,决定使用freemarker。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Configuration config=new Configuration (); ServletContext context = request.getServletContext (); config.setServletContextForTemplateLoading (context, "template" ); Template template =config.getTemplate ("home.ftl" ); Map<String ,Object> map=new HashMap <String ,Object>(); map.put ("basePath" , request.getContextPath ()); map.put ("lineList" , lineList); response.setCharacterEncoding ("utf8" ); PrintWriter out = response.getWriter (); try { template .process (map, out); out.flush (); out.close (); } catch (TemplateException e) { e.printStackTrace (); } }
3.2.3. json目前,前后端传输数据最常用的格式不外乎xml和json,本系统采用json作为数据传输格式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding ("utf8" ); PrintWriter pw = response.getWriter (); String key = request.getParameter ("key" ); ArrayList <Line> lineList = lineService.searchLine (key ); if (lineList.size () > 0 ){ jsonObj = new JSONObject ("{'code':'0','ext':'success'}" ); jsonObj.put ("lineList" , lineList); }else { jsonObj = new JSONObject ("{'code':'1','ext':'error'}" ); } pw.println (jsonObj); }
3.2.4. jdbc数据库连接和查询,使用jdbc。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 public ArrayList<Line > getLines() { // 结果集合 ArrayList<Line > result = new ArrayList<Line >(); // Step 1 : Claim Connection and Statement Connection conn = null ; Statement stmt = null ; try { // STEP 2 : Register JDBC driver Class .forName(JDBC_DRIVER); // STEP 3 : Open a connection System .out .println("Connecting to database..."); conn = DriverManager.getConnection(DB_URL, USER , PASS); // STEP 4 : Execute a query System .out .println("Creating statement..."); stmt = conn.createStatement(); String sql ; sql = "select * from line"; ResultSet rs = stmt.executeQuery(sql ); // STEP 5 : Extract data from result set while (rs.next()) { // Retrieve by column name int id = rs.getInt("id"); String busName = rs.getString("bus_name"); String fullName = rs.getString("full_name"); String firstStop = rs.getString("first_stop"); String lastStop = rs.getString("last_stop"); Line line = new Line(id, busName, fullName, firstStop, lastStop); result.add (line ); } // STEP 6 : Clean-up environment rs.close (); stmt.close (); conn.close (); } catch (SQLException se) { // Handle errors for JDBC se.printStackTrace(); } catch (Exception e) { // Handle errors for Class .forName e.printStackTrace(); } finally { // finally block used to close resources try { if (stmt != null ) stmt.close (); } catch (SQLException se2) { } // nothing we can do try { if (conn != null ) conn.close (); } catch (SQLException se) { se.printStackTrace(); } // end finally try } // end try System .out .println("Goodbye!"); return result; }
3.3. 数据库3.3.1. 数据搜集长春公交有近200条公交线路,这里,我们从8684网站上搜集了常用的11条线路用来做测试。
3.3.2. 表设计1 2 3 4 5 6 7 8 CREATE TABLE `line ` ( `id` int (4 ) NOT NULL AUTO_INCREMENT, `bus_name` varchar (32 ) NOT NULL , `full_name` tinytext NOT NULL , `first_stop` varchar (32 ) DEFAULT NULL , `last_stop` varchar (32 ) DEFAULT NULL , PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
4. 效果演示
5. 源码分享https://github.com/voidking/bus-search
6. 后记为什么不做实时公交查询?因为拿不到数据。百度地图没有提供实时公交API,也拿不到公交公司的数据。
7. 书签Introducing JSONhttp://www.json.org/
JSON入门之二:org.json的基本用法http://blog.csdn.net/jediael_lu/article/details/25779087
JSON解析工具-org.json使用教程http://www.open-open.com/lib/view/open1381566882614.html
Amaze UI 模板中心http://tpl.amazeui.org/
(淘宝无限适配)手机端rem布局详解http://www.cnblogs.com/well-nice/p/5509589.html
长春公交查询http://changchun.8684.cn/
百度地图JavaScript 开源库http://lbsyun.baidu.com/index.php?title=open/library
百度地图API示例http://lbsyun.baidu.com/jsdemo.htm#a1_2