标签:get adp 时间 pen fail .sh 通过 unit map
继上一文章,百度地图离线功能,这里主要讲述下载瓦片图具体方法。
1.利用全能电子地图下载带水印的瓦片图。其中文件夹路径为tile/层级/x/y.jpg,如下图所示,全能电子地图1.9下载的百度地图瓦片图是一个个黑点。
2.根据图片url下载图片,根据URL获取HttpURLConnection, 根据HttpURLConnection获取输入流InputStream ,在用输出流OutputStream out = new FileOutputStream(file);将字节写入文件即可。代码如下:
/** * 下载图片 */ public class BaiDuMapDownload { static volatile Integer c = 0;//成功数 static volatile Integer fail = 0;//失败数量
public static void main(String[] args) throws Exception { 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 = new FileOutputStream(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 implements Runnable{ 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, int z) { this.link = link; this.i = i; this.j = j; this.z = z; } public static void main(String[] args) throws Exception { 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<Runnable>()); for (int i = xmin; i <= xmax; i++) { //循环X for (int j = ymin; j <= ymax; j++) { //循环Y threadPoolExecutor.execute(new BDTask(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 void run() { 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 = new FileOutputStream(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++; } } } }
标签:get adp 时间 pen fail .sh 通过 unit map
原文地址:https://www.cnblogs.com/aeolian/p/8761430.html