美文网首页Gis专辑GISGIS之家
Openlayers4+servlet实现切片的本地缓存

Openlayers4+servlet实现切片的本地缓存

作者: 牛老师讲webgis | 来源:发表于2017-10-16 18:00 被阅读90次

    概述

    本文实现的是结合Openlayers4和java servlet实现公网资源切片的本地缓存。

    优点

    相比较其他下载利器,本实例具有以下优点:

    1. 实现简单,操作简单;
    2. 不会出现IP被封;
    3. 结合web,看到哪下到哪,主动保存未缓存的切片;
    4. 可通过修改URL和代码缓存多种地图切片。

    缺点

    鉴于web的实现,该切片缓存的方式具有以下缺点:

    1. 被动式缓存,需要用户浏览需要下载的区域;
    2. 无法批量缓存。
    3. 主要是针对开发人员的,非开发人员使用有困难;

    实现效果

    操作页面 缓存文件 缓存切片

    实现思路

    实现流程

    实现代码

    页面代码

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>切片下载</title>
        <link rel="stylesheet" href="https://openlayers.org/en/v4.1.1/css/ol.css" type="text/css">
        <style type="text/css">
            body, #map {
                border: 0px;
                margin: 0px;
                padding: 0px;
                width: 100%;
                height: 100%;
                font-size: 13px;
                overflow: hidden;
            }
        </style>
        <script src="https://openlayers.org/en/v4.1.1/build/ol.js"></script>
        <script type="text/javascript" src="plugin/jquery/jquery-3.1.1.min.js"></script>
        <script type="text/javascript">
            var map;
            function init(){
                var cva_w = getGeoheyLayer("blue");
                var province = new ol.layer.Image({
                    source: new ol.source.ImageWMS({
                        ratio: 1,
                        url: 'http://localhost:6080/geoserver/bj_grid/wms',
                        params: {
                            'FORMAT': 'image/png',
                            'VERSION': '1.1.1',
                            STYLES: '',
                            LAYERS: 'bj_grid:bou2_4p',
                        }
                    })
                });
                map = new ol.Map({
                    controls: ol.control.defaults({
                        attribution: false
                    }),
                    target: 'map',
                    layers: [cva_w, province],
                    view: new ol.View({
                        center: ol.proj.transform([104.214, 35.847], 'EPSG:4326', 'EPSG:3857'),
                        zoom: 4
                    })
                });
            }
            function getGeoheyLayer(style){
                var url = "http://localhost:8081/lzugis-web/tile?layer="+style+"&z={z}&x={x}&y={y}";
                var layer = new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url:url
                    })
                });
                return layer;
            }
        </script>
    </head>
    <body onLoad="init()">
    <div id="map">
    </div>
    </body>
    </html>
    

    servlet代码

    package com.lzugis.web.servlet;
    
    import com.lzugis.web.helper.CommonConfig;
    
    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 java.awt.image.BufferedImage;
    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    /**
     * Created by admin on 2017/9/10.
     */
    @WebServlet(description = "wms services", urlPatterns =  {"/tile"})
    public class TileServiceServlet extends HttpServlet {
    
        private String url = "https://s4.geohey.com/s/mapping/";
        private String tilepath = "d:/tile/geohey/";
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String x = request.getParameter("x"),
                    y = request.getParameter("y"),
                    z = request.getParameter("z"),
                    layer = request.getParameter("layer");
    
            StringBuffer tileUrl = new StringBuffer();
            tileUrl.append(url);
            tileUrl.append(layer+"/all?");
            tileUrl.append("z="+z+"&x="+x+"&y="+y);
            tileUrl.append("&retina=&ak=MGUxMmI2ZTk4YTVhNDEzYmJhZDJkNDM3ZWI5ZDAwOGE");
    
            String tilefile = tilepath+layer+"/"+z+"/"+x+"_"+y+".png";
            File tile = new File(tilefile);
            byte[] tileByte = null;
            /**
             * 如果文件存在,则直接读取文件
             * 如果文件不存在,在先保存
             */
            if(tile.exists()){
                tileByte = getFileBytes(tilefile);
            }
            else{
                tileByte = getUrlBytes(tileUrl.toString());
                saveTileFile(tileByte, tilefile);
            }
            OutputStream os = response.getOutputStream();
            InputStream is = new ByteArrayInputStream(tileByte);
            try {
                int count = 0;
                byte[] buffer = new byte[1024 * 1024];
                while ((count = is.read(buffer)) != -1) {
                    os.write(buffer, 0, count);
                }
                os.flush();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                os.close();
                is.close();
            }
        }
    
        private void saveTileFile(byte[] tileByte, String tilefile){
            try {
                BufferedImage bi = null;
                bi = ImageIO.read(new ByteArrayInputStream(tileByte));
                //判断文件夹是否存在,否则创建
                File filetile = new File(tilefile);
                if (!filetile.getParentFile().exists()) {
                    filetile.getParentFile().mkdirs();
                }
                ImageIO.write(bi, "png", filetile);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        private byte[] getFileBytes(String tilefile){
            byte[] buffer = null;
            try {
                File file = new File(tilefile);
                FileInputStream fis = new FileInputStream(file);
                ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
                byte[] b = new byte[1000];
                int n;
                while ((n = fis.read(b)) != -1) {
                    bos.write(b, 0, n);
                }
                fis.close();
                bos.close();
                buffer = bos.toByteArray();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return buffer;
        }
    
        private byte[] getUrlBytes(String tilurl){
            try {
                //new一个URL对象
                URL url = new URL(tilurl);
                //打开链接
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                //设置请求方式为"GET"
                conn.setRequestMethod("GET");
                //超时响应时间为5秒
                conn.setConnectTimeout(5 * 1000);
                //通过输入流获取图片数据
                InputStream inStream = conn.getInputStream();
                //得到图片的二进制数据,以二进制封装得到数据,具有通用性
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                //创建一个Buffer字符串
                byte[] buffer = new byte[1024];
                //每次读取的字符串长度,如果为-1,代表全部读取完毕
                int len = 0;
                //使用一个输入流从buffer里把数据读取出来
                while ((len = inStream.read(buffer)) != -1) {
                    //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
                    outStream.write(buffer, 0, len);
                }
                //关闭输入流
                inStream.close();
                //把outStream里的数据写入内存
                return outStream.toByteArray();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    类型 内容
    qq 1004740957
    公众号 lzugis15
    e-mail niujp08@qq.com
    webgis群 1004740957
    Android群 337469080
    GIS数据可视化群 458292378

    技术博客
    CSDN:http://blog.csdn.NET/gisshixisheng
    博客园:http://www.cnblogs.com/lzugis/
    在线教程
    http://edu.csdn.Net/course/detail/799
    Github
    https://github.com/lzugis/
    联系方式

    类型 内容
    qq 1004740957
    公众号 lzugis15
    e-mail niujp08@qq.com
    webgis群 1004740957
    Android群 337469080
    GIS数据可视化群 458292378
    LZUGIS

    相关文章

      网友评论

        本文标题:Openlayers4+servlet实现切片的本地缓存

        本文链接:https://www.haomeiwen.com/subject/ockluxtx.html