پردازش دادههای جغرافیایی به کمک SQL Server و Entity framework
نویسنده: وحید نصیری
تاریخ: ۱۳۹۳/۰۳/۳۰ ۱۰:۴۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
CREATE TABLE [Geo](
[id] [int] IDENTITY(1,1) NOT NULL,
[Location] [geography] NULL
)
insert into Geo( Location , long, lat ) values
( geography::STGeomFromText ('POINT(-121.527200 45.712113)', 4326)) using System.Data.Entity.Spatial;
namespace EFGeoTests.Models
{
public class GeoLocation
{
public int Id { get; set; }
public DbGeography Location { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public override string ToString()
{
return string.Format("Name:{0}, Location:{1}", Name, Location);
}
}
} using System;
using System.Data.Entity;
using EFGeoTests.Models;
namespace EFGeoTests.Config
{
public class MyContext : DbContext
{
public DbSet<GeoLocation> GeoLocations { get; set; }
public MyContext()
: base("Connection1")
{
this.Database.Log = sql => Console.Write(sql);
}
}
} private static DbGeography createPoint(double longitude, double latitude, int coordinateSystemId = 4326)
{
var text = string.Format(CultureInfo.InvariantCulture.NumberFormat,"POINT({0} {1})", longitude, latitude);
return DbGeography.PointFromText(text, coordinateSystemId);
} GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
/// <summary>
/// Gets the current shape in the collection
/// </summary>
public Shape Current
{
get
{
if (_disposed) throw new ObjectDisposedException("Shapefile");
if (!_opened) throw new InvalidOperationException("Shapefile not open.");
// get the metadata
StringDictionary metadata = null;
if (!RawMetadataOnly)
{
metadata = new StringDictionary();
for (int i = 0; i < _dbReader.FieldCount; i++)
{
string value = _dbReader.GetValue(i).ToString();
if (_dbReader.GetDataTypeName(i) == "DBTYPE_WVARCHAR")
{
// برای نمایش متون فارسی نیاز است
value = Encoding.UTF8.GetString(Encoding.GetEncoding(720).GetBytes(value));
}
metadata.Add(_dbReader.GetName(i),
value);
}
} using System.Collections.Generic;
using System.Linq;
using Catfood.Shapefile;
namespace EFGeoTests
{
public class MapPoint
{
public Dictionary<string, string> Metadata { set; get; }
public double X { set; get; }
public double Y { set; get; }
}
public static class ShapeReader
{
public static IList<MapPoint> ReadShapeFile(string path)
{
var results = new List<MapPoint>();
using (var shapefile = new Shapefile(path))
{
foreach (var shape in shapefile)
{
if (shape.Type != ShapeType.Point)
continue;
var shapePoint = shape as ShapePoint;
if (shapePoint == null)
continue;
var metadataNames = shape.GetMetadataNames();
if(!metadataNames.Any())
continue;
var metadata = new Dictionary<string, string>();
foreach (var metadataName in metadataNames)
{
metadata.Add(metadataName,shape.GetMetadata(metadataName));
}
results.Add(new MapPoint
{
Metadata = metadata,
X = shapePoint.Point.X,
Y = shapePoint.Point.Y
});
}
}
return results;
}
}
} var points = ShapeReader.ReadShapeFile("IranShapeFiles\\places.shp");
using (var context = new MyContext())
{
context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.ProxyCreationEnabled = false;
context.Configuration.ValidateOnSaveEnabled = false;
if (context.GeoLocations.Any())
return;
foreach (var point in points)
{
context.GeoLocations.Add(new GeoLocation
{
Name = point.Metadata["name"],
Type = point.Metadata["type"],
Location = createPoint(point.X, point.Y)
});
}
context.SaveChanges();
}
var tehran = createPoint(51.4179604, 35.6884243);
using (var context = new MyContext())
{
// find any locations within 5 kilometers ordered by distance
var locations = context.GeoLocations
.Where(loc => loc.Location.Distance(tehran) < 5000)
.OrderBy(loc => loc.Location.Distance(tehran))
.ToList();
foreach (var location in locations)
{
Console.WriteLine(location.Name);
}
} var tehran = createPoint(51.4179604, 35.6884243);
using (var context = new MyContext())
{
// find any locations within 5 kilometers ordered by distance
var tehranLocation = context.GeoLocations.FirstOrDefault(loc => loc.Location.SpatialEquals(tehran));
if (tehranLocation != null)
{
Console.WriteLine(tehranLocation.Type);
}
}
Unable to load DLL 'SqlServerSpatial.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
var searchLocation = DbGeography.FromText(String.Format("POINT({0} {1})", longitude, latitude));
var nearbyLocations =
(from location in _context.GeoLocations
where // (Additional filtering criteria here...)
select new
{
LocationID = location.ID,
// ...
Distance = searchLocation.Distance(
DbGeography.FromText("POINT(" + location.Longitude + " " + location.Latitude + ")"))
})
.OrderBy(location => location.Distance)
.ToList();