抽稀+图片生成

概述:

在上文“ 大量POI点展示的一种解决方案”中,介绍了在在后台将POI生成图片在前台展示,文章中没有涉及到点的抽稀问题,也就是当点的数据量非常大的时候,这种展示方式还是会有一定的效率问题,在本文,书接上文,介绍一种点抽稀的算法,并结合上文,实现大量poi点的高效展示。

 

效果:

 

实现思路:

1、点抽稀与图片生成

  1. package com.lzugis.web;  
  2.   
  3. import java.awt.Color;  
  4. import java.awt.Image;  
  5. import java.awt.image.BufferedImage;  
  6. import java.io.BufferedInputStream;  
  7. import java.io.File;  
  8. import java.io.FileInputStream;  
  9. import java.io.IOException;  
  10. import java.io.InputStream;  
  11. import java.io.OutputStream;  
  12. import java.util.ArrayList;  
  13. import java.util.List;  
  14. import java.util.Map;  
  15.   
  16. import javax.imageio.ImageIO;  
  17. import javax.servlet.ServletException;  
  18. import javax.servlet.annotation.WebServlet;  
  19. import javax.servlet.http.HttpServlet;  
  20. import javax.servlet.http.HttpServletRequest;  
  21. import javax.servlet.http.HttpServletResponse;  
  22.   
  23. import org.springframework.jdbc.core.JdbcTemplate;  
  24.   
  25. import com.lzugis.db.SpringUtil;  
  26. import com.lzugis.web.Model.Pos;  
  27.   
  28. /** 
  29.  * Servlet implementation class PoiServlet 
  30.  */  
  31. @WebServlet(description = "poi servlet", urlPatterns =  {"/poi"})  
  32. public class PoiServlet extends HttpServlet {  
  33.     private static final long serialVersionUID = 1L;      
  34.     private static double M_PI = Math.PI;  
  35.     //6378137赤道半径,一度对应赤道上的一米,20037508.342789244  
  36.     private static double Degree2Meter = M_PI * 6378137 / 180.0;  
  37.       
  38.     /** 
  39.      * @see HttpServlet#HttpServlet() 
  40.      */  
  41.     public PoiServlet() {  
  42.         super();  
  43.         // TODO Auto-generated constructor stub  
  44.     }  
  45.   
  46.     /** 
  47.      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 
  48.      */  
  49.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  50.         // TODO Auto-generated method stub  
  51.         this.doPost(request, response);  
  52.     }  
  53.   
  54.     /** 
  55.      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  56.      */  
  57.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  58.         // TODO Auto-generated method stub  
  59.         String bbox= request.getParameter("BBOX");  
  60.         String width= request.getParameter("WIDTH");  
  61.         String height= request.getParameter("HEIGHT");  
  62.         int z = Integer.parseInt(request.getParameter("z").toString());  
  63.         String layer = request.getParameter("layer");  
  64.         System.out.println(z+","+layer+","+bbox);  
  65.         int w = Integer.parseInt(width),  
  66.              h = Integer.parseInt(height);  
  67.         String[] extent = bbox.split(",");  
  68.         double xmin = Double.parseDouble(extent[0]),  
  69.                 ymin = Double.parseDouble(extent[1]),  
  70.                 xmax = Double.parseDouble(extent[2]),  
  71.                 ymax = Double.parseDouble(extent[3]);  
  72.         double scalex = ((xmax-xmin)*3600)/w,  
  73.                 scaley = ((ymax-ymin)*3600)/h;  
  74.         //获取抽稀数据  
  75.         double dis = 2000000/(z+1);  
  76.         System.out.println(dis);  
  77.         List<Pos> fc = new ArrayList<Pos>();  
  78.         List<Pos> fcDel = new ArrayList<Pos>();  
  79.         double buf = dis/Degree2Meter;  
  80.         JdbcTemplate jdbcTemplate = (JdbcTemplate) SpringUtil.getBean("jdbcTemplate");  
  81.         String sqlQuery = "select * from "+layer+" where x>=? and x<=? and y>=? and y<=?";  
  82.         List<Map<String, Object>> list =  jdbcTemplate.queryForList(sqlQuery, new Object[]{xmin,xmax,ymin,ymax});  
  83.         BufferedImage image = new BufferedImage(w, h,BufferedImage.TYPE_INT_RGB);  
  84.         java.awt.Graphics2D g2d = image.createGraphics();  
  85.         image = g2d.getDeviceConfiguration().createCompatibleImage(w,h,  
  86.             java.awt.Transparency.TRANSLUCENT);  
  87.         g2d.dispose();  
  88.         g2d = image.createGraphics();  
  89.         if(list.size()>20){  
  90.             for(int i=0;i<list.size();i++){  
  91.                 Map<String,Object> map = list.get(i);  
  92.                 double x =  Double.parseDouble(map.get("x").toString());  
  93.                 double y =  Double.parseDouble(map.get("y").toString());  
  94.                 Pos pos = new Pos(x,y);  
  95.                 pos.setBuffer(buf);  
  96.                 if (fc.contains(pos)) {  
  97.                     fcDel.add(pos);  
  98.                 }   
  99.                 else {  
  100.                     fc.add(pos);  
  101.                     double scrx = (x-xmin)*3600/scalex,  
  102.                             scry = (ymax-y)*3600/scaley;                   
  103.                     g2d.setColor(Color.RED);  
  104.                     Image img = ImageIO.read(new File("c:/icon.png"));  
  105.                     g2d.drawImage(img, (int)scrx, (int)scry, null, null);  
  106.                 }  
  107.             }  
  108.         }  
  109.         else{  
  110.             for(int i=0;i<list.size();i++){  
  111.                 Map<String,Object> map = list.get(i);  
  112.                 double x =  Double.parseDouble(map.get("x").toString());  
  113.                 double y =  Double.parseDouble(map.get("y").toString());  
  114.                 Pos pos = new Pos(x,y);  
  115.                 pos.setBuffer(buf);  
  116.                 fc.add(pos);  
  117.                 double scrx = (x-xmin)*3600/scalex,  
  118.                         scry = (ymax-y)*3600/scaley;                   
  119.                 g2d.setColor(Color.RED);  
  120.                 Image img = ImageIO.read(new File("c:/icon.png"));  
  121.                 g2d.drawImage(img, (int)scrx, (int)scry, null, null);                     
  122.             }  
  123.         }  
  124.         System.out.println("共"+list.size()+"个点,其中:保留"+fc.size()+"个,删除"+fcDel.size()+"个");  
  125.         g2d.setStroke(new java.awt.BasicStroke(10));  
  126.         // 释放对象  
  127.         g2d.dispose();  
  128.         // 保存文件  
  129.         OutputStream os = response.getOutputStream();  
  130.         try {  
  131.             String poiimg = "c:/wms.png";  
  132.             ImageIO.write(image, "png", new File(poiimg));  
  133.             int count = 0;  
  134.             byte[] buffer = new byte[1024 * 1024];  
  135.             InputStream inStream = new BufferedInputStream(new FileInputStream(poiimg));  
  136.             while ((count = inStream.read(buffer)) != -1){  
  137.                 os.write(buffer, 0, count);  
  138.             }  
  139.             os.flush();           
  140.             inStream.close();  
  141.             os.close();  
  142.         }  
  143.         catch (IOException e) {  
  144.             e.printStackTrace();  
  145.         }  
  146.     }  
  147. }  

其中,Pos类如下:

  1. package com.lzugis.web.Model;  
  2.   
  3. public class Pos {  
  4.     public double x;  
  5.     public double y;  
  6.   
  7.     private double buf;  
  8.   
  9.     public Pos(double x, double y) {  
  10.         this.x = x;  
  11.         this.y = y;  
  12.     }  
  13.   
  14.     public void setBuffer(double buf) {  
  15.         this.buf = buf;  
  16.     }  
  17.   
  18.     public boolean equals(Object pt) {  
  19.         if (pt instanceof Pos)  
  20.             return (Math.abs(this.x - ((Pos) pt).x) <= buf && Math.abs(this.y  
  21.                     - ((Pos) pt).y) <= buf);  
  22.         return false;  
  23.     }  
  24.   
  25.     public int hashCode() {  
  26.         return Integer.valueOf(x + "" + y);  
  27.     }  
  28.   
  29. }  

2、扩展wms,在请求参数后添加zoom和layername

  1. OpenLayers.Layer.PoiLayer = OpenLayers.Class(OpenLayers.Layer.Grid, {  
  2.     DEFAULT_PARAMS: { service: "WMS",  
  3.         version: "1.1.1",  
  4.         request: "GetMap",  
  5.         styles: "",  
  6.         format: "image/jpeg"  
  7.     },  
  8.     isBaseLayer: true,  
  9.     encodeBBOX: false,  
  10.     noMagic: false,  
  11.     yx: {},  
  12.     layer:"",  
  13.     initialize: function(name, url, params, options) {  
  14.         var newArguments = [];  
  15.         //uppercase params  
  16.         params = OpenLayers.Util.upperCaseObject(params);  
  17.         if (parseFloat(params.VERSION) >= 1.3 && !params.EXCEPTIONS) {  
  18.             params.EXCEPTIONS = "INIMAGE";  
  19.         }  
  20.         newArguments.push(name, url, params, options);  
  21.         OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);  
  22.         OpenLayers.Util.applyDefaults(  
  23.             this.params,  
  24.             OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS)  
  25.         );  
  26.   
  27.   
  28.         //layer is transparent          
  29.         if (!this.noMagic && this.params.TRANSPARENT &&  
  30.             this.params.TRANSPARENT.toString().toLowerCase() == "true") {  
  31.   
  32.             // unless explicitly set in options, make layer an overlay  
  33.             if ( (options == null) || (!options.isBaseLayer) ) {  
  34.                 this.isBaseLayer = false;  
  35.             }  
  36.   
  37.             // jpegs can never be transparent, so intelligently switch the   
  38.             //  format, depending on the browser's capabilities  
  39.             if (this.params.FORMAT == "image/jpeg") {  
  40.                 this.params.FORMAT = OpenLayers.Util.alphaHack() ? "image/gif"  
  41.                     : "image/png";  
  42.             }  
  43.         }  
  44.   
  45.     },  
  46.     clone: function (obj) {  
  47.   
  48.         if (obj == null) {  
  49.             obj = new OpenLayers.Layer.WMS(this.name,  
  50.                 this.url,  
  51.                 this.params,  
  52.                 this.getOptions());  
  53.         }  
  54.   
  55.         //get all additions from superclasses  
  56.         obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);  
  57.   
  58.         // copy/set any non-init, non-simple values here  
  59.   
  60.         return obj;  
  61.     },  
  62.     reverseAxisOrder: function() {  
  63.         var projCode = this.projection.getCode();  
  64.         return parseFloat(this.params.VERSION) >= 1.3 &&  
  65.             !!(this.yx[projCode] || OpenLayers.Projection.defaults[projCode].yx);  
  66.     },  
  67.     getURL: function (bounds) {  
  68.         bounds = this.adjustBounds(bounds);  
  69.         var imageSize = this.getImageSize();  
  70.         var newParams = {};  
  71.         // WMS 1.3 introduced axis order  
  72.         var reverseAxisOrder = this.reverseAxisOrder();  
  73.         newParams.BBOX = this.encodeBBOX ?  
  74.             bounds.toBBOX(null, reverseAxisOrder) :  
  75.             bounds.toArray(reverseAxisOrder);  
  76.         newParams.WIDTH = imageSize.w;  
  77.         newParams.HEIGHT = imageSize.h;  
  78.         var requestString = this.getFullRequestString(newParams);  
  79.         var zoom = this.map.getZoom();  
  80.         var layer = this.name;  
  81.         return requestString+"&z="+zoom+"&layer="+layer;  
  82.     },  
  83.   
  84.     mergeNewParams:function(newParams) {  
  85.         var upperParams = OpenLayers.Util.upperCaseObject(newParams);  
  86.         var newArguments = [upperParams];  
  87.         return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,  
  88.             newArguments);  
  89.     },  
  90.     getFullRequestString:function(newParams, altUrl) {  
  91.         var mapProjection = this.map.getProjectionObject();  
  92.         var projectionCode = this.projection && this.projection.equals(mapProjection) ?  
  93.             this.projection.getCode() :  
  94.             mapProjection.getCode();  
  95.         var value = (projectionCode == "none") ? null : projectionCode;  
  96.         if (parseFloat(this.params.VERSION) >= 1.3) {  
  97.             this.params.CRS = value;  
  98.         } else {  
  99.             this.params.SRS = value;  
  100.         }  
  101.   
  102.         if (typeof this.params.TRANSPARENT == "boolean") {  
  103.             newParams.TRANSPARENT = this.params.TRANSPARENT ? "TRUE" : "FALSE";  
  104.         }  
  105.   
  106.         return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(  
  107.             this, arguments);  
  108.     },  
  109.   
  110.     CLASS_NAME: "OpenLayers.Layer.PoiLayer"  
  111. });  

3、前台调用并展示

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head lang="en">  
  4.     <meta charset="UTF-8">  
  5.     <title>openlayers map</title>  
  6.     <link rel="stylesheet" href="../../../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.         .tool{  
  16.             position: absolute;  
  17.             top:10pt;  
  18.             right: 10pt;  
  19.             padding: 5px;  
  20.             background: #fff;  
  21.             border: 1px solid #ff5500;  
  22.             z-index: 1000;  
  23.         }  
  24.     </style>  
  25.     <script src="../../../plugin/OpenLayers-2.13.1/OpenLayers.js"></script>  
  26.     <script src="extend/PoiLayer.js"></script>  
  27.     <script src="../../../plugin/jquery/jquery-1.8.3.js"></script>  
  28.     <script>  
  29.         var map;  
  30.         var tiled;  
  31.         OpenLayers.IMAGE_RELOAD_ATTEMPTS = 5;  
  32.         OpenLayers.DOTS_PER_INCH = 25.4 / 0.28;  
  33.         $(window).load(function() {  
  34.             var format = 'image/png';  
  35.             var bounds = new OpenLayers.Bounds(  
  36.                     73.45100463562233, 18.16324718764174,  
  37.                     134.97679764650596, 53.531943152223576  
  38.             );  
  39.             var options = {  
  40.                 controls: [],  
  41.                 maxExtent: bounds,  
  42.                 maxResolution: 0.2403351289487642,  
  43.                 projection: "EPSG:4326",  
  44.                 units: 'degrees'  
  45.             };  
  46.             map = new OpenLayers.Map('map', options);  
  47.             var url = "http://localhost:8088/geoserver/lzugis/wms";  
  48.             tiled = new OpenLayers.Layer.WMS(  
  49.                     "Geoserver layers - Tiled",  
  50.                     url,  
  51.                     {  
  52.                         "LAYERS": 'lzugis:province',  
  53.                         "STYLES": '',  
  54.                         format: format  
  55.                     },  
  56.                     {  
  57.                         buffer: 0,  
  58.                         displayOutsideMaxExtent: true,  
  59.                         isBaseLayer: true,  
  60.                         yx : {'EPSG:4326' : true}  
  61.                     }  
  62.             );  
  63.             map.addLayers([tiled]);  
  64.             map.addControl(new OpenLayers.Control.Zoom());  
  65.             map.addControl(new OpenLayers.Control.Navigation());  
  66.             map.zoomToExtent(bounds);  
  67.   
  68.             $("#addchart").on("click",function(){  
  69.                 var poiurl = "http://localhost:8081/lzugis/poi";  
  70.                 var wms = new OpenLayers.Layer.PoiLayer("county",  
  71.                         poiurl,  
  72.                         {  
  73.                             layers: "poi",  
  74.                             transparent: true  
  75.                         }, {  
  76.                             opacity: 1,  
  77.                             singleTile: true  
  78.                         });  
  79.                 map.addLayers([wms]);  
  80.             });  
  81.         });  
  82.     </script>  
  83. </head>  
  84. <body>  
  85. <div id="map">  
  86.     <div class="tool">  
  87.         <button id="addchart">添加marker</button>  
  88.     </div>  
  89. </div>  
  90. <map name="marker" id="marker"></map>  
  91. </body>  
  92. </html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值