抓取百度地图瓦片(离线GIS)

项目需要用到离线GIS,研究了一下,做个记录

需要百度离线api的js

参考:
于忠达 https://my.oschina.net/smzd/blog/548538
giao00000 https://blog.csdn.net/wml00000/article/details/82219015

第一个是api2.0 第二个是在此基础上的3.0,我用的是2.0
使用起来和在线的差不多,引入api.js就可以,具体看大佬博客吧

另外一个是地图瓦片,因为是离线地图,所以需要把地图资源下载到本地,百度地图背景是一张张的图片,比如放大级别(zoom)是1,是一张最大的图,放大级别为2,地图会被拆成4份,放大级别为3,地图会被拆成16份 ,这样理解。
地图瓦片的坐标是(zoom,x,y)三元素,zoom是缩放级别,X是横坐标,Y是纵坐标,左下角为原点,具体看下图。

坐标轴
15级

比如你想抓15级地图,目测一个矩形区域,找到左下角的一个点,一路放大到需要的级别,看下x,y的范围即可
在这里插入图片描述
中国地图15级范围

左下x左下y右上x右上y
15382562686143301

网上很多抓取瓦片的工具,不是有水印,就是要收费,所以自己写了个爬虫去爬。

首先一个配置文件,定义级别和范围,存储路径,线程数
config.properties

zIndex=15
left-bottom-x=3825
left-bottom-y=626
right-top-x=8614
right-top-y=3301
thread-size=10
#\u76EE\u5F55\u540E\u9762\u4E0D\u52A0\u659C\u7EBF\u662F\u50BB\u903C
savepath=D:\\work\\tiles\\tiles\\

主进程读取配置信息,启动线程

static
    {
        Properties pro = new Properties();
        try
        {
            // 开发用这一行 读取当前目录配置文件
            // pro.load(Demo1.class.getResourceAsStream("config.properties"));
            // 打jar包用这一行 方便外部修改配置文件
            pro.load(new FileInputStream("config.properties"));
            zIndex = pro.getProperty("zIndex");
            savePath = pro.getProperty("savepath");
            String leftbottomx = pro.getProperty("left-bottom-x");
            String leftbottomy = pro.getProperty("left-bottom-y");
            String righttopx = pro.getProperty("right-top-x");
            String righttopy = pro.getProperty("right-top-y");
            String threadsize = pro.getProperty("thread-size");
            xmin = Integer.valueOf(leftbottomx);
            ymin = Integer.valueOf(leftbottomy);
            xmax = Integer.valueOf(righttopx);
            ymax = Integer.valueOf(righttopy);
            threadSize = Integer.valueOf(threadsize);
            System.out.println("读取数据完成xmin:" + xmin + " ymin:" + ymin + " xmax:"
                    + xmax + " ymax:" + ymax);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
}

根据线程数确定每个线程的任务,线程池什么的都没用,直接跑把。。。

private void getImg()
    {

        // 以x分开多线程
        Integer needRunTaskSize = xmax - xmin;
        Integer erevtSize = needRunTaskSize / threadSize;

        for (int i = 0; i < threadSize; i++)
        {
            // 算出这个线程的范围
            ImgTask imgTask = new ImgTask(zIndex, erevtSize * (i) + xmin,
                    erevtSize * (i + 1) + xmin, ymin, ymax);
            imgTask.setSavePath(savePath);
            imgTask.start();
        }

        int lave = needRunTaskSize % threadSize;
        if (lave != 0)
        {
            // 多跑一个处理剩余的
            ImgTask imgTask = new ImgTask(zIndex, xmax - lave, xmax, ymin,
                    ymax);
            imgTask.setSavePath(savePath);
            imgTask.start();
        }
}

单个任务的话,只要从网上拿到图片保存起来就ok
在这里插入图片描述

这是个日志文件根据当前任务的范围命名,记录任务状态,下面的都写在了run()里面

File logfile = new File(xmin + "to" + xmax);
BufferedWriter bWriter = null;
if (!logfile.exists())
{
    try
    {
        logfile.createNewFile();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}
try
{
    bWriter = new BufferedWriter(new OutputStreamWriter(
            new FileOutputStream(logfile, true), "utf-8"));
}
catch (UnsupportedEncodingException e)
{
    e.printStackTrace();
}
catch (FileNotFoundException e1)
{
    e1.printStackTrace();
}

接下来就是根据参数构建url,这个url可以去官网随便找个demo看下最新的网址是什么,udt=20181205这个参数越新,数据也就越新。
先去判断是不是有这个文件了,有的话就不用请求了,比如任务中断了,下次再跑不用把前面的再请求一遍。

String link = "http://online0.map.bdimg.com/tile/?qt=vtile&x={x}&y={y}&z={z}&styles=pl&scaler=1&udt=20181205&xxx={rand}";
for (int i = xmin; i <= xmax; i++)
{ // 循环X
    for (int j = ymin; j <= ymax; j++)
    { // 循环Y
        try
        {
            File dir = new File(savePath + z + "/" + i);
            if (!dir.exists())
            {
                dir.mkdirs();
            }
            File file = new File(
                    savePath + z + "/" + i + "/" + j + ".png");
            // System.out.println(file);
            if (!file.exists())
            {
                file.createNewFile();
            }
            else
            {
                bWriter.write("文件存在跳过" + file);
                bWriter.newLine();
                bWriter.flush();
                System.out.println("文件存在跳过" + file);
                continue;
            }

如果本地没有这个文件,那就下载下来

URL url = new URL(link.replace("{x}", i + "")
        .replace("{y}", j + "").replace("{z}", z + "")
        .replace("{rand}", new Date().getTime() + ""));
//System.out.println(url);
HttpURLConnection conn = (HttpURLConnection) url
        .openConnection();
conn.setConnectTimeout(100);
conn.connect();
InputStream in = conn.getInputStream();
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();
bWriter.write("成功下载" + file);
bWriter.newLine();
bWriter.flush();

然后导出个jar包,放在那里跑把

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

15级抓完有10个G, 1-14级才2个多G
在这里插入图片描述

代码仍在了这里
https://gitee.com/localhost_liangbing/baiduTiles

  • 7
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值