ArcPy में दो ज्यामितीयों की तुलना?


18

मैं उन दोनों के बीच अंतर की पहचान करने के लिए दो अलग-अलग फीचर वर्गों की तुलना करने की कोशिश कर रहा हूं (एक अलग फ़ंक्शन के प्रकार)। मेरा मूल वर्कफ़्लो:

  1. मैं SearchCursor का उपयोग करके ज्यामिति निकालता हूं
  2. दो फीचर वर्गों की ज्यामिति को जेजोन के रूप में एक संशोधित __geo_interface__( वाल्वलॉन्डन से प्राप्तreturn {'type': 'Polygon', 'coordinates': [[((pt.X, pt.Y) if pt else None) for pt in part] for part in self]} ) के रूप में सहेजें । यह साझा ज्यामिति ऑब्जेक्ट से बचने के लिए है जो ईएसआरआई कर्सर के साथ उपयोग करता है और गहरी प्रतियां बनाने में असमर्थता है (इसके बारे में यहाँ कुछ चर्चा gis.stackexchange के बारे में बात करते हैं)।
  3. एक विशिष्ट पहचानकर्ता के आधार पर दो फ़ीचर वर्गों की ज्यामितीय जाँच करें। उदाहरण के लिए, FC2 OID1 ज्यामिति के साथ FC1 OID1 ज्यामिति की तुलना करें। ईएसआरआई ऑब्जेक्ट उदाहरण के रूप में ज्यामिति प्राप्त करने के लिए, कॉल arcpy.AsShape()(साथ बिंदु 2 ऊपर देखें) के साथ बहुभुज पढ़ने के लिए संशोधित किया गया है return cls(Array([map(lambda p: Point(*p) if p is not None else Point(), part) for part in coordinates]))। तुलना केवल ज्यामिति कक्षाgeom1.equals(geom2) में इंगित की गई है ।

मैं ज्यामिति में ~ 140 बदलावों को खोजने की उम्मीद करता हूं, लेकिन मेरी स्क्रिप्ट में जोर है कि 430 हैं। मैंने उन जियोजोन अभ्यावेदन की जांच करने की कोशिश की और वे समान हैं, फिर भी ज्यामिति वर्ग बराबर () ऐसा कहने से इनकार करता है।

एक उदाहरण नीचे है:

>>> geom1geoJSON 
{'type': 'Polygon', 'coordinates': [[(-122.8423481559999, 47.060497293000083), (-122.84239755599992, 47.059262423000064), (-122.84416913599989, 47.059309693000046), (-122.84416913599989, 47.060497293000083), (-122.8423481559999, 47.060497293000083)]]}
>>> geom2geoJSON 
{'type': 'Polygon', 'coordinates': [[(-122.8423481559999, 47.060497293000083), (-122.84239755599992, 47.059262423000064), (-122.84416913599989, 47.059309693000046), (-122.84416913599989, 47.060497293000083), (-122.8423481559999, 47.060497293000083)]]}
>>> geom1 = arcpy.AsShape(geom1geoJSON)
>>> geom2 = arcpy.AsShape(geom2geoJSON)
>>> geom1.equals(geom2)
False
>>> geom2.equals(geom1)
False

यहां अपेक्षित व्यवहार सच्चा होना चाहिए (गलत नहीं)।

इससे पहले कि मैं ogr geometries के लिए सब कुछ ले जाने से पहले किसी को कोई सुझाव है? (मैं ogr.CreateGeometryFromGeoJSON के रूप में झिझक रहा हूं) () एक स्ट्रिंग की उम्मीद करता है, और आर्कपी __geo_interface__एक शब्दकोश देता है और मुझे लगता है कि मैं अतिरिक्त जटिलता जोड़ रहा हूं)।

निम्नलिखित संसाधनों से मदद मिली, भले ही वे इस सवाल का जवाब न दें:

  1. यहाँ पर gis.stackexchange.com पर arcpy.Geometry सवाल है जो मेरे पाठ में ऊपर लिंक किया गया था।
  2. आर्कगिस.कॉम फ़ोरम से आर्कपी के बहुभुज वर्ग में त्रुटियां (स्पष्ट रूप से आर्कगिस 10.0 में बहुत अधिक सटीक त्रुटियां हैं जो सैद्धांतिक रूप से 10.1 में तय हुईं, लेकिन मैं यह सत्यापित नहीं कर सकता कि 10.0 एसपी 5 में आपको अभी भी त्रुटि मिलती है)।

जवाबों:


12

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

खुशी से जब से आपने अर्पी को स्थापित किया है तो आप सुन्न हो गए हैं, जो संख्यात्मक सरणियों के सेट की तुलना करना आसान बनाता है। इस मामले में मैं numpy.allclose फ़ंक्शन का सुझाव दूंगा , जो कि 1.3.0 में उपलब्ध है (आर्कजीआईएस 10 के साथ स्थापित)।

ऊपर दिए गए नमूनों से

geom1geoJSON = {'type': 'Polygon', 'coordinates': [[(-122.8423481559999, 47.060497293000083), (-122.84239755599992, 47.059262423000064), (-122.84416913599989, 47.059309693000046), (-122.84416913599989, 47.060497293000083), (-122.8423481559999, 47.060497293000083)]]}
geom2geoJSON = {'type': 'Polygon', 'coordinates': [[(-122.8423481559999, 47.060497293000083), (-122.84239755599992, 47.059262423000064), (-122.84416913599989, 47.059309693000046), (-122.84416913599989, 47.060497293000083), (-122.8423481559999, 47.060497293000083)]]}

import numpy as np

close = np.allclose(np.array(geom1geoJSON["coordinates"]), np.array(geom2geoJSON["coordinates"]), atol=1e-7)
#Returns True

atolकीवर्ड सहिष्णुता मान निर्दिष्ट करता है।

ध्यान दें कि आपको बिल्कुल भी उपयोग नहीं करना चाहिए arcpy.AsShape। कभी। जैसा कि मैंने इस प्रश्न (/ बेशर्म प्लग) में उल्लेख किया है कि आर्कजीआईएस में एक ज्ञात बग है जो ज्यामिति को रौंदता है जब वे एक समन्वय प्रणाली के बिना बनाए जाते हैं ( env.XYToleranceपर्यावरण चर सेट करने के बाद भी )। इससे arcpy.AsShapeबचने का कोई उपाय नहीं है। सौभाग्य geometry.__geo_interface__से एक मौजूदा ज्यामिति से सही ज्यामिति निकालता है (हालांकि यह @ पॉसनशेयर से फिक्स किए बिना जटिल बहुभुज को संभालता नहीं है)।


धन्यवाद। मैं ऐसा करने के लिए numpy का उपयोग करने के बारे में नहीं सोचता था। एक अन्य समाधान दशमलव मॉड्यूल का उपयोग करता हुआ प्रतीत होता है और उसी के माध्यम से काम करता है, लेकिन इसके लिए बहुत अधिक कार्य की आवश्यकता होती है।
मिखालिस अवराम

मुझे लगता है कि numpy.allclose() rtolपैरामीटर को 0. पर सेट करना महत्वपूर्ण होगा । डिफ़ॉल्ट रूप से यह 1e-05 है और यह बड़ी सहिष्णुता पैदा कर सकता है यदि सरणियों के मान बड़े हैं: stackoverflow.com/a/57063678/1914034
रडार

11

समन्वय की सटीकता यहाँ एक महत्वपूर्ण विचार है। फ़्लोटिंग पॉइंट नंबर बिल्कुल संग्रहीत नहीं किए जा सकते।

यदि आप फ़ीचर तुलना उपकरण का उपयोग करते हैं , तो क्या यह डिफ़ॉल्ट XY सहिष्णुता का उपयोग करके अपेक्षित परिणाम के साथ आता है?


मैंने फीचर तुलना टूल की जांच नहीं की क्योंकि मैं जो टूल बना रहा हूं वह वास्तव में अलग-अलग फीचर क्लासेस के बीच ले जाने वाले व्यक्तिगत फीचर्स की तुलना करता है। यह कहना है, एक फीचर सिटीरोड्स से काउंटीरोड्स में जा सकता है, इसलिए मुझे यह पता लगाने की जरूरत है कि क्या ज्यामिति में कुछ भी बदला गया है और फीचर क्लास के अलावा अन्य विशेषताओं को पकड़े हुए है। कुल 24 फ़ीचर कक्षाएं हैं, और सुविधाएँ उनके बीच स्थानांतरित हो सकती हैं। फ़ीचर तुलना केवल 2 फ़ीचर वर्गों की तुलना करेगी, इसलिए यह मुझे बता सकती है कि क्या यह अब FC में मौजूद नहीं है। फिर भी मुझे यह सुनिश्चित करने के लिए कि इसे बदलने की सुविधा की तुलना करने की आवश्यकता नहीं है
मिशैलिस अवराम

मैंने डिफ़ॉल्ट टॉलरेंस (8.983e-009 जो कि काफी छोटा है, लेकिन यह एक फ़ाइल GDB है) के साथ फ़ीचर तुलना टूल की जाँच की और यह कुछ बदलावों की रिपोर्ट करता है, लेकिन सही लोगों की नहीं। विशेष रूप से, यह कहता है कि 69 ज्यामिति परिवर्तन हैं (मैं पहले से बेहतर अनुमान लगाता हूं) लेकिन ऐसा लगता है कि ओआईडी अद्वितीय विशेषताओं की पहचान करने का तरीका है (पुराने ओआईडी 1 और नए ओआईडी 1 की खोज करता है) जो जरूरी नहीं कि सच है (मैंने इसका उपयोग करने के लिए इसे निर्धारित किया है) मेरी RUID एक छाँट के रूप में है लेकिन यह इसे पसंद नहीं है)। इस प्रकार फिर से ड्राईंग बोर्ड का इस्तेमाल करते हैं।
मिखली अवराम

4

बगल में @ blah328 जवाब है, आप टैग पसंद रिपोर्टिंग के साथ तालिका मूल्यों और क्षेत्र परिभाषा के साथ मतभेद और समानता के लिए दो तालिकाओं की तुलना करने के टेबल की तुलना करें

उदाहरण:

import arcpy
from arcpy import env
arcpy.TableCompare_management(r'c:\Workspace\wells.dbf', r'c:\Workspace
\wells_new.dbf', 'WELL_ID', 'ALL', 'IGNORE_EXTENSION_PROPERTIES', 'WELL_DEPTH 0.001',
'#','CONTINUE_COMPARE', r'C:\Workspace\well_compare.txt' 

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

3
def truncateCoordinates(myGeometry)
    trucated_coords = []
    partnum = 0

    for part in (myGeometry):
        for pnt in myGeometry.getPart(partnum):
            if pnt:
                trucated_coords.append("{:10.4f}".format(pnt.X))
                trucated_coords.append("{:10.4f}".format(pnt.Y))
             else:
                continue
        partnum += 1     
    return truncated_coords

यदि .equals()फ़ंक्शन अपेक्षित रूप से काम नहीं कर रहा है और / या निर्देशांक ArcGIS में थोड़ा बदल दिया गया है, तो आप XY निर्देशांक की मालिश कर सकते हैं, फिर ज्यामिति के स्ट्रिंग बराबर की तुलना करें। सूचना, truncateCoordinates()4 वें दशमलव स्थान से परे सभी मानों को काट देता है।

geom1 = truncateCoordinates(feature1.Shape)
geom2 = truncateCoordinates(feature2.Shape)

geom1 == geom2

@ क्लेविस- यह ज्यामिति की तुलना करने का एक तरीका है, लेकिन ऐसा लगता है कि जब आप ठीक उसी ज्यामिति की तुलना कर रहे हों, तो ज्यामिति की तरह होना चाहिए। निर्देशांक ट्रंकिंग एक तरह से हैक है। शायद ESRI को फ़्लोट के बजाय दशमलव () प्रकार का उपयोग शुरू करने की आवश्यकता होती है यदि वे फ़्लोटिंग पॉइंट मानों को आंतरिक रूप से सही ढंग से संभाल नहीं सकते हैं लेकिन उन्हें समान स्ट्रिंग्स के रूप में प्रतिनिधित्व कर सकते हैं।
मिकालिस अवराम

1

आप "ARE_IDENTICAL_TO" ओवरलैप_टाइप पैरामीटर के साथ स्थान (डेटा प्रबंधन) टूल का चयन करें का उपयोग कर सकते हैं, चयन स्विच करें, पंक्ति गिनती की जांच करें और फिर ऑब्जेक्ट्स या किसी अन्य प्रासंगिक जानकारी को इकट्ठा करने के लिए पंक्तियों के माध्यम से लूप करें।

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