大量POI的解决方案2

概述

在前面的文章中,讲述了通过“抽稀+后台生成图片”的方式解决大量POI点展示的一种思路,后面看了tilestache的矢量切片方式,自己仔细思考了下,提出了本文大量POI点的展示解决方案。

 

tilestache

大概看了下tilestache,理解了下,大概解决思路是这样的:随着地图四至范围的变换,实时的去请求数据,并将数据在前段渲染,这样就大大提升了大量点的展示的效率问题。

 

效果

实现代码

1、后台实现

后台实现非常简单,通过servlet返回查询结果,根据四至作为条件进行查询,代码如下:

[javascript] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. package com.lzugis.web;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.annotation.WebServlet;  
  10. import javax.servlet.http.HttpServlet;  
  11. import javax.servlet.http.HttpServletRequest;  
  12. import javax.servlet.http.HttpServletResponse;  
  13.   
  14. import net.sf.json.JSON;  
  15. import net.sf.json.JSONArray;  
  16.   
  17. import org.springframework.jdbc.core.JdbcTemplate;  
  18.   
  19. import com.lzugis.db.SpringUtil;  
  20.   
  21. /** 
  22.  * Servlet implementation class PoiServlet 
  23.  */  
  24. @WebServlet(description = "poi servlet", urlPatterns =  {"/getpois"})  
  25. public class PointsServlet extends HttpServlet {  
  26.     private static final long serialVersionUID = 1L;      
  27.       
  28.     /** 
  29.      * @see javax.servlet.http.HttpServlet#HttpServlet() 
  30.      */  
  31.     public PointsServlet() {  
  32.         super();  
  33.         // TODO Auto-generated constructor stub  
  34.     }  
  35.   
  36.     /** 
  37.      * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) 
  38.      */  
  39.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  40.         // TODO Auto-generated method stub  
  41.         this.doPost(request, response);  
  42.     }  
  43.   
  44.     /** 
  45.      * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) 
  46.      */  
  47.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  48.         // TODO Auto-generated method stub  
  49.         String bbox= request.getParameter("bbox");  
  50.         int z = Integer.parseInt(request.getParameter("z").toString());  
  51.         System.out.println(z+","+bbox);  
  52.         String[] extent = bbox.split(",");  
  53.         double xmin = Double.parseDouble(extent[0]),  
  54.                 ymin = Double.parseDouble(extent[1]),  
  55.                 xmax = Double.parseDouble(extent[2]),  
  56.                 ymax = Double.parseDouble(extent[3]);  
  57.           
  58.         JdbcTemplate jdbcTemplate = (JdbcTemplate) SpringUtil.getBean("jdbcTemplate");  
  59.         String sqlQuery = "select * from county where x>=? and x<=? and y>=? and y<=?";  
  60.         List<Map<String, Object>> list =  jdbcTemplate.queryForList(sqlQuery, new Object[]{xmin,xmax,ymin,ymax});  
  61.         JSON json = JSONArray.fromObject(list);       
  62.         response.setContentType("text/html;charset=utf-8");  
  63.         PrintWriter out = response.getWriter();  
  64.         out.println(json);  
  65.         out.flush();  
  66.         out.close();  
  67.     }  
  68. }  

2、前台实现

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head lang="en">  
  4.     <meta charset="UTF-8">  
  5.     <title>openlayers map</title>  
  6.     <link rel="stylesheet" href="http://localhost:63342/lzugis/plugin/OpenLayers-2.13.1/theme/default/style.css" type="text/css">  
  7.     <style>  
  8.         html, body, #map{  
  9.             padding:0;  
  10.             margin:0;  
  11.             height:100%;  
  12.             width:100%;  
  13.             overflow: hidden;  
  14.         }  
  15.     </style>  
  16.     <script src="http://localhost:63342/lzugis/plugin/OpenLayers-2.13.1/OpenLayers.js"></script>  
  17.     <script src="http://localhost:63342/lzugis/plugin/jquery/jquery-1.8.3.js"></script>  
  18.     <script src="http://localhost:63342/lzugis/example/openlayers/ol2/extend/Grid.js"></script>  
  19.     <script>  
  20.         var map, sld;  
  21.         $(window).load(function() {  
  22.             var format = 'image/png';  
  23.             var bounds = new OpenLayers.Bounds(  
  24.                     73.45100463562233, 18.16324718764174,  
  25.                     134.97679764650596, 53.531943152223576  
  26.             );  
  27.             var options = {  
  28.                 controls: [],  
  29.                 maxExtent: bounds,  
  30.                 maxResolution: 0.2403351289487642,  
  31.                 projection: "EPSG:4326",  
  32.                 units: 'degrees'  
  33.             };  
  34.             map = new OpenLayers.Map('map', options);  
  35.             var tiled = new OpenLayers.Layer.WMS(  
  36.                     "Geoserver layers - Tiled",  
  37.                     "http://localhost:8088/geoserver/lzugis/wms",  
  38.                     {  
  39.                         "LAYERS": 'province',  
  40.                         "STYLES": '',  
  41.                         format: format  
  42.                     },  
  43.                     {  
  44.                         buffer: 0,  
  45.                         displayOutsideMaxExtent: true,  
  46.                         isBaseLayer: true,  
  47.                         yx : {'EPSG:4326' : true}  
  48.                     }  
  49.             );  
  50.             map.addLayers([tiled]);  
  51.             OpenLayers.INCHES_PER_UNIT["千米"] = OpenLayers.INCHES_PER_UNIT["km"];  
  52.             OpenLayers.INCHES_PER_UNIT["米"] = OpenLayers.INCHES_PER_UNIT["m"];  
  53.             OpenLayers.INCHES_PER_UNIT["英里"] = OpenLayers.INCHES_PER_UNIT["mi"];  
  54.             OpenLayers.INCHES_PER_UNIT["英寸"] = OpenLayers.INCHES_PER_UNIT["ft"];  
  55.             //比例尺  
  56.             map.addControl(new OpenLayers.Control.ScaleLine({topOutUnits:"千米",topInUnits:"米",bottomOutUnits:"英里",  
  57.                 bottomInUnits:"英寸"  
  58.             }));  
  59.             map.addControl(new OpenLayers.Control.Zoom());  
  60.             map.addControl(new OpenLayers.Control.Navigation());  
  61.             map.addControl(new OpenLayers.Control.OverviewMap());  
  62.             map.zoomToExtent(bounds);  
  63.   
  64.             var baseName = "http://localhost:8081/lzugis/getpois";  
  65.             var protocol = new OpenLayers.Protocol.HTTP({  
  66.                 url: baseName  
  67.             });  
  68.             var strategy = new OpenLayers.Strategy.Grid();  
  69.             var vectors = new OpenLayers.Layer.Vector("Vector", {  
  70.                 strategies: [strategy],  
  71.                 protocol: protocol  
  72.             });  
  73.             map.addLayer(vectors);  
  74.             var options = {  
  75.                 hover: true  
  76.             };  
  77.             var select = new OpenLayers.Control.SelectFeature(vectors, options);  
  78.             map.addControl(select);  
  79.             select.activate();  
  80.         });  
  81.     </script>  
  82. </head>  
  83. <body>  
  84. <div id="map">  
  85. </div>  
  86. </body>  
  87. </html>  

在此处,调用了一个扩展的Strategy,该Strategy里实现了数据的实时调用与数据展示,扩展Grid.js代码如下:

[javascript] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. OpenLayers.Strategy.Grid = OpenLayers.Class(OpenLayers.Strategy, {  
  2.     grid: null,  
  3.     buffer: 1,  
  4.     loadedBounds: null,  
  5.     zoom: null,  
  6.     geometryFeatureMap: {},  
  7.     tiles: {},  
  8.     initialize: function(options) {  
  9.         OpenLayers.Strategy.prototype.initialize.apply(this, [options]);  
  10.     },  
  11.   
  12.     destroy: function() {  
  13.         this.clearGrid();  
  14.         this.grid = null;  
  15.         this.tileSize = null;  
  16.         OpenLayers.Strategy.prototype.destroy.apply(this, arguments);  
  17.     },  
  18.   
  19.     activate: function() {  
  20.         var activated = OpenLayers.Strategy.prototype.activate.call(this);  
  21.         if(activated) {  
  22.             this.layer.events.on({  
  23.                 "moveend": this.update,  
  24.                 "refresh": this.update,  
  25.                 scope: this  
  26.             });  
  27.             if(this.layer.visibility == true || this.preload) {  
  28.                 this.update();  
  29.             }  
  30.             else {  
  31.                 this.layer.events.on({  
  32.                     "visibilitychanged": this.load,  
  33.                     scope: this  
  34.                 });  
  35.             }  
  36.         }  
  37.           
  38.         return activated;  
  39.     },  
  40.   
  41.     deactivate: function() {  
  42.         var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);  
  43.         if(deactivated) {  
  44.             this.layer.events.un({  
  45.                 "moveend": this.update,  
  46.                 "refresh": this.update,  
  47.                 "visibilitychanged": this.load,  
  48.                 scope: this  
  49.             });  
  50.         }  
  51.         return deactivated;  
  52.     },  
  53.   
  54.     loadData: function(bbox,zoom) {  
  55.         var scope = this;  
  56.         var url = scope.layer.protocol.url+"?bbox="+bbox+"&z="+zoom;  
  57.         $.ajax({  
  58.             type : "POST",  
  59.             cache: false,  
  60.             url : url,  
  61.             async : false,  
  62.             success : function(data) {  
  63.                 scope.readDone(data);  
  64.             }  
  65.         });  
  66.     },  
  67.   
  68.     update: function() {  
  69.         var bounds = this.layer.map.getExtent();  
  70.         if (bounds == null) return;  
  71.         var map = this.layer.map  
  72.         var curZoom = map.zoom;  
  73.         if (curZoom != this.zoom) {  
  74.             this.layer.destroyFeatures();  
  75.             this.geometryFeatureMap = {};  
  76.             this.tiles = {};  
  77.             this.zoom = curZoom  
  78.         }  
  79.         this.loadData(bounds.toBBOX(),curZoom);  
  80.     },  
  81.   
  82.     readDone: function(data) {  
  83.         this.merge(data, this.options);  
  84.     },  
  85.   
  86.     merge: function(data, options) {   
  87.         var data = eval("("+data+")");  
  88.         console.log("供查询到"+data.length+"条数据");  
  89.         if(data.length > 0) {    
  90.             var features = [];            
  91.             for(var i=0, len=data.length; i<len; ++i) {  
  92.                 var d = data[i];  
  93.                 var feature = new OpenLayers.Feature.Vector(  
  94.                         new OpenLayers.Geometry.Point(d.x, d.y),  
  95.                         d  
  96.                 );  
  97.                 features.push(feature);  
  98.             }  
  99.             this.layer.addFeatures(features);  
  100.         }  
  101.     },  
  102.     CLASS_NAME: "OpenLayers.Strategy.Grid"  
  103. }); 
posted @ 2016-07-18 14:57  韩慧兵  阅读(313)  评论(0编辑  收藏  举报