多线程下载英文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(); } } }