利用线程池下载百度地图瓦片图详解编程语言
2023-06-13 09:11:48 时间
继上一文章,百度地图离线功能,这里主要讲述下载瓦片图具体方法。
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++; }
包装一下方便使用
其中,baiduMap.properties的link为下载地址,rootDir为存储地址
BaiDuMapDownloadByThreadPool.java代码如下
package com.autumn.dao; import java.io.File; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.Properties; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; * 下载图片 public class BaiDuMapDownloadByThreadPool { public static void main(String[] args) throws Exception { //根据properties文件配置url和存储路径 Properties properties = new Properties(); File file = new File("classpath:baiduMap.properties"); InputStream inputStream = BaiDuMapDownloadByThreadPool.class.getResourceAsStream("baiduMap.properties"); //判断是否有此文件 if (inputStream!=null) { properties.load(inputStream); String link = properties.getProperty("link"); if (link!=null !link.isEmpty()){ BDTask.link=link; String rootDir = properties.getProperty("rootDir"); if (rootDir!=null !rootDir.isEmpty()){ BDTask.rootDir=rootDir; BDTask.startDownload(); * 线程池下载图片 class BDTask implements Runnable { //正常百度地图String link = "http://online3.map.bdimg.com/onlinelabel/?qt=tile x={x} y={y} z={z} styles=pl udt=20170712 scaler=1 p=1"; //午夜蓝版 static String link ="http://api0.map.bdimg.com/customimage/tile? x={x} y={y} z={z} udt=20180711 scale=1 ak=0F7691e465f5d7d161a4771f48ee38ff styles=t%3Awater%7Ce%3Aall%7Cc%3A%23021019%2Ct%3Ahighway%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Ahighway%7Ce%3Ag.s%7Cc%3A%23147a92%2Ct%3Aarterial%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Aarterial%7Ce%3Ag.s%7Cc%3A%230b3d51%2Ct%3Alocal%7Ce%3Ag%7Cc%3A%23000000%2Ct%3Aland%7Ce%3Aall%7Cc%3A%2308304b%2Ct%3Arailway%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Arailway%7Ce%3Ag.s%7Cc%3A%2308304b%2Ct%3Asubway%7Ce%3Ag%7Cl%3A-70%2Ct%3Abuilding%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Aall%7Ce%3Al.t.f%7Cc%3A%23857f7f%2Ct%3Aall%7Ce%3Al.t.s%7Cc%3A%23000000%2Ct%3Abuilding%7Ce%3Ag%7Cc%3A%23022338%2Ct%3Agreen%7Ce%3Ag%7Cc%3A%23062032%2Ct%3Aboundary%7Ce%3Aall%7Cc%3A%231e1c1c%2Ct%3Amanmade%7Ce%3Ag%7Cc%3A%23022338%2Ct%3Apoi%7Ce%3Aall%7Cv%3Aoff%2Ct%3Aall%7Ce%3Al.i%7Cv%3Aoff%2Ct%3Aall%7Ce%3Al.t.f%7Cv%3Aon%7Cc%3A%232da0c6";; static String rootDir = "d:/mybaidumapdownload1"; 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 startDownload() { ThreadPoolExecutor threadPoolExecutor = null; long start = 0L; for(Level c : Level.values()){ int z = c.getLevel(); int xmin = c.getX_min(); int xmax = c.getX_max(); int ymin = c.getY_min(); int ymax = c.getY_max(); start = System.currentTimeMillis(); //开始时间 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(); //此种方法会一直创建线程导致死机 /*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结束 threadPoolExecutor.shutdown(); //关闭线程池 while (!threadPoolExecutor.isTerminated()) { } //所有任务被执行完毕时继续往下执行 System.out.println("-------用时-------:" + (System.currentTimeMillis() - start)); 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 file = new File(rootDir+"/tiles/" + z + "/" + i + "/" + j + ".jpg"); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); 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++; * 枚举类型,这里所有的等级和xy轴数据为扬州的地图 * 等级 x最小 x最大 y最小 y最大 enum Level { Level_3(3, 1, 1, 0, 0), Level_4(4, 3, 3, 0, 0), Level_5(5, 6, 6, 1, 3), Level_6(6, 12, 12, 3, 3), Level_7(7, 25, 25, 7, 7), Level_8(8, 50, 50, 14, 14), Level_9(9, 101, 101, 28, 29), Level_10(10, 202, 203, 57, 59), Level_11(11, 404, 407, 115, 119), Level_12(12, 808, 814, 230,239), Level_13(13, 1617, 1629, 460, 480), Level_14(14, 3234, 3259, 920, 960), Level_15(15, 6469, 6518, 1840, 1920), Level_16(16, 12939, 13036, 3680, 3850), Level_17(17, 25878, 26073, 7360, 7670), Level_18(18, 51757, 52146, 14720,15400), Level_19(19, 103514, 104292, 29400,30700); private int level; private int x_min; private int x_max; private int y_min; private int y_max; Level(int level, int x_min, int x_max, int y_min, int y_max) { this.level = level; this.x_min = x_min; this.x_max = x_max; this.y_min = y_min; this.y_max = y_max; public int getLevel() { return level; public int getX_min() { return x_min; public int getX_max() { return x_max; public int getY_min() { return y_min; public int getY_max() { return y_max; }
源码
17821.html
cjava相关文章
- 下载大文件绕过百度云管家方法
- 从普通双非到百度算法岗,优秀!
- 实战解析:真实AI场景下,极小目标检测与精度提升 | 百度AI公开课
- 刚刚,百度文心一言揭开面纱!能续写《三体》,算“鸡兔同笼”题,将开启首批内测
- 百度地图:2022年度中国城市交通报告
- 百度高德地图行政区域边界GeoJSON数据获取并绘制行政区域
- Python多线程结合队列下载百度音乐代码详解编程语言
- 使用百度云下载Linux镜像,轻松解决系统安装问题(linux镜像百度云)
- Linux下载百度云:实现系统上的云盘体验(linux下载百度网盘)
- 尚观Oracle云服务上百度一体化(尚观oracle百度云)
- 百度新政策禁止网站强制跳转APP 但百度自己依然强迫下载百度APP
- Oracle下载:百度云盘安全可靠(oracle下载百度云盘)
- 百度文库、网盘、QQ音乐年卡大促 半价抄底:99元起
- 专访|百度IDL负责人林元庆:告别蹒跚 AI大幕已启
- Redis入门视频教程:免费下载百度云资源(redis视频教程百度云)
- Oracle在百度云上载快速极速体验(oracle百度云下载)
- Oracle教程:百度云实现快速学习(oracle教程百度云)
- Linux下载百度云快速、安全、便捷(linux如何下载百度云)
- Redis高级教程学习百度云课堂(redis高级视频百度云)
- Oracle书籍百度云盘版本下载(oracle书籍百度云盘)
- 百度主任架构师「跨界」AI制药、连拿7亿元融资,望石智慧有何过人之处?
- 百度百家号关键词搜索管理是什么、有什么作用及为什么审核通不过?
- 7nm自研 百度昆仑芯2量产:性能提升2-3倍、已与国产OS适配
- 百度留言本js大家可以参考下