使用 C# 从 Well Known Text 创建 GeoJSON 输出
Creating GeoJSON output from Well Known Text with C#
我正在尝试创建类似于此处描述的 GeoJSON 格式的 JSON 输出:http://geojson.org/geojson-spec.html
特别是,我有从我的数据源以文本格式返回的文本,我想将我的 DTO 转换为 JSON,格式如下我的评论所示。我遇到的主要问题是尝试创建没有 属性 名称的坐标数组 [[ ... ]]。
代码:
/*
Geometry Text Format from database: POLYGON ((319686.3666000003 7363726.7955, 319747.05190000031 7363778.9233, 319700.78849999979 7363832.7814, 319640.10329999961 7363780.6536, 319686.3666000003 7363726.7955))
And we want format:
"geometry": {
"type": "Polygon",
"coordinates": [[
[319686.3666000003, 7363726.795],
[319747.0519000003, 7363778.9233],
[319700.78849999979, 7363832.7814],
[319640.10329999961, 7363780.6536],
[319686.3666000003, 7363726.795]
]]
}
*/
// Strip out everything except the coordinates
var coordRawText = myWkt.Replace("POLYGON ((", "");
coordRawText = coordRawText.Replace("))", "");
coordRawText = coordRawText.Replace(", ", ",");
// Seperate coordinates to iterate through
var coordsArray = coordRawText.Split(',');
var coordsEnumerable = coordsArray.Select(coord => coord.Replace(" ", ","));
// Build list of coordinates
var coordsList = new List<CoordinateDto>();
foreach (var coord in coordsEnumerable)
{
var splt = coord.Split(',');
var x = double.Parse(splt[0]);
var y = double.Parse(splt[1]);
coordsList.Add(new CoordinateDto {X = x, Y = y});
}
myDto.Geometry = new GeometryDto
{
Type = "Polygon",
Coordinates = coordsList
};
以上输出 "almost" 我想要的,但不完全是。输出如下图:
"geometry":{"type":"Polygon","coordinates":[{"x":319686.3666000003,"y":7363726.7955},{"x":319747.05190000031,"y":7363778.9233},{"x":319700.78849999979,"y":7363832.7814},{"x":319640.10329999961,"y":7363780.6536},{"x":319686.3666000003,"y":7363726.7955}]}
我的DTO定义如下:
[DataContract]
public class GeometryDto
{
[DataMember]
public string Type { get; set; }
[DataMember]
public List<CoordinateDto> Coordinates { get; set; }
}
[DataContract]
public class CoordinateDto
{
[DataMember]
public double X { get; set; }
[DataMember]
public double Y { get; set; }
}
我曾尝试使用元组而不是坐标 class,但只是插入了 "item1" 和 "item2" 属性 名称而不是 "x" 和 "y".
我唯一没有尝试过的是创建我自己的 JSON 转换器?
在此先感谢您的帮助,
亲切的问候,
斯蒂芬
更新解决方案
多亏了这里选择的答案(来自 Dhanuka777)关于多维数组,我找到了一个解决方案,但为了完整性以防它有帮助:
我必须创建一个新的辅助函数(Jon Skeet 的 Create Rectangular Array 函数的略微修改版本,来自此处:How to convert list of arrays into a multidimensional array)
代码解决方案如下图:
/*
Geometry Text Format from database: POLYGON ((319686.3666000003 7363726.7955, 319747.05190000031 7363778.9233, 319700.78849999979 7363832.7814, 319640.10329999961 7363780.6536, 319686.3666000003 7363726.7955))
And we want format:
"geometry": {
"type": "Polygon",
"coordinates": [[
[319686.3666000003, 7363726.795],
[319747.0519000003, 7363778.9233],
[319700.78849999979, 7363832.7814],
[319640.10329999961, 7363780.6536],
[319686.3666000003, 7363726.795]
]]
}
*/
// Strip out everything except the coordinates
var coordRawText = myWkt.Replace("POLYGON ((", "");
coordRawText = coordRawText.Replace("))", "");
coordRawText = coordRawText.Replace(", ", ",");
// Seperate coordinates to iterate through
var coordsArray = coordRawText.Split(',');
var coordsEnumerable = coordsArray.Select(coord => coord.Replace(" ", ","));
// Build list of coordinates
var coordsList = new List<double[,]>();
foreach (var coord in coordsEnumerable)
{
var splt = coord.Split(',');
var x = double.Parse(splt[0]);
var y = double.Parse(splt[1]);
coordsList.Add(new[,] {{ x, y }});
}
myDto.Geometry = new GeometryDto
{
Type = "Polygon",
Coordinates = CreateRectangularArray(coordsList)
};
Create Rectangular Array 定义的稍微修改版本如下:
static T[,] CreateRectangularArray<T>(IList<T[,]> arrays)
{
// TODO: Validation and special-casing for arrays.Count == 0
int minorLength = arrays[0].Length;
T[,] ret = new T[arrays.Count, minorLength];
for (int i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
if (array.Length != minorLength)
{
throw new ArgumentException
("All arrays must be the same length");
}
for (int j = 0; j < minorLength; j++)
{
ret[i, j] = array[0, j];
}
}
return ret;
}
更新后的GeometryDto如下:
[DataContract]
public class GeometryDto
{
[DataMember]
public string Type { get; set; }
[DataMember]
public double[,] Coordinates { get; set; }
}
Web API 将使用 Newtonsoft Json 以所需格式序列化对象。
我宁愿使用 Newtonsoft Json 序列化程序来输出它。将坐标定义为二维数组即可。
public class GeometryDto
{
public string Type { get; set; }
public double[,] coordinates { get; set; }
}
class Program
{
static void Main()
{
var obj = new GeometryDto
{
Type = "Polygon",
coordinates = new double[,] { { 319686.3666000003, 7363726.795 }, { 319747.0519000003, 7363778.9233 }, { 5.3434444, 6.423443 }, { 7.2343424234, 8.23424324 } }
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
Console.WriteLine(json);
Console.ReadKey();
}
}
从这里获取 Nuget。
输出:
{"Type":"Polygon","coordinates":[[319686.3666000003,7363726.795],[319747.05190000031,7363778.9233],...]}
我正在尝试创建类似于此处描述的 GeoJSON 格式的 JSON 输出:http://geojson.org/geojson-spec.html
特别是,我有从我的数据源以文本格式返回的文本,我想将我的 DTO 转换为 JSON,格式如下我的评论所示。我遇到的主要问题是尝试创建没有 属性 名称的坐标数组 [[ ... ]]。
代码:
/*
Geometry Text Format from database: POLYGON ((319686.3666000003 7363726.7955, 319747.05190000031 7363778.9233, 319700.78849999979 7363832.7814, 319640.10329999961 7363780.6536, 319686.3666000003 7363726.7955))
And we want format:
"geometry": {
"type": "Polygon",
"coordinates": [[
[319686.3666000003, 7363726.795],
[319747.0519000003, 7363778.9233],
[319700.78849999979, 7363832.7814],
[319640.10329999961, 7363780.6536],
[319686.3666000003, 7363726.795]
]]
}
*/
// Strip out everything except the coordinates
var coordRawText = myWkt.Replace("POLYGON ((", "");
coordRawText = coordRawText.Replace("))", "");
coordRawText = coordRawText.Replace(", ", ",");
// Seperate coordinates to iterate through
var coordsArray = coordRawText.Split(',');
var coordsEnumerable = coordsArray.Select(coord => coord.Replace(" ", ","));
// Build list of coordinates
var coordsList = new List<CoordinateDto>();
foreach (var coord in coordsEnumerable)
{
var splt = coord.Split(',');
var x = double.Parse(splt[0]);
var y = double.Parse(splt[1]);
coordsList.Add(new CoordinateDto {X = x, Y = y});
}
myDto.Geometry = new GeometryDto
{
Type = "Polygon",
Coordinates = coordsList
};
以上输出 "almost" 我想要的,但不完全是。输出如下图:
"geometry":{"type":"Polygon","coordinates":[{"x":319686.3666000003,"y":7363726.7955},{"x":319747.05190000031,"y":7363778.9233},{"x":319700.78849999979,"y":7363832.7814},{"x":319640.10329999961,"y":7363780.6536},{"x":319686.3666000003,"y":7363726.7955}]}
我的DTO定义如下:
[DataContract]
public class GeometryDto
{
[DataMember]
public string Type { get; set; }
[DataMember]
public List<CoordinateDto> Coordinates { get; set; }
}
[DataContract]
public class CoordinateDto
{
[DataMember]
public double X { get; set; }
[DataMember]
public double Y { get; set; }
}
我曾尝试使用元组而不是坐标 class,但只是插入了 "item1" 和 "item2" 属性 名称而不是 "x" 和 "y".
我唯一没有尝试过的是创建我自己的 JSON 转换器?
在此先感谢您的帮助,
亲切的问候,
斯蒂芬
更新解决方案
多亏了这里选择的答案(来自 Dhanuka777)关于多维数组,我找到了一个解决方案,但为了完整性以防它有帮助:
我必须创建一个新的辅助函数(Jon Skeet 的 Create Rectangular Array 函数的略微修改版本,来自此处:How to convert list of arrays into a multidimensional array)
代码解决方案如下图:
/*
Geometry Text Format from database: POLYGON ((319686.3666000003 7363726.7955, 319747.05190000031 7363778.9233, 319700.78849999979 7363832.7814, 319640.10329999961 7363780.6536, 319686.3666000003 7363726.7955))
And we want format:
"geometry": {
"type": "Polygon",
"coordinates": [[
[319686.3666000003, 7363726.795],
[319747.0519000003, 7363778.9233],
[319700.78849999979, 7363832.7814],
[319640.10329999961, 7363780.6536],
[319686.3666000003, 7363726.795]
]]
}
*/
// Strip out everything except the coordinates
var coordRawText = myWkt.Replace("POLYGON ((", "");
coordRawText = coordRawText.Replace("))", "");
coordRawText = coordRawText.Replace(", ", ",");
// Seperate coordinates to iterate through
var coordsArray = coordRawText.Split(',');
var coordsEnumerable = coordsArray.Select(coord => coord.Replace(" ", ","));
// Build list of coordinates
var coordsList = new List<double[,]>();
foreach (var coord in coordsEnumerable)
{
var splt = coord.Split(',');
var x = double.Parse(splt[0]);
var y = double.Parse(splt[1]);
coordsList.Add(new[,] {{ x, y }});
}
myDto.Geometry = new GeometryDto
{
Type = "Polygon",
Coordinates = CreateRectangularArray(coordsList)
};
Create Rectangular Array 定义的稍微修改版本如下:
static T[,] CreateRectangularArray<T>(IList<T[,]> arrays)
{
// TODO: Validation and special-casing for arrays.Count == 0
int minorLength = arrays[0].Length;
T[,] ret = new T[arrays.Count, minorLength];
for (int i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
if (array.Length != minorLength)
{
throw new ArgumentException
("All arrays must be the same length");
}
for (int j = 0; j < minorLength; j++)
{
ret[i, j] = array[0, j];
}
}
return ret;
}
更新后的GeometryDto如下:
[DataContract]
public class GeometryDto
{
[DataMember]
public string Type { get; set; }
[DataMember]
public double[,] Coordinates { get; set; }
}
Web API 将使用 Newtonsoft Json 以所需格式序列化对象。
我宁愿使用 Newtonsoft Json 序列化程序来输出它。将坐标定义为二维数组即可。
public class GeometryDto
{
public string Type { get; set; }
public double[,] coordinates { get; set; }
}
class Program
{
static void Main()
{
var obj = new GeometryDto
{
Type = "Polygon",
coordinates = new double[,] { { 319686.3666000003, 7363726.795 }, { 319747.0519000003, 7363778.9233 }, { 5.3434444, 6.423443 }, { 7.2343424234, 8.23424324 } }
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
Console.WriteLine(json);
Console.ReadKey();
}
}
从这里获取 Nuget。
输出: {"Type":"Polygon","coordinates":[[319686.3666000003,7363726.795],[319747.05190000031,7363778.9233],...]}