web-dev-qa-db-ja.com

ASP.NetコアのJsonファイルからNetTopologySuite.Geometries.Pointデータをシードする方法

シードファイルからユーザーオブジェクトの「場所」データをシードしたい

C#オブジェクト。PointはNetTopologySuite.Geometries.Pointはユーザーオブジェクトの一部です

  public class User: IdentityUser<int> {
      // member data here
      public Point Location { get; set; } // has lat/lng data points
  }

このようなことをして、起動時にデータベースにデータをシードします

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();
        }
     }
 }

このようなjson配列のjsonファイル "UserSeedData.json"を使用して、lng/latデータポイントを表すある種の「位置」データをそこに貼り付けることができます。

{
  "Email": "[email protected]",
  "Username": "Lola",
  "Gender": "female",
  "DateOfBirth": "1994-02-21",
  "Password": "password",
  "Created": "2017-08-02",
  "LastActive": "2017-08-02",
  "Introduction": "blah blah blah",
  "LookingFor": "blah blah blah",
  "City": "San Francisco",
  "Country": "United States",
  "Longitude": -122.431297,
  "Latitude": 37.773972,
  "Location": // something here!!!
  "Photos": [{
    "url": "https://randomuser.me/api/portraits/women/3.jpg",
    "isMain": true,
    "description": "Non deserunt labore sunt ex laboris et adipisicing ullamco officia minim."
  }]
}

これで、シードメソッドでこのようなことができることがわかりましたが、.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();
}
6
user1186050

NetTopologiySuiteのPointオブジェクトにはパラメーターのないコンストラクターが含まれていないため、逆シリアル化中にJSONを簡単にマップすることはできません。

ただし、独自のLocationオブジェクトを簡単に作成し、ループ内で値をNetTopologySuiteのPointオブジェクトにマッピングすることができます。

まず、新しいLocationオブジェクトを定義します...

public class Location
{
    public double Longitude { get; set; }
    public double Latitude { get; set; }
    public int SRID { get; set; }
}

次に、JSONのロケーション行を以下の行で更新して、ロケーションオブジェクトを定義します。

"Location": {"Longitude":-122.4194155, "Latitude":37.7749295, "SRID":4326},

完全なJSON:

[{
        "Email": "[email protected]",
        "Username": "Lola",
        "Gender": "female",
        "DateOfBirth": "1994-02-21",
        "Password": "password",
        "Created": "2017-08-02",
        "LastActive": "2017-08-02",
        "Introduction": "blah blah blah",
        "LookingFor": "blah blah blah",
        "City": "San Francisco",
        "Country": "United States",
        "Longitude": -122.431297,
        "Latitude": 37.773972,
        "Location": {"Longitude":-122.4194155, "Latitude":37.7749295, "SRID":4326},
        "Photos": [{
            "url": "https://randomuser.me/api/portraits/women/3.jpg",
            "isMain": true,
            "description": "Non deserunt labore sunt ex laboris et adipisicing ullamco officia minim."
        }]
    }]

次に、新しいLocationオブジェクトを使用するようにUserオブジェクトを更新し、NetTopologySuiteのPointオブジェクトにJsonIgnore属性を設定します。

public class User : IdentityUser<int>
{
    // member data here

    public Location Location { get; set; }

    [JsonIgnore]
    public Point LocationPoint { get; set; } // has lat/lng data points
}

最後に、foreachループを更新してデータをマップします...

foreach (var user in users)
{
    user.Photos.SingleOrDefault().IsApproved = true;
    user.LocationPoint = new Point(user.Location.Longitude, user.Location.Latitude) {SRID = user.Location.SRID};
    _userManager.CreateAsync(user, "password").Wait();
    _userManager.AddToRoleAsync(user, "Member").Wait();
}

以上のように、NetTopologySuiteのPointオブジェクトをユーザーオブジェクト内で直接使用することを再考し、代わりに独自のロケーションオブジェクトを使用することをお勧めします。次に、実際にPointを使用するコードに近いNetTopologySuiteのPointオブジェクトに転置します。ただし、これはアプリケーションによって異なります。

1
quaabaam

パーティーには少し遅れますが、これは私の見解です。Pointを現在のJsonシリアライザーの設定と簡単に互換させることができます。

[DataContract]
public class GeoLocation : NetTopologySuite.Geometries.Point
{
    const int GoogleMapSRID = 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;
}

DataContractDataMemberはここで重要です:

new GeoLocation(42.9074, -78.7911).ToJson() => {"longitude":42.9074,"latitude":-78.7911}
0
Ahmed Alejo