PostGIS रेखागणित क्वेरी "त्रुटि: मिश्रित SRID geometries पर ऑपरेशन" केवल कुछ मूल्यों के लिए


17

मेरे पास दो ज्यामिति स्तंभों के साथ PostGIS तालिका है, दोनों को SRID 4326 के साथ परिभाषित किया गया है। मैं बिना किसी समस्या के तालिका में सम्मिलित कर सकता हूं, निम्नलिखित INSERTकथन का उपयोग करके (जहां lngऔर latप्रोग्राम में पारित मान हैं):

INSERT INTO pad_meta (
    uuid, created, updated, name, origin, radius, area, expiry, creator
) VALUES (
    $1, now(), now(), $2, ST_GeomFromText('POINT(lng, lat)', 4326), $3, 
    ST_Buffer(ST_GeomFromText('POINT(lng, lat)', 4326), $4), $5, $6
)

लेकिन जब मैं ST_Intersects का उपयोग कर, एक चौराहे के लिए क्वेरी बिंदु के मूल्य के आधार पर मैं ERROR: Operation on mixed SRID geometries

उदाहरण के लिए, यह क्वेरी काम करती है:

SELECT * FROM pad_meta where ST_Intersects(
    'POINT(-122.334172173172 46.602634395263560)'::geometry, area::geometry 
) ORDER BY created DESC;

और यह त्रुटियां बाहर हैं:

SELECT * FROM pad_meta where ST_Intersects(
    'POINT(-122.334172173172 47.602634395263560)'::geometry, area::geometry 
) ORDER BY created DESC;

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

मुझे लगता है कि मैं मौलिक रूप से कुछ गलत समझ रहा हूं। फिलहाल, मैंने ST_GeomFromTextSRID का उपयोग करने और स्पष्ट रूप से निर्दिष्ट करने के लिए क्वेरी को पुन: स्वरूपित करके समस्या को हल / सुधार / हल किया है।

SELECT * FROM pad_meta where ST_Intersects(
    ST_GeomFromText('POINT(-122.334172173172 47.602634395263560)', 4326), area
) ORDER BY created DESC;

लेकिन मैं सच में समझ नहीं पाता कि क्या अंतर है, या अगर यह वास्तव में "समाधान" है।

मेरा प्रश्न है: मुझे केवल विशिष्ट मानों के लिए त्रुटि क्यों हो रही है, और इस क्वेरी को प्रारूपित करने का उचित तरीका क्या है?

यहाँ संदर्भ के लिए मेरी तालिका परिभाषा है:

CREATE TABLE IF NOT EXISTS pad_meta (
  uuid CHAR(32),
  created TIMESTAMP,
  updated TIMESTAMP,
  name VARCHAR(128),
  origin GEOMETRY(Point, 4326),
  radius INTEGER,
  area GEOMETRY(Polygon, 4326),
  expiry TIMESTAMP,
  creator CHAR(32),
  PRIMARY KEY (uuid)
);

मैंने यह भी सत्यापित किया है कि ज्यामिति में एक ही प्रकार का SRID_columns है:

SELECT f_table_name, f_geometry_column, srid FROM geometry_columns;
f_table_name | f_geometry_column | srid
--------------+-------------------+------
 pad_meta     | origin            | 4326
 pad_meta     | area              | 4326

मदद / सलाह की सराहना की। धन्यवाद! (नोट: मैंने यह प्रश्न भी देखा है , लेकिन चूंकि मैं तालिका में सम्मिलित करते समय पहले से ही अपनी ज्यामिति SRID को स्पष्ट रूप से परिभाषित कर रहा हूं, ऐसा लगता है कि ऐसा नहीं है।)

जवाबों:


24

जब आप SRID के बिना एक ज्यामिति निर्दिष्ट करते हैं, तो यह वास्तव में है 0(या -1संस्करण <2 के लिए):

SELECT ST_SRID('POINT(-122.334172173172 46.602634395263560)'::geometry);
 st_srid
---------
       0

इसलिए जब आप SRID = 4326 के साथ इस ज्यामिति का उपयोग करते हैं, तो यह मिश्रण 0और होता है 4326। यह आमतौर पर एक उपयोगी त्रुटि है, अगर स्थानिक संदर्भ वास्तव में अलग हैं। आपके मामले के साथ, SRID समान हैं, लेकिन आपने SRID को क्वेरी बिंदु पर एनकोड नहीं किया है। इसलिए, अपनी क्वेरी को ठीक करने के लिए हमेशा अपने क्वेरी बिंदु के लिए उसी SRID को निर्दिष्ट करें , और वे अब मिश्रित नहीं होंगे।

एक तरफ ध्यान दें के रूप में, प्रकार के रूप में यहाँ दिखाया गया है, 4326 की एक डिफ़ॉल्ट SRID (डब्ल्यूजीएस 84) है:geography

SELECT ST_SRID('POINT(-122.334172173172 46.602634395263560)'::geography::geometry);
 st_srid
---------
    4326

इसलिए, यदि आप geographyप्रकारों के बजाय प्रकारों का उपयोग करते हैं geometry, तो SRID को निर्दिष्ट करने की आवश्यकता नहीं है (जब तक कि आप मंगल या जो भी हो, वैकल्पिक दीर्घवृत्त के लिए एक अलग SRID नहीं चाहते हैं)।


क्यों एक प्रश्न में एक त्रुटि है, और दूसरा नहीं है, ST_Intersects पहले एक &&बाउंडिंग बॉक्स खोज करता है , जो तेज है, और SRIDs के बारे में परवाह नहीं करता है। यदि बाउंडिंग बॉक्स प्रतिच्छेद नहीं करते हैं तो कोई मिश्रित SRID त्रुटि संदेश नहीं उठाए जाएंगे। लेकिन अगर वे इंटरसेक्ट करते हैं, तो दूसरा फ़िल्टर होता है _ST_Intersects, जो अधिक सटीक होता है और दो SRID की जाँच करता है ताकि यह सुनिश्चित हो सके कि वे मेल खाते हैं, और यदि उन्हें मिलाया जाता है तो कोई त्रुटि उठाता है। उदाहरण के लिए:

WITH pad_meta AS (
    SELECT 'SRID=4326;POLYGON((-124 50, -124 47, -121 50, -124 50))'::geometry AS area)

SELECT * FROM pad_meta where ST_Intersects(
    'POINT(-122.334172173172 46.602634395263560)'::geometry, area::geometry 
);

कोई प्रतिच्छेदन बाउंडिंग बॉक्स और बाइपास नहीं है _ST_Intersects। लेकिन POINT(-122.334172173172 47.602634395263560)त्रुटि को उठाया जाएगा क्योंकि बाउंडिंग बॉक्स ओवरलैप करते हैं (भले ही ज्यामितीय वास्तव में प्रतिच्छेद नहीं करते हैं)।

हालांकि, एक ही ज्यामितीय और विभिन्न फिल्टर के साथ:

WITH pad_meta AS (
    SELECT 'SRID=4326;POLYGON((-124 50, -124 47, -121 50, -124 50))'::geometry AS area)

SELECT * FROM pad_meta where _ST_Intersects(
    'POINT(-122.334172173172 46.602634395263560)'::geometry, area::geometry 
);

मिश्रित SRID त्रुटि को फेंकता है, क्योंकि बाउंडिंग बॉक्स को नहीं माना जाता है।


वाह धन्यवाद। यह समझ आता है। SRID=4326कथन के शेष भाग के लिए SRID को सेट करने का सही तरीका (जैसा आपने ऊपर दिया था) के साथ एक क्वेरी को प्रीफ़िक्स कर रहा है? (जैसा ST_GeomFromTextकि मैं सिर्फ इसलिए नहीं जानता था कि SRID को निर्दिष्ट करने का उपयोग करने के विरोध में ...)? क्या प्रश्नों के लिए एक डिफ़ॉल्ट SRID सेट करने का एक तरीका है? हर बार स्पष्ट रूप से सेट करने के लिए बल्कि क्रिया को लगता है। फिर से धन्यवाद!
jyykate

1
मैंने अपने जवाब को geographyप्रकारों का उपयोग करने के लिए अद्यतन किया है , जो हमेशा 4326 होते हैं। साथ ही, SRID को निर्दिष्ट करने के कई तरीके हैं।
माइक टी

0

टिप्पणियों की एक जोड़ी जो मदद कर सकती है: एक, Point(Double, Double)एक देशी पोस्टग्रेक्सेल फ़ंक्शन है जिसे आप पोस्टगिस डेटा प्रकार के लिए बाध्य कर रहे हैं। ST_MakePoint(double x, double y)उचित ज्यामिति बनाएगा। इसके अलावा, आपके प्रश्न में आप दूसरे तर्क को देशांतर के रूप में संदर्भित करते हैं। उचित आदेश है x, y, जो से मेल खाती है Longitude, Latitude। उन लोगों को उलट कर बिना किसी अपवाद के फेंकने से अप्रत्याशित परिणाम वापस आ सकते हैं।

इसमें से कोई भी वास्तव में नहीं बताता है कि आपका पहला उदाहरण कभी-कभी क्यों काम करता है और दूसरों को नहीं, लेकिन उम्मीद है कि इससे आपको अच्छे प्रश्न बनाने में मदद मिलेगी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.