Search code examples
c#sqlgeographysql-types

using SqlGeography types in C# client-side


In C# client-side, I am trying to use the SQLServerTypes (SqlServerSpatial140.dll) assembly (edit: doing so directly, SqlServerTypes.Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory)) to measure the distance between points on the planet, between one street address and another street address which are usually within 50 miles of each other (but sometimes a lot farther). Each location is expressed as a latitude/longitude pair.

This is a Framework application and uses the NuGet package.

Is this code correct? I don't think it can be, since the values I'm getting for distance are much too small, e.g. 24.35946... when the two points are hundreds of miles away from each other, such as two towns, one of them in North Carolina and the other in Puerto Rico. Isn't meters the standard unit?

        foreach (Origin o in Origins)
        {
            o.loc = SqlGeometry.Point(o.lat, o.lon, 4326);
            foreach (Destination d in Destinations)
            {
                SqlDouble distance = o.loc.STDistance(SqlGeometry.Point(d.lat, d.lon, 4326));
                <snip>                   
            }
        }

Is 4326 the correct SRID? I get the same results if zero is the SRID. Also, the order in which the parameters to Point are supplied (lat,lon) or (lon,lat) doesn't make the distance numbers much larger.

P.S. I was able to get it working with Brian's help. Here's how I'm instantiating the Point:

 public Microsoft.SqlServer.Types.SqlGeography CreateGeographyPoint(double longitude, double latitude)
        {
            var text = string.Format("POINT({0} {1})", longitude, latitude);
            var ch = new System.Data.SqlTypes.SqlChars(text);
            return Microsoft.SqlServer.Types.SqlGeography.STPointFromText( ch, 4326);
        }

Solution

  • You should use the Sqlgeography class and the Srid of 4326 will give you the result in meters.

    SqlGeometry is for Cartesian coordinates (x, y), and SqlGeography is for Geospatial coordinates Long, Lat in that order.

    Replace SqlGeometry with SqlGeography.