सक्रिय डोमेन के साथ सुविधा वर्ग सूचीबद्ध करना?


19

मेरे पास एक एश्री फ़ाइल जियोडैटेबेस है जिसमें विशेषता डोमेन परिभाषित हैं। मुझे कुछ विशेषता डोमेन हटाने की आवश्यकता है, लेकिन " क्योंकि डोमेन का उपयोग विशेषता नियम द्वारा किया जाता है।" । मैं यह कैसे पता लगा सकता हूं कि कौन सी सुविधा वर्ग (तों) डोमेन का उपयोग कर रहा है?

Executing: DeleteDomain R:\v5\YT_Canvec.gdb Permanency
Start Time: Thu May 19 11:01:02 2011
ERROR 999999: Error executing function.
The domain is used by an attribute rule.
Failed to execute (DeleteDomain).
Failed at Thu May 19 11:01:02 2011 (Elapsed Time: 0.00 seconds)

जियोडेटाबेस में सौ से अधिक फीचर क्लासेस हैं, अंतःक्रियात्मक रूप से प्रत्येक के लिए एफसी क्षेत्र गुणों को देखना गैर-स्टार्टर है। Gdb एक व्यक्तिगत gdb में बदलने और ms-access (वैसे भी एक डोडी) के साथ पिछले दरवाजे में जाने के लिए बहुत बड़ा है।


(2011-मई -26): यह वाक्यांश करने का एक और तरीका है "डोमेन एक्स का उपयोग कौन सा फ़ीचर वर्ग कर रहा है?"


क्या आप उप-डोमेन का उपयोग कर रहे हैं?
कर्क कुयकेंडल

@kirk, हां एक उपप्रकार है, लेकिन जिन डोमेन को मैं हटाने की कोशिश कर रहा हूं, वे उपप्रकार का उपयोग नहीं कर रहे हैं
मैट विल्की

1
उस स्थिति में मुझे लगता है कि ब्रायन का कोड काम करेगा।
कर्क कुक्केंडल

1
@kirk, सुधार: मुझे नहीं लगा कि मैं उप-डोमेन + डोमेन का उपयोग कर रहा था, लेकिन एक तकनीकी सहायता मामले के बारे में बहुत कुछ बताने और खोलने के बाद, यह पता चलता है कि मैं वास्तव में एक के बाद एक का उपयोग कर रहा था। विशेष रूप से शेष कपाल की पहचान करने के लिए यह सत्य-क्लिक-फ़ेस्ट था। मुझे आपके c # तरीके को फॉलो करने में अधिक समय लगाना चाहिए था!
मैट विल्की

जवाबों:


3

उप-वर्गों के साथ फीचर कक्षाओं को संभालने के प्रश्न का उत्तर देने के लिए, यह आर्कपी (10.1+) के साथ संभव है।

arcpy.env.workspace = your_gdb

for FC in arcpy.ListFeatureClasses():
    for stcode, stdict in list(arcpy.da.ListSubtypes(FC).items()):
        for stkey in list(stdict.keys()):
            if stkey == 'FieldValues':
                for field, fieldvals in list(stdict[stkey].items()):
                    if fieldvals[1] is not None:
                        print(
                            "{},{},{},{}".format(FC,
                                                 'None' if stcode == 0 else stdict['Name'],
                                                 field,
                                                 fieldvals[1].name))

उपप्रकार कोड, stcode, शून्य होगा यदि कोई उपप्रकार नहीं है, तो कोड 'कोई नहीं' प्रिंट करता है।

उपप्रकार शब्दकोश यह करने के लिए अधिक है, इसलिए यह कोड में निरीक्षण किया गया है।


मेरे इस स्वीकार किए गए उत्तर को बदलना। यह छोटा और प्रत्यक्ष है। Github.com/envygeo/arcplus/blob/master/ArcToolbox/Scripts/… पर आपके कोड का मेरा संस्करण । धन्यवाद!
मैट विल्की

21

पायथन में एक भू-स्थान में फीचर कक्षाओं को सूचीबद्ध करने के लिए, सूची में प्रत्येक फीचर वर्ग के माध्यम से लूपिंग, प्रत्येक फीचर क्लास में फील्ड्स को सूचीबद्ध करने और प्रत्येक क्षेत्र के डोमेन को दिखाने के लिए तरीके हैं।

import arcpy

#Set workspace environment to geodatabase
arcpy.env.workspace = your_gdb

#Get list of feature classes in geodatabase
FCs = arcpy.ListFeatureClasses()

#Loop through feature classes in list
for FC in FCs:

    #List fields in feature class
    fields = arcpy.ListFields(FC)

    #Loop through fields
    for field in fields:

        #Check if field has domain
        if field.domain != "":

            #Print feature class, field, domain name
            print FC, field.name, field.domain

उपरोक्त कोड ArcGIS 10 में काम करना चाहिए और यह अजगर इंटरप्रेटर विंडो में दाईं ओर एक सूची प्रिंट करेगा। फिर आप परिणामों की अधिक आसानी से समीक्षा करने के लिए टेक्स्ट एडिटर या एक्सेल में सूची को कॉपी और पेस्ट कर सकते हैं।


क्या यह उप डोमेन को भी नियंत्रित करेगा?
कर्क कुयकेंडल

मुझे यकीन नहीं है कि यह उपप्रकार या उप-डोमेन नियंत्रित करेगा। मैंने पहले कभी उपप्रकार का उपयोग नहीं किया है। यदि किसी विशेष क्षेत्र को निर्दिष्ट डोमेन है, तो डोमेन नाम मुद्रित किया जाएगा।
ब्रायन

सुंदर, धन्यवाद ब्रायन। शुरू में यह मेरे लिए काम नहीं करता था, लेकिन आखिरकार मुझे याद आया कि कुछ अतिरिक्त मदद के बिना लिस्टएफसी फीचरडैटसेट में नहीं आता है ( gis.stackexchange.com/questions/5893/… )। अब सब अच्छा है! :)
मैट विल्की

@Kirk, नहीं यह डोमेन का उपयोग कर उपप्रकार नहीं देखता है।
मैट विल्की

सभी उपप्रकारों और उनके संबंधित डोमेन के माध्यम से जाने के लिए उदाहरण resource.arcgis.com/en/help/main/10.1/index.html#//… का अनुसरण करें ।
माइकल स्टिम्सन

8

चूँकि मुझे नहीं लगता कि अजगर सबटाइप संभालता है, इसलिए मुझे इस c # कोड को पोस्ट करना चाहिए। मैंने इसका परीक्षण एस्री के सैंपल वाटर / वेस्टवाटर जियोडब के साथ किया और निम्नलिखित अप्रयुक्त डोमेन पाया:

HistoryType is not used
PLSSFirstDivisionType is not used
PLSSDirection is not used
PLSSPrincipalMeridian is not used
ParcelType is not used
PLSSSpecialSurveyType is not used
CartoLineType is not used
PLSSSecondDivisionType is not used

अक्सर डीबीए उस डोमेन से नाराज हो जाते हैं - जो अनिवार्य रूप से लुकअप टेबल हैं - एसक्यूएल के माध्यम से एक्सेस नहीं किया जा सकता है।

यह कोड arcmap से परीक्षण किया गया ( मैट की टिप्पणी के अनुसार अद्यतन ):

protected override void OnClick()
{
    string fgdbPath = @"C:\projects\NetTools\InfrastructureEditingTemplate\MapsandGeodatabase\LocalGovernment.gdb";
    var dict = SummarizeDomains(fgdbPath);
    ListDomains(dict);
    // list what featureclasses use a particular domain ...
    string domName = "State_Bnd_Rules";
    if (dict.ContainsKey(domName))
    {
        if (dict[domName].Count > 0)
        {
            Debug.Print("{0} is used by these featureclasses: ", domName);
            foreach (string fcfldName in dict[domName])
            {
                Debug.Print("\t{0}", fcfldName);
            }
        }
        else
            Debug.Print("{0} is not used by any featureclasses", domName);
    }
    else
    {
        Debug.Print("Domain name not found in geodb: {0}", domName);
    }
}

private void ListDomains(Dictionary<string,List<string>> dict)
{
    foreach (KeyValuePair<string, List<string>> kvp in dict)
    {
        Debug.Print("Domain {0}",kvp.Key);
        if (kvp.Value.Count > 0)
        {
            foreach (string fcfldName in kvp.Value)
            {
                Debug.Print("\t{0}", fcfldName);
            }
        }
        else
            Debug.Print("\tUNUSED DOMAIN!");
    }
}

private Dictionary<string, List<string>> SummarizeDomains(string fgdPath)
{
    var ws = Open(fgdPath);
    var dict = InitDict(ws);

    var enumDs1 = ws.get_Datasets(esriDatasetType.esriDTAny);
    IDataset ds;
    while ((ds = enumDs1.Next()) != null)
    {
        Debug.Print("processing {0}", ds.Name);
        if (ds is IObjectClass)
            LoadDomains((IObjectClass)ds, dict);
        else if (ds is IFeatureDataset)
        {
            var enumDs2 = ds.Subsets;
            enumDs2.Reset();
            IDataset ds2;
            while ((ds2 = enumDs2.Next()) != null)
            {
                if (ds2 is IObjectClass)
                    LoadDomains((IObjectClass)ds2, dict);
            }
        }
    }
    return dict;
}
private void LoadDomains(IObjectClass oc, Dictionary<string, List<string>> dict)
{
    if (oc is ISubtypes && ((ISubtypes)oc).HasSubtype)
        LoadSubtypeDomains(oc, dict);
    else
    {
        for (int i = 0; i < oc.Fields.FieldCount; i++)
        {
            var fld = oc.Fields.get_Field(i);
            if (fld.Domain == null)
                continue;
            if (dict.ContainsKey(fld.Domain.Name))
                dict[fld.Domain.Name].Add(String.Format("{0}.{1}",((IDataset)oc).Name,fld.Name));
            else
                throw new Exception("domain not found: " + fld.Domain.Name);
        }
    }
}
private void LoadSubtypeDomains(IObjectClass oc, Dictionary<string, List<string>> dict)
{
    ISubtypes subTypes = oc as ISubtypes;
    var enumSubtypes = subTypes.Subtypes;
    enumSubtypes.Reset();
    int code;
    string stName;
    while ((stName = enumSubtypes.Next(out code)) != null)
    {
        for (int i = 0; i < oc.Fields.FieldCount; i++)
        {
            string fldName = oc.Fields.get_Field(i).Name;
            var domain = subTypes.get_Domain(code, fldName);
            if (domain != null)
            {
                if (dict.ContainsKey(domain.Name))
                    dict[domain.Name].Add(String.Format("{0}.{1}.{2}",stName,((IDataset)oc).Name,fldName));
                else
                    throw new Exception("domain not found: " + domain.Name);
            }
        }
    }
}
private Dictionary<string, List<string>> InitDict(IWorkspace ws)
{
    var dict = new Dictionary<string, List<string>>(StringComparer.InvariantCultureIgnoreCase);
    var enumDomain = ((IWorkspaceDomains)ws).Domains;
    enumDomain.Reset();
    IDomain d = null;
    while ((d = enumDomain.Next()) != null)
        dict.Add(d.Name, new List<string>());
    return dict;
}

private IWorkspace Open(string fgdbPath)
{
    Type t = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
    var wsf = Activator.CreateInstance(t) as IWorkspaceFactory;
    return wsf.OpenFromFile(fgdbPath, 0);
}

अप्रयुक्त डोमेन को सूचीबद्ध करते समय उपयोगी है, यह समस्या को हल करने का विलोम है। मैं वास्तव में "कौन सा FC डोमेन X का उपयोग कर रहा हूँ?" (इसलिए मैं लिंक को हटा सकता हूं, और डोमेन को अप्रयुक्त डोमेन बना सकता हूं )। ((मैंने अभी भी कोड की कोशिश नहीं की है, मैं सिर्फ समारोह के नाम पर जा रहा हूं))
मैट विल्की

@ ओम ओह, हाँ, यह समझ में आता है। मैंने यह दिखाने के लिए कोड बदल दिया है कि यह कैसे करना है।
कर्क कुक्केंडल

उह, शायद यह एक पूर्ण विकसित प्रश्न होना चाहिए, लेकिन, मैं यह कोड कहां रखूं? मैं VBA संपादक ( उपकरण-> मैक्रोज़-> विज़ुअल बेसिक एडिटर ) के बराबर v10 का पता नहीं लगा सकता ।
मैट विल्की

आपको Visual Studio Express (फ़्री) या उससे अधिक, और ArcGIS SDK इंस्टॉल करना होगा । एक बार जब आप ऐसा कर लेते हैं, तो आपको कमांड बटन बनाने के लिए इस वॉकथ्रू का पालन करने में सक्षम होना चाहिए , फिर मेरे कोड को क्लिक इवेंट में कॉपी और पेस्ट करें। आपको परियोजना के लिए उपयुक्त संदर्भ भी जोड़ने होंगे।
कर्क कुक्केंडल

5

इस कोड को वही वापस करना चाहिए जो पूछा जा रहा है। यह एक कार्यक्षेत्र GDB / FS में सभी फ़ीचर वर्गों और तालिकाओं को सफलतापूर्वक पार कर जाएगा और एक डोमेन, फ़ील्ड नाम और इसके साथ संबंधित फ़ीचर वर्ग / तालिका से संबंधित सभी फ़ील्ड लौटा देगा।

import os
import arcpy
lst=[]
for dirpath,dirnames,files in arcpy.da.Walk( # the path to your workspace
, datatype=["FeatureClass","Table"]):
     for file in files:
         lst.append(os.path.join(dirpath,file))
for i in lst:
     for fld in arcpy.ListFields(i):
         if fld.domain != "":
             print os.path.basename(i),fld.name, fld.domain 

4

दुर्भाग्य से ब्रायन का जवाब, जो पूछे गए सवाल का सीधा और उपयोगी जवाब है, मेरी वास्तविक समस्या को हल नहीं करता है। मैं हाथ में जीडीबी में एक बग की वजह से अनुमान लगाता हूं (भले ही किसी भी विशेषता वर्ग के डोमेन संलग्न नहीं हैं, फिर भी एक है जिसे मुझे हटाने की अनुमति नहीं है)। किसी भी मामले में मुझे यह निर्धारित करने के लिए एक और तरीका मिला है कि एफसी के संबद्ध डोमेन हैं। यह इंटरैक्टिव है, लेकिन हर एक fc पर प्रत्येक क्षेत्र की संपत्ति से गुजरने की तुलना में बहुत तेज़ है:

समस्या gdb से दूसरे gdb पर fc की ड्रैग और ड्रॉप बंच डेटा ट्रांसफर संवाद का निरीक्षण करें । लिंक किया गया विशेषता डोमेन, यदि कोई हो, सूची के निचले भाग में होगा। छोटे और छोटे गुच्छों में दोहराएं जब तक कि आप संकीर्ण न हों जो @ $% ## एफसी आपको कठिन समय दे रहा है।

अंत में एक सीवी डोमेन से जुड़े 2 एफसी तक सीमित हो गया


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

4

यह वही है जो मैं कल्पना करता हूं कि मैट विल्की को ब्रायन के कोड को बढ़ाने और देखने के लिए लिखना था। मुझे सभी डेटाबेस के रूट डायरेक्टरी में टेबल, फ़ीचर क्लासेस और सभी फ़ीचर डेटासेट में फ़ीचर प्राप्त करने थे। मैंने कुछ अन्य श्रमिकों को पुराने डोमेन के हमारे जियोडेटाबेस वातावरण को साफ करने की अनुमति देने के लिए एक csv के रूप में जानकारी का निर्यात किया।

def domainInfo(csvExportFolder):
    import arcpy,csv,os

    fcTabList = []
    list = []

    #Set workspace environment to geodatabase
    arcpy.env.workspace = r"H:\GIS\SDEConnections\Admin\Infrastructure.sde"

    #Prepping the csv
    csvFile = csv.writer(open(csvExportFolder+"\\"+ "Infrastructure Domains" + ".csv","wb"),delimiter = "|")
    csvFile.writerow(["FeatureDataSet","FeatureClass","FieldName","Domain"])

    #Get list of all features in geodatabase
    fdsList = arcpy.ListDatasets()
    fcs = arcpy.ListFeatureClasses()
    tbs = arcpy.ListTables()

    for fds in fdsList:
        fcs = arcpy.ListFeatureClasses("","",fds)
        if len(fcs) != 0:
            for fc in fcs:
                fcTabList.append([fds,fc])

    for fc in fcs:
        fcTabList.append([None,fc])

    for tb in tbs:
        fcTabList.append([None,tb])

    # Loop through all features in the database list
    for item in fcTabList:
        fds = item[0]
        fc = item[1]
        # List fields in feature class
        fields = arcpy.ListFields(fc)

        # Loop through fields
        for field in fields:

            # Check if field has domain
            if field.domain != "":

                # Print feature class, field, domain name
                csvFile.writerow([fds,fc,field.name,field.domain])

def main():
    csvExportFolder = r"H:\GIS"
    domainInfo(csvExportFolder)

if __name__ == "__main__":
    main()

0

Esri: FAQ: मैं उन सभी स्थानों को कैसे ढूँढ सकता हूँ जहाँ डोमेन को मेरे जियोडेटाबेस में संदर्भित किया गया है? "पायथन फ़ंक्शंस जो इन संरचनाओं के गुणों को एक जियोडेटाबेस में सूचीबद्ध कर सकते हैं। गुणों के बीच संदर्भित डोमेन हैं। एक नमूना स्क्रिप्ट और फ़ाइल जियोडैटेबेस प्रदान किए जाते हैं जो प्रदर्शित करते हैं कि डोमेन और फ़ीचर कक्षाओं के अन्य गुणों को सूचीबद्ध करने के लिए पायथन फ़ंक्शंस का उपयोग कैसे किया जा सकता है। तालिकाएँ। डोमेन को फ़ीचर वर्ग या तालिका में फ़ील्ड के साथ जोड़ा जा सकता है, उन्हें अतिरिक्त रूप से उप-प्रकार द्वारा वर्गीकृत फ़ील्ड के लिए सेट किया जा सकता है। "

इस प्रश्न के लिए परिणाम शोर हैं, जो डोमेन उपयोग में हैं, उससे आगे जा रहे हैं, लेकिन आरंभ करने के लिए व्यापक मंच है।

Executing: ParseDomainReferences [...]

fc at root level: Pt1
  fld OBJECTID
  fld SHAPE
  fld Field_Text, domain [Pets]
  fld Field_Long
  fld Field_Short, domain [Counts]
  fld Field_Double, domain [Ratios]
[...]
Subtype Code: 1
subCode: ('Default', False)
subCode: ('Name', u'One')
subCode: ('SubtypeField', u'Field_Long')
FieldValues
fldName: Field_Double, default: [no default], domain: Ratios
fldName: OBJECTID, default: [no default], domain: [no domain]
fldName: Field_Long, default: [no default], domain: [no domain]
fldName: Field_Short, default: 1, domain: Counts
fldName: SHAPE, default: [no default], domain: [no domain]
fldName: Field_Text, default: N, domain: [no domain]
[...etc]

कोड अंश, संक्षिप्तता के लिए संपादित:

def ParseFieldList (fc, fcPath):
...
      for fld in fldList:
        if fld.domain != None:
          if fld.domain != "":
...
        arcpy.AddMessage ("  fld " + fld.name + s)

      # get subtype list
      subDict = arcpy.da.ListSubtypes (fcPath)
      if len (subDict) > 0:
        for stCode in subDict.iteritems():
...
          valkey, vallist = stCode
          arcpy.AddMessage ("Subtype Code: {0}".format(valkey))
          i = 0
          for subCode in vallist.iteritems():
            i += 1
            if i < 4:
              arcpy.AddMessage ("subCode: {0}".format(subCode))
            else:
              fldkey, fldlist = subCode
              arcpy.AddMessage (fldkey)
              for fld in fldlist.iteritems():
...
                if dom != None:
                  s2 = dom.name
                arcpy.AddMessage ("fldName: " + fldName + ", default: " + s1 + ", domain: " + s2)
...
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.