sql server & .net core 使用空間數據


使用的庫

Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddEntityFrameworkSqlServer()
             .AddDbContext<YourDbContext>(options => options.UseSqlServer(_configuration.GetConnectionString("SqlServer"),
              //映射到空間數據的數據庫中的類型在模型中使用 NTS 類型
              x => x.UseNetTopologySuite()));
}

建表需要注意:Geography or geometry

By default, spatial properties are mapped to geography columns in SQL Server. To use geometry, configure the column type in your model.
默認的數據類型是geography,如果要使用geometry,需要聲明
比如使用geoserver,不識別geography,則需要geometry

[Column(TypeName = "geometry")]
public Polygon Shape { get; set; }

參考資料

新增/修改數據

//srid=4326:wgs84
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
var currentLocation = geometryFactory.CreatePoint(new Coordinate(x, y));

//LinearRing的點必須形成一個封閉的線串,而LineString則不需要
var line = new NetTopologySuite.Geometries.LineString(new Coordinate[]
{
    new Coordinate(10,0),
    new Coordinate(10,10),
    new Coordinate(0,10),
    new Coordinate(0,0),
    //new Coordinate(10,0),
});
//設置坐標系
line.SRID = srid;

var geom = new NetTopologySuite.Geometries.Polygon(
    new LinearRing(new Coordinate[]
    {
        //逆時針繪制
        new Coordinate(10,0),
        new Coordinate(10,10),
        new Coordinate(0,10),
        new Coordinate(0,0),
        new Coordinate(10,0),
    }));
//設置坐標系
geom.SRID = srid;

查詢數據

概念

GeoJSON:一種地理數據的描述格式。GeoJSON可以描述的對象包括:幾何體,要素和要素集。(相關資料)
使用GepJSON需要引用一個新庫

GeoJSON.Net

WKT(Well-known text):一種文本標記語言,用於表示矢量幾何對象、空間參照系統及空間參照系統之間的轉換。它的二進制表示方式,亦即WKB(well-known-binary)則勝於在傳輸和在數據庫中存儲相同的信息。該格式由開放地理空間聯盟(OGC)制定。WKT可以表示的幾何對象包括:點,線,多邊形,TIN(不規則三角網)及多面體。(相關資料)
Geometry/geojson/WKT 三者可以互轉

//Geometry to GeoJSON
Position position = new Position(x, y);
GeoJSON.Net.Geometry.Point point = new GeoJSON.Net.Geometry.Point(position);
var s = JsonConvert.SerializeObject(point);
//Geometry to wkt
var s2= NetTopologySuite.IO.WKTWriter.ToPoint(city.Location.Coordinate);

結果

"GeoJSON結果:{\"type\":\"Point\",\"coordinates\":[10.0,100.0]},WKT結果:POINT(100 10)"

//Geometry to GeoJSON
var coordinates = new List<IPosition>();
foreach (var item in road.Line.Coordinates)
{
    coordinates.Add(new Position(item.X, item.Y, item.Z));
}
GeoJSON.Net.Geometry.LineString line = new GeoJSON.Net.Geometry.LineString(coordinates);
var s= JsonConvert.SerializeObject(line);
//Geometry to wkt
var s2 = NetTopologySuite.IO.WKTWriter.ToLineString(road.Line.CoordinateSequence);

結果

"GeoJSON結果:{\"type\":\"LineString\",\"coordinates\":[[0.0,10.0,\"NaN\"],[10.0,10.0,\"NaN\"],[10.0,0.0,\"NaN\"],[0.0,0.0,\"NaN\"]]},WKT結果:LINESTRING(10 0, 10 10, 0 10, 0 0)"

//Geometry to GeoJSON
var lines = new List<GeoJSON.Net.Geometry.LineString>();
var polygon = country.Border as NetTopologySuite.Geometries.Polygon;
List<Coordinate[]> res = new List<Coordinate[]>();
res.Add(polygon.Shell.Coordinates);
foreach (ILineString interiorRing in polygon.InteriorRings)
{
    res.Add(interiorRing.Coordinates);
}
foreach(var line in res)
{
    var coordinates = new List<IPosition>();
    foreach (var item in line)
    {
        coordinates.Add(new Position(item.X, item.Y, item.Z));
    }
    lines.Add(new GeoJSON.Net.Geometry.LineString(coordinates));
}
GeoJSON.Net.Geometry.Polygon jsonPolygon = new GeoJSON.Net.Geometry.Polygon(lines);
var s = JsonConvert.SerializeObject(jsonPolygon);
//Geometry to wkt
//點和線的是靜態方法,面的是方法_(:з」∠)_
var writer = new NetTopologySuite.IO.WKTWriter();
var s2 = writer.Write(country.Border);

結果

"GeoJSON結果:{\"type\":\"Polygon\",\"coordinates\":[[[0.0,10.0,\"NaN\"],[10.0,10.0,\"NaN\"],[10.0,0.0,\"NaN\"],[0.0,0.0,\"NaN\"],[0.0,10.0,\"NaN\"]]]},WKT結果:POLYGON ((10 0, 10 10, 0 10, 0 0, 10 0))"

計算

計算點與點之間的距離

var distance= NetTopologySuite.Operation.Distance.DistanceOp.Distance(point1, point2);

點是否包含在面以內

var prepGeom = NetTopologySuite.Geometries.Prepared.PreparedGeometryFactory.Prepare(geom);
var isContain = prepGeom.Contains(point);

經緯度Longitude && Latitude

sql server

Coordinates in NTS are in terms of X and Y values. To represent longitude and latitude, use X for longitude and Y for latitude. Note that this is backwards from the latitude, longitude format in which you typically see these values.
簡單來說,X是longitude(經度),Y是latitude(緯度)

geojson

geojson則是相反的

public Position(double latitude, double longitude, double? altitude = null)

示例代碼

示例代碼

參考資料

空間數據
空間類型 - geometry (Transact-SQL)
NTS Topology Suite
空間數據 (SQL Server)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM