于是乎伪嫁,領導拍板了,更新帝洪!必須更新似舵!
找遍各大網絡數據,最新版的中國行政區(qū)劃圖(省市縣級)葱峡,最新版更新到2015年砚哗,嗯,還是不知道是否真的2015砰奕。然后蛛芥,爬遍了城墻內外,萬能寶一份2017的數據100+军援,地理空間數據云的仅淑,一份縣級中國區(qū)劃2014版,報價十幾萬……鑒于真實的2020數據胸哥,大概率小貧民是不可獲得的(涉密),只能從開源數據上想想辦法了空厌。
鑒于之前爬遍全網的經歷庐船,目光直接鎖定OpenStreetMap的數據,開源蝇庭、免費醉鳖、并且經過驗證,矢量邊界比手中現(xiàn)有的行政區(qū)劃更加精細哮内。缺點則是涉及到領土有爭議的部分領域盗棵,OSM是站在對立面的,童鞋們慎重氨狈ⅰ纹因!
來吧,話不多說,上干貨!
1. 技術路線介紹
根據之前掌握的信息腮郊,OSM官方是提供矢量圖形下載的。大概是我使用的導出方式不對惊畏,一直沒能下下來。
經過多方找了GeoJSON中的OpenStreetMap管理邊界
以及提取OSM行政邊界的方法, 確認OSM當前的行政邊界的下載的方式密任。整體路線大概是
1. 獲取所有行政區(qū)劃的relation code颜启,
2. 通過CURL命令下載。(大概率需要科學上網)
備案方法2:通過[http://polygons.openstreetmap.fr/?id=RELATIONID](http://polygons.openstreetmap.fr/?id=)
獲取到圖形自動入庫浪讳。(此方法建議無法科學上網的童鞋們使用缰盏。)
2. 獲取關系編碼
通過觀察網頁中的相關信息,咱們可以快速的看到,每一個區(qū)域的編號口猜,以及與它接壤的外圍編號负溪,以及它的子一級編號
鑒于此,中國34個省市的關系網盡在掌握济炎。
數據獲取邏輯如下:
- 獲取中國34個省市縣的關系網川抡;
- 向下查找每個省市對應的市級關系編碼;
- 根據市級關系編碼冻辩,再向下查找縣級編碼猖腕。
基于此拆祈,便可獲取全中國34個省市縣區(qū)最新的shp矢量行政區(qū)劃了恨闪。
一個簡單的爬蟲小程序便應運而生。
package com.openstreetmap.reptile;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Node;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author
* @Date: 2020/1/16 13:55
* @Description: 用于處理爬蟲邏輯
**/
@Slf4j
public class FileReptileCore {
public static void main(String[] args) {
try {
//34個省市縣的編碼
String code ="913011;553303;153314;911844;286937;2128285;912998;199073;407492;913106;913073;913012;913109;198590;912942;" +
"153269;913100;913006;913105;913068;913094;553302;153292;153310;286342;161349;" +
"913101;912940;912999;913067;913069;913110;1867188";
String[] codeArr = code.split(";");
Map<String,List<String>> cityLevelCode = new HashMap<>();
//基礎的訪問網址
String baseUrl = "https://www.openstreetmap.org/relation/";
for (int i = 0; i < codeArr.length; i++) {
//輸出當前正在爬取的省份編碼
log.info("===========開始輸出:" + codeArr[i]);
String url = baseUrl + codeArr[i];
org.jsoup.nodes.Document doc = Jsoup.connect(url).ignoreContentType(true).timeout(30000).get();
//獲取節(jié)點數據
List<Node> relationNodeList = doc.body().childNodes().get(3).childNodes().get(1).childNodes().get(9).childNodes().get(3).childNodes()
.get(17).childNodes();
int size = relationNodeList.size();
List<String> cityCode = new ArrayList<>();
//循環(huán)讀取市級節(jié)點
for (int j = 0; j < size; j++) {
Node node = relationNodeList.get(j);
if(node.toString().equals(" ")){
continue;
}
String value = node.childNodes().get(1).attributes().get("href");
if(value.contains("relation")){
String relationCode = value.split("/")[2];
cityCode.add(relationCode);
System.out.println(relationCode);
}
}
cityLevelCode.put(codeArr[i],cityCode);
}
//根據市級節(jié)點的code放坏,獲得縣級的code
for (Map.Entry province :cityLevelCode.entrySet()) {
List<String> cityCodeArr = (List<String>)province.getValue();
int cityCodeArrsize = cityCodeArr.size();
for (int a = 0; a < cityCodeArrsize; a++) {
log.info("===========開始輸出:" + cityCodeArr.get(a));
String url = baseUrl + cityCodeArr.get(a);
org.jsoup.nodes.Document doc = Jsoup.connect(url).ignoreContentType(true).timeout(30000).get();
List<Node> relationNodeList = doc.body().childNodes().get(3).childNodes().get(1).childNodes().get(9).childNodes().get(3).childNodes()
.get(17).childNodes();
int size = relationNodeList.size();
for (int j = 0; j < size; j++) {
Node node = relationNodeList.get(j);
if(node.toString().equals(" ")){
continue;
}
String value = node.childNodes().get(1).attributes().get("href");
if(value.contains("relation")){
String relationCode = value.split("/")[2];
System.out.println(relationCode);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
基于此咙咽,所有省市縣的編碼獲取完畢。
3. 根據編碼下載shp
根據這位大大的文章OSM行政邊界的方法, 使用CURL命令即可
curl -f -o file.zip --url
"https://wambachers-osm.website/boundaries/exportBoundaries?cliVersion=1.0&cliKey=52d97a3b-3fc1-44cd-bd9a-e8c1c9468bab&exportFormat=shp&exportLayout=levels&exportAreas=land&union=false&selected=3287346"
其中:
curl -f -o 代表下載操作淤年;
file.zip: 表示下載的文件名钧敞;
--url: 代表將此url下面的文件下載下來
整個鏈接:https://wambachers-osm.website/boundaries/exportBoundaries?cliVersion=1.0&cliKey=52d97a3b-3fc1-44cd-bd9a-e8c1c9468bab&exportFormat=shp&exportLayout=levels&exportAreas=land&union=false&selected=3287346中,需要修改的部分便是327346麸粮,這個就是上文獲取的code溉苛。多文件下載時,僅需將多個code使用 , 隔開即可
比如:
curl -f -o file.zip --url
"https://wambachers-osm.website/boundaries/exportBoundaries?cliVersion=1.0&cliKey=52d97a3b-3fc1-44cd-bd9a-e8c1c9468bab&exportFormat=shp&exportLayout=levels&exportAreas=land&union=false&selected=3287346,2963917
等等……
備注
至于備選方法弄诲,只要拿到了關系代碼愚战,也是一個簡單查詢命令便可轉存入庫。在此便不贅述齐遵。
關于上文介紹的數據寂玲,如有需要,有償私信哈~Q或者郵箱是(344326924@qq.com)