【问题标题】:Construct DbGeography point from Latitude and Longitude doubles?从纬度和经度双打构造 DbGeography 点?
【发布时间】:2022-04-29 00:51:17
【问题描述】:

我想从纬度和经度双精度中构造一个 DbGeography 点。

我知道我可以将我的双打转换为字符串并使用DbGeography.FromText 方法。

var latitude = 50.0d;
var longitude = 30.0d;

var pointString = string.Format(
    "POINT({0} {1})",
    longitude.ToString(),
    latitude.ToString());

var point = DbGeography.FromText(pointString);

但是将我的双打转换为字符串似乎很浪费,以便 DbGeography 可以再次将它们解析为双打。


我尝试像这样直接构建 DbGeography:

var point = new DbGeography()
{
    Latitude = 50,
    Longitude = 30
};

但纬度和经度属性是只读的。 (这是有道理的,因为 DbGeography 类处理的不仅仅是单个点)


DbGeography 类还提供了一个采用字节数组的FromBinary 方法。我不确定如何将我的纬度和经度加倍转换为格式正确的字节数组。

有没有比顶部的代码更简单的方法来构造一个经纬度双精度的 DbGeography 实例?

【问题讨论】:

  • 你为什么不创建一个方法public static DbGeography CreatePoint(double, double) 来包装你的代码?它不会避免转换,但至少可以让你的代码更清晰......
  • 我可能最终会做这样的事情。没有静态扩展方法太糟糕了;我希望能够将所有静态 DbGeography 创建方法保留在一个类下。
  • 并不是说这真的有帮助,但在 C# 6+ 版本中,您可以像这样使用字符串插值: DbGeography.FromText($"POINT({longitude} {latitude})");跨度>

标签: entity-framework geospatial


【解决方案1】:

简而言之,没有。

SqlGeography 有一个合适的方法:

Microsoft.SqlServer.Types.SqlGeography.Point(latitude, longitude, srid);

...但是无论如何您都必须转换为 DbGeography。如果您对此感兴趣,请参阅我之前关于转换的答案:DbGeography to SqlGeography (and back)

也就是说,我完全同意 Raphael Althaus 的观点,即您应该创建一个静态方法来让您的生活更轻松:

public static DbGeography CreatePoint(double lat, double lon, int srid = 4326)
{
    string wkt = String.Format("POINT({0} {1})", lon, lat);

    return DbGeography.PointFromText(wkt, srid);
}

那么所有的使用都可以通过那个方法。

编辑

@Korayem 提出了一个很好的建议,自从最初回答这个问题以来,我实际上已经完成了自己的工作。大多数人使用 SRID 4326,因此我们可以通过将其作为参数的默认值来使静态方法更易于使用。

【讨论】:

  • 包含 CreatePoint 方法的有用 GeoUtils 类可以在这里找到:codepaste.net/73hssg
  • @Zharro 虽然不难修改以满足用户需求,但上面的示例还允许动态 SRID 值,而 GeoUtils 假定为 4326。有些人需要不同的 SRID(并且可以简单地更改数字)但有些人们使用多个 SRID,并且能够在方法参数中指定它允许这样做。
  • @JonBellamy @Zharro 这样做可以两全其美public static DbGeography CreatePoint(double lat, double lon, int srid=4326)
  • @Shimmy 当你想使用空间函数(例如最近的位置等)时,好处就来了。如果你不做任何这些,就没有真正的好处。您可以创建一个复杂类型,但如果您这样做,您不妨使用 DbGeography (SqlGeography),因此只需创建两列。
  • 我还建议将答案更改为始终使用 CultureInfo.InvariantCulture。在我的文化中,逗号是小数分隔符,所以这段代码不能马上工作。
【解决方案2】:

你可以这样简化:

  DbGeography.FromText(String.Format(CultureInfo.InvariantCulture, "POINT({0} {1})", longitude, latitude));

例如:

DbGeography.FromText("POINT(-73.935242 40.730610)"),

不使用 int srid = 4326;这是默认值。

如果您多次使用它,请在静态方法中使用它:

private static DbGeography CreatePoint(double latitude, double longitude)
{
    return DbGeography.FromText(String.Format(CultureInfo.InvariantCulture, "POINT({0} {1})", longitude, latitude));
}

PS:不要忘记使用CultureInfo.InvariantCulture,因为某些文化会例外。

【讨论】:

    【解决方案3】:

    假设您的目标是 SQL Server,您可以在不进行字符串解析的情况下执行此操作。首先创建一个SqlGeography:

    var sqlPoint = Microsoft.SqlServer.Types.SqlGeography.Point(latitude, longitude, srid);
    

    然后从此 SqlGeography 创建一个 DbGeography(请参阅我的 answer 以了解有关 DbGeography 转换的单独问题)。

    var dbPoint = System.Data.Entity.SqlServer.SqlSpatialServices.Default.GeographyFromProviderValue(sqlPoint);
    

    【讨论】:

      【解决方案4】:

      你可以使用SqlGeographyBuilder来做到这一点

                      SqlGeographyBuilder sqlGeographyBuilder = new SqlGeographyBuilder();
                      sqlGeographyBuilder.SetSrid(4326);
                      sqlGeographyBuilder.BeginGeography(OpenGisGeographyType.Polygon);
                      sqlGeographyBuilder.BeginFigure(37.944197500754 ,- 127.24365234375);
                      sqlGeographyBuilder.AddLine(37.944197500754 ,- 80.68359375);
                      sqlGeographyBuilder.AddLine(24.966140159913 ,- 80.68359375);
                      sqlGeographyBuilder.AddLine(24.966140159913 ,- 127.24365234375);
                      sqlGeographyBuilder.AddLine(37.944197500754 ,- 127.24365234375);
                      sqlGeographyBuilder.EndFigure();
                      sqlGeographyBuilder.EndGeography();
      
                      SqlGeography polygon = sqlGeographyBuilder.ConstructedGeography;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-05
        • 2015-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-10
        相关资源
        最近更新 更多