继上一文章,百度地图离线功能,这里主要讲述下载瓦片图具体方法。
1.利用全能电子地图下载带水印的瓦片图。其中文件夹路径为tile/层级/x/y.jpg,如下图所示,全能电子地图1.9下载的百度地图瓦片图是一个个黑点。
2.根据图片url下载图片,根据URL获取HttpURLConnection, 根据HttpURLConnection获取输入流InputStream ,在用输出流OutputStream out = new FileOutputStream(file);将字节写入文件即可。代码如下:
/*** 下载图片*/
public classBaiDuMapDownload {static volatile Integer c = 0;//成功数
static volatile Integer fail = 0;//失败数量
public static voidmain(String[] args)throwsException {
String link= "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&udt=20170712&scaler=1&p=1";int z = 19;//层级
int xmin = 103514;//x最小值
int xmax = 104292;//x最大值
int ymin = 29400;//y最小值
int ymax = 30700;//y最大值
for (int i = xmin; i <= xmax; i++) { //循环X
for (int j = ymin; j <= ymax; j++) { //循环Y
try{
URL url= new URL(link.replace("{x}", i + "").replace("{y}", j + "").replace("{z}", z + ""));
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(100);
conn.connect();
InputStream in=conn.getInputStream();
File dir= new File("d:/mybaidumapdownload1/tiles/" + z + "/" +i);if (!dir.exists()) {
dir.mkdirs();
}
File file= new File("d:/mybaidumapdownload1/tiles/" + z + "/" + i + "/" + j + ".jpg");if (!file.exists()) {
file.createNewFile();
}
OutputStream out= newFileOutputStream(file);byte[] bytes = new byte[1024 * 20];int len = 0;while ((len = in.read(bytes)) != -1) {
out.write(bytes,0, len);
}
out.close();
in.close();//System.out.println("已成功下载:" + z + "_" + i + "_" + j + ".jpg");
c++;
}catch(Exception e) {
System.out.println(e.getMessage());
fail++;
}
}//循环Y结束
} //循环X结束
Thread.sleep(1000);
System.out.println("共下载: " + c + " 张");
System.out.println("失败: " + fail + " 张");
}
}
3.通过上面的代码就可以下载百度图片,但是很明显,上面代码是单线程,而且会IO阻塞,百度地图下载到第19级时有将近一百万的瓦片图。下面是线程池ThreadPoolExecutor
优化下代码。本来两天才能下完的图时间缩减一天会感觉很棒。
/*** 线程池下载图片*/
class BDTask implementsRunnable{
String link;int i; //x坐标
int j; //y坐标
int z; //缩放级别
static volatile Integer c = 0;//成功数
static volatile Integer fail = 0;//失败数量
public BDTask(String link, int i, int j, intz) {this.link =link;this.i =i;this.j =j;this.z =z;
}public static voidmain(String[] args)throwsException {
String link= "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&udt=20170712&scaler=1&p=1";int z = 12; //层级
int xmin = 808; //x最小值
int xmax = 814; //x最大值
int ymin = 230; //y最小值
int ymax = 239; //y最大值
//创建线程池,corePoolSize两条线程,最大存在四条线程,大于corePoolSize小于MaxmumPoolSize的线程等待空闲时间为500毫秒,任务队列LinkBlockingQueue不写时的默认值为Integer默认值.
ThreadPoolExecutor threadPoolExecutor= new ThreadPoolExecutor(2,4,500, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());for (int i = xmin; i <= xmax; i++) { //循环X
for (int j = ymin; j <= ymax; j++) { //循环Y
threadPoolExecutor.execute(newBDTask(link,i,j,z));//new Thread(new BDTask(link,i,j,z)).start();//此种方法会一直创建线程导致死机
} //循环Y结束
} //循环X结束
threadPoolExecutor.shutdown(); //关闭线程池
while (!threadPoolExecutor.isTerminated()){} //一直循环等到所有任务被执行完毕时继续往下执行
System.out.println("共下载: " + c + " 张");
System.out.println("失败: " + fail + " 张");
}public voidrun() {try{
URL url= new URL(link.replace("{x}", i + "").replace("{y}", j + "").replace("{z}", z + ""));
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(100);
conn.connect();
InputStream in=conn.getInputStream();
File dir= new File("d:/mybaidumapdownload1/tiles/" + z + "/" +i);if (!dir.exists()) {
dir.mkdirs();
}
File file= new File("d:/mybaidumapdownload1/tiles/" + z + "/" + i + "/" + j + ".jpg");if (!file.exists()) {
file.createNewFile();
}
OutputStream out= newFileOutputStream(file);byte[] bytes = new byte[1024 * 20];int len = 0;while ((len = in.read(bytes)) != -1) {
out.write(bytes,0, len);
}
out.close();
in.close();synchronized(fail) {
c++;
}
}catch(Exception e) {
System.out.println(e.getMessage());synchronized(c) {
fail++;
}
}
}
}