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

242 lines
10 KiB
C#

using SimpleCore.PropType;
using SimpleCore;
using System.Collections.Generic;
using System.Dynamic;
using SimpleLite.CADTools;
using SimpleLite.Props;
using SimpleLite.UI;
using System.Numerics;
using System.Drawing;
using System;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using SimpleLite.RCS;
using SimpleLite.RCS.CarTypes;
namespace StandardScene.Model
{
public class Map
{
public List<ExpandoObject> Sites { get; set; }
public List<ExpandoObject> Tracks { get; set; }
public List<ExpandoObject> CircularArcTracks { get; set; }
public List<ExpandoObject> BezierTracks { get; set; }
public static Map GetMap()
{
var map = new Map
{
Sites = new List<ExpandoObject>()
};
Site[] allSites = SimpleLib.GetAllSites();
foreach (var site in allSites)
{
dynamic theSite = new ExpandoObject();
theSite.Id = ((Prop)site).id;
theSite.Name = ((Prop)site).name;
theSite.X = site.x;
theSite.Y = site.y;
theSite.Fields = new Dictionary<string, string>();
foreach (var kv in site.fields)
{
theSite.Fields.Add(kv.Key, kv.Value);
}
theSite.Type = theSite.Fields.ContainsKey("Standby") ? "standby" : theSite.Fields.ContainsKey("Charge") ? "charge" : theSite.Fields.ContainsKey("Shelf") ? "shelf" : "default";
map.Sites.Add(theSite);
}
map.Tracks = new List<ExpandoObject>();
map.CircularArcTracks = new List<ExpandoObject>();
map.BezierTracks = new List<ExpandoObject>();
var allTracks = SimpleLib.GetAllTracks();
foreach (var track in allTracks)
{
switch (track)
{
case UITrack uiTrack:
{
dynamic theTrack = new ExpandoObject();
theTrack.Id = uiTrack.id;
theTrack.A = uiTrack.siteA;
theTrack.B = uiTrack.siteB;
theTrack.Fields = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> kv in uiTrack.fields)
{
theTrack.Fields.Add(kv.Key, kv.Value);
}
theTrack.Direction = uiTrack.direction switch
{
1 => "a2b",
2 => "b2a",
_ => "both"
};
theTrack.Type = 0;
map.Tracks.Add(theTrack);
break;
}
case UICircularArcTrack circularArcTrack:
{
dynamic theTrack = new ExpandoObject();
theTrack.Id = circularArcTrack.id;
theTrack.A = circularArcTrack.siteA;
theTrack.B = circularArcTrack.siteB;
theTrack.Fields = new Dictionary<string, string>();
foreach (var kv in circularArcTrack.fields)
{
theTrack.Fields.Add(kv.Key, kv.Value);
}
theTrack.Direction = circularArcTrack.direction switch
{
1 => "a2b",
2 => "b2a",
_ => "both"
};
//添加原点坐标、半径、开始角度、结束角度
theTrack.Type = 1;
theTrack.CenterX = circularArcTrack.Arc.Center.X;
theTrack.CenterY = circularArcTrack.Arc.Center.Y;
theTrack.Radius = circularArcTrack.Arc.Radius;
theTrack.AngleStart = circularArcTrack.Arc.AngleStart;
theTrack.AngleEnd = circularArcTrack.Arc.AngleEnd;
//获取圆弧的控制点
var controlPoint = ArcHelper.CalculateControlPoint(
circularArcTrack.Arc.PointStart.X, circularArcTrack.Arc.PointStart.Y,
circularArcTrack.Arc.PointEnd.X, circularArcTrack.Arc.PointEnd.Y,
circularArcTrack.Arc.Center.X, circularArcTrack.Arc.Center.Y,
circularArcTrack.Arc.Radius,
circularArcTrack.Arc.AngleStart, circularArcTrack.Arc.AngleEnd);
theTrack.ControlPointsX = controlPoint.X;
theTrack.ControlPointsY = controlPoint.Y;
map.CircularArcTracks.Add(theTrack);
break;
}
case UIBezierTrack bezierTrack:
{
dynamic theTrack = new ExpandoObject();
theTrack.Id = bezierTrack.id;
theTrack.A = bezierTrack.siteA;
theTrack.B = bezierTrack.siteB;
theTrack.Fields = new Dictionary<string, string>();
foreach (var kv in bezierTrack.fields)
{
theTrack.Fields.Add(kv.Key, kv.Value);
}
theTrack.Direction = bezierTrack.direction switch
{
1 => "a2b",
2 => "b2a",
_ => "both"
};
//根据typeInfo获取控制点个数
theTrack.Type = 2;
var array = bezierTrack.typeInfo.Split(',');
var num = int.Parse(array[1]);//获取控制点的个数(包括起点和终点)
var list = new List<Vector2>();
for (var i = 0; i < num; i++)
{
//只记录中间的控制点
if (i <= 0 || i >= num - 1) continue;
float x = float.Parse(array[2 + i * 2]);
float y = float.Parse(array[3 + i * 2]);
list.Add(new Vector2(x, y));
}
theTrack.controlPoints = list;
map.BezierTracks.Add(theTrack);
break;
}
default:
break;
}
}
return map;
}
}
public class ArcHelper
{
/// <summary>
/// 获取圆弧控制点
/// </summary>
/// <returns></returns>
public static PointF CalculateControlPoint(float pointStartX, float pointStartY, float pointEndX, float pointEndY, float centerX, float centerY, float radius, float angleStart, float angleEnd)
{
PointF center = new PointF(centerX, centerY);
double startAngle = angleStart * 3.14159 / 180.0;
double endAngel = angleEnd * 3.14159 / 180.0;
if (angleStart > angleEnd)//如果起始角度小于结束角度就加上360度
{
endAngel += 2 * 3.14159;
}
PointF midPoint = new PointF(
(float)(center.X + radius * Math.Cos((startAngle + endAngel) / 2)),
(float)(center.Y + radius * Math.Sin((startAngle + endAngel) / 2)));
return midPoint;
}
}
public class LidarMap
{
public string LidarMapsBase64 { get; set; }
public float DistanceX { get; set; }
public float DistanceY { get; set; }
public float Ratio { get; set; }
private static readonly HttpClient hc = new HttpClient();
public static async Task<LidarMap> GetLidarMap()
{
var par = JsonConvert.DeserializeAnonymousType(await hc.GetStringAsync($"http://127.0.0.1:4321/getMapParameters"),
new { up = 0f, down = 0f, left = 0f, right = 0f, pt = 0 });
var lengthWidthRatio =Math.Abs((par.right - par.left) / (par.up - par.down));
var height = 1024;var width = 1024;
if (lengthWidthRatio > 1)
{
height = (int)(1024 / lengthWidthRatio);
}
else
{
width = (int)(1024 * lengthWidthRatio);
}
var mapBmp= new Bitmap((await hc.GetStreamAsync($"http://127.0.0.1:4321/getMapPng?width={width}&height={height}")));
for(int x =0;x<mapBmp.Width;x++)
{
for (int y = 0; y < mapBmp.Height; y++)
{
Color pixColor = mapBmp.GetPixel(x, y);
if (pixColor.R != 255 || pixColor.G != 255 || pixColor.B != 255)
{
mapBmp.SetPixel(x, y, Color.FromArgb(0,pixColor));
}
else
{
mapBmp.SetPixel(x,y,Color.Black);
}
}
}
return new LidarMap
{
LidarMapsBase64 = "data:image/png;base64," + BitmapToBase64(mapBmp, ImageFormat.Png),
DistanceX = par.left,
DistanceY = par.up,
Ratio = lengthWidthRatio > 1?Math.Abs(par.left-par.right)/1024: Math.Abs(par.up - par.down)/1024,
};
}
static string BitmapToBase64(Bitmap bmp, ImageFormat format)
{
using MemoryStream ms = new MemoryStream();
bmp.Save(ms, format); // 保存格式可以是Png, Jpeg等
byte[] imageBytes = ms.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
}