ASP.NET Core MVC и EF Core и .NET 8: поиск близлежащих местоположенийC#

Место общения программистов C#
Ответить
Anonymous
 ASP.NET Core MVC и EF Core и .NET 8: поиск близлежащих местоположений

Сообщение Anonymous »

Я использую ASP.NET Core 8 MVC и EF Core 8.
Моя модель записи EF выглядит следующим образом:

Код: Выделить всё

public class Record
{
[Key]
public int Id { get; set; }

public NetTopologySuite.Geometries.Point Location { get; set; }

// other properties...
}
В SQL Server Express этот столбец имеет тип данных «география»..
В моем контроллере я создаю/сохраняю свои координаты из Google Maps ( google.com/maps) вот так:

Код: Выделить всё

if (vm.Latitude.HasValue && vm.Longitude.HasValue)
{
var geometryFactory = NetTopologySuite.NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
newRecord.Location = geometryFactory.CreatePoint(new NetTopologySuite.Geometries.Coordinate(vm.Longitude.Value, vm.Latitude.Value));
}
Местоположение, которое я использую для поиска близлежащих объектов:

Код: Выделить всё

search nearby(lon: 4.9317 and lat: 51.308) distance 500
Код:

Код: Выделить всё

var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
var currentLocation = geometryFactory.CreatePoint(new NetTopologySuite.Geometries.Coordinate(lon, lat)); // {POINT (4.9317 51.308)}

double maxDistance = 500000d;

var baseQuery = _Context.Records
.Include(x => x.City)
.ThenInclude(c => c.Region)
.Where(r => r.Location != null
&& r.Location.Distance(currentLocation) < maxDistance)
.OrderBy(r => r.Location.Distance(currentLocation));

var str = baseQuery.Take(10).AsNoTracking().ToQueryString();
var results = await baseQuery.Take(10)
.AsNoTracking().ToListAsync(); // --> results: 0.
Выполняется запрос, который не возвращает результатов:

Код: Выделить всё

DECLARE @__p_2 int = 10;
DECLARE @__currentLocation_0 geography = 0xE6100000010C8195438B6CA7494099BB96900FBA1340;
DECLARE @__maxDistance_1 float = 500000.0E0;

SELECT [t].[Id], [t].[CityId], [t].[Info], [t].[InfoPlainText], [t].[Location], [t].[PeriodEnd], [t].[PeriodStart], [t].[Title], [t].[UniqueId], [c].[Id], [c].[GeonamesId], [c].[Name], [c].[ParentId], [c].[RegionId], [c].[WikidataItemId], [r0].[Id], [r0].[CountryId], [r0].[Name]
FROM (
SELECT TOP(@__p_2) [r].[Id], [r].[CityId], [r].[Info], [r].[InfoPlainText], [r].[Location], [r].[PeriodEnd], [r].[PeriodStart], [r].[Title], [r].[UniqueId], [r].[Location].STDistance(@__currentLocation_0) AS [c]
FROM [Record] AS [r]
WHERE [r].[Location] IS NOT NULL AND [r].[Location].STDistance(@__currentLocation_0) < @__maxDistance_1
ORDER BY [r].[Location].STDistance(@__currentLocation_0)
) AS [t]
LEFT JOIN [City] AS [c] ON [t].[CityId] = [c].[Id]
LEFT JOIN [Region] AS [r0] ON [c].[RegionId] = [r0].[Id]
ORDER BY [t].[c]
Когда я изменяю свой запрос, чтобы убрать ограничениеwhere:

Код: Выделить всё

        var baseQuery = _Context.Records.Include(x => x.City).ThenInclude(c => c.Region)
.Where(r => r.Location != null)
.OrderBy(r => r.Location.Distance(currentLocation));

var str = baseQuery.Take(10).AsNoTracking().ToQueryString();
var results = await baseQuery.Take(10).AsNoTracking().ToListAsync();
Сгенерированный запрос:

Код: Выделить всё

DECLARE @__p_1 int = 10;
DECLARE @__currentLocation_0 geography = 0xE6100000010C8195438B6CA7494099BB96900FBA1340;

DECLARE @__p_1 int = 10;
DECLARE @__currentLocation_0 geography = 0xE6100000010C8195438B6CA7494099BB96900FBA1340;

SELECT [t].[Id], [t].[CityId], [t].[Info], [t].[InfoPlainText], [t].[Location], [t].[PeriodEnd], [t].[PeriodStart], [t].[Title], [t].[UniqueId], [c].[Id], [c].[GeonamesId], [c].[Name], [c].[ParentId], [c].[RegionId], [c].[WikidataItemId], [r0].[Id], [r0].[CountryId], [r0].[Name]
FROM (
SELECT TOP(@__p_1) [r].[Id], [r].[CityId], [r].[Info], [r].[InfoPlainText], [r].[Location], [r].[PeriodEnd], [r].[PeriodStart], [r].[Title], [r].[UniqueId], [r].[Location].STDistance(@__currentLocation_0) AS [c]
FROM [Record] AS [r]
WHERE [r].[Location] IS NOT NULL
ORDER BY [r].[Location].STDistance(@__currentLocation_0)
) AS [t]
LEFT JOIN [City] AS [c] ON [t].[CityId] = [c].[Id]
LEFT JOIN [Region] AS [r0] ON [c].[RegionId] = [r0].[Id]
ORDER BY [t].[c]
мои 10 результатов сейчас:

Код: Выделить всё

1. "POINT (50.283291 5.914316)"
2. "POINT (50.283241 5.914246)"
3. "POINT (50.8844 4.72612)"
4. "POINT (51.251796 4.498143)"
5. "POINT (51.20726318532986 4.430896961356696)"
6.  "POINT (50.92025 3.97411)"
7. "POINT (50.83778860805526 3.5672699996515727)"
8. "POINT (50.990267 3.440428)"
9. "POINT (51.083765 3.449011)"
10. "POINT (51.083647 3.44874)"
Но здесь моя первая точка действительно намного дальше моей позиции: долгота: 4,9317 и широта: 51,308
А также currentLocation< /code> похоже, поменял местами x и y:

Код: Выделить всё

{POINT (4.9317 51.308)}
Код:

Код: Выделить всё

var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
var currentLocation = geometryFactory.CreatePoint(new NetTopologySuite.Geometries.Coordinate(lon, lat)); // {POINT (4.9317 51.308)}
Я думал, что в этой координате используется x = lon, y = lat.
Но при переключении долготы и широты для моего текущего местоположения я получаю правильный результат по моему запросу.
Что мне не хватает? Должно быть что-то ясное, и как я могу определить, когда переключать долготу/широту?
В настоящее время я не понимаю, почему и когда мне нужно переключать lon и < em>широта моего текущего положения, чтобы поиск работал правильно?

Подробнее здесь: https://stackoverflow.com/questions/791 ... -locations
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»