Skip to main content
Inspiring
January 30, 2025
Answered

重複オブジェクトの整理方法について

  • January 30, 2025
  • 4 replies
  • 1424 views

巨大(オブジェクト数:数十万以上)なファイルを編集しています。

残念なことに同じアピアランスのオブジェクトがそれぞれ2重〜4重に重なっており、

また異なるオブジェクトと重なる部分もあり、それぞれ別オブジェクトとしての

保持が必要なため、パスファインダー:合体等での整理は難しいのでは?と思っています。

このままでは編集に非常に時間がかかること、また最終的な出力に支障が出る恐れがあることから、

重複オブジェクトの整理をしたいのです。

スクリプト等による整理ができれば一番良いと思うのですが、思うようなスクリプトは見つからず、

何か良い解決方法があればと思い投稿いたします。

ご教授いただけますでしょうか、何卒よろしくお願い致します。

Correct answer tkonkaz

返信頂きありがとうございました。このフォーラムや他助言等により手作業及び下記のスクリプトにてデータ量を4分の1程度(オブジェクト数約200万→50万程)まで低減できましたので御礼申し上げます。重ねてありがとうございました。

 

if (app.documents.length > 0) {
 var doc = app.activeDocument;
 var layer = doc.activeLayer; // 現在のアクティブなレイヤーを取得

 

 // レイヤー内のすべてのオブジェクトを取得
 var allItems = layer.pageItems;

 

 // オブジェクトの位置とサイズをキーにして重複をチェックするためのオブジェクト
 var uniqueObjects = {};

 

 // 重複しているオブジェクトを削除
 for (var i = allItems.length - 1; i >= 0; i--) {
  var item = allItems[i];

 

  // オブジェクトの位置とサイズをキーとして生成
  var key = item.position + "," + item.width + "," + item.height;

 

  // 同じ位置とサイズのオブジェクトが既に存在する場合は削除
  if (uniqueObjects[key]) {
   item.remove();
  } else {
   uniqueObjects[key] = item;
  }
 }
}

4 replies

tkonkazAuthorCorrect answer
Inspiring
February 8, 2025

返信頂きありがとうございました。このフォーラムや他助言等により手作業及び下記のスクリプトにてデータ量を4分の1程度(オブジェクト数約200万→50万程)まで低減できましたので御礼申し上げます。重ねてありがとうございました。

 

if (app.documents.length > 0) {
 var doc = app.activeDocument;
 var layer = doc.activeLayer; // 現在のアクティブなレイヤーを取得

 

 // レイヤー内のすべてのオブジェクトを取得
 var allItems = layer.pageItems;

 

 // オブジェクトの位置とサイズをキーにして重複をチェックするためのオブジェクト
 var uniqueObjects = {};

 

 // 重複しているオブジェクトを削除
 for (var i = allItems.length - 1; i >= 0; i--) {
  var item = allItems[i];

 

  // オブジェクトの位置とサイズをキーとして生成
  var key = item.position + "," + item.width + "," + item.height;

 

  // 同じ位置とサイズのオブジェクトが既に存在する場合は削除
  if (uniqueObjects[key]) {
   item.remove();
  } else {
   uniqueObjects[key] = item;
  }
 }
}

Legend
February 5, 2025

CADデータの処理ですよね?

その旨はっきり書いた方が、回答を得られやすいかと思います。あれはかなり特殊なデータですから

tkonkazAuthor
Inspiring
February 6, 2025

ご記入ありがとうございます。そうですね、ご指摘の通り伺う際にもう少し詳しく掛けたら回答が得られやすかったと思います、申し訳ありません。今更ですが、編集をしていたのはPDF形式で頂いた地図のような背景データです。これが重すぎで前景の編集が出来ない状態で、ご指摘の通り多分CAD等からの出力とは思うのですが気付かず伺った次第です。現在CADの分かる方に重複を削除してもらったデータがあるので、取り込み試す所です。他には重複オブジェクトを減らすスクリプトも検索の結果見つかったのですが、実行してみると上記でご指摘頂いたように思うような動作になりません。なかなか難しいですね。

Legend
February 9, 2025

そういうのだと、地理関連のデータ(GIS?)かもしれないですね。

あれのデータも癖が強すぎで、単純見た目な場合は自分で生成しなおした方がマシかもしれないです

Inspiring
January 31, 2025

有料プラグインになりますが、地理情報開発社製のPlugX-Search+という製品のObjectSearch+の機能でアピアランスの差異も検出する同一オブジェクトの一括選択ができます。

https://www.adobe.com/jp/information/creativecloud/illustrator-plugin.html#kensaku

adobeのページでも紹介があります(リンクが切れてますが…)

(オブジェクト数:数十万以上)ということで手作業は現実的では無いかもしれませんが、重なったものを全選択して一番前面のもの以外削除くらいはできるので、地道に片付けるのであればこういったものも検討していただけるかもしれませんね。

tkonkazAuthor
Inspiring
February 3, 2025

返信ありがとうございます、助かります。また確認が遅くなり申し訳ありません。Plug-XシリーズについてはShapeを導入していますが、Search+は知らなかったので興味深いです。このままちびちびと作業をするぐらいなら数万円の出費も全然大丈夫です。ただ先程取説にて手順を確認してみましたが、「同一オブジェクトの一括選択」は分かるのですが、その後の「一番手前のもの以外削除」の手順がどうも分かりません。もしご存じでしたら追記で教授お願い出来ればと思いますがいかがでしょうか。

何卒よろしくお願いいたします。

Inspiring
February 3, 2025

誤解を招く表記をしており申し訳ございませんでした。
[重なっているオブジェクトを全選択→一番上のオブジェクトをグループ選択ツールでマウスクリック→キーボードのdeleteキー]で後ろのオブジェクトだけを消せる。
という特に捻りもない手作業を思い浮かべて回答させていただいていました。

 

スクリプトを使うのであれば、

if (app.documents.length > 0) {
    var doc = app.activeDocument;
    if (doc.selection.length > 1) {
        var selectedItems = [];
        for (var i = 0; i < doc.selection.length; i++) {
            selectedItems.push(doc.selection[i]);
        }
        var topItem = selectedItems[0];
            for (var i = 1; i < selectedItems.length; i++) {
                //最背面でzOrderPositionが無いオブジェクトは例外処理で避ける
                try {
                    if (selectedItems[i].zOrderPosition > topItem.zOrderPosition) {
                        topItem = selectedItems[i];
                    }
                } catch (e) {
                }
            }
        for (var i = 0; i < selectedItems.length; i++) {
            if (selectedItems[i] !== topItem) {
                selectedItems[i].remove();
            }
        }
    }
}

といったところでしょうか。
※上記スクリプトは【レイヤーを跨いだ重なりは比較しておらず、同一レイヤー内の重なりの比較で最前面を検出して最前面以外を削除】なのでご注意ください。

 

スクリプトをキーボードショートカット等に登録すれば、一手減らせるとは思いますが凄い解決方法を思いついているわけではなく申し訳ないです。

Ten A
Community Expert
Community Expert
January 30, 2025

スクリプトとかはアピアランスを認識できないのでアピアランスでオブジェクトを構成している場合は手立てがありません。
基本的形状のジオメトリが完全に一致するかどうかなら判断は可能ですが、形状と塗り及び線の設定が一致するぐらいなら書けるかもしれません。しかしながら、この手のはデータを見ながら調整しないと意図した挙動にすり合わせるのは困難です。
手作業である程度整理したうえでラスターに落とし、必要な部分を切り抜いたりするなどで逃げるのが落とし所な気もします。

tkonkazAuthor
Inspiring
January 30, 2025

早速の返信ありがとうございます、助かります。

なるほど、アピアランスでオブジェクトを構成している場合、スクリプトでの整理は難しいのですね。

また、塗りおよび線の設定が一致するオブジェクトであってもそんな簡単には行かないとのこと、承知しました。こちらでは一度CAD経由で解決出来ないか試してみます。

Illustrator内での方法についてはもう少し募集させてください。

Ten A
Community Expert
Community Expert
January 30, 2025

他の形式に書き出すととアピアランスの類はラスターに落ちちゃいますね。ラスターに落ちてもいいのであればIllustrator上でおとしてしまえば良い訳で、あまりメリットは無い様に思います。

基本的にアピアランスが絡んでる場合はIllustrator上で完結させる必要があるでしょう。