use*_*050 5 c# json nettopologysuite asp.net-core-2.2
我想从种子文件中为用户对象的“位置”数据注入种子
c#对象,其中Point是a NetTopologySuite.Geometries.Point是我的用户对象的一部分
public class User: IdentityUser<int> {
// member data here
public Point Location { get; set; } // has lat/lng data points
}
Run Code Online (Sandbox Code Playgroud)
我通过执行以下操作将数据播种到我的数据库中
public void SeedUsers()
{
if (!_userManager.Users.Any())
{
var userData = System.IO.File.ReadAllText("Data/UserSeedData.json");
var users = JsonConvert.DeserializeObject<List<User>>(userData);
var roles = new List<Role>
{
new Role{Name = "Member"},
new Role{Name = "Admin"},
new Role{Name = "Moderator"},
new Role{Name = "VIP"},
};
foreach (var role in roles)
{
_roleManager.CreateAsync(role).Wait();
}
foreach (var user in users)
{
user.Photos.SingleOrDefault().IsApproved = true;
_userManager.CreateAsync(user, "password").Wait();
_userManager.AddToRoleAsync(user, "Member").Wait();
}
}
}
Run Code Online (Sandbox Code Playgroud)
用这样的json数组的json文件“ UserSeedData.json”,我希望能够在其中粘贴表示lng / lat数据点的某种“位置”数据。
public class User: IdentityUser<int> {
// member data here
public Point Location { get; set; } // has lat/lng data points
}
Run Code Online (Sandbox Code Playgroud)
现在,我知道我的种子方法可以做到这一点,但是我正在寻找一种将其包含在.json文件中的方法,因此我可以使用不同的数据点
foreach (var user in users)
{
user.Photos.SingleOrDefault().IsApproved = true;
user.Location = new Point(-122.4194155, 37.7749295) { SRID = 4326 };
_userManager.CreateAsync(user, "password").Wait();
_userManager.AddToRoleAsync(user, "Member").Wait();
}
Run Code Online (Sandbox Code Playgroud)
NetTopologySuite具有一个单独的nuget NetTopologySuite.IO.GeoJSON,用于使用Json.NET将NetTopologySuite类型从JSON序列化为JSON。它包括用于几何对象(例如)的转换器Point。如果您将此nuget添加到您的项目中,您将能够添加诸如Point数据模型之类的几何实体并直接对模型进行(反)序列化。
为此,首先将NetTopologySuite.IO.GeoJSON添加到您的项目中。
然后添加以下扩展方法:
public static partial class JsonExtensions
{
public static T LoadFromFileWithGeoJson<T>(string path, JsonSerializerSettings settings = null)
{
var serializer = NetTopologySuite.IO.GeoJsonSerializer.CreateDefault(settings);
serializer.CheckAdditionalContent = true;
using (var textReader = new StreamReader(path))
using (var jsonReader = new JsonTextReader(textReader))
{
return serializer.Deserialize<T>(jsonReader);
}
}
}
Run Code Online (Sandbox Code Playgroud)
并按照您的问题Location向User模型添加属性:
public class User : IdentityUser<int>
{
public Point Location { get; set; }
// Remainder unchanged.
// ...
}
Run Code Online (Sandbox Code Playgroud)
现在,JSON格式Point如下所示:
{"type":"Point","coordinates":[-122.431297,37.773972]}
Run Code Online (Sandbox Code Playgroud)
因此,将您的JSON文件编辑为:
[
{
"Location": {
"type": "Point",
"coordinates": [
-122.431297,
37.773972
]
},
// Remainder unchanged
Run Code Online (Sandbox Code Playgroud)
完成所有这些操作后,您将可以非常简单地反序列化JSON文件,如下所示:
var users = JsonExtensions.LoadFromFileWithGeoJson<List<User>>("Data/UserSeedData.json");
Run Code Online (Sandbox Code Playgroud)
笔记:
NetTopologySuite.IO.GeoJSON需要Newtonsoft.Json版本9.0.1或更高版本。如果您使用的是更高版本,则可能需要添加bindingRedirect以避免生成警告。
请参阅如何将[NetTopologySuite.IO.GeoJSON]与ASP.NET Core一起使用,以获取有关将此包集成到项目中的其他信息。
本SRID似乎并没有被保存为点的JSON的一部分。相反,它是由IGeometryFactory反序列化时使用的设置的Point,默认情况下为new GeometryFactory(new PrecisionModel(), 4326);。
如果您需要对此进行控制,则可以JsonSerializer使用来使用特定工厂构造一个GeoJsonSerializer.Create(IGeometryFactory factory)。
演示在这里摆弄。
您可以子类化NetTopologySuite.Geometries.Point并添加一个[JsonConstructor]来解析您的 json 文件。它应该可以直接替换其余代码。
public class MyPoint : Point
{
[JsonConstructor]
public MyPoint(double latitude, double longitude, int srid)
:base(new GeoAPI.Geometries.Coordinate(longitude, latitude))
{
SRID = srid;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,纬度 = y 且经度 = x,因此顺序相反。
换成你MyPoint的班级PointUser
public class User: IdentityUser<int> {
// member data here
public MyPoint Location { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
它应该按原样与您的 json 一起使用。