大量POI点展示的一种解决方案——续

来源:互联网 发布:bandicam mac版 编辑:程序博客网 时间:2024/05/22 01:21

概述:

在上文“ 大量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.342789244private 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 stubthis.doPost(request, response);}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubString 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%;            width: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)





0 0
原创粉丝点击