নতুন অ-ওভারল্যাপিং বহুভুজগুলিতে ওভারল্যাপিং বিস্ফোরিত হচ্ছে?


10

একাধিক বহুভিত্তিক প্রদত্ত যে একাধিক উপায়ে ওভারল্যাপ করে, আমি এই বৈশিষ্ট্যগুলি থেকে সমস্ত বহুভুজগুলি পুনরুক্তি করে অন্যের সাথে ওভারল্যাপ না করে এমন সমস্ত বহিরাগত রফতানি করতে চাই।

পণ্যটি এমন অনেকগুলি বৈশিষ্ট্য হবে যাতে কোনও ওভারল্যাপ থাকে না, যখন একত্রে সংমিশ্রণ করা হয়, মূলটি তৈরি হয়।

পণ্যগুলি তখন জোনাল স্ট্যাটিস্টিকসে ইনপুট হিসাবে ব্যবহার করা যেতে পারে এবং প্রতিটি বহুভুজের উপর জোনাল স্ট্যাটিস্টিকগুলি পুনরাবৃত্তি করার চেয়ে এটি আরও দ্রুত হবে।

আমি সাফল্য ছাড়াই এটি আরকেপিতে কোড করার চেষ্টা করছি।

এটি করার কোডটি কি ইতিমধ্যে বিদ্যমান?


আপনি কী বোঝাতে চাইছেন যে আপনি ডেটা টপোলজিক্যালি সঠিক সেটে সেট করতে চান?
নাগ্যিচেক

@ জিওস্ট জোনালস্ট্যাটসকে বহুভুজগুলির প্রয়োজন যা ওভারল্যাপ হয় না। আপনার যখন একটি ওভারল্যাপিং সংগ্রহ রয়েছে, তখন স্পষ্টতই কিন্তু অদক্ষ সমাধান হ'ল পলিগুলির উপর লুপ করুন এবং একের পর এক জোনাল পরিসংখ্যান গণনা করুন। নন-ওভারল্যাপিং পলির একটি উপসেট নির্বাচন করা, তাদের ক্ষেত্রে জোনালস্ট্যাট প্রয়োগ করা এবং পুনরাবৃত্তি করা আরও দক্ষ। প্রশ্নটি জিজ্ঞাসা করে যে কীভাবে এই জাতীয় নির্বাচনগুলি দক্ষতার সাথে করা যায়।
whuber

হুবহু - আমি মনে করি যে @ জিওজিস্ট ইনপুট বহুভুজগুলির ছেদগুলি থেকে নন-ওভারল্যাপিং বহুভুজগুলির একটি সেট তৈরি করার পরামর্শ দিচ্ছে। এই চিত্রটি দেখুন - (মন্তব্যগুলিতে ছবি পোস্ট করতে পারবেন না?) ইনপুটটি বাম দিকে রয়েছে। পুরো অঞ্চলটি তিনটি বহুভুজ দ্বারা আচ্ছাদিত, যার প্রতিটি একে অপরকে উভয়কে ছেদ করে। একমাত্র অ-ওভারল্যাপিং সাবসেটগুলি হ'ল সিঙ্গেলন এবং এগুলি ইউনিয়ন স্থান পূরণ করার গোটানুকির প্রয়োজনীয়তা পূরণ করে না। আমি মনে করি Geoist অধিকার যা zonalstats জন্য বৈধ নন-ছেদ অঞ্চলে সেট তৈরি পরামর্শ হয়
Llaves

আমি মনে করি চূড়ান্ত পণ্যটি কী হওয়া উচিত তা নিয়ে কিছু বিভ্রান্তি রয়েছে। আপনি একটি উদাহরণ দিতে পারেন? আমার ব্যাখ্যাটি হ'ল আপনি চাইবেন যে আউটপুটটি বহুভুজগুলির একটি নির্বাচন হতে পারে যা ওভারল্যাপ হয় না - যখন বাকী বহুভুজগুলি ছাড়ায় বা দ্রবীভূত করে। আপনি কি এক বা একাধিক বৈশিষ্ট্যযুক্ত ক্লাস নিয়ে কাজ করছেন?
হারুন

1
আমার কাছে শোনার মতো @ গোটানুকি ন্যূনতম সংখ্যক বৈশিষ্ট্য শ্রেণি তৈরি করতে চাইছে যেখানে কেবল
বহুভুজযুক্ত

উত্তর:


14

এটি একটি গ্রাফ রঙিন সমস্যা

মনে রাখবেন যে কোনও গ্রাফের বর্ণমালা কোনও গ্রাফের শীর্ষে এমন একটি রঙের असाइनমেন্ট হয় যাতে কোনও প্রান্ত ভাগ করে নেওয়ার কোনও দুটি উল্লম্বের রঙও একই রকম থাকে না। বিশেষত, গ্রাফের (বিমূর্ত) অনুভূমিকাগুলি বহুভুজ। যখনই দুটি ছেদ করা হয় তখন একটি (পুনর্নির্দেশিত) প্রান্তের সাথে সংযুক্ত থাকে (বহুভুজ হিসাবে)। যদি আমরা সমস্যার কোনও সমাধান গ্রহণ করি - যা বহুভুজগুলির সংগ্রহকে বিচ্ছিন্ন করে (বলুন কে ) একটি ক্রম - এবং ক্রমটিতে প্রতিটি সংকলনের জন্য একটি অনন্য রঙ নির্ধারণ করে, তবে আমরা গ্রাফের একটি কে- কালারিং পেয়েছি । এটি একটি ছোট কে পাওয়া বাঞ্চনীয়

এই সমস্যাটি বেশ শক্ত এবং যথেচ্ছ গ্রাফগুলির জন্য অমীমাংসিত থেকে যায়। কোডের পক্ষে সহজ এমন একটি আনুমানিক সমাধান বিবেচনা করুন। একটি ক্রমিক অ্যালগরিদম করা উচিত। ওয়েলশ-পাওয়েল অ্যালগরিদম হল একটি লোভী সমাধান যা ডিগ্রি দ্বারা শীর্ষে অবস্থিত ক্রমের উপর ভিত্তি করে। মূল বহুভুজগুলির ভাষায় অনুবাদিত, বহুভুজগুলি প্রথমে ওভারল্যাপ করা অন্যান্য বহুভুজের সংখ্যার ক্রমবর্ধমান ক্রমে বাছাই করুন। ক্রমে কাজ করে, প্রথম বহুভুজটিকে প্রাথমিক রঙ দিন। একটি রং যে পছন্দ করে, হয় যে: প্রত্যেক ক্রমানুযায়ী পদক্ষেপে, একটি বিদ্যমান রঙ দিয়ে পরবর্তী বহুভুজ রঙ চেষ্টা নাইতিমধ্যে যে বহুভুজ প্রতিবেশী যে কোনও দ্বারা ব্যবহৃত। (উপলভ্য রঙগুলির মধ্যে বেছে নেওয়ার অনেকগুলি উপায় রয়েছে; যা সর্বনিম্ন ব্যবহৃত হয়েছে এমনটি চেষ্টা করুন বা অন্যথায় এলোমেলোভাবে বেছে নিন)) পরবর্তী বহুভুজটি যদি বিদ্যমান রঙের সাথে রঙিন না হতে পারে তবে একটি নতুন রঙ তৈরি করুন এবং এটির সাথে এটি রঙ করুন।

একবার আপনি অল্প সংখ্যক রঙের সাথে রঙিনতা অর্জন করার পরে, রঙ অনুসারে জোনালস্ট্যাটগুলি রঙ করুন: নির্মানের মাধ্যমে, আপনি গ্যারান্টিযুক্ত যে প্রদত্ত রঙের ওভারল্যাপের কোনও দুটি বহুভুজ নয়।


এখানে নমুনা কোড ইন R। (পাইথন কোডটি খুব বেশি আলাদা হবে না)) প্রথমে, আমরা দেখানো সাতটি বহুভুজগুলির মধ্যে ওভারল্যাপগুলি বর্ণনা করি।

সাতটি বহুভুজের মানচিত্র

edges <- matrix(c(1,2, 2,3, 3,4, 4,5, 5,1, 2,6, 4,6, 4,7, 5,7, 1,7), ncol=2, byrow=TRUE)

অর্থাৎ বহুভুজ 1 এবং 2 ওভারল্যাপ করে এবং তাই বহুভুজ 2 এবং 3, 3 এবং 4, ..., 1 এবং 7 করে।

অবতরণ ডিগ্রি দ্বারা শীর্ষে বাছাই করুন:

vertices <- unique(as.vector(edges))
neighbors <- function(i) union(edges[edges[, 1]==i,2], edges[edges[, 2]==i,1])
nbrhoods <- sapply(vertices, neighbors)
degrees <- sapply(nbrhoods, length)
v <- vertices[rev(order(degrees))]

এ (ক্রুড) সিক্যুয়াল কালারিং অ্যালগরিদম প্রাথমিকতম উপলভ্য রঙ ব্যবহার করে যা ইতিমধ্যে কোনও ওভারল্যাপিং বহুভুজ দ্বারা ব্যবহৃত হয়নি:

color <- function(i) {
  n <- neighbors(i)
  candidate <- min(setdiff(1:color.next, colors[n]))
  if (candidate==color.next) color.next <<- color.next+1
  colors[i] <<- candidate
}

ডেটা স্ট্রাকচার ( colorsএবং color.next) আরম্ভ করুন এবং অ্যালগরিদম প্রয়োগ করুন:

colors <- rep(0, length(vertices))
color.next <- 1
temp <- sapply(v, color)

বহুভুজগুলি রঙ অনুসারে গ্রুপগুলিতে বিভক্ত করুন:

split(vertices, colors)

এই উদাহরণে আউটপুট চারটি রঙ ব্যবহার করে:

$`1`
[1] 2 4

$`2`
[1] 3 6 7

$`3`
[1] 5

$`4`
[1] 1

বহুভুজ চার বর্ণের

এটি বহুভুজকে চারটি নন-ওভারল্যাপিং গ্রুপে বিভক্ত করেছে। এক্ষেত্রে সমাধানটি সর্বোত্তম নয় (graph 6 3,6,5 {, {2,4}, 7 1,7} graph এই গ্রাফের জন্য একটি তিনটি রঙিন)। সাধারণভাবে সমাধানটি খুব খারাপ হওয়া উচিত নয়, যদিও।


আমি নিশ্চিত নই যে এটি প্রশ্নের উত্তর দেয় কিনা, বা প্রশ্নটি কী, তবে এটি একটি ভাল উত্তর কম নয়।
নাগেইটেক

@ জিওজিস্টের কি কোনও উপায় আছে যা আমি চিত্রটিকে আরও পরিষ্কার করে বলতে পারি বা সমস্যাটি আরও ভালভাবে ব্যাখ্যা করতে পারি?
whuber

6

#Wuber দ্বারা প্রস্তাবিত পদ্ধতিটি আমাকে নতুন দিকনির্দেশনা নিতে অনুপ্রাণিত করেছিল এবং এখানে দুটি ফাংশনে আমার আরকি সমাধান রয়েছে। প্রথমটি, কাউন্টোভারল্যাপস নামে পরিচিত, প্রতিটি পলি যা ওভারল্যাপ করে এবং এটিতে কতটি ওভারল্যাপ ঘটেছিল তার জন্য রেকর্ড করতে দুটি ক্ষেত্র তৈরি করে "ওভারল্যাপস" এবং "ওভালপ্যাক্ট"। দ্বিতীয় ফাংশন, এক্সপ্লোডওভারল্যাপস, একটি তৃতীয় ক্ষেত্র তৈরি করে, "এক্সপাল", যা নন-ওভারল্যাপিং পলির প্রতিটি গ্রুপকে একটি অনন্য পূর্ণসংখ্যা দেয়। ব্যবহারকারী এই ক্ষেত্রের উপর ভিত্তি করে নতুন এফসি রফতানি করতে পারেন। প্রক্রিয়াটি দুটি ফাংশনে বিভক্ত হয়ে গেছে কারণ আমার মনে হয় কাউন্টওভারল্যাপস সরঞ্জাম নিজেই কার্যকর প্রমাণ করতে পারে। কোডটি (এবং অযত্নে নামকরণের কনভেনশন) এর opালুতাটিকে ক্ষমা করুন, কারণ এটি বেশ প্রাথমিক বিষয়, তবে এটি কার্যকর হয়। "আইডনাম" নিশ্চিত করুন ক্ষেত্রটি অনন্য আইডি সহ একটি ক্ষেত্র উপস্থাপন করে (কেবলমাত্র পূর্ণসংখ্যার আইডি দিয়ে পরীক্ষা করা হয়)। এই সমস্যার সাথে যোগাযোগের জন্য প্রয়োজনীয় কাঠামোটি আমাকে সরবরাহ করার জন্য হুবুহু ধন্যবাদ!

def countOverlaps(fc,idName):
    intersect = arcpy.Intersect_analysis(fc,'intersect')
    findID = arcpy.FindIdentical_management(intersect,"explFindID","Shape")
    arcpy.MakeFeatureLayer_management(intersect,"intlyr")
    arcpy.AddJoin_management("intlyr",arcpy.Describe("intlyr").OIDfieldName,findID,"IN_FID","KEEP_ALL")
    segIDs = {}
    featseqName = "explFindID.FEAT_SEQ"
    idNewName = "intersect."+idName

    for row in arcpy.SearchCursor("intlyr"):
        idVal = row.getValue(idNewName)
        featseqVal = row.getValue(featseqName)
        segIDs[featseqVal] = []
    for row in arcpy.SearchCursor("intlyr"):
        idVal = row.getValue(idNewName)
        featseqVal = row.getValue(featseqName)
        segIDs[featseqVal].append(idVal)

    segIDs2 = {}
    for row in arcpy.SearchCursor("intlyr"):
        idVal = row.getValue(idNewName)
        segIDs2[idVal] = []

    for x,y in segIDs.iteritems():
        for segID in y:
            segIDs2[segID].extend([k for k in y if k != segID])

    for x,y in segIDs2.iteritems():
        segIDs2[x] = list(set(y))

    arcpy.RemoveJoin_management("intlyr",arcpy.Describe(findID).name)

    if 'overlaps' not in [k.name for k in arcpy.ListFields(fc)]:
        arcpy.AddField_management(fc,'overlaps',"TEXT")
    if 'ovlpCount' not in [k.name for k in arcpy.ListFields(fc)]:
        arcpy.AddField_management(fc,'ovlpCount',"SHORT")

    urows = arcpy.UpdateCursor(fc)
    for urow in urows:
        idVal = urow.getValue(idName)
        if segIDs2.get(idVal):
            urow.overlaps = str(segIDs2[idVal]).strip('[]')
            urow.ovlpCount = len(segIDs2[idVal])
        urows.updateRow(urow)

def explodeOverlaps(fc,idName):

    countOverlaps(fc,idName)

    arcpy.AddField_management(fc,'expl',"SHORT")

    urows = arcpy.UpdateCursor(fc,'"overlaps" IS NULL')
    for urow in urows:
        urow.expl = 1
        urows.updateRow(urow)

    i=1
    lyr = arcpy.MakeFeatureLayer_management(fc)
    while int(arcpy.GetCount_management(arcpy.SelectLayerByAttribute_management(lyr,"NEW_SELECTION",'"expl" IS NULL')).getOutput(0)) > 0:
        ovList=[]
        urows = arcpy.UpdateCursor(fc,'"expl" IS NULL','','','ovlpCount D')
        for urow in urows:
            ovVal = urow.overlaps
            idVal = urow.getValue(idName)
            intList = ovVal.replace(' ','').split(',')
            for x in intList:
                intList[intList.index(x)] = int(x)
            if idVal not in ovList:
                urow.expl = i
            urows.updateRow(urow)
            ovList.extend(intList)
        i+=1

2
এটি আমার সমাধানের সাথে সংযুক্ত করতে: আপনার আমার কোডের countOverlapsদুটি লাইনের nbrhoods <- sapply(vertices, neighbors); degrees <- sapply(nbrhoods, length)সাথে degreesমিল : এটি ওভারল্যাপ গণনা। অবশ্যই আপনার কোডটি দীর্ঘতর কারণ এটি আমার জিআইএস বিশ্লেষণের বেশিরভাগ প্রতিবিম্ব প্রতিফলিত করে যা আমার সমাধানে মঞ্জুর করা হয়েছে: যথা, আপনি প্রথমে কোন বহুভুজকে ওভারল্যাপ করে তা সনাক্ত করেন এবং শেষে আপনি বহুভুজ ডেটাসেটগুলি আউটপুট দেওয়ার সমাধানটি ব্যবহার করেন। গ্রাফ-তাত্ত্বিক গণনাগুলিকে
সজ্জিত করা

1

এটি কিছুক্ষণ হয়ে গেছে, তবে আমি এই কোডটি নিজের প্রয়োগের জন্য ব্যবহার করেছি এবং এটি দুর্দান্ত কাজ করছে - আপনাকে ধন্যবাদ। আমি এটির আপডেট করার জন্য এটির কিছু অংশ পুনরায় লিখেছি, লাইনে এটি প্রয়োগ করেছি (সহনশীলতার সাথে) এবং এটিকে উল্লেখযোগ্যভাবে গতি বাড়িয়ে তুলি (নীচে - আমি এটি 50 মিলিয়ন ছেদযুক্ত বাফারে চালাচ্ছি এবং এটি কয়েক ঘন্টা সময় নেয়)।

def ExplodeOverlappingLines(fc, tolerance, keep=True):
        print('Buffering lines...')
        idName = "ORIG_FID"
        fcbuf = arcpy.Buffer_analysis(fc, fc+'buf', tolerance, line_side='FULL', line_end_type='FLAT')
        print('Intersecting buffers...')
        intersect = arcpy.Intersect_analysis(fcbuf,'intersect')

        print('Creating dictionary of overlaps...')
        #Find identical shapes and put them together in a dictionary, unique shapes will only have one value
        segIDs = defaultdict(list)
        with arcpy.da.SearchCursor(intersect, ['Shape@WKT', idName]) as cursor:
            x=0
            for row in cursor:
                if x%100000 == 0:
                    print('Processed {} records for duplicate shapes...'.format(x))
                segIDs[row[0]].append(row[1])
                x+=1

        #Build dictionary of all buffers overlapping each buffer
        segIDs2 = defaultdict(list)
        for v in segIDs.values():
            for segID in v:
                segIDs2[segID].extend([k for k in v if k != segID and k not in segIDs2[segID]])

        print('Assigning lines to non-overlapping sets...')
        grpdict = {}
        # Mark all non-overlapping one to group 1
        for row in arcpy.da.SearchCursor(fcbuf, [idName]):
            if row[0] in segIDs2:
                grpdict[row[0]] = None
            else:
                grpdict[row[0]] = 1

        segIDs2sort = sorted(segIDs2.items(), key=lambda x: (len(x[1]), x[0])) #Sort dictionary by number of overlapping features then by keys
        i = 2
        while None in grpdict.values(): #As long as there remain features not assigned to a group
            print(i)
            ovset = set()  # list of all features overlapping features within current group
            s_update = ovset.update
            for rec in segIDs2sort:
                if grpdict[rec[0]] is None: #If feature has not been assigned a group
                    if rec[0] not in ovset: #If does not overlap with a feature in that group
                        grpdict[rec[0]] = i  # Assign current group to feature
                        s_update(rec[1])  # Add all overlapping feature to ovList
            i += 1 #Iterate to the next group

        print('Writing out results to "expl" field in...'.format(fc))
        arcpy.AddField_management(fc, 'expl', "SHORT")
        with arcpy.da.UpdateCursor(fc,
                                   [arcpy.Describe(fc).OIDfieldName, 'expl']) as cursor:
            for row in cursor:
                if row[0] in grpdict:
                    row[1] = grpdict[row[0]]
                    cursor.updateRow(row)

        if keep == False:
            print('Deleting intermediate outputs...')
            for fc in ['intersect', "explFindID"]:
                arcpy.Delete_management(fc)

-3

এই ক্ষেত্রে আমি সাধারণত নিম্নলিখিত পদ্ধতিটি ব্যবহার করি:

  • একটি ইউনিয়নের মাধ্যমে ফিচার ক্লাসটি পাস করুন; (এটি তার সমস্ত ছেদগুলিতে বহুভুজকে ভেঙে ফেলে)
  • এক্স, ওয়াই এবং এরিয়া ক্ষেত্র যুক্ত করুন এবং তাদের গণনা করুন;
  • এক্স, ওয়াই, এরিয়া ক্ষেত্র দ্বারা ফলাফল দ্রবীভূত করুন।

আমি বিশ্বাস করি যে ফলাফলটি আপনি চেয়েছিলেন তা হবে এবং আপনি এমনকি ওভারল্যাপের সংখ্যাও গণনা করতে পারেন। পারফরম্যান্সের দিক থেকে এটি আপনার পক্ষে ভাল কি না তা জানেন না।


2
এই পদ্ধতিটি আপনাকে পছন্দসই পণ্যটিতে পৌঁছে না, যা সংক্ষিপ্ততর সিরিজ নির্বাচন বা মূলটির অনন্য বৈশিষ্ট্য শ্রেণীর যা ওভারল্যাপ হয় না। পণ্যগুলি আঞ্চলিক পরিসংখ্যানগুলিতে খাওয়ানো হবে এবং সুতরাং প্রতিটি বৈশিষ্ট্যের মূল জ্যামিতিটি রাখা জরুরী।
ndimhypervol

আপনি ঠিক বলেছেন, দুঃখিত। প্রশ্নটা আমি ভাল করে বুঝতে পারিনি। সেক্ষেত্রে এবং রাস্টার আকারের উপর নির্ভর করে আমি রাস্টারটিকে সাধারণত একটি অস্থায়ী বিন্দুর বৈশিষ্ট্য শ্রেণিতে (প্রতিটি ঘর একটি বিন্দু) রূপান্তর করতে এবং তার এবং বহুভুস্তরের স্তরটির মধ্যে একটি স্থানিক সংযুক্তি সম্পাদন করব। হতে পারে এটি খুব সরল, এবং পারফরম্যান্স বন্ধুত্বপূর্ণ পদ্ধতির তবে কাজ করে এবং ওভারল্যাপযুক্ত বহুভুজ আপনাকে কোনও সমস্যা দেয় না।
আলেকজান্দ্রে নেটো

আপনি যদি এই স্থানিক যোগদানের অর্থ কী তা যদি সঠিকভাবে বুঝতে পারি তবে আপনার দ্বিতীয় সমাধানটি এখনও কাজ করবে না, আলেকজান্দ্রে, কারণ পয়েন্টগুলি এবং বহুভুজের মধ্যে বহু-বহু-সম্পর্ক রয়েছে। নির্বিশেষে, যে কোনও বৃহদায়তন রাস্টারদের জন্য এই ভেক্টর-ভিত্তিক পদ্ধতিটি অত্যন্ত অদক্ষ এবং বড় রাস্টারদের পক্ষে এটি চালানো অসম্ভব হবে।
whuber

@ হুবুয়ার আপনি খুব ধীর প্রক্রিয়া সম্পর্কে ঠিক বলেছেন (দ্বিদ্বৈপ ২.৮ গিগাহার্টজ, ভিসার সাথে থ্রিজিবি র‌্যামে অর্ধ ঘণ্টা আমাকে ৪২৪৮ এক্স 3009 রাস্টার এবং ২৪০১ বহুভুজ দিয়ে আমাকে টোকা দিন)। তবে এটি কাজ করে, যেমন আমি এটি ইতিমধ্যে পরীক্ষা করেছি। স্পেশাল জয়েন্টে আপনাকে একের সাথে একটি সম্পর্ক ব্যবহার করতে হবে এবং রাস্টার মানগুলি (যেমন, সম, ইত্যাদি ...) একত্রিত করতে হবে। ফলাফলটি আসলটির অনুরূপ ভেক্টর বহুভুজ স্তর হবে তবে একত্রিত রাস্টার মানগুলির সাথে একটি নতুন কলাম রয়েছে যা প্রতিটি বহুভুজকে ছেদ করে। অনুকূল সমাধান না হওয়ায় এটি কম প্রোগ্রামিং দক্ষতার সাথে কারও পক্ষে কার্যকর হতে পারে (আমার মতো :-))।
আলেকজান্দ্রি নেট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.