Как я могу автоматически сгруппировать каждую фигуру с текстом внутри для огромной коллекции прямоугольников?

У меня есть .dwgкарта (файл AutoCad), полная полей (прямоугольников), которыми я манипулирую с помощью Illustrator. Внутри каждого прямоугольника есть текст, указывающий его номер. Проблема в том, что между прямоугольником и его номером нет связи, и это то, что я пытаюсь сделать. Также порядок или рисунок не тот, когда я проверяю слои.

Есть ли способ с Illustrator, который может сгруппировать каждый прямоугольник с текстом внутри него, и это для всех полей? Вручную можно, но невозможно для каждого отдельного поля: около 40 000 прямоугольников.

Я предполагаю, что подход должен иметь какое-то отношение к «близости», поскольку это единственные данные, которые говорят нам о соответствии между прямоугольником и его номером.

Какова конечная цель группировки прямоугольника по его номеру? Возможно, есть и другой способ добиться того, чего вы хотите в конце концов.
Есть ли способ использовать AutoCad для экспорта файла в более удобный формат? Когда мне сталкивались с подобными вещами в прошлом (после нескольких минут плача в ванной), мне было проще воссоздать рисунок с нуля в Illustrator (хотя мне никогда не приходилось что-то делать). с таким количеством элементов).
После комментария @Voxwoman: не могли бы вы экспортировать его в виде .svgфайла? Тогда возможно решение сценария, которое помещает прямоугольные и текстовые объекты с ближайшими координатами x, y в g-элемент , по существу, группируя их.
Illustrator может открывать исходный формат DWG, что означает, что он может читать блоки, внешние ссылки, формы и объекты. Таким образом, вы можете сохранить свой DWG и сгруппировать прямоугольники с блоками и внешними ссылками и проверить, каким образом их можно импортировать в иллюстратор.
Это простая задача, если она создана в Illustrator. Однако при импорте какого-либо другого файла нет ничего простого в том, что вам нужно.
Всем спасибо. Вот дополнительная информация: @Bart, конечная цель - получить число, ссылающееся на прямоугольник, чтобы в приложении я мог ввести число для отображения соответствующего прямоугольника. Voxwoman: вы правы, но в данном случае это невозможно, потому что координаты каждого прямоугольника реальны и очень точны: я думаю, невозможно перерисовать всю карту. Я экспортировал файл в .svg. У меня есть код XML. Я считаю, что решение для сценариев возможно, как упомянул Барт, но мне было интересно, может ли быть более простой/быстрый способ через Illustrator. Спасибо за вашу помощь!!

Ответы (1)

Есть плагин, который поможет вам в этом. Вы можете получить его здесь: http://www.wundes.com/JS4AI/index.php

Загрузите « GroupOverlappingObjects.js » в папку сценариев Illustrator. На ПК должно быть примерно так:

"C:\Program Files\Adobe\Illustrator CS\Presets\Scripts"

или Mac

"/Applications/Adobe Illustrator CC 2015/Presets/en_US/Scripts"

Откройте/перезагрузите Illustrator и выберите все объекты, которые вы хотите сгруппировать. Затем перейдите к:

Файл > Скрипты > GroupOverlappingObjects

Должно появиться диалоговое окно, чтобы сообщить вам, сколько групп было создано. Установка флажка слоев должна показать ваши недавно сгруппированные элементы.

Я тестировал это в Illustrator CC 2015.

Содержимое javascript (29.07.2015):

/////////////////////////////////////////////////////////////////
//Group Overlapping (Beta) -- CS, CS2, CS3
//>=--------------------------------------
//
//  Groups all overlapping objects in selection into discreet groups.
//  The definition for 'overlaping' is based on objects bounding boxes, not their actual geometry.
//  Each new groups zOrder is determined by the depth of the front-most object in each group.
//  There is no limit to the number of groups created.
//  Any non-overlapping objects are ignored.
//
// Note: Currently, this is not very efficient code. It works well on small groups (less than 120 objects)
// and works faster on smaller groupings. Running this on a huge number of objects will likely crash illustrator.
// It serves my purposes, but test it's limits on your machine, and use at your own risk. 
// On a 2.53GHz P4, a group of 100 objects took 20 seconds with 2 groups.
//  
//
//>=--------------------------------------
// JS code (c) copyright: John Wundes ( john@wundes.com ) www.wundes.com
//copyright full text here:  http://www.wundes.com/js4ai/copyright.txt
////////////////////////////////////////////////////////////////// 

//this little section is just for testing
//the number of times each function is called.
var testmode = 0;
var t1=t2=t3=t4=t5=t6=t7=0;
var testmsg="";
//
//
//
var go=true;
if(selection.length>120){
go = confirm("You have selected "+selection.length+" objects. It is highly recommended that you select less than 120 objects at a time. Do you want to continue anyway?");

}
if(selection.length>1 && go == true){
    var groups=0;
    var slen = selection.length;
    var hitList= new Array(slen);
    var groupArr = new Array(slen);
    // for each element in selection
    for (var sx=0;sx<slen;sx++){ 
    //t6++; //---------------------------------------------loop tracker
        var tArr = new Array(0);
            // for each element in selection (again)
        for (var si=0;si<slen;si++){
            //t7++; //-------------------------------------loop tracker
            groupArr[sx] = tArr;
            //note each object hits itself once.
            if(hitTest(selection[sx],selection[si])){
                    groupArr[sx].push(selection[si]);
            }
        }
    } 

minimize(groupArr);
var zError = 0;
var gaLen = groupArr.length;
for(var each=0;each<gaLen;each++){
    if(groupArr[each].length>1){
        groupArr[each].sort(sortBy_zOrder);
    }
if(zError==1){
    alert("cannot read some objects zOrderPosition");
}
//alert("halftime");
for(var each =0;each<gaLen;each++){ 
    t1++; //----------------------------------------------loop tracker
    if(groupArr[each].length>1){
        groups++;
    groupAll(groupArr[each]);
    }
}
//
//---all done with main code, now display statistics if you care...
//

testmsg="\nObjects processed: "+t1+"\nObjects grouped: "+t2+"\nObjects ignored: "+(t1-t2);

if(testmode==1){
testmsg+="\n\n---testmode data---\nhits compared: "+t5+"\nfunction 'minimize' called: "+t3+
"\nitems tested within 'minimize': "+t4;
"\nelements: "+t6+
"\nelements*elements: "+t7;
}

var x=0;

while(x<selection.length){

    if(selection[x].name == "wundes_GO_group"){
         selection[x].name = "";
    }else{
        selection[x].selected = false;
          x--;
    }
    x++;
}
redraw();
alert(groups+" groups created.\n----------------"+testmsg);
}


}
//----------------------------------------------------------->
//--------------------------------functions------------------<
//----------------------------------------------------------->
function sortBy_zOrder(a, b) {
        if(a.zOrderPosition==undefined){
            alert(a.zOrderPosition);
            zError = 1;
             return 0;
        }
        var x = Number(a.zOrderPosition);
        var y = Number(b.zOrderPosition);


return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}

function groupAll(arr){
    var tempGroup = arr[0].parent.groupItems.add();

    tempGroup.move(arr[0],ElementPlacement.PLACEBEFORE);
    var max = arr.length;
    for(var i=max-1;i>=0;i--){
        t2++; //-----------------------------------------loop tracker
        arr[i].move(tempGroup,ElementPlacement.INSIDE);
    }
        //name the object for selection at end... (will be removed later)
        tempGroup.name = "wundes_GO_group";
        tempGroup.selected = true;

}
//---------------hitTest functions ---------------
function hitTest(a,b){
    var OK=0;
    if(isWithinX(a,b) || isWithinX(b,a)){
        OK++;   
    }
    if(isWithinY(a,b) || isWithinY(b,a)){
        OK++;
    }
    if (OK<2){
        //alert("miss.");
        return false;
    }else{
        //alert("Hit!")
            return true;
    }
}
function isWithinX(a,b){
    var p1 = a.geometricBounds[0];
    var p2 = b.geometricBounds[0];
    if(p2<=p1 && p1<=p2+b.width){
         return true;
    }else{
        return false;
    } 
}
function isWithinY(a,b){
    var p3 = a.geometricBounds[1];
    var p4 = b.geometricBounds[1];
    if(p3>=p4 && p4>=(p3-a.height)){
        return true;
    } 
        return false;
}

/*
//-----------------------------------OK, finding groups is done, now do the grouping---------------
*/

function itemize(a){
 var out="";
 return(a.join("\n"));
}
function minimize(arr){
for(var e in arr){
    t3++; //-----------------------------------------loop tracker
    for (ot in arr){
        t4++; //-------------------------------------loop tracker
        if(arr[e]!=arr[ot]){
        //if it's not THIS element,
        //test for overlaps
        if(overlaps(arr[e],arr[ot])){
            merge(arr[e],arr[ot]);
            arr[e] = new Array(0);
            minimize(arr);
            break;
        }
        }
    }
}

}
function merge(a,b){
    var alen = a.length;
    for (var all=0;all<alen;all++){
        if(contains(b,a[all])){
            //do nothing
        }else{

         b.push(a[all]);

        }
    }

}
function contains(ar,i){
    for (var all in ar){
        if (ar[all] == i){
            return true;
        }
    }
return false;
}


function overlaps(ar1,ar2){
    for (var each in ar1){
        t5++; //------------------------------------loop tracker
        if(contains(ar2,ar1[each])){//
            return true;
        }
    }
return false;
}