多线程下载英文Google地图

 

1. pom.xml文件

 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.smartmap</groupId>
    <artifactId>sano3</artifactId>
    <version>1.0-SNAPSHOT</version>


    <properties>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <slf4j.version>1.7.21</slf4j.version>
        <commmons.collections.version>3.2.1</commmons.collections.version>
        <commons.fileupload.version>1.2.1</commons.fileupload.version>
        <commons.io.version>2.4</commons.io.version>

        <!-- Encoding -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
        <dependency>
            <groupId>org.xerial</groupId>
            <artifactId>sqlite-jdbc</artifactId>
            <version>3.15.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <!--  General data-binding functionality for Jackson: works on core streaming API  -->
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.4</version>
        </dependency>
        <dependency>
            <!--  Json  -->
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20160810</version>
        </dependency>
        <dependency>
            <!--  Core Protocol Buffers library. Protocol Buffers are a way of encoding structured data in an efficient yet extensible format.  -->
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.1.0</version>
        </dependency>

        <dependency>
            <!--  A plugin to allow execution of system and Java programs  -->
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.5.0</version>
        </dependency>
        <dependency>
            <!--  Runs Ant scripts embedded in the POM  -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.8</version>
        </dependency>
        <dependency>
            <!--  The Resources Plugin handles the copying of project resources to the output directory. There are two different kinds of resources: main resources and test resources.   -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <!--    Builds a Java Archive (JAR) file from the compiled project classes and resources.   -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.0.2</version>
        </dependency>
        <dependency>
            <!--  The Compiler Plugin is used to compile the sources of your project. -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <!--  Repackages the project classes together with their dependencies into a single uber-jar, optionally renaming classes or removing unused classes.  -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.3</version>
        </dependency>
        <dependency>
            <!--  The Maven Source Plugin creates a JAR archive of the source files of the current project.  -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.sun.jdmk</groupId>
                    <artifactId>jmxtools</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jmx</groupId>
                    <artifactId>jmxri</artifactId>
                </exclusion>
            </exclusions>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <!--  The slf4j API  -->
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <!--<version>1.7.21</version>-->
            <version>1.5.5</version>
        </dependency>
        <dependency>
            <!--  SLF4J LOG4J-12 Binding  -->
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <!--<version>1.7.21</version>-->
            <version>1.5.5</version>
        </dependency>
        <dependency>
            <!--  Maven Surefire MOJO in maven-surefire-plugin  -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>src/main/java</sourceDirectory>
        <testSourceDirectory>src/test/java</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.5.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <executable>java</executable>
                    <arguments>
                        <argument>-classpath</argument>
                        <classpath>
                        </classpath>
                        <argument>com.smartmap.exam.salon3.App</argument>
                    </arguments>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 

2.  App.java

package com.smartmap.exam.salon3;

import com.smartmap.exam.salon3.tilecache.DownTileMutipleThreadApp;
import com.smartmap.exam.salon3.tilecache.DownTileSingleThreadApp;

/**
 * Created by zyx on 2016/11/5.
 */
public class App {
    public int add(int a, int b) {
        return a + b;
    }
    public int subtract(int a, int b) {
        return a - b;
    }

    public App() {
    }

    public static void main(String args[]) {
        System.out.println("Hello World!");

        int startLevel = 1;
        int endLevel = 7;
        double xmin =  -180;
        double ymin =  -85.05112878;
        double xmax =  180;
        double ymax =  85.05112878;

        //DownTileSingleThreadApp downTile = new DownTileSingleThreadApp();
        //downTile.downTile(startLevel, endLevel, xmin, ymin, xmax, ymax);

        //
        /*
        DownTileSingleThreadApp downTile = new DownTileSingleThreadApp();
        String[] parameterStringArray = {
                "16,22,-70.7863,-33.5632,-70.5662,-33.3624"
        };
        //
        for(int i=0; i<parameterStringArray.length; i++) {
            String parameterString = parameterStringArray[i];
            String[] parameters = parameterString.split(",");
            System.out.println(parameters);
            startLevel = Integer.valueOf(parameters[0]);
            endLevel = Integer.valueOf(parameters[1]);
            xmin = Double.valueOf(parameters[2]);
            ymin = Double.valueOf(parameters[3]);
            xmax = Double.valueOf(parameters[4]);
            ymax = Double.valueOf(parameters[5]);
            downTile.downTile(startLevel, endLevel, xmin, ymin, xmax, ymax);
        }
        */
    /*
    "10,15,-74.2393899661748,-35.2486992939983,-67.7829962222134,-31.5372209203788",
                "1,9,-180,-85.05112878,180,85.05112878",
                "7,11,-78.7627850312735,-38.6775577375241,-63.0565026784138,-28.8170274076513",
    */
        String[] parameterStringArray = {
        "22,23,-70.7863,-33.5632,-70.5662,-33.3624",
                "9,13,-80.7848,-39.5913,-61.9966,-26.9706"
                
        };
        //
        DownTileMutipleThreadApp downTile = new DownTileMutipleThreadApp();
        for(int i=0; i<parameterStringArray.length; i++) {
            String parameterString = parameterStringArray[i];
            String[] parameters = parameterString.split(",");
            System.out.println(parameters);
            startLevel = Integer.valueOf(parameters[0]);
            endLevel = Integer.valueOf(parameters[1]);
            xmin = Double.valueOf(parameters[2]);
            ymin = Double.valueOf(parameters[3]);
            xmax = Double.valueOf(parameters[4]);
            ymax = Double.valueOf(parameters[5]);
            for(int level=startLevel; level<endLevel; level++) {
                System.out.println("------------------------------" + level + "-----------------------");
                for(int k=0; k<2; k++) {

                    downTile.downTileRange(level, xmin, ymin, xmax, ymax);
            System.out.println("------------------------------" + level + "-----------------------");
                }
            }
        }
    }
}

 

3.  DownTileMutipleThreadApp.java

 

package com.smartmap.exam.salon3.tilecache;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by zyx on 2016/11/28.
 */
public class DownTileMutipleThreadApp {
    private static final Logger logger = LoggerFactory.getLogger(DownTileMutipleThreadApp.class);
    private final static double xmin =  -180.0;
    private final static double ymin =  -85.05112878;
    private final static double xmax =  180;
    private final static double ymax =  85.05112878;
    //
    private final static double minXPro = -20037508.3427892;
    private final static double minYPro =  -20037508.3427892;
    private final static double maxXPro =  20037508.3427892;
    private final static double maxYPro =  20037508.3427892;
    //
    private final static double earthRadius  = 6378137.0;
    //
    private String baseURL = "http://www.google.cn/maps/vt?lyrs=m%40189&gl=cn";
    private String baseFilePath = "E:\\google\\en\\map";
    //
    private int threadCountRow = 10;
    private int threadCountColumn = 10;
    /**
     *
     * @param xmin
     * @param ymin
     * @param xmax
     * @param ymax
     * @return
     */
    private double[] computeProjectCoordinate(double xmin, double ymin, double xmax, double ymax) {
        double xminProject = earthRadius * (xmin - 0) / 180 * Math.PI;
        double yminProject = earthRadius * Math.log(Math.tan(Math.PI / 4 + ymin / 2 * Math.PI / 180));
        double xmaxProject = earthRadius * (xmax - 0) / 180 * Math.PI;
        double ymaxProject = earthRadius * Math.log(Math.tan(Math.PI / 4 + ymax / 2 * Math.PI / 180));
        //print(xminProject, yminProject, xmaxProject, ymaxProject)
        double[]  projectCoordinateRange = new double[]{xminProject, yminProject, xmaxProject, ymaxProject};
        return projectCoordinateRange;
    }

    /**
     *
     * @param level
     * @param xminProject
     * @param yminProject
     * @param xmaxProject
     * @param ymaxProject
     * @return
     */
    private int[] computeTileRange(int level, double xminProject, double yminProject, double xmaxProject, double ymaxProject) {
        double mapXYSpan = (maxXPro - minXPro);
        double mapImageXYSpan = mapXYSpan / Math.pow(2.0, level);

        int rowStart = (int)((maxYPro - ymaxProject) / mapImageXYSpan);
        int rowEnd = (int)((maxYPro - yminProject) / mapImageXYSpan);

        int columnStart = (int)((xminProject - minXPro) / mapImageXYSpan)+1;
        int columnEnd = (int)((xmaxProject - minXPro) / mapImageXYSpan)+1;
        int[]  tileRange = new int[]{columnStart, rowStart, columnEnd, rowEnd};
        //
        System.out.println(mapImageXYSpan + "   " + rowStart + "   " + rowEnd + "   " + columnStart + "   " + columnEnd);
        //
        return tileRange;
    }


    public void downTileRange(int level, double xmin, double ymin, double xmax, double ymax){
        //
        try {
            double[] projectCoordinateRange = computeProjectCoordinate(xmin, ymin, xmax, ymax);
            int[]  tileRange = computeTileRange(level, projectCoordinateRange[0], projectCoordinateRange[1], projectCoordinateRange[2], projectCoordinateRange[3]);
            //
            int columnStart = tileRange[0];
            int rowStart = tileRange[1];
            int columnEnd = tileRange[2];
            int rowEnd = tileRange[3];
            //
            int columnCountAll = columnEnd - columnStart;
            int rowCountAll = rowEnd - rowStart;
            //
            int columnCountPerThread = columnCountAll / this.threadCountColumn;
            columnCountPerThread +=  ((columnCountAll % this.threadCountColumn == 0)?0:1);
            //
            int rowCountPerThread = rowCountAll / this.threadCountRow;
            rowCountPerThread += ((rowCountAll % this.threadCountRow == 0)?0:1);
            System.out.println(columnCountPerThread + " <----> " + rowCountPerThread);
            //
            ThreadGroup threadGroup = new ThreadGroup("DownTileMutipleThreadAppThreadGroup");
            //
            DownTileThread downTileThread = null;
            //
            for(int i = 0; i<this.threadCountRow; i++) {
                int rowStartThread = rowStart + i * rowCountPerThread;
                int rowEndThread = rowStart + (i + 1) * rowCountPerThread;
                if(rowStartThread > rowEnd)
                {
                    break;
                }
                if(rowEndThread > rowEnd)
                {
                    rowEndThread = rowEnd;
                }
                for (int j = 0; j < this.threadCountColumn; j++) {
                    int columnStartThread = columnStart + j * columnCountPerThread;
                    int columnEndThread = columnStart + (j + 1) * columnCountPerThread;
                    if(columnStartThread > columnEnd)
                    {
                        break;
                    }
                    if(columnEndThread > columnEnd)
                    {
                        columnEndThread = columnEnd;
                    }
                    // String baseFilePath, int level, int columnStart, int rowStart, int columnEnd, int rowEnd
                    String threadName = "Thread" + i * j;
                    downTileThread = new DownTileThread(threadGroup, threadName, this.baseFilePath, level, columnStartThread, rowStartThread, columnEndThread, rowEndThread);
                    downTileThread.start();
                    //Thread.currentThread().sleep(3000);
                }
            }
            Thread.currentThread().sleep(3000);
            downTileThread.join();
            int activeCount = threadGroup.activeCount();
            while(activeCount > 0)
            {
                Thread.currentThread().sleep(5000);
                activeCount = threadGroup.activeCount();
                System.out.println("activeCount:  " + activeCount);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    //8,10,-74.2393899661748,-35.2486992939983,-67.7829962222134,-31.5372209203788
    //7,9,-78.7627850312735,-38.6775577375241,-63.0565026784138,-28.8170274076513
    //6,8,-100.725925780599,-50.7810948395102,-29.9193824693404,-8.25138729930426
    // 10,14,-71.4579,-34.1396,-69.9808,-32.7919
    public static void main(String args[]) {
        int startLevel = 1;
        int endLevel = 7;
        double xmin =  -180;
        double ymin =  -85.05112878;
        double xmax =  180;
        double ymax =  85.05112878;


        //1,9,-180,-85.05112878,180,85.05112878
        DownTileMutipleThreadApp downTile = new DownTileMutipleThreadApp();
        /*
        Scanner scanner = new Scanner(System.in);
        System.out.println("input:  startLevel endLevel xmin ymin xmax ymax");

        String parameterString = scanner.next();

        "6,9,-129.217225609756,-60.7335151345493,-4.98429878048784,12.9539853357581",
                "7,9,-78.7627850312735,-38.6775577375241,-63.0565026784138,-28.8170274076513",
                "8,10,-74.2393899661748,-35.2486992939983,-67.7829962222134,-31.5372209203788",
                "10,16,-70.7863,-33.5632,-70.5662,-33.3624",
                "10,13,-71.4579,-34.1396,-69.9808,-32.7919",
                "13,16,-71.0329,-33.8309,-70.4218,-33.1669",
        */
        //"6,8,-100.725925780599,-50.7810948395102,-29.9193824693404,-8.25138729930426",
        String[] parameterStringArray = {
                "19,21,-70.7863,-33.5632,-70.5662,-33.3624"
        };
        for(int i=0; i<parameterStringArray.length; i++) {
            String parameterString = parameterStringArray[i];
            String[] parameters = parameterString.split(",");
            System.out.println(parameters);
            startLevel = Integer.valueOf(parameters[0]);
            endLevel = Integer.valueOf(parameters[1]);
            xmin = Double.valueOf(parameters[2]);
            ymin = Double.valueOf(parameters[3]);
            xmax = Double.valueOf(parameters[4]);
            ymax = Double.valueOf(parameters[5]);
            for(int level=startLevel; level<endLevel; level++) {
                System.out.println("------------------------------" + level + "-----------------------");
                downTile.downTileRange(level, xmin, ymin, xmax, ymax);
            }
        }
    }
}

 

4. DownTileSingleThreadApp.java

 

package com.smartmap.exam.salon3.tilecache;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.*;

import javax.net.ssl.SSLContext;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.io.File;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by zyx on 2016/11/21.
 */
public class DownTileSingleThreadApp {
    private static final Logger logger = LoggerFactory.getLogger(DownTileSingleThreadApp.class);
    private final static double xmin =  -180.0;
    private final static double ymin =  -85.05112878;
    private final static double xmax =  180;
    private final static double ymax =  85.05112878;
    //
    private final static double minXPro = -20037508.3427892;
    private final static double minYPro =  -20037508.3427892;
    private final static double maxXPro =  20037508.3427892;
    private final static double maxYPro =  20037508.3427892;
    //
    private final static double earthRadius  = 6378137.0;
    //
    private String baseURL = "http://www.google.cn/maps/vt?lyrs=m%40189&gl=cn";
    private String baseFilePath = "E:\\google\\en\\map";
    //

    /**
     *
     * @param xmin
     * @param ymin
     * @param xmax
     * @param ymax
     * @return
     */
    private double[] computeProjectCoordinate(double xmin, double ymin, double xmax, double ymax) {
        double xminProject = earthRadius * (xmin - 0) / 180 * Math.PI;
        double yminProject = earthRadius * Math.log(Math.tan(Math.PI / 4 + ymin / 2 * Math.PI / 180));
        double xmaxProject = earthRadius * (xmax - 0) / 180 * Math.PI;
        double ymaxProject = earthRadius * Math.log(Math.tan(Math.PI / 4 + ymax / 2 * Math.PI / 180));
        //print(xminProject, yminProject, xmaxProject, ymaxProject)
        double[]  projectCoordinateRange = new double[]{xminProject, yminProject, xmaxProject, ymaxProject};
        return projectCoordinateRange;
    }

    /**
     *
     * @param level
     * @param xminProject
     * @param yminProject
     * @param xmaxProject
     * @param ymaxProject
     * @return
     */
    private int[] computeTileRange(int level, double xminProject, double yminProject, double xmaxProject, double ymaxProject) {
        double mapXYSpan = (maxXPro - minXPro);
        double mapImageXYSpan = mapXYSpan / Math.pow(2.0, level);

        int rowStart = (int)((maxYPro - ymaxProject) / mapImageXYSpan);
        int rowEnd = (int)((maxYPro - yminProject) / mapImageXYSpan);

        int columnStart = (int)((xminProject - minXPro) / mapImageXYSpan);
        int columnEnd = (int)((xmaxProject - minXPro) / mapImageXYSpan);
        int[]  tileRange = new int[]{columnStart, rowStart, columnEnd, rowEnd};
        //
        System.out.println(mapImageXYSpan + "   " + rowStart + "   " + rowEnd + "   " + columnStart + "   " + columnEnd);
        //
        return tileRange;
    }

    /**
     *
     * @param level
     * @param columnStart
     * @param rowStart
     * @param columnEnd
     * @param rowEnd
     */
    private void downTileRange(int level, int columnStart, int rowStart, int columnEnd, int rowEnd) {
        //
        /*for(int row=rowStart; row<rowEnd; row++)
        {
            for(int column=columnStart+1; column<columnEnd+1; column++)
            {*/
        for(int row=rowEnd; row> rowStart-1; row--)
        {
            for(int column=columnStart; column<columnEnd+1; column++)
            {
                String url = baseURL + "&z=" + level + "&x=" + column  + "&y=" + row;
                url = "https://www.google.com:443/maps/vt/pb=!1m4!1m3!1i" + level + "!2i" + column + "!3i" + row + "!2m3!1e0!2sm!3i368045507!3m7!2sen!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0!5m1!1e0";
                String fullFilePath = baseFilePath + "\\" + level + "\\" + column + "\\" + row + ".png";

                File file = new File(fullFilePath);
                System.out.println("check: " + level + "  " + column + "  " + row);
                if(!file.exists())
                {
                    System.out.println("--> " + level + "  " + column + "  " + row);
                    System.out.println(url);
                    File fileParent = file.getParentFile();
                    if(!fileParent.exists())
                    {
                        fileParent.mkdirs();
                    }
                    downTileSingle(url, fullFilePath);
                }
            }
        }
    }

    private static CloseableHttpClient getHttpClient() {
        RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create();
        ConnectionSocketFactory connectionSocketFactory = new PlainConnectionSocketFactory();
        registryBuilder.register("http", connectionSocketFactory);
        //指定信任密钥存储对象和连接套接字工厂
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            //信任任何链接
            TrustStrategy trustStrategy = new TrustStrategy() {
                //@Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            };
            SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(keyStore, trustStrategy).build();
            LayeredConnectionSocketFactory layeredConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            registryBuilder.register("https", layeredConnectionSocketFactory);
        } catch (KeyStoreException e) {
            throw new RuntimeException(e);
        } catch (KeyManagementException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        Registry<ConnectionSocketFactory> registry = registryBuilder.build();
        //设置连接管理器
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registry);
//      connManager.setDefaultConnectionConfig(connConfig);
//      connManager.setDefaultSocketConfig(socketConfig);
        //构建客户端
        CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().setConnectionManager(poolingHttpClientConnectionManager).build();
        return closeableHttpClient;
    }

    /**
     * get
     *
     * @param url     请求的url
     * @param queries 请求的参数,在浏览器?后面的数据,没有可以传null
     * @return
     * @throws IOException
     */
    public static byte[] get(String url, Map<String, String> queries) throws IOException {
        byte[] image = null;
        //支持https
        CloseableHttpClient httpClient = getHttpClient();
        StringBuilder stringBuilder = new StringBuilder(url);
        if (queries != null && queries.keySet().size() > 0) {
            boolean firstFlag = true;
            Iterator iterator = queries.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry<String, String>) iterator.next();
                if (firstFlag) {
                    stringBuilder.append("?" + (String) entry.getKey() + "=" + (String) entry.getValue());
                    firstFlag = false;
                } else {
                    stringBuilder.append("&" + (String) entry.getKey() + "=" + (String) entry.getValue());
                }
            }
        }

        try {
            HttpGet httpGet = new HttpGet(stringBuilder.toString());
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(30000)
                    .setConnectTimeout(30000).build();//设置请求和传输超时时间
            httpGet.setConfig(requestConfig);
            //System.out.println("Executing request " + httpGet.getRequestLine());
            //请求数据
            CloseableHttpResponse response = httpClient.execute(httpGet);
            //System.out.println(response.getStatusLine());
            int status = response.getStatusLine().getStatusCode();
            if (status == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                //String responseBody = EntityUtils.toString(entity);
                //EntityUtils.consume(entity);
                image = EntityUtils.toByteArray(entity);
            } else {
                System.out.println("http return status error:" + status);
                throw new ClientProtocolException("Unexpected response status: " + status);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            httpClient.close();
        }
        return image;
    }

    public static byte[] sendGetRequest(String url) throws IOException {
        byte[] image = null;
        //支持https
        CloseableHttpClient httpClient = getHttpClient();
        HttpGet httpGet = new HttpGet(url);
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)
                .setConnectTimeout(30000).build();//设置请求和传输超时时间
        httpGet.setConfig(requestConfig);
        try {
            //请求数据
            CloseableHttpResponse response = httpClient.execute(httpGet);
            int status = response.getStatusLine().getStatusCode();
            if (HttpStatus.SC_OK == status) {
                HttpEntity httpEntity = response.getEntity();
                image = EntityUtils.toByteArray(httpEntity);
            } else {
                System.out.println("http return status error:" + status);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            httpClient.close();
        }
        return image;
    }

    private void saveByteArrayToImage(byte[] image, String filePath)
    {
        try {
            if(image != null)
            {
                File file = new File(filePath);
                //System.out.println(filePath);
                //file.createNewFile();
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                bufferedOutputStream.write(image);
                //bufferedOutputStream.flush();
                bufferedOutputStream.close();
                fileOutputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *
     * @param url
     * @param filePath
     */
    private void downTileSingle(String url, String filePath) {
        byte[] image = null;
        try {
            image = DownTileSingleThreadApp.sendGetRequest(url);
            saveByteArrayToImage(image, filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *
     */
    public void downTile(int startLevel, int endLevel, double xmin, double ymin, double xmax, double ymax)
    {
        for(int level=startLevel; level < endLevel; level++)
        {
            System.out.println("------------------------------------------");
            System.out.println(level);
            //
            double[] projectCoordinateRange = computeProjectCoordinate(xmin, ymin, xmax, ymax);
            int[]  tileRange = computeTileRange(level, projectCoordinateRange[0], projectCoordinateRange[1], projectCoordinateRange[2], projectCoordinateRange[3]);

            downTileRange(level, tileRange[0], tileRange[1], tileRange[2], tileRange[3]);
            System.out.println("------------------------------------------");
        }
    }
    //8,10,-74.2393899661748,-35.2486992939983,-67.7829962222134,-31.5372209203788
    //7,9,-78.7627850312735,-38.6775577375241,-63.0565026784138,-28.8170274076513
    //6,8,-100.725925780599,-50.7810948395102,-29.9193824693404,-8.25138729930426
    // 10,14,-71.4579,-34.1396,-69.9808,-32.7919
    public static void main(String args[]) {
        int startLevel = 1;
        int endLevel = 7;
        double xmin =  -180;
        double ymin =  -85.05112878;
        double xmax =  180;
        double ymax =  85.05112878;

        //
        DownTileSingleThreadApp downTile = new DownTileSingleThreadApp();
        /*
        Scanner scanner = new Scanner(System.in);
        System.out.println("input:  startLevel endLevel xmin ymin xmax ymax");

        String parameterString = scanner.next();
        */
        //"6,8,-100.725925780599,-50.7810948395102,-29.9193824693404,-8.25138729930426",
        String[] parameterStringArray = {
                "6,9,-129.217225609756,-60.7335151345493,-4.98429878048784,12.9539853357581",
        "7,9,-78.7627850312735,-38.6775577375241,-63.0565026784138,-28.8170274076513",
        "8,10,-74.2393899661748,-35.2486992939983,-67.7829962222134,-31.5372209203788",
        "10,16,-70.7863,-33.5632,-70.5662,-33.3624",
        "10,13,-71.4579,-34.1396,-69.9808,-32.7919",
        "13,16,-71.0329,-33.8309,-70.4218,-33.1669",
        "16,21,-70.7863,-33.5632,-70.5662,-33.3624"
        };
        for(int i=0; i<parameterStringArray.length; i++) {
            String parameterString = parameterStringArray[i];
            String[] parameters = parameterString.split(",");
            System.out.println(parameters);
            startLevel = Integer.valueOf(parameters[0]);
            endLevel = Integer.valueOf(parameters[1]);
            xmin = Double.valueOf(parameters[2]);
            ymin = Double.valueOf(parameters[3]);
            xmax = Double.valueOf(parameters[4]);
            ymax = Double.valueOf(parameters[5]);
            downTile.downTile(startLevel, endLevel, xmin, ymin, xmax, ymax);
        }
    }

}

 

5. DownTileThread.java

 

package com.smartmap.exam.salon3.tilecache;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * Created by zyx on 2016/11/28.
 */
public class DownTileThread extends Thread {

    private static final Logger logger = LoggerFactory.getLogger(DownTileSingleThreadApp.class);

    //
    //private String baseURL = "http://www.google.cn/maps/vt?lyrs=m%40189&gl=cn";
    //
    private String baseFilePath = "E:\\google\\en\\map";
    private int level;
    private int columnStart;
    private int rowStart;
    private int columnEnd;
    private int rowEnd;

    /**
     *
     * @param baseFilePath
     * @param level
     * @param columnStart
     * @param rowStart
     * @param columnEnd
     * @param rowEnd
     */
    public DownTileThread(ThreadGroup threadGroup, String name, String baseFilePath, int level, int columnStart, int rowStart, int columnEnd, int rowEnd)
    {
        super(threadGroup, name);
        this.baseFilePath = baseFilePath;
        this.level = level;
        this.columnStart = columnStart;
        this.rowStart = rowStart;
        this.columnEnd = columnEnd;
        this.rowEnd = rowEnd;
    }

    @Override
    public void run() {
        System.out.println("Thread:   " + this.getName() + "  " + rowStart + "   " + rowEnd + "   " + columnStart + "   " + columnEnd);
        downTileRange();
    }

    private void downTileRange() {
        //
        try {
            CloseableHttpClient httpClient = getHttpClient();
            for(int row=rowStart; row<rowEnd; row++)
            {
                for(int column=columnStart; column<columnEnd; column++)
                {
                    String url = "https://www.google.com:443/maps/vt/pb=!1m4!1m3!1i" + level + "!2i" + column + "!3i" + row + "!2m3!1e0!2sm!3i368045507!3m7!2sen!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0!5m1!1e0";
                    String fullFilePath = baseFilePath + "\\" + level + "\\" + column + "\\" + row + ".png";
                    File file = new File(fullFilePath);
                    if(!file.exists())
                    {
                        System.out.println(this.getName()+" :--> " + level + "  " + column + "  " + row);
                        //System.out.println(url);
                        File fileParent = file.getParentFile();
                        if(!fileParent.exists())
                        {
                            fileParent.mkdirs();
                        }
                        downTileSingle(httpClient, url, fullFilePath);
                    }
                }
            }
            if(httpClient != null) {
                httpClient.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *
     * @param url
     * @param filePath
     */
    public void downTileSingle(CloseableHttpClient httpClient, String url, String filePath) {
        byte[] image = null;
        try {
            image = sendGetRequest(httpClient, url);
            saveByteArrayToImage(image, filePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public byte[] sendGetRequest(CloseableHttpClient httpClient, String url) throws IOException {
        byte[] image = null;
        RequestConfig.Builder builder = RequestConfig.custom();
        builder.setSocketTimeout(30000);
        builder.setConnectTimeout(30000);
        RequestConfig requestConfig = builder.build();
        //支持https
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(requestConfig);
        CloseableHttpResponse response = null;
        try {
            //请求数据
            response = httpClient.execute(httpGet);
            int status = response.getStatusLine().getStatusCode();
            if (HttpStatus.SC_OK == status) {
                HttpEntity httpEntity = response.getEntity();
                image = EntityUtils.toByteArray(httpEntity);
            } else {
                System.out.println("http return status error:" + status);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if(response != null)
            {
                response.close();
            }
        }
        return image;
    }

    /**
     *
     * @return
     */
    private CloseableHttpClient getHttpClient() {
        RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create();
        ConnectionSocketFactory connectionSocketFactory = new PlainConnectionSocketFactory();
        registryBuilder.register("http", connectionSocketFactory);
        //指定信任密钥存储对象和连接套接字工厂
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            //信任任何链接
            TrustStrategy trustStrategy = new TrustStrategy() {
                //@Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            };
            SSLContextBuilder sslContextBuilder = SSLContexts.custom();
            sslContextBuilder.useTLS();
            sslContextBuilder.loadTrustMaterial(keyStore, trustStrategy);
            SSLContext sslContext = sslContextBuilder.build();
            LayeredConnectionSocketFactory layeredConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            registryBuilder.register("https", layeredConnectionSocketFactory);
        } catch (KeyStoreException e) {
            throw new RuntimeException(e);
        } catch (KeyManagementException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        Registry<ConnectionSocketFactory> registry = registryBuilder.build();
        //设置连接管理器
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registry);
//      connManager.setDefaultConnectionConfig(connConfig);
//      connManager.setDefaultSocketConfig(socketConfig);
        //构建客户端
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        return closeableHttpClient;
    }

    private void saveByteArrayToImage(byte[] image, String filePath)
    {
        try {
            if(image != null)
            {
                File file = new File(filePath);
                //System.out.println(filePath);
                //file.createNewFile();
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                bufferedOutputStream.write(image);
                //bufferedOutputStream.flush();
                bufferedOutputStream.close();
                fileOutputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
posted @ 2016-12-10 21:29  ParamousGIS  阅读(329)  评论(0编辑  收藏  举报