SQL सर्वर में सह-निर्देशांक (देशांतर / अक्षांश, Google मानचित्र से) संग्रहीत करने का सबसे अच्छा तरीका क्या है?


103

मैं SQL Server 2008 में एक तालिका डिज़ाइन कर रहा हूं जो उपयोगकर्ताओं की सूची और Google मानचित्र को-ऑर्डिनेट (देशांतर और अक्षांश) को संग्रहीत करेगा।

क्या मुझे दो क्षेत्रों की आवश्यकता होगी, या यह 1 के साथ किया जा सकता है?

इस तरह के डेटा को संग्रहीत करने के लिए सबसे अच्छा (या सबसे सामान्य) डेटा-प्रकार क्या है?

जवाबों:


54

SQL Server 2008 में पेश किए गए नए स्थानिक डेटा-प्रकारों पर एक नज़र डालें। वे इस तरह के कार्य के लिए डिज़ाइन किए गए हैं और अनुक्रमण और क्वेरी को बहुत आसान और अधिक कुशल बनाते हैं।

अधिक जानकारी:


63

निष्पक्ष चेतावनी! GEOGRAPHY प्रकार का उपयोग करने की सलाह लेने से पहले, सुनिश्चित करें कि आप डेटा तक पहुंचने के लिए Linq या Entity फ्रेमवर्क का उपयोग करने की योजना नहीं बना रहे हैं क्योंकि यह समर्थित नहीं है (नवंबर 2010 तक) और आप दुखी होंगे!

अद्यतन जुलाई 2017

इस उत्तर को पढ़ने वालों के लिए, यह अप्रचलित है क्योंकि यह बैकडेटेड टेक्नोलॉजी स्टैक को संदर्भित करता है। अधिक जानकारी के लिए टिप्पणियाँ देखें।


1
चूँकि मूल उत्तर पोस्ट किया गया था, मुझे यह लेख jasonfollas.com/blog/archive/2010/02/02/14/… पर मिला, जो एक संभावित समाधान पर चर्चा कर रहा है।
नॉर्मन एच

56
चेतावनी अब मान्य नहीं है। ईएफ अब भूगोल प्रकारों का समर्थन करता है।
मार्सेलो मेसन

1
Nerveless EF स्थानिक प्रकारों का समर्थन करता है, यह WCF डेटा सेवाओं के लिए विभिन्न प्रकार के सेट का उपयोग करता है, इस प्रकार संगत नहीं हैं
abatishchev

1
हाइबरनेट 5 स्थानिक अभी भी उदाहरण के लिए नहीं है :(
यूजीन

1
फेयर वार्निंग अभी भी एंटिटी फ्रेमवर्क कोर 2.0 github.com/aspnet/EntityFrameworkCore/issues/1100
ono2012

29

मैं SQL सर्वर के लिए जवाब नहीं जानता लेकिन ...

में MySQL के रूप में बचाने के लिएFLOAT( 10, 6 )

यह Google डेवलपर दस्तावेज़ से आधिकारिक अनुशंसा है ।

CREATE TABLE `coords` (
  `lat` FLOAT( 10, 6 ) NOT NULL ,
  `lng` FLOAT( 10, 6 ) NOT NULL ,
) ENGINE = MYISAM ;

19
प्रश्न में स्पष्ट रूप से SQL सर्वर लिखा गया है, MySQL नहीं। और आप निश्चित रूप से सिर्फ एक अक्षांश और देशांतर के साथ एक तालिका नहीं चाहेंगे।
आराकनिद

2
सहमत -बाद जवाब। नए GEOGRAPHY स्थानिक प्रकार का उपयोग करें।
प्योर.क्रोम

2
लिंक भी स्थानांतरित हो गया है, code.google.com/apis/maps/articles/phpsqlajax.html पर
राल्फ लावेल

14
मैं सटीक मुद्दों के कारण फ्लोट का उपयोग नहीं करूंगा। दशमलव (9,6) का प्रयोग करें।
कप्पन

ऐसे वास्तविक मामले हैं जहां एसक्यूएल 2014 में उच्च घनत्व सूचकांक के साथ, जहां latऔर lngआउटपरफॉर्म georgraphyकिया जाता है। उदाहरण के लिए: सभी बिंदु एक आयत को हटा रहे हैं। केवल मुझे यकीन नहीं है, मैं देखता हूं कि Google मानचित्र अब 6 अंकों के बजाय 7 का उपयोग करता है?
नेनाद

22

जिस तरह से मैं इसे करता हूं: मैं अक्षांश और देशांतर को संग्रहीत करता हूं और फिर मेरे पास एक तीसरा स्तंभ है जो 1 दो स्तंभों का एक स्वचालित व्युत्पन्न भूगोल प्रकार है। तालिका इस प्रकार है:

CREATE TABLE [dbo].[Geopoint]
(
    [GeopointId] BIGINT NOT NULL PRIMARY KEY IDENTITY, 
    [Latitude] float NOT NULL, 
    [Longitude] float NOT NULL, 
    [ts] ROWVERSION NOT NULL, 
    [GeographyPoint]  AS ([geography]::STGeomFromText(((('POINT('+CONVERT([varchar](20),[Longitude]))+' ')+CONVERT([varchar](20),[Latitude]))+')',(4326))) 
)

यह आपको जियोप्वाइंट कॉलम पर स्थानिक प्रश्नों का लचीलापन देता है और आप सीएसवी प्रयोजनों के लिए उन्हें प्रदर्शित करने या निकालने के लिए अक्षांश और देशांतर मान भी प्राप्त कर सकते हैं।


मैं जिस चीज की तलाश कर रहा था, उसके लिए क्या आपके पास पटरियों / लाइनों के लिए कुछ भी है
एग्गी

एक अन्य दृष्टिकोण जो आपके परिदृश्य के आधार पर भी काम कर सकता है, वह लंबे और अव्यक्त का भंडारण कर रहा है और फिर बस गतिशील रूप से रनटाइम पर फ्लाई पर भूगोल ऑब्जेक्ट बना रहा है।
जैपनीजोलिका

1
महान विचार है लेकिन ध्यान रखें कि यदि आप किसी के इरादे हैं तो आप गणना किए गए कॉलम पर स्थानिक सूचकांक नहीं बना सकते।
hugughan3

1
@ hvaughan3 मुझे लगता है कि आप कर सकते हैं यदि आप इसे एक बनाने कायम गणना स्तंभ।
निकल 24

2
धन्यवाद और +1, आपके उत्तर से मुझे मदद मिली। लेकिन मुझे लगता है कि इसके Pointबजाय इसका इस्तेमाल करना बेहतर होगा STGeomFromText। उदाहरण के लिए [geography]::Point([Latitude], [Longitude], 4326):।
डिफॉल्ट.क्रेमर

21

मैं उन लोगों के प्रति विरोधाभासी होने से नफरत करता हूं जिन्होंने कहा "यहां एक नया प्रकार है, चलो इसका उपयोग करें"। नए SQL Server 2008 स्थानिक प्रकारों में इसके कुछ नियम हैं - अर्थात् दक्षता, हालांकि आप नेत्रहीन यह नहीं कह सकते कि हमेशा उस प्रकार का उपयोग करें। यह वास्तव में कुछ बड़े चित्र मुद्दों पर निर्भर करता है।

एक उदाहरण के रूप में, एकीकरण। इस प्रकार के पास .Net में एक समतुल्य प्रकार है - लेकिन इंटरोप के बारे में क्या? .Net के पुराने संस्करणों के समर्थन या विस्तार के बारे में क्या? सेवा स्तर पर इस प्रकार को अन्य प्लेटफार्मों पर उजागर करने के बारे में क्या? डेटा के सामान्यीकरण के बारे में क्या है - हो सकता है कि आप अक्षांश या सूचना के स्टैंडअलोन टुकड़ों के रूप में रुचि रखते हों। शायद आपने पहले से ही लंबे / अव्यवस्था को संभालने के लिए जटिल व्यावसायिक तर्क लिखे हैं।

मैं यह नहीं कह रहा हूं कि आपको स्थानिक प्रकार का उपयोग नहीं करना चाहिए - कई मामलों में आपको करना चाहिए। मैं सिर्फ यह कह रहा हूं कि आपको उस रास्ते पर जाने से पहले कुछ और महत्वपूर्ण सवाल पूछने चाहिए। मेरे लिए आपके प्रश्न का सही उत्तर देने के लिए मुझे आपकी विशिष्ट स्थिति के बारे में अधिक जानना होगा।

लंबे / लाट को अलग-अलग या एक स्थानिक प्रकार में संचय करना दोनों व्यवहार्य समाधान हैं, और एक अपनी परिस्थितियों के आधार पर दूसरे के लिए बेहतर हो सकता है।


जीआईएस और स्थानिक डेटा प्रोसेसिंग में एक लंबा इतिहास और मानक पाठ्य, द्विआधारी प्रतिनिधित्व 2000 के दशक से कम से कम है। यदि आप स्थानिक प्रकार और मानक अभ्यावेदन का उपयोग नहीं करते हैं, तो आपके द्वारा बताई गई सभी समस्याएं समाप्त हो
जाएंगी

15

आप क्या करना चाहते हैं अक्षांश और देशांतर को नए SQL2008 स्थानिक प्रकार -> GEOGRAPHY के रूप में संग्रहीत करें।

यहां एक टेबल का स्क्रीन शॉट है, जो मेरे पास है।

संपूर्ण पाठ http://img20.imageshack.us/img20/6839/zipcodetable.png

इस तालिका में, हमारे पास दो फ़ील्ड हैं जो भूगोल डेटा संग्रहीत करते हैं।

  • सीमा: यह बहुभुज है जो ज़िप कोड सीमा है
  • CentrePoint: यह अक्षांश / देशांतर बिंदु है जो इस बहुभुज के दृश्य मध्य बिंदु का प्रतिनिधित्व करता है।

मुख्य कारण यह है कि आप इसे एक GEOGRAPHY प्रकार के रूप में डेटाबेस में सहेजना चाहते हैं, इसलिए आप इसके बाद सभी SPATIAL तरीकों का लाभ उठा सकते हैं -> उदा। पॉली में बिंदु, दो बिंदुओं के बीच की दूरी, आदि।

BTW, हम अक्षांश / लंबे डेटा को पुनः प्राप्त करने के लिए Google के मैप्स एपीआई का भी उपयोग करते हैं और हमारे Sql 2008 DB में स्टोर करते हैं - इसलिए यह विधि काम करती है।


1
और क्या होगा यदि आप अभी तक 2008 पर नहीं हैं, या क्या होगा यदि आप SQLCE का उपयोग करते हैं? उत्तरार्द्ध GEOGRAPHY प्रकार का समर्थन नहीं करता ...
fretje

3
यदि SqlCE या <2008 द्विआधारी का समर्थन करता है, तो परिणामों को स्टोर करना संभव है, यह परिवर्तनशील है और फिर अपने .NET कोड में इस बाइनरी डेटा प्रतिनिधित्व के खिलाफ स्थानिक गणना करने के लिए स्थानिक उपकरण लाइब्रेरी dll का उपयोग करें। सबसे अच्छा समाधान नहीं, लेकिन फिर भी कुछ समस्याओं का एक संभावित समाधान । (sql स्थानिक के लिए nuget .. उस dll को हथियाने के लिए)।
प्योर.क्रोम

2
छवि लिंक टूट गया है
ब्रायन डेनी

urgh :( कुछ भी नहीं छवियों के लिए धन्यवाद। मैंने सालों से IS का उपयोग नहीं किया है :( imgur.com सभी तरह से!
Pure.Krome 15'14 2:14

1
-1, यह उत्तर छवि के बिना अधूरा है। कृपया इसे एक नई छवि या पाठ तालिका विवरण के साथ बदलने या इस उत्तर को हटाने पर विचार करें।
इल्मरी करोनें

11

SQL सर्वर में स्थानिक संबंधित जानकारी के लिए समर्थन है। आप http://www.microsoft.com/sqlserver/2008/en/us/spatial-data.aspx पर अधिक देख सकते हैं ।

वैकल्पिक रूप से आप सूचना को दो बुनियादी क्षेत्रों के रूप में संग्रहीत कर सकते हैं, आमतौर पर एक फ़्लोट मानक डेटा प्रकार होता है जो अधिकांश उपकरणों द्वारा रिपोर्ट किया जाता है और एक इंच या दो के लिए पर्याप्त सटीक होता है - Google मानचित्र के लिए पर्याप्त से अधिक।


2

नोट : यह हाल ही में SQL सर्वर, .NET स्टैक अपडेट पर आधारित एक उत्तर है

भूगोल डेटा प्रकार के तहत एसक्यूएल सर्वर में प्वाइंट्स (नोट कैपिटल पी) डेटा के रूप में गूगल मैप्स से अव्यक्त और देशांतर को संग्रहीत किया जाना चाहिए।

मान लें कि आपके वर्तमान डेटा को Sampleस्तंभ के तहत varchar के रूप में एक तालिका में संग्रहीत किया जाता है latऔर lon, नीचे क्वेरी आपको भूगोल में बदलने में मदद करेगी

alter table Sample add latlong geography
go
update Sample set latlong= geography::Point(lat,lon,4326)
go

पुनश्च: अगली बार जब आप भूगोल डेटा के साथ इस तालिका का चयन करते हैं, तो परिणाम और संदेश टैब के अलावा, आपको विज़ुअलाइज़ेशन के लिए नीचे दिए गए स्थानिक परिणाम टैब भी मिलेंगे

SSMS भू परिणाम टैब


0

यदि आप Entity Framework 5 <का उपयोग कर रहे हैं तो आप उपयोग कर सकते हैं DbGeography। MSDN से उदाहरण:

public class University  
{ 
    public int UniversityID { get; set; } 
    public string Name { get; set; } 
    public DbGeography Location { get; set; } 
}

public partial class UniversityContext : DbContext 
{ 
    public DbSet<University> Universities { get; set; } 
}

using (var context = new UniversityContext ()) 
{ 
    context.Universities.Add(new University() 
        { 
            Name = "Graphic Design Institute", 
            Location = DbGeography.FromText("POINT(-122.336106 47.605049)"), 
        }); 

    context. Universities.Add(new University() 
        { 
            Name = "School of Fine Art", 
            Location = DbGeography.FromText("POINT(-122.335197 47.646711)"), 
        }); 

    context.SaveChanges(); 

    var myLocation = DbGeography.FromText("POINT(-122.296623 47.640405)"); 

    var university = (from u in context.Universities 
                        orderby u.Location.Distance(myLocation) 
                        select u).FirstOrDefault(); 

    Console.WriteLine( 
        "The closest University to you is: {0}.", 
        university.Name); 
}

https://msdn.microsoft.com/en-us/library/hh859721(v=vs.113).aspx

मैं जिस चीज से जूझता DbGeographyथा, मैंने उसका उपयोग करना शुरू कर दिया था coordinateSystemId। नीचे दिए गए कोड के लिए एक उत्कृष्ट स्पष्टीकरण और स्रोत के लिए नीचे दिए गए उत्तर को देखें।

public class GeoHelper
{
    public const int SridGoogleMaps = 4326;
    public const int SridCustomMap = 3857;

    public static DbGeography FromLatLng(double lat, double lng)
    {
        return DbGeography.PointFromText(
            "POINT("
            + lng.ToString() + " "
            + lat.ToString() + ")",
            SridGoogleMaps);
    }
}

https://stackoverflow.com/a/25563269/3850405


-4

यदि आप इसे केवल URL में स्थानापन्न करने जा रहे हैं, तो मुझे लगता है कि एक क्षेत्र ऐसा करेगा - जिससे आप एक URL बना सकते हैं

http://maps.google.co.uk/maps?q=12.345678,12.345678&z=6

लेकिन जैसा कि यह डेटा के दो टुकड़े हैं मैं उन्हें अलग-अलग क्षेत्रों में संग्रहीत करूंगा


यह मेरा मामला। मुझे निर्देशांक को केवल एक फ़ील्ड में संग्रहीत करने और कॉमा द्वारा अलग करने की आवश्यकता है। मुझे लगता है कि एक क्षेत्र के रूप में एक पाठ का उपयोग कर सकता है। तुम क्या सोचते हो?
अमर

-10

फ्लोट के रूप में दोनों को स्टोर करें, और उन पर अद्वितीय कुंजी शब्दों का उपयोग करें। I.em

create table coordinates(
coord_uid counter primary key,
latitude float,
longitude float,
constraint la_long unique(latitude, longitude)
);

यह सुनिश्चित करने के लिए कि अक्षांश और देशांतर जोड़ी का केवल 1 अनूठा सेट है। आप अपनी तालिका में दो बार {0,0} को समन्वयित नहीं करना चाहते हैं, क्या आप नहीं?
ग्रेविटॉन

1
आप शायद इस तरह से एक अलग निर्देशांक तालिका नहीं रखना चाहते हैं, विशेष रूप से विशिष्टता की कमी के साथ यह एक रखरखाव दुःस्वप्न है मामले को संभालते हुए कि दो स्थान एक ही बिंदु को संदर्भित करते हैं, न कि अपरिष्कृत पंक्तियों की सफाई का उल्लेख करने के लिए।
आराकनिद

2
> आप शायद इस तरह एक अलग निर्देशांक तालिका नहीं करना चाहते हैं - बिल्कुल नहीं? कभी नहीँ? आप इसे 1 क्षेत्र में कैसे स्टोर करेंगे? SQL 2008 स्थानिक प्रकार का उपयोग नहीं करने वाले लाखों लोगों के बारे में क्या?
सैली

2
इस तरह की अड़चन होना एक बुरा निर्णय है। मान लीजिए कि बॉब अंदर रहता है House A, और House Bउस घर में चला जाएगा , जहां एलिस रहते थे। जल्द ही बॉब अपने पते (स्थान) को बचाने में सक्षम नहीं होगा, क्योंकि ऐलिस ने उसे अभी तक अपडेट नहीं किया है - या कभी नहीं होगा।
jweyrich

@ सैली - यही उन्होंने नहीं कहा। उसकी टिप्पणी पढ़ें। उन्होंने कहा कि अलग-अलग तालिका में मूल्यों की एक जोड़ी को संग्रहीत करने का कोई कारण नहीं होना चाहिए । बस लेटेस्ट / लॉन्ग को ओरिजिनल टेबल पर रखें और एक दूसरी टेबल के ओवरहेड और सभी जॉन्स को सेव करें।
निकग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.