first commit -push
This commit is contained in:
130
RobotNet.MapManager/Controllers/ActionsController.cs
Normal file
130
RobotNet.MapManager/Controllers/ActionsController.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapManager.Services;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.Shares;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ActionsController(MapEditorDbContext MapDb, LoggerController<ActionsController> Logger) : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
public async Task<MessageResult<ActionDto>> CreateAction([FromBody] ActionCreateModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FindAsync(model.MapId);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {model.MapId}");
|
||||
|
||||
if (MapDb.Actions.Any(action => action.Name == model.Name && action.MapId == model.MapId)) return new(false, $"Tên Action {model.Name} đã tồn tại");
|
||||
|
||||
var entity = await MapDb.Actions.AddAsync(new()
|
||||
{
|
||||
MapId = model.MapId,
|
||||
Name = model.Name,
|
||||
Content = model.Content,
|
||||
});
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
Id = entity.Entity.Id,
|
||||
MapId = entity.Entity.MapId,
|
||||
Name = entity.Entity.Name,
|
||||
Content = entity.Entity.Content,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Logger.Warning($"CreateAction: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"CreateAction: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("{id}")]
|
||||
public async Task<IEnumerable<ActionDto>> GetActions(Guid id)
|
||||
{
|
||||
return await MapDb.Actions.Where(action => action.MapId == id).Select(action => new ActionDto()
|
||||
{
|
||||
Id = action.Id,
|
||||
MapId = action.MapId,
|
||||
Name = action.Name,
|
||||
Content = action.Content,
|
||||
}).ToListAsync();
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
public async Task<MessageResult> UpdateAction([FromBody] ActionDto model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var action = await MapDb.Actions.FindAsync(model.Id);
|
||||
if (action is not null)
|
||||
{
|
||||
action.Name = model.Name;
|
||||
action.Content = model.Content;
|
||||
MapDb.Actions.Update(action);
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(true);
|
||||
}
|
||||
return new(false, $"Hệ thống không tìm thấy Action {model.Name} này");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"UpdateAction: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"UpdateAction: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult> DeleteAction(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var action = await MapDb.Actions.FindAsync(id);
|
||||
if (action is not null)
|
||||
{
|
||||
foreach (var node in MapDb.Nodes)
|
||||
{
|
||||
var actionIds = JsonSerializer.Deserialize<Guid[]>(node.Actions);
|
||||
if (actionIds is not null && actionIds.Any(a => a == action.Id))
|
||||
{
|
||||
var acitonIdsAfter = actionIds.ToList();
|
||||
acitonIdsAfter.Remove(action.Id);
|
||||
node.Actions = JsonSerializer.Serialize(acitonIdsAfter.Count > 0 ? acitonIdsAfter : []);
|
||||
}
|
||||
}
|
||||
foreach (var edge in MapDb.Edges)
|
||||
{
|
||||
var actionIds = JsonSerializer.Deserialize<Guid[]>(edge.Actions);
|
||||
if (actionIds is not null && actionIds.Any(a => a == action.Id))
|
||||
{
|
||||
var acitonIdsAfter = actionIds.ToList();
|
||||
acitonIdsAfter.Remove(action.Id);
|
||||
edge.Actions = JsonSerializer.Serialize(acitonIdsAfter.Count > 0 ? acitonIdsAfter : []);
|
||||
}
|
||||
}
|
||||
MapDb.Actions.Remove(action);
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(true) ;
|
||||
}
|
||||
return new(false, $"Hệ thống không tìm thấy Action {id} này");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"DeleteAction {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"DeleteAction {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
269
RobotNet.MapManager/Controllers/EdgesController.cs
Normal file
269
RobotNet.MapManager/Controllers/EdgesController.cs
Normal file
@@ -0,0 +1,269 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapManager.Services;
|
||||
using RobotNet.MapShares;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.MapShares.Enums;
|
||||
using RobotNet.Shares;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class EdgesController(MapEditorDbContext MapDb, LoggerController<EdgesController> Logger) : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
[Route("")]
|
||||
public async Task<MessageResult<EdgeCreateDto>> CreateEdge([FromBody] EdgeCreateModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FindAsync(model.MapId);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {model.MapId}");
|
||||
|
||||
if (Math.Sqrt(Math.Pow(model.X1 - model.X2, 2) + Math.Pow(model.Y1 - model.Y2, 2)) < map.EdgeMinLengthDefault) return new(false, "Độ dài edge quá nhỏ");
|
||||
|
||||
var nodes = await MapDb.Nodes.Where(n => n.MapId == model.MapId).ToListAsync();
|
||||
var edges = await MapDb.Edges.Where(e => e.MapId == model.MapId && e.TrajectoryDegree == TrajectoryDegree.One).ToListAsync();
|
||||
|
||||
var closesStartNode = MapEditorHelper.GetClosesNode(model.X1, model.Y1, [.. nodes.Select(node => new NodeDto()
|
||||
{
|
||||
MapId = node.MapId,
|
||||
X = node.X,
|
||||
Y = node.Y,
|
||||
Theta = node.Theta,
|
||||
Actions = node.Actions,
|
||||
Id = node.Id,
|
||||
Name = node.Name,
|
||||
AllowedDeviationTheta = node.AllowedDeviationTheta,
|
||||
AllowedDeviationXy = node.AllowedDeviationXy
|
||||
})]);
|
||||
|
||||
var closesEndNode = MapEditorHelper.GetClosesNode(model.X2, model.Y2, [.. nodes.Select(node => new NodeDto()
|
||||
{
|
||||
MapId = node.MapId,
|
||||
X = node.X,
|
||||
Y = node.Y,
|
||||
Theta = node.Theta,
|
||||
Actions = node.Actions,
|
||||
Id = node.Id,
|
||||
Name = node.Name,
|
||||
AllowedDeviationTheta = node.AllowedDeviationTheta,
|
||||
AllowedDeviationXy = node.AllowedDeviationXy
|
||||
})]);
|
||||
|
||||
Node? startNode = await MapDb.Nodes.FindAsync(closesStartNode?.Id);
|
||||
Node? endNode = await MapDb.Nodes.FindAsync(closesEndNode?.Id);
|
||||
List<Guid> RemoveEdge = [];
|
||||
List<EdgeDto> AddEdgeDto = [];
|
||||
|
||||
if (startNode is null)
|
||||
{
|
||||
startNode = ServerHelper.CreateNode(map, model.X1, model.Y1);
|
||||
await MapDb.Nodes.AddAsync(startNode);
|
||||
var closesEdge = ServerHelper.GetClosesEdge(model.X1, model.Y1, nodes, edges, 0.1);
|
||||
if (closesEdge is not null)
|
||||
{
|
||||
var closesEdgeStartNode = await MapDb.Nodes.FirstOrDefaultAsync(n => n.Id == closesEdge.StartNodeId);
|
||||
var closesEdgeEndNode = await MapDb.Nodes.FirstOrDefaultAsync(n => n.Id == closesEdge.EndNodeId);
|
||||
if (closesEdgeStartNode is not null && closesEdgeEndNode is not null)
|
||||
{
|
||||
var startEdge = ServerHelper.CreateEdge(map, closesEdgeStartNode.Id, startNode.Id, TrajectoryDegree.One);
|
||||
var endEdge = ServerHelper.CreateEdge(map, startNode.Id, closesEdgeEndNode.Id, TrajectoryDegree.One);
|
||||
await MapDb.Edges.AddAsync(startEdge);
|
||||
await MapDb.Edges.AddAsync(endEdge);
|
||||
|
||||
MapDb.Edges.Remove(closesEdge);
|
||||
edges.Remove(closesEdge);
|
||||
RemoveEdge.Add(closesEdge.Id);
|
||||
|
||||
edges.Add(startEdge);
|
||||
edges.Add(endEdge);
|
||||
nodes.Add(startNode);
|
||||
AddEdgeDto.Add(ServerHelper.CreateEdgeDto(startEdge, closesEdgeStartNode, startNode));
|
||||
AddEdgeDto.Add(ServerHelper.CreateEdgeDto(endEdge, startNode, closesEdgeEndNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
if (endNode is null)
|
||||
{
|
||||
endNode = ServerHelper.CreateNode(map, model.X2, model.Y2);
|
||||
await MapDb.Nodes.AddAsync(endNode);
|
||||
|
||||
var closesEdge = ServerHelper.GetClosesEdge(model.X2, model.Y2, nodes, edges, 0.1);
|
||||
if (closesEdge is not null)
|
||||
{
|
||||
var closesEdgeStartNode = await MapDb.Nodes.FirstOrDefaultAsync(n => n.Id == closesEdge.StartNodeId);
|
||||
var closesEdgeEndNode = await MapDb.Nodes.FirstOrDefaultAsync(n => n.Id == closesEdge.EndNodeId);
|
||||
if (closesEdgeStartNode is not null && closesEdgeEndNode is not null)
|
||||
{
|
||||
var startEdge = ServerHelper.CreateEdge(map, closesEdgeStartNode.Id, endNode.Id, TrajectoryDegree.One);
|
||||
var endEdge = ServerHelper.CreateEdge(map, endNode.Id, closesEdgeEndNode.Id, TrajectoryDegree.One);
|
||||
await MapDb.Edges.AddAsync(startEdge);
|
||||
await MapDb.Edges.AddAsync(endEdge);
|
||||
|
||||
MapDb.Edges.Remove(closesEdge);
|
||||
RemoveEdge.Add(closesEdge.Id);
|
||||
AddEdgeDto.Add(ServerHelper.CreateEdgeDto(startEdge, closesEdgeStartNode, endNode));
|
||||
AddEdgeDto.Add(ServerHelper.CreateEdgeDto(endEdge, endNode, closesEdgeEndNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var edge = ServerHelper.CreateEdge(map, startNode.Id, endNode.Id, model.TrajectoryDegree, model.ControlPoint1X, model.ControlPoint1Y, model.ControlPoint2X, model.ControlPoint2Y);
|
||||
await MapDb.Edges.AddAsync(edge);
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
AddEdgeDto.Add(ServerHelper.CreateEdgeDto(edge, startNode, endNode));
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new EdgeCreateDto()
|
||||
{
|
||||
EdgesDto = AddEdgeDto,
|
||||
RemoveEdge = RemoveEdge,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"CreateEdge: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"CreateEdge: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult> DeleteEdge(Guid id)
|
||||
{
|
||||
using var transaction = await MapDb.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
var edge = await MapDb.Edges.FindAsync(id);
|
||||
if (edge == null) return new(false, $"Không tồn tại edge id = {id}");
|
||||
|
||||
MapDb.Edges.Remove(edge);
|
||||
|
||||
if (!MapDb.Edges.Any(e => (e.StartNodeId == edge.StartNodeId || e.EndNodeId == edge.StartNodeId) && e.Id != edge.Id))
|
||||
{
|
||||
var node = await MapDb.Nodes.FindAsync(edge.StartNodeId);
|
||||
if (node != null)
|
||||
{
|
||||
var element = await MapDb.Elements.FirstOrDefaultAsync(e => e.NodeId == node.Id);
|
||||
if (element is not null) MapDb.Elements.Remove(element);
|
||||
MapDb.Nodes.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (!MapDb.Edges.Any(e => (e.StartNodeId == edge.EndNodeId || e.EndNodeId == edge.EndNodeId) && e.Id != edge.Id))
|
||||
{
|
||||
var node = await MapDb.Nodes.FindAsync(edge.EndNodeId);
|
||||
if (node != null)
|
||||
{
|
||||
var element = await MapDb.Elements.FirstOrDefaultAsync(e => e.NodeId == node.Id);
|
||||
if (element is not null) MapDb.Elements.Remove(element);
|
||||
MapDb.Nodes.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
await transaction.CommitAsync();
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
Logger.Warning($"DeleteEdge {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"DeleteEdge {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("")]
|
||||
public async Task<MessageResult> DeleteEdges([FromBody] IEnumerable<Guid> DeleteEdgesId)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<Edge> deleteEdges = [];
|
||||
List<Node> deleteNodes = [];
|
||||
foreach (var edgeId in DeleteEdgesId)
|
||||
{
|
||||
var edge = await MapDb.Edges.FindAsync(edgeId);
|
||||
if (edge == null) continue;
|
||||
|
||||
MapDb.Edges.Remove(edge);
|
||||
|
||||
if (!MapDb.Edges.Any(e => (e.StartNodeId == edge.StartNodeId || e.EndNodeId == edge.StartNodeId) && e.Id != edge.Id))
|
||||
{
|
||||
var node = await MapDb.Nodes.FindAsync(edge.StartNodeId);
|
||||
if (node != null)
|
||||
{
|
||||
var element = await MapDb.Elements.FirstOrDefaultAsync(e => e.NodeId == node.Id);
|
||||
if (element is not null) MapDb.Elements.Remove(element);
|
||||
MapDb.Nodes.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (!MapDb.Edges.Any(e => (e.StartNodeId == edge.EndNodeId || e.EndNodeId == edge.EndNodeId) && e.Id != edge.Id))
|
||||
{
|
||||
var node = await MapDb.Nodes.FindAsync(edge.EndNodeId);
|
||||
if (node != null)
|
||||
{
|
||||
var element = await MapDb.Elements.FirstOrDefaultAsync(e => e.NodeId == node.Id);
|
||||
if (element is not null) MapDb.Elements.Remove(element);
|
||||
MapDb.Nodes.Remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"DeleteEdges: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"DeleteEdges: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("")]
|
||||
public async Task<MessageResult> UpdateEdge([FromBody] EdgeUpdateModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var edge = await MapDb.Edges.FindAsync(model.Id);
|
||||
if (edge == null) return new(false, $"Không tồn tại edge id = {model.Id}");
|
||||
|
||||
edge.MaxSpeed = model.MaxSpeed;
|
||||
edge.MaxHeight = model.MaxHeight;
|
||||
edge.MinHeight = model.MinHeight;
|
||||
edge.ControlPoint1X = model.ControlPoint1X;
|
||||
edge.ControlPoint1Y = model.ControlPoint1Y;
|
||||
edge.ControlPoint2X = model.ControlPoint2X;
|
||||
edge.ControlPoint2Y = model.ControlPoint2Y;
|
||||
edge.DirectionAllowed = model.DirectionAllowed;
|
||||
edge.RotationAllowed = model.RotationAllowed;
|
||||
edge.MaxRotationSpeed = model.MaxRotationSpeed;
|
||||
edge.Actions = JsonSerializer.Serialize(model.Actions ?? []);
|
||||
edge.AllowedDeviationXy = model.AllowedDeviationXy;
|
||||
edge.AllowedDeviationTheta = model.AllowedDeviationTheta;
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"UpdateEdge: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"UpdateEdge: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
258
RobotNet.MapManager/Controllers/ElementModelsController.cs
Normal file
258
RobotNet.MapManager/Controllers/ElementModelsController.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapManager.Services;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ElementModelsController(MapEditorDbContext MapDb, MapEditorStorageRepository MapStorage, LoggerController<ElementModelsController> Logger) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("map/{mapId}")]
|
||||
public async Task<MessageResult<IEnumerable<ElementModelDto>>> Gets(Guid mapId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new(true)
|
||||
{
|
||||
Data = await (from elm in MapDb.ElementModels
|
||||
where !string.IsNullOrEmpty(elm.Name) && elm.MapId == mapId
|
||||
select new ElementModelDto()
|
||||
{
|
||||
Id = elm.Id,
|
||||
MapId = elm.MapId,
|
||||
Name = elm.Name,
|
||||
Height = elm.Height,
|
||||
Width = elm.Width,
|
||||
Image1Height = elm.Image1Height,
|
||||
Image2Height = elm.Image2Height,
|
||||
Image1Width = elm.Image1Width,
|
||||
Image2Width = elm.Image2Width,
|
||||
Content = elm.Content,
|
||||
}).ToListAsync()
|
||||
};
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Gets: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"Gets: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult<ElementModelDto>> Get(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var elmodel = await MapDb.ElementModels.FindAsync(id);
|
||||
if (elmodel is null) return new(false, $"Element Model {id} không tồn tại");
|
||||
return new(true)
|
||||
{
|
||||
Data = new ElementModelDto()
|
||||
{
|
||||
Id = elmodel.Id,
|
||||
Name = elmodel.Name,
|
||||
MapId = elmodel.MapId,
|
||||
Height = elmodel.Height,
|
||||
Width = elmodel.Width,
|
||||
Content = elmodel.Content,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Get {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"Get {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<MessageResult<ElementModelDto>> CreateElementModel([FromForm] ElementModelCreateModel model, [FromForm(Name = "imageOpen")] IFormFile imageOpen, [FromForm(Name = "imageClose")] IFormFile imageClose)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (model == null || imageOpen == null || imageClose == null) return new(false, "Dữ liệu đầu vào không hợp lệ");
|
||||
var map = await MapDb.Maps.FindAsync(model.MapId);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {model.MapId}");
|
||||
if (MapDb.ElementModels.Any(elm => elm.Name == model.Name && elm.MapId == model.MapId)) return new(false, $"Tên Model {model.Name} đã tồn tại");
|
||||
|
||||
var image1 = SixLabors.ImageSharp.Image.Load(imageOpen.OpenReadStream());
|
||||
var image2 = SixLabors.ImageSharp.Image.Load(imageClose.OpenReadStream());
|
||||
var entity = MapDb.ElementModels.Add(new()
|
||||
{
|
||||
Name = model.Name,
|
||||
MapId = model.MapId,
|
||||
Width = model.Width,
|
||||
Height = model.Height,
|
||||
Image1Height = (ushort)image1.Height,
|
||||
Image1Width = (ushort)image1.Width,
|
||||
Image2Height = (ushort)image2.Height,
|
||||
Image2Width = (ushort)image2.Width,
|
||||
Content = "",
|
||||
});
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
var (isSuccess, message) = await MapStorage.UploadAsync("ElementOpenModels", $"{entity.Entity.Id}", imageOpen.OpenReadStream(), imageOpen.Length, imageOpen.ContentType, CancellationToken.None);
|
||||
if (!isSuccess)
|
||||
{
|
||||
MapDb.ElementModels.Remove(entity.Entity);
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(false, message);
|
||||
}
|
||||
(isSuccess, message) = await MapStorage.UploadAsync("ElementCloseModels", $"{entity.Entity.Id}", imageClose.OpenReadStream(), imageClose.Length, imageClose.ContentType, CancellationToken.None);
|
||||
if (!isSuccess)
|
||||
{
|
||||
MapDb.ElementModels.Remove(entity.Entity);
|
||||
await MapDb.SaveChangesAsync();
|
||||
await MapStorage.DeleteAsync("ElementOpenModels", $"{entity.Entity.Id}", CancellationToken.None);
|
||||
return new(false, message);
|
||||
}
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
Id = entity.Entity.Id,
|
||||
Name = entity.Entity.Name,
|
||||
MapId = entity.Entity.MapId,
|
||||
Width = entity.Entity.Width,
|
||||
Height = entity.Entity.Height,
|
||||
Image1Height = entity.Entity.Image1Height,
|
||||
Image1Width = entity.Entity.Image1Width,
|
||||
Image2Height = entity.Entity.Image2Height,
|
||||
Image2Width = entity.Entity.Image2Width,
|
||||
Content = entity.Entity.Content
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"CreateElementModel: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"CreateElementModel: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
public async Task<MessageResult<ElementModelDto>> Update([FromBody] ElementModelUpdateModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var elModel = await MapDb.ElementModels.FindAsync(model.Id);
|
||||
if (elModel is null) return new(false, $"Model {model.Id} không tồn tại");
|
||||
if (MapDb.ElementModels.Any(elm => elm.Name == model.Name && elm.MapId == elModel.MapId && model.Id != elModel.Id)) return new(false, $"Tên Model {model.Name} đã tồn tại");
|
||||
|
||||
elModel.Name = model.Name;
|
||||
elModel.Width = model.Width;
|
||||
elModel.Height = model.Height;
|
||||
elModel.Content = model.Content;
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(true)
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
Id = elModel.Id,
|
||||
Name = elModel.Name,
|
||||
MapId = elModel.MapId,
|
||||
Width = elModel.Width,
|
||||
Height = elModel.Height,
|
||||
Image1Height = elModel.Image1Height,
|
||||
Image1Width = elModel.Image1Width,
|
||||
Image2Height = elModel.Image2Height,
|
||||
Image2Width = elModel.Image2Width,
|
||||
Content = elModel.Content
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Update: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"Update: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult> Delete(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var elModel = await MapDb.ElementModels.FindAsync(id);
|
||||
if (elModel is null) return new(false, $"Model {id} không tồn tại");
|
||||
|
||||
await MapStorage.DeleteAsync("ElementOpenModels", id.ToString(), CancellationToken.None);
|
||||
await MapStorage.DeleteAsync("ElementCloseModels", id.ToString(), CancellationToken.None);
|
||||
MapDb.Elements.RemoveRange(MapDb.Elements.Where(e => e.ModelId == id));
|
||||
MapDb.ElementModels.Remove(elModel);
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Delete {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"Delete {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("openimage/{id}")]
|
||||
public async Task<MessageResult> UpdateOpenImage(Guid id, [FromForm(Name = "image")] IFormFile image)
|
||||
{
|
||||
try
|
||||
{
|
||||
var elModel = await MapDb.ElementModels.FindAsync(id);
|
||||
if (elModel is null) return new(false, $"Model {id} không tồn tại");
|
||||
|
||||
var imageStream = image.OpenReadStream();
|
||||
var (isSuccess, message) = await MapStorage.UploadAsync("ElementOpenModels", $"{elModel.Id}", imageStream, image.Length, image.ContentType, CancellationToken.None);
|
||||
if (!isSuccess) return new(false, message);
|
||||
|
||||
var imageUpdate = SixLabors.ImageSharp.Image.Load(image.OpenReadStream());
|
||||
elModel.Image1Width = (ushort)imageUpdate.Width;
|
||||
elModel.Image1Height = (ushort)imageUpdate.Height;
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"UpdateOpenImage {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"UpdateOpenImage {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("closeimage/{id}")]
|
||||
public async Task<MessageResult> UpdateCloseImage(Guid id, [FromForm(Name = "image")] IFormFile image)
|
||||
{
|
||||
try
|
||||
{
|
||||
var elModel = await MapDb.ElementModels.FindAsync(id);
|
||||
if (elModel is null) return new(false, $"Model {id} không tồn tại");
|
||||
|
||||
var imageStream = image.OpenReadStream();
|
||||
var (isSuccess, message) = await MapStorage.UploadAsync("ElementCloseModels", $"{elModel.Id}", imageStream, image.Length, image.ContentType, CancellationToken.None);
|
||||
if (!isSuccess) return new(false, message);
|
||||
|
||||
var imageUpdate = SixLabors.ImageSharp.Image.Load(image.OpenReadStream());
|
||||
elModel.Image2Width = (ushort)imageUpdate.Width;
|
||||
elModel.Image2Height = (ushort)imageUpdate.Height;
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"UpdateCloseImage {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"UpdateCloseImage {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
211
RobotNet.MapManager/Controllers/ElementsController.cs
Normal file
211
RobotNet.MapManager/Controllers/ElementsController.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapManager.Services;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ElementsController(MapEditorDbContext MapDb, LoggerController<ElementsController> Logger) : ControllerBase
|
||||
{
|
||||
|
||||
[HttpGet]
|
||||
public async Task<MessageResult<ElementDto>> GetElement([FromQuery] string mapName, [FromQuery] string elementName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == mapName);
|
||||
if (map is null) return new(false, $"Không tồn tại map tên = {mapName}");
|
||||
|
||||
var el = await MapDb.Elements.FirstOrDefaultAsync(e => e.MapId == map.Id && e.Name == elementName);
|
||||
if (el is null) return new(false, $"Không tồn tại element name = {elementName}");
|
||||
|
||||
var elNode = await MapDb.Nodes.FindAsync(el.NodeId);
|
||||
if (elNode is null) return new(false, $"Không tồn tại node id = {el.NodeId}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
Id = el.Id,
|
||||
Name = el.Name,
|
||||
MapId = el.MapId,
|
||||
IsOpen = el.IsOpen,
|
||||
NodeId = el.NodeId,
|
||||
OffsetX = el.OffsetX,
|
||||
OffsetY = el.OffsetY,
|
||||
ModelId = el.ModelId,
|
||||
Content = el.Content,
|
||||
NodeName = elNode.Name,
|
||||
X = elNode.X,
|
||||
Y = elNode.Y,
|
||||
Theta = elNode.Theta
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"GetElement: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"GetElement: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("{modelId}")]
|
||||
public async Task<MessageResult<IEnumerable<ElementDto>>> GetElementsByModelId([FromRoute] Guid modelId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var elModel = await MapDb.ElementModels.FindAsync(modelId);
|
||||
if (elModel is null) return new(false, $"Không tồn tại model id = {modelId}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = await (from el in MapDb.Elements
|
||||
where el.ModelId == modelId
|
||||
select new ElementDto()
|
||||
{
|
||||
Id = el.Id,
|
||||
MapId = el.MapId,
|
||||
Name = el.Name,
|
||||
ModelId = el.ModelId,
|
||||
ModelName = elModel.Name,
|
||||
IsOpen = el.IsOpen,
|
||||
NodeId = el.NodeId,
|
||||
OffsetX = el.OffsetX,
|
||||
OffsetY = el.OffsetY,
|
||||
Content = el.Content,
|
||||
}).ToListAsync()
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"GetElementsByModelId: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"GetElementsByModelId: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<MessageResult<ElementDto>> Create([FromBody] ElementCreateModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (model == null || string.IsNullOrEmpty(model.Name)) return new(false, "Dữ liệu không hợp lệ");
|
||||
var map = await MapDb.Maps.FindAsync(model.MapId);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {model.MapId}");
|
||||
|
||||
var node = await MapDb.Nodes.FindAsync(model.NodeId);
|
||||
if (node == null) return new(false, $"Không tồn tại node id = {model.NodeId}");
|
||||
|
||||
var elModel = await MapDb.ElementModels.FindAsync(model.ModelId);
|
||||
if (elModel is null) return new(false, $"Không tồn tại element model id = {model.ModelId}");
|
||||
|
||||
if (MapDb.Elements.Any(el => el.Name == model.Name && el.MapId == model.MapId)) return new(false, $"Tên Element đã tồn tại");
|
||||
|
||||
if (MapDb.Elements.Any(el => el.NodeId == model.NodeId)) return new(false, $"Node này đã có Element");
|
||||
|
||||
var entity = await MapDb.Elements.AddAsync(new()
|
||||
{
|
||||
Name = model.Name,
|
||||
MapId = model.MapId,
|
||||
NodeId = model.NodeId,
|
||||
ModelId = model.ModelId,
|
||||
OffsetX = model.OffsetX,
|
||||
OffsetY = model.OffsetY,
|
||||
Content = elModel.Content,
|
||||
});
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
Id = entity.Entity.Id,
|
||||
MapId = entity.Entity.MapId,
|
||||
NodeId = entity.Entity.NodeId,
|
||||
ModelName = elModel.Name,
|
||||
Name = entity.Entity.Name,
|
||||
ModelId = entity.Entity.ModelId,
|
||||
OffsetX = entity.Entity.OffsetX,
|
||||
OffsetY = entity.Entity.OffsetY,
|
||||
Content = entity.Entity.Content,
|
||||
IsOpen = entity.Entity.IsOpen,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Create: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"Create: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
public async Task<MessageResult<ElementDto>> Update([FromBody] ElementUpdateModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var element = await MapDb.Elements.FindAsync(model.Id);
|
||||
if (element == null) return new(false, $"Không tồn tại element id = {model.Id}");
|
||||
|
||||
var map = await MapDb.Maps.FindAsync(element.MapId);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {element.MapId}");
|
||||
|
||||
if (MapDb.Elements.Any(el => el.Name == model.Name && el.MapId == element.MapId && el.Id != model.Id)) return new(false, $"Tên Element đã tồn tại");
|
||||
|
||||
element.Name = model.Name;
|
||||
element.OffsetX = model.OffsetX;
|
||||
element.OffsetY = model.OffsetY;
|
||||
element.Content = model.Content;
|
||||
element.IsOpen = model.IsOpen;
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
Id = element.Id,
|
||||
MapId = element.MapId,
|
||||
NodeId = element.NodeId,
|
||||
Name = element.Name,
|
||||
ModelId = element.ModelId,
|
||||
OffsetX = element.OffsetX,
|
||||
OffsetY = element.OffsetY,
|
||||
Content = element.Content,
|
||||
IsOpen = element.IsOpen,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Update: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"Update: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult> Delete(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var element = await MapDb.Elements.FindAsync(id);
|
||||
if (element == null) return new(false, $"Không tồn tại element id = {id}");
|
||||
|
||||
MapDb.Elements.Remove(element);
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Delete {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"Delete {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
66
RobotNet.MapManager/Controllers/ImagesController.cs
Normal file
66
RobotNet.MapManager/Controllers/ImagesController.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RobotNet.MapManager.Services;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[AllowAnonymous]
|
||||
public class ImagesController(MapEditorStorageRepository StorageRepo, IHttpClientFactory HttpClientFactory, LoggerController<ImagesController> Logger) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("map/{id}")]
|
||||
public async Task<IActionResult> GetMapImage(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var (usingLocal, url) = StorageRepo.GetUrl("MapImages", $"{id}");
|
||||
if (!usingLocal)
|
||||
{
|
||||
var http = HttpClientFactory.CreateClient();
|
||||
var imageBytes = await http.GetByteArrayAsync(url);
|
||||
if (imageBytes != null && imageBytes.Length > 0) return File(imageBytes, "image/png");
|
||||
else return NotFound("Không thể lấy được ảnh map.");
|
||||
}
|
||||
if (System.IO.File.Exists(url)) return File(System.IO.File.ReadAllBytes(url), "image/png");
|
||||
else return NotFound();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Logger.Warning($"GetMapImage {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("elementModel/{id}")]
|
||||
public async Task<IActionResult> GetElementModelImage(Guid id, [FromQuery] bool IsOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
var (usingLocal, url) = StorageRepo.GetUrl(IsOpen ? "ElementOpenModels" : "ElementCloseModels", id.ToString());
|
||||
if (!usingLocal)
|
||||
{
|
||||
var http = HttpClientFactory.CreateClient();
|
||||
var imageBytes = await http.GetByteArrayAsync(url);
|
||||
if (imageBytes != null && imageBytes.Length > 0)
|
||||
{
|
||||
return File(imageBytes, "image/png");
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound("Không thể lấy được ảnh element model.");
|
||||
}
|
||||
}
|
||||
if (System.IO.File.Exists(url)) return File(System.IO.File.ReadAllBytes(url), "image/png");
|
||||
else return NotFound();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"GetElementModelImage {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RobotNet.MapManager.Services;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[AllowAnonymous]
|
||||
public class MapDesignerLoggerController(LoggerController<MapDesignerLoggerController> Logger) : ControllerBase
|
||||
{
|
||||
private readonly string LoggerDirectory = "mapManagerlogs";
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IEnumerable<string>> GetLogs([FromQuery(Name = "date")] DateTime date)
|
||||
{
|
||||
string temp = "";
|
||||
try
|
||||
{
|
||||
string fileName = $"{date:yyyy-MM-dd}.log";
|
||||
string path = Path.Combine(LoggerDirectory, fileName);
|
||||
if (!Path.GetFullPath(path).StartsWith(Path.GetFullPath(LoggerDirectory)))
|
||||
{
|
||||
Logger.Warning($"GetLogs: phát hiện đường dẫn không hợp lệ.");
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!System.IO.File.Exists(path))
|
||||
{
|
||||
Logger.Warning($"GetLogs: không tìm thấy file log của ngày {date.ToShortDateString()} - {path}.");
|
||||
return [];
|
||||
}
|
||||
|
||||
temp = Path.Combine(LoggerDirectory, $"{Guid.NewGuid()}.log");
|
||||
System.IO.File.Copy(path, temp);
|
||||
return await System.IO.File.ReadAllLinesAsync(temp);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Logger.Warning($"GetLogs: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return [];
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (System.IO.File.Exists(temp)) System.IO.File.Delete(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
249
RobotNet.MapManager/Controllers/MapExportController.cs
Normal file
249
RobotNet.MapManager/Controllers/MapExportController.cs
Normal file
@@ -0,0 +1,249 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapManager.Services;
|
||||
using RobotNet.MapShares;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.Shares;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class MapExportController(MapEditorDbContext MapDb, MapEditorStorageRepository StorageRepo, IHttpClientFactory HttpClientFactory, LoggerController<MapExportController> Logger) : ControllerBase
|
||||
{
|
||||
private readonly byte[] Key = Encoding.UTF8.GetBytes("2512199802031998");
|
||||
private readonly byte[] IV = Encoding.UTF8.GetBytes("2512199802031998");
|
||||
|
||||
[HttpGet]
|
||||
[Route("encrypt/{Id}")]
|
||||
public async Task<IActionResult> EncryptMap(Guid Id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Id == Id);
|
||||
if (map is null) return NotFound($"Map {Id} không tồn tại");
|
||||
|
||||
var (usingLocal, url) = StorageRepo.GetUrl("MapImages", $"{Id}");
|
||||
byte[] imageData = await GetImageDataAsync(usingLocal, url);
|
||||
|
||||
var elementModels = MapDb.ElementModels.Where(n => n.MapId == Id);
|
||||
List<ElementModelExportDto> ElementModelExport = [];
|
||||
foreach (var elementModel in elementModels)
|
||||
{
|
||||
var getImageOpen = StorageRepo.GetUrl("ElementOpenModels", elementModel.Id.ToString());
|
||||
byte[] imageElementModelOpenData = await GetImageDataAsync(getImageOpen.usingLocal, getImageOpen.url);
|
||||
|
||||
var getImageClose = StorageRepo.GetUrl("ElementCloseModels", elementModel.Id.ToString());
|
||||
byte[] imageElementModelCloseData = await GetImageDataAsync(getImageClose.usingLocal, getImageClose.url);
|
||||
|
||||
ElementModelExport.Add(new ElementModelExportDto()
|
||||
{
|
||||
Id = elementModel.Id,
|
||||
Height = elementModel.Height,
|
||||
Width = elementModel.Width,
|
||||
Image1Height = elementModel.Image1Height,
|
||||
Image2Height = elementModel.Image2Height,
|
||||
Image1Width = elementModel.Image1Width,
|
||||
Image2Width = elementModel.Image2Width,
|
||||
Name = elementModel.Name,
|
||||
Content = elementModel.Content,
|
||||
ImageOpenData = imageElementModelOpenData,
|
||||
ImageCloseData = imageElementModelCloseData,
|
||||
});
|
||||
}
|
||||
var nodes = MapDb.Nodes.Where(n => n.MapId == Id);
|
||||
var edges = MapDb.Edges.Where(n => n.MapId == Id);
|
||||
var zones = MapDb.Zones.Where(n => n.MapId == Id);
|
||||
var actions = MapDb.Actions.Where(n => n.MapId == Id);
|
||||
var elements = MapDb.Elements.Where(n => n.MapId == Id);
|
||||
|
||||
var mapDto = new MapExportDto()
|
||||
{
|
||||
Id = Id,
|
||||
Name = map.Name,
|
||||
Description = map.Description,
|
||||
Info = new()
|
||||
{
|
||||
OriginX = map.OriginX,
|
||||
OriginY = map.OriginY,
|
||||
Resolution = map.Resolution,
|
||||
ViewX = map.ViewX,
|
||||
ViewY = map.ViewY,
|
||||
ViewWidth = map.ViewWidth,
|
||||
ViewHeight = map.ViewHeight,
|
||||
VDA5050 = map.VDA5050,
|
||||
},
|
||||
Setting = new()
|
||||
{
|
||||
NodeNameAutoGenerate = map.NodeNameAutoGenerate,
|
||||
NodeNameTemplate = map.NodeNameTemplateDefault,
|
||||
NodeAllowedDeviationXy = map.EdgeAllowedDeviationXyDefault,
|
||||
NodeAllowedDeviationTheta = map.EdgeAllowedDeviationThetaDefault,
|
||||
|
||||
EdgeStraightMaxSpeed = map.EdgeStraightMaxSpeedDefault,
|
||||
EdgeCurveMaxSpeed = map.EdgeCurveMaxSpeedDefault,
|
||||
EdgeMaxRotationSpeed = map.EdgeMaxRotationSpeedDefault,
|
||||
EdgeMinLength = map.EdgeMinLengthDefault,
|
||||
EdgeMaxHeight = map.EdgeMaxHeightDefault,
|
||||
EdgeMinHeight = map.EdgeMinHeightDefault,
|
||||
EdgeRotationAllowed = map.EdgeRotationAllowedDefault,
|
||||
EdgeDirectionAllowed = map.EdgeDirectionAllowedDefault,
|
||||
EdgeAllowedDeviationTheta = map.EdgeAllowedDeviationThetaDefault,
|
||||
EdgeAllowedDeviationXy = map.EdgeAllowedDeviationXyDefault,
|
||||
|
||||
ZoneMinSquare = map.ZoneMinSquareDefault,
|
||||
},
|
||||
Data = new()
|
||||
{
|
||||
NodeCount = map.NodeCount,
|
||||
Nodes = [.. nodes.Select(n => new NodeDto()
|
||||
{
|
||||
Id = n.Id,
|
||||
Name = n.Name,
|
||||
X = n.X,
|
||||
Y = n.Y,
|
||||
Theta = n.Theta,
|
||||
AllowedDeviationXy = n.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = n.AllowedDeviationTheta,
|
||||
Actions = n.Actions,
|
||||
})],
|
||||
Edges = [.. edges.Select(e => new EdgeDto()
|
||||
{
|
||||
ControlPoint1X = e.ControlPoint1X,
|
||||
ControlPoint1Y = e.ControlPoint1Y,
|
||||
ControlPoint2X = e.ControlPoint2X,
|
||||
ControlPoint2Y = e.ControlPoint2Y,
|
||||
TrajectoryDegree = e.TrajectoryDegree,
|
||||
EndNodeId = e.EndNodeId,
|
||||
StartNodeId = e.StartNodeId,
|
||||
DirectionAllowed = e.DirectionAllowed,
|
||||
RotationAllowed = e.RotationAllowed,
|
||||
AllowedDeviationTheta = e.AllowedDeviationTheta,
|
||||
AllowedDeviationXy = e.AllowedDeviationXy,
|
||||
MaxHeight = e.MaxHeight,
|
||||
MinHeight = e.MinHeight,
|
||||
MaxSpeed = e.MaxSpeed,
|
||||
MaxRotationSpeed = e.MaxRotationSpeed,
|
||||
Actions = e.Actions,
|
||||
})],
|
||||
Zones = [.. zones.Select(z => new ZoneDto()
|
||||
{
|
||||
Type = z.Type,
|
||||
X1 = z.X1,
|
||||
Y1 = z.Y1,
|
||||
X2 = z.X2,
|
||||
Y2 = z.Y2,
|
||||
X3 = z.X3,
|
||||
Y3 = z.Y3,
|
||||
X4 = z.X4,
|
||||
Y4 = z.Y4,
|
||||
})],
|
||||
Actions = [.. actions.Select(a => new ActionDto()
|
||||
{
|
||||
Id = a.Id,
|
||||
Name = a.Name,
|
||||
Content = a.Content,
|
||||
})],
|
||||
ElementModels = [.. ElementModelExport],
|
||||
Elements = [.. elements.Select(e => new ElementDto()
|
||||
{
|
||||
Name = e.Name,
|
||||
IsOpen = e.IsOpen,
|
||||
ModelId = e.ModelId,
|
||||
NodeId = e.NodeId,
|
||||
OffsetX = e.OffsetX,
|
||||
OffsetY = e.OffsetY,
|
||||
Content = e.Content,
|
||||
})],
|
||||
ImageData = imageData,
|
||||
}
|
||||
};
|
||||
|
||||
var jsonData = JsonSerializer.Serialize(mapDto, JsonOptionExtends.Write);
|
||||
var data = EncryptDataAES(jsonData, Key, IV);
|
||||
return File(data, "application/octet-stream", $"{map.Name}.map");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"EncryptMap: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return NotFound("Hệ thống có lỗi xảy ra");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("decrypt")]
|
||||
public async Task<MessageResult<MapExportDto>> DecryptMap([FromForm(Name = "importmap")] IFormFile file)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (file == null || file.Length == 0) return new(false, "File không hợp lệ");
|
||||
if (!file.FileName.EndsWith(".map", StringComparison.OrdinalIgnoreCase)) return new(false, "Định dạng file không hợp lệ, yêu cầu file .map");
|
||||
using var memoryStream = new MemoryStream();
|
||||
await file.CopyToAsync(memoryStream);
|
||||
byte[] fileBytes = memoryStream.ToArray();
|
||||
|
||||
var jsonData = DecryptDataAES(fileBytes, Key, IV);
|
||||
var mapData = JsonSerializer.Deserialize<MapExportDto>(jsonData, JsonOptionExtends.Read);
|
||||
if (mapData is null) return new(false, "Dữ liệu không hợp lệ");
|
||||
else return new(true) { Data = mapData };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"EncryptMap: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"EncryptMap: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] EncryptDataAES(string data, byte[] key, byte[] iv)
|
||||
{
|
||||
using Aes aesAlg = Aes.Create();
|
||||
aesAlg.Key = key;
|
||||
aesAlg.IV = iv;
|
||||
|
||||
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
|
||||
|
||||
using MemoryStream msEncrypt = new();
|
||||
using CryptoStream csEncrypt = new(msEncrypt, encryptor, CryptoStreamMode.Write);
|
||||
using (StreamWriter swEncrypt = new(csEncrypt))
|
||||
{
|
||||
swEncrypt.Write(data);
|
||||
}
|
||||
return msEncrypt.ToArray();
|
||||
}
|
||||
|
||||
private static string DecryptDataAES(byte[] data, byte[] key, byte[] iv)
|
||||
{
|
||||
using Aes aesAlg = Aes.Create();
|
||||
aesAlg.Key = key;
|
||||
aesAlg.IV = iv;
|
||||
|
||||
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
|
||||
|
||||
using MemoryStream msDecrypt = new(data);
|
||||
using CryptoStream csDecrypt = new(msDecrypt, decryptor, CryptoStreamMode.Read);
|
||||
using StreamReader srDecrypt = new(csDecrypt);
|
||||
return srDecrypt.ReadToEnd();
|
||||
}
|
||||
|
||||
public async Task<byte[]> GetImageDataAsync(bool usingLocal, string url)
|
||||
{
|
||||
if (!usingLocal)
|
||||
{
|
||||
var http = HttpClientFactory.CreateClient();
|
||||
var response = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
|
||||
if (!response.IsSuccessStatusCode) return [];
|
||||
return await response.Content.ReadAsByteArrayAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (System.IO.File.Exists(url)) return System.IO.File.ReadAllBytes(url);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
381
RobotNet.MapManager/Controllers/MapsDataController.cs
Normal file
381
RobotNet.MapManager/Controllers/MapsDataController.cs
Normal file
@@ -0,0 +1,381 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapManager.Services;
|
||||
using RobotNet.MapShares;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.MapShares.Models;
|
||||
using RobotNet.Shares;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class MapsDataController(MapEditorDbContext MapDb, LoggerController<MapsDataController> Logger) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult<MapDataDto>> GetMapData(Guid id)
|
||||
{
|
||||
var map = await MapDb.Maps.FindAsync(id);
|
||||
if (map is null) return new(false, $"Không tìm thấy bản đồ: {id}");
|
||||
|
||||
var result = new MessageResult<MapDataDto>(true)
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
Id = map.Id,
|
||||
Name = map.Name,
|
||||
OriginX = map.OriginX,
|
||||
OriginY = map.OriginY,
|
||||
Resolution = map.Resolution,
|
||||
ImageHeight = map.ImageHeight,
|
||||
ImageWidth = map.ImageWidth,
|
||||
Active = map.Active,
|
||||
Nodes = [.. MapDb.Nodes.Where(node => node.MapId == id).Select(node => new NodeDto()
|
||||
{
|
||||
Id = node.Id,
|
||||
MapId = node.MapId,
|
||||
Name = node.Name,
|
||||
Theta = node.Theta,
|
||||
X = node.X,
|
||||
Y = node.Y,
|
||||
AllowedDeviationXy = node.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = node.AllowedDeviationTheta,
|
||||
Actions = node.Actions,
|
||||
})],
|
||||
Edges = [.. MapDb.Edges.Where(edge => edge.MapId == id).Select(edge => new EdgeDto()
|
||||
{
|
||||
Id = edge.Id,
|
||||
MapId = edge.MapId,
|
||||
StartNodeId = edge.StartNodeId,
|
||||
EndNodeId = edge.EndNodeId,
|
||||
|
||||
MaxSpeed = edge.MaxSpeed,
|
||||
MaxHeight = edge.MaxHeight,
|
||||
MinHeight = edge.MinHeight,
|
||||
DirectionAllowed = edge.DirectionAllowed,
|
||||
RotationAllowed = edge.RotationAllowed,
|
||||
TrajectoryDegree = edge.TrajectoryDegree,
|
||||
ControlPoint1X = edge.ControlPoint1X,
|
||||
ControlPoint1Y = edge.ControlPoint1Y,
|
||||
ControlPoint2X = edge.ControlPoint2X,
|
||||
ControlPoint2Y = edge.ControlPoint2Y,
|
||||
MaxRotationSpeed = edge.MaxRotationSpeed,
|
||||
Actions = edge.Actions,
|
||||
AllowedDeviationXy = edge.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = edge.AllowedDeviationTheta,
|
||||
})],
|
||||
Zones = [.. MapDb.Zones.Where(zone => zone.MapId == id).Select(zone => new ZoneDto()
|
||||
{
|
||||
Id = zone.Id,
|
||||
MapId = zone.MapId,
|
||||
Type = zone.Type,
|
||||
Name = zone.Name,
|
||||
X1 = zone.X1,
|
||||
X2 = zone.X2,
|
||||
Y1 = zone.Y1,
|
||||
Y2 = zone.Y2,
|
||||
X3 = zone.X3,
|
||||
Y3 = zone.Y3,
|
||||
X4 = zone.X4,
|
||||
Y4 = zone.Y4,
|
||||
}).OrderBy(z => z.Type)],
|
||||
Elements = [.. MapDb.Elements.Where(el => el.MapId == id).Select(element => new ElementDto()
|
||||
{
|
||||
Id = element.Id,
|
||||
MapId = element.MapId,
|
||||
ModelId = element.ModelId,
|
||||
Name = element.Name,
|
||||
NodeId = element.NodeId,
|
||||
OffsetX = element.OffsetX,
|
||||
OffsetY = element.OffsetY,
|
||||
IsOpen = element.IsOpen,
|
||||
Content = element.Content,
|
||||
})],
|
||||
Actions = [.. MapDb.Actions.Where(a => a.MapId == id).Select(action => new ActionDto()
|
||||
{
|
||||
Id = action.Id,
|
||||
MapId = action.MapId,
|
||||
Name = action.Name,
|
||||
Content = action.Content,
|
||||
})]
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("{id}/updates")]
|
||||
public async Task<MessageResult<IEnumerable<EdgeDto>>> Updates(Guid id, MapEditorBackupModel model)
|
||||
{
|
||||
if (model == null || model.Steps == null) return new(false, "Dữ liệu đầu vào không hợp lệ");
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FindAsync(id);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {id}");
|
||||
|
||||
List<EdgeDto> EdgeDtos = [];
|
||||
foreach (var step in model.Steps)
|
||||
{
|
||||
switch (step.Type)
|
||||
{
|
||||
case MapEditorBackupType.Node:
|
||||
PositionBackup? nodeUpdate = JsonSerializer.Deserialize<PositionBackup>(step.Obj.ToString() ?? "", JsonOptionExtends.Read);
|
||||
if (nodeUpdate is not null)
|
||||
{
|
||||
var nodeDb = await MapDb.Nodes.FindAsync(step.Id);
|
||||
if (nodeDb is not null)
|
||||
{
|
||||
nodeDb.X = nodeUpdate.X;
|
||||
nodeDb.Y = nodeUpdate.Y;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MapEditorBackupType.ControlPoint1Edge:
|
||||
PositionBackup? controlPoint1 = JsonSerializer.Deserialize<PositionBackup>(step.Obj.ToString() ?? "", JsonOptionExtends.Read);
|
||||
if (controlPoint1 is not null)
|
||||
{
|
||||
var edgeDb = await MapDb.Edges.FindAsync(step.Id);
|
||||
if (edgeDb is not null)
|
||||
{
|
||||
edgeDb.ControlPoint1X = controlPoint1.X;
|
||||
edgeDb.ControlPoint1Y = controlPoint1.Y;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MapEditorBackupType.ControlPoint2Edge:
|
||||
PositionBackup? controlPoint2 = JsonSerializer.Deserialize<PositionBackup>(step.Obj.ToString() ?? "", JsonOptionExtends.Read);
|
||||
if (controlPoint2 is not null)
|
||||
{
|
||||
var edgeDb = await MapDb.Edges.FindAsync(step.Id);
|
||||
if (edgeDb is not null)
|
||||
{
|
||||
edgeDb.ControlPoint2X = controlPoint2.X;
|
||||
edgeDb.ControlPoint2Y = controlPoint2.Y;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MapEditorBackupType.Zone:
|
||||
ZoneShapeBackup? zoneUpdate = JsonSerializer.Deserialize<ZoneShapeBackup>(step.Obj.ToString() ?? "", JsonOptionExtends.Read);
|
||||
if (zoneUpdate is not null)
|
||||
{
|
||||
var zoneDb = await MapDb.Zones.FindAsync(step.Id);
|
||||
if (zoneDb is not null)
|
||||
{
|
||||
zoneDb.X1 = zoneUpdate.X1;
|
||||
zoneDb.Y1 = zoneUpdate.Y1;
|
||||
zoneDb.X2 = zoneUpdate.X2;
|
||||
zoneDb.Y2 = zoneUpdate.Y2;
|
||||
zoneDb.X3 = zoneUpdate.X3;
|
||||
zoneDb.Y3 = zoneUpdate.Y3;
|
||||
zoneDb.X4 = zoneUpdate.X4;
|
||||
zoneDb.Y4 = zoneUpdate.Y4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MapEditorBackupType.MoveEdge:
|
||||
List<EdgeBackup>? edgesUpdate = JsonSerializer.Deserialize<List<EdgeBackup>>(step.Obj.ToString() ?? "", JsonOptionExtends.Read);
|
||||
if (edgesUpdate is not null && edgesUpdate.Count > 0)
|
||||
{
|
||||
foreach (var edgeUpate in edgesUpdate)
|
||||
{
|
||||
var edgeDb = await MapDb.Edges.FindAsync(edgeUpate.Id);
|
||||
if (edgeDb is not null)
|
||||
{
|
||||
var startNode = await MapDb.Nodes.FindAsync(edgeDb.StartNodeId);
|
||||
var endNode = await MapDb.Nodes.FindAsync(edgeDb.EndNodeId);
|
||||
if (startNode is not null && endNode is not null)
|
||||
{
|
||||
startNode.X = edgeUpate.StartX;
|
||||
startNode.Y = edgeUpate.StartY;
|
||||
endNode.X = edgeUpate.EndX;
|
||||
endNode.Y = edgeUpate.EndY;
|
||||
}
|
||||
edgeDb.ControlPoint1X = edgeUpate.ControlPoint1X;
|
||||
edgeDb.ControlPoint1Y = edgeUpate.ControlPoint1Y;
|
||||
edgeDb.ControlPoint2X = edgeUpate.ControlPoint2X;
|
||||
edgeDb.ControlPoint2Y = edgeUpate.ControlPoint2Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MapEditorBackupType.Copy:
|
||||
List<EdgeMapCopyModel>? edgesCopy = JsonSerializer.Deserialize<List<EdgeMapCopyModel>>(step.Obj.ToString() ?? "", JsonOptionExtends.Read);
|
||||
if (edgesCopy is not null && edgesCopy.Count > 0)
|
||||
{
|
||||
Dictionary<Guid, Node> CreateNewNode = [];
|
||||
foreach (var edgeCopy in edgesCopy)
|
||||
{
|
||||
if (!CreateNewNode.TryGetValue(edgeCopy.StartNodeId, out _))
|
||||
{
|
||||
var startNode = await MapDb.Nodes.FindAsync(edgeCopy.StartNodeId);
|
||||
var newStartNode = await MapDb.Nodes.AddAsync(new Node()
|
||||
{
|
||||
MapId = edgeCopy.MapId,
|
||||
Name = map.NodeNameAutoGenerate ? $"{map.NodeNameTemplateDefault}{++map.NodeCount}" : string.Empty,
|
||||
X = edgeCopy.X1,
|
||||
Y = edgeCopy.Y1,
|
||||
Theta = startNode is not null ? startNode.Theta : 0,
|
||||
Actions = startNode is not null ? startNode.Actions : "",
|
||||
AllowedDeviationXy = startNode is not null ? startNode.AllowedDeviationXy : map.NodeAllowedDeviationXyDefault,
|
||||
AllowedDeviationTheta = startNode is not null ? startNode.AllowedDeviationTheta : map.NodeAllowedDeviationThetaDefault,
|
||||
});
|
||||
CreateNewNode.Add(edgeCopy.StartNodeId, newStartNode.Entity);
|
||||
}
|
||||
if (!CreateNewNode.TryGetValue(edgeCopy.EndNodeId, out _))
|
||||
{
|
||||
var endNode = await MapDb.Nodes.FindAsync(edgeCopy.EndNodeId);
|
||||
var newEndNode = await MapDb.Nodes.AddAsync(new Node()
|
||||
{
|
||||
MapId = edgeCopy.MapId,
|
||||
Name = map.NodeNameAutoGenerate ? $"{map.NodeNameTemplateDefault}{++map.NodeCount}" : string.Empty,
|
||||
X = edgeCopy.X2,
|
||||
Y = edgeCopy.Y2,
|
||||
Theta = endNode is not null ? endNode.Theta : 0,
|
||||
Actions = endNode is not null ? endNode.Actions : "",
|
||||
AllowedDeviationXy = endNode is not null ? endNode.AllowedDeviationXy : map.NodeAllowedDeviationXyDefault,
|
||||
AllowedDeviationTheta = endNode is not null ? endNode.AllowedDeviationTheta : map.NodeAllowedDeviationThetaDefault,
|
||||
});
|
||||
CreateNewNode.Add(edgeCopy.EndNodeId, newEndNode.Entity);
|
||||
}
|
||||
|
||||
var newEdge = await MapDb.Edges.AddAsync(new Edge()
|
||||
{
|
||||
MapId = edgeCopy.MapId,
|
||||
StartNodeId = CreateNewNode[edgeCopy.StartNodeId] is null ? Guid.Empty : CreateNewNode[edgeCopy.StartNodeId].Id,
|
||||
EndNodeId = CreateNewNode[edgeCopy.EndNodeId] is null ? Guid.Empty : CreateNewNode[edgeCopy.EndNodeId].Id,
|
||||
TrajectoryDegree = edgeCopy.TrajectoryDegree,
|
||||
ControlPoint1X = edgeCopy.ControlPoint1X,
|
||||
ControlPoint1Y = edgeCopy.ControlPoint1Y,
|
||||
ControlPoint2X = edgeCopy.ControlPoint2X,
|
||||
ControlPoint2Y = edgeCopy.ControlPoint2Y,
|
||||
DirectionAllowed = edgeCopy.DirectionAllowed,
|
||||
RotationAllowed = edgeCopy.RotationAllowed,
|
||||
MaxSpeed = edgeCopy.MaxSpeed,
|
||||
MaxRotationSpeed = edgeCopy.MaxRotationSpeed,
|
||||
MaxHeight = edgeCopy.MaxHeight,
|
||||
MinHeight = edgeCopy.MinHeight,
|
||||
Actions = edgeCopy.Actions,
|
||||
AllowedDeviationTheta = edgeCopy.AllowedDeviationTheta,
|
||||
AllowedDeviationXy = edgeCopy.AllowedDeviationXy,
|
||||
});
|
||||
EdgeDtos.Add(new()
|
||||
{
|
||||
|
||||
Id = newEdge.Entity.Id,
|
||||
MapId = newEdge.Entity.MapId,
|
||||
StartNodeId = newEdge.Entity.StartNodeId,
|
||||
EndNodeId = newEdge.Entity.EndNodeId,
|
||||
TrajectoryDegree = newEdge.Entity.TrajectoryDegree,
|
||||
ControlPoint1X = newEdge.Entity.ControlPoint1X,
|
||||
ControlPoint1Y = newEdge.Entity.ControlPoint1Y,
|
||||
ControlPoint2X = newEdge.Entity.ControlPoint2X,
|
||||
ControlPoint2Y = newEdge.Entity.ControlPoint2Y,
|
||||
DirectionAllowed = newEdge.Entity.DirectionAllowed,
|
||||
RotationAllowed = newEdge.Entity.RotationAllowed,
|
||||
MaxSpeed = newEdge.Entity.MaxSpeed,
|
||||
MaxRotationSpeed = newEdge.Entity.MaxRotationSpeed,
|
||||
MaxHeight = newEdge.Entity.MaxHeight,
|
||||
MinHeight = newEdge.Entity.MinHeight,
|
||||
Actions = newEdge.Entity.Actions,
|
||||
AllowedDeviationXy = newEdge.Entity.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = newEdge.Entity.AllowedDeviationTheta,
|
||||
StartNode = new NodeDto()
|
||||
{
|
||||
Id = CreateNewNode[edgeCopy.StartNodeId].Id,
|
||||
Name = CreateNewNode[edgeCopy.StartNodeId].Name,
|
||||
MapId = CreateNewNode[edgeCopy.StartNodeId].MapId,
|
||||
Theta = CreateNewNode[edgeCopy.StartNodeId].Theta,
|
||||
X = CreateNewNode[edgeCopy.StartNodeId].X,
|
||||
Y = CreateNewNode[edgeCopy.StartNodeId].Y,
|
||||
AllowedDeviationXy = CreateNewNode[edgeCopy.StartNodeId].AllowedDeviationXy,
|
||||
AllowedDeviationTheta = CreateNewNode[edgeCopy.StartNodeId].AllowedDeviationTheta,
|
||||
Actions = CreateNewNode[edgeCopy.StartNodeId].Actions,
|
||||
},
|
||||
EndNode = new NodeDto()
|
||||
{
|
||||
Id = CreateNewNode[edgeCopy.EndNodeId].Id,
|
||||
Name = CreateNewNode[edgeCopy.EndNodeId].Name,
|
||||
MapId = CreateNewNode[edgeCopy.EndNodeId].MapId,
|
||||
Theta = CreateNewNode[edgeCopy.EndNodeId].Theta,
|
||||
X = CreateNewNode[edgeCopy.EndNodeId].X,
|
||||
Y = CreateNewNode[edgeCopy.EndNodeId].Y,
|
||||
AllowedDeviationXy = CreateNewNode[edgeCopy.EndNodeId].AllowedDeviationXy,
|
||||
AllowedDeviationTheta = CreateNewNode[edgeCopy.EndNodeId].AllowedDeviationTheta,
|
||||
Actions = CreateNewNode[edgeCopy.EndNodeId].Actions,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MapEditorBackupType.SplitNode:
|
||||
var nodeSplit = await MapDb.Nodes.FindAsync(step.Id);
|
||||
if (nodeSplit is not null)
|
||||
{
|
||||
SplitNodeBackup? SplitNodeUpdate = JsonSerializer.Deserialize<SplitNodeBackup>(step.Obj.ToString() ?? "", JsonOptionExtends.Read);
|
||||
if (SplitNodeUpdate is not null)
|
||||
{
|
||||
foreach (var data in SplitNodeUpdate.EdgeSplit)
|
||||
{
|
||||
var edge = await MapDb.Edges.FindAsync(data.Key);
|
||||
if (edge is not null)
|
||||
{
|
||||
var newNode = new Node()
|
||||
{
|
||||
Id = data.Value.Id,
|
||||
Name = data.Value.Name,
|
||||
X = data.Value.X,
|
||||
Y = data.Value.Y,
|
||||
Theta = data.Value.Theta,
|
||||
MapId = data.Value.MapId,
|
||||
AllowedDeviationXy = data.Value.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = data.Value.AllowedDeviationTheta,
|
||||
Actions = data.Value.Actions,
|
||||
};
|
||||
if (edge.StartNodeId == nodeSplit.Id) edge.StartNodeId = newNode.Id;
|
||||
else if (edge.EndNodeId == nodeSplit.Id) edge.EndNodeId = newNode.Id;
|
||||
else continue;
|
||||
await MapDb.Nodes.AddAsync(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MapEditorBackupType.MergeNode:
|
||||
var nodemerge = await MapDb.Nodes.FindAsync(step.Id);
|
||||
if (nodemerge is not null)
|
||||
{
|
||||
MergeNodeUpdate? MergeNodeUpdate = JsonSerializer.Deserialize<MergeNodeUpdate>(step.Obj.ToString() ?? "", JsonOptionExtends.Read);
|
||||
if (MergeNodeUpdate is not null)
|
||||
{
|
||||
foreach (var data in MergeNodeUpdate.EdgesMerge)
|
||||
{
|
||||
var edge = await MapDb.Edges.FindAsync(data.Key);
|
||||
if (edge is not null)
|
||||
{
|
||||
var rmNode = await MapDb.Nodes.FindAsync(data.Value);
|
||||
if (edge.StartNodeId == data.Value) edge.StartNodeId = nodemerge.Id;
|
||||
else if (edge.EndNodeId == data.Value) edge.EndNodeId = nodemerge.Id;
|
||||
if (rmNode is not null) MapDb.Nodes.Remove(rmNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
Logger.Info($"User {HttpContext.User.Identity?.Name} đã cập nhật dữ liệu cho bản đồ: {map.Name} - {map.Id}");
|
||||
return new(true) { Data = EdgeDtos };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Updates: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, "Hệ thống có lỗi xảy ra");
|
||||
}
|
||||
}
|
||||
}
|
||||
571
RobotNet.MapManager/Controllers/MapsManagerController.cs
Normal file
571
RobotNet.MapManager/Controllers/MapsManagerController.cs
Normal file
@@ -0,0 +1,571 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapManager.Hubs;
|
||||
using RobotNet.MapManager.Services;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.MapShares.Enums;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class MapsManagerController(MapEditorDbContext MapDb, MapEditorStorageRepository StorageRepo, IHubContext<MapHub> MapHub, LoggerController<MapsManagerController> Logger) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
public async Task<IEnumerable<MapInfoDto>> GetMapInfos([FromQuery(Name = "txtSearch")] string? txtSearch)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(txtSearch))
|
||||
{
|
||||
return await (from map in MapDb.Maps
|
||||
select new MapInfoDto()
|
||||
{
|
||||
Id = map.Id,
|
||||
VersionId = map.VersionId,
|
||||
Name = map.Name,
|
||||
Description = map.Description,
|
||||
Active = map.Active,
|
||||
OriginX = map.OriginX,
|
||||
OriginY = map.OriginY,
|
||||
Width = Math.Round(map.ImageWidth * map.Resolution, 2),
|
||||
Height = Math.Round(map.ImageHeight * map.Resolution, 2),
|
||||
Resolution = map.Resolution,
|
||||
VDA5050 = map.VDA5050,
|
||||
}).ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
return await (from map in MapDb.Maps
|
||||
where !string.IsNullOrEmpty(map.Name) && map.Name.Contains(txtSearch)
|
||||
select new MapInfoDto()
|
||||
{
|
||||
Id = map.Id,
|
||||
VersionId = map.VersionId,
|
||||
Name = map.Name,
|
||||
Description = map.Description,
|
||||
Active = map.Active,
|
||||
OriginX = map.OriginX,
|
||||
OriginY = map.OriginY,
|
||||
Width = Math.Round(map.ImageWidth * map.Resolution, 2),
|
||||
Height = Math.Round(map.ImageHeight * map.Resolution, 2),
|
||||
Resolution = map.Resolution,
|
||||
VDA5050 = map.VDA5050,
|
||||
}).ToListAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"GetMapInfos: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult<MapInfoDto>> GetMapInfoId(Guid id)
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Id == id);
|
||||
if (map == null) return new MessageResult<MapInfoDto>(false, $"Không tìm thấy map {id}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new MapInfoDto()
|
||||
{
|
||||
Id = map.Id,
|
||||
Name = map.Name,
|
||||
Active = map.Active,
|
||||
OriginX = map.OriginX,
|
||||
OriginY = map.OriginY,
|
||||
Width = Math.Round(map.ImageWidth * map.Resolution, 2),
|
||||
Height = Math.Round(map.ImageHeight * map.Resolution, 2),
|
||||
Resolution = map.Resolution,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("info")]
|
||||
public async Task<MessageResult<MapInfoDto>> GetMapInfoName([FromQuery(Name = "name")] string name)
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == name);
|
||||
if (map == null) return new MessageResult<MapInfoDto>(false, $"Không tìm thấy map {name}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new MapInfoDto()
|
||||
{
|
||||
Id = map.Id,
|
||||
Name = map.Name,
|
||||
Active = map.Active,
|
||||
OriginX = map.OriginX,
|
||||
OriginY = map.OriginY,
|
||||
Width = Math.Round(map.ImageWidth * map.Resolution, 2),
|
||||
Height = Math.Round(map.ImageHeight * map.Resolution, 2),
|
||||
Resolution = map.Resolution,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("")]
|
||||
public async Task<MessageResult<MapInfoDto>> CreateMap([FromForm] MapCreateModel model, [FromForm(Name = "Image")] IFormFile imageUpload)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (imageUpload is null) return new(false, "Dữ liệu không hợp lệ");
|
||||
if (imageUpload.ContentType != "image/png") return new(false, "Ảnh map chỉ hỗ trợ định dạng image/png");
|
||||
if (await MapDb.Maps.AnyAsync(map => map.Name == model.Name)) return new(false, "Tên của map đã tồn tại. Hãy đặt tên khác!");
|
||||
|
||||
var image = SixLabors.ImageSharp.Image.Load(imageUpload.OpenReadStream());
|
||||
|
||||
var entityMap = await MapDb.Maps.AddAsync(new Map()
|
||||
{
|
||||
Name = model.Name,
|
||||
OriginX = model.OriginX,
|
||||
OriginY = model.OriginY,
|
||||
Resolution = model.Resolution,
|
||||
ImageHeight = (ushort)image.Height,
|
||||
ImageWidth = (ushort)image.Width,
|
||||
Active = false,
|
||||
|
||||
NodeCount = 0,
|
||||
NodeNameAutoGenerate = true,
|
||||
NodeNameTemplateDefault = "Node",
|
||||
NodeAllowedDeviationXyDefault = 0.1,
|
||||
NodeAllowedDeviationThetaDefault = 0,
|
||||
|
||||
EdgeMinLengthDefault = 1,
|
||||
EdgeMaxHeightDefault = 1,
|
||||
EdgeMinHeightDefault = 0.1,
|
||||
EdgeStraightMaxSpeedDefault = 1,
|
||||
EdgeCurveMaxSpeedDefault = 0.3,
|
||||
EdgeMaxRotationSpeedDefault = 0.5,
|
||||
EdgeAllowedDeviationXyDefault = 0.1,
|
||||
EdgeAllowedDeviationThetaDefault = 0,
|
||||
EdgeRotationAllowedDefault = true,
|
||||
EdgeDirectionAllowedDefault = DirectionAllowed.Both,
|
||||
|
||||
ZoneMinSquareDefault = 0.25,
|
||||
});
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
var (isSuccess, message) = await StorageRepo.UploadAsync("MapImages", $"{entityMap.Entity.Id}", imageUpload.OpenReadStream(), imageUpload.Length, imageUpload.ContentType, CancellationToken.None);
|
||||
if (!isSuccess)
|
||||
{
|
||||
MapDb.Maps.Remove(entityMap.Entity);
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(false, message);
|
||||
}
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
Logger.Info($"User {HttpContext.User.Identity?.Name} đã tạo bản đồ mới với tên: {model.Name}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new MapInfoDto()
|
||||
{
|
||||
Id = entityMap.Entity.Id,
|
||||
Name = entityMap.Entity.Name,
|
||||
Active = entityMap.Entity.Active,
|
||||
OriginX = entityMap.Entity.OriginX,
|
||||
OriginY = entityMap.Entity.OriginY,
|
||||
Width = entityMap.Entity.ImageWidth * entityMap.Entity.Resolution,
|
||||
Height = entityMap.Entity.ImageHeight * entityMap.Entity.Resolution,
|
||||
Resolution = entityMap.Entity.Resolution,
|
||||
},
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"CreateMap: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"CreateMap: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult<MapInfoDto>> UpdateMap(Guid id, [FromBody] MapUpdateModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (id != model.Id) return new(false, "Dữ liệu gửi không chính xác");
|
||||
|
||||
var map = await MapDb.Maps.FindAsync(id);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {id}");
|
||||
|
||||
if (map.Name != model.Name && await MapDb.Maps.AnyAsync(m => m.Name == model.Name))
|
||||
{
|
||||
return new(false, "Tên của map đã tồn tại, Hãy đặt tên khác!");
|
||||
}
|
||||
|
||||
if (model.Resolution <= 0)
|
||||
{
|
||||
return new(false, "Độ phân giải của bản đồ phải lớn hơn 0");
|
||||
}
|
||||
|
||||
map.Name = model.Name;
|
||||
bool originChange = map.OriginX != model.OriginX || map.OriginY != model.OriginY;
|
||||
if (originChange)
|
||||
{
|
||||
map.OriginX = model.OriginX;
|
||||
map.OriginY = model.OriginY;
|
||||
}
|
||||
if (map.Resolution != model.Resolution)
|
||||
{
|
||||
var scale = model.Resolution / map.Resolution;
|
||||
map.Resolution = model.Resolution;
|
||||
if (originChange)
|
||||
{
|
||||
map.OriginX *= scale;
|
||||
map.OriginY *= scale;
|
||||
}
|
||||
|
||||
var nodes = await MapDb.Nodes.Where(n => n.MapId == map.Id).ToListAsync();
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
node.X *= scale;
|
||||
node.Y *= scale;
|
||||
}
|
||||
|
||||
var edges = await MapDb.Edges.Where(e => e.MapId == map.Id).ToListAsync();
|
||||
foreach (var edge in edges)
|
||||
{
|
||||
edge.ControlPoint1X *= scale;
|
||||
edge.ControlPoint1Y *= scale;
|
||||
edge.ControlPoint2X *= scale;
|
||||
edge.ControlPoint2Y *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
Logger.Info($"User {HttpContext.User.Identity?.Name} đã cập nhật thông tin bản đồ : {model.Id} - {map.Name}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
Id = id,
|
||||
Name = map.Name,
|
||||
OriginX = map.OriginX,
|
||||
OriginY = map.OriginY,
|
||||
Resolution = model.Resolution,
|
||||
Width = Math.Round(map.ImageWidth * map.Resolution, 2),
|
||||
Height = Math.Round(map.ImageHeight * map.Resolution, 2),
|
||||
},
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"UpdateMap {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"UpdateMap {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult> DeleteMap(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FindAsync(id);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {id}");
|
||||
|
||||
MapDb.Elements.RemoveRange(MapDb.Elements.Where(e => e.MapId == map.Id));
|
||||
MapDb.ElementModels.RemoveRange(MapDb.ElementModels.Where(em => em.MapId == map.Id));
|
||||
MapDb.Edges.RemoveRange(MapDb.Edges.Where(edge => edge.MapId == map.Id));
|
||||
MapDb.Nodes.RemoveRange(MapDb.Nodes.Where(node => node.MapId == map.Id));
|
||||
MapDb.Zones.RemoveRange(MapDb.Zones.Where(zone => zone.MapId == map.Id));
|
||||
MapDb.Actions.RemoveRange(MapDb.Actions.Where(action => action.MapId == map.Id));
|
||||
MapDb.Maps.Remove(map);
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
await StorageRepo.DeleteAsync("MapImages", $"{id}", CancellationToken.None);
|
||||
|
||||
Logger.Info($"User {HttpContext.User.Identity?.Name} đã xóa bản đồ {map.Name}");
|
||||
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"DeleteMap {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"DeleteMap {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("active")]
|
||||
public async Task<MessageResult> ActiveToggle([FromBody] MapActiveModel model)
|
||||
{
|
||||
var map = await MapDb.Maps.FindAsync(model.Id);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {model.Id}");
|
||||
|
||||
map.Active = model.Active;
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
await MapHub.Clients.All.SendAsync("MapUpdated", model.Id);
|
||||
|
||||
Logger.Info($"User {HttpContext.User.Identity?.Name} đã thay đổi trạng thái active bản đồ {map.Name}: {model.Active}");
|
||||
|
||||
return new(true);
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("image/{id}")]
|
||||
public async Task<MessageResult> UpdateImage(Guid id, [FromForm(Name = "image")] IFormFile image)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FindAsync(id);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {id}");
|
||||
|
||||
var imageStream = image.OpenReadStream();
|
||||
var imageUpdate = SixLabors.ImageSharp.Image.Load(imageStream);
|
||||
map.ImageWidth = (ushort)imageUpdate.Width;
|
||||
map.ImageHeight = (ushort)imageUpdate.Height;
|
||||
await MapDb.SaveChangesAsync();
|
||||
var (isSuccess, message) = await StorageRepo.UploadAsync("MapImages", $"{id}", image.OpenReadStream(), image.Length, image.ContentType, CancellationToken.None);
|
||||
|
||||
Logger.Info($"User {HttpContext.User.Identity?.Name} đã thay đổi ảnh của bản đồ {map.Name}");
|
||||
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"UpdateImage {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"UpdateImage {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("import")]
|
||||
public async Task<MessageResult<MapInfoDto>> ImportNewMap([FromBody] MapExportDto model)
|
||||
{
|
||||
if (model == null || model.Data == null || model.Data.ImageData == null || model.Data.ImageData.Length == 0)
|
||||
{
|
||||
return new(false, "Dữ liệu đầu vào không hợp lệ");
|
||||
}
|
||||
|
||||
using var transaction = await MapDb.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
if (await MapDb.Maps.AnyAsync(map => map.Name == model.Name)) return new(false, "Tên của map đã tồn tại, Hãy đặt tên khác!");
|
||||
|
||||
using var stream = new MemoryStream(model.Data.ImageData);
|
||||
var imageFile = new FormFile(stream, 0, model.Data.ImageData.Length, "", $"{model.Name}.png")
|
||||
{
|
||||
Headers = new HeaderDictionary(),
|
||||
ContentType = "image/png",
|
||||
};
|
||||
var image = SixLabors.ImageSharp.Image.Load(imageFile.OpenReadStream());
|
||||
|
||||
var entityMap = await MapDb.Maps.AddAsync(new Map()
|
||||
{
|
||||
Name = model.Name,
|
||||
Description = model.Description,
|
||||
OriginX = model.Info.OriginX,
|
||||
OriginY = model.Info.OriginY,
|
||||
Resolution = model.Info.Resolution,
|
||||
ImageHeight = (ushort)image.Height,
|
||||
ImageWidth = (ushort)image.Width,
|
||||
Active = false,
|
||||
ViewX = model.Info.ViewX,
|
||||
ViewY = model.Info.ViewY,
|
||||
ViewWidth = model.Info.ViewWidth,
|
||||
ViewHeight = model.Info.ViewHeight,
|
||||
VDA5050 = model.Info.VDA5050,
|
||||
|
||||
NodeCount = model.Data.NodeCount,
|
||||
NodeNameAutoGenerate = model.Setting.NodeNameAutoGenerate,
|
||||
NodeNameTemplateDefault = model.Setting.NodeNameTemplate,
|
||||
NodeAllowedDeviationXyDefault = model.Setting.NodeAllowedDeviationXy,
|
||||
NodeAllowedDeviationThetaDefault = model.Setting.NodeAllowedDeviationTheta,
|
||||
|
||||
EdgeMinLengthDefault = model.Setting.EdgeMinLength,
|
||||
EdgeMaxHeightDefault = model.Setting.EdgeMaxHeight,
|
||||
EdgeMinHeightDefault = model.Setting.EdgeMinHeight,
|
||||
EdgeStraightMaxSpeedDefault = model.Setting.EdgeStraightMaxSpeed,
|
||||
EdgeCurveMaxSpeedDefault = model.Setting.EdgeCurveMaxSpeed,
|
||||
EdgeMaxRotationSpeedDefault = model.Setting.EdgeMaxRotationSpeed,
|
||||
EdgeAllowedDeviationXyDefault = model.Setting.EdgeAllowedDeviationXy,
|
||||
EdgeAllowedDeviationThetaDefault = model.Setting.EdgeAllowedDeviationTheta,
|
||||
EdgeRotationAllowedDefault = model.Setting.EdgeRotationAllowed,
|
||||
EdgeDirectionAllowedDefault = model.Setting.EdgeDirectionAllowed,
|
||||
|
||||
ZoneMinSquareDefault = model.Setting.ZoneMinSquare,
|
||||
});
|
||||
|
||||
var (isSuccess, message) = await StorageRepo.UploadAsync("MapImages", $"{entityMap.Entity.Id}", imageFile.OpenReadStream(), imageFile.Length, imageFile.ContentType, CancellationToken.None);
|
||||
if (!isSuccess)
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
return new(false, message);
|
||||
}
|
||||
|
||||
Dictionary<Guid, Guid> actionSwap = [];
|
||||
foreach (var action in model.Data.Actions)
|
||||
{
|
||||
var actionDb = await MapDb.Actions.AddAsync(new Data.Action()
|
||||
{
|
||||
MapId = entityMap.Entity.Id,
|
||||
Name = action.Name,
|
||||
Content = action.Content,
|
||||
});
|
||||
actionSwap.Add(action.Id, actionDb.Entity.Id);
|
||||
}
|
||||
|
||||
Dictionary<Guid, Guid> nodeSwap = [];
|
||||
foreach (var node in model.Data.Nodes)
|
||||
{
|
||||
var actions = System.Text.Json.JsonSerializer.Deserialize<Guid[]>(node.Actions ?? "");
|
||||
List<Guid> newActions = [];
|
||||
if (actions is not null && actions.Length > 0)
|
||||
{
|
||||
foreach (var actionId in actions)
|
||||
{
|
||||
if (actionSwap.TryGetValue(actionId, out Guid newActionId) && newActionId != Guid.Empty) newActions.Add(newActionId);
|
||||
}
|
||||
}
|
||||
var nodeDb = await MapDb.Nodes.AddAsync(new Node()
|
||||
{
|
||||
Name = node.Name,
|
||||
MapId = entityMap.Entity.Id,
|
||||
X = node.X,
|
||||
Y = node.Y,
|
||||
Theta = node.Theta,
|
||||
AllowedDeviationXy = node.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = node.AllowedDeviationTheta,
|
||||
Actions = System.Text.Json.JsonSerializer.Serialize(newActions),
|
||||
});
|
||||
nodeSwap.Add(node.Id, nodeDb.Entity.Id);
|
||||
}
|
||||
|
||||
var Edges = model.Data.Edges.Select(e => new Edge()
|
||||
{
|
||||
MapId = entityMap.Entity.Id,
|
||||
StartNodeId = nodeSwap[e.StartNodeId],
|
||||
EndNodeId = nodeSwap[e.EndNodeId],
|
||||
ControlPoint1X = e.ControlPoint1X,
|
||||
ControlPoint1Y = e.ControlPoint1Y,
|
||||
ControlPoint2X = e.ControlPoint2X,
|
||||
ControlPoint2Y = e.ControlPoint2Y,
|
||||
TrajectoryDegree = e.TrajectoryDegree,
|
||||
MaxHeight = e.MaxHeight,
|
||||
MinHeight = e.MinHeight,
|
||||
MaxSpeed = e.MaxSpeed,
|
||||
MaxRotationSpeed = e.MaxRotationSpeed,
|
||||
AllowedDeviationXy = e.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = e.AllowedDeviationTheta,
|
||||
DirectionAllowed = e.DirectionAllowed,
|
||||
RotationAllowed = e.RotationAllowed,
|
||||
Actions = e.Actions,
|
||||
}).ToList();
|
||||
|
||||
var Zones = model.Data.Zones.Select(z => new Zone()
|
||||
{
|
||||
MapId = entityMap.Entity.Id,
|
||||
Type = z.Type,
|
||||
X1 = z.X1,
|
||||
X2 = z.X2,
|
||||
Y1 = z.Y1,
|
||||
Y2 = z.Y2,
|
||||
X3 = z.X3,
|
||||
X4 = z.X4,
|
||||
Y3 = z.Y3,
|
||||
Y4 = z.Y4,
|
||||
}).ToList();
|
||||
|
||||
Dictionary<Guid, Guid> elementModelSwap = [];
|
||||
foreach (var elementModel in model.Data.ElementModels)
|
||||
{
|
||||
var elementModelDb = await MapDb.ElementModels.AddAsync(new ElementModel()
|
||||
{
|
||||
MapId = entityMap.Entity.Id,
|
||||
Name = elementModel.Name,
|
||||
Height = elementModel.Height,
|
||||
Width = elementModel.Width,
|
||||
Image1Height = elementModel.Image1Height,
|
||||
Image1Width = elementModel.Image1Width,
|
||||
Image2Height = elementModel.Image2Height,
|
||||
Image2Width = elementModel.Image2Width,
|
||||
Content = elementModel.Content,
|
||||
});
|
||||
elementModelSwap.Add(elementModel.Id, elementModelDb.Entity.Id);
|
||||
|
||||
using var openStream = new MemoryStream(elementModel.ImageOpenData);
|
||||
var imageOpenFile = new FormFile(openStream, 0, elementModel.ImageOpenData.Length, "", $"{elementModel.Name}O.png")
|
||||
{
|
||||
Headers = new HeaderDictionary(),
|
||||
ContentType = "image/png",
|
||||
};
|
||||
await StorageRepo.UploadAsync("ElementOpenModels", $"{elementModelDb.Entity.Id}", imageOpenFile.OpenReadStream(), imageOpenFile.Length, imageOpenFile.ContentType, CancellationToken.None);
|
||||
|
||||
using var closeStream = new MemoryStream(elementModel.ImageCloseData);
|
||||
var imageCloseFile = new FormFile(closeStream, 0, elementModel.ImageCloseData.Length, "", $"{elementModel.Name}C.png")
|
||||
{
|
||||
Headers = new HeaderDictionary(),
|
||||
ContentType = "image/png",
|
||||
};
|
||||
await StorageRepo.UploadAsync("ElementCloseModels", $"{elementModelDb.Entity.Id}", imageCloseFile.OpenReadStream(), imageCloseFile.Length, imageCloseFile.ContentType, CancellationToken.None);
|
||||
}
|
||||
|
||||
var Elements = model.Data.Elements.Select(e => new Data.Element()
|
||||
{
|
||||
MapId = entityMap.Entity.Id,
|
||||
Name = e.Name,
|
||||
IsOpen = e.IsOpen,
|
||||
ModelId = elementModelSwap[e.ModelId],
|
||||
Content = e.Content,
|
||||
NodeId = nodeSwap[e.NodeId],
|
||||
OffsetX = e.OffsetX,
|
||||
OffsetY = e.OffsetY,
|
||||
}).ToList();
|
||||
|
||||
if (Edges.Count > 0) await MapDb.Edges.AddRangeAsync(Edges);
|
||||
if (Zones.Count > 0) await MapDb.Zones.AddRangeAsync(Zones);
|
||||
if (Elements.Count > 0) await MapDb.Elements.AddRangeAsync(Elements);
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
await transaction.CommitAsync();
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new MapInfoDto()
|
||||
{
|
||||
Id = entityMap.Entity.Id,
|
||||
Name = entityMap.Entity.Name,
|
||||
Active = entityMap.Entity.Active,
|
||||
OriginX = entityMap.Entity.OriginX,
|
||||
OriginY = entityMap.Entity.OriginY,
|
||||
Width = entityMap.Entity.ImageWidth * entityMap.Entity.Resolution,
|
||||
Height = entityMap.Entity.ImageHeight * entityMap.Entity.Resolution,
|
||||
Resolution = entityMap.Entity.Resolution,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
Logger.Warning($"ImportNewMap: Lỗi khi xử lý hình ảnh: {ex.Message}");
|
||||
return new(false, $"ImportNewMap: Lỗi khi xử lý hình ảnh: {ex.Message}");
|
||||
}
|
||||
catch (DbUpdateException ex)
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
Logger.Warning($"ImportNewMap: Lỗi khi lưu vào database: {ex.Message}");
|
||||
return new(false, $"ImportNewMap: Lỗi khi lưu vào database: {ex.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
Logger.Warning($"ImportNewMap: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"ImportNewMap: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
79
RobotNet.MapManager/Controllers/MapsSettingController.cs
Normal file
79
RobotNet.MapManager/Controllers/MapsSettingController.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class MapsSettingController(MapEditorDbContext MapDb) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult<MapSettingDefaultDto>> GetMapSetting(Guid id)
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Id == id);
|
||||
if (map == null) return new(false, $"Không tìm thấy map {id}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new MapSettingDefaultDto()
|
||||
{
|
||||
Id = map.Id,
|
||||
EdgeStraightMaxSpeed = map.EdgeStraightMaxSpeedDefault,
|
||||
EdgeCurveMaxSpeed = map.EdgeCurveMaxSpeedDefault,
|
||||
EdgeMaxHeight = map.EdgeMaxHeightDefault,
|
||||
EdgeMinHeight = map.EdgeMinHeightDefault,
|
||||
EdgeMinLength = map.EdgeMinLengthDefault,
|
||||
EdgeDirectionAllowed = map.EdgeDirectionAllowedDefault,
|
||||
EdgeMaxRotationSpeed = map.EdgeMaxRotationSpeedDefault,
|
||||
EdgeRotationAllowed = map.EdgeRotationAllowedDefault,
|
||||
EdgeAllowedDeviationXy = map.EdgeAllowedDeviationXyDefault,
|
||||
EdgeAllowedDeviationTheta = map.EdgeAllowedDeviationThetaDefault,
|
||||
|
||||
NodeAllowedDeviationTheta = map.NodeAllowedDeviationThetaDefault,
|
||||
NodeAllowedDeviationXy = map.NodeAllowedDeviationXyDefault,
|
||||
NodeNameAutoGenerate = map.NodeNameAutoGenerate,
|
||||
NodeNameTemplate = map.NodeNameTemplateDefault,
|
||||
|
||||
ZoneMinSquare = map.ZoneMinSquareDefault,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[HttpPut]
|
||||
[Route("")]
|
||||
public async Task<MessageResult> Update([FromBody] MapSettingDefaultDto mapSetting)
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Id == mapSetting.Id);
|
||||
if (map == null) return new(false, $"Không tìm thấy map {mapSetting.Id}");
|
||||
|
||||
map.EdgeStraightMaxSpeedDefault = mapSetting.EdgeStraightMaxSpeed;
|
||||
map.EdgeCurveMaxSpeedDefault = mapSetting.EdgeCurveMaxSpeed;
|
||||
map.EdgeMaxHeightDefault = mapSetting.EdgeMaxHeight;
|
||||
map.EdgeMinHeightDefault = mapSetting.EdgeMinHeight;
|
||||
map.EdgeMinLengthDefault = mapSetting.EdgeMinLength;
|
||||
map.EdgeDirectionAllowedDefault = mapSetting.EdgeDirectionAllowed;
|
||||
map.EdgeMaxRotationSpeedDefault = mapSetting.EdgeMaxRotationSpeed;
|
||||
map.EdgeRotationAllowedDefault = mapSetting.EdgeRotationAllowed;
|
||||
map.EdgeAllowedDeviationXyDefault = mapSetting.EdgeAllowedDeviationXy;
|
||||
map.EdgeAllowedDeviationThetaDefault = mapSetting.EdgeAllowedDeviationTheta;
|
||||
|
||||
map.NodeAllowedDeviationThetaDefault = mapSetting.NodeAllowedDeviationTheta;
|
||||
map.NodeAllowedDeviationXyDefault = mapSetting.NodeAllowedDeviationXy;
|
||||
map.NodeNameAutoGenerate = mapSetting.NodeNameAutoGenerate;
|
||||
map.NodeNameTemplateDefault = mapSetting.NodeNameTemplate;
|
||||
|
||||
map.ZoneMinSquareDefault = mapSetting.ZoneMinSquare;
|
||||
|
||||
MapDb.Maps.Update(map);
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
return new(true);
|
||||
}
|
||||
}
|
||||
58
RobotNet.MapManager/Controllers/NodesController.cs
Normal file
58
RobotNet.MapManager/Controllers/NodesController.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class NodesController(MapEditorDbContext MapDb) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("{mapId}")]
|
||||
public async Task<NodeDto[]> GetNodes(Guid mapId)
|
||||
{
|
||||
return await (from node in MapDb.Nodes
|
||||
where node.MapId == mapId
|
||||
select new NodeDto()
|
||||
{
|
||||
Id = node.Id,
|
||||
Name = node.Name,
|
||||
MapId = mapId,
|
||||
X = node.X,
|
||||
Y = node.Y,
|
||||
Theta = node.Theta,
|
||||
AllowedDeviationXy = node.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = node.AllowedDeviationTheta,
|
||||
Actions = node.Actions,
|
||||
}).ToArrayAsync();
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("")]
|
||||
public async Task<MessageResult> Update([FromBody] NodeUpdateModel model)
|
||||
{
|
||||
var node = await MapDb.Nodes.FindAsync(model.Id);
|
||||
if (node == null) return new(false, $"Không tồn tại node id = {model.Id}");
|
||||
|
||||
if (node.Name != model.Name && !string.IsNullOrWhiteSpace(model.Name) && await MapDb.Nodes.AnyAsync(n => n.Name == model.Name && n.MapId == node.MapId))
|
||||
{
|
||||
return new(false, $"Tên node {model.Name} đã tồn tại trong map");
|
||||
}
|
||||
|
||||
node.Name = model.Name;
|
||||
node.X = model.X;
|
||||
node.Y = model.Y;
|
||||
node.Theta = model.Theta;
|
||||
node.AllowedDeviationXy = model.AllowedDeviationXy;
|
||||
node.AllowedDeviationTheta = model.AllowedDeviationTheta;
|
||||
node.Actions = System.Text.Json.JsonSerializer.Serialize(model.Actions ?? []);
|
||||
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(true);
|
||||
}
|
||||
}
|
||||
232
RobotNet.MapManager/Controllers/ScriptElementsController.cs
Normal file
232
RobotNet.MapManager/Controllers/ScriptElementsController.cs
Normal file
@@ -0,0 +1,232 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapManager.Services;
|
||||
using RobotNet.MapShares;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.MapShares.Models;
|
||||
using RobotNet.MapShares.Property;
|
||||
using RobotNet.Shares;
|
||||
using Serialize.Linq.Serializers;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ScriptElementsController(MapEditorDbContext MapDb, LoggerController<ScriptElementsController> Logger) : ControllerBase
|
||||
{
|
||||
private static readonly ExpressionSerializer expressionSerializer;
|
||||
|
||||
static ScriptElementsController()
|
||||
{
|
||||
var jss = new Serialize.Linq.Serializers.JsonSerializer();
|
||||
expressionSerializer = new ExpressionSerializer(jss);
|
||||
|
||||
expressionSerializer.AddKnownType(typeof(Script.Expressions.ElementProperties));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<MessageResult<IEnumerable<ElementDto>>> GetElementsWithCondition([FromBody] ElementExpressionModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == model.MapName);
|
||||
if (map is null) return new(false, $"Không tồn tại map tên = {model.MapName}");
|
||||
|
||||
var elModel = await MapDb.ElementModels.FirstOrDefaultAsync(m => m.MapId == map.Id && m.Name == model.ModelName);
|
||||
if (elModel is null) return new(false, $"Không tồn tại element model tên = {model.ModelName}");
|
||||
|
||||
var modelProperties = System.Text.Json.JsonSerializer.Deserialize<List<ElementProperty>>(elModel.Content, JsonOptionExtends.Read);
|
||||
if (modelProperties is null || modelProperties.Count == 0)
|
||||
return new(false, $"Không tồn tại property nào trong element model tên = {model.ModelName}");
|
||||
|
||||
var expr = expressionSerializer.DeserializeText(model.Expression);
|
||||
var lambda = (Expression<Func<Script.Expressions.ElementProperties, bool>>)expr;
|
||||
|
||||
// Compile và chạy:
|
||||
var func = lambda.Compile();
|
||||
|
||||
var elements = await MapDb.Elements.Where(e => e.MapId == map.Id && e.ModelId == elModel.Id).ToListAsync();
|
||||
List<ElementDto> elementSatisfies = [];
|
||||
foreach (var element in elements)
|
||||
{
|
||||
var properties = MapManagerExtensions.GetElementProperties(element.IsOpen, element.Content);
|
||||
if (func.Invoke(properties))
|
||||
{
|
||||
var elNode = await MapDb.Nodes.FindAsync(element.NodeId);
|
||||
if (elNode is null) continue; // Bỏ qua nếu không tìm thấy node
|
||||
elementSatisfies.Add(new ElementDto()
|
||||
{
|
||||
Id = element.Id,
|
||||
Name = element.Name,
|
||||
MapId = element.MapId,
|
||||
IsOpen = element.IsOpen,
|
||||
NodeId = element.NodeId,
|
||||
OffsetX = element.OffsetX,
|
||||
OffsetY = element.OffsetY,
|
||||
ModelId = element.ModelId,
|
||||
Content = element.Content,
|
||||
NodeName = elNode.Name,
|
||||
ModelName = elModel.Name,
|
||||
X = elNode.X,
|
||||
Y = elNode.Y,
|
||||
Theta = elNode.Theta
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = elementSatisfies
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"GetElement: Hệ thống có lỗi xảy ra - {ex}");
|
||||
return new(false, $"Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("{mapName}/node/{nodeName}")]
|
||||
public async Task<MessageResult<NodeDto>> GetNode([FromRoute] string mapName, [FromRoute] string nodeName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == mapName);
|
||||
if (map is null) return new(false, $"Không tồn tại map tên = {mapName}");
|
||||
|
||||
var node = await MapDb.Nodes.FirstOrDefaultAsync(n => n.MapId == map.Id && n.Name == nodeName);
|
||||
if (node is null) return new(false, $"Không tồn tại node {nodeName} trong map {mapName}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new NodeDto()
|
||||
{
|
||||
Id = node.Id,
|
||||
Name = node.Name,
|
||||
MapId = node.MapId,
|
||||
X = node.X,
|
||||
Y = node.Y,
|
||||
Theta = node.Theta,
|
||||
AllowedDeviationXy = node.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = node.AllowedDeviationTheta,
|
||||
Actions = node.Actions,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"GetElement: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"GetElement: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("{mapName}/element/{elementName}")]
|
||||
public async Task<MessageResult<ElementDto>> GetElement([FromRoute] string mapName, [FromRoute] string elementName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == mapName);
|
||||
if (map is null) return new(false, $"Không tồn tại map tên = {mapName}");
|
||||
|
||||
var el = await MapDb.Elements.FirstOrDefaultAsync(e => e.MapId == map.Id && e.Name == elementName);
|
||||
if (el is null) return new(false, $"Không tồn tại element name = {elementName}");
|
||||
|
||||
var elModel = await MapDb.ElementModels.FindAsync(el.ModelId);
|
||||
if (elModel == null) return new(false, $"Không tồn tại element model id = {el.ModelId}");
|
||||
|
||||
var elNode = await MapDb.Nodes.FindAsync(el.NodeId);
|
||||
if (elNode is null) return new(false, $"Không tồn tại node id = {el.NodeId}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
Id = el.Id,
|
||||
Name = el.Name,
|
||||
MapId = el.MapId,
|
||||
IsOpen = el.IsOpen,
|
||||
NodeId = el.NodeId,
|
||||
OffsetX = el.OffsetX,
|
||||
OffsetY = el.OffsetY,
|
||||
ModelId = el.ModelId,
|
||||
Content = el.Content,
|
||||
NodeName = elNode.Name,
|
||||
ModelName = elModel.Name,
|
||||
X = elNode.X,
|
||||
Y = elNode.Y,
|
||||
Theta = elNode.Theta
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"GetElement: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"GetElement: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPatch]
|
||||
[Route("{mapName}/element/{elementName}")]
|
||||
public async Task<MessageResult> UpdateElementProperty([FromRoute] string mapName, [FromRoute] string elementName, [FromBody] ElementPropertyUpdateModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == mapName);
|
||||
if (map is null) return new(false, $"Không tồn tại map tên = {mapName}");
|
||||
|
||||
var element = await MapDb.Elements.FirstOrDefaultAsync(m => m.Name == elementName && m.MapId == map.Id);
|
||||
if (element == null) return new(false, $"Không tồn tại element tên = {elementName} trong map tên = {mapName}");
|
||||
|
||||
var properties = System.Text.Json.JsonSerializer.Deserialize<List<ElementProperty>>(element.Content, JsonOptionExtends.Read);
|
||||
foreach (var property in model.Properties)
|
||||
{
|
||||
var existingProperty = properties?.FirstOrDefault(p => p.Name == property.Name);
|
||||
if (existingProperty != null)
|
||||
{
|
||||
existingProperty.DefaultValue = property.DefaultValue;
|
||||
}
|
||||
else return new(false, $"Không tồn tại property name = {property.Name} trong element");
|
||||
}
|
||||
var content = System.Text.Json.JsonSerializer.Serialize(properties, JsonOptionExtends.Write);
|
||||
element.Content = content;
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Update: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"Update: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPatch]
|
||||
[Route("{mapName}/element/{elementName}/IsOpen")]
|
||||
public async Task<MessageResult> UpdateOpenOfElement([FromRoute] string mapName, [FromRoute] string elementName, [FromQuery] bool isOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == mapName);
|
||||
if (map is null) return new(false, $"Không tồn tại map tên = {mapName}");
|
||||
|
||||
var element = await MapDb.Elements.FirstOrDefaultAsync(m => m.Name == elementName && m.MapId == map.Id);
|
||||
if (element == null) return new(false, $"Không tồn tại element tên = {elementName} trong map tên = {mapName}");
|
||||
|
||||
element.IsOpen = isOpen;
|
||||
await MapDb.SaveChangesAsync();
|
||||
|
||||
return new(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Update: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"Update: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
114
RobotNet.MapManager/Controllers/ZonesController.cs
Normal file
114
RobotNet.MapManager/Controllers/ZonesController.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapManager.Services;
|
||||
using RobotNet.MapShares;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.MapManager.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ZonesController(MapEditorDbContext MapDb, LoggerController<ZonesController> Logger) : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
[Route("")]
|
||||
public async Task<MessageResult<ZoneDto>> Create([FromBody] ZoneCreateModel zone)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = await MapDb.Maps.FindAsync(zone.MapId);
|
||||
if (map == null) return new(false, $"Không tồn tại map id = {zone.MapId}");
|
||||
|
||||
if (MapEditorHelper.CalculateQuadrilateralArea(zone.X1, zone.Y1, zone.X2, zone.Y2, zone.X3, zone.Y3, zone.X4, zone.Y4) < map.ZoneMinSquareDefault)
|
||||
return new(false, "Kích thước Zone quá nhỏ");
|
||||
|
||||
var entity = await MapDb.Zones.AddAsync(new()
|
||||
{
|
||||
MapId = zone.MapId,
|
||||
Type = zone.Type,
|
||||
Name = "",
|
||||
X1 = zone.X1,
|
||||
X2 = zone.X2,
|
||||
X3 = zone.X3,
|
||||
X4 = zone.X4,
|
||||
Y1 = zone.Y1,
|
||||
Y2 = zone.Y2,
|
||||
Y3 = zone.Y3,
|
||||
Y4 = zone.Y4,
|
||||
});
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(true)
|
||||
{
|
||||
Data = new ZoneDto() { Id = entity.Entity.Id, MapId = entity.Entity.MapId, Type = entity.Entity.Type, X1 = entity.Entity.X1, X2 = entity.Entity.X2, X3 = entity.Entity.X3, X4 = entity.Entity.X4, Y1 = entity.Entity.Y1, Y2 = entity.Entity.Y2, Y3 = entity.Entity.Y3, Y4 = entity.Entity.Y4 }
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Create: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, "Hệ thống có lỗi xảy ra");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("{id}")]
|
||||
public async Task<MessageResult> Delete(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var zoneExisted = await MapDb.Zones.FindAsync(id);
|
||||
if (zoneExisted is not null)
|
||||
{
|
||||
MapDb.Zones.Remove(zoneExisted);
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(true);
|
||||
}
|
||||
return new(false, "Hệ thống không tìm thấy khu vực Zone này");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Delete {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, "Hệ thống có lỗi xảy ra");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("")]
|
||||
public async Task<MessageResult> Update([FromBody] ZoneUpdateModel zone)
|
||||
{
|
||||
try
|
||||
{
|
||||
var zoneExisted = await MapDb.Zones.FindAsync(zone.Id);
|
||||
if (zoneExisted is not null)
|
||||
{
|
||||
if (zoneExisted.Name != zone.Name && !string.IsNullOrWhiteSpace(zone.Name) && await MapDb.Zones.AnyAsync(z => z.Name == zone.Name && z.MapId == zoneExisted.MapId))
|
||||
{
|
||||
return new(false, $"Tên zone {zone.Name} đã tồn tại trong map");
|
||||
}
|
||||
|
||||
zoneExisted.Type = zone.Type;
|
||||
zoneExisted.Name = zone.Name;
|
||||
zoneExisted.X1 = zone.X1;
|
||||
zoneExisted.X2 = zone.X2;
|
||||
zoneExisted.X3 = zone.X3;
|
||||
zoneExisted.X4 = zone.X4;
|
||||
zoneExisted.Y1 = zone.Y1;
|
||||
zoneExisted.Y2 = zone.Y2;
|
||||
zoneExisted.Y3 = zone.Y3;
|
||||
zoneExisted.Y4 = zone.Y4;
|
||||
MapDb.Zones.Update(zoneExisted);
|
||||
await MapDb.SaveChangesAsync();
|
||||
return new(true);
|
||||
}
|
||||
return new(false, "Hệ thống không tìm thấy khu vực Zone này");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Update: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
return new(false, $"Update: Hệ thống có lỗi xảy ra - {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
30
RobotNet.MapManager/Data/Action.cs
Normal file
30
RobotNet.MapManager/Data/Action.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace RobotNet.MapManager.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("Actions")]
|
||||
[Index(nameof(MapId), nameof(Name), Name = "IX_Action_MapId_Name")]
|
||||
public class Action
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("MapId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid MapId { get; set; }
|
||||
|
||||
[Column("Name", TypeName = "nvarchar(64)")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("Content", TypeName = "nvarchar(max)")]
|
||||
public string Content { get; set; }
|
||||
|
||||
public Map Map { get; set; }
|
||||
}
|
||||
77
RobotNet.MapManager/Data/Edge.cs
Normal file
77
RobotNet.MapManager/Data/Edge.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapShares.Enums;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace RobotNet.MapManager.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("Edges")]
|
||||
[Index(nameof(MapId), Name = "IX_Edge_MapId")]
|
||||
public class Edge
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("MapId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid MapId { get; set; }
|
||||
|
||||
[Column("StartNodeId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid StartNodeId { get; set; }
|
||||
|
||||
[Column("EndNodeId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid EndNodeId { get; set; }
|
||||
|
||||
[Column("ControlPoint1X", TypeName = "float")]
|
||||
public double ControlPoint1X { get; set; }
|
||||
|
||||
[Column("ControlPoint1Y", TypeName = "float")]
|
||||
public double ControlPoint1Y { get; set; }
|
||||
|
||||
[Column("ControlPoint2X", TypeName = "float")]
|
||||
public double ControlPoint2X { get; set; }
|
||||
|
||||
[Column("ControlPoint2Y", TypeName = "float")]
|
||||
public double ControlPoint2Y { get; set; }
|
||||
|
||||
[Column("TrajectoryDegree", TypeName = "tinyint")]
|
||||
public TrajectoryDegree TrajectoryDegree { get; set; }
|
||||
|
||||
[Column("MaxHeight", TypeName = "float")]
|
||||
public double MaxHeight { get; set; }
|
||||
|
||||
[Column("MinHeight", TypeName = "float")]
|
||||
public double MinHeight { get; set; }
|
||||
|
||||
[Column("DirectionAllowed", TypeName = "tinyint")]
|
||||
public DirectionAllowed DirectionAllowed { get; set; }
|
||||
|
||||
[Column("RotationAllowed", TypeName = "bit")]
|
||||
public bool RotationAllowed { get; set; }
|
||||
|
||||
[Column("MaxRotationSpeed", TypeName = "float")]
|
||||
public double MaxRotationSpeed { get; set; }
|
||||
|
||||
[Column("MaxSpeed", TypeName = "float")]
|
||||
public double MaxSpeed { get; set; }
|
||||
|
||||
[Column("AllowedDeviationXy", TypeName = "float")]
|
||||
public double AllowedDeviationXy { get; set; }
|
||||
|
||||
[Column("AllowedDeviationTheta", TypeName = "float")]
|
||||
public double AllowedDeviationTheta { get; set; }
|
||||
|
||||
[Column("Actions", TypeName = "nvarchar(max)")]
|
||||
public string Actions { get; set; }
|
||||
|
||||
public Map Map { get; set; }
|
||||
public virtual Node StartNode { get; set; }
|
||||
public virtual Node EndNode { get; set; }
|
||||
}
|
||||
49
RobotNet.MapManager/Data/Element.cs
Normal file
49
RobotNet.MapManager/Data/Element.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace RobotNet.MapManager.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("Elements")]
|
||||
[Index(nameof(MapId), nameof(ModelId), Name = "IX_Element_MapId_ModelId")]
|
||||
public class Element
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("MapId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid MapId { get; set; }
|
||||
|
||||
[Column("ModelId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid ModelId { get; set; }
|
||||
|
||||
[Column("NodeId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid NodeId { get; set; }
|
||||
|
||||
[Column("Name", TypeName = "nvarchar(64)")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("IsOpen", TypeName = "bit")]
|
||||
public bool IsOpen { get; set; }
|
||||
|
||||
[Column("OffsetX", TypeName = "float")]
|
||||
public double OffsetX { get; set; }
|
||||
|
||||
[Column("OffsetY", TypeName = "float")]
|
||||
public double OffsetY { get; set; }
|
||||
|
||||
[Column("Content", TypeName = "nvarchar(max)")]
|
||||
public string Content { get; set; }
|
||||
|
||||
public Map Map { get; set; }
|
||||
public ElementModel Model { get; set; }
|
||||
public Node Node { get; set; }
|
||||
}
|
||||
55
RobotNet.MapManager/Data/ElementModel.cs
Normal file
55
RobotNet.MapManager/Data/ElementModel.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace RobotNet.MapManager.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("ElementModels")]
|
||||
[Index(nameof(MapId), nameof(Name), Name = "IX_ElementModel_MapId_Name")]
|
||||
public class ElementModel
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("MapId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid MapId { get; set; }
|
||||
|
||||
[Column("Name", TypeName = "nvarchar(64)")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("Width", TypeName = "float")]
|
||||
[Required]
|
||||
public double Width { get; set; }
|
||||
|
||||
[Column("Height", TypeName = "float")]
|
||||
[Required]
|
||||
public double Height { get; set; }
|
||||
|
||||
[Column("Image1Width", TypeName = "int")]
|
||||
[Required]
|
||||
public int Image1Width { get; set; }
|
||||
|
||||
[Column("Image1Height", TypeName = "int")]
|
||||
[Required]
|
||||
public int Image1Height { get; set; }
|
||||
|
||||
[Column("Image2Width", TypeName = "int")]
|
||||
[Required]
|
||||
public int Image2Width { get; set; }
|
||||
|
||||
[Column("Image2Height", TypeName = "int")]
|
||||
[Required]
|
||||
public int Image2Height { get; set; }
|
||||
|
||||
[Column("Content", TypeName = "nvarchar(max)")]
|
||||
public string Content { get; set; }
|
||||
|
||||
public virtual ICollection<Element> Elements { get; } = [];
|
||||
public Map Map { get; set; }
|
||||
}
|
||||
125
RobotNet.MapManager/Data/Map.cs
Normal file
125
RobotNet.MapManager/Data/Map.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using RobotNet.MapShares.Enums;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace RobotNet.MapManager.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("Maps")]
|
||||
public class Map
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("Name", TypeName = "nvarchar(64)")]
|
||||
[Required]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("Description", TypeName = "ntext")]
|
||||
public string Description { get; set; } = "";
|
||||
|
||||
[Column("VersionId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid VersionId { get; set; }
|
||||
|
||||
[Column("OriginX", TypeName = "float")]
|
||||
[Required]
|
||||
public double OriginX { get; set; }
|
||||
|
||||
[Column("OriginY", TypeName = "float")]
|
||||
[Required]
|
||||
public double OriginY { get; set; }
|
||||
|
||||
[Column("Resolution", TypeName = "float")]
|
||||
[Required]
|
||||
public double Resolution { get; set; }
|
||||
|
||||
[Column("ViewX", TypeName = "float")]
|
||||
[Required]
|
||||
public double ViewX { get; set; }
|
||||
|
||||
[Column("ViewY", TypeName = "float")]
|
||||
[Required]
|
||||
public double ViewY { get; set; }
|
||||
|
||||
[Column("ViewWidth", TypeName = "float")]
|
||||
[Required]
|
||||
public double ViewWidth { get; set; }
|
||||
|
||||
[Column("ViewHeight", TypeName = "float")]
|
||||
[Required]
|
||||
public double ViewHeight { get; set; }
|
||||
|
||||
[Column("ImageWidth", TypeName = "float")]
|
||||
[Required]
|
||||
public double ImageWidth { get; set; }
|
||||
|
||||
[Column("ImageHeight", TypeName = "float")]
|
||||
[Required]
|
||||
public double ImageHeight { get; set; }
|
||||
|
||||
[Column("NodeCount", TypeName = "BigInt")]
|
||||
public Int64 NodeCount { get; set; }
|
||||
|
||||
[Column("Active", TypeName = "bit")]
|
||||
public bool Active { get; set; }
|
||||
|
||||
[Column("VDA5050", TypeName = "nvarchar(max)")]
|
||||
public string VDA5050 { get; set; } = ""; //AdditionalAttributes
|
||||
|
||||
[Column("NodeNameAutoGenerate", TypeName = "bit")]
|
||||
public bool NodeNameAutoGenerate { get; set; }
|
||||
|
||||
[Column("NodeNameTemplateDefault", TypeName = "nvarchar(64)")]
|
||||
public string NodeNameTemplateDefault { get; set; }
|
||||
|
||||
[Column("NodeAllowedDeviationXyDefault", TypeName = "float")]
|
||||
public double NodeAllowedDeviationXyDefault { get; set; }
|
||||
|
||||
[Column("NodeAllowedDeviationThetaDefault", TypeName = "float")]
|
||||
public double NodeAllowedDeviationThetaDefault { get; set; }
|
||||
|
||||
[Column("EdgeMinLengthDefault", TypeName = "float")]
|
||||
public double EdgeMinLengthDefault { get; set; }
|
||||
|
||||
[Column("EdgeStraightMaxSpeedDefault", TypeName = "float")]
|
||||
public double EdgeStraightMaxSpeedDefault { get; set; }
|
||||
|
||||
[Column("EdgeCurveMaxSpeedDefault", TypeName = "float")]
|
||||
public double EdgeCurveMaxSpeedDefault { get; set; }
|
||||
|
||||
[Column("EdgeMaxHeightDefault", TypeName = "float")]
|
||||
public double EdgeMaxHeightDefault { get; set; }
|
||||
|
||||
[Column("EdgeMinHeightDefault", TypeName = "float")]
|
||||
public double EdgeMinHeightDefault { get; set; }
|
||||
|
||||
[Column("EdgeMaxRoataionSpeedDefault", TypeName = "float")]
|
||||
public double EdgeMaxRotationSpeedDefault { get; set; }
|
||||
|
||||
[Column("EdgeDirectionAllowedDefault", TypeName = "tinyint")]
|
||||
public DirectionAllowed EdgeDirectionAllowedDefault { get; set; }
|
||||
|
||||
[Column("EdgeRotationAllowedDefault", TypeName = "bit")]
|
||||
public bool EdgeRotationAllowedDefault { get; set; }
|
||||
|
||||
[Column("EdgeAllowedDeviationXyDefault", TypeName = "float")]
|
||||
public double EdgeAllowedDeviationXyDefault { get; set; }
|
||||
|
||||
[Column("EdgeAllowedDeviationThetaDefault", TypeName = "float")]
|
||||
public double EdgeAllowedDeviationThetaDefault { get; set; }
|
||||
|
||||
[Column("ZoneMinSquareDefault", TypeName = "float")]
|
||||
public double ZoneMinSquareDefault { get; set; }
|
||||
|
||||
public virtual ICollection<Node> Nodes { get; } = [];
|
||||
public virtual ICollection<Edge> Edges { get; } = [];
|
||||
public virtual ICollection<Action> Actions { get; } = [];
|
||||
public virtual ICollection<Zone> Zones { get; } = [];
|
||||
public virtual ICollection<ElementModel> ElementModels { get; } = [];
|
||||
public virtual ICollection<Element> Elements { get; } = [];
|
||||
}
|
||||
90
RobotNet.MapManager/Data/MapEditorDbContext.cs
Normal file
90
RobotNet.MapManager/Data/MapEditorDbContext.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace RobotNet.MapManager.Data;
|
||||
|
||||
|
||||
public class MapEditorDbContext(DbContextOptions<MapEditorDbContext> options) : DbContext(options)
|
||||
{
|
||||
public DbSet<Map> Maps { get; private set; }
|
||||
public DbSet<Node> Nodes { get; private set; }
|
||||
public DbSet<Edge> Edges { get; private set; }
|
||||
public DbSet<Zone> Zones { get; private set; }
|
||||
public DbSet<Action> Actions { get; private set; }
|
||||
public DbSet<ElementModel> ElementModels { get; private set; }
|
||||
public DbSet<Element> Elements { get; private set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Map>()
|
||||
.HasMany(e => e.Actions)
|
||||
.WithOne(e => e.Map)
|
||||
.HasForeignKey(e => e.MapId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
modelBuilder.Entity<Map>()
|
||||
.HasMany(e => e.Edges)
|
||||
.WithOne(e => e.Map)
|
||||
.HasForeignKey(e => e.MapId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
modelBuilder.Entity<Map>()
|
||||
.HasMany(e => e.Nodes)
|
||||
.WithOne(e => e.Map)
|
||||
.HasForeignKey(e => e.MapId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
modelBuilder.Entity<Map>()
|
||||
.HasMany(e => e.Zones)
|
||||
.WithOne(e => e.Map)
|
||||
.HasForeignKey(e => e.MapId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
modelBuilder.Entity<Edge>()
|
||||
.HasOne(e => e.StartNode)
|
||||
.WithMany(n => n.StartEdges)
|
||||
.HasForeignKey(e => e.StartNodeId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
modelBuilder.Entity<Edge>()
|
||||
.HasOne(e => e.EndNode)
|
||||
.WithMany(n => n.EndEdges)
|
||||
.HasForeignKey(e => e.EndNodeId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
modelBuilder.Entity<Map>()
|
||||
.HasMany(e => e.ElementModels)
|
||||
.WithOne(e => e.Map)
|
||||
.HasForeignKey(e => e.MapId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
modelBuilder.Entity<Map>()
|
||||
.HasMany(e => e.Elements)
|
||||
.WithOne(e => e.Map)
|
||||
.HasForeignKey(e => e.MapId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
modelBuilder.Entity<Node>()
|
||||
.HasOne(n => n.Element)
|
||||
.WithOne(e => e.Node)
|
||||
.HasForeignKey<Element>(e => e.NodeId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
modelBuilder.Entity<ElementModel>()
|
||||
.HasMany(e => e.Elements)
|
||||
.WithOne(e => e.Model)
|
||||
.HasForeignKey(e => e.ModelId)
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
}
|
||||
17
RobotNet.MapManager/Data/MapManagerDbExtensions.cs
Normal file
17
RobotNet.MapManager/Data/MapManagerDbExtensions.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace RobotNet.MapManager.Data;
|
||||
|
||||
public static class MapManagerDbExtensions
|
||||
{
|
||||
public static async Task SeedMapManagerDbAsync(this IServiceProvider serviceProvider)
|
||||
{
|
||||
using var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
|
||||
|
||||
using var appDb = scope.ServiceProvider.GetRequiredService<MapEditorDbContext>();
|
||||
|
||||
await appDb.Database.MigrateAsync();
|
||||
//await appDb.Database.EnsureCreatedAsync();
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
603
RobotNet.MapManager/Data/Migrations/20250425030649_AddMapdb.Designer.cs
generated
Normal file
603
RobotNet.MapManager/Data/Migrations/20250425030649_AddMapdb.Designer.cs
generated
Normal file
@@ -0,0 +1,603 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using RobotNet.MapManager.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RobotNet.MapManager.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(MapEditorDbContext))]
|
||||
[Migration("20250425030649_AddMapdb")]
|
||||
partial class AddMapdb
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Action", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Content");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId", "Name" }, "IX_Action_MapId_Name");
|
||||
|
||||
b.ToTable("Actions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Edge", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Actions")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Actions");
|
||||
|
||||
b.Property<double>("AllowedDeviationTheta")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationTheta");
|
||||
|
||||
b.Property<double>("AllowedDeviationXy")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationXy");
|
||||
|
||||
b.Property<double>("ControlPoint1X")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint1X");
|
||||
|
||||
b.Property<double>("ControlPoint1Y")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint1Y");
|
||||
|
||||
b.Property<double>("ControlPoint2X")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint2X");
|
||||
|
||||
b.Property<double>("ControlPoint2Y")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint2Y");
|
||||
|
||||
b.Property<byte>("DirectionAllowed")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("DirectionAllowed");
|
||||
|
||||
b.Property<Guid>("EndNodeId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("EndNodeId");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<double>("MaxHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MaxHeight");
|
||||
|
||||
b.Property<double>("MaxRotationSpeed")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MaxRotationSpeed");
|
||||
|
||||
b.Property<double>("MaxSpeed")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MaxSpeed");
|
||||
|
||||
b.Property<double>("MinHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MinHeight");
|
||||
|
||||
b.Property<bool>("RotationAllowed")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("RotationAllowed");
|
||||
|
||||
b.Property<Guid>("StartNodeId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("StartNodeId");
|
||||
|
||||
b.Property<byte>("TrajectoryDegree")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("TrajectoryDegree");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EndNodeId");
|
||||
|
||||
b.HasIndex("StartNodeId");
|
||||
|
||||
b.HasIndex(new[] { "MapId" }, "IX_Edge_MapId");
|
||||
|
||||
b.ToTable("Edges");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Element", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Content");
|
||||
|
||||
b.Property<bool>("IsOpen")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsOpen");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<Guid>("ModelId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("ModelId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<Guid>("NodeId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("NodeId");
|
||||
|
||||
b.Property<double>("OffsetX")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OffsetX");
|
||||
|
||||
b.Property<double>("OffsetY")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OffsetY");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ModelId");
|
||||
|
||||
b.HasIndex("NodeId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex(new[] { "MapId", "ModelId" }, "IX_Element_MapId_ModelId");
|
||||
|
||||
b.ToTable("Elements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.ElementModel", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Content");
|
||||
|
||||
b.Property<double>("Height")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Height");
|
||||
|
||||
b.Property<int>("Image1Height")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image1Height");
|
||||
|
||||
b.Property<int>("Image1Width")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image1Width");
|
||||
|
||||
b.Property<int>("Image2Height")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image2Height");
|
||||
|
||||
b.Property<int>("Image2Width")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image2Width");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<double>("Width")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Width");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId", "Name" }, "IX_ElementModel_MapId_Name");
|
||||
|
||||
b.ToTable("ElementModels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Map", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<bool>("Active")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<double>("EdgeAllowedDeviationThetaDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeAllowedDeviationThetaDefault");
|
||||
|
||||
b.Property<double>("EdgeAllowedDeviationXyDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeAllowedDeviationXyDefault");
|
||||
|
||||
b.Property<double>("EdgeCurveMaxSpeedDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeCurveMaxSpeedDefault");
|
||||
|
||||
b.Property<byte>("EdgeDirectionAllowedDefault")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("EdgeDirectionAllowedDefault");
|
||||
|
||||
b.Property<double>("EdgeMaxHeightDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMaxHeightDefault");
|
||||
|
||||
b.Property<double>("EdgeMaxRotationSpeedDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMaxRoataionSpeedDefault");
|
||||
|
||||
b.Property<double>("EdgeMinHeightDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMinHeightDefault");
|
||||
|
||||
b.Property<double>("EdgeMinLengthDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMinLengthDefault");
|
||||
|
||||
b.Property<bool>("EdgeRotationAllowedDefault")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("EdgeRotationAllowedDefault");
|
||||
|
||||
b.Property<double>("EdgeStraightMaxSpeedDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeStraightMaxSpeedDefault");
|
||||
|
||||
b.Property<double>("ImageHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ImageHeight");
|
||||
|
||||
b.Property<double>("ImageWidth")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ImageWidth");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<double>("NodeAllowedDeviationThetaDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("NodeAllowedDeviationThetaDefault");
|
||||
|
||||
b.Property<double>("NodeAllowedDeviationXyDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("NodeAllowedDeviationXyDefault");
|
||||
|
||||
b.Property<long>("NodeCount")
|
||||
.HasColumnType("BigInt")
|
||||
.HasColumnName("NodeCount");
|
||||
|
||||
b.Property<bool>("NodeNameAutoGenerate")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("NodeNameAutoGenerate");
|
||||
|
||||
b.Property<string>("NodeNameTemplateDefault")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("NodeNameTemplateDefault");
|
||||
|
||||
b.Property<double>("OriginX")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OriginX");
|
||||
|
||||
b.Property<double>("OriginY")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OriginY");
|
||||
|
||||
b.Property<double>("Resolution")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Resolution");
|
||||
|
||||
b.Property<string>("VDA5050")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("VDA5050");
|
||||
|
||||
b.Property<Guid>("VersionId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("VersionId");
|
||||
|
||||
b.Property<double>("ViewHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewHeight");
|
||||
|
||||
b.Property<double>("ViewWidth")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewWidth");
|
||||
|
||||
b.Property<double>("ViewX")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewX");
|
||||
|
||||
b.Property<double>("ViewY")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewY");
|
||||
|
||||
b.Property<double>("ZoneMinSquareDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ZoneMinSquareDefault");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Maps");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Node", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Actions")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Actions");
|
||||
|
||||
b.Property<double>("AllowedDeviationTheta")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationTheta");
|
||||
|
||||
b.Property<double>("AllowedDeviationXy")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationXy");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<double>("Theta")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Theta");
|
||||
|
||||
b.Property<double>("X")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X");
|
||||
|
||||
b.Property<double>("Y")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId", "Name" }, "IX_Node_MapId_Name");
|
||||
|
||||
b.ToTable("Nodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Zone", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Type");
|
||||
|
||||
b.Property<double>("X1")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X1");
|
||||
|
||||
b.Property<double>("X2")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X2");
|
||||
|
||||
b.Property<double>("X3")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X3");
|
||||
|
||||
b.Property<double>("X4")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X4");
|
||||
|
||||
b.Property<double>("Y1")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y1");
|
||||
|
||||
b.Property<double>("Y2")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y2");
|
||||
|
||||
b.Property<double>("Y3")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y3");
|
||||
|
||||
b.Property<double>("Y4")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y4");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId" }, "IX_Zone_MapId");
|
||||
|
||||
b.ToTable("Zones");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Action", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Actions")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Edge", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Node", "EndNode")
|
||||
.WithMany("EndEdges")
|
||||
.HasForeignKey("EndNodeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Edges")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.Node", "StartNode")
|
||||
.WithMany("StartEdges")
|
||||
.HasForeignKey("StartNodeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("EndNode");
|
||||
|
||||
b.Navigation("Map");
|
||||
|
||||
b.Navigation("StartNode");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Element", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Elements")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.ElementModel", "Model")
|
||||
.WithMany("Elements")
|
||||
.HasForeignKey("ModelId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.Node", "Node")
|
||||
.WithOne("Element")
|
||||
.HasForeignKey("RobotNet.MapManager.Data.Element", "NodeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
|
||||
b.Navigation("Model");
|
||||
|
||||
b.Navigation("Node");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.ElementModel", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("ElementModels")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Node", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Nodes")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Zone", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Zones")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.ElementModel", b =>
|
||||
{
|
||||
b.Navigation("Elements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Map", b =>
|
||||
{
|
||||
b.Navigation("Actions");
|
||||
|
||||
b.Navigation("Edges");
|
||||
|
||||
b.Navigation("ElementModels");
|
||||
|
||||
b.Navigation("Elements");
|
||||
|
||||
b.Navigation("Nodes");
|
||||
|
||||
b.Navigation("Zones");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Node", b =>
|
||||
{
|
||||
b.Navigation("Element");
|
||||
|
||||
b.Navigation("EndEdges");
|
||||
|
||||
b.Navigation("StartEdges");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
313
RobotNet.MapManager/Data/Migrations/20250425030649_AddMapdb.cs
Normal file
313
RobotNet.MapManager/Data/Migrations/20250425030649_AddMapdb.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RobotNet.MapManager.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddMapdb : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Maps",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(64)", nullable: false),
|
||||
Description = table.Column<string>(type: "ntext", nullable: true),
|
||||
VersionId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
OriginX = table.Column<double>(type: "float", nullable: false),
|
||||
OriginY = table.Column<double>(type: "float", nullable: false),
|
||||
Resolution = table.Column<double>(type: "float", nullable: false),
|
||||
ViewX = table.Column<double>(type: "float", nullable: false),
|
||||
ViewY = table.Column<double>(type: "float", nullable: false),
|
||||
ViewWidth = table.Column<double>(type: "float", nullable: false),
|
||||
ViewHeight = table.Column<double>(type: "float", nullable: false),
|
||||
ImageWidth = table.Column<double>(type: "float", nullable: false),
|
||||
ImageHeight = table.Column<double>(type: "float", nullable: false),
|
||||
NodeCount = table.Column<long>(type: "BigInt", nullable: false),
|
||||
Active = table.Column<bool>(type: "bit", nullable: false),
|
||||
VDA5050 = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
NodeNameAutoGenerate = table.Column<bool>(type: "bit", nullable: false),
|
||||
NodeNameTemplateDefault = table.Column<string>(type: "nvarchar(64)", nullable: true),
|
||||
NodeAllowedDeviationXyDefault = table.Column<double>(type: "float", nullable: false),
|
||||
NodeAllowedDeviationThetaDefault = table.Column<double>(type: "float", nullable: false),
|
||||
EdgeMinLengthDefault = table.Column<double>(type: "float", nullable: false),
|
||||
EdgeStraightMaxSpeedDefault = table.Column<double>(type: "float", nullable: false),
|
||||
EdgeCurveMaxSpeedDefault = table.Column<double>(type: "float", nullable: false),
|
||||
EdgeMaxHeightDefault = table.Column<double>(type: "float", nullable: false),
|
||||
EdgeMinHeightDefault = table.Column<double>(type: "float", nullable: false),
|
||||
EdgeMaxRoataionSpeedDefault = table.Column<double>(type: "float", nullable: false),
|
||||
EdgeDirectionAllowedDefault = table.Column<byte>(type: "tinyint", nullable: false),
|
||||
EdgeRotationAllowedDefault = table.Column<bool>(type: "bit", nullable: false),
|
||||
EdgeAllowedDeviationXyDefault = table.Column<double>(type: "float", nullable: false),
|
||||
EdgeAllowedDeviationThetaDefault = table.Column<double>(type: "float", nullable: false),
|
||||
ZoneMinSquareDefault = table.Column<double>(type: "float", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Maps", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Actions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
MapId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(64)", nullable: true),
|
||||
Content = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Actions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Actions_Maps_MapId",
|
||||
column: x => x.MapId,
|
||||
principalTable: "Maps",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ElementModels",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
MapId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(64)", nullable: true),
|
||||
Width = table.Column<double>(type: "float", nullable: false),
|
||||
Height = table.Column<double>(type: "float", nullable: false),
|
||||
Image1Width = table.Column<int>(type: "int", nullable: false),
|
||||
Image1Height = table.Column<int>(type: "int", nullable: false),
|
||||
Image2Width = table.Column<int>(type: "int", nullable: false),
|
||||
Image2Height = table.Column<int>(type: "int", nullable: false),
|
||||
Content = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ElementModels", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ElementModels_Maps_MapId",
|
||||
column: x => x.MapId,
|
||||
principalTable: "Maps",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Nodes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
MapId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(64)", nullable: true),
|
||||
X = table.Column<double>(type: "float", nullable: false),
|
||||
Y = table.Column<double>(type: "float", nullable: false),
|
||||
Theta = table.Column<double>(type: "float", nullable: false),
|
||||
AllowedDeviationXy = table.Column<double>(type: "float", nullable: false),
|
||||
AllowedDeviationTheta = table.Column<double>(type: "float", nullable: false),
|
||||
Actions = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Nodes", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Nodes_Maps_MapId",
|
||||
column: x => x.MapId,
|
||||
principalTable: "Maps",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Zones",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
MapId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
Type = table.Column<int>(type: "int", nullable: false),
|
||||
X1 = table.Column<double>(type: "float", nullable: false),
|
||||
Y1 = table.Column<double>(type: "float", nullable: false),
|
||||
X2 = table.Column<double>(type: "float", nullable: false),
|
||||
Y2 = table.Column<double>(type: "float", nullable: false),
|
||||
X3 = table.Column<double>(type: "float", nullable: false),
|
||||
Y3 = table.Column<double>(type: "float", nullable: false),
|
||||
X4 = table.Column<double>(type: "float", nullable: false),
|
||||
Y4 = table.Column<double>(type: "float", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Zones", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Zones_Maps_MapId",
|
||||
column: x => x.MapId,
|
||||
principalTable: "Maps",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Edges",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
MapId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
StartNodeId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
EndNodeId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
ControlPoint1X = table.Column<double>(type: "float", nullable: false),
|
||||
ControlPoint1Y = table.Column<double>(type: "float", nullable: false),
|
||||
ControlPoint2X = table.Column<double>(type: "float", nullable: false),
|
||||
ControlPoint2Y = table.Column<double>(type: "float", nullable: false),
|
||||
TrajectoryDegree = table.Column<byte>(type: "tinyint", nullable: false),
|
||||
MaxHeight = table.Column<double>(type: "float", nullable: false),
|
||||
MinHeight = table.Column<double>(type: "float", nullable: false),
|
||||
DirectionAllowed = table.Column<byte>(type: "tinyint", nullable: false),
|
||||
RotationAllowed = table.Column<bool>(type: "bit", nullable: false),
|
||||
MaxRotationSpeed = table.Column<double>(type: "float", nullable: false),
|
||||
MaxSpeed = table.Column<double>(type: "float", nullable: false),
|
||||
AllowedDeviationXy = table.Column<double>(type: "float", nullable: false),
|
||||
AllowedDeviationTheta = table.Column<double>(type: "float", nullable: false),
|
||||
Actions = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Edges", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Edges_Maps_MapId",
|
||||
column: x => x.MapId,
|
||||
principalTable: "Maps",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Edges_Nodes_EndNodeId",
|
||||
column: x => x.EndNodeId,
|
||||
principalTable: "Nodes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Edges_Nodes_StartNodeId",
|
||||
column: x => x.StartNodeId,
|
||||
principalTable: "Nodes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Elements",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
MapId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
ModelId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
NodeId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
Name = table.Column<string>(type: "nvarchar(64)", nullable: true),
|
||||
IsOpen = table.Column<bool>(type: "bit", nullable: false),
|
||||
OffsetX = table.Column<double>(type: "float", nullable: false),
|
||||
OffsetY = table.Column<double>(type: "float", nullable: false),
|
||||
Content = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Elements", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Elements_ElementModels_ModelId",
|
||||
column: x => x.ModelId,
|
||||
principalTable: "ElementModels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Elements_Maps_MapId",
|
||||
column: x => x.MapId,
|
||||
principalTable: "Maps",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Elements_Nodes_NodeId",
|
||||
column: x => x.NodeId,
|
||||
principalTable: "Nodes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Action_MapId_Name",
|
||||
table: "Actions",
|
||||
columns: new[] { "MapId", "Name" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Edge_MapId",
|
||||
table: "Edges",
|
||||
column: "MapId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Edges_EndNodeId",
|
||||
table: "Edges",
|
||||
column: "EndNodeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Edges_StartNodeId",
|
||||
table: "Edges",
|
||||
column: "StartNodeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ElementModel_MapId_Name",
|
||||
table: "ElementModels",
|
||||
columns: new[] { "MapId", "Name" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Element_MapId_ModelId",
|
||||
table: "Elements",
|
||||
columns: new[] { "MapId", "ModelId" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Elements_ModelId",
|
||||
table: "Elements",
|
||||
column: "ModelId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Elements_NodeId",
|
||||
table: "Elements",
|
||||
column: "NodeId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Node_MapId_Name",
|
||||
table: "Nodes",
|
||||
columns: new[] { "MapId", "Name" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Zone_MapId",
|
||||
table: "Zones",
|
||||
column: "MapId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Actions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Edges");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Elements");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Zones");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ElementModels");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Nodes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Maps");
|
||||
}
|
||||
}
|
||||
}
|
||||
608
RobotNet.MapManager/Data/Migrations/20250812041834_AddZoneName.Designer.cs
generated
Normal file
608
RobotNet.MapManager/Data/Migrations/20250812041834_AddZoneName.Designer.cs
generated
Normal file
@@ -0,0 +1,608 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using RobotNet.MapManager.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RobotNet.MapManager.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(MapEditorDbContext))]
|
||||
[Migration("20250812041834_AddZoneName")]
|
||||
partial class AddZoneName
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Action", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Content");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId", "Name" }, "IX_Action_MapId_Name");
|
||||
|
||||
b.ToTable("Actions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Edge", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Actions")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Actions");
|
||||
|
||||
b.Property<double>("AllowedDeviationTheta")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationTheta");
|
||||
|
||||
b.Property<double>("AllowedDeviationXy")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationXy");
|
||||
|
||||
b.Property<double>("ControlPoint1X")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint1X");
|
||||
|
||||
b.Property<double>("ControlPoint1Y")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint1Y");
|
||||
|
||||
b.Property<double>("ControlPoint2X")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint2X");
|
||||
|
||||
b.Property<double>("ControlPoint2Y")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint2Y");
|
||||
|
||||
b.Property<byte>("DirectionAllowed")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("DirectionAllowed");
|
||||
|
||||
b.Property<Guid>("EndNodeId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("EndNodeId");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<double>("MaxHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MaxHeight");
|
||||
|
||||
b.Property<double>("MaxRotationSpeed")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MaxRotationSpeed");
|
||||
|
||||
b.Property<double>("MaxSpeed")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MaxSpeed");
|
||||
|
||||
b.Property<double>("MinHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MinHeight");
|
||||
|
||||
b.Property<bool>("RotationAllowed")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("RotationAllowed");
|
||||
|
||||
b.Property<Guid>("StartNodeId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("StartNodeId");
|
||||
|
||||
b.Property<byte>("TrajectoryDegree")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("TrajectoryDegree");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EndNodeId");
|
||||
|
||||
b.HasIndex("StartNodeId");
|
||||
|
||||
b.HasIndex(new[] { "MapId" }, "IX_Edge_MapId");
|
||||
|
||||
b.ToTable("Edges");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Element", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Content");
|
||||
|
||||
b.Property<bool>("IsOpen")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsOpen");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<Guid>("ModelId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("ModelId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<Guid>("NodeId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("NodeId");
|
||||
|
||||
b.Property<double>("OffsetX")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OffsetX");
|
||||
|
||||
b.Property<double>("OffsetY")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OffsetY");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ModelId");
|
||||
|
||||
b.HasIndex("NodeId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex(new[] { "MapId", "ModelId" }, "IX_Element_MapId_ModelId");
|
||||
|
||||
b.ToTable("Elements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.ElementModel", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Content");
|
||||
|
||||
b.Property<double>("Height")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Height");
|
||||
|
||||
b.Property<int>("Image1Height")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image1Height");
|
||||
|
||||
b.Property<int>("Image1Width")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image1Width");
|
||||
|
||||
b.Property<int>("Image2Height")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image2Height");
|
||||
|
||||
b.Property<int>("Image2Width")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image2Width");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<double>("Width")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Width");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId", "Name" }, "IX_ElementModel_MapId_Name");
|
||||
|
||||
b.ToTable("ElementModels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Map", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<bool>("Active")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<double>("EdgeAllowedDeviationThetaDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeAllowedDeviationThetaDefault");
|
||||
|
||||
b.Property<double>("EdgeAllowedDeviationXyDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeAllowedDeviationXyDefault");
|
||||
|
||||
b.Property<double>("EdgeCurveMaxSpeedDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeCurveMaxSpeedDefault");
|
||||
|
||||
b.Property<byte>("EdgeDirectionAllowedDefault")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("EdgeDirectionAllowedDefault");
|
||||
|
||||
b.Property<double>("EdgeMaxHeightDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMaxHeightDefault");
|
||||
|
||||
b.Property<double>("EdgeMaxRotationSpeedDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMaxRoataionSpeedDefault");
|
||||
|
||||
b.Property<double>("EdgeMinHeightDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMinHeightDefault");
|
||||
|
||||
b.Property<double>("EdgeMinLengthDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMinLengthDefault");
|
||||
|
||||
b.Property<bool>("EdgeRotationAllowedDefault")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("EdgeRotationAllowedDefault");
|
||||
|
||||
b.Property<double>("EdgeStraightMaxSpeedDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeStraightMaxSpeedDefault");
|
||||
|
||||
b.Property<double>("ImageHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ImageHeight");
|
||||
|
||||
b.Property<double>("ImageWidth")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ImageWidth");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<double>("NodeAllowedDeviationThetaDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("NodeAllowedDeviationThetaDefault");
|
||||
|
||||
b.Property<double>("NodeAllowedDeviationXyDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("NodeAllowedDeviationXyDefault");
|
||||
|
||||
b.Property<long>("NodeCount")
|
||||
.HasColumnType("BigInt")
|
||||
.HasColumnName("NodeCount");
|
||||
|
||||
b.Property<bool>("NodeNameAutoGenerate")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("NodeNameAutoGenerate");
|
||||
|
||||
b.Property<string>("NodeNameTemplateDefault")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("NodeNameTemplateDefault");
|
||||
|
||||
b.Property<double>("OriginX")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OriginX");
|
||||
|
||||
b.Property<double>("OriginY")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OriginY");
|
||||
|
||||
b.Property<double>("Resolution")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Resolution");
|
||||
|
||||
b.Property<string>("VDA5050")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("VDA5050");
|
||||
|
||||
b.Property<Guid>("VersionId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("VersionId");
|
||||
|
||||
b.Property<double>("ViewHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewHeight");
|
||||
|
||||
b.Property<double>("ViewWidth")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewWidth");
|
||||
|
||||
b.Property<double>("ViewX")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewX");
|
||||
|
||||
b.Property<double>("ViewY")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewY");
|
||||
|
||||
b.Property<double>("ZoneMinSquareDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ZoneMinSquareDefault");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Maps");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Node", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Actions")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Actions");
|
||||
|
||||
b.Property<double>("AllowedDeviationTheta")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationTheta");
|
||||
|
||||
b.Property<double>("AllowedDeviationXy")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationXy");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<double>("Theta")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Theta");
|
||||
|
||||
b.Property<double>("X")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X");
|
||||
|
||||
b.Property<double>("Y")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId", "Name" }, "IX_Node_MapId_Name");
|
||||
|
||||
b.ToTable("Nodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Zone", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Type");
|
||||
|
||||
b.Property<double>("X1")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X1");
|
||||
|
||||
b.Property<double>("X2")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X2");
|
||||
|
||||
b.Property<double>("X3")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X3");
|
||||
|
||||
b.Property<double>("X4")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X4");
|
||||
|
||||
b.Property<double>("Y1")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y1");
|
||||
|
||||
b.Property<double>("Y2")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y2");
|
||||
|
||||
b.Property<double>("Y3")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y3");
|
||||
|
||||
b.Property<double>("Y4")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y4");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId" }, "IX_Zone_MapId");
|
||||
|
||||
b.ToTable("Zones");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Action", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Actions")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Edge", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Node", "EndNode")
|
||||
.WithMany("EndEdges")
|
||||
.HasForeignKey("EndNodeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Edges")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.Node", "StartNode")
|
||||
.WithMany("StartEdges")
|
||||
.HasForeignKey("StartNodeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("EndNode");
|
||||
|
||||
b.Navigation("Map");
|
||||
|
||||
b.Navigation("StartNode");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Element", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Elements")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.ElementModel", "Model")
|
||||
.WithMany("Elements")
|
||||
.HasForeignKey("ModelId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.Node", "Node")
|
||||
.WithOne("Element")
|
||||
.HasForeignKey("RobotNet.MapManager.Data.Element", "NodeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
|
||||
b.Navigation("Model");
|
||||
|
||||
b.Navigation("Node");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.ElementModel", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("ElementModels")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Node", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Nodes")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Zone", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Zones")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.ElementModel", b =>
|
||||
{
|
||||
b.Navigation("Elements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Map", b =>
|
||||
{
|
||||
b.Navigation("Actions");
|
||||
|
||||
b.Navigation("Edges");
|
||||
|
||||
b.Navigation("ElementModels");
|
||||
|
||||
b.Navigation("Elements");
|
||||
|
||||
b.Navigation("Nodes");
|
||||
|
||||
b.Navigation("Zones");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Node", b =>
|
||||
{
|
||||
b.Navigation("Element");
|
||||
|
||||
b.Navigation("EndEdges");
|
||||
|
||||
b.Navigation("StartEdges");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RobotNet.MapManager.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddZoneName : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Name",
|
||||
table: "Zones",
|
||||
type: "nvarchar(64)",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Name",
|
||||
table: "Zones");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,605 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using RobotNet.MapManager.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RobotNet.MapManager.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(MapEditorDbContext))]
|
||||
partial class MapEditorDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Action", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Content");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId", "Name" }, "IX_Action_MapId_Name");
|
||||
|
||||
b.ToTable("Actions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Edge", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Actions")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Actions");
|
||||
|
||||
b.Property<double>("AllowedDeviationTheta")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationTheta");
|
||||
|
||||
b.Property<double>("AllowedDeviationXy")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationXy");
|
||||
|
||||
b.Property<double>("ControlPoint1X")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint1X");
|
||||
|
||||
b.Property<double>("ControlPoint1Y")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint1Y");
|
||||
|
||||
b.Property<double>("ControlPoint2X")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint2X");
|
||||
|
||||
b.Property<double>("ControlPoint2Y")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ControlPoint2Y");
|
||||
|
||||
b.Property<byte>("DirectionAllowed")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("DirectionAllowed");
|
||||
|
||||
b.Property<Guid>("EndNodeId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("EndNodeId");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<double>("MaxHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MaxHeight");
|
||||
|
||||
b.Property<double>("MaxRotationSpeed")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MaxRotationSpeed");
|
||||
|
||||
b.Property<double>("MaxSpeed")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MaxSpeed");
|
||||
|
||||
b.Property<double>("MinHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("MinHeight");
|
||||
|
||||
b.Property<bool>("RotationAllowed")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("RotationAllowed");
|
||||
|
||||
b.Property<Guid>("StartNodeId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("StartNodeId");
|
||||
|
||||
b.Property<byte>("TrajectoryDegree")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("TrajectoryDegree");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EndNodeId");
|
||||
|
||||
b.HasIndex("StartNodeId");
|
||||
|
||||
b.HasIndex(new[] { "MapId" }, "IX_Edge_MapId");
|
||||
|
||||
b.ToTable("Edges");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Element", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Content");
|
||||
|
||||
b.Property<bool>("IsOpen")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsOpen");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<Guid>("ModelId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("ModelId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<Guid>("NodeId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("NodeId");
|
||||
|
||||
b.Property<double>("OffsetX")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OffsetX");
|
||||
|
||||
b.Property<double>("OffsetY")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OffsetY");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ModelId");
|
||||
|
||||
b.HasIndex("NodeId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex(new[] { "MapId", "ModelId" }, "IX_Element_MapId_ModelId");
|
||||
|
||||
b.ToTable("Elements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.ElementModel", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Content");
|
||||
|
||||
b.Property<double>("Height")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Height");
|
||||
|
||||
b.Property<int>("Image1Height")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image1Height");
|
||||
|
||||
b.Property<int>("Image1Width")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image1Width");
|
||||
|
||||
b.Property<int>("Image2Height")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image2Height");
|
||||
|
||||
b.Property<int>("Image2Width")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Image2Width");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<double>("Width")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Width");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId", "Name" }, "IX_ElementModel_MapId_Name");
|
||||
|
||||
b.ToTable("ElementModels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Map", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<bool>("Active")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<double>("EdgeAllowedDeviationThetaDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeAllowedDeviationThetaDefault");
|
||||
|
||||
b.Property<double>("EdgeAllowedDeviationXyDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeAllowedDeviationXyDefault");
|
||||
|
||||
b.Property<double>("EdgeCurveMaxSpeedDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeCurveMaxSpeedDefault");
|
||||
|
||||
b.Property<byte>("EdgeDirectionAllowedDefault")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("EdgeDirectionAllowedDefault");
|
||||
|
||||
b.Property<double>("EdgeMaxHeightDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMaxHeightDefault");
|
||||
|
||||
b.Property<double>("EdgeMaxRotationSpeedDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMaxRoataionSpeedDefault");
|
||||
|
||||
b.Property<double>("EdgeMinHeightDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMinHeightDefault");
|
||||
|
||||
b.Property<double>("EdgeMinLengthDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeMinLengthDefault");
|
||||
|
||||
b.Property<bool>("EdgeRotationAllowedDefault")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("EdgeRotationAllowedDefault");
|
||||
|
||||
b.Property<double>("EdgeStraightMaxSpeedDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("EdgeStraightMaxSpeedDefault");
|
||||
|
||||
b.Property<double>("ImageHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ImageHeight");
|
||||
|
||||
b.Property<double>("ImageWidth")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ImageWidth");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<double>("NodeAllowedDeviationThetaDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("NodeAllowedDeviationThetaDefault");
|
||||
|
||||
b.Property<double>("NodeAllowedDeviationXyDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("NodeAllowedDeviationXyDefault");
|
||||
|
||||
b.Property<long>("NodeCount")
|
||||
.HasColumnType("BigInt")
|
||||
.HasColumnName("NodeCount");
|
||||
|
||||
b.Property<bool>("NodeNameAutoGenerate")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("NodeNameAutoGenerate");
|
||||
|
||||
b.Property<string>("NodeNameTemplateDefault")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("NodeNameTemplateDefault");
|
||||
|
||||
b.Property<double>("OriginX")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OriginX");
|
||||
|
||||
b.Property<double>("OriginY")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("OriginY");
|
||||
|
||||
b.Property<double>("Resolution")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Resolution");
|
||||
|
||||
b.Property<string>("VDA5050")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("VDA5050");
|
||||
|
||||
b.Property<Guid>("VersionId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("VersionId");
|
||||
|
||||
b.Property<double>("ViewHeight")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewHeight");
|
||||
|
||||
b.Property<double>("ViewWidth")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewWidth");
|
||||
|
||||
b.Property<double>("ViewX")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewX");
|
||||
|
||||
b.Property<double>("ViewY")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ViewY");
|
||||
|
||||
b.Property<double>("ZoneMinSquareDefault")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("ZoneMinSquareDefault");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Maps");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Node", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("Actions")
|
||||
.HasColumnType("nvarchar(max)")
|
||||
.HasColumnName("Actions");
|
||||
|
||||
b.Property<double>("AllowedDeviationTheta")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationTheta");
|
||||
|
||||
b.Property<double>("AllowedDeviationXy")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("AllowedDeviationXy");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<double>("Theta")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Theta");
|
||||
|
||||
b.Property<double>("X")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X");
|
||||
|
||||
b.Property<double>("Y")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId", "Name" }, "IX_Node_MapId_Name");
|
||||
|
||||
b.ToTable("Nodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Zone", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<Guid>("MapId")
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("MapId");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Type");
|
||||
|
||||
b.Property<double>("X1")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X1");
|
||||
|
||||
b.Property<double>("X2")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X2");
|
||||
|
||||
b.Property<double>("X3")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X3");
|
||||
|
||||
b.Property<double>("X4")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("X4");
|
||||
|
||||
b.Property<double>("Y1")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y1");
|
||||
|
||||
b.Property<double>("Y2")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y2");
|
||||
|
||||
b.Property<double>("Y3")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y3");
|
||||
|
||||
b.Property<double>("Y4")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Y4");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "MapId" }, "IX_Zone_MapId");
|
||||
|
||||
b.ToTable("Zones");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Action", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Actions")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Edge", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Node", "EndNode")
|
||||
.WithMany("EndEdges")
|
||||
.HasForeignKey("EndNodeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Edges")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.Node", "StartNode")
|
||||
.WithMany("StartEdges")
|
||||
.HasForeignKey("StartNodeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("EndNode");
|
||||
|
||||
b.Navigation("Map");
|
||||
|
||||
b.Navigation("StartNode");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Element", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Elements")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.ElementModel", "Model")
|
||||
.WithMany("Elements")
|
||||
.HasForeignKey("ModelId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotNet.MapManager.Data.Node", "Node")
|
||||
.WithOne("Element")
|
||||
.HasForeignKey("RobotNet.MapManager.Data.Element", "NodeId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
|
||||
b.Navigation("Model");
|
||||
|
||||
b.Navigation("Node");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.ElementModel", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("ElementModels")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Node", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Nodes")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Zone", b =>
|
||||
{
|
||||
b.HasOne("RobotNet.MapManager.Data.Map", "Map")
|
||||
.WithMany("Zones")
|
||||
.HasForeignKey("MapId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Map");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.ElementModel", b =>
|
||||
{
|
||||
b.Navigation("Elements");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Map", b =>
|
||||
{
|
||||
b.Navigation("Actions");
|
||||
|
||||
b.Navigation("Edges");
|
||||
|
||||
b.Navigation("ElementModels");
|
||||
|
||||
b.Navigation("Elements");
|
||||
|
||||
b.Navigation("Nodes");
|
||||
|
||||
b.Navigation("Zones");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotNet.MapManager.Data.Node", b =>
|
||||
{
|
||||
b.Navigation("Element");
|
||||
|
||||
b.Navigation("EndEdges");
|
||||
|
||||
b.Navigation("StartEdges");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
51
RobotNet.MapManager/Data/Node.cs
Normal file
51
RobotNet.MapManager/Data/Node.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace RobotNet.MapManager.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("Nodes")]
|
||||
[Index(nameof(MapId), nameof(Name), Name = "IX_Node_MapId_Name")]
|
||||
public class Node
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("MapId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid MapId { get; set; }
|
||||
|
||||
[Column("Name", TypeName = "nvarchar(64)")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("X", TypeName = "float")]
|
||||
[Required]
|
||||
public double X { get; set; }
|
||||
|
||||
[Column("Y", TypeName = "float")]
|
||||
[Required]
|
||||
public double Y { get; set; }
|
||||
|
||||
[Column("Theta", TypeName = "float")]
|
||||
[Required]
|
||||
public double Theta { get; set; }
|
||||
|
||||
[Column("AllowedDeviationXy", TypeName = "float")]
|
||||
public double AllowedDeviationXy { get; set; }
|
||||
|
||||
[Column("AllowedDeviationTheta", TypeName = "float")]
|
||||
public double AllowedDeviationTheta { get; set; }
|
||||
|
||||
[Column("Actions", TypeName = "nvarchar(max)")]
|
||||
public string Actions { get; set; }
|
||||
|
||||
public Map Map { get; set; }
|
||||
public Element Element { get; set; }
|
||||
public ICollection<Edge> StartEdges { get; } = [];
|
||||
public ICollection<Edge> EndEdges { get; } = [];
|
||||
}
|
||||
61
RobotNet.MapManager/Data/Zone.cs
Normal file
61
RobotNet.MapManager/Data/Zone.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapShares.Enums;
|
||||
|
||||
namespace RobotNet.MapManager.Data;
|
||||
|
||||
[Table("Zones")]
|
||||
[Index(nameof(MapId), Name = "IX_Zone_MapId")]
|
||||
public class Zone
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("MapId", TypeName = "uniqueidentifier")]
|
||||
[Required]
|
||||
public Guid MapId { get; set; }
|
||||
|
||||
[Column("Type", TypeName = "int")]
|
||||
[Required]
|
||||
public ZoneType Type { get; set; }
|
||||
|
||||
[Column("Name", TypeName = "nvarchar(64)")]
|
||||
[Required]
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
[Column("X1", TypeName = "float")]
|
||||
[Required]
|
||||
public double X1 { get; set; }
|
||||
|
||||
[Column("Y1", TypeName = "float")]
|
||||
[Required]
|
||||
public double Y1 { get; set; }
|
||||
|
||||
[Column("X2", TypeName = "float")]
|
||||
[Required]
|
||||
public double X2 { get; set; }
|
||||
|
||||
[Column("Y2", TypeName = "float")]
|
||||
[Required]
|
||||
public double Y2 { get; set; }
|
||||
|
||||
[Column("X3", TypeName = "float")]
|
||||
[Required]
|
||||
public double X3 { get; set; }
|
||||
|
||||
[Column("Y3", TypeName = "float")]
|
||||
[Required]
|
||||
public double Y3 { get; set; }
|
||||
|
||||
[Column("X4", TypeName = "float")]
|
||||
public double X4 { get; set; }
|
||||
|
||||
[Column("Y4", TypeName = "float")]
|
||||
public double Y4 { get; set; }
|
||||
|
||||
public Map Map { get; set; } = default!;
|
||||
}
|
||||
65
RobotNet.MapManager/Dockerfile
Normal file
65
RobotNet.MapManager/Dockerfile
Normal file
@@ -0,0 +1,65 @@
|
||||
FROM alpine:3.22 AS base
|
||||
WORKDIR /app
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
|
||||
WORKDIR /src
|
||||
|
||||
COPY ["RobotNet.MapManager/RobotNet.MapManager.csproj", "RobotNet.MapManager/"]
|
||||
COPY ["RobotNet.MapShares/RobotNet.MapShares.csproj", "RobotNet.MapShares/"]
|
||||
COPY ["RobotNet.Script/RobotNet.Script.csproj", "RobotNet.Script/"]
|
||||
COPY ["RobotNet.Script.Expressions/RobotNet.Script.Expressions.csproj", "RobotNet.Script.Expressions/"]
|
||||
COPY ["RobotNet.Shares/RobotNet.Shares.csproj", "RobotNet.Shares/"]
|
||||
COPY ["RobotNet.OpenIddictClient/RobotNet.OpenIddictClient.csproj", "RobotNet.OpenIddictClient/"]
|
||||
|
||||
# RUN dotnet package remove "Microsoft.EntityFrameworkCore.Tools" --project "RobotNet.MapManager/RobotNet.MapManager.csproj"
|
||||
RUN dotnet restore "RobotNet.MapManager/RobotNet.MapManager.csproj"
|
||||
|
||||
COPY RobotNet.MapManager/ RobotNet.MapManager/
|
||||
COPY RobotNet.MapShares/ RobotNet.MapShares/
|
||||
COPY RobotNet.Script/ RobotNet.Script/
|
||||
COPY RobotNet.Script.Expressions/ RobotNet.Script.Expressions/
|
||||
COPY RobotNet.Shares/ RobotNet.Shares/
|
||||
COPY RobotNet.OpenIddictClient/ RobotNet.OpenIddictClient/
|
||||
|
||||
RUN rm -rf ./RobotNet.MapManager/bin
|
||||
RUN rm -rf ./RobotNet.MapManager/obj
|
||||
RUN rm -rf ./RobotNet.MapShares/bin
|
||||
RUN rm -rf ./RobotNet.MapShares/obj
|
||||
RUN rm -rf ./RobotNet.Script/bin
|
||||
RUN rm -rf ./RobotNet.Script/obj
|
||||
RUN rm -rf ./RobotNet.Script.Expressions/bin
|
||||
RUN rm -rf ./RobotNet.Script.Expressions/obj
|
||||
RUN rm -rf ./RobotNet.Shares/bin
|
||||
RUN rm -rf ./RobotNet.Shares/obj
|
||||
RUN rm -rf ./RobotNet.OpenIddictClient/bin
|
||||
RUN rm -rf ./RobotNet.OpenIddictClient/obj
|
||||
|
||||
WORKDIR "/src/RobotNet.MapManager"
|
||||
RUN dotnet build "RobotNet.MapManager.csproj" -c Release -o /app/build
|
||||
|
||||
FROM build AS publish
|
||||
WORKDIR /src/RobotNet.MapManager
|
||||
RUN dotnet publish "RobotNet.MapManager.csproj" \
|
||||
-c Release \
|
||||
-o /app/publish \
|
||||
--runtime linux-musl-x64 \
|
||||
--self-contained true \
|
||||
/p:PublishTrimmed=false \
|
||||
/p:PublishReadyToRun=true
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish ./
|
||||
|
||||
RUN apk add --no-cache icu-libs tzdata ca-certificates
|
||||
|
||||
RUN echo '#!/bin/sh' >> ./start.sh
|
||||
RUN echo 'update-ca-certificates' >> ./start.sh
|
||||
RUN echo 'exec ./RobotNet.MapManager' >> ./start.sh
|
||||
|
||||
RUN chmod +x ./RobotNet.MapManager
|
||||
RUN chmod +x ./start.sh
|
||||
|
||||
# Use the start script to ensure certificates are updated before starting the application
|
||||
EXPOSE 443
|
||||
ENTRYPOINT ["./start.sh"]
|
||||
165
RobotNet.MapManager/Hubs/MapHub.cs
Normal file
165
RobotNet.MapManager/Hubs/MapHub.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.Shares;
|
||||
|
||||
namespace RobotNet.MapManager.Hubs;
|
||||
|
||||
[Authorize]
|
||||
public class MapHub(MapEditorDbContext MapDb) : Hub
|
||||
{
|
||||
public async Task<MessageResult<MapDataDto>> GetMapData(Guid mapId)
|
||||
{
|
||||
var map = await MapDb.Maps.FindAsync(mapId);
|
||||
if (map is null) return new(false, $"Không tìm thấy bản đồ: {mapId}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new()
|
||||
{
|
||||
Id = map.Id,
|
||||
Name = map.Name,
|
||||
OriginX = map.OriginX,
|
||||
OriginY = map.OriginY,
|
||||
Resolution = map.Resolution,
|
||||
ImageHeight = map.ImageHeight,
|
||||
ImageWidth = map.ImageWidth,
|
||||
Active = map.Active,
|
||||
Nodes = [.. MapDb.Nodes.Where(node => node.MapId == mapId).Select(node => new NodeDto()
|
||||
{
|
||||
Id = node.Id,
|
||||
MapId = node.MapId,
|
||||
Name = node.Name,
|
||||
Theta = node.Theta,
|
||||
X = node.X,
|
||||
Y = node.Y,
|
||||
AllowedDeviationXy = node.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = node.AllowedDeviationTheta,
|
||||
Actions = node.Actions,
|
||||
})],
|
||||
Edges = [.. MapDb.Edges.Where(edge => edge.MapId == mapId).Select(edge => new EdgeDto()
|
||||
{
|
||||
Id = edge.Id,
|
||||
MapId = edge.MapId,
|
||||
StartNodeId = edge.StartNodeId,
|
||||
EndNodeId = edge.EndNodeId,
|
||||
|
||||
MaxSpeed = edge.MaxSpeed,
|
||||
MaxHeight = edge.MaxHeight,
|
||||
MinHeight = edge.MinHeight,
|
||||
DirectionAllowed = edge.DirectionAllowed,
|
||||
RotationAllowed = edge.RotationAllowed,
|
||||
TrajectoryDegree = edge.TrajectoryDegree,
|
||||
ControlPoint1X = edge.ControlPoint1X,
|
||||
ControlPoint1Y = edge.ControlPoint1Y,
|
||||
ControlPoint2X = edge.ControlPoint2X,
|
||||
ControlPoint2Y = edge.ControlPoint2Y,
|
||||
MaxRotationSpeed = edge.MaxRotationSpeed,
|
||||
Actions = edge.Actions,
|
||||
AllowedDeviationXy = edge.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = edge.AllowedDeviationTheta,
|
||||
})],
|
||||
Zones = [.. MapDb.Zones.Where(zone => zone.MapId == mapId).Select(zone => new ZoneDto()
|
||||
{
|
||||
Id = zone.Id,
|
||||
MapId = zone.MapId,
|
||||
Type = zone.Type,
|
||||
Name = zone.Name,
|
||||
X1 = zone.X1,
|
||||
X2 = zone.X2,
|
||||
Y1 = zone.Y1,
|
||||
Y2 = zone.Y2,
|
||||
X3 = zone.X3,
|
||||
Y3 = zone.Y3,
|
||||
X4 = zone.X4,
|
||||
Y4 = zone.Y4,
|
||||
}).OrderBy(z => z.Type)],
|
||||
Elements = [.. MapDb.Elements.Where(el => el.MapId == mapId).Select(element => new ElementDto()
|
||||
{
|
||||
Id = element.Id,
|
||||
MapId = element.MapId,
|
||||
ModelId = element.ModelId,
|
||||
Name = element.Name,
|
||||
NodeId = element.NodeId,
|
||||
OffsetX = element.OffsetX,
|
||||
OffsetY = element.OffsetY,
|
||||
IsOpen = element.IsOpen,
|
||||
Content = element.Content,
|
||||
})],
|
||||
Actions = [.. MapDb.Actions.Where(a => a.MapId == mapId).Select(action => new ActionDto()
|
||||
{
|
||||
Id = action.Id,
|
||||
MapId = action.MapId,
|
||||
Name = action.Name,
|
||||
Content = action.Content,
|
||||
})]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<MessageResult<ElementDto[]>> GetElementsState(Guid mapId)
|
||||
{
|
||||
var map = await MapDb.Maps.FindAsync(mapId);
|
||||
if (map is null) return new(false, $"Không tìm thấy bản đồ: {mapId}");
|
||||
var elements = MapDb.Elements
|
||||
.Where(el => el.MapId == mapId)
|
||||
.Select(element => new ElementDto()
|
||||
{
|
||||
Id = element.Id,
|
||||
MapId = element.MapId,
|
||||
ModelId = element.ModelId,
|
||||
Name = element.Name,
|
||||
NodeId = element.NodeId,
|
||||
OffsetX = element.OffsetX,
|
||||
OffsetY = element.OffsetY,
|
||||
IsOpen = element.IsOpen,
|
||||
Content = element.Content
|
||||
});
|
||||
return new(true, "") { Data = [..elements] };
|
||||
}
|
||||
|
||||
public async Task<MessageResult<MapInfoDto>> GetMapInfoByName(string name)
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Name == name);
|
||||
if (map == null) return new MessageResult<MapInfoDto>(false, $"Không tìm thấy map {name}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new MapInfoDto()
|
||||
{
|
||||
Id = map.Id,
|
||||
Name = map.Name,
|
||||
Active = map.Active,
|
||||
OriginX = map.OriginX,
|
||||
OriginY = map.OriginY,
|
||||
Width = Math.Round(map.ImageWidth * map.Resolution, 2),
|
||||
Height = Math.Round(map.ImageHeight * map.Resolution, 2),
|
||||
Resolution = map.Resolution,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<MessageResult<MapInfoDto>> GetMapInfoById(Guid id)
|
||||
{
|
||||
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Id == id);
|
||||
if (map == null) return new MessageResult<MapInfoDto>(false, $"Không tìm thấy map {id}");
|
||||
|
||||
return new(true)
|
||||
{
|
||||
Data = new MapInfoDto()
|
||||
{
|
||||
Id = map.Id,
|
||||
Name = map.Name,
|
||||
Active = map.Active,
|
||||
OriginX = map.OriginX,
|
||||
OriginY = map.OriginY,
|
||||
Width = Math.Round(map.ImageWidth * map.Resolution, 2),
|
||||
Height = Math.Round(map.ImageHeight * map.Resolution, 2),
|
||||
Resolution = map.Resolution,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
94
RobotNet.MapManager/Program.cs
Normal file
94
RobotNet.MapManager/Program.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NLog.Web;
|
||||
using OpenIddict.Validation.AspNetCore;
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapManager.Hubs;
|
||||
using RobotNet.MapManager.Services;
|
||||
using RobotNet.OpenIddictClient;
|
||||
using System.Globalization;
|
||||
|
||||
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Host.UseNLog();
|
||||
|
||||
// builder.AddServiceDefaults();
|
||||
|
||||
// Add services to the container.
|
||||
var openIddictOption = builder.Configuration.GetSection(nameof(OpenIddictClientProviderOptions)).Get<OpenIddictClientProviderOptions>()
|
||||
?? throw new InvalidOperationException("OpenID configuration not found or invalid format.");
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddSignalR();
|
||||
builder.Services.AddOpenIddict()
|
||||
.AddValidation(options =>
|
||||
{
|
||||
// Note: the validation handler uses OpenID Connect discovery
|
||||
// to retrieve the address of the introspection endpoint.
|
||||
options.SetIssuer(openIddictOption.Issuer);
|
||||
options.AddAudiences(openIddictOption.Audiences);
|
||||
|
||||
// Configure the validation handler to use introspection and register the client
|
||||
// credentials used when communicating with the remote introspection endpoint.
|
||||
options.UseIntrospection()
|
||||
.SetClientId(openIddictOption.ClientId)
|
||||
.SetClientSecret(openIddictOption.ClientSecret);
|
||||
|
||||
// Register the System.Net.Http integration.
|
||||
if (builder.Environment.IsDevelopment())
|
||||
{
|
||||
options.UseSystemNetHttp(httpOptions =>
|
||||
{
|
||||
httpOptions.ConfigureHttpClientHandler(context =>
|
||||
{
|
||||
context.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => true;
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
options.UseSystemNetHttp();
|
||||
}
|
||||
|
||||
// Register the ASP.NET Core host.
|
||||
options.UseAspNetCore();
|
||||
});
|
||||
|
||||
builder.Services.AddAuthentication(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
|
||||
builder.Services.AddAuthorization();
|
||||
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
options.AddDefaultPolicy(policy =>
|
||||
{
|
||||
policy.AllowAnyOrigin()
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
|
||||
Action<DbContextOptionsBuilder> appDbOptions = options => options.UseSqlServer(connectionString, b => b.MigrationsAssembly("RobotNet.MapManager"));
|
||||
builder.Services.AddDbContext<MapEditorDbContext>(appDbOptions);
|
||||
|
||||
builder.Services.AddSingleton<MapEditorStorageRepository>();
|
||||
builder.Services.AddSingleton(typeof(LoggerController<>));
|
||||
|
||||
var app = builder.Build();
|
||||
await app.Services.SeedMapManagerDbAsync();
|
||||
// Configure the HTTP request pipeline.
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseCors();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.MapHub<MapHub>("/hubs/map/data");
|
||||
|
||||
app.Run();
|
||||
15
RobotNet.MapManager/Properties/launchSettings.json
Normal file
15
RobotNet.MapManager/Properties/launchSettings.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"workingDirectory": "$(TargetDir)",
|
||||
"applicationUrl": "https://localhost:7177",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
RobotNet.MapManager/RobotNet.MapManager.csproj
Normal file
29
RobotNet.MapManager/RobotNet.MapManager.csproj
Normal file
@@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NLog" Version="6.0.3" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="6.0.3" />
|
||||
<PackageReference Include="OpenIddict.Validation.AspNetCore" Version="7.0.0" />
|
||||
<PackageReference Include="OpenIddict.Validation.SystemNetHttp" Version="7.0.0" />
|
||||
<PackageReference Include="Minio" Version="6.0.5" />
|
||||
<PackageReference Include="Serialize.Linq" Version="4.0.167" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RobotNet.MapShares\RobotNet.MapShares.csproj" />
|
||||
<ProjectReference Include="..\RobotNet.OpenIddictClient\RobotNet.OpenIddictClient.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
6
RobotNet.MapManager/RobotNet.MapManager.http
Normal file
6
RobotNet.MapManager/RobotNet.MapManager.http
Normal file
@@ -0,0 +1,6 @@
|
||||
@RobotNet.MapManager_HostAddress = http://localhost:5082
|
||||
|
||||
GET {{RobotNet.MapManager_HostAddress}}/weatherforecast/
|
||||
Accept: application/json
|
||||
|
||||
###
|
||||
108
RobotNet.MapManager/Services/LoggerController.cs
Normal file
108
RobotNet.MapManager/Services/LoggerController.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
namespace RobotNet.MapManager.Services;
|
||||
|
||||
public class LoggerController<T>(ILogger<T> Logger)
|
||||
{
|
||||
public event Action? LoggerUpdate;
|
||||
public void Write(string message, LogLevel level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case LogLevel.Trace:
|
||||
Logger.LogTrace("{mes}", message);
|
||||
break;
|
||||
case LogLevel.Debug:
|
||||
Logger.LogDebug("{mes}", message);
|
||||
break;
|
||||
case LogLevel.Information:
|
||||
Logger.LogInformation("{mes}", message);
|
||||
break;
|
||||
case LogLevel.Warning:
|
||||
Logger.LogWarning("{mes}", message);
|
||||
break;
|
||||
case LogLevel.Error:
|
||||
Logger.LogError("{mes}", message);
|
||||
break;
|
||||
case LogLevel.Critical:
|
||||
Logger.LogCritical("{mes}", message);
|
||||
break;
|
||||
}
|
||||
LoggerUpdate?.Invoke();
|
||||
}
|
||||
|
||||
public void Write(string message)
|
||||
{
|
||||
Write(message, LogLevel.Information);
|
||||
}
|
||||
|
||||
public async Task WriteAsync(string message)
|
||||
{
|
||||
var write = Task.Run(() => Write(message));
|
||||
await write.WaitAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
public async Task TraceAsync(string message)
|
||||
{
|
||||
var write = Task.Run(() => Write(message, LogLevel.Trace));
|
||||
await write.WaitAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
public async Task DebugAsync(string message)
|
||||
{
|
||||
var write = Task.Run(() => Write(message, LogLevel.Debug));
|
||||
await write.WaitAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
public async Task InfoAsync(string message)
|
||||
{
|
||||
var write = Task.Run(() => Write(message, LogLevel.Information));
|
||||
await write.WaitAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
public async Task WarningAsync(string message)
|
||||
{
|
||||
var write = Task.Run(() => Write(message, LogLevel.Warning));
|
||||
await write.WaitAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
public async Task ErrorAsync(string message)
|
||||
{
|
||||
var write = Task.Run(() => Write(message, LogLevel.Error));
|
||||
await write.WaitAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
public async Task CriticalAsync(string message)
|
||||
{
|
||||
var write = Task.Run(() => Write(message, LogLevel.Critical));
|
||||
await write.WaitAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
public void Trace(string message)
|
||||
{
|
||||
Write(message, LogLevel.Trace);
|
||||
}
|
||||
|
||||
public void Debug(string message)
|
||||
{
|
||||
Write(message, LogLevel.Debug);
|
||||
}
|
||||
|
||||
public void Info(string message)
|
||||
{
|
||||
Write(message, LogLevel.Information);
|
||||
}
|
||||
|
||||
public void Warning(string message)
|
||||
{
|
||||
Write(message, LogLevel.Warning);
|
||||
}
|
||||
|
||||
public void Error(string message)
|
||||
{
|
||||
Write(message, LogLevel.Error);
|
||||
}
|
||||
|
||||
public void Critical(string message)
|
||||
{
|
||||
Write(message, LogLevel.Critical);
|
||||
}
|
||||
}
|
||||
140
RobotNet.MapManager/Services/MapEditorStorageRepository.cs
Normal file
140
RobotNet.MapManager/Services/MapEditorStorageRepository.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using Minio;
|
||||
using Minio.DataModel.Args;
|
||||
using Minio.Exceptions;
|
||||
|
||||
namespace RobotNet.MapManager.Services;
|
||||
|
||||
public class MapEditorStorageRepository
|
||||
{
|
||||
private class MinioOption
|
||||
{
|
||||
public bool UsingLocal { get; set; }
|
||||
public string? Endpoint { get; set; }
|
||||
public string? User { get; set; }
|
||||
public string? Password { get; set; }
|
||||
public string? Bucket { get; set; }
|
||||
}
|
||||
|
||||
private readonly IMinioClient MinioClient;
|
||||
private readonly MinioOption MinioOptions = new();
|
||||
public MapEditorStorageRepository(IConfiguration configuration)
|
||||
{
|
||||
configuration.Bind("MinIO", MinioOptions);
|
||||
MinioClient = new MinioClient()
|
||||
.WithEndpoint(MinioOptions.Endpoint)
|
||||
.WithCredentials(MinioOptions.User, MinioOptions.Password)
|
||||
.WithSSL(false)
|
||||
.Build();
|
||||
}
|
||||
|
||||
public async Task<(bool, string)> UploadAsync(string path, string objectName, Stream data, long size, string contentType, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!MinioOptions.UsingLocal)
|
||||
{
|
||||
var beArgs = new BucketExistsArgs().WithBucket(MinioOptions.Bucket);
|
||||
bool found = await MinioClient.BucketExistsAsync(beArgs, cancellationToken).ConfigureAwait(false);
|
||||
if (!found)
|
||||
{
|
||||
var mbArgs = new MakeBucketArgs()
|
||||
.WithBucket(MinioOptions.Bucket);
|
||||
await MinioClient.MakeBucketAsync(mbArgs, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
var getListBucketsTask = await MinioClient.ListBucketsAsync(cancellationToken);
|
||||
var putObjectArgs = new PutObjectArgs()
|
||||
.WithBucket(MinioOptions.Bucket)
|
||||
.WithObject($"{path}/{objectName}")
|
||||
.WithObjectSize(size)
|
||||
.WithStreamData(data)
|
||||
.WithContentType(contentType);
|
||||
await MinioClient.PutObjectAsync(putObjectArgs, cancellationToken).ConfigureAwait(false);
|
||||
return (true, "");
|
||||
}
|
||||
|
||||
var mapImageFolder = string.IsNullOrEmpty(MinioOptions.Bucket) ? "MapImages" : MinioOptions.Bucket;
|
||||
if (!Directory.Exists(mapImageFolder)) Directory.CreateDirectory(mapImageFolder);
|
||||
var folderPath = Path.Combine(mapImageFolder, path);
|
||||
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
|
||||
var pathLocal = Path.Combine(folderPath, $"{objectName}.png");
|
||||
if (File.Exists($"{pathLocal}.bk")) File.Delete($"{pathLocal}.bk");
|
||||
if (File.Exists(pathLocal)) File.Move(pathLocal, $"{pathLocal}.bk");
|
||||
using (Stream fileStream = new FileStream(pathLocal, FileMode.Create))
|
||||
{
|
||||
await data.CopyToAsync(fileStream, cancellationToken);
|
||||
}
|
||||
return (true, "");
|
||||
}
|
||||
catch (MinioException ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public (bool usingLocal, string url) GetUrl(string path, string objectName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!MinioOptions.UsingLocal)
|
||||
{
|
||||
var presignedGetObjectArgs = new PresignedGetObjectArgs()
|
||||
.WithBucket(MinioOptions.Bucket)
|
||||
.WithObject($"{path}/{objectName}")
|
||||
.WithExpiry(60 * 60 * 24);
|
||||
var url = MinioClient.PresignedGetObjectAsync(presignedGetObjectArgs);
|
||||
url.Wait();
|
||||
return (false, url.Result);
|
||||
}
|
||||
var mapImageFolder = string.IsNullOrEmpty(MinioOptions.Bucket) ? "MapImages" : MinioOptions.Bucket;
|
||||
if (Directory.Exists(mapImageFolder))
|
||||
{
|
||||
var folderPath = Path.Combine(mapImageFolder, path);
|
||||
if (Directory.Exists(folderPath))
|
||||
{
|
||||
var pathLocal = Path.Combine(folderPath, $"{objectName}.png");
|
||||
if (File.Exists(pathLocal))
|
||||
{
|
||||
return (true, pathLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (true, "");
|
||||
}
|
||||
catch (MinioException ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool, string)> DeleteAsync(string path, string objectName, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!MinioOptions.UsingLocal)
|
||||
{
|
||||
var removeObjectArgs = new RemoveObjectArgs()
|
||||
.WithBucket(MinioOptions.Bucket)
|
||||
.WithObject($"{path}/{objectName}");
|
||||
await MinioClient.RemoveObjectAsync(removeObjectArgs, cancellationToken).ConfigureAwait(false);
|
||||
return (true, "");
|
||||
}
|
||||
var mapImageFolder = string.IsNullOrEmpty(MinioOptions.Bucket) ? "MapImages" : MinioOptions.Bucket;
|
||||
if (Directory.Exists(mapImageFolder))
|
||||
{
|
||||
var folderPath = Path.Combine(mapImageFolder, path);
|
||||
if (Directory.Exists(folderPath))
|
||||
{
|
||||
var pathLocal = Path.Combine(folderPath, $"{objectName}.png");
|
||||
if (File.Exists(pathLocal)) File.Delete(pathLocal);
|
||||
if (File.Exists($"{pathLocal}.bk")) File.Delete($"{pathLocal}.bk");
|
||||
}
|
||||
}
|
||||
return (true, "");
|
||||
}
|
||||
catch (MinioException ex)
|
||||
{
|
||||
return (false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
161
RobotNet.MapManager/Services/ServerHelper.cs
Normal file
161
RobotNet.MapManager/Services/ServerHelper.cs
Normal file
@@ -0,0 +1,161 @@
|
||||
using RobotNet.MapManager.Data;
|
||||
using RobotNet.MapShares.Dtos;
|
||||
using RobotNet.MapShares.Enums;
|
||||
|
||||
namespace RobotNet.MapManager.Services;
|
||||
|
||||
public class ServerHelper
|
||||
{
|
||||
public static Edge CreateEdge(Map map, Guid startNodeId, Guid endNodeId, TrajectoryDegree trajectoryDegree, double cpX1 = 0, double cpY1 = 0, double cpX2 = 0, double cpY2 = 0)
|
||||
{
|
||||
return new Edge()
|
||||
{
|
||||
MapId = map.Id,
|
||||
StartNodeId = startNodeId,
|
||||
EndNodeId = endNodeId,
|
||||
TrajectoryDegree = trajectoryDegree,
|
||||
DirectionAllowed = map.EdgeDirectionAllowedDefault,
|
||||
RotationAllowed = map.EdgeRotationAllowedDefault,
|
||||
MaxSpeed = trajectoryDegree == TrajectoryDegree.One ? map.EdgeStraightMaxSpeedDefault : map.EdgeCurveMaxSpeedDefault,
|
||||
MaxRotationSpeed = map.EdgeMaxRotationSpeedDefault,
|
||||
MaxHeight = map.EdgeMaxHeightDefault,
|
||||
MinHeight = map.EdgeMinHeightDefault,
|
||||
Actions = "[]",
|
||||
AllowedDeviationXy = map.EdgeAllowedDeviationXyDefault,
|
||||
AllowedDeviationTheta = map.EdgeAllowedDeviationThetaDefault,
|
||||
ControlPoint1X = cpX1,
|
||||
ControlPoint1Y = cpY1,
|
||||
ControlPoint2X = cpX2,
|
||||
ControlPoint2Y = cpY2,
|
||||
};
|
||||
}
|
||||
|
||||
public static Node CreateNode(Map map, double x, double y)
|
||||
{
|
||||
return new Node()
|
||||
{
|
||||
MapId = map.Id,
|
||||
Name = map.NodeNameAutoGenerate ? $"{map.NodeNameTemplateDefault}{++map.NodeCount}" : string.Empty,
|
||||
X = x,
|
||||
Y = y,
|
||||
Theta = 0,
|
||||
AllowedDeviationXy = map.NodeAllowedDeviationXyDefault,
|
||||
AllowedDeviationTheta = map.NodeAllowedDeviationThetaDefault,
|
||||
Actions = "[]",
|
||||
};
|
||||
}
|
||||
|
||||
public static EdgeDto CreateEdgeDto(Edge edge, Node startNode, Node endNode)
|
||||
{
|
||||
return new EdgeDto()
|
||||
{
|
||||
Id = edge.Id,
|
||||
MapId = edge.MapId,
|
||||
StartNodeId = edge.StartNodeId,
|
||||
EndNodeId = edge.EndNodeId,
|
||||
TrajectoryDegree = edge.TrajectoryDegree,
|
||||
ControlPoint1X = edge.ControlPoint1X,
|
||||
ControlPoint1Y = edge.ControlPoint1Y,
|
||||
ControlPoint2X = edge.ControlPoint2X,
|
||||
ControlPoint2Y = edge.ControlPoint2Y,
|
||||
DirectionAllowed = edge.DirectionAllowed,
|
||||
RotationAllowed = edge.RotationAllowed,
|
||||
MaxSpeed = edge.MaxSpeed,
|
||||
MaxRotationSpeed = edge.MaxRotationSpeed,
|
||||
MaxHeight = edge.MaxHeight,
|
||||
MinHeight = edge.MinHeight,
|
||||
Actions = edge.Actions,
|
||||
AllowedDeviationXy = edge.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = edge.AllowedDeviationTheta,
|
||||
StartNode = new NodeDto()
|
||||
{
|
||||
Id = startNode.Id,
|
||||
Name = startNode.Name,
|
||||
MapId = startNode.MapId,
|
||||
Theta = startNode.Theta,
|
||||
X = startNode.X,
|
||||
Y = startNode.Y,
|
||||
Actions = startNode.Actions,
|
||||
AllowedDeviationXy = startNode.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = startNode.AllowedDeviationTheta,
|
||||
},
|
||||
EndNode = new NodeDto()
|
||||
{
|
||||
Id = endNode.Id,
|
||||
Name = endNode.Name,
|
||||
MapId = endNode.MapId,
|
||||
Theta = endNode.Theta,
|
||||
X = endNode.X,
|
||||
Y = endNode.Y,
|
||||
AllowedDeviationXy = endNode.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = endNode.AllowedDeviationTheta,
|
||||
Actions = endNode.Actions,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public static NodeDto CreateNodeDto(Node node)
|
||||
{
|
||||
return new NodeDto()
|
||||
{
|
||||
Id = node.Id,
|
||||
Name = node.Name,
|
||||
MapId = node.MapId,
|
||||
Theta = node.Theta,
|
||||
X = node.X,
|
||||
Y = node.Y,
|
||||
AllowedDeviationXy = node.AllowedDeviationXy,
|
||||
AllowedDeviationTheta = node.AllowedDeviationTheta,
|
||||
Actions = node.Actions,
|
||||
};
|
||||
}
|
||||
|
||||
public static Edge? GetClosesEdge(double x, double y, IEnumerable<Node> nodes, IEnumerable<Edge> edges, double allowDistance)
|
||||
{
|
||||
double minDistance = double.MaxValue;
|
||||
Edge? edgeResult = null;
|
||||
foreach (var edge in edges)
|
||||
{
|
||||
if (edge is not null)
|
||||
{
|
||||
var startNode = nodes.FirstOrDefault(n => n.Id == edge.StartNodeId);
|
||||
var endNode = nodes.FirstOrDefault(n => n.Id == edge.EndNodeId);
|
||||
if (startNode is null || endNode is null) continue;
|
||||
var distance = DistanceToSegment(x, y, startNode.X, startNode.Y, endNode.X, endNode.Y);
|
||||
if (distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
edgeResult = edge;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (minDistance > allowDistance) return null;
|
||||
return edgeResult;
|
||||
}
|
||||
|
||||
private static double DistanceToSegment(double x, double y, double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
|
||||
double segmentLengthSquared = dx * dx + dy * dy;
|
||||
|
||||
double t;
|
||||
if (segmentLengthSquared == 0)
|
||||
{
|
||||
t = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
t = ((x - x1) * dx + (y - y1) * dy) / segmentLengthSquared;
|
||||
t = Math.Max(0, Math.Min(1, t));
|
||||
}
|
||||
|
||||
double nearestX = x1 + t * dx;
|
||||
double nearestY = y1 + t * dy;
|
||||
|
||||
double distanceSquared = (x - nearestX) * (x - nearestX) + (y - nearestY) * (y - nearestY);
|
||||
|
||||
return Math.Sqrt(distanceSquared);
|
||||
}
|
||||
}
|
||||
31
RobotNet.MapManager/appsettings.json
Normal file
31
RobotNet.MapManager/appsettings.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=172.20.235.170;Database=RobotNet.MapEditor;User Id=sa;Password=robotics@2022;TrustServerCertificate=True;MultipleActiveResultSets=true"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"System.Net.Http.HttpClient": "Warning",
|
||||
"OpenIddict.Validation.OpenIddictValidationDispatcher": "Warning",
|
||||
"Microsoft.EntityFrameworkCore.Database": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"MinIO": {
|
||||
"UsingLocal": false,
|
||||
"Endpoint": "172.20.235.170:9000",
|
||||
"Bucket": "mapeditor",
|
||||
"User": "minio",
|
||||
"Password": "robotics"
|
||||
},
|
||||
"OpenIddictClientProviderOptions": {
|
||||
"Issuer": "https://localhost:7061/",
|
||||
"Audiences": [
|
||||
"robotnet-map-manager"
|
||||
],
|
||||
"ClientId": "robotnet-map-manager",
|
||||
"ClientSecret": "72B36E68-2F2B-455B-858A-77B1DCC79979",
|
||||
"Scopes": [ ]
|
||||
}
|
||||
}
|
||||
24
RobotNet.MapManager/nlog.config
Normal file
24
RobotNet.MapManager/nlog.config
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
autoReload="true">
|
||||
|
||||
<extensions>
|
||||
<add assembly="NLog.Web.AspNetCore"/>
|
||||
</extensions>
|
||||
|
||||
<targets>
|
||||
<target xsi:type="File" name="mapManagerLogFile" fileName="${basedir}/mapManagerlogs/${shortdate}.log" maxArchiveFiles="90" archiveEvery="Day" >
|
||||
<layout type='JsonLayout'>
|
||||
<attribute name='time' layout='${date:format=HH\:mm\:ss.ffff}' />
|
||||
<attribute name='level' layout='${level:upperCase=true}'/>
|
||||
<attribute name='logger' layout='${logger}' />
|
||||
<attribute name='message' layout='${message}' />
|
||||
<attribute name='exception' layout='${exception:format=tostring}' />
|
||||
</layout>
|
||||
</target>
|
||||
</targets>
|
||||
<rules>
|
||||
<logger name="RobotNet.MapManager.*" minlevel="Debug" writeto="mapManagerLogFile" />
|
||||
</rules>
|
||||
</nlog>
|
||||
Reference in New Issue
Block a user