gis地图相关开发常用到天地图等地图服务作为底图使用,但是内网环境访问不到在线的服务,我们可以把地图瓦片下载下来发布。大概实现原理就是通过经纬度范围计算瓦片的x、y、z,然后组装成请求瓦片的url,然后把请求的资源保存到本地。
文章目录
目录
一、地图瓦片是什么?
二、实现代码
一、地图瓦片是什么?
瓦片地图金字塔模型是一种多分辨率层次模型,从瓦片金字塔的底层到顶层,分辨率越来越低,但表示的地理范围不变。首先确定地图服务平台所要提供的缩放级别的数量N,把缩放级别最高、地图比例尺最大的地图图片作为金字塔的底层,即第0层,并对其进行分块,从地图图片的左上角开始,从左至右、从上到下进行切割,分割成相同大小(比如256x256像素)的正方形地图瓦片,形成第0层瓦片矩阵;在第0层地图图片的基础上,按每像素分割为2×2个像素的方法生成第1层地图图片,并对其进行分块,分割成与下一层相同大小的正方形地图瓦片,形成第1层瓦片矩阵;采用同样的方法生成第2层瓦片矩阵;…;如此下去,直到第N一1层,构成整个瓦片金字塔。
二、实现代码
根据经纬度获取瓦片坐标,算法参考Slippy map tilenames - OpenStreetMap Wiki, 各种语言的实现都有。
public static void getGoogleMap(double [] startPoint,double [] endPoint,int [] z,String src,String targetDir) throws IOException {
// int zoom = 15;
double minlat = startPoint[0]; //35.522920921
double minlon = startPoint[1];//103.480619123
double maxlat = endPoint[0];//36.033726441
double maxlon = endPoint[1];//103.520211928
for (int k = z[0]; k <= z[z.length - 1]; k ++){
Map minMap = getTileNumber(minlat, minlon, k);
Map maxMap = getTileNumber(maxlat, maxlon, k);
int minX = minMap.get("x");
int minY = minMap.get("y") ;
int maxX = maxMap.get("x");
int maxY = maxMap.get("y");
//
ExecutorService service = Executors.newFixedThreadPool(100);
for (int i = minX; i <= maxX; i++) {
for (int j = minY; j <= maxY; j++) {
String url = String.format(src, k, i, j);
System.out.println(url);
Runnable runnable = new MyRunnable() {
String url,targetDir;
int i,j,k;
@Override
public MyRunnable setOptions(String url, int i, int j, int k, String targetDir) {
this.url = url;
this.i = i;
this.j = j;
this.k = k;
this.targetDir = targetDir;
return this;
}
@Override
public void run() {
try {
downLaodImages(this.url, this.i, this.j, this.k,this.targetDir);
} catch (Exception e) {
e.printStackTrace();
}
}
};
((MyRunnable) runnable).setOptions(url, i, j, k,targetDir);
service.execute(runnable);
}
}
}
}
public static Map getTileNumber(final double lat, final double lon, final int zoom) {
Map map = new HashMap<>();
int xtile = (int)Math.floor( (lon + 180) / 360 * (1<= (1<= (1<
根据瓦片的url下载瓦片保存到本地
public static void downLaodImages(String url,int x,int y, int z,String targetDir) throws IOException {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8");
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
File zFile = new File(targetDir+"\"+z);
if(!zFile.exists()){
zFile.mkdir();
}
File xFile = new File(targetDir+"\"+z+"\"+x);
if(!xFile.exists()){
xFile.mkdir();
}
DataInputStream dataInputStream = new DataInputStream(conn.getInputStream()) ;;
FileOutputStream fileOutputStream;
//根据坐标 x y z生成文件名 下载png无损图片
String imageName = targetDir+"\"+z+"\"+x+"\"+y+".png";
fileOutputStream = new FileOutputStream(new File(imageName));
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = dataInputStream.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
fileOutputStream.write(output.toByteArray());
dataInputStream.close();
fileOutputStream.close();
output.close();
System.out.println("已完成下载!");
}



