У меня есть таблица с ID
, LATITUDE
, LONGITUDE
, COUNTRY_CD
и я пытаюсь группы (кластеры) ID
вместе в пределах 40 метров и присвоить имя/номер в эту группу. Ex. есть 7 ID снизу, записи находятся на расстоянии до 40 метров и вам нужно назначить имя/номер.Как группировать близлежащую широту и долготу и назначать имя/номер этой группе в SQL Server?
Мой стол имеет 100 K записей широты, долготы по всему миру и будет более 100 кластеров из страны, и я не знаю, сколько кластеров будет в каждой стране.
Я прекрасно разбираюсь в цепях близлежащих точек. Ex, ID1 и ID3 оба «близки» к ID6 (но не друг другу).
create table #temp
(
ID varchar(10),
LATITUDE [decimal](11, 8),
LONGITUDE [decimal](11, 8),
COUNTRY_CD [char](2)
)
insert into #temp select 'ID1', 10.81583689, 78.61898689, 'IN'
insert into #temp select 'ID2', 10.81513789, 78.61898789, 'IN'
insert into #temp select 'ID3', 10.81514889, 78.61894889, 'IN'
insert into #temp select 'ID4', 10.81523989, 78.61898989, 'IN'
insert into #temp select 'ID5', 10.81521089, 78.61891089, 'IN'
insert into #temp select 'ID6', 10.81551189, 78.61891189, 'IN'
insert into #temp select 'ID7', 10.81551189, 78.61791189, 'IN'
insert into #temp select 'ID8', 10.81561189, 78.61792189, 'IN'
insert into #temp select 'ID9', 10.81571189, 78.61793189, 'IN'
select
t1.ID, t2.ID,
t1.LATITUDE,
t1.LONGITUDE,
t1.COUNTRY_CD,
--calculate the distance in meters
cast(6378137.0 * sqrt(power((radians(t1.LATITUDE) - radians(t2.LATITUDE)), 2)
+ power((radians(t1.LONGITUDE) - radians(t2.LONGITUDE)) * cos(radians(t1.LATITUDE)), 2)) as integer) as MAPPING_DISTANCE,
(row_number() over (partition by t1.ID order by
--rank the distance in meters
cast(6378137.0*sqrt(power((radians(t1.LATITUDE)-radians(t2.LATITUDE)),2)
+ power((radians(t1.LONGITUDE)-radians(t2.LONGITUDE))*cos(radians(t1.LATITUDE)),2)) as integer) asc
)) as DISTANCE_RANK
from
(select
ID, LATITUDE, LONGITUDE, COUNTRY_CD
from
#temp) t1
--join the above list of ID to get near by ID
inner join
(select
ID, LATITUDE, LONGITUDE, COUNTRY_CD
from
#temp) t2 on t1.COUNTRY_CD = t2.COUNTRY_CD
--this brings ID available in 75 meters radius
and (t2.LATITUDE between (t1.LATITUDE - 0.00056) and (t1.LATITUDE + 0.00056))
and (t2.LONGITUDE between (t1.LONGITUDE - 0.00076) and (t1.LONGITUDE + 0.00076))
--distance between t1 co-ordinates and t2 co-ordinates in meters
and (cast(6378137.0*sqrt(power((radians(t1.LATITUDE)-radians(t2.LATITUDE)),2) + power((radians(t1.LONGITUDE)-radians(t2.LONGITUDE))*cos(radians(t1.LATITUDE)),2)) as integer)) <= 40 --limit to 40 meters
and t1.ID != t2.ID --exclude the same ID
выше запрос приносит идентификатор, которые находятся в пределах 40 метров, но я не знаю, как фильтровать ID те находятся в кластере ?. Ex, 'Cluster_1'?
см этого изображения 2 clusters from above 9 ID
Обратите внимание, что я не буду давать какой-либо конкретную координату в качестве входных данных, но запрос должен автоматически выбрать идентификатор в пределах расстояния от доступных координат в таблице.
Мой ожидаемый результат, как показано ниже,
ID LATITUDE LONGITUDE COUNTRY_CD CLUSTER_NAME
ID1 10.81583689 78.61898689 IN Cluster_1
ID2 10.81513789 78.61898789 IN Cluster_1
ID3 10.81514889 78.61894889 IN Cluster_1
ID4 10.81523989 78.61898989 IN Cluster_1
ID5 10.81521089 78.61891089 IN Cluster_1
ID6 10.81551189 78.61891189 IN Cluster_1
ID7 10.81551189 78.61791189 IN Cluster_2
ID8 10.81561189 78.61792189 IN Cluster_2
ID9 10.81571189 78.61793189 IN Cluster_2
Любые предложения, как идентификатор фильтра, которые находятся в кластере? Если будет любой другой простой способ сделать это, было бы здорово!
Есть причина, почему вы хранение координат по отдельности и вручную реализация вычисления расстояния, а не с помощью 'geography' типа данных? –
Hi @Damien_The_Unbelieve Моя таблица и логика реализованы через 2 года, а координаты для ID могут немного измениться во время повседневного обновления, поскольку координаты извлекаются из другой системы. Итак, я должен рассчитать расстояние каждый день и сопоставить ID. Если это возможно в типе данных географии, я также могу переключиться. Но как захватить идентификаторы в кластере? – Rajini
«Я в порядке, когда собираю цепи соседних точек» - так что если ваши очки были кольцом точек на расстоянии 39 м друг от друга вдоль экватора, вы были бы счастливы иметь всего один кластер для всего мира? – AakashM