java开发百度地图瓦片_利用线程池下载百度地图瓦片图(示例代码)

继上一文章,百度地图离线功能,这里主要讲述下载瓦片图具体方法。

1.利用全能电子地图下载带水印的瓦片图。其中文件夹路径为tile/层级/x/y.jpg,如下图所示,全能电子地图1.9下载的百度地图瓦片图是一个个黑点。

lazy.gif

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++;

}

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值