private static DbGeography GetRandomPointInZone(DbGeography validZone, Random rnd) { DbGeography pos = null; double minlat = double.MaxValue; double maxlat = double.MinValue; double minlon = double.MaxValue; double maxlon = double.MinValue; for (int i = 1; i <= validZone.PointCount; i++) { var point = validZone.PointAt(i); if (point.Latitude != null && minlat > point.Latitude) minlat = (double)point.Latitude; if (point.Longitude != null && minlon > point.Longitude) minlon = (double)point.Longitude; if (point.Latitude != null && maxlat < point.Latitude) maxlat = (double)point.Latitude; if (point.Longitude != null && maxlon < point.Longitude) maxlon = (double)point.Longitude; } int retry = 0; while (pos == null || !pos.Intersects(validZone)) //Aquí comprobamos que la posición aleatoria está dentro de la zona. { var latitude = GetRandomDouble(rnd, minlat, maxlat); var longitude = GetRandomDouble(rnd, minlon, maxlon); var wkt = String.Format("POINT({0} {1})", longitude.ToString(CultureInfo.InvariantCulture), latitude.ToString(CultureInfo.InvariantCulture)); pos = DbGeography.PointFromText(wkt, 4326); retry++; if (retry > 1000) throw new Exception("Parece un bucle infinito, tras 1000 reintentos no se ha podido obtener una posición dentro de la zona válida"); } return pos; }
/// <summary> /// Returns a queryable of matching devices for the given lat/long coordinate /// The given coordinates must intersect one of the stored GeoFence values to be a match. /// Use the deviceTypeValueId to constrain matching to only certain device types. /// NOTE: If more than one device is found, the caller will have to pick which one they want /// since there doesn't seem to be a way to determine which geofence to choose /// if the geofences are overlapping at the specific latitude/longitude /// </summary> /// <param name="latitude">Latitude of the mobile phone/kiosk.</param> /// <param name="longitude">Longitude of the mobile phone/kiosk.</param> /// <param name="deviceTypeValueId">Longitude of the mobile phone/kiosk.</param> /// <returns>a single matching Device kiosk or null if nothing was matched</returns> public IQueryable <Device> GetDevicesByGeocode(double latitude, double longitude, int deviceTypeValueId) { DbGeography geoLocation = Location.GetGeoPoint(latitude, longitude); var deviceQueryable = Queryable() .Where(d => d.DeviceTypeValueId == deviceTypeValueId && d.Location != null && geoLocation.Intersects(d.Location.GeoFence) ); return(deviceQueryable); }
/// <summary> /// Finds the matching device for the given lat/long coordinates. The given coordinates /// must intersect one of the stored GeoFence values to be a match. Use the deviceTypeValueId /// to constrain matching to only certain device types. /// </summary> /// <param name="latitude">Latitude of the mobile phone/kiosk.</param> /// <param name="longitude">Longitude of the mobile phone/kiosk.</param> /// <param name="deviceTypeValueId">Longitude of the mobile phone/kiosk.</param> /// <returns>a single matching Device kiosk or null if nothing was matched</returns> public Device GetByGeocode(double latitude, double longitude, int deviceTypeValueId) { Device device = null; DbGeography aLocation = DbGeography.FromText(string.Format("POINT({0} {1})", longitude, latitude)); device = Queryable() .Where(d => d.DeviceTypeValueId == deviceTypeValueId && d.Location != null && aLocation.Intersects(d.Location.GeoFence)) .FirstOrDefault(); return(device); }
public static bool IsOverlap(this DbGeography polygon1, DbGeography polygon2) { SqlGeography sqlPolygon1 = SqlGeography.STGeomFromWKB(new System.Data.SqlTypes.SqlBytes(polygon1.AsBinary()), DbGeography.DefaultCoordinateSystemId).MakeValid(); sqlPolygon1 = sqlPolygon1.ReorientObject(); polygon1 = DbGeography.FromBinary(sqlPolygon1.STAsBinary().Value); SqlGeography sqlPolygon2 = SqlGeography.STGeomFromWKB(new System.Data.SqlTypes.SqlBytes(polygon2.AsBinary()), DbGeography.DefaultCoordinateSystemId).MakeValid(); sqlPolygon2 = sqlPolygon2.ReorientObject(); polygon2 = DbGeography.FromBinary(sqlPolygon2.STAsBinary().Value); return(polygon1.Intersects(polygon2)); }
public static bool IsInside(this DbGeography point, DbGeography polygon) { //DbGeography point = DbGeography.FromText(string.Format("POINT({1} {0})", latitude.ToString().Replace(',', '.'), longitude.ToString().Replace(',', '.')), DbGeography.DefaultCoordinateSystemId); // If the polygon area is larger than an earth hemisphere (510 Trillion m2 / 2), we know it needs to be fixed /*if (polygon.Area.HasValue && polygon.Area.Value > 255000000000000L) * { * * }*/ SqlGeography sqlPolygon = SqlGeography.STGeomFromWKB(new System.Data.SqlTypes.SqlBytes(polygon.AsBinary()), DbGeography.DefaultCoordinateSystemId).MakeValid(); sqlPolygon = sqlPolygon.ReorientObject(); polygon = DbGeography.FromBinary(sqlPolygon.STAsBinary().Value); return(point.Intersects(polygon)); }
private static bool IsInside(DbGeography polygon, DbGeography point) { SqlServerTypes.Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory); var wellKnownText = polygon.AsText(); var sqlGeography = SqlGeography.STGeomFromText(new SqlChars(wellKnownText), DbGeography.DefaultCoordinateSystemId) .MakeValid(); var invertedSqlGeography = sqlGeography.ReorientObject(); if (sqlGeography.STArea() > invertedSqlGeography.STArea()) { sqlGeography = invertedSqlGeography; } polygon = DbSpatialServices.Default.GeographyFromProviderValue(sqlGeography); return(point.Intersects(polygon)); }
public bool IsInTheUnitedStates(DbGeography dbGeography) { return(dbGeography.Intersects(_unitedStates.features[0].geometry.coordinates)); }