ArcGIS+百度地图API:制作杭州市边界shp文件
參考文章:百度地圖API+ArcGIS軟件—城市出行時空數(shù)據(jù)可視化_WenWu_Both的博客-CSDN博客
這篇博客在介紹的時候遺漏了很多關(guān)鍵步驟,我對此進行了必要的補充。
一、獲取輪廓線的代碼(getData.html)
<!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>獲取地區(qū)輪廓線</title><script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=lpAE5ZQGsVIyTHdChEo9CwPnCXyTbCFl"></script><style type="text/css">body,html {width: 100%;height: 100%;margin: 0;font-family: '微軟雅黑';}#container {height: 500px;width: 90%;margin-left: 50px}#Div1 {width: 100%}</style> </head><body><div id="container"></div><br />輸入省、直轄市或縣名稱:<input type="text" id="districtName" style="width:80px" value="杭州市"><input type="button" onclick="getBoundary()" value="獲取輪廓線"><textarea id="Div1" style="width:100%;height:200px"></textarea><script type="text/javascript">var map = new BMap.Map('container');map.centerAndZoom(new BMap.Point(116.403765, 39.914850), 5);map.addControl(new BMap.MapTypeControl()); //添加地圖類型控件map.setCurrentCity("杭州市"); // 設(shè)置地圖顯示的城市 此項是必須設(shè)置的map.enableScrollWheelZoom(true); //開啟鼠標(biāo)滾輪縮放function getBoundary() {var bdary = new BMap.Boundary();var name = document.getElementById("districtName").value;bdary.get(name, function (rs) { //獲取行政區(qū)域map.clearOverlays(); //清除地圖覆蓋物 document.getElementById('Div1').innerText = rs.boundaries;var count = rs.boundaries.length; //行政區(qū)域的點有多少個for (var i = 0; i < count; i++) {var ply = new BMap.Polygon(rs.boundaries[i], {strokeWeight: 2,strokeColor: "#ff0000"}); //建立多邊形覆蓋物map.addOverlay(ply); //添加覆蓋物map.setViewport(ply.getPath()); //調(diào)整視野 }var blob = new Blob(rs.boundaries, {type: "text/csv,charset=UTF-8"})var csvUrl = URL.createObjectURL(blob)var aEle = document.createElement("a")aEle.download = "data.csv" //文件名隨意aEle.href = csvUrlaEle.click()});}</script> </body></html>注意一下這行代碼?
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=lpAE5ZQGsVIyTHdChEo9CwPnCXyTbCFl">其中ak=lpAE5ZQGsVIyTHdChEo9CwPnCXyTbCFl
ak=后面的是我申請的百度地圖的開發(fā)者許可密鑰(不知道什么時候會過期,如果過期了建議自己去百度地圖申請一個)
打開getData.html,這里以杭州為例(如果想獲取別的城市的shp文件,可以自行在文本框內(nèi)更改),點擊獲取輪廓線后瀏覽器會彈出下載文件的彈窗,選擇將文件另存為到指定的目錄,這里我選擇將文件保存到C:/Users/Administrator/Desktop/GIS/data文件夾中。
二、數(shù)據(jù)轉(zhuǎn)換(dataTransform.cpp)
使用excel打開data.csv,格式如下
為了便于arcgis(arcmap)處理,我們希望得到這種格式的數(shù)據(jù)
于是我編寫了一個C語言程序(dataTransform.cpp)負責(zé)格式轉(zhuǎn)換,這里的代碼需要根據(jù)個人情況修改原文件路徑和轉(zhuǎn)換后的文件路徑,直接運行會出錯。
同時,由于百度地圖API獲取得到的邊界坐標(biāo)是基于百度坐標(biāo)系BD09,為了方便后續(xù)使用,需要將其轉(zhuǎn)換到通用的WGS84坐標(biāo)系,有關(guān)地理坐標(biāo)系的相關(guān)知識可以參考我的這篇博客
主流地理坐標(biāo)系、投影坐標(biāo)系和投影方法的區(qū)別和聯(lián)系_ 一只博客-CSDN博客https://blog.csdn.net/qq_42276781/article/details/122597363有關(guān)BD09和WGS84轉(zhuǎn)換的知識可以閱讀我的這篇博客
地理坐標(biāo)系:WGS84和BD09互轉(zhuǎn)_ 一只博客-CSDN博客https://blog.csdn.net/qq_42276781/article/details/122596796dataTransform.cpp
#include<stdio.h> #include<math.h> #include<stdlib.h> #define PI 3.1415926535897932384626 double* BD09ToWGS84(double, double); double* WGS84ToBD09(double, double); double* BD09ToGCJ02(double, double); double* GCJ02ToBD09(double, double); double* GCJ02ToWGS84(double, double); double* WGS84ToGCJ02(double, double); int main(){//input file pathFILE *fp = fopen("C://Users//Administrator//Desktop//GIS//data//data.csv", "r");//output file pathFILE *fq = fopen("C://Users//Administrator//Desktop//GIS//data//data2.csv", "w");double lon, lat;int i = 1; fprintf(fq, "id, lon, lat\n");while(fscanf(fp, "%lf, %lf;", &lon, &lat)>0){double *temp = BD09ToWGS84(lon, lat);fprintf(fq, "%d, %f, %f\n", i++, temp[0], temp[1]);}fclose(fp);fclose(fq); }// (BD09 <=> WGS84) base on (BD09 <=> GCJ02) and (WGS84 <=> GCJ02) double* BD09ToWGS84(double lon_BD, double lat_BD){double *GCJ = BD09ToGCJ02(lon_BD, lat_BD);return GCJ02ToWGS84(GCJ[0], GCJ[1]); } double* WGS84ToBD09(double lon_WGS, double lat_WGS){double *GCJ = WGS84ToGCJ02(lon_WGS, lat_WGS);return GCJ02ToBD09(GCJ[0], GCJ[1]); } // BD09 <=> GCJ02 double baiduFactor = (PI * 3000.0) / 180.0;double* BD09ToGCJ02(double lon_BD, double lat_BD){double *GCJ = (double *)malloc(2*sizeof(double));double x = lon_BD - 0.0065;double y = lat_BD - 0.006;double z = sqrt(x * x + y * y) - 0.00002 * sin(y * baiduFactor);double theta = atan2(y, x) - 0.000003 * cos(x * baiduFactor);GCJ[0] = z * cos(theta);GCJ[1] = z * sin(theta);return GCJ; }double* GCJ02ToBD09(double lon_GCJ, double lat_GCJ){double *BD = (double *)malloc(2*sizeof(double));double z = sqrt(lon_GCJ * lon_GCJ + lat_GCJ * lat_GCJ) + 0.00002 * sin(lat_GCJ * baiduFactor);double theta = atan2(lat_GCJ, lon_GCJ) + 0.000003 * cos(lon_GCJ * baiduFactor);BD[0] = z * cos(theta) + 0.0065;BD[1] = z * sin(theta) + 0.006;return BD; } // WGS84 <=> GCJ02 double a = 6378245; double ee = 0.006693421622965823;// roughly check whether coordinates are in China. int isInChinaBbox(double lon, double lat){return lon >= 72.004 && lon <= 137.8347 && lat >= 0.8293 && lat <= 55.8271; }double transformLat(double x, double y){double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x));ret += ((20.0 * sin(6.0 * x * PI) + 20.0 * sin(2.0 * x * PI)) * 2.0) / 3.0;ret += ((20.0 * sin(y * PI) + 40.0 * sin((y / 3.0) * PI)) * 2.0) / 3.0;ret += ((160.0 * sin((y / 12.0) * PI) + 320.0 * sin((y * PI) / 30.0)) * 2.0) / 3.0;return ret; }double transformLon(double x, double y){double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x));ret += ((20.0 * sin(6.0 * x * PI) + 20.0 * sin(2.0 * x * PI)) * 2.0) / 3.0;ret += ((20.0 * sin(x * PI) + 40.0 * sin((x / 3.0) * PI)) * 2.0) / 3.0;ret += ((150.0 * sin((x / 12.0) * PI) + 300.0 * sin((x / 30.0) * PI)) * 2.0) / 3.0;return ret; }double* delta(double lon, double lat){double *d = (double *)malloc(2*sizeof(double));double dLon = transformLon(lon - 105.0, lat - 35.0);double dLat = transformLat(lon - 105.0, lat - 35.0);double radLat = (lat / 180.0) * PI;double magic = sin(radLat);magic = 1.0 - ee * magic * magic;double sqrtMagic = sqrt(magic);d[0] = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * PI);d[1] = (dLat * 180.0) / ((a * (1.0 - ee)) / (magic * sqrtMagic) * PI);return d; }double* WGS84ToGCJ02(double lon_WGS, double lat_WGS){double *GCJ = (double *)malloc(2*sizeof(double));if (!isInChinaBbox(lon_WGS, lat_WGS)){GCJ[0] = lon_WGS;GCJ[1] = lat_WGS;return GCJ;} double *d = delta(lon_WGS, lat_WGS);GCJ[0] = lon_WGS + d[0];GCJ[1] = lat_WGS + d[1];return GCJ; }double* GCJ02ToWGS84(double lon_GCJ, double lat_GCJ) {double *WGS = (double *)malloc(2*sizeof(double));if (!isInChinaBbox(lon_GCJ, lat_GCJ)){WGS[0] = lon_GCJ;WGS[1] = lat_GCJ;return WGS;} WGS[0] = lon_GCJ; WGS[1] = lat_GCJ;double *temp = WGS84ToGCJ02(WGS[0], WGS[1]);double dx = temp[0] - lon_GCJ;double dy = temp[1] - lat_GCJ;while (fabs(dx) > 1e-6 || fabs(dy) > 1e-6) {WGS[0] -= dx;WGS[1] -= dy;temp = WGS84ToGCJ02(WGS[0], WGS[1]);dx = temp[0] - lon_GCJ;dy = temp[1] - lat_GCJ;}return WGS; }使用devc++運行,轉(zhuǎn)換后的文件被保存到C://Users//Administrator//Desktop//GIS//data//data2.csv,即
C:\Users\Administrator\Desktop\GIS\data\data2.csv
最終在data文件夾下,有一個data.csv原數(shù)據(jù)文件,一個data2.csv轉(zhuǎn)換后的數(shù)據(jù)文件
三、Arcmap處理
如果ArcMap的界面被搞亂了不知道如何還原,可以參考我這篇博客
ArcMap10.7界面初始化_ 一只博客-CSDN博客https://blog.csdn.net/qq_42276781/article/details/122468720
打開ArcMap后使用默認空白地圖,點擊確定
點擊添加數(shù)據(jù),點擊連接到文件夾,選擇數(shù)據(jù)所在的文件夾,選擇data2.csv,點擊添加
右鍵data2.csv,點擊顯示XY數(shù)據(jù),X字段選擇lon,Y字段選擇lat,輸入坐標(biāo)的坐標(biāo)系為地理坐標(biāo)系=>World=>WGS 1984(由于之前我們已經(jīng)把BD09轉(zhuǎn)換為WGS84,所以這里需要指定WGS作為地理坐標(biāo)系),點擊確定
點擊ArcToolbox,點擊數(shù)據(jù)管理工具,點擊要素,點擊要素轉(zhuǎn)點,輸入要素選擇data2.csv,輸出要素類指定為data目錄下的point.shp文件,點擊確定
至此,我們得到了杭州市邊界的點shp文件,考慮到邊界一般都是線shp文件,所以接下來還需要將點shp文件轉(zhuǎn)為線shp文件。
點擊點集轉(zhuǎn)線,輸入要素為point.shp,輸出要素類為指定目錄data下的line.shp,線字段選擇ORIG_ID,排序字段選擇FID,勾選閉合線,點擊確定。
通過勾選這三個圖層可以發(fā)現(xiàn),point.shp和data2.csv都是點,而line.shp是線
打開data文件夾,可以發(fā)現(xiàn)杭州市的線shp文件已經(jīng)導(dǎo)出了。
總結(jié)
以上是生活随笔為你收集整理的ArcGIS+百度地图API:制作杭州市边界shp文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux动态库注册函数,linux下加
- 下一篇: 微领地商业模式开发 软件开发