استفاده از داده های مکانی در EfCore   - قسمت دوم : آموزش NetTopologySuite
استفاده از داده های مکانی در EfCore - قسمت دوم : آموزش NetTopologySuite

 در قسمت قبل با داده های مکانی آشنا شدیم، داده های مکانی بیانگر موقعیت فیزیکی و شکل اشیاء بر روی مختصات جغرافیایی هستند. بسیاری از بانک های اطلاعاتی از جمله SQL Server از داده های مکانی پشتیبانی می کنند و می توانیم در کنار سایر انواع داده ای، از داده های مکانی نیز در موجودیت های خودمان استفاده کنیم.
به صورت پیشفرض داده های مکانی در EFCore  پشتیبانی نمی شوند مایکروسافت از نسخه EFCore 2.2 کتابخانه NetTopologySuite که به اختصار NTS هم گفته می شود را برای پشتیبانی از داده های مکانی ارائه کرد. پس برای استفاده از داده های مکانی در EFCore حتما باید از نسخه 2.2 به بالاتر استفاده کنیم و کتابخانه NetTopologySuite هم نصب کنیم.

 

  • نصب NetTopologySuite

بسته کتابخانه NetTopologySuite را می توانیم از Nuget  نصب کنیم. این کتابخانه چهار نوع مختلف را ارائه کرده است که می توانیم بسته به Provider مورد نظرمان یکی از آنها را نصب کنیم.

 

توضیحاتبسته NugetEf Core Provider
پشتیبانی از MSSQL Server  در Entity Freamwork Core

Microsoft.EntityFrameworkCore

.SqlServer.NetTopologySuite

 

Microsoft.EntityFrameworkCore.SqlServer
پشتیبانی از پایگاه داده SQLite  در Entity Freamwork Core

Microsoft.EntityFrameworkCore

.Sqlite.NetTopologySuite

Microsoft.EntityFrameworkCore.Sqlite
 NetTopologySuiteMicrosoft.EntityFrameworkCore.InMemory
پشتیبانی از Npgsql در Entity Freamwork PostgreSQL

Npgsql.EntityFrameworkCore.

PostgreSQL.NetTopologySuite

Npgsql.EntityFrameworkCore.PostgreSQL
  •   انواع داده مکانی در NetTopologySuite  

شش نوع داده مکانی در کتابخانه NetTopologySuite  پشتیبانی می شود که می توانیم از آنها در موجودیت های برنامه استفاده کنیم. انواع داده ای NetTopologySuite در فضای نام NetTopologySuite.Geometries قرار دارند.

  1.   Point

  2.   LineString

  3.    Polygon

  4.   MultiPoint

  5.   MultiLineString

  6.   MultiPolygon

توجه: در قسمت اول مقاله توضیح کاملی در مورد انواع داده های مکانی ارائه شده است.

  •   فعال کردن NetTopologySuite در DBContext

همانطور که گفتیم NetTopologySuite یک کتابخانه مکانی برای فریمورک دات نت است که کار Mapping داده های مکانی در EntityFreamCore را انجام می دهد.
برای فعال کردن mapping انوع داده ای NetTopologySuite به داده های مکانی باید در DBContxt  متُد UseNetTopologySuite را در قسمت provider مربوطه استفاده کنیم. به عنوان مثال در SqlServer به صورت زیر آن را فعال می کنیم.

string connection = "Data Source=.;Initial Catalog=BugetoSpatialData;Integrated Security=True;MultipleActiveResultSets=true ";
services.AddEntityFrameworkSqlServer()
.AddDbContext<DataBaseContext>(option =>
option.UseSqlServer(connection, x => x.UseNetTopologySuite()));

 

 

  •  استفاده از NetTopologySuite در موجودیت ها

یک کلاس به نام Store ایجاد کرده ایم، ازاین کلاس برای نگهداری اطلاعات فروشگاه استفاده می کنیم. در اطلاعات فروشگاه ما قصد داریم که موقعیت مکانی فروشگاه هم در کنار دیگر اطلاعات آن نگهداری کنیم. برای نگهداری موقعیت مکانی یک فیلد با نام Location واز نوع Point به کلاس Store اضافه کرده ایم.
برای نمایش یک موقعیت مکانی به دو عدد X,Y و یا همان Lat,Long نیاز داریم، نوع داده ای Point هم دو عدد X,Y را دریافت می کند. که X برای نگهداری Long و Y برای نگهداری Lat است. به همین دلیل برای نگهداری موقعیت مکانی فروشگاه از نوع داده ای Point استفاده کردیم. البته اگر هر فروشگاه چندین شعبه داشته باشد باید از نوع داده ای MultiPoint استفاده کنیم.

 

  using NetTopologySuite.Geometries;
  public class Store
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public string PhoneNumber { get; set; }
        [Column(TypeName = "geometry")]
        public Point  Location { get; set; }
    }

 

  •    افزودن مقادیر

برای ذخیره مکان یک شئ در بانک اطلاعاتی باید یک نمونه از نوع geometry با استفاده از طول عرض جغرافیایی آن شئ ایجاد کنیم و سپس این نمونه ساخته شده از نوع geometry را ذخیره نماییم. برای ایجاد نمونهgeometry می توانیم از متُد CreateGeometryFactory مربوط به کتابخانه NetTopologySuite استفاده کنیم. پس از ساخت یک نمونه از CreateGeometryFactory می توانیم با استفاده از تابع CreatePoint یک نقطه را ایجاد کنیم. این تابع طول عرض جغرافیایی را به عنوان پارامتر دریافت می کند.
متُد CreateGeometryFactory پارامتری به نام SRID دریافت می کند. SRID شناسه منحصر به فردی است که در سیستم های مختصات جغرافیایی استفاده می شود و عدد 4326 یک استاندارد متداول است که بسیاری از برنامه ها از جمله، Waze ، Google Map  از آن  برای SRID استفاده کرده اند.


1.    برای ایجاد یک Point از کد زیر استفاده می کنیم:

var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
  var currentLocation = geometryFactory.CreatePoint(new NetTopologySuite.Geometries.Coordinate(5,3));

 

2.    برای ایجاد یک LineString از کد زیر استفاده می کنیم:

 

          var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid:   4326);
            Coordinate[] LineStringArray = new Coordinate[3];
            LineStringArray[0] = new Coordinate(51.242079734802246, 35.63340706937167);
            LineStringArray[1] = new Coordinate(51.23916149139404, 35.63082591309715);
            LineStringArray[2] = new Coordinate(51.23504161834717, 35.633720988098574);
            var LineString = geometryFactory.CreateLineString(LineStringArray);

 


3.    برای ایجاد Poygon از کد زیر استفاده می کنیم:

var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid:   4326);

Coordinate[] polygonArray = new Coordinate[5];
            polygonArray[0] = new Coordinate(51.394686698913574, 35.718608138232895);
            polygonArray[1] = new Coordinate(51.392154693603516, 35.71808549588366);
           polygonArray[2] = new Coordinate(51.39271259307861, 35.715507076789464);
            polygonArray[3] = new Coordinate(51.395244598388665, 35.71655239188316);
           polygonArray[4] = new Coordinate(51.394686698913574, 35.718608138232895);
var polygone = geometryFactory.CreatePolygon(polygonArray);

 

 

کد زیر افزودن یک فروشگاه به همراه موقعیت مکانی آن به مدل Store را انجام می دهد.

             var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
            var currentLocation = geometryFactory.CreatePoint(new NetTopologySuite.Geometries.Coordinate(51.258741, 36.254155));

            Store newStore = new Store()
            {
                Name = "فروشگاه شماره یک",
                Address = "تهران - میدان تیموری - خیابان قاسمی - پلاک 7",
                PhoneNumber="09128698172",
                Location = currentLocation,
            };
            _context.Stores.Add(newStore);
            _context.SaveChanges();

 

  •    کوئری گرفتن از داده های مکانی

پس از نصب NetTopologySuite دستورات LINQ این کتابخانه برای استفاده دردسترس ما قرار دارند. این دستورات استفاده از داده های مکانی را برای ما بسیار راحت کرده و بسیاری از کوئری های پیچیده را می توانیم با این دستورات به سادگی اجرا کنیم.
برای مثال اگر ما بخواهیم نزدیکترین فروشگاه به یک موقعیت مکانی را بدست بیاریم از متُد Distance استفاده می کنیم.

  var neareStore = db.Stores .OrderBy(c => c.Location.Distance(currentLocation))FirstOrDefault();

 

  •    داده های مکانی در SQLServer

اگراز پایگاه داده SQLServer استفاده می کنید باید به این مورد توجه داشته باشید. به صورت پیش فرض در SQLServer نوع داده ای، داده های مکانی geography در نظر گرفته می شود.
برای تغییر نوع داده ای به  geometry باید یکی از روش های زیر را اعمال کنید.


1.    روش استفاده از Data Annotation

        [Column(TypeName = "geometry")]
        public Point  Location { get; set; }


2.    روش استفاده از Fluent API
      

           protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            modelBuilder.Entity<Store>(p =>
            {
                p.Property(store => store.Location).HasColumnType("geometry");

                {

                }
            });
        }

   

  •    امکانات NetTopologySuite

در جدول زیر متُدها و خصوصیات کتابخانه NetTopologySuite را مشاهده می کنیم و مشخص می کنیم که در کدام Provider های مربوط به EFCore پشتیبانی می شود.

 

NpgsqlSQLiteSQL Server (geography)SQL Server (geometry)متد
Geometry.Area
Geometry.AsBinary
Geometry.AsText
 Geometry.Boundary

Geometry.Buffer(double)
  Geometry.Buffer(double, int)
 Geometry.Centroid

Geometry.Contains(Geometry)
Geometry.ConvexHull()
  Geometry.CoveredBy(Geometry)
   Geometry.Covers(Geometry)
 Geometry.Crosses(Geometry)
Geometry.Difference(Geometry)
Geometry.Dimension
Geometry.Disjoint(Geometry)
Geometry.Distance(Geometry)
 Geometry.Envelope
   Geometry.EqualsExact(Geometry)
Geometry.EqualsTopologically(Geometry)
Geometry.GeometryType
 Geometry.GetGeometryN(int)
 Geometry.InteriorPoint
Geometry.Intersection(Geometry)
Geometry.Intersects(Geometry)
Geometry.IsEmpty
 Geometry.IsSimple
 Geometry.IsValid
Geometry.IsWithinDistance(Geometry, double)
 Geometry.Length
Geometry.NumGeometries
Geometry.NumPoints
Geometry.OgcGeometryType
Geometry.Overlaps(Geometry)
 Geometry.PointOnSurface
 Geometry.Relate(Geometry, string)
  Geometry.Reverse()
Geometry.SRID
Geometry.SymmetricDifference(Geometry)
Geometry.ToBinary()
Geometry.ToText()
 Geometry.Touches(Geometry)
  Geometry.Union()
Geometry.Union(Geometry)
Geometry.Within(Geometry)
GeometryCollection.Count
GeometryCollection[int]
LineString.Count
LineString.EndPoint
LineString.GetPointN(int)
 LineString.IsClosed
LineString.IsRing
LineString.StartPoint
MultiLineString.IsClosed
Point.M
Point.X
Point.Y
Point.Z
Polygon.ExteriorRing
Polygon.GetInteriorRingN(int)

 

تگ‌ها
اشتراک
0 نظرات

برای ارسال نظر باید وارد حساب کاربری خود شوید
ورود به حساب کاربری ثبت نام