Saya mencoba untuk menghitung jarak antara dua posisi pada peta. Saya telah disimpan di data saya: Bujur, Lintang, X POS, Y POS.
Saya sebelumnya telah menggunakan berikut cuplikan.
DECLARE @orig_lat DECIMAL
DECLARE @orig_lng DECIMAL
SET @orig_lat=53.381538 set @orig_lng=-1.463526
SELECT *,
3956 * 2 * ASIN(
SQRT( POWER(SIN((@orig_lat - abs(dest.Latitude)) * pi()/180 / 2), 2)
+ COS(@orig_lng * pi()/180 ) * COS(abs(dest.Latitude) * pi()/180)
* POWER(SIN((@orig_lng - dest.Longitude) * pi()/180 / 2), 2) ))
AS distance
--INTO #includeDistances
FROM #orig dest
Saya don't namun kepercayaan data yang keluar dari ini, tampaknya akan memberikan sedikit hasil yang tidak akurat.
Beberapa contoh data dalam kasus anda membutuhkannya
Latitude Longitude Distance
53.429108 -2.500953 85.2981833133896
Bisa ada yang membantu saya keluar dengan kode saya, saya don't pikiran jika anda ingin memperbaiki apa yang sudah saya miliki jika anda memiliki cara baru untuk mencapai ini yang akan menjadi besar.
Sebutkan apa yang unit pengukuran hasil anda di.
Karena anda're menggunakan SQL Server 2008, anda memiliki geografi
jenis data yang tersedia, yang dirancang untuk persis seperti ini data:
DECLARE @source geography = 'POINT(0 51.5)'
DECLARE @target geography = 'POINT(-3 56)'
SELECT @source.STDistance(@target)
Memberikan
----------------------
538404.100197555
(1 row(s) affected)
Memberitahu kami itu adalah tentang 538 km dari (dekat) London (dekat) Edinburgh.
Tentu akan ada jumlah belajar untuk melakukan yang pertama, tetapi sekali anda tahu itu's jauh lebih mudah daripada melaksanakan sendiri Haversine perhitungan; plus anda mendapatkan BANYAK fungsi.
Jika anda ingin mempertahankan yang sudah ada struktur data, anda masih dapat menggunakan STDistance
, dengan membangun cocok geografi
contoh menggunakan Titik
metode:
DECLARE @orig_lat DECIMAL(12, 9)
DECLARE @orig_lng DECIMAL(12, 9)
SET @orig_lat=53.381538 set @orig_lng=-1.463526
DECLARE @orig geography = geography::Point(@orig_lat, @orig_lng, 4326);
SELECT *,
@orig.STDistance(geography::Point(dest.Latitude, dest.Longitude, 4326))
AS distance
--INTO #includeDistances
FROM #orig dest
Fungsi di bawah ini memberikan jarak antara dua geocoordinates di m
create function [dbo].[fnCalcDistanceMiles] (@Lat1 decimal(8,4), @Long1 decimal(8,4), @Lat2 decimal(8,4), @Long2 decimal(8,4))
returns decimal (8,4) as
begin
declare @d decimal(28,10)
-- Convert to radians
set @Lat1 = @Lat1 / 57.2958
set @Long1 = @Long1 / 57.2958
set @Lat2 = @Lat2 / 57.2958
set @Long2 = @Long2 / 57.2958
-- Calc distance
set @d = (Sin(@Lat1) * Sin(@Lat2)) + (Cos(@Lat1) * Cos(@Lat2) * Cos(@Long2 - @Long1))
-- Convert to miles
if @d <> 0
begin
set @d = 3958.75 * Atan(Sqrt(1 - power(@d, 2)) / @d);
end
return @d
end
Fungsi di bawah ini memberikan jarak antara dua geocoordinates di kilometer
CREATE FUNCTION dbo.fnCalcDistanceKM(@lat1 FLOAT, @lat2 FLOAT, @lon1 FLOAT, @lon2 FLOAT)
RETURNS FLOAT
AS
BEGIN
RETURN ACOS(SIN(PI()*@lat1/180.0)*SIN(PI()*@lat2/180.0)+COS(PI()*@lat1/180.0)*COS(PI()*@lat2/180.0)*COS(PI()*@lon2/180.0-PI()*@lon1/180.0))*6371
END
Fungsi di bawah ini memberikan jarak antara dua geocoordinates di kilometer menggunakan Geografi tipe data yang diperkenalkan pada sql server 2008
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326);
SET @h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);
SELECT @g.STDistance(@h);
Penggunaan:
select [dbo].[fnCalcDistanceKM](13.077085,80.262675,13.065701,80.258916)
Sepertinya Microsoft menginvasi otak dari semua responden lain dan membuat mereka menulis sebagai solusi yang rumit mungkin. Berikut adalah cara paling sederhana tanpa ada tambahan fungsi-fungsi/menyatakan pernyataan:
PILIH: geografi:Titik(LATITUDE_1, LONGITUDE_1, 4326).STDistance(geografi::Titik(LATITUDE_2, LONGITUDE_2, 4326))
Cukup mengganti data anda bukan LATITUDE_1
, LONGITUDE_1
, LATITUDE_2
, LONGITUDE_2
misalnya:
SELECT geography::Point(53.429108, -2.500953, 4326).STDistance(geography::Point(c.Latitude, c.Longitude, 4326))
from coordinates c
Seperti yang anda're menggunakan SQL 2008 atau yang lebih baru, aku'd sarankan memeriksa GEOGRAFI tipe data. SQL memiliki built-in dukungan untuk geospasial pertanyaan.
misalnya anda'd memiliki kolom dalam tabel jenis GEOGRAFI yang akan diisi dengan geospasial representasi koordinat (check out MSDN referensi terkait di atas untuk contoh). Datatype ini kemudian memaparkan metode yang memungkinkan anda untuk melakukan seluruh host geospasial pertanyaan (misalnya mencari jarak antara 2 poin)
Create Function [dbo].[DistanceKM]
(
@Lat1 Float(18),
@Lat2 Float(18),
@Long1 Float(18),
@Long2 Float(18)
)
Returns Float(18)
AS
Begin
Declare @R Float(8);
Declare @dLat Float(18);
Declare @dLon Float(18);
Declare @a Float(18);
Declare @c Float(18);
Declare @d Float(18);
Set @R = 6367.45
--Miles 3956.55
--Kilometers 6367.45
--Feet 20890584
--Meters 6367450
Set @dLat = Radians(@lat2 - @lat1);
Set @dLon = Radians(@long2 - @long1);
Set @a = Sin(@dLat / 2)
* Sin(@dLat / 2)
+ Cos(Radians(@lat1))
* Cos(Radians(@lat2))
* Sin(@dLon / 2)
* Sin(@dLon / 2);
Set @c = 2 * Asin(Min(Sqrt(@a)));
Set @d = @R * @c;
Return @d;
End
GO
Penggunaan:
pilih dbo.DistanceKM(37.848832506474, 37.848732506474, 27.83935546875, 27.83905546875)
Output:
0,02849639
Anda dapat mengubah @R parameter dengan berkomentar mengapung.
Selain jawaban-jawaban berikut adalah cara untuk menghitung jarak dalam MEMILIH:
CREATE FUNCTION Get_Distance
(
@La1 float , @Lo1 float , @La2 float, @Lo2 float
)
RETURNS TABLE
AS
RETURN
-- Distance in Meters
SELECT GEOGRAPHY::Point(@La1, @Lo1, 4326).STDistance(GEOGRAPHY::Point(@La2, @Lo2, 4326))
AS Distance
GO
Penggunaan:
select Distance
from Place P1,
Place P2,
outer apply dbo.Get_Distance(P1.latitude, P1.longitude, P2.latitude, P2.longitude)
Skalar fungsi juga bekerja tetapi mereka sangat tidak efisien ketika komputasi data dalam jumlah besar.
Saya berharap ini bisa membantu seseorang.