本文是使用servlet实现网络切片的缓存;再使用openlayers3、4加载发布的切片。
一、切片规则
我们通常可以使用xyz这样的坐标来精确定位一张瓦片。z表示地图层级,x为瓦片坐标横坐标,y为瓦片坐标纵坐标。一般情况下,z的最小值是0,此时x、y值都为0,世界地图由一张瓦片组成;z的值确定的情况下,x的范围为[0,2^z-1],y的范围为[0,2^z-1]。
而对于这种类型的瓦片,openlayers提供了ol.source.XYZ
来加载。
以flightaware地图为例,打开浏览器开发者工具,我们可以明显看到底图的url也是XYZ格式的,因此很容易写出在线地图的加载方式:
var layer = new ol.layer.Tile({
source: new ol.source.XYZ({
url:'http://e1.flightcdn.com/images/tilecache/classic/mobile.2.0.2/{z}/{x}/{y}.png'
}),
projection: 'EPSG:3857'
})
成功加载:
二、使用servlet下载切片
了解切片规则后,我们就可以使用servlet将切片下载到本地
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownLoadGisFiles {
public static void main(String[] args)
{
for(int z=0;z<=10;z++) //层级范围是0-10
{
for(int x=0;x<=Math.pow(2,z)-1;x++)
{
for(int y=0;y<=Math.pow(2,z)-1;y++)
{
String nURI="http://e1.flightcdn.com/images/tilecache/classic/mobile.2.0.2/"+z+"/"+x+"/"+y+".jpeg"; //地图下载
String savePath=z+"/"+x;
String tokens[]= savePath.split("/");
String root="d:/GIS"; //本地存放的目录
String path=root+"/"+z;
File file=new File(path);
if(!file.exists()){
file.mkdirs();
}
String h=root+"/"+z+"/"+x;
File file2=new File(h);
if(!file2.exists()){
file2.mkdirs();
}
saveFile("d:/GIS/"+savePath+"/"+y+".jpeg",nURI);
}
}
}
}
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[10240];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
public static byte[] getImageFromNetByUrl(String strUrl) {
try {
URL url = new URL(strUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();// 通过输入流获取图片数据
byte[] btImg = readInputStream(inStream);// 得到图片的二进制数据
return btImg;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void saveFile(String local,String url)
{
byte[] btImg2 = getImageFromNetByUrl(url);
if (null != btImg2 && btImg2.length > 0) {
try {
File file = new File(local);
FileOutputStream fops = new FileOutputStream(file);
fops.write(btImg2);
fops.flush();
fops.close();
System.out.println("图片已经写入"+local);
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("没有从该连接获得内容");
}
}
}
三、发布和使用本地切片
切片下载到本地之后,我们可以使用tomcat或者iis发布,然后将步骤一中的图层url改为发布的地址,即使用本地切片。
四、需要完善
后续完善可以通过在页面上框选下载范围、选择下载级别、选择地图类型、以及断开重连等,达到更好的使用效果和用户交互。