C#解析GEOJSON数据

之前的一篇文章里介绍了geojson的标准格式,这里介绍一下用C#的Newtonsoft.Json库对一个geojson文件进行解析,因为Python的json库解析json还是非常容易的,用json.load或json.loads就可以读入json数据然后按照字典或列表的方式进行定位和更改其中的内容,因为最近一个 项目需要用C#进行解析,这里做一个记录。

下载与安装Newtonsoft.Json

首先在官网下载Newtonsoft.Json。官网上号称:

Popular high-performance JSON framework for .NET

当然确实还是很好用的,提供的接口还是挺友好的,开始入手可能有一些小困难。这个库的功能主要有3大块,分别为序列化json(将文本保存的json解析为可查询的json)、反序列化json和用LINQ对json进行查询。

在官网上可以点击Download下载压缩文件然后在自己的工程的解决方案管理器里添加引用,找到Newtonsoft.Json.dll文件然后引用。还有一个更快捷的方式是使用程序包管理器控制台进行安装,过程如下图:

C#解析GEOJSON数据_第1张图片
Newtonsoft.Json的安装

先打开 程序包管理器控制台,然后输入Install-Package Newtonsoft.json 进行安装。

安装好后在项目里记得添上using Newtonsoft.Json;这条语句。
这个库提供的数据类型有JObject、JProperty以及最基本的JToken。

读入json数据

下面是读入json并序列化到一个JObject对象的过程

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

如果输入文件inputFile不是标准的json格式可能会引发JsonReaderException异常。

索引对应数据

例如下面的geojson数据:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {"NAME": "hanzghou poi", "id": 1, "prov": " zhejiang"},
      "geometry": {
        "type": "Point",
        "coordinates": [
          120.07850646972656,
          30.304428412161137
        ]
      }
    }
  ]
}
C#解析GEOJSON数据_第2张图片
该数据的效果

我们用前面的两句代码读入后,可以用JToken jprop=o["type"]索引到文本FeatureCollection,JToken可以对应各种类型的数据,并且保存着原来json的结构,可以在向下索引或者回溯到父节点。而JToken jfts = o["features"]已知内容是一个数组,可以用List jlst = jfts.ToList();对里面的元素进行枚举,

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

对于json的在大括号里的键值对(一般称为字典格式)数据,可以通过类似 o["features"] 的方式,将键放在中括号里进行索引,可以多级索引并保存为数值类型或者文本类型(需要一个隐式转换的语句)而不限于JToken进行保存,例如:string jtw = (string)jlst[i]["geometry"]["type"];,如果想要提取键怎么办呢?JToken没有获取键的接口,这个我摸索了一段时间,可以通过JProperty类型来解决,JProperty 有Name接口可以获取相应的Name;

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

geojson数据写入csv

下面是一个提取geojson的点数据到csv和根据csv写一个geojson文件的小示例,包含了从0开始写一个geojson文件的过程。

        /// 
        /// geojson转csv,只对点要素有效
        /// 
        private void geojsonToCsvPoi () {
            //其他要素不管,如果没有点要素,生成为空
            StreamReader sr = new StreamReader(inputFile, Encoding.UTF8);
            JObject o = JObject.Parse(sr.ReadToEnd());

            JToken jfts = o["features"];

            List jlst = jfts.ToList();
            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 转换完成";//逻辑上不是,但为了不覆盖catch的内容,写在了这里
                    }
                    catch (Exception exp) {
                        infoLabel.Text = exp.Message;
                    }
                }else { //
                }
            }
            csvWter.Close();
            
        }

        /// 
        /// csv转geojson的点数据
        /// 
        private void csvPoiToGeojson () {
            try {
                StreamReader csvRder = new StreamReader(inputFile,Encoding.UTF8);
                string csvall = csvRder.ReadToEnd();//读入csv文件
                string[] csvlst = csvall.Split('\n');
                List jfeslst = new List();
                for (int j = 0; j < csvlst.Length; j++) {
                    if (csvlst[j] == "" && j == 0) {
                        infoLabel.Text = "输入csv文件为空,请确认输入文件后重试";
                        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 转geojson完成!";
            }
            catch( Exception expt) {
                infoLabel.Text = expt.Message;
            }
        }


Newtonsoft.Json可以很优秀地处理json格式的数据,也可以将其他类型的数据(例如kml)解析为json,本文主要讲了这个库处理geojson数据的一些方式。
如果您有其他解析需求没能在本文中找到答案,可以在其官方文档查看相应方法或函数的使用。

你可能感兴趣的:(C#解析GEOJSON数据)