下载谷歌离线地图瓦片图「建议收藏」

下载谷歌离线地图瓦片图「建议收藏」项目中遇到一个需求,需要将某个地图区域的离线地图下载下来,整理很多网上的资料自己实现根据起始点的经纬度下载离线地图,代码如下importjava.io.*;importjava.net.URL;importjava.net.URLConnection;importjava.util.HashMap;importjava.util.Map;importjava.util.zip.ZipEntry;importjava.util.zip.ZipOutputStream;publi

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

项目中遇到一个需求,需要将某个地图区域的离线地图下载下来,整理很多网上的资料自己实现根据起始点的经纬度下载离线地图,代码如下

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Test {
    private static final int  BUFFER_SIZE = 2 * 1024;
    public static void main(String[] args) throws Exception {
    double [] start = new double[]{36.03267263,103.480619123};//最大纬度 最小精度 起点
    double [] end = new double[]{35.522920921,103.520211928};//最小纬度  最大精度  终点
   // 36.03267263 103.480619123 35.522920921 103.520211928
        int [] z = new int[] {8,9};
        /**
         * 谷歌地图地址参数
         * lyrs = 类型
         *
         * h = roads only 路线图
         * m = standard roadmap
         * p = terrain 地形图
         * r = somehow altered roadmap
         * s = satellite only 卫星图
         * t = terrain only
         * y = hybrid 混合
         */
        String src = "http://mt0.google.cn/vt/lyrs=m@180000000&hl=zh-CN&gl=cn&x=%s&y=%s&z=%s&s=Ga";
        String targetDir  ="D:\\map";
        //getGoogleMap(start,end,z,src,targetDir); //获取谷歌地图瓦片图
        getFileInfo(targetDir);//获取下载之后的文件信息
        toZip(targetDir, "D:/map.zip",true);//压缩下载的文件
    }

/**
 * 获取下载之后的文件信息
 * @param targetDir
 */
public static  void getFileInfo(String targetDir){
    File file = new File(targetDir);
    System.out.println("下载后的文件大小:"+file.length()/1024+"M");
    File[] files = file.listFiles();
    for (File f : files){
        String level = f.getName();
        int count =0;
        File[] cfiles = f.listFiles();
        for (File cf : cfiles){
            count+=cf.list().length;
        }
        System.out.println("L"+level+"文件数量: "+count);
    }
}
/**
 * 根据起始点经纬度获取地图信息
 * @param startPoint 数组 如:new double[]{35.522920921,103.480619123};
 * @param endPoint 数组 如:new double[]{36.033726441,103.520211928};
 * @param z 地图级别 new int[] {8,9}; 0-17
 * @param src 地图下载地址
 * @param targetDir 本地保存的路径
 * @throws IOException
 */
public static void getGoogleMap(double [] startPoint,double [] endPoint,int [] z,String src,String targetDir) throws IOException {
   // int zoom = 15;
    double minlat = startPoint[0]; //35.522920921
    double minlon = startPoint[1];//103.480619123
    double maxlat = endPoint[0];//36.033726441
    double maxlon = endPoint[1];//103.520211928

    for (int k = z[0]; k <= z[1]; k ++){
        Map<String, Integer> minMap = getTileNumber(minlat, minlon, k);
        Map<String, Integer> maxMap = getTileNumber(maxlat, maxlon, k);
       int minX = minMap.get("x");
        int minY = minMap.get("y") ;
        int maxX = maxMap.get("x");
        int maxY = maxMap.get("y");
        //
        for (int i = minX; i <= maxX; i++) {
            for (int j = minY; j <= maxY; j++) {
                String url = String.format(src, i, j, k);
                System.out.println(url);
                downLaodImages(url, i, j, k,targetDir);
            }

        }
    }
}

/**
 * 根据经纬度获取瓦片坐标 算法请参考
 * https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
 * @param lat
 * @param lon
 * @param zoom
 * @return
 */
public static Map getTileNumber(final double lat, final double lon, final int zoom) {
    Map<String,Integer> map = new HashMap<>();
    int xtile = (int)Math.floor( (lon + 180) / 360 * (1<<zoom) ) ;
    int ytile = (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1<<zoom) ) ;
    if (xtile < 0)
        xtile=0;
    if (xtile >= (1<<zoom))
        xtile=((1<<zoom)-1);
    if (ytile < 0)
        ytile=0;
    if (ytile >= (1<<zoom))
        ytile=((1<<zoom)-1);
    map.put("z",zoom);
    map.put("x",xtile);
    map.put("y",ytile);
    return map;
}

/**
 *
 * @param url 下载图片的url
 * @param x
 * @param y
 * @param z
 * @throws IOException
 */
public static void downLaodImages(String url,int x,int y, int z,String targetDir) throws IOException {

    URL realUrl = new URL(url);
    // 打开和URL之间的连接
    URLConnection conn = realUrl.openConnection();
    // 设置通用的请求属性
    conn.setRequestProperty("Accept-Charset", "utf-8");
    conn.setRequestProperty("contentType", "utf-8");
    conn.setRequestProperty("accept", "*/*");
    conn.setRequestProperty("connection", "Keep-Alive");
    conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");


    File zFile = new File(targetDir+"\\"+z);
    if(!zFile.exists()){
        zFile.mkdir();
    }
    File xFile = new File(targetDir+"\\"+z+"\\"+x);
    if(!xFile.exists()){
        xFile.mkdir();
    }
    DataInputStream dataInputStream = new DataInputStream(conn.getInputStream()) ;;
    FileOutputStream fileOutputStream = null;
    //根据坐标 x y z生成文件名 下载png无损图片
    String imageName =  targetDir+"\\"+z+"\\"+x+"\\"+y+".png";
    fileOutputStream = new FileOutputStream(new File(imageName));
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length;
    while ((length = dataInputStream.read(buffer)) > 0) {
        output.write(buffer, 0, length);
    }
    fileOutputStream.write(output.toByteArray());
    dataInputStream.close();
    fileOutputStream.close();
    output.close();
    System.out.println("已完成下载!");
}

/**
 * 压缩
 */

public static void toZip(String srcDir, String outName, boolean KeepDirStructure)
         throws RuntimeException{

             long start = System.currentTimeMillis();ZipOutputStream zos = null ;
             try {
                 FileOutputStream out= new FileOutputStream(new File(outName));
                    zos = new ZipOutputStream(out);
                    File sourceFile = new File(srcDir);
                     compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
                     long end = System.currentTimeMillis();
                    System.out.println("压缩完成,耗时:" + (end - start) +" ms");
                } catch (Exception e) {
                     throw new RuntimeException("zip error",e);
                }finally{
                 if(zos != null){
                     try {
                         zos.close();
                                 } catch (IOException e) {
                                     e.printStackTrace();
                                 }
                        }
                }

         }
private static void compress(File sourceFile, ZipOutputStream zos, String name,
                              boolean KeepDirStructure) throws Exception{
             byte[] buf = new byte[BUFFER_SIZE];
             if(sourceFile.isFile()){
                    // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
                 zos.putNextEntry(new ZipEntry(name));
                    // copy文件到zip输出流中
                     int len;
                     FileInputStream in = new FileInputStream(sourceFile);
                     while ((len = in.read(buf)) != -1){
                             zos.write(buf, 0, len);
                         }
                     // Complete the entry
                    zos.closeEntry();
                     in.close();
                 } else {
                     //是文件夹
                     File[] listFiles = sourceFile.listFiles();
                     if(listFiles == null || listFiles.length == 0){
                            // 需要保留原来的文件结构时,需要对空文件夹进行处理
                            if(KeepDirStructure){
                                    // 空文件夹的处理
                                     zos.putNextEntry(new ZipEntry(name + "/"));
                                     // 没有文件,不需要文件的copy
                                    zos.closeEntry();
                               }

                         }else {
                             for (File file : listFiles) {
                                     // 判断是否需要保留原来的文件结构
                                     if (KeepDirStructure) {
                                             // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
                                             // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
                                             compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
                                         } else {
                                             compress(file, zos, file.getName(),KeepDirStructure);
                                         }

                                 }
                         }
                 }
        }

 }

安利一门Python超级好课!
扫码下单输优惠码【csdnfxzs】再减5元,比官网还便宜!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/191235.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Linux sleep命令[通俗易懂]

    Linux sleep命令[通俗易懂]Linuxsleep命令可以用来将目前动作延迟一段时间。使用权限:所有使用者。语法参数说明:–help:显示辅助讯息–version:显示版本编号number:时间长度,

    2022年7月1日
    21
  • 暴力激活成功教程字典及字典生成器[通俗易懂]

    暴力激活成功教程字典及字典生成器[通俗易懂]GitHub上的:https://github.com/danielmiessler/SecLists/tree/master/Passwords/Leaked-Databaseshttps://

    2022年8月4日
    4
  • python和delphi哪个好_python编程时如何修改撤回

    python和delphi哪个好_python编程时如何修改撤回原博文2020-03-2818:10−复制行,在代码行光标后,输入Ctrl+d,即为复制一行,输入多次即为复制多行撤销上一步操作:Ctrl+z为多行代码加注释#代码选中的条件下,同时按住Ctrl+/,被选中行被注释,再次按下Ctrl+/,注…0319相关推荐2019-12-2423:37−djangoTermipython:manage.pymakemigrati…

    2022年8月27日
    6
  • 常用数据库建模工具

    常用数据库建模工具收藏:http://www.oschina.net/project/tag/83/db-modelIntellij下mybatis插件 MyBatisCodeHelper [国产]MyBatisCodeHelper是Intellij上的mybatis插件,通过java对象生成建表sql,dao,mapperxml文件,方便的生成curd,另外可以通…上次更新:2017…

    2022年7月27日
    5
  • 数据结构–链表的排序详解

    数据结构–链表的排序详解1、前言前面两篇博客,我已经把线性表的两种基本的表示形式,做了一个基本的介绍和一些对比。但是,我突然发现在链表这里我缺少一个很重要的内容,那就是对我们的链表进行排序,其实,在连接两个链表的时候,就要求我们的那两个链表是有序的。2、链表排序—最简单、直接的方式(直接采用冒泡或者选择排序,而且不是交换结点,只交换数据域)//线性表的排序,采用冒泡排序,直接遍历链表voidListsort(Nod

    2022年10月11日
    0
  • staruml使用方法(对讲机按键使用说明)

    综述StarUML是一种生成类图和其他类型的统一建模语言(UML)图表的工具。这是一个用Java语言描述的创建类图的简明手册。StarUML(简称SU),是一种创建UML类图,并能够自动生成Java的“stubcode”的工具。SU也可以做JAVA逆向工程,以产生相应的UML图表。在本教程中,我们将使用SU设计一个pizza饼。执行下列步骤,可以创建如下面所示的UML图。SU可以生…

    2022年4月12日
    71

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号