Files
ENIG/Cs_HMI/PathLogic/Core/MapLoader.cs
2025-09-18 17:25:14 +09:00

336 lines
11 KiB
C#

using System;
using System.IO;
using Newtonsoft.Json;
using PathLogic.Models;
namespace PathLogic.Core
{
/// <summary>
/// 맵 파일 로더 클래스
/// 기존 AGV 맵 에디터에서 생성한 JSON 파일을 로드
/// </summary>
public class MapLoader
{
/// <summary>
/// 파일에서 맵 데이터 로드
/// </summary>
/// <param name="filePath">맵 파일 경로</param>
/// <returns>로드된 맵 데이터</returns>
public MapData LoadFromFile(string filePath)
{
if (!File.Exists(filePath))
{
throw new FileNotFoundException($"맵 파일을 찾을 수 없습니다: {filePath}");
}
try
{
string jsonContent = File.ReadAllText(filePath);
return LoadFromJson(jsonContent);
}
catch (Exception ex)
{
throw new Exception($"맵 파일 로드 중 오류 발생: {ex.Message}", ex);
}
}
/// <summary>
/// JSON 문자열에서 맵 데이터 로드
/// </summary>
/// <param name="jsonContent">JSON 문자열</param>
/// <returns>로드된 맵 데이터</returns>
public MapData LoadFromJson(string jsonContent)
{
if (string.IsNullOrEmpty(jsonContent))
{
throw new ArgumentException("JSON 내용이 비어있습니다.");
}
try
{
// JSON 역직렬화 설정
var settings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.IsoDateFormat,
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
// JSON 파일 구조 분석
var jsonObject = JsonConvert.DeserializeObject<dynamic>(jsonContent, settings);
var mapData = new MapData();
// 메타데이터 로드
if (jsonObject.CreatedDate != null)
{
mapData.CreatedDate = jsonObject.CreatedDate;
}
if (jsonObject.Version != null)
{
mapData.Version = jsonObject.Version;
}
// 노드 데이터 로드
if (jsonObject.Nodes != null)
{
foreach (var nodeJson in jsonObject.Nodes)
{
var node = LoadNodeFromJson(nodeJson);
if (node != null)
{
mapData.Nodes.Add(node);
}
}
}
// 맵 데이터 유효성 검증
var validationIssues = mapData.ValidateMap();
if (validationIssues.Count > 0)
{
Console.WriteLine("맵 데이터 검증 경고:");
foreach (var issue in validationIssues)
{
Console.WriteLine($" - {issue}");
}
}
Console.WriteLine($"맵 로드 완료: {mapData.GetStatistics()}");
return mapData;
}
catch (JsonException ex)
{
throw new Exception($"JSON 파싱 오류: {ex.Message}", ex);
}
catch (Exception ex)
{
throw new Exception($"맵 데이터 로드 중 오류: {ex.Message}", ex);
}
}
/// <summary>
/// JSON 객체에서 노드 데이터 로드
/// </summary>
/// <param name="nodeJson">노드 JSON 객체</param>
/// <returns>로드된 노드</returns>
private MapNode LoadNodeFromJson(dynamic nodeJson)
{
try
{
var node = new MapNode();
// 필수 필드
node.NodeId = nodeJson.NodeId ?? string.Empty;
node.Name = nodeJson.Name ?? string.Empty;
// 위치 정보 파싱
if (nodeJson.Position != null)
{
var position = nodeJson.Position.ToString();
node.Position = ParsePosition(position);
}
// 노드 타입
if (nodeJson.Type != null)
{
if (Enum.TryParse<NodeType>(nodeJson.Type.ToString(), out NodeType nodeType))
{
node.Type = nodeType;
}
}
// 도킹 방향
if (nodeJson.DockDirection != null)
{
if (Enum.TryParse<DockingDirection>(nodeJson.DockDirection.ToString(), out DockingDirection dockDirection))
{
node.DockDirection = dockDirection;
}
}
// 연결된 노드들
if (nodeJson.ConnectedNodes != null)
{
foreach (var connectedNodeId in nodeJson.ConnectedNodes)
{
if (connectedNodeId != null)
{
node.ConnectedNodes.Add(connectedNodeId.ToString());
}
}
}
// 기타 속성들
if (nodeJson.CanRotate != null)
node.CanRotate = nodeJson.CanRotate;
if (nodeJson.StationId != null)
node.StationId = nodeJson.StationId;
if (nodeJson.StationType != null && Enum.TryParse<StationType>(nodeJson.StationType.ToString(), out StationType stationType))
node.StationType = stationType;
if (nodeJson.CreatedDate != null)
node.CreatedDate = nodeJson.CreatedDate;
if (nodeJson.ModifiedDate != null)
node.ModifiedDate = nodeJson.ModifiedDate;
if (nodeJson.IsActive != null)
node.IsActive = nodeJson.IsActive;
// RFID 정보
if (nodeJson.RfidId != null)
node.RfidId = nodeJson.RfidId;
if (nodeJson.RfidStatus != null)
node.RfidStatus = nodeJson.RfidStatus;
if (nodeJson.RfidDescription != null)
node.RfidDescription = nodeJson.RfidDescription;
// UI 관련 속성들 (맵 에디터 호환성을 위해)
LoadUIProperties(node, nodeJson);
// 기본 색상 설정
node.SetDefaultColorByType(node.Type);
return node;
}
catch (Exception ex)
{
Console.WriteLine($"노드 로드 오류: {ex.Message}");
return null;
}
}
/// <summary>
/// UI 관련 속성 로드
/// </summary>
/// <param name="node">대상 노드</param>
/// <param name="nodeJson">노드 JSON 객체</param>
private void LoadUIProperties(MapNode node, dynamic nodeJson)
{
try
{
if (nodeJson.LabelText != null)
node.LabelText = nodeJson.LabelText;
if (nodeJson.FontFamily != null)
node.FontFamily = nodeJson.FontFamily;
if (nodeJson.FontSize != null)
node.FontSize = (float)nodeJson.FontSize;
if (nodeJson.ImagePath != null)
node.ImagePath = nodeJson.ImagePath;
if (nodeJson.Opacity != null)
node.Opacity = (float)nodeJson.Opacity;
if (nodeJson.Rotation != null)
node.Rotation = (float)nodeJson.Rotation;
if (nodeJson.ShowBackground != null)
node.ShowBackground = nodeJson.ShowBackground;
// Scale 파싱
if (nodeJson.Scale != null)
{
var scale = nodeJson.Scale.ToString();
node.Scale = ParseScale(scale);
}
}
catch (Exception ex)
{
Console.WriteLine($"UI 속성 로드 오류: {ex.Message}");
}
}
/// <summary>
/// 위치 문자열을 Point로 파싱
/// 예: "65, 229" -> Point(65, 229)
/// </summary>
/// <param name="positionString">위치 문자열</param>
/// <returns>파싱된 Point</returns>
private System.Drawing.Point ParsePosition(string positionString)
{
try
{
if (string.IsNullOrEmpty(positionString))
return System.Drawing.Point.Empty;
var parts = positionString.Split(',');
if (parts.Length >= 2)
{
int x = int.Parse(parts[0].Trim());
int y = int.Parse(parts[1].Trim());
return new System.Drawing.Point(x, y);
}
}
catch (Exception ex)
{
Console.WriteLine($"위치 파싱 오류: {positionString}, {ex.Message}");
}
return System.Drawing.Point.Empty;
}
/// <summary>
/// 스케일 문자열을 SizeF로 파싱
/// 예: "1, 1" -> SizeF(1.0f, 1.0f)
/// </summary>
/// <param name="scaleString">스케일 문자열</param>
/// <returns>파싱된 SizeF</returns>
private System.Drawing.SizeF ParseScale(string scaleString)
{
try
{
if (string.IsNullOrEmpty(scaleString))
return new System.Drawing.SizeF(1.0f, 1.0f);
var parts = scaleString.Split(',');
if (parts.Length >= 2)
{
float width = float.Parse(parts[0].Trim());
float height = float.Parse(parts[1].Trim());
return new System.Drawing.SizeF(width, height);
}
}
catch (Exception ex)
{
Console.WriteLine($"스케일 파싱 오류: {scaleString}, {ex.Message}");
}
return new System.Drawing.SizeF(1.0f, 1.0f);
}
/// <summary>
/// 맵 데이터를 JSON 파일로 저장
/// </summary>
/// <param name="mapData">저장할 맵 데이터</param>
/// <param name="filePath">저장할 파일 경로</param>
public void SaveToFile(MapData mapData, string filePath)
{
try
{
var settings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.IsoDateFormat,
NullValueHandling = NullValueHandling.Ignore,
Formatting = Formatting.Indented
};
string jsonContent = JsonConvert.SerializeObject(mapData, settings);
File.WriteAllText(filePath, jsonContent);
Console.WriteLine($"맵 데이터 저장 완료: {filePath}");
}
catch (Exception ex)
{
throw new Exception($"맵 파일 저장 중 오류: {ex.Message}", ex);
}
}
}
}