5

निम्न डेटा को देखते हुए, यह संभव होगा, और यदि ऐसा है कि यह निर्धारित करने का सबसे प्रभावी तरीका होगा कि पहली तालिका में 'शर्डिंगटन' स्थान शामिल है या नहीं दूसरी तालिका में किसी भी स्थान के त्रिज्या दिया गया है।भौगोलिक त्रिज्या के भीतर एक बिंदु है - SQL Server 2008

geodata स्तंभ इतना एसक्यूएल सर्वर स्थानिक सुविधाओं के लिए एक विकल्प का उपयोग कर रहे है और साथ ही अक्षांश और देशांतर का उपयोग कर, 'भूगोल' प्रकार का है।

Location  GeoData  Latitude Longitude 
=========================================================== 
Shurdington XXXXXXXXXX 51.8677979 -2.113189 

ID Location   GeoData  Latitude Longitude Radius 
============================================================================== 
1000 Gloucester  XXXXXXXXXX 51.8907127 -2.274598 10 
1001 Leafield  XXXXXXXXXX 51.8360519 -1.537438 10 
1002 Wotherton  XXXXXXXXXX 52.5975151 -3.061798 5 
1004 Nether Langwith XXXXXXXXXX 53.2275276 -1.212108 20 
1005 Bromley   XXXXXXXXXX 51.4152069 0.0292294 10 

किसी भी सहायता की बहुत सराहना की जाती है।

उत्तर

8

डाटा बनाएं

CREATE TABLE #Data (
    Id int, 
    Location nvarchar(50), 
    Latitude decimal(10,5), 
    Longitude decimal(10,5), 
    Radius int 
) 

INSERT #Data (Id,Location,Latitude,Longitude,Radius) VALUES 
(1000,'Gloucester', 51.8907127 ,-2.274598 , 20), -- Increased to 20 
(1001,'Leafield', 51.8360519 , -1.537438 , 10), 
(1002,'Wotherton', 52.5975151, -3.061798 , 5), 
(1004,'Nether Langwith', 53.2275276 , -1.212108 , 20), 
(1005,'Bromley', 51.4152069 , 0.0292294 , 10) 

टेस्ट

एक POINT

DECLARE @p GEOGRAPHY = GEOGRAPHY::STGeomFromText('POINT(-2.113189 51.8677979)', 4326); 

के रूप में अपनी रुचि के स्थल घोषित पता लगाने के लिए अगर यह एक और बिंदु के दायरे में है:

-- First create a Point. 
DECLARE @point GEOGRAPHY = GEOGRAPHY::STGeomFromText('POINT(-2.27460 51.89071)', 4326); 
-- Buffer the point (meters) and check if the 1st point intersects 
SELECT @point.STBuffer(50000).STIntersects(@p) 

किसी एक क्वेरी में यह सब का मेल:

select *, 
     GEOGRAPHY::STGeomFromText('POINT('+ 
      convert(nvarchar(20), Longitude)+' '+ 
      convert(nvarchar(20), Latitude)+')', 4326) 
     .STBuffer(Radius * 1000).STIntersects(@p) as [Intersects] 
from #Data 

देता है:

Id   Location Latitude Longitude Radius Intersects 
1000 Gloucester 51.89071 -2.27460 20 1 
1001 Leafield 51.83605 -1.53744 10 0 
1002 Wotherton 52.59752 -3.06180 5 0 
1004 Nether Langwith 53.22753 -1.21211 20 0 
1005 Bromley   51.41521 0.02923   10 0 

पुन: क्षमता। कुछ सही अनुक्रमण के साथ यह प्रतीत होता है एसक्यूएल के स्थानिक अनुक्रमित बहुत जल्दी

+0

इस उदाहरण को प्यार करें, हालांकि आश्चर्यजनक रूप से दूरी काफी हद तक बाहर प्रतीत होती है - शायद यह SQL सर्वर की स्थानिक विशेषताओं के बारे में ज्ञान की कमी के साथ है, लेकिन फिर भी, मुझे लगता है कि एक जोड़कर कॉलम '.STDistance (@p)/1609.34' यह मील की दूरी को वापस कर देगा, ऐसा लगता है कि यह बंद हो रहा है - या वह मुझे है? – Nathan

+0

'STGeomFromText' से 'POINT' बनाते समय इसे समझ लिया गया है, यह आवश्यक है कि लेट/लम्बाई दूसरे तरीके से इनपुट किया जाए, उदा। देशांतर/अक्षांश। – Nathan

+0

@Nathan आप सही हैं, मैं – Paddy

1

आप दो अंक के बीच दूरी की गणना और दिए गए त्रिज्या को यह दूरी की तुलना हो सकती है।

छोटी दूरी की गणना के लिए, आप फॉर्मूला का उपयोग Wikipedia - Geographical distance - Spherical Earth projected to a plane पर कर सकते हैं, जो "बहुत तेज़ और छोटे दूरी के लिए काफी सटीक परिणाम" का दावा करता है।

सूत्र के अनुसार, आप अक्षांश और देशांतर में अंतर और मतलब अक्षांश

with geo as (select g1.id, g1.latitude as lat1, g1.longitude as long1, g1.radius, 
        g2.latitude as lat2, g2.longitude as long2 
      from geography g1 
      join geography g2 on g2.location = 'shurdington' 
           and g1.location <> 'shurdington') 
    base as (select id, 
        (radians(lat1) - radians(lat2)) as dlat, 
        (radians(long1) - radians(long2)) as dlong, 
        (radians(lat1) + radians(lat2))/2 as mlat, radius 
       from geo) 
    dist as (select id, 
        6371.009 * sqrt(square(dlat) + square(cos(mlat) * dlong)) as distance, 
        radius 
       from base) 
select id, distance 
from dist 
where distance <= radius 

मैं मध्यवर्ती कदम के रूप में with select रों इस्तेमाल किया गणना "पठनीय" रखने की जरूरत है।

+0

तदनुसार अपना उत्तर अपडेट करूंगा, यह देखते हुए कि "एसक्यूएल सर्वर स्थानिक सुविधाओं का उपयोग एक विकल्प है"? – AakashM

+0

@AakashM क्योंकि यह एक दिलचस्प अभ्यास था। –

1

यदि आप स्वयं गणित करना चाहते हैं, तो आप पाइथागोरस के आधार पर समकक्ष अनुमानित अनुमान का उपयोग कर सकते हैं। सूत्र है:

वर एक्स = (lon2-lon1) * गणित.क्योंकि ((lat1 + lat2)/2); var y = (lat2-lat1); var डी = Math.sqrt (x * x + y * y) * आर;

SELECT * 
FROM Table2 t2 
WHERE EXISTS (
SELECT 1 FROM Table1 t1 
WHERE 
    ABS (
    SQRT (
    (SQUARE((RADIANS(t2.longitude) - RADIANS(t1.longitude)) * COS((RADIANS(t2.Latitude) + RADIANS(t1.Latitude))/2))) + 
    (SQUARE(RADIANS(t1.Latitude) - RADIANS(t2.Latitude))) 
    ) * 6371 --Earth radius in km, use 3959 for miles 
    ) 
    <= t2.Radius 
) 

ध्यान दें कि यह उपलब्ध नहीं सबसे सटीक तरीका है लेकिन संभावना अच्छी है:

एसक्यूएल के संदर्भ में, यह आपके 2 तालिका में उन स्थानों है कि उनके दायरे के भीतर 1 में अपने प्रवेश को शामिल देना चाहिए पर्याप्त। यदि आप दुनिया भर में फैले दूरी को देख रहे हैं तो आप Google 'हावर्सिन' फॉर्मूला की इच्छा कर सकते हैं।

यह धान के समाधान के साथ तुलना करने के लायक हो सकता है यह देखने के लिए कि वे कितनी अच्छी तरह से सहमत हैं और कौन सा सर्वश्रेष्ठ प्रदर्शन करता है।

संबंधित मुद्दे