DXF図面をJavaプログラムにむンポヌトし、この「単玔な」圢匏のすべおの熊手を螏む

AutoCADおよび類䌌のCADシステムは、蚭蚈の分野で長い間暙準になっおおり、広く䜿甚されおいるDWG / DXFファむル圢匏が同じ暙準になったこずは驚くこずではありたせん。 そのため、建築家やデザむナヌ向けの䜕らかの゜リュヌションを開発しおいる堎合、これらの圢匏たたは少なくずも1぀の圢匏で䜜業できるこずは、補品の必須機胜です。







私のWebサヌビスの䞀郚ずしお、 歩行者の動きをシミュレヌトするために 、これらの圢匏のマスタヌプランをむンポヌトするこずも心配しなければなりたせんでした。 私は以前にCADずビゞネスをしおいなかったので、「そこに䜕があるのか​​、考えおみおください-図面、線、倚角圢の別の圢匏、そこで䜕が耇雑になるのでしょうか」 しかし、その過皋で、そこには十分な耇雑さがあり、いく぀かのニュアンスは数䞖玀の深さから䌞びる叀代の束葉杖に非垞に䌌おいたすが、倚くのこずは圢匏自䜓の仕様に実際には文曞化されおいたせんたずえば、ブロックや曲線での䜜業。 どうやら、それらはどの補図工にずっおも明らかであるず考えられおいたすが、別の分野から来お、そのような知識がない堎合はどうですか



䞀般的に、カットの䞋には、グヌグルで怜玢できなかったレヌキず解決策のリストがあり、真倜䞭たでに図面を採掘する必芁がありたした。





解決すべき課題



Javaアプリケヌションでは、地区マスタヌプランのむンポヌトを構成し、それを内郚の単玔化されたGeoJSON衚珟に倉換する必芁がありたした。 同時に、完党な情報やあらゆる皮類の゚ンティティは必芁ありたせんでした。シミュレヌションで䜿甚されるのはそれらの䞀郚のみです。 そのため、この資料では、DXFのすべおの機胜ず重芁な技術゜リュヌションを網矅しおいるわけではありたせん。 そしお、なぜDWGではなくDXFなのか そしお、それに぀いお以䞋。



フォヌマット遞択



それでは、䞻に「AutoCAD」および「ファむル圢匏」ずいう蚀葉に関連付けられおいるものは䜕ですか そしお、これはDWGです。 もずもずAutoDeskによっお䜜成されたバむナリクロヌズ圢匏ずその仕様は公開されおいたせんでしたが、䞀時はOpen Design Allianceによっお元に戻されたした。

そしお、倱望の1぀目は次のずおりです。この圢匏の珟圚の無料実装はありたせん。 䞀般的に。

AutoDeskからそれを操䜜するためのラむブラリがありたす。 ODAによっお䜜成された人気のあるTeighaラむブラリがありたす。 そしお...それだけです。 䞡方ずも支払われおおり、十分に支払われおいたす私たちは数癟および数千ドルに぀いお話しおいたす。 ふさわしくない。

無料のオヌプン゜ヌス゜リュヌションずしお暙準を実装しようずする詊みがいく぀かありたす。 たずえば、 jdwglibです。 しかし、それらはすべお5〜10幎前に最埌に曎新され、長い間死んでいたす。 そしお、進歩はただ止たっおおらず、AutoCADの新しいバヌゞョンはDWGに新しい機胜を远加したす。その結果、最新バヌゞョンのファむルを読むずいう倢ず、修正されたバグのサポヌトず垌望に別れを告げるこずができたす。



代替手段はDXFです。 人気はやや劣りたすが、同時にすべおのCADシステムでサポヌトされおおり、圓初はオヌプンであるため、理論的にはより䞀般的です。

最初にラむブラリを怜玢するのもがっかりしたす-特にJavaでは、5幎前の最新リリヌス、捚おられたリポゞトリ、氞遠を芋る悲しいニュヌス、䞍圓な楜芳䞻矩ず玄束に満ちた単䞀のラむブプロゞェクトはありたせん。 ただし、DWGずは異なり、フォヌマット自䜓はそれほど積極的に開発されおいないため、かなり叀いラむブラリでも最新の図面を開くこずができたす。



その結果、Kabejaラむブラリが遞択され、その最埌のリリヌスは2011幎でした。 付属のサンプルDXFからSVGぞの倉換を䜿甚しお、珟圚のすべおの図面ファむルが正しく開くこずを確認し、その埌むンポヌトを開始したした。 StackoverflowのCADの第䞀人者からのDXFの解析に関する質問に぀いお、「DXFはシンプルに芋えたすが、実際には䜜業にうんざりしおいる」ずいうコメントが少しありたした。



レむダヌ



DXF図面には、䞀連のレむダヌレむダヌずブロックブロックが含たれおいたす。 そこには他の゚ンティティがありたすが、最も単玔な堎合にゞオメトリの座暙を匕き裂くために、それらは必芁ありたせん。







レむダヌのすべおは明らかで、Photoshopの堎合ず同じように機胜したす。 レむダヌのオンずオフを切り替えたり、レむダヌのデフォルトのグラフィックスパラメヌタヌを蚭定したりできたす぀たり、たずえば、このレむダヌのデフォルトではすべおの線にそのような倪さを蚭定できたす。 私のタスクは座暙を絞るだけなので、衚瀺の問題には察凊したせんでした。



さお、すべおがシンプルに思えたす。各レむダヌに぀いお、レむダヌのリストを実行したす。オブゞェクトのリストを䜿甚しお、座暙を倉換したす。 ただし、すでにここで最初のレヌキを螏んでいたす。CADに衚瀺され、ファむルに含たれおいる䞀連のレむダヌは同じものではありたせん 。 突然道路の䞀郚を倱った理由を頭を痛めた。 それらはNanoCADにありたすが、私の゚クスポヌトにはありたせん。 デバッガヌに入りたした-Kabejaが返す構造䜓にもありたせん。 ただし、サンプルずずもにファむル党䜓を゚クスポヌトする堎合はそうです。 䞀般に、ファむル内の゚ディタヌの1぀のレむダヌは、「layerName」、「layerName @ 1」などの名前を持぀耇数のレむダヌで衚すこずができるこずが刀明したした。 なぜこれが行われ、どこから来たのか-悪魔はそれを知っおいたすが、事実-レむダヌの名前ず完党に䞀臎するものを怜玢するラむブラリコヌド構造でさえ、名前キヌでMapにレむダヌを保存するこずを瀺唆したすヒント。



ブロック



ブロックは、䞀床描画するず耇数回挿入できるテンプレヌトです。 この堎合、ベヌスナニットを倉曎するず、すべおの挿入が倉曎されたす。 䟿利に。 さらにクヌルなのは、ブロックに耇数のレむダヌのオブゞェクトを含めるこずができるこずです。 この堎合、挿入はいく぀かのレむダヌにも属したす。 この堎合、ブロックには他のブロックの挿入が含たれる堎合がありたす。 ぀たり、「ハりスセクション」ブロックを䜜成し、それらから「ハりス」ブロックを䜜成しお、カヌドに数回挿入するこずができたす。 この堎合、最終オブゞェクトには、元のブロックだけでなく、いく぀かのレむダヌ個別の塗り぀ぶし、個別の茪郭、個別の特殊マヌクが含たれたす。 これらはすべおナヌザヌの芳点から芋るず非垞にクヌルですが、プログラマヌに䜜業が远加されたす。

さらに、ブロックは1回だけでなく、長方圢のマトリックスの圢で繰り返し挿入できたす。 これを行うために、挿入オブゞェクトには、行数、列数、およびそれらの間の距離を持぀パラメヌタヌがありたす。



その結果、これたでの挿入凊理コヌドは次のようになりたす。



for (int row = 0; row < insert.getRows(); ++row) { for (int col = 0; col < insert.getColumns(); ++col) { //                 ,    . AffineTransform transform = new AffineTransform(); transform.translate( insert.getPoint().getX() - (insert.getColumns() - col) * insert.getColumnSpacing() , insert.getPoint().getY() - (insert.getRows() - row) * insert.getRowSpacing()); transform.rotate(Math.toRadians(insert.getRotate())); transform.scale(insert.getScaleX(), insert.getScaleY()); // Feature    ,    GeoJSON  for (Feature f : block.features) { //   ,  .         Feature inserted = cloneFeatureWithTransform(f, transform); features.add(inserted); } } } return block.features.size();
      
      







ファむル内のブロックずレむダヌが順序付けられおいないこずを知るこずも重芁です。 ぀たり、凊理ブロックは、ただ凊理されおいない別のブロックからの挿入で぀たずくこずがありたす。 正盎なずころ、私はそれがなんずかサむクルを䜜るこずができるかどうか、そしおその堎合に䜕が起こるかわかりたせん。



行



私の仕事は、DXFをGeoJSONに倉換するこずです。すべおのタむプのゞオメトリは、砎線ず倚角圢のみを認識し、円匧ず曲線は認識したせん。



DXFは、さたざたな回線オプションをサポヌトしおいたす。



  1. すでに2皮類の砎線-ポリラむンずLWPolyline。 私の単玔な2D図面の堎合、それらの間に違いはありたせん
  2. 円匧、さらには楕円ず円圢の2぀のタむプ。 幞いなこずに、Kabejaクラスには既にそれらのポむントの座暙を取埗するための既補のメ゜ッドがあるため、必芁な粟床でアヌクをポリラむンに倉換するこずは難しくありたせん
  3. スプラむン-繰り返したすが、カベゞャ自身はポリラむンに倉換する方法を知っおいたす
  4. ちょうど線圢セグメント




すべおがシンプルに思えたすが、違いたす。 䞀芋単玔なポリラむンタむプでも、2次曲線を衚瀺するために䜿甚できたす砎線だけでなく。 これを行うには、頂点をbulgeに蚭定できたす。 それが瀺されおいる堎合、2぀の頂点は盎線ではなく、これらの頂点を通過する円の円匧で接続され、その䞭心はそれらずこのパラメヌタヌで衚珟できたす。







これは、円の䞭心を特定できるコヌドです。

 private Point getCenterByVerticesAndBulge(DXFVertex a, DXFVertex b, double bulge) { double norm = Math.sqrt(Math.pow(b.getX() - a.getX(), 2) + Math.pow(b.getY() - a.getY(), 2)); double s = norm / 2; double d = s * (1 - bulge * bulge) / (bulge * bulge); // "direction" double u = (b.getX() - a.getX()) / norm; double v = (b.getY() - a.getY()) / norm; //"center" double c1 = Math.signum(bulge) * -v * d + (a.getX() + b.getX()) / 2; double c2 = Math.signum(bulge) * u * d + (a.getY() + b.getY()) / 2; return new Point(c1, c2, 0); }
      
      







私は長い間これらの匧をめぐっお戊いたしたが、最終的に私は吐き出し、それらをオフにしお、頂点を盎接接続したした。 䞀般的な蚈画では、このような円匧は通垞、亀差点の角を䞞くするために䜿甚されるため、それらを完党にスコアリングするこずができたす-シミュレヌションの芳点からの違いはわずかです。



塗り぀ぶし/ハッチハッチ



これは私のシミュレヌタが盎接動䜜するものです。 ずりあえず、私は建物、道路、発電機を詰め物で正確に指定するこずを芁求したすそうでなければ、個々の線のミッシュマッシュのどこが内偎で、どこが倖偎であるかは明確ではありたせん。



そしお、ここにもニュアンスがありたす

  1. 塗り぀ぶしの境界線は、線オブゞェクトの任意の組み合わせにするこずができたす。 境界線の䞀郚を壊しおから、いく぀かの匧を描いおから、さたざたな線分だけのセグメントを壊すこずができたす
  2. 1぀の塗り぀ぶしオブゞェクトには、任意の数の切り離された領域ポリゎンに倖郚境界が1぀しかない他の倚くの圢匏ずは異なりたすを含めるこずができたす。
  3. 塗り぀ぶしは繰り返しネストするこずができたす。぀たり、穎塗り぀ぶしの䞭に別の塗り぀ぶしがあり、そこに再び穎があり、DXFのすべおは耇数の境界を持぀1぀のHATCHオブゞェクトによっお指定されたす。
  4. 塗り぀ぶしずその境界の関係にはさらに゚キゟチックなオプションがありたす写真を参照が、これたでのずころ私には出䌚っおいない、神に感謝








䞀般に、塗り぀ぶし甚のDXFから「倖郚たたは内郚」フラグが付いた䞀連の境界線を取埗し、それらが䞀般的にどのように䜜成され、GeoJSONのようなポリゎンに沿っおそれらを分散する方法を理解する必芁がありたす。ネストがありたす。



私はいく぀かの方法で行きたしたが、各アルゎリズムに぀いお、このアルゎリズムが機胜しない図面をすぐに入手したした。 たずえば、これはここにありたすチタの䜏宅地の道路ず私道の図、それらはすべお文字通り非垞に耇雑な構造を持぀HATCHオブゞェクトのペアによっお定矩され、䜕らかの理由ですべおの境界が倖郚ずしおマヌクされおいたすカベゞャには䜕らかのバグがあるず感じおいたすDXFが倖郚ず倖郚の2぀の同様のフラグをすぐに定矩する方法ですが、ラむブラリ自䜓には1぀しかありたせん







その結果、動䜜する唯䞀のアルゎリズムは次のようになりたす。

  1. 倖偎の境界線ごずにポリゎンを䜜成したす
  2. 倖郚たたは内郚のどちらでマヌクされおいるかに関係なく、他のすべおの境界を枛算したす
  3. 考えられる問題を修正したすポリゎンが空であるこずが刀明した、穎が倖偎の茪郭の境界を越えお行く、ポリゎンが切断された領域にクラッシュするなど




3番目のポむントおよび実際に既にシミュレヌションアルゎリズム自䜓の内郚にあるゞオメトリを操䜜するためでは、JTSラむブラリであるJava Topology Suiteを䜿甚したした。 これには、バッファの構築などの操䜜から四分朚などのデヌタ構造たで、ゞオメトリを操䜜するために必芁なすべおのプリミティブず操䜜が非垞に倚く含たれおいたす。



勝利



束葉杖でできるこずすべおを苊劎しお支えた埌、必芁なDXFサブセットのサポヌトを䜜成し、図面をシミュレヌタに盎接ロヌドしお、デザむナヌの孊校を決定するために䜿甚できたした。 私は䞊蚘の情報のほずんどを戊いで2晩たでNanoCADの䞊に座らなければならなかったため広告ではありたせんが、これは私が芋぀けた唯䞀の簡単にアクセスできる無料で高品質のDXF゚ディタヌであるため、同じLibreCADは最初の図面を正しく開くこずができたせんでした圌に匕き枡されたした、私もそれをhabrasocietyず共有するこずにしたした-突然私の経隓のすべおが誰かの時間を節玄したす。



ええ、はい、䞊蚘のスクリヌンショットからの領域のアルゎリズムの予枬のようなものです







明らかな結論は、正しい角床でトラックを䜜成する必芁はないが、必芁のない奇劙な曲線を䜜成しようずする必芁はないずいうこずです。 この地域が建蚭されたずきに私の予枬が実珟するかどうか、数幎埌に芋おみたしょう。



提䟛された地区蚈画に぀いおは、包括的な建築および建蚭蚭蚈ワヌクショップのおかげで



All Articles