前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大量POI的解决方案2

大量POI的解决方案2

作者头像
lzugis
发布2018-10-23 12:02:06
8020
发布2018-10-23 12:02:06
举报

概述

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

tilestache

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

效果

实现代码

1、后台实现

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

代码语言:javascript
复制
package com.lzugis.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

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 net.sf.json.JSON;
import net.sf.json.JSONArray;

import org.springframework.jdbc.core.JdbcTemplate;

import com.lzugis.db.SpringUtil;

/**
 * Servlet implementation class PoiServlet
 */
@WebServlet(description = "poi servlet", urlPatterns =  {"/getpois"})
public class PointsServlet extends HttpServlet {
	private static final long serialVersionUID = 1L; 	
	
    /**
     * @see javax.servlet.http.HttpServlet#HttpServlet()
     */
    public PointsServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doPost(request, response);
	}

	/**
	 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String bbox= request.getParameter("bbox");
	    int z = Integer.parseInt(request.getParameter("z").toString());
	    System.out.println(z+","+bbox);
	    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]);
	    
		JdbcTemplate jdbcTemplate = (JdbcTemplate) SpringUtil.getBean("jdbcTemplate");
        String sqlQuery = "select * from county where x>=? and x<=? and y>=? and y<=?";
        List<Map<String, Object>> list =  jdbcTemplate.queryForList(sqlQuery, new Object[]{xmin,xmax,ymin,ymax});
        JSON json = JSONArray.fromObject(list);	    
	    response.setContentType("text/html;charset=utf-8");
	    PrintWriter out = response.getWriter();
	    out.println(json);
	    out.flush();
	    out.close();
	}
}

2、前台实现

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>openlayers map</title>
    <link rel="stylesheet" href="http://localhost:63342/lzugis/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;
        }
    </style>
    <script src="http://localhost:63342/lzugis/plugin/OpenLayers-2.13.1/OpenLayers.js"></script>
    <script src="http://localhost:63342/lzugis/plugin/jquery/jquery-1.8.3.js"></script>
    <script src="http://localhost:63342/lzugis/example/openlayers/ol2/extend/Grid.js"></script>
    <script>
        var map, sld;
        $(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 tiled = new OpenLayers.Layer.WMS(
                    "Geoserver layers - Tiled",
                    "http://localhost:8088/geoserver/lzugis/wms",
                    {
                        "LAYERS": 'province',
                        "STYLES": '',
                        format: format
                    },
                    {
                        buffer: 0,
                        displayOutsideMaxExtent: true,
                        isBaseLayer: true,
                        yx : {'EPSG:4326' : true}
                    }
            );
            map.addLayers([tiled]);
            OpenLayers.INCHES_PER_UNIT["千米"] = OpenLayers.INCHES_PER_UNIT["km"];
            OpenLayers.INCHES_PER_UNIT["米"] = OpenLayers.INCHES_PER_UNIT["m"];
            OpenLayers.INCHES_PER_UNIT["英里"] = OpenLayers.INCHES_PER_UNIT["mi"];
            OpenLayers.INCHES_PER_UNIT["英寸"] = OpenLayers.INCHES_PER_UNIT["ft"];
            //比例尺
            map.addControl(new OpenLayers.Control.ScaleLine({topOutUnits:"千米",topInUnits:"米",bottomOutUnits:"英里",
                bottomInUnits:"英寸"
            }));
            map.addControl(new OpenLayers.Control.Zoom());
            map.addControl(new OpenLayers.Control.Navigation());
            map.addControl(new OpenLayers.Control.OverviewMap());
            map.zoomToExtent(bounds);

            var baseName = "http://localhost:8081/lzugis/getpois";
            var protocol = new OpenLayers.Protocol.HTTP({
                url: baseName
            });
            var strategy = new OpenLayers.Strategy.Grid();
            var vectors = new OpenLayers.Layer.Vector("Vector", {
                strategies: [strategy],
                protocol: protocol
            });
            map.addLayer(vectors);
            var options = {
                hover: true
            };
            var select = new OpenLayers.Control.SelectFeature(vectors, options);
            map.addControl(select);
            select.activate();
        });
    </script>
</head>
<body>
<div id="map">
</div>
</body>
</html>

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

代码语言:javascript
复制
OpenLayers.Strategy.Grid = OpenLayers.Class(OpenLayers.Strategy, {
    grid: null,
    buffer: 1,
    loadedBounds: null,
    zoom: null,
    geometryFeatureMap: {},
    tiles: {},
    initialize: function(options) {
        OpenLayers.Strategy.prototype.initialize.apply(this, [options]);
    },

    destroy: function() {
        this.clearGrid();
        this.grid = null;
        this.tileSize = null;
        OpenLayers.Strategy.prototype.destroy.apply(this, arguments);
    },

    activate: function() {
        var activated = OpenLayers.Strategy.prototype.activate.call(this);
        if(activated) {
            this.layer.events.on({
                "moveend": this.update,
                "refresh": this.update,
                scope: this
            });
            if(this.layer.visibility == true || this.preload) {
                this.update();
            }
            else {
                this.layer.events.on({
                    "visibilitychanged": this.load,
                    scope: this
                });
            }
        }
        
        return activated;
    },

    deactivate: function() {
        var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);
        if(deactivated) {
            this.layer.events.un({
                "moveend": this.update,
                "refresh": this.update,
                "visibilitychanged": this.load,
                scope: this
            });
        }
        return deactivated;
    },

    loadData: function(bbox,zoom) {
        var scope = this;
        var url = scope.layer.protocol.url+"?bbox="+bbox+"&z="+zoom;
        $.ajax({
            type : "POST",
            cache: false,
            url : url,
            async : false,
            success : function(data) {
                scope.readDone(data);
            }
        });
    },

    update: function() {
        var bounds = this.layer.map.getExtent();
        if (bounds == null) return;
        var map = this.layer.map
        var curZoom = map.zoom;
        if (curZoom != this.zoom) {
            this.layer.destroyFeatures();
            this.geometryFeatureMap = {};
            this.tiles = {};
            this.zoom = curZoom
        }
        this.loadData(bounds.toBBOX(),curZoom);
    },

    readDone: function(data) {
        this.merge(data, this.options);
    },

    merge: function(data, options) { 
        var data = eval("("+data+")");
        console.log("供查询到"+data.length+"条数据");
        if(data.length > 0) {  
            var features = [];          
            for(var i=0, len=data.length; i<len; ++i) {
                var d = data[i];
                var feature = new OpenLayers.Feature.Vector(
                        new OpenLayers.Geometry.Point(d.x, d.y),
                        d
                );
                features.push(feature);
            }
            this.layer.addFeatures(features);
        }
    },
    CLASS_NAME: "OpenLayers.Strategy.Grid"
});
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年07月05日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档