2009-07-03 17 views
14

का उपयोग कर देखें मैं नीचेअगर एक बहुभुज के भीतर अक्षांश/देशांतर गिर mysql

CREATE TABLE geom (g GEOMETRY); 

तालिका बनाया है और कई पंक्तियों नीचे दिए गए उदाहरण डाला है है:

INSERT INTO geom (g) 
VALUES(PolygonFromText('POLYGON((
9.190586853 45.464518970, 
9.190602686 45.463993916, 
9.191572471 45.464001929, 
9.191613325 45.463884676, 
9.192136130 45.463880767, 
9.192111509 45.464095594, 
9.192427961 45.464117804, 
9.192417811 45.464112862, 
9.192509035 45.464225851, 
9.192493139 45.464371079, 
9.192448471 45.464439002, 
9.192387444 45.464477861, 
9.192051402 45.464483037, 
9.192012814 45.464643592, 
9.191640825 45.464647090, 
9.191622331 45.464506215, 
9.190586853 45.464518970))') 
); 

अब मैं सभी खोज करना चाहते हैं डेटा और उन प्रविष्टियों को वापस लौटाएं जहां एक बहुभुज/लंबे समय तक मैंने बहुभुज के साथ गिरना शुरू किया है।

यह mysql का उपयोग करके कैसे किया जा सकता है? या क्या किसी को भी किसी भी लिंक के बारे में पता है जो मुझे सही दिशा में इंगित करेगा?

उत्तर

17

v5.1 के रूप में MySQL केवल minimum bounding rectangles (MBR) पर संचालन का समर्थन करता है। जबकि वहाँ एक "Contains" समारोह जो आपको क्या चाहिए क्या करना होगा है, यह पूरी तरह से लागू नहीं किया गया है और relevant manual page

वर्तमान में से MBRContains

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

इन कार्यों स्थानिक विश्लेषण के लिए पूर्ण समर्थन के साथ आगामी रिलीज़ में लागू किया जा सकता है।

आप क्या कर सकते हैं MySQL आपको एमबीआर के आधार पर अनुमानित परिणाम देता है, और उसके बाद इसे अधिक सटीक परीक्षण करने के लिए प्रक्रिया पोस्ट करें। वैकल्पिक रूप से, PostGIS पर स्विच करें!

(अपडेट मई 2012 - धन्यवाद माइक Toews)

MySQL 5.6.1+ बल्कि एमबीआर से

MySQL मूल रूप से इन कार्यों ऐसा है कि वे वस्तु बाउंडिंग आयतों का इस्तेमाल किया और लौट आए कार्यान्वित functions which use object shapes प्रदान करता है संबंधित एमबीआर-आधारित कार्यों के समान परिणाम। MySQL 5.6.1 के अनुसार, संबंधित संस्करण उपलब्ध हैं जो सटीक ऑब्जेक्ट आकार का उपयोग करते हैं। इन संस्करणों को एक ST_ उपसर्ग के साथ नामित किया गया है। उदाहरण के लिए, (0) ऑब्जेक्ट बाध्य आयत का उपयोग करता है, जबकि ST_Contains() ऑब्जेक्ट आकृतियों का उपयोग करता है।

+2

अच्छी खबर यह है कि ([वहाँ 'v5.6 के लिए ST_' उपसर्ग के कार्यों का पूरा समूह है] है http://dev.mysql.com/doc/refman /5.6/en/functions-for-testing-spatial-relations-between-geometric-objects.html#function_st-contains) जो PostGIS के समान उनके उचित कार्यान्वयन करते हैं। –

6

आप एक PostgreSQL के PostGIS विस्तार http://postgis.refractions.net/ तरह सही ढंग से लागू स्थानिक ऑपरेटरों है कि करने के लिए डीबीएस नहीं बदल सकते हैं, तो आप एक दो भाग दृष्टिकोण का उपयोग कर इस समस्या को हल कर सकते हैं।

सबसे पहले MySQL आपको अपने अंतरण ऑपरेटर (http://dev.mysql.com/doc/refman/5.1/en/functions-that-test-spatial-relationships-between-geometries.html#function_intersects) का उपयोग करके बाउंडिंग बॉक्स (जो डिफ़ॉल्ट रूप से करता है) के आधार पर एक बाउंडिंग बॉक्स प्री-फ़िल्टरिंग परिणाम देता है। यदि प्रश्न धीमे हैं, तो सुनिश्चित करें कि आपके पास पहले अपने ज्यामिति फ़ील्ड पर एक अनुक्रमणिका है।

फिर (, सी ++ आधारित हालांकि यह भी अजगर की तरह अलग अलग भाषाओं के लिए बाइंडिंग है) मूल ज्यामिति कि आप GEOS (http://trac.osgeo.org/geos/) की तरह जीआईएस ज्यामिति पुस्तकालय का एक ज्यामिति वस्तु में आपकी क्वेरी में उपयोग हाइड्रेट, सुडौल (http://trac.gispython.org/lab/wiki/Shapely), OGR (या जावा टोपोलॉजी सुइट (जेटीएस) http://www.vividsolutions.com/jts/jtshome.htm)।

टेस्ट geometries है कि आप के भीतर या काटती है। तरह उपयुक्त ऑपरेटर का उपयोग कर अपने क्वेरी परिणाम से वापस पाने के प्रत्येक इन पुस्तकालयों के किसी भी आप एक बूलियन दे देंगे परिणाम

व्यक्तिगत रूप से, मैं ओजीआर के नमूने देखता हूं क्योंकि इसमें एक बड़ा समुदाय है जो मदद के लिए तैयार है।

ऐसा लिंक डालने के लिए

ओह, हाँ, और खेद ... मुझे लगता है कि मैं कर रहा हूँ के बाद से 'नई' मैं केवल एक लिंक पोस्ट कर सकते हैं (?)

1

समारोह MySQL मंचों पर this post में दी गई पूरी तरह से काम करता है मेरे लिए।

यह बहुत तेज़ नहीं है और आपको यह सुनिश्चित करना होगा कि पैरामीटर 'एमपी' आपके द्वारा उपयोग किए जा रहे स्थानिक कॉलम के समान प्रकार है (मैंने ओआरजीओजीआर का उपयोग ऑर्डनेंस सर्वे आकारफाइल को MySQL में आयात करने के लिए किया था, इसलिए इसे 'मल्टीप्लिओगन' से बदलना पड़ा 'टू' GEOMETRY ')

+0

बस जोड़ने के लिए, मैंने मूल आकार फ़ाइल को http://mapshaper.com/test/demo.html के माध्यम से चलकर परिमाण के क्रम से क्वेरी गति में वृद्धि की - भगवान डगलस-पेकर को आशीर्वाद दें ... –

+0

@all उन लोगों के लिए 5.6 से नीचे mysql संस्करण का उपयोग कर रहे हैं यह मदद करनी चाहिए –

0

मैंने function को फिर से लिखा है जो पिछले पोस्ट में @danherd द्वारा दिया गया था, इसलिए यह वास्तविक मल्टीप्लिगॉन के साथ काम कर सकता है जो कि एक बहुभुज से अधिक होता है। आप में से उन लोगों के लिए जो अभी भी पुराने MySQL संस्करण का उपयोग करते रहें, इसे मदद करनी चाहिए।

संदेश यह है:

DELIMITER // 

CREATE FUNCTION GISWithin(pt POINT, mp MULTIPOLYGON) RETURNS INT(1) DETERMINISTIC 

BEGIN 

DECLARE str_big, str, xy LONGTEXT; 
DECLARE x, y, p1x, p1y, p2x, p2y, m, xinters DECIMAL(16, 13) DEFAULT 0; 
DECLARE counter INT DEFAULT 0; 
DECLARE p, pb, pe, sb, se, ct DECIMAL(16, 0) DEFAULT 0; 

SELECT MBRWithin(pt, mp) INTO p; 
IF p != 1 OR ISNULL(p) THEN 
return p; 
END IF; 

SELECT X(pt), Y(pt), ASTEXT(mp) INTO x, y, str_big; 
SET str_big = REPLACE(str_big, 'MULTIPOLYGON(((',''); 
SET str_big = REPLACE(str_big, ')))', ''); 
SET str_big = REPLACE(str_big, ')),((', '|'); 
SET str_big = CONCAT(str_big, '|'); 

SET sb = 1; 
SET se = LOCATE('|', str_big); 
SET str = SUBSTRING(str_big, sb, se - sb); 

WHILE se > 0 DO 
SET ct = ct + 1; 
SET str = SUBSTRING(str_big, sb, se - sb); 

SET pb = 1; 
SET pe = LOCATE(',', str); 
SET xy = SUBSTRING(str, pb, pe - pb); 
SET p = INSTR(xy, ' '); 
SET p1x = SUBSTRING(xy, 1, p - 1); 
SET p1y = SUBSTRING(xy, p + 1); 
SET str = CONCAT(str, xy, ','); 

WHILE pe > 0 DO 
SET xy = SUBSTRING(str, pb, pe - pb); 
SET p = INSTR(xy, ' '); 
SET p2x = SUBSTRING(xy, 1, p - 1); 
SET p2y = SUBSTRING(xy, p + 1); 
IF p1y < p2y THEN SET m = p1y; ELSE SET m = p2y; END IF; 
IF y > m THEN 
IF p1y > p2y THEN SET m = p1y; ELSE SET m = p2y; END IF; 
IF y <= m THEN 
IF p1x > p2x THEN SET m = p1x; ELSE SET m = p2x; END IF; 
IF x <= m THEN 
IF p1y != p2y THEN 
SET xinters = (y - p1y) * (p2x - p1x)/(p2y - p1y) + p1x; 
END IF; 
IF p1x = p2x OR x <= xinters THEN 
SET counter = counter + 1; 
END IF; 
END IF; 
END IF; 
END IF; 
SET p1x = p2x; 
SET p1y = p2y; 
SET pb = pe + 1; 
SET pe = LOCATE(',', str, pb); 
END WHILE; 

SET sb = se + 1; 
SET se = LOCATE('|', str_big, sb); 

END WHILE; 

RETURN counter % 2; 

END 

DELIMITER ; 

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

  • कोई संबंधित समस्या नहीं^_^