Openlayers4+servlet实现切片的本地缓存
时间:2022-06-13
本文章向大家介绍Openlayers4+servlet实现切片的本地缓存,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
概述
本文实现的是结合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;
}
}
- Go实现短url项目
- 【Go 语言社区】GO语言多核并行化的问题
- mysql执行计划看是否最优
- 通过IP定位区域的SQL优化思路(r10笔记第10天)
- Java基础-day06-知识点回顾与练习
- 【Go 语言社区】Golang语言的多核并行化例子
- 一条SQL语句的执行计划变化探究(r10笔记第9天)
- 【Go 语言社区】Web 通信 之 长连接、长轮询(long polling)--转
- Dubbo入门-协议;注册中心
- Oracle 12c PDB浅析(二)(r8笔记第29天)
- 【Go 语言社区】在 Go 语言中,如何正确的使用并发
- Data Guard高级玩法:通过闪回恢复failover备库 (r10笔记第7天)
- ajax跨域问题-web开发必会
- 在线重定义的补充测试(r10笔记第26天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 0794-5.16.2-Hive和Imapla查询decimal类型结果不同异常
- 利用TFRecords存储于读取带标签的图片
- matlab sum函数
- [tensorflow损失函数系列]softmax_cross_entropy_with_logits
- RESTful API 设计最佳实践
- Spring 是如何解决循环依赖的?
- 移动webhead参数
- 看了这篇泛型,下次设计链表别傻傻的用int 表示node节点的值了
- 标准TensorFlow格式 TFRecords
- LeetCode 05最长回文子串
- 基于NCNN的3x3可分离卷积再思考盒子滤波
- [译]Buidler 新手教程
- tf.train.shuffle_batch函数解析
- 网页小图标Favicon
- ASP.net Core MVC项目给js文件添加版本号