C#解析GEOJSON數(shù)據(jù)

之前的一篇文章里介紹了geojson的標(biāo)準(zhǔn)格式,這里介紹一下用C#的Newtonsoft.Json庫對一個geojson文件進(jìn)行解析,因為Python的json庫解析json還是非常容易的,用json.load或json.loads就可以讀入json數(shù)據(jù)然后按照字典或列表的方式進(jìn)行定位和更改其中的內(nèi)容,因為最近一個 項目需要用C#進(jìn)行解析,這里做一個記錄。

下載與安裝Newtonsoft.Json

首先在官網(wǎng)下載Newtonsoft.Json。官網(wǎng)上號稱:

Popular high-performance JSON framework for .NET

當(dāng)然確實還是很好用的,提供的接口還是挺友好的,開始入手可能有一些小困難。這個庫的功能主要有3大塊,分別為序列化json(將文本保存的json解析為可查詢的json)、反序列化json和用LINQ對json進(jìn)行查詢。

在官網(wǎng)上可以點擊Download下載壓縮文件然后在自己的工程的解決方案管理器里添加引用,找到Newtonsoft.Json.dll文件然后引用。還有一個更快捷的方式是使用程序包管理器控制臺進(jìn)行安裝,過程如下圖:

Newtonsoft.Json的安裝

先打開程序包管理器控制臺,然后輸入Install-Package Newtonsoft.json 進(jìn)行安裝。

安裝好后在項目里記得添上using Newtonsoft.Json;這條語句。
這個庫提供的數(shù)據(jù)類型有JObject、JProperty以及最基本的JToken。

讀入json數(shù)據(jù)

下面是讀入json并序列化到一個JObject對象的過程

StreamReader sr = new StreamReader(inputFile, Encoding.UTF8);
JObject o = JObject.Parse(sr.ReadToEnd());

如果輸入文件inputFile不是標(biāo)準(zhǔn)的json格式可能會引發(fā)JsonReaderException異常。

索引對應(yīng)數(shù)據(jù)

例如下面的geojson數(shù)據(jù):

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {"NAME": "hanzghou poi", "id": 1, "prov": " zhejiang"},
      "geometry": {
        "type": "Point",
        "coordinates": [
          120.07850646972656,
          30.304428412161137
        ]
      }
    }
  ]
}
該數(shù)據(jù)的效果

我們用前面的兩句代碼讀入后,可以用JToken jprop=o["type"]索引到文本FeatureCollection,JToken可以對應(yīng)各種類型的數(shù)據(jù),并且保存著原來json的結(jié)構(gòu),可以在向下索引或者回溯到父節(jié)點。而JToken jfts = o["features"]已知內(nèi)容是一個數(shù)組,可以用List<JToken> jlst = jfts.ToList();對里面的元素進(jìn)行枚舉,

List<JToken> jlst = jfts.ToList();
for (int i = 0; i < j jlst.Count; i++){
    //do sth
}

對于json的在大括號里的鍵值對(一般稱為字典格式)數(shù)據(jù),可以通過類似 o["features"] 的方式,將鍵放在中括號里進(jìn)行索引,可以多級索引并保存為數(shù)值類型或者文本類型(需要一個隱式轉(zhuǎn)換的語句)而不限于JToken進(jìn)行保存,例如:string jtw = (string)jlst[i]["geometry"]["type"];,如果想要提取鍵怎么辦呢?JToken沒有獲取鍵的接口,這個我摸索了一段時間,可以通過JProperty類型來解決,JProperty 有Name接口可以獲取相應(yīng)的Name;

JToken gprop = jlst[i]["properties"];
JProperty jpeo = (JProperty)gprop.ElementAt(0);
string usingStr=jpeo.Name;

geojson數(shù)據(jù)寫入csv

下面是一個提取geojson的點數(shù)據(jù)到csv和根據(jù)csv寫一個geojson文件的小示例,包含了從0開始寫一個geojson文件的過程。

        /// <summary>
        /// geojson轉(zhuǎn)csv,只對點要素有效
        /// </summary>
        private void geojsonToCsvPoi () {
            //其他要素不管,如果沒有點要素,生成為空
            StreamReader sr = new StreamReader(inputFile, Encoding.UTF8);
            JObject o = JObject.Parse(sr.ReadToEnd());

            JToken jfts = o["features"];

            List<JToken> jlst = jfts.ToList<JToken>();
            int jlen = jlst.Count;

            StreamWriter csvWter = new StreamWriter(outputFile);
            for (int i = 0; i < jlen; i++) {
                string jt1 = (string)jlst[i]["geometry"]["type"];
                if (jt1 == "Point") {
                    try {
                        Array poiArr = jlst[i]["geometry"]["coordinates"].ToArray();
                        csvWter.WriteLine(coordPoint(poiArr));
                        infoLabel.Text = "geojson to csv 轉(zhuǎn)換完成";//邏輯上不是,但為了不覆蓋catch的內(nèi)容,寫在了這里
                    }
                    catch (Exception exp) {
                        infoLabel.Text = exp.Message;
                    }
                }else { //
                }
            }
            csvWter.Close();
            
        }

        /// <summary>
        /// csv轉(zhuǎn)geojson的點數(shù)據(jù)
        /// </summary>
        private void csvPoiToGeojson () {
            try {
                StreamReader csvRder = new StreamReader(inputFile,Encoding.UTF8);
                string csvall = csvRder.ReadToEnd();//讀入csv文件
                string[] csvlst = csvall.Split('\n');
                List<JObject> jfeslst = new List<JObject>();
                for (int j = 0; j < csvlst.Length; j++) {
                    if (csvlst[j] == "" && j == 0) {
                        infoLabel.Text = "輸入csv文件為空,請確認(rèn)輸入文件后重試";
                        return; //如果是空文件
                    }
                    if (csvlst[j] != "") {//排除空行
                        double[] dlst = stringPoiToDList(csvlst[j]);
                        if (dlst.Length == 5 && dlst[0] == 0d)
                            return;
                        JProperty jcoord = new JProperty("coordinates",dlst);
                        JProperty jtpoi = new JProperty("type", "Point");

                        JProperty jgomtry =new JProperty("geometry", new JObject(jtpoi, jcoord));
                        JProperty jprots = new JProperty("properties",new JObject());
                        JObject jtfea = new JObject(new JProperty("type", "Feature"),jprots,jgomtry);
                        jfeslst.Add(jtfea);
                    }
                }
                JProperty jfs = new JProperty("features", jfeslst);

                JObject jcsv = new JObject(new JProperty("type", "FeatureCollection"), jfs);
                File.WriteAllText(outputFile, jcsv.ToString());
                infoLabel.Text = "csv 轉(zhuǎn)geojson完成!";
            }
            catch( Exception expt) {
                infoLabel.Text = expt.Message;
            }
        }


Newtonsoft.Json可以很優(yōu)秀地處理json格式的數(shù)據(jù),也可以將其他類型的數(shù)據(jù)(例如kml)解析為json,本文主要講了這個庫處理geojson數(shù)據(jù)的一些方式。
如果您有其他解析需求沒能在本文中找到答案,可以在其官方文檔查看相應(yīng)方法或函數(shù)的使用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容