किसी विशिष्ट अक्षांश / लंबे बिंदु के 30 किमी के दायरे में सभी परिणाम लौटाएं?


21

मेरे पास एक स्तंभ के साथ एक तालिका है the_geomजिसमें डेटा समान है:

0103000020E61000000100000005000000CE473AACFA071E40F27FB23340744740336FE841C6231E40873BED903F744740FC150A0ACE231E40D19E2684637647409C9B443D00081E409A9AF82664764740CE473AACFA071E40F27FB23340744740

जब फंक्शन ST_AsEWKT(the_geom)रिटर्न लागू होता है:

SRID=4326;POLYGON((7.5077921782085 46.9082092877942,7.53493597966353 46.9081898840296,7.53496566473541 46.9249119938446,7.50781341296434 46.9249314035307,7.5077921782085 46.9082092877942))

मुझे उदाहरण के लिए सभी डेटा का चयन करने की आवश्यकता है जो एक विशिष्ट अक्षांश / लंबे बिंदु के 30 किमी के दायरे में है:

  • lat = 46.8167
  • lng = 6.9333

हालाँकि जब भी मैंने उपयोग करने की कोशिश की ST_Distance(), मुझे हमेशा 1 से कम मूल्य मिले, और ST_DWithin()हमेशा सही उपयोग करने पर ।

जवाबों:


23

कृपया निश्चित दूरी के भीतर डेटा प्राप्त करने के लिए PostgreSQL के निम्नलिखित प्रश्न की जाँच करें। मुझे उम्मीद है इससे मदद मिलेगी।

SELECT *
FROM your_table
WHERE ST_Distance_Sphere(the_geom, ST_MakePoint(your_lon,your_lat)) <= radius_mi * 1609.34

1
इसके साथ काम कर पाने में सक्षम था: SELECT * FROM myTable WHERE GeometryType (ST_Centroid (the_geom)) = 'POINT' और ST_Distance_Sphere (ST_Point (ST_XX (ST_Centroid (the_geom))), ST_Y (ST_Centroid (A_omom)) , 46.8167))) <= 18 * 1609.34
dan2k3k4

यह महान है :)
फरहत अब्बास

2
बस किसी और के लिए आश्चर्य की बात है, 1609.34 आंकड़ा प्रति मील मीटर है, जो कि आधार इकाई पोस्टग्रैज का उपयोग कर रहा है। तो किलोमीटर करने के लिए, स्पष्ट रूप से 1000 से गुणा करें।
1mike12

2
ध्यान दें: यह 1609.344 बिलकुल (परिभाषा के अनुसार) है
बैरिस्टर क्वार्टर

6

ऐसा लगता है कि आप ज्यामिति कॉलम में अपना ज्यामिति जमा कर रहे हैं, भूगोल कॉलम नहीं।
यह ठीक है, लेकिन फ़ंक्शन ST_Distance हमेशा मीटर के बजाय प्रक्षेपण इकाइयों में माप लौटाएगा। आपके मामले में (4326), वह डिग्री होगी।
बस ST_Within के साथ एक बफर का उपयोग करना या तो काम नहीं करेगा, क्योंकि ST_Buffer को डिग्री के साथ भी मापा जाएगा।

आप या तो ज्यामिति के बजाय भूगोल का उपयोग करने के लिए अपने डेटा को परिवर्तित कर सकते हैं, या आप अपनी बात को कुछ ऐसे प्रक्षेपण में बदल सकते हैं जो मीटर, बफर का उपयोग करता है, फिर 4326 में वापस देखें कि उसके भीतर क्या है:

SELECT
    *
FROM <your data>
WHERE ST_Within(the_geom, 
                ST_Transform(ST_Buffer(ST_Transform(ST_SetSRID(ST_MakePoint(6.9333, 46.8167), 4326), 3857), 30000), 4326)) = 1

यह उस बिंदु को 3857 में प्रोजेक्ट करता है , जो वेब मैप्स के साथ लोकप्रिय एक प्रोजेक्शन है। फिर यह इसे 30,000 मीटर तक बफ़र करता है और फिर ST_Within को पास करने से पहले इसे 4326 पर वापस भेज देता है।


छद्म मर्केटर को छोड़कर दूरी के लिए अविश्वसनीय है, इसलिए जब तक डेटा भूमध्य रेखा के करीब नहीं होता है, तब तक परिणाम बंद हो जाएंगे, खासकर 30 किमी की दूरी के साथ।
विन्स

6

मेरी दुनिया में, कस्टम SRID (Google मानचित्र के लिए) का उपयोग करके कुछ इस तरह से काम किया गया है:

SELECT * FROM addresses WHERE ST_DWithin(location, ST_SetSRID(ST_MakePoint(longitude, latitude), 3785), radius);

जहाँ एक प्रकार का locationज्यामिति (बिंदु, 3785), और longitude, latitudeऔर radiusफ़्लोट्स हैं (जैसे -100, 44N, 100W / 44N / 30 "इकाइयों" के लिए - नीचे देखें)

देखें कि किसी अन्य वस्तु के दायरे में सभी वस्तुओं को खोजने का सबसे अच्छा तरीका क्या है? पोस्टगिस डॉक्स में:

ST_DWithin(geometry, geometry, distance)समारोह एक अनुक्रमित दूरी खोज करने के एक आसान तरीका है। यह दूरी त्रिज्या को घेरने के लिए एक बड़ी खोज आयत बनाकर काम करता है, फिर परिणामों की अनुक्रमित सबसेट पर सटीक दूरी की खोज करता है।

अद्यतन: इकाइयाँ SRID 3785 के लिए मील की दूरी पर नहीं हैं ... वे या तो रेडियन या डिग्री या ऐसा कुछ प्रतीत होते हैं। लेकिन मेरी एसआरआईडी के लिए विशिष्टता कहती है कि इसकी इकाइयाँ या तो मीटर या डिग्री हैं और यह निश्चित रूप से उनमें से कुछ भी नहीं है, कम से कम कुछ रूपांतरण के बिना नहीं:

alex=# select * from spatial_ref_sys where srid=3785; srid | auth_name | auth_srid | srtext | proj4text
3785 | EPSG | 3785 | PROJCS["Popular Visualisation CRS / Mercator (deprecated)",GEOGCS["Popular Visualisation CRS",DATUM["Popular_Visualisation_Datum",SPHEROID["Popular Visualisation Sphere",6378137,0,AUTHORITY["EPSG","7059"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6055"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4055"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"],AUTHORITY["EPSG","3785"],AXIS["X",EAST],AXIS["Y",NORTH]] | +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs


3785 (आपकी पोस्ट में) और 3857 में क्या अंतर है?
ट्यून

वे अलग-अलग अनुमान हैं। 3875 बनाम 3857 - मुझे नहीं पता कि क्या कोई दूसरे से बेहतर है
अलेक्जेंड्फी

1
"EPSG 3785 को अन्यथा समान EPSG 3857 के पक्ष में चित्रित किया गया है" - github.com/rgeo/rgeo/pull/61
Yarin

2

मुझे लगता है कि यह काम करना चाहिए:

SELECT gid FROM table 
WHERE ST_DWithin(the_geom, ST_SetSRID(ST_Point(6.9333, 46.8167), 4326), 30000)

3
यदि आप भूगोल के लिए the_geom कास्ट करते हैं जो काम करना चाहिए। st_dwithin (भूगोल (the_geom), भूगोल (<प्वाइंट, 4326>), 30000)
कैविला
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.