TiandituDownload.java 6.17 KB
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.*;

public class TiandituDownload {

    double[] res = {
            1.40625,
            0.703125,
            0.3515625,
            0.17578125,
            0.087890625,
            0.0439453125,
            0.02197265625,
            0.010986328125,
            0.0054931640625,
            0.00274658203125,
            0.001373291015625,
            0.0006866455078125,
            0.00034332275390625,
            0.000171661376953125,
            8.58306884765629E-05,
            4.29153442382814E-05,
            2.14576721191407E-05,
            1.07288360595703E-05,
            5.36441802978515E-06,
            2.68220901489258E-06,
            1.34110450744629E-06
    };
    double[] scale = {
            400000000,
            295497598.5708346,
            147748799.285417,
            73874399.6427087,
            36937199.8213544,
            18468599.9106772,
            9234299.95533859,
            4617149.97766929,
            2308574.98883465,
            1154287.49441732,
            577143.747208662,
            288571.873604331,
            144285.936802165,
            72142.9684010827,
            36071.4842005414,
            18035.7421002707,
            9017.87105013534,
            4508.93552506767,
            2254.467762533835,
            1127.2338812669175,
            563.616940
    };

    int minLevel = 1;
    int maxLevel = 2;

    // 保存数据的sqlite文件路径
    String dbpath;

    Connection conn = null;

    Statement stmt = null;

    public TiandituDownload(String dbpath){
        this.dbpath =dbpath;
    }

    private CalEnv calculateEnv(Point originPoint, int level){
        int startX = (int) Math.floor((originPoint.getLng() + 180)/(256 * res[level]));
        int startY = (int) Math.floor((90 - originPoint.getLat())/(256 * res[level]));
        if(startX<0)startX = 0;
        if(startY<0)startY = 0;

        return new CalEnv(startX, startY);
    }

    private void Download(Point minPoint, Point maxPoint, int level, TianDiTuTiledMapServiceType type){

        try{
            CalEnv startEnv = calculateEnv(minPoint, level);
            CalEnv stopEnv = calculateEnv(maxPoint, level);

//            System.out.println(startEnv.getStartX() + ":" +startEnv.getStartY());
//            System.out.println(stopEnv.getStartX() + ":" +stopEnv.getStartY());
            PreparedStatement preparedStatement;
            ResultSet rs;

            for(int i = startEnv.getStartX(); i <= stopEnv.getStartX(); i++){
                for(int j = stopEnv.getStartY(); j<= startEnv.getStartY(); j++){
                    boolean hasData = false;
                    try{
                        // 查询瓦片是否存在
                        String querySQL = "select * from " + type + " where TILELEVEL = " + level + " and TILECOL = " + i + " and TILEROW = " + j;
                        rs = stmt.executeQuery(querySQL);
                        while(rs.next()){
                            hasData = true;
                        }
                        // 如果不存在
                        if(!hasData){
                            String url = new TDTUrl(level, i, j, type).generatUrl();
                            // 获得地图瓦片
                            byte[] img = getTile(url);
                            System.out.println("正在下载 "+url);
                            // 将数据写入sqlite
                            String insertSQL = "INSERT INTO "+ type + "(TILELEVEL,TILECOL,TILEROW,TILEDATA) VALUES (?,?,?,?)";
                            preparedStatement = conn.prepareStatement(insertSQL);
                            preparedStatement.setInt(1, level);
                            preparedStatement.setInt(2, i);
                            preparedStatement.setInt(3, j);
                            preparedStatement.setBytes(4, img);
                            preparedStatement.execute();
                        }
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                }
                conn.commit();
            }
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }

    public void Download(Point minPoint, Point maxPoint, int minLevel, int maxLevel, TianDiTuTiledMapServiceType type) throws SQLException {
        try {
            Class.forName("org.sqlite.JDBC");
            conn = DriverManager.getConnection("jdbc:sqlite:" + this.dbpath);
            conn.setAutoCommit(false);
            stmt = conn.createStatement();
            // 新建数据表
            String sql = "CREATE TABLE IF NOT EXISTS " + type +
                    "(TILELEVEL INT," +
                    "TILECOL INT," +
                    "TILEROW INT," +
                    "TILEDATA BLOB)";
            stmt.executeUpdate(sql);
            stmt.close();

            for(int m = minLevel; m<= maxLevel; m++){
                this.Download(minPoint, maxPoint, m, type);
            }
            conn.close();
            System.out.println("下载完成");

        }catch (Exception e){

        }
    }

    protected byte[] getTile(String url) throws Exception {
        byte[] result = null;
        try {
            // 如果没有就直接从web上读取
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            URL sjwurl = new URL(url);
            HttpURLConnection httpUrl = null;
            BufferedInputStream bis = null;
            byte[] buf = new byte[1024];

            httpUrl = (HttpURLConnection) sjwurl.openConnection();
            httpUrl.connect();
            bis = new BufferedInputStream(httpUrl.getInputStream());

            while (true) {
                int bytes_read = bis.read(buf);
                if (bytes_read > 0) {
                    bos.write(buf, 0, bytes_read);
                } else {
                    break;
                }
            }

            bis.close();
            httpUrl.disconnect();

            result = bos.toByteArray();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return result;
    }
}