방향관리를 노드 정보에 추가

This commit is contained in:
backuppc
2026-01-15 16:16:41 +09:00
parent 82592e117d
commit 64ff2ecfb9
4 changed files with 496 additions and 21 deletions

View File

@@ -69,6 +69,13 @@ namespace AGVMapEditor.Forms
this.allTurnLeftRightCrossOnToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.allTurnLeftRightCrossOnToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.tabPage2 = new System.Windows.Forms.TabPage(); this.tabPage2 = new System.Windows.Forms.TabPage();
this.lstMagnetDirection = new System.Windows.Forms.ListBox(); this.lstMagnetDirection = new System.Windows.Forms.ListBox();
this.toolStrip4 = new System.Windows.Forms.ToolStrip();
this.btDirDelete = new System.Windows.Forms.ToolStripButton();
this.btMakeDirdata = new System.Windows.Forms.ToolStripButton();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.statusStrip1.SuspendLayout(); this.statusStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel1.SuspendLayout();
@@ -81,6 +88,8 @@ namespace AGVMapEditor.Forms
this.toolStrip3.SuspendLayout(); this.toolStrip3.SuspendLayout();
this.toolStrip2.SuspendLayout(); this.toolStrip2.SuspendLayout();
this.tabPage2.SuspendLayout(); this.tabPage2.SuspendLayout();
this.toolStrip4.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
// statusStrip1 // statusStrip1
@@ -451,6 +460,8 @@ namespace AGVMapEditor.Forms
// tabPage2 // tabPage2
// //
this.tabPage2.Controls.Add(this.lstMagnetDirection); this.tabPage2.Controls.Add(this.lstMagnetDirection);
this.tabPage2.Controls.Add(this.tableLayoutPanel1);
this.tabPage2.Controls.Add(this.toolStrip4);
this.tabPage2.Location = new System.Drawing.Point(4, 22); this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2"; this.tabPage2.Name = "tabPage2";
this.tabPage2.Size = new System.Drawing.Size(292, 309); this.tabPage2.Size = new System.Drawing.Size(292, 309);
@@ -463,11 +474,92 @@ namespace AGVMapEditor.Forms
this.lstMagnetDirection.Dock = System.Windows.Forms.DockStyle.Fill; this.lstMagnetDirection.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstMagnetDirection.FormattingEnabled = true; this.lstMagnetDirection.FormattingEnabled = true;
this.lstMagnetDirection.ItemHeight = 12; this.lstMagnetDirection.ItemHeight = 12;
this.lstMagnetDirection.Location = new System.Drawing.Point(0, 0); this.lstMagnetDirection.Location = new System.Drawing.Point(0, 25);
this.lstMagnetDirection.Name = "lstMagnetDirection"; this.lstMagnetDirection.Name = "lstMagnetDirection";
this.lstMagnetDirection.Size = new System.Drawing.Size(292, 309); this.lstMagnetDirection.Size = new System.Drawing.Size(292, 246);
this.lstMagnetDirection.TabIndex = 3; this.lstMagnetDirection.TabIndex = 3;
// //
// toolStrip4
//
this.toolStrip4.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.btDirDelete,
this.btMakeDirdata});
this.toolStrip4.Location = new System.Drawing.Point(0, 0);
this.toolStrip4.Name = "toolStrip4";
this.toolStrip4.Size = new System.Drawing.Size(292, 25);
this.toolStrip4.TabIndex = 5;
this.toolStrip4.Text = "toolStrip4";
//
// btDirDelete
//
this.btDirDelete.Image = ((System.Drawing.Image)(resources.GetObject("btDirDelete.Image")));
this.btDirDelete.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btDirDelete.Name = "btDirDelete";
this.btDirDelete.Size = new System.Drawing.Size(61, 22);
this.btDirDelete.Text = "Delete";
this.btDirDelete.Click += new System.EventHandler(this.btDirDelete_Click);
//
// btMakeDirdata
//
this.btMakeDirdata.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.btMakeDirdata.Image = ((System.Drawing.Image)(resources.GetObject("btMakeDirdata.Image")));
this.btMakeDirdata.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btMakeDirdata.Name = "btMakeDirdata";
this.btMakeDirdata.Size = new System.Drawing.Size(69, 22);
this.btMakeDirdata.Text = "Remake";
this.btMakeDirdata.Click += new System.EventHandler(this.toolStripButton3_Click);
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 3;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel1.Controls.Add(this.button1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.button2, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.button3, 2, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 271);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 1;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(292, 38);
this.tableLayoutPanel1.TabIndex = 6;
//
// button1
//
this.button1.Dock = System.Windows.Forms.DockStyle.Fill;
this.button1.Location = new System.Drawing.Point(3, 3);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(91, 32);
this.button1.TabIndex = 0;
this.button1.Text = "Left";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Dock = System.Windows.Forms.DockStyle.Fill;
this.button2.Location = new System.Drawing.Point(100, 3);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(91, 32);
this.button2.TabIndex = 0;
this.button2.Text = "Straight";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Dock = System.Windows.Forms.DockStyle.Fill;
this.button3.Location = new System.Drawing.Point(197, 3);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(92, 32);
this.button3.TabIndex = 0;
this.button3.Text = "Right";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// MainForm // MainForm
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
@@ -500,6 +592,10 @@ namespace AGVMapEditor.Forms
this.toolStrip2.ResumeLayout(false); this.toolStrip2.ResumeLayout(false);
this.toolStrip2.PerformLayout(); this.toolStrip2.PerformLayout();
this.tabPage2.ResumeLayout(false); this.tabPage2.ResumeLayout(false);
this.tabPage2.PerformLayout();
this.toolStrip4.ResumeLayout(false);
this.toolStrip4.PerformLayout();
this.tableLayoutPanel1.ResumeLayout(false);
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
@@ -547,5 +643,12 @@ namespace AGVMapEditor.Forms
private System.Windows.Forms.ToolStripMenuItem allTurnLeftRightCrossOnToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem allTurnLeftRightCrossOnToolStripMenuItem;
private System.Windows.Forms.TabPage tabPage2; private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.ListBox lstMagnetDirection; private System.Windows.Forms.ListBox lstMagnetDirection;
private System.Windows.Forms.ToolStrip toolStrip4;
private System.Windows.Forms.ToolStripButton btDirDelete;
private System.Windows.Forms.ToolStripButton btMakeDirdata;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
} }
} }

View File

@@ -10,6 +10,7 @@ using AGVNavigationCore.Models;
using MapImage = AGVNavigationCore.Models.MapImage; using MapImage = AGVNavigationCore.Models.MapImage;
using MapLabel = AGVNavigationCore.Models.MapLabel; using MapLabel = AGVNavigationCore.Models.MapLabel;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.ComponentModel;
namespace AGVMapEditor.Forms namespace AGVMapEditor.Forms
{ {
@@ -43,8 +44,8 @@ namespace AGVMapEditor.Forms
public override string ToString() public override string ToString()
{ {
// RFID가 있으면 RFID(노드이름), 없으면 NodeID(노드이름) 형태로 표시 // RFID가 있으면 RFID(노드이름), 없으면 NodeID(노드이름) 형태로 표시
string fromDisplay = FromRfidId > 0 string fromDisplay = FromRfidId > 0
? $"{FromRfidId:0000}(*{FromNodeId.PadLeft(4,'0')})" ? $"{FromRfidId:0000}(*{FromNodeId.PadLeft(4, '0')})"
: $"(*{FromNodeId})"; : $"(*{FromNodeId})";
string toDisplay = ToRfidId > 0 string toDisplay = ToRfidId > 0
@@ -58,6 +59,7 @@ namespace AGVMapEditor.Forms
} }
#endregion #endregion
#region Constructor #region Constructor
@@ -981,6 +983,9 @@ namespace AGVMapEditor.Forms
// 이미지 노드인 경우 편집 버튼 활성화 // 이미지 노드인 경우 편집 버튼 활성화
UpdateImageEditButton(); UpdateImageEditButton();
// 마그넷 방향 리스트 업데이트
RefreshMagnetDirectionList();
} }
/// <summary> /// <summary>
@@ -996,6 +1001,7 @@ namespace AGVMapEditor.Forms
{ {
_propertyGrid.SelectedObject = null; _propertyGrid.SelectedObject = null;
DisableImageEditButton(); DisableImageEditButton();
lstMagnetDirection.DataSource = null;
} }
/// <summary> /// <summary>
@@ -1101,6 +1107,13 @@ namespace AGVMapEditor.Forms
// 변경된 속성명 디버그 출력 // 변경된 속성명 디버그 출력
System.Diagnostics.Debug.WriteLine($"[PropertyGrid] 속성 변경됨: {e.ChangedItem.PropertyDescriptor.Name}"); System.Diagnostics.Debug.WriteLine($"[PropertyGrid] 속성 변경됨: {e.ChangedItem.PropertyDescriptor.Name}");
// 🔥 MagnetDirectionInfo 변경 처리
if (_propertyGrid.SelectedObject is MagnetDirectionInfo magInfo)
{
ApplyDirectionChange(magInfo);
return;
}
// RFID 값 변경시 중복 검사 // RFID 값 변경시 중복 검사
if (e.ChangedItem.PropertyDescriptor.Name == "RFID") if (e.ChangedItem.PropertyDescriptor.Name == "RFID")
{ {
@@ -1308,5 +1321,323 @@ namespace AGVMapEditor.Forms
UpdateStatusBar($"모든 노드의 회전/교차 속성 활성화 완료"); UpdateStatusBar($"모든 노드의 회전/교차 속성 활성화 완료");
} }
} }
/// <summary>
/// 마그넷 방향 정보를 표현하는 클래스
/// </summary>
public class MagnetDirectionInfo
{
[JsonIgnore, Browsable(false)]
public MapNode FromNode { get; set; }
[JsonIgnore, Browsable(false)]
public MapNode ToNode { get; set; }
[Category("연결 정보")]
[DisplayName("출발 노드")]
[Description("출발 노드의 ID입니다.")]
[ReadOnly(true)]
public string FromNodeId => FromNode?.ID2 ?? "Unknown";
[Category("연결 정보")]
[DisplayName("도착 노드")]
[Description("도착 노드의 ID입니다.")]
[ReadOnly(true)]
public string ToNodeId => ToNode?.ID2 ?? "Unknown";
[Category("설정")]
[DisplayName("방향")]
[Description("이동할 마그넷 방향입니다.")]
public MagnetPosition? Direction { get; set; }
public override string ToString()
{
string dirStr = Direction.HasValue ? Direction.Value.ToString() : "None";
string fromStr = FromNode != null ? FromNode.ID2 : "Unknown";
string toStr = ToNode != null ? ToNode.ID2 : "Unknown";
return $"{fromStr} -> {toStr} : {dirStr}";
}
}
private void RefreshMagnetDirectionList()
{
// 현재 선택된 항목 기억
int selectedIndex = lstMagnetDirection.SelectedIndex;
// 데이터 소스 초기화 (UI 갱신 강제)
lstMagnetDirection.DataSource = null;
lstMagnetDirection.Items.Clear();
if (this._mapCanvas.Nodes == null) return;
var directions = new List<MagnetDirectionInfo>();
// 모든 노드 검색
foreach (var nodeItem in this._mapCanvas.Nodes)
{
if (nodeItem is MapNode node)
{
if (node.MagnetDirections != null && node.MagnetDirections.Count > 0)
{
foreach (var kvp in node.MagnetDirections)
{
var neighborId = kvp.Key;
var dir = kvp.Value;
var neighbor = this._mapCanvas.Nodes.FirstOrDefault(t => t.Id == neighborId);
directions.Add(new MagnetDirectionInfo
{
FromNode = node,
ToNode = neighbor,
Direction = dir
});
}
}
}
}
// 보기 좋게 정렬 (FromNode ID 순)
directions.Sort((a, b) => string.Compare(a.FromNode.Id, b.FromNode.Id));
if (directions.Count > 0)
{
lstMagnetDirection.DataSource = directions;
}
// 이벤트 연결
lstMagnetDirection.SelectedIndexChanged -= LstMagnetDirection_SelectedIndexChanged;
lstMagnetDirection.SelectedIndexChanged += LstMagnetDirection_SelectedIndexChanged;
lstMagnetDirection.DoubleClick -= LstMagnetDirection_DoubleClick;
lstMagnetDirection.DoubleClick += LstMagnetDirection_DoubleClick;
// 선택 항목 복원 (가능한 경우) -> 선택된 객체가 다르게 생성되므로 인덱스로 복원 시도
if (selectedIndex >= 0 && selectedIndex < lstMagnetDirection.Items.Count)
{
lstMagnetDirection.SelectedIndex = selectedIndex;
}
}
private void LstMagnetDirection_SelectedIndexChanged(object sender, EventArgs e)
{
if (lstMagnetDirection.SelectedItem is MagnetDirectionInfo info)
{
// 버튼 상태 업데이트
UpdateDirectionButtons(info);
}
}
private void LstMagnetDirection_DoubleClick(object sender, EventArgs e)
{
if (lstMagnetDirection.SelectedItem is MagnetDirectionInfo info)
{
var node = info.FromNode;
if (node != null)
{
// 방향 순환
if (info.Direction == MagnetPosition.S) info.Direction = MagnetPosition.L;
else if (info.Direction == MagnetPosition.L) info.Direction = MagnetPosition.R;
else if (info.Direction == MagnetPosition.R) info.Direction = MagnetPosition.S;
ApplyDirectionChange(info);
}
}
}
private void ApplyDirectionChange(MagnetDirectionInfo info)
{
var node = info.FromNode;
if (node == null) return;
// 딕셔너리 업데이트
if (node.MagnetDirections == null)
node.MagnetDirections = new Dictionary<string, MagnetPosition>();
if (info.ToNode != null)
{
if (info.Direction == null)
{
if (node.MagnetDirections.ContainsKey(info.ToNode.Id))
node.MagnetDirections.Remove(info.ToNode.Id);
}
else
{
node.MagnetDirections[info.ToNode.Id] = info.Direction.Value;
}
_hasChanges = true;
UpdateTitle();
// 리스트 갱신
RefreshMagnetDirectionList();
// 캔버스 등 갱신
_mapCanvas.Invalidate();
// 속성창 갱신 (선택된 객체가 바뀌었을 수 있으므로 다시 설정은 RefreshMagnetDirectionList의 선택 복원에서 처리됨)
_propertyGrid.Refresh();
}
}
private void btMakeDirdata_Click(object sender, EventArgs e)
{
}
private void toolStripButton3_Click(object sender, EventArgs e)
{
if (this._mapCanvas.Nodes == null || this._mapCanvas.Nodes.Count == 0)
return;
// 기존 목록을 모두 지울지 물어보고
var result = MessageBox.Show(
"기존 설정된 마그넷 방향 정보를 모두 초기화하시겠습니까?\n'예'를 선택하면 모든 방향 정보가 삭제된 후 재설정됩니다.\n'아니오'를 선택하면 기존 정보는 유지되고 없는 부분만 추가됩니다.",
"마그넷 방향 자동 생성",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question);
if (result == DialogResult.Cancel)
return;
bool clearAll = (result == DialogResult.Yes);
int updateCount = 0;
foreach (var node in this._mapCanvas.Nodes)
{
// 연결 노드가 3개 이상인 노드들을 찾아서
if (node.Type == NodeType.Normal && node is MapNode mapNode)
{
if (clearAll)
{
if (mapNode.MagnetDirections != null)
mapNode.MagnetDirections.Clear();
else mapNode.MagnetDirections = new Dictionary<string, MagnetPosition>();
}
if (mapNode.ConnectedNodes.Count >= 3)
{
// 마그넷 방향 딕셔너리가 없으면 생성
if (mapNode.MagnetDirections == null)
mapNode.MagnetDirections = new Dictionary<string, MagnetPosition>();
foreach (var connectedId in mapNode.ConnectedNodes)
{
// 이미 설정된 경우 건너뜀 (모두 초기화 안 한 경우)
if (!clearAll && mapNode.MagnetDirections.ContainsKey(connectedId))
continue;
// 모두 자동 생성을 해준다 (기본은 직진으로)
mapNode.MagnetDirections[connectedId] = MagnetPosition.S;
updateCount++;
}
}
}
}
if (updateCount > 0)
{
_hasChanges = true;
UpdateTitle();
// 현재 선택된 노드의 속성창 및 리스트 갱신
UpdateNodeProperties();
MessageBox.Show($"총 {updateCount}개의 연결에 대해 마그넷 방향(직진)이 설정되었습니다.", "완료", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("변경된 사항이 없습니다.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void btDirDelete_Click(object sender, EventArgs e)
{
if (lstMagnetDirection.SelectedItem is MagnetDirectionInfo info)
{
// 선택된 방향정보를 삭제한다.
var result = MessageBox.Show(
$"선택한 마그넷 방향 정보를 삭제하시겠습니까?\n{info.FromNodeId} -> {info.ToNodeId} : {info.Direction}",
"삭제 확인",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
if (info.FromNode != null && info.FromNode.MagnetDirections != null)
{
if (info.ToNode != null && info.FromNode.MagnetDirections.ContainsKey(info.ToNode.Id))
{
info.FromNode.MagnetDirections.Remove(info.ToNode.Id);
_hasChanges = true;
UpdateTitle();
// 리스트 및 UI 갱신
RefreshMagnetDirectionList();
// 캔버스 갱신
_mapCanvas.Invalidate();
}
}
}
}
else
{
MessageBox.Show("삭제할 항목을 선택해주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void button1_Click(object sender, EventArgs e)
{
//set left
if (lstMagnetDirection.SelectedItem is MagnetDirectionInfo info)
{
info.Direction = MagnetPosition.L;
ApplyDirectionChange(info);
UpdateDirectionButtons(info);
}
}
private void button2_Click(object sender, EventArgs e)
{
//set straight
if (lstMagnetDirection.SelectedItem is MagnetDirectionInfo info)
{
info.Direction = MagnetPosition.S;
ApplyDirectionChange(info);
UpdateDirectionButtons(info);
}
}
private void button3_Click(object sender, EventArgs e)
{
//set right
if (lstMagnetDirection.SelectedItem is MagnetDirectionInfo info)
{
info.Direction = MagnetPosition.R;
ApplyDirectionChange(info);
UpdateDirectionButtons(info);
}
}
private void UpdateDirectionButtons(MagnetDirectionInfo info)
{
button1.BackColor = SystemColors.Control;
button2.BackColor = SystemColors.Control;
button3.BackColor = SystemColors.Control;
if (info.Direction == MagnetPosition.L) button1.BackColor = Color.Lime;
else if (info.Direction == MagnetPosition.S) button2.BackColor = Color.Lime;
else if (info.Direction == MagnetPosition.R) button3.BackColor = Color.Lime;
}
} }
} }

View File

@@ -123,6 +123,15 @@
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>249, 17</value> <value>249, 17</value>
</metadata> </metadata>
<metadata name="toolStrip4.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 56</value>
</metadata>
<metadata name="toolStrip3.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>462, 17</value>
</metadata>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>249, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="btNodeRemove.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="btNodeRemove.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
@@ -139,9 +148,6 @@
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value> </value>
</data> </data>
<metadata name="toolStrip3.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>462, 17</value>
</metadata>
<data name="btnSelect.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="btnSelect.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
@@ -169,6 +175,20 @@
YIGDKaeH7rEGFFd1IN1M4c5nAYIcIXLXvmW+uOKfXMvpRO9rFnzJi9lqBKPZYVCedzYsH6SQ2l+Eu2SD YIGDKaeH7rEGFFd1IN1M4c5nAYIcIXLXvmW+uOKfXMvpRO9rFnzJi9lqBKPZYVCedzYsH6SQ2l+Eu2SD
bfNyWeHqqhbxahSCGIM2MwSKrYzDWboBx5sxIsP6yvTPH0lk3YoGI9lhaB8NQZO+gl8Dj7SN1tpAvgAA bfNyWeHqqhbxahSCGIM2MwSKrYzDWboBx5sxIsP6yvTPH0lk3YoGI9lhaB8NQZO+gl8Dj7SN1tpAvgAA
AABJRU5ErkJggg== AABJRU5ErkJggg==
</value>
</data>
<data name="btnAddNode.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHdSURBVDhPnZLra9NgFMb3T/hV8b8YFP+efZE5RL+qQxEV
dN6+OXfBTynNZtYmbeKSxfSS1pDSNq29UEpJW9tSULT6lvXCI+8LicTpij4QQs45z+85kLNSqVRQLpdR
KpVQLBZRKBSQz+dh2zZ9X1hZJsdxsFgszjzdbpdBDMM4H0KTqcF1XZbcbrd9CK1ZlnU+hK5Mh2ka/c7l
cvZ4PMZsNmN1CjRN8+8QmuoNplKp03Q67U4mEwy/dPDeOWS9VquFZDL5ZwhN9laez+eg5tHXT3ga3cDD
gzXozgHrNZtN6LoOSZKCEMuyyGg0YkPT6RSDzx1sRa/h1btb2NXu4ll0w4c0Gg2oqhqEZLPZK6ZpkuFw
yIY+uh/w6HANr4/v4I3+AHvavQCkXq9DluUgJJPJhFRVJYPBgA3VOnk8Edaxc7zpQ7aO1qEWw6xfrVYh
iiI4jvsFMQwjpCgK6ff7ZyD7J/fxUrqBF0c3MZtP2RbxeByRSOSSD6DSNC2USCRIr9fzIY/fXsXz2HVs
K5v4/uObb+Y47nLA7EmWZQahl8jWdW1sK7cxOSXLzZ5EUQzFYjFCL9H7xdQsSdJysydBEFYFQSD0wGq1
2r+ZPfE8v8rzPPkvsycKCYfDF3+ve/oJ+zEPR++RdtEAAAAASUVORK5CYII=
</value> </value>
</data> </data>
<data name="btnAddLabel.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="btnAddLabel.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@@ -197,20 +217,6 @@
lIotLMtCsVh8lQG4PM/L2bZNlstlBjno78Ds90jcG+zJLjMrivL6yCzlOI6A8EsUkEUP1PsItk/Om6UM lIotLMtCsVh8lQG4PM/L2bZNlstlBjno78Ds90jcG+zJLjMrivL6yCzlOI6A8EsUkEUP1PsItk/Om6UM
w8jpuk74JcpfzM2maZ43S2madqlpGuEHNhwO/80sparqpaqq5L/MUhxSKBRe/l6X+gWA2x2MFEPZrwAA w8jpuk74JcpfzM2maZ43S2madqlpGuEHNhwO/80sparqpaqq5L/MUhxSKBRe/l6X+gWA2x2MFEPZrwAA
AABJRU5ErkJggg== AABJRU5ErkJggg==
</value>
</data>
<data name="btnAddNode.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHdSURBVDhPnZLra9NgFMb3T/hV8b8YFP+efZE5RL+qQxEV
dN6+OXfBTynNZtYmbeKSxfSS1pDSNq29UEpJW9tSULT6lvXCI+8LicTpij4QQs45z+85kLNSqVRQLpdR
KpVQLBZRKBSQz+dh2zZ9X1hZJsdxsFgszjzdbpdBDMM4H0KTqcF1XZbcbrd9CK1ZlnU+hK5Mh2ka/c7l
cvZ4PMZsNmN1CjRN8+8QmuoNplKp03Q67U4mEwy/dPDeOWS9VquFZDL5ZwhN9laez+eg5tHXT3ga3cDD
gzXozgHrNZtN6LoOSZKCEMuyyGg0YkPT6RSDzx1sRa/h1btb2NXu4ll0w4c0Gg2oqhqEZLPZK6ZpkuFw
yIY+uh/w6HANr4/v4I3+AHvavQCkXq9DluUgJJPJhFRVJYPBgA3VOnk8Edaxc7zpQ7aO1qEWw6xfrVYh
iiI4jvsFMQwjpCgK6ff7ZyD7J/fxUrqBF0c3MZtP2RbxeByRSOSSD6DSNC2USCRIr9fzIY/fXsXz2HVs
K5v4/uObb+Y47nLA7EmWZQahl8jWdW1sK7cxOSXLzZ5EUQzFYjFCL9H7xdQsSdJysydBEFYFQSD0wGq1
2r+ZPfE8v8rzPPkvsycKCYfDF3+ve/oJ+zEPR++RdtEAAAAASUVORK5CYII=
</value> </value>
</data> </data>
<data name="btnDelete.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="btnDelete.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@@ -398,6 +404,36 @@
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC 1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value>
</data>
<data name="btDirDelete.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK
YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X
/aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t
I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM
cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh
6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD
lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value>
</data>
<data name="btMakeDirdata.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK
YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X
/aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t
I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM
cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh
6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD
lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value> </value>
</data> </data>
</root> </root>

View File

@@ -40,6 +40,11 @@ namespace AGVNavigationCore.Models
[Description("도킹/충전 노드의 진입 방향입니다.")] [Description("도킹/충전 노드의 진입 방향입니다.")]
public DockingDirection DockDirection { get; set; } = DockingDirection.DontCare; public DockingDirection DockDirection { get; set; } = DockingDirection.DontCare;
[Category("노드 설정")]
[Description("각 연결된 노드로 향할 때의 마그넷 방향 정보입니다.")]
public Dictionary<string, MagnetPosition> MagnetDirections { get; set; } = new Dictionary<string, MagnetPosition>();
[Category("연결 정보")] [Category("연결 정보")]
[Description("연결된 노드 ID 목록입니다.")] [Description("연결된 노드 ID 목록입니다.")]
[ReadOnly(true)] [ReadOnly(true)]