Files
StandardSence/StandardScene.Core/StandardCADTool.cs
T
2026-06-14 11:19:15 +08:00

295 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Newtonsoft.Json;
using SimpleLite;
using SimpleLite.RCS;
using SimpleLite.RCS.CarTypes;
using SimpleLite.CADTools;
using SimpleLite.Props;
using SimpleLite.UI;
using SimpleCore;
using SimpleCore.Library;
using SimpleCore.PropType;
using StandardScene.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace StandardScene
{
[CADToolDescriptor(name = "复制目标站点所有字段")]
public class CopySiteFieldsFromTarget : CADTool
{
public override async void Invoke()
{
var sel = SimpleMonitor.selected.OfType<UISite>().ToList();
var targetPoint = await Program.UI.getPoint(new UIOps.getPointOptions() { site = true });
var targetSite = SimpleLib.GetSite(targetPoint.site);
var ignoreKey = new string[] { "mustFree" };
if (sel.Count <= 0) return;
foreach (var site in sel)
{
foreach (var field in targetSite.fields)
{
if (ignoreKey.Contains(field.Key)) continue;
site.fields[field.Key] = field.Value;
}
}
}
}
[CADToolDescriptor(name = "区域流量管控-限制进入区域的车数量")]
public class RegionalTrafficControl : CADTool
{
// 重写调用方法:执行区域流量管控的车辆数量限制配置
public override async void Invoke()
{
// 获取选中的所有站点UI对象
var selectedSites = SimpleMonitor.selected.OfType<UISite>().ToList();
// 弹出输入框,提示用户按「区域编号,限制数量」格式输入,取消则直接返回
var inputDialogResult = InputBox.ShowDialog("请输入区域编号和限制数量,格式:1,3");
if (inputDialogResult != SimpleLite.DialogResult.OK) return;
// 拆分输入的区域编号和限制数量
var inputValues = InputBox.ResultValue.Split(',');
// 若无配置信息,直接返回
if (inputValues.Length <= 1) return;
// 解析区域编号(浮点型保留原类型,兼容后续扩展)
var areaNumber = float.Parse(inputValues[0]);
// 解析区域车辆限制数量(浮点型保留原类型,兼容非整数配置)
var limitVehicleCount = float.Parse(inputValues[1]);
// 遍历所有选中站点,为其添加区域流量管控的字段配置
foreach (var currentSite in selectedSites)
{
// 配置字段:area+区域编号 作为键,限制数量作为值
if (!currentSite.fields.ContainsKey($"Region{areaNumber}"))
{
currentSite.fields.Add($"Region{areaNumber}", limitVehicleCount.ToString());
}
}
}
}
[CADToolDescriptor(name = "复制目标站点所有字段(不覆盖)")]
public class CopySiteFieldsFromTargetNoOverwrite : CADTool
{
public override async void Invoke()
{
var sel = SimpleMonitor.selected.OfType<UISite>().ToList();
var targetPoint = await Program.UI.getPoint(new UIOps.getPointOptions() { site = true });
var targetSite = SimpleLib.GetSite(targetPoint.site);
var ignore = new string[] { "mustFree" };
if (sel.Count <= 0) return;
foreach (var site in sel)
{
foreach (var field in targetSite.fields)
{
if (!site.fields.ContainsKey(field.Key))
{
site.fields[field.Key] = field.Value;
}
}
}
}
}
[CADToolDescriptor(name = "复制目标站点颜色")]
public class BatchChangeSiteColor : CADTool
{
public override async void Invoke()
{
var sel = SimpleMonitor.selected.OfType<UISite>().ToList();
var targetPoint = await Program.UI.getPoint(new UIOps.getPointOptions() { site = true });
var targetSite = (UISite)SimpleLib.GetSite(targetPoint.site);
if (sel.Count <= 0) return;
foreach (var site in sel)
{
site.color = targetSite.color;
}
}
}
[CADToolDescriptor(name = "导入FASS地图")]
public class ImportFASSMap : CADTool
{
public override void Invoke()
{
//打开文件选择框
using (var ofd = new System.Windows.Forms.OpenFileDialog())
{
ofd.InitialDirectory = "C:\\";
ofd.Filter = "FASS地图文件(*.json)|*.json";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string filePath = ofd.FileName;
//解析文件内容
string jsonString = File.ReadAllText(filePath);
MapStructure mapStructure = JsonConvert.DeserializeObject<MapStructure>(jsonString);
Model.Configuration configuration = ConvertMapStructureToConfiguration(mapStructure);
// 输出 JSON 字符串到文本文件
// 将 MapStructure 对象序列化为 JSON 字符串
// 设置格式化选项
string jsonSsring = JsonConvert.SerializeObject(configuration);
// 获取桌面路径
string desktopPath =
AppDomain.CurrentDomain
.BaseDirectory; // Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string outPath = Path.Combine(desktopPath, "output.json"); // 输出文件路径
// 输出 JSON 字符串到桌面上的文本文件
File.WriteAllText(outPath, jsonSsring);
Console.WriteLine($"JSON 数据已成功写入到 {outPath}");
//todo:分析文件内容,并导入站点、路径信息
}
}
}
public static Model.Configuration ConvertMapStructureToConfiguration(MapStructure mapStructure)
{
Model.Configuration config = new Model.Configuration();
List<int> index = new List<int>();
// 处理 Sites
foreach (var node in mapStructure.Nodes)
{
SimpleSite site = new SimpleSite
{
id = int.Parse(node.Code.Text), // 将 node.Code.Text 赋值给 SimpleSite 的 Id
name = node.Name.Text, // 将 node.Name.Text 赋值给 SimpleSite 的 Name
x = node.Base.Point.X, // 将 node.Base.Point.X 赋值给 SimpleSite 的 X
y = node.Base.Point.Y, // 将 node.Base.Point.Y 赋值给 SimpleSite 的 Y
color = "defaultColor", // 默认颜色示例,您可以根据需要更改
displaySetting = "defaultDisplay", // 默认显示设置示例,您可以根据需要更改
fields = new Dictionary<string, string>(), // Assuming fields is an empty object
mustFree = new List<object>() // Assuming mustFree is an empty array
};
config.Sites[node.Code.Text] = site; // 将 SimpleSite 添加到 Sites 字典中
AddInDescendingOrder(index, int.Parse(node.Code.Text));
}
// 处理 Tracks
foreach (var edge in mapStructure.Edges)
{
int id = index[0] + 1;
AddInDescendingOrder(index, id);
StandardScene.Model.Track track = new StandardScene.Model.Track
{
id = id, // 将 edge.Index 赋值给 Track 的 Id
name = "NoName", // 将 edge.Name.Text 赋值给 Track 的 Name
siteA = int.Parse(mapStructure.Nodes.Find(n => n.Id == edge.Data.StartNodeId).Code
.Text), // 找到 StartNode 的索引
siteB = int.Parse(mapStructure.Nodes.Find(n => n.Id == edge.Data.EndNodeId).Code
.Text), // 找到 EndNode 的索引
_siteA = int.Parse(mapStructure.Nodes.Find(n => n.Id == edge.Data.StartNodeId).Code.Text),
_siteB = int.Parse(mapStructure.Nodes.Find(n => n.Id == edge.Data.EndNodeId).Code.Text),
fields = new Dictionary<string, string>(),
typeInfo = "0",
layerName = "g",
displaySetting = ""
};
config.Tracks[id.ToString()] = track; // 将 Track 添加到 Tracks 字典中
}
return config;
}
static void AddInDescendingOrder(List<int> list, int number)
{
// 找到插入位置
int i = 0;
while (i < list.Count && list[i] >= number)
{
i++;
}
list.Insert(i, number); // 在找到的位置插入
}
}
[CADToolDescriptor(name = "批量间距生成站点")]
public class BulkIntervalSiteCreator : CADTool
{
public override async void Invoke()
{
try
{
G.pushStatus("请选择参考点");
var target = await Program.UI.getPoint();
var templateSite = SimpleLib.GetAllSites().OrderBy(p => LessMath.dist(target.x, target.y, p.x, p.y))
.FirstOrDefault();
// 检查是否找到模板站点
if (templateSite == null)
{
G.pushStatus("未找到参考站点");
return;
}
// 存储所有生成的站点(用于处理组间连接)
List<UISite> generatedSites = new List<UISite>();
if (InputBox.ShowDialog("请输入需要生成的二维码数量(必须是偶数数量)以及站点间距和延伸角度,,格式为\"6,1000,0\"。") !=
SimpleLite.DialogResult.OK) return;
generatedSites.Add((UISite)templateSite);
var values = InputBox.ResultValue.Split(',').Select(ss => float.Parse(ss)).ToArray();
// 验证数量是否为偶数
if (values[0] % 2 != 0)
{
G.pushStatus("数量必须是偶数");
return;
}
for (int i = 0; i < values[0] / 2; i = i + 2)
{
var curPos = Tuple.Create(templateSite.x, templateSite.y, values[2]);
var targetPos = LessMath.Transform2D(curPos, Tuple.Create(values[1] * (i + 1), 0f, 0f));
var targetPos2 = LessMath.Transform2D(curPos, Tuple.Create(values[1] * (i + 2), 0f, 0f));
var siteA = new UISite() { id = Prop.GenerateID(), x = targetPos.Item1, y = targetPos.Item2 };
((UISite)siteA).color = ""; //
var siteB = new UISite() { id = Prop.GenerateID(), x = targetPos2.Item1, y = targetPos2.Item2 };
SimpleLib.SetSite(siteA);
SimpleLib.SetSite(siteB);
generatedSites.Add(siteA);
generatedSites.Add(siteB);
}
for (int i = 0; i < generatedSites.Count - 1; i++)
{
Commons.AddOrUpdateSiteField(generatedSites[i], "tag", "0");
// 每两个相邻站点都创建路径(包含组内和组间)
SimpleLib.SetTrack(new UITrack(
generatedSites[i].id,
generatedSites[i + 1].id
));
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
// SyncQrMap(同步二维码地图到小车)已迁出至 StandardScene.QrLidar\Cad\SyncQrMap.csscene.qrlidar 平台)。
}