本文是使用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改为发布的地址,即使用本地切片。
四、需要完善
后续完善可以通过在页面上框选下载范围、选择下载级别、选择地图类型、以及断开重连等,达到更好的使用效果和用户交互。