zoukankan      html  css  js  c++  java
  • 大量POI点展示的一种解决方案——续

    概述:

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


    效果:






    实现思路:

    1、点抽稀与图片生成

    package com.lzugis.web;
    
    import java.awt.Color;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import com.lzugis.db.SpringUtil;
    import com.lzugis.web.Model.Pos;
    
    /**
     * Servlet implementation class PoiServlet
     */
    @WebServlet(description = "poi servlet", urlPatterns =  {"/poi"})
    public class PoiServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L; 	
    	private static double M_PI = Math.PI;
    	//6378137赤道半径,一度对应赤道上的一米,20037508.342789244
    	private static double Degree2Meter = M_PI * 6378137 / 180.0;
    	
        /**
         * @see HttpServlet#HttpServlet()
         */
        public PoiServlet() {
            super();
            // TODO Auto-generated constructor stub
        }
    
    	/**
    	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		this.doPost(request, response);
    	}
    
    	/**
    	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		String bbox= request.getParameter("BBOX");
    		String width= request.getParameter("WIDTH");
    	    String height= request.getParameter("HEIGHT");
    	    int z = Integer.parseInt(request.getParameter("z").toString());
    	    String layer = request.getParameter("layer");
    	    System.out.println(z+","+layer+","+bbox);
    	    int w = Integer.parseInt(width),
    	    	 h = Integer.parseInt(height);
    	    String[] extent = bbox.split(",");
    	    double xmin = Double.parseDouble(extent[0]),
    	    		ymin = Double.parseDouble(extent[1]),
    	    		xmax = Double.parseDouble(extent[2]),
    	    		ymax = Double.parseDouble(extent[3]);
    	    double scalex = ((xmax-xmin)*3600)/w,
    	    		scaley = ((ymax-ymin)*3600)/h;
    	    //获取抽稀数据
    	    double dis = 2000000/(z+1);
    	    System.out.println(dis);
    		List<Pos> fc = new ArrayList<Pos>();
            List<Pos> fcDel = new ArrayList<Pos>();
            double buf = dis/Degree2Meter;
    		JdbcTemplate jdbcTemplate = (JdbcTemplate) SpringUtil.getBean("jdbcTemplate");
            String sqlQuery = "select * from "+layer+" where x>=? and x<=? and y>=? and y<=?";
            List<Map<String, Object>> list =  jdbcTemplate.queryForList(sqlQuery, new Object[]{xmin,xmax,ymin,ymax});
            BufferedImage image = new BufferedImage(w, h,BufferedImage.TYPE_INT_RGB);
    	    java.awt.Graphics2D g2d = image.createGraphics();
    	    image = g2d.getDeviceConfiguration().createCompatibleImage(w,h,
    	    	java.awt.Transparency.TRANSLUCENT);
    	    g2d.dispose();
    	    g2d = image.createGraphics();
    	    if(list.size()>20){
    	        for(int i=0;i<list.size();i++){
    	        	Map<String,Object> map = list.get(i);
    	        	double x =  Double.parseDouble(map.get("x").toString());
    	        	double y =  Double.parseDouble(map.get("y").toString());
    	        	Pos pos = new Pos(x,y);
    	        	pos.setBuffer(buf);
    	        	if (fc.contains(pos)) {
    	        		fcDel.add(pos);
    	        	} 
    	        	else {
    	        		fc.add(pos);
    	        		double scrx = (x-xmin)*3600/scalex,
    	      	    			scry = (ymax-y)*3600/scaley;      	    	 
    	      	    	g2d.setColor(Color.RED);
    	      	    	Image img = ImageIO.read(new File("c:/icon.png"));
    	      	    	g2d.drawImage(img, (int)scrx, (int)scry, null, null);
    	        	}
    	        }
    	    }
    	    else{
    	    	for(int i=0;i<list.size();i++){
    	        	Map<String,Object> map = list.get(i);
    	        	double x =  Double.parseDouble(map.get("x").toString());
    	        	double y =  Double.parseDouble(map.get("y").toString());
    	        	Pos pos = new Pos(x,y);
    	        	pos.setBuffer(buf);
    	        	fc.add(pos);
            		double scrx = (x-xmin)*3600/scalex,
          	    			scry = (ymax-y)*3600/scaley;      	    	 
          	    	g2d.setColor(Color.RED);
          	    	Image img = ImageIO.read(new File("c:/icon.png"));
          	    	g2d.drawImage(img, (int)scrx, (int)scry, null, null);	        		
    	        }
    	    }
            System.out.println("共"+list.size()+"个点,其中:保留"+fc.size()+"个,删除"+fcDel.size()+"个");
            g2d.setStroke(new java.awt.BasicStroke(10));
    	    // 释放对象
    	    g2d.dispose();
    	    // 保存文件
    	    OutputStream os = response.getOutputStream();
    	    try {
    	    	String poiimg = "c:/wms.png";
    	    	ImageIO.write(image, "png", new File(poiimg));
    	        int count = 0;
    	        byte[] buffer = new byte[1024 * 1024];
                InputStream inStream = new BufferedInputStream(new FileInputStream(poiimg));
    	        while ((count = inStream.read(buffer)) != -1){
    	            os.write(buffer, 0, count);
    	        }
    	        os.flush();	        
    	        inStream.close();
    	        os.close();
    	    }
    	    catch (IOException e) {
    	        e.printStackTrace();
    	    }
    	}
    }
    其中,Pos类如下:

    package com.lzugis.web.Model;
    
    public class Pos {
    	public double x;
    	public double y;
    
    	private double buf;
    
    	public Pos(double x, double y) {
    		this.x = x;
    		this.y = y;
    	}
    
    	public void setBuffer(double buf) {
    		this.buf = buf;
    	}
    
    	public boolean equals(Object pt) {
    		if (pt instanceof Pos)
    			return (Math.abs(this.x - ((Pos) pt).x) <= buf && Math.abs(this.y
    					- ((Pos) pt).y) <= buf);
    		return false;
    	}
    
    	public int hashCode() {
    		return Integer.valueOf(x + "" + y);
    	}
    
    }
    2、扩展wms,在请求参数后添加zoom和layername

    OpenLayers.Layer.PoiLayer = OpenLayers.Class(OpenLayers.Layer.Grid, {
        DEFAULT_PARAMS: { service: "WMS",
            version: "1.1.1",
            request: "GetMap",
            styles: "",
            format: "image/jpeg"
        },
        isBaseLayer: true,
        encodeBBOX: false,
        noMagic: false,
        yx: {},
        layer:"",
        initialize: function(name, url, params, options) {
            var newArguments = [];
            //uppercase params
            params = OpenLayers.Util.upperCaseObject(params);
            if (parseFloat(params.VERSION) >= 1.3 && !params.EXCEPTIONS) {
                params.EXCEPTIONS = "INIMAGE";
            }
            newArguments.push(name, url, params, options);
            OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
            OpenLayers.Util.applyDefaults(
                this.params,
                OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS)
            );
    
    
            //layer is transparent        
            if (!this.noMagic && this.params.TRANSPARENT &&
                this.params.TRANSPARENT.toString().toLowerCase() == "true") {
    
                // unless explicitly set in options, make layer an overlay
                if ( (options == null) || (!options.isBaseLayer) ) {
                    this.isBaseLayer = false;
                }
    
                // jpegs can never be transparent, so intelligently switch the 
                //  format, depending on the browser's capabilities
                if (this.params.FORMAT == "image/jpeg") {
                    this.params.FORMAT = OpenLayers.Util.alphaHack() ? "image/gif"
                        : "image/png";
                }
            }
    
        },
        clone: function (obj) {
    
            if (obj == null) {
                obj = new OpenLayers.Layer.WMS(this.name,
                    this.url,
                    this.params,
                    this.getOptions());
            }
    
            //get all additions from superclasses
            obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
    
            // copy/set any non-init, non-simple values here
    
            return obj;
        },
        reverseAxisOrder: function() {
            var projCode = this.projection.getCode();
            return parseFloat(this.params.VERSION) >= 1.3 &&
                !!(this.yx[projCode] || OpenLayers.Projection.defaults[projCode].yx);
        },
        getURL: function (bounds) {
            bounds = this.adjustBounds(bounds);
            var imageSize = this.getImageSize();
            var newParams = {};
            // WMS 1.3 introduced axis order
            var reverseAxisOrder = this.reverseAxisOrder();
            newParams.BBOX = this.encodeBBOX ?
                bounds.toBBOX(null, reverseAxisOrder) :
                bounds.toArray(reverseAxisOrder);
            newParams.WIDTH = imageSize.w;
            newParams.HEIGHT = imageSize.h;
            var requestString = this.getFullRequestString(newParams);
            var zoom = this.map.getZoom();
            var layer = this.name;
            return requestString+"&z="+zoom+"&layer="+layer;
        },
    
        mergeNewParams:function(newParams) {
            var upperParams = OpenLayers.Util.upperCaseObject(newParams);
            var newArguments = [upperParams];
            return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,
                newArguments);
        },
        getFullRequestString:function(newParams, altUrl) {
            var mapProjection = this.map.getProjectionObject();
            var projectionCode = this.projection && this.projection.equals(mapProjection) ?
                this.projection.getCode() :
                mapProjection.getCode();
            var value = (projectionCode == "none") ? null : projectionCode;
            if (parseFloat(this.params.VERSION) >= 1.3) {
                this.params.CRS = value;
            } else {
                this.params.SRS = value;
            }
    
            if (typeof this.params.TRANSPARENT == "boolean") {
                newParams.TRANSPARENT = this.params.TRANSPARENT ? "TRUE" : "FALSE";
            }
    
            return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(
                this, arguments);
        },
    
        CLASS_NAME: "OpenLayers.Layer.PoiLayer"
    });
    3、前台调用并展示

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>openlayers map</title>
        <link rel="stylesheet" href="../../../plugin/OpenLayers-2.13.1/theme/default/style.css" type="text/css">
        <style>
            html, body, #map{
                padding:0;
                margin:0;
                height:100%;
                100%;
                overflow: hidden;
            }
            .tool{
                position: absolute;
                top:10pt;
                right: 10pt;
                padding: 5px;
                background: #fff;
                border: 1px solid #ff5500;
                z-index: 1000;
            }
        </style>
        <script src="../../../plugin/OpenLayers-2.13.1/OpenLayers.js"></script>
        <script src="extend/PoiLayer.js"></script>
        <script src="../../../plugin/jquery/jquery-1.8.3.js"></script>
        <script>
            var map;
            var tiled;
            OpenLayers.IMAGE_RELOAD_ATTEMPTS = 5;
            OpenLayers.DOTS_PER_INCH = 25.4 / 0.28;
            $(window).load(function() {
                var format = 'image/png';
                var bounds = new OpenLayers.Bounds(
                        73.45100463562233, 18.16324718764174,
                        134.97679764650596, 53.531943152223576
                );
                var options = {
                    controls: [],
                    maxExtent: bounds,
                    maxResolution: 0.2403351289487642,
                    projection: "EPSG:4326",
                    units: 'degrees'
                };
                map = new OpenLayers.Map('map', options);
                var url = "http://localhost:8088/geoserver/lzugis/wms";
                tiled = new OpenLayers.Layer.WMS(
                        "Geoserver layers - Tiled",
                        url,
                        {
                            "LAYERS": 'lzugis:province',
                            "STYLES": '',
                            format: format
                        },
                        {
                            buffer: 0,
                            displayOutsideMaxExtent: true,
                            isBaseLayer: true,
                            yx : {'EPSG:4326' : true}
                        }
                );
                map.addLayers([tiled]);
                map.addControl(new OpenLayers.Control.Zoom());
                map.addControl(new OpenLayers.Control.Navigation());
                map.zoomToExtent(bounds);
    
                $("#addchart").on("click",function(){
                    var poiurl = "http://localhost:8081/lzugis/poi";
                    var wms = new OpenLayers.Layer.PoiLayer("county",
                            poiurl,
                            {
                                layers: "poi",
                                transparent: true
                            }, {
                                opacity: 1,
                                singleTile: true
                            });
                    map.addLayers([wms]);
                });
            });
        </script>
    </head>
    <body>
    <div id="map">
        <div class="tool">
            <button id="addchart">添加marker</button>
        </div>
    </div>
    <map name="marker" id="marker"></map>
    </body>
    </html>

    传播GIS知识 | 交流GIS经验 | 分享GIS价值 | 专注GIS发展

    技术博客

    http://blog.csdn.net/gisshixisheng


    在线教程

    http://edu.csdn.net/course/detail/799

    Github

    https://github.com/lzugis/


    联系方式

    q       q:1004740957

    e-mail:niujp08@qq.com

    公众号:lzugis15

    Q Q 群:452117357(webgis)
                 337469080(Android)





  • 相关阅读:
    linux基础命令篇四
    linux基础命令篇三
    linux基础命令篇二
    msf测试
    msf
    [精品转载] [NoSaFe]KALI下免杀神器TheFatRat使用秘籍
    kali&BT安装好之后无法上网或者无法获得内网IP
    Kali Linux安装之后需要做的一些事
    在Ubuntu下解决E: 无法对目录 /var/lib/apt/lists/ 加锁的问题(转)
    xshell之类的软件第一次连接不上初次安装kali问题(转)
  • 原文地址:https://www.cnblogs.com/lzugis/p/6539784.html
Copyright © 2011-2022 走看看