之前的一篇文章里介绍了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文件然后引用。还有一个更快捷的方式是使用程序包管理器控制台进行安装,过程如下图:
先打开 程序包管理器控制台,然后输入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
]
}
}
]
}
我们用前面的两句代码读入后,可以用JToken jprop=o["type"]索引到文本FeatureCollection,JToken可以对应各种类型的数据,并且保存着原来json的结构,可以在向下索引或者回溯到父节点。而JToken jfts = o["features"]已知内容是一个数组,可以用List
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数据的一些方式。
如果您有其他解析需求没能在本文中找到答案,可以在其官方文档查看相应方法或函数的使用。