12

试图返回一些非常简单的 GeoJSON 数据。我找到了 NetTopologySuite,并设置了一个简单的 FeaturesCollection,并尝试将其序列化为 GeoJson 字符串,结果却出现以下错误:

“检测到类型为‘GeoAPI.Geometries.Coordinate’的属性‘CoordinateValue’的自引用循环。路径‘Features[0].Geometry.Coordinates[0]’。”

查看类标题,Point 使用 Coordinate,它确实具有 Coordinate 属性,因此我可以看到为什么会有循环引用。问题是,大多数(如果不是全部)几何似乎都使用点,所以这将使得不可能序列化任何东西......除非我错过了一些东西。

那么这是一个错误还是我错过了什么?

仅用一个点进行测试并得到相同的错误,所以这里是代码:

using NTS = NetTopologySuite;

var ret = new NTS.Geometries.Point(42.9074, -78.7911);

var jsonSerializer = NTS.IO.GeoJsonSerializer.Create();

var sw = new System.IO.StringWriter();
jsonSerializer.Serialize(sw, ret);

var json = sw.ToString();
4

3 回答 3

6

更新

GeoJsonSerializer已移至NetTopologySuite.IO.GeoJSON现在有自己的静态Create()方法:

/// <summary>
/// Factory method to create a (Geo)JsonSerializer
/// </summary>
/// <remarks>Calls <see cref="GeoJsonSerializer.CreateDefault()"/> internally</remarks>
/// <returns>A <see cref="JsonSerializer"/></returns>
public new static JsonSerializer Create()
{
    return CreateDefault();
}

直接构造函数的使用已被弃用:

[Obsolete("Use GeoJsonSerializer.Create...() functions")]
public GeoJsonSerializer() : this(Wgs84Factory) { }

问题中的代码现在应该可以按预期工作。


原始答案

使用GeoJsonSerializer类的默认构造函数:

var jsonSerializer = new NetTopologySuite.IO.GeoJsonSerializer();

这附上了一个CoordinateConverter防止问题的方法。

GeoJsonSerializer实际上并没有静态Create()方法,因此您将退回到基类的JsonSerializer.Create(). 事实上,以下会导致编译器错误:

GeoJsonSerializer jsonSerializer = NTS.IO.GeoJsonSerializer.Create();
于 2014-11-05T22:02:15.843 回答
0

您可以使用以下命令,而不是在您已经序列化后返回 Json:

        return Content(sw.ToString, "application/Json");
于 2015-12-16T17:46:21.473 回答
0

聚会有点晚了,但这是我对此的看法:您可以轻松地使其Point与当前的 Json Serializer 设置兼容。

[DataContract]
public class GeoLocation : NetTopologySuite.Geometries.Point
{
    const int GoogleMapsSRID = 4326 ;

    public GeoLocation(double latitude, double longitude)
        : base(x: longitude, y: latitude) =>
          base.SRID = GoogleMapsSRID;

    [DataMember]
    public double Longitude => base.X;

    [DataMember]
    public double Latitude => base.Y;
}

DataContract和是这里的DataMember关键:

new GeoLocation(42.9074, -78.7911).ToJson() => {"longitude":42.9074,"latitude":-78.7911}
于 2020-03-09T04:24:33.783 回答