You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1629 lines
73 KiB

using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DataValidation;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Znyc.Dispatching.Application.Services;
using Znyc.Dispatching.Common.Extensions;
using Znyc.Dispatching.Core;
using Znyc.Dispatching.Core.Entitys;
using Znyc.Dispatching.Core.Extension;
using Znyc.Dispatching.Core.Helpers;
using Znyc.Dispatching.MongoDb.Repository.Collection;
using Znyc.Dispatching.MongoDb.Repository.Repositorys;
namespace Znyc.Dispatching.Application
{
/// <summary>
/// 车辆信息服务
/// </summary>
[ApiDescriptionSettings(Name = "vehicle", Order = 146)]
public class VehicleService : IVehicleService, IDynamicApiController, ITransient
{
private string[] INDEX_STRINGS = {"A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z", "#"};
private readonly ICacheService _cacheService;
private readonly IRepository<Employee> _employeeRepository;
private readonly IGpsRealTimeRepository _gpsRealTimeRepository;
private readonly IMongodbBaseRepository _mongodbBaseRepository;
private readonly IPgyAlertStraightDtlRepository _pgyAlertStraightGtlRepository;
private readonly IRepository<Vehicle> _repository;
private readonly IUserManager _userManager;
private readonly IRepository<User> _userRepository;
private readonly IDictionaryService _dictionaryService;
private readonly ILogger<VehicleService> _logger;
private readonly IRepository<VehiclePerson> _vehiclePersonRepository;
private readonly IRepository<Order> _orderRepository;
private readonly IRepository<Oil> _oilRepository;
public VehicleService(
IRepository<Vehicle> repository,
IGpsRealTimeRepository gpsRealTimeRepository,
IRepository<Employee> employeeRepository,
IRepository<User> userRepository,
IPgyAlertStraightDtlRepository pgyAlertStraightGtlRepository,
ICacheService cacheService,
IUserManager userManager,
IDictionaryService dictionaryService,
IMongodbBaseRepository mongodbBaseRepository,
IRepository<VehiclePerson> vehiclePersonRepository,
IRepository<Order> orderRepository,
IRepository<Oil> oilRepository,
ILogger<VehicleService> logger)
{
_repository = repository;
_userManager = userManager;
_gpsRealTimeRepository = gpsRealTimeRepository;
_employeeRepository = employeeRepository;
_userRepository = userRepository;
_pgyAlertStraightGtlRepository = pgyAlertStraightGtlRepository;
_cacheService = cacheService;
_mongodbBaseRepository = mongodbBaseRepository;
_dictionaryService = dictionaryService;
_logger = logger;
_vehiclePersonRepository = vehiclePersonRepository;
_orderRepository = orderRepository;
_oilRepository = oilRepository;
}
/// <summary>
/// 初始化车辆
/// </summary>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
[Route("api/v1/InitVehicle")]
public async Task InitVehicle()
{
var vehicles = _repository.DetachedEntities.AsQueryable().ToList();
vehicles.ForEach( x =>
{
_cacheService.GetVehicleAsync(x.Id);
});
}
/// <summary>
/// 根据id获取车辆Gps信息
/// </summary>
/// <param name="vehicleId"></param>
/// <returns></returns>
[HttpGet]
[Route("api/v1/vehicle/gps/{vehicleId}")]
public async Task<VehicleGpsOutput> GetVehicleGpsByIdAsync(long vehicleId)
{
//车辆
Vehicle vehicle = await _cacheService.GetVehicleAsync(vehicleId);
//公司
CompanyOutput company = await _cacheService.GetCompanyAsync(_userManager.CompanyId, _userManager.UserId);
//gps数据
GpsRealTime gpsRealTime = await _gpsRealTimeRepository.GetGpsRealTimeByVehicleId(vehicleId);
if (gpsRealTime.IsNotNull())
{
var Timeres = TimeHelper.ExecDateDiff(gpsRealTime.GpsTime.AddHours(8), DateTime.Now);
if (Timeres > 15)
{
gpsRealTime.GpsState = 0;
gpsRealTime.Acc = 0;
gpsRealTime.Work = 0;
gpsRealTime.GpsMode = 2;
gpsRealTime.Useing = 1;
}
}
VehicleGpsOutput vehicleGpsOutput = new VehicleGpsOutput
{
Id = vehicle.Id,
CompanyId = vehicle.CompanyId,
ContactPerson = vehicle.ContactPerson,
ContactPhone = vehicle.ContactPhone,
VehicleCode = vehicle.VehicleCode,
VehiclePlate = vehicle.VehiclePlate,
Acc = gpsRealTime?.Acc ?? 0,
Work = gpsRealTime?.Work ?? 0,
Status = vehicle.Status,
ImeiNo = vehicle.ImeiNo,
Speed = gpsRealTime?.Speed ?? 0,
TerminalType = (int)vehicle.TerminalType,
OpenTime = vehicle.OpenTime,
Direct = gpsRealTime?.Direct ?? 0,
ExpireTime = vehicle.ExpireTime,
AccDurationTime = gpsRealTime?.AccDurationTime ?? "0分钟",
IsOverspeedAlarm = vehicle.IsOverspeedAlarm,
IsOveroffAlarm = vehicle.IsOveroffAlarm,
GpsTime = gpsRealTime?.GpsTime.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss") ?? "未激活",
Address = gpsRealTime?.Address ?? "暂无位置",
Overspeed = vehicle.Overspeed,
IsOverstopAlarm = vehicle.IsOverstopAlarm,
Overstop = vehicle.Overstop,
GpsMode = gpsRealTime?.GpsMode ?? 2,
GpsAlert = gpsRealTime.IsNull() ? 1 : gpsRealTime.GpsAlert,
Useing = gpsRealTime.IsNull() ? 1 : gpsRealTime.Useing,
GpsState = gpsRealTime.IsNull() ? 0 : gpsRealTime.GpsState,
WorkDurationTime = gpsRealTime?.WorkDurationTime ?? "0分钟",
DurationTime = gpsRealTime?.DurationTime ?? "0分钟",
RecTime = gpsRealTime?.RecTime.AddHours(8).ToString("yyyy-MM-dd HH:mm-ss") ?? "未激活",
OfflineTime = gpsRealTime.IsNull() ||
gpsRealTime?.RecTime < Convert.ToDateTime("2000-01-01 00:00:00.000")
? "未激活"
: StringHelper.ShowTimeInterval(gpsRealTime?.RecTime.AddHours(8)),
GpsSignalSource = "卫星",
TerminalTypeName =
typeof(TerminalTypeEnum).GetDescription((int)TerminalTypeEnum.BSJKGM_08) ?? "未知设备型号",
Latitude = gpsRealTime.IsNull() ? company.Latitude : gpsRealTime.Latitude,
Longitude = gpsRealTime.IsNull() ? company.Longitude : gpsRealTime.Longitude
};
return vehicleGpsOutput;
}
/// <summary>
/// 获取地图信息
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("api/v1/maps")]
public async Task<List<MapMonitorDataOutput>> GetMapMonitorAsync()
{
List<VehicleGpsOutput> vehicleGpsOutput = new List<VehicleGpsOutput>();
List<GpsRealTime> gpsRealTimels = new List<GpsRealTime>();
//车辆缓存
vehicleGpsOutput = (await _cacheService.GetVehicleByCompanyIdAsync(_userManager.CompanyId)) .Where(x => x.IsActivate && x.IsGps && x.Status == 1).ToList();
//
gpsRealTimels = await _gpsRealTimeRepository.GetGpsRealTimeByCompanyId(_userManager.CompanyId);
//公司
var company = await _cacheService.GetCompanyAsync(_userManager.CompanyId, _userManager.UserId);
//返回地图数据
var mapMonitorList = new List<MapMonitorDataOutput>();
foreach (VehicleGpsOutput vehicle in vehicleGpsOutput)
{
var mapMonitorDataOutput = new MapMonitorDataOutput
{
Id = vehicle.Id,
VehiclePlate = vehicle.VehiclePlate,
VehicleCode = vehicle.VehicleCode,
ContactPerson = vehicle.ContactPerson,
ContactPhone = vehicle.ContactPhone,
Status = vehicle.Status,
SimNo = vehicle.SimNo,
CompanyId = vehicle.CompanyId,
ImeiNo = vehicle.ImeiNo,
OpenTime = vehicle.OpenTime,
ExpireTime = vehicle.ExpireTime,
TerminalTypeName =
typeof(TerminalTypeEnum).GetDescription((int)TerminalTypeEnum.BSJKGM_08) ?? "未知设备型号"
};
var gpsRealTime = gpsRealTimels.FirstOrDefault(x => x.VehicleId == vehicle.Id);
if (gpsRealTime.IsNotNull())
{
var Timeres = TimeHelper.ExecDateDiff(gpsRealTime.GpsTime.AddHours(8), DateTime.Now);
if (Timeres > 15)
{
gpsRealTime.GpsState = 0;
gpsRealTime.Acc = 0;
gpsRealTime.Work = 0;
gpsRealTime.GpsMode = 2;
gpsRealTime.Useing = 1;
}
mapMonitorDataOutput.Longitude = gpsRealTime.Longitude;
mapMonitorDataOutput.Latitude = gpsRealTime.Latitude;
if (gpsRealTime?.GpsState != 2 && gpsRealTime?.GpsState != 0&& gpsRealTime?.GpsState != 1)
{
gpsRealTime.GpsState = 2;
}
mapMonitorDataOutput.GpsTime = gpsRealTime?.GpsTime.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss") ?? "未激活";
mapMonitorDataOutput.RecTime = gpsRealTime?.RecTime.AddHours(8).ToString("yyyy-MM-dd HH:mm-ss") ?? "未激活";
mapMonitorDataOutput.Direct = gpsRealTime?.Direct ?? 0;
mapMonitorDataOutput.DurationTime = gpsRealTime?.DurationTime ?? "0分钟";
mapMonitorDataOutput.Acc = gpsRealTime?.Acc ?? 0;
mapMonitorDataOutput.Speed = gpsRealTime?.Speed ?? 0;
mapMonitorDataOutput.GpsState = gpsRealTime?.GpsState ?? 0;
mapMonitorDataOutput.AccDurationTime = gpsRealTime?.AccDurationTime ?? "0分钟";
mapMonitorDataOutput.Address = gpsRealTime.IsNull() || gpsRealTime.Address.IsNull() ? "暂无位置" : gpsRealTime?.Address;
mapMonitorDataOutput.Work = gpsRealTime?.Work ?? 0;
mapMonitorDataOutput.WorkDurationTime = gpsRealTime?.WorkDurationTime ?? "0分钟";
mapMonitorDataOutput.OfflineTime = gpsRealTime.IsNull() ||
gpsRealTime?.RecTime < Convert.ToDateTime("2000-01-01 00:00:00.000")
? "未激活"
: StringHelper.ShowTimeInterval(gpsRealTime?.RecTime.AddHours(8));
mapMonitorDataOutput.GpsSignalSource = "卫星";
mapMonitorDataOutput.GpsMode = gpsRealTime.GpsMode;
mapMonitorDataOutput.GpsAlert = gpsRealTime.GpsAlert;
mapMonitorDataOutput.Useing = gpsRealTime.Useing;
};
mapMonitorList.Add(mapMonitorDataOutput);
}
return mapMonitorList;
}
/// <summary>.
/// 分页查询
/// </summary>
/// <param name="key"></param>
/// <param name="status">0全部,1任务中,2空闲,3停用</param>
/// <param name="currentPage"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
[HttpGet]
[Route("api/v1/vehicles/search")]
public async Task<VehicleListOutput> PageAsync([Required] int status = -1, [Required] int currentPage = 1,
[Required] int pageSize = 10, [FromQuery] string key = null)
{
List<VehicleGpsOutput> vehicles = new List<VehicleGpsOutput>();
//车辆
vehicles = (await _cacheService.GetVehicleByCompanyIdAsync(_userManager.CompanyId))
.Where(x => x.IsActivate && x.IsGps && x.Status == 1).ToList();
//gps车辆数据
List<GpsRealTime> gpsRealTimes = await _gpsRealTimeRepository.GetGpsRealTimeByCompanyId(_userManager.CompanyId);
List<VehicleGpsOutput> vehicleGpsOutputsList = new List<VehicleGpsOutput>();
foreach (VehicleGpsOutput vehicle in vehicles)
{
GpsRealTime gpsRealTime = gpsRealTimes.FirstOrDefault(x => x.VehicleId == vehicle.Id);
if (gpsRealTime.IsNotNull())
{
var Timeres = TimeHelper.ExecDateDiff(gpsRealTime.GpsTime.AddHours(8), DateTime.Now);
if (Timeres > 15)
{
gpsRealTime.GpsState = 0;
gpsRealTime.Acc = 0;
gpsRealTime.Work = 0;
gpsRealTime.GpsMode = 2;
gpsRealTime.Useing = 1;
}
}
VehicleGpsOutput vehicleGpsOutput = new VehicleGpsOutput
{
Id = vehicle.Id,
VehiclePlate = vehicle.VehiclePlate,
VehicleCode = vehicle.VehicleCode,
Status = vehicle.Status,
CompanyId = vehicle.CompanyId,
Speed = gpsRealTime?.Speed ?? 0,
GpsState = gpsRealTime?.GpsState ?? 0,
AccDurationTime = gpsRealTime?.AccDurationTime ?? "0分钟",
DurationTime = gpsRealTime?.DurationTime ?? "0分钟",
OfflineTime =
gpsRealTime.IsNull() || gpsRealTime?.RecTime < Convert.ToDateTime("2000-01-01 00:00:00.000")
? "未激活"
: StringHelper.ShowTimeInterval(gpsRealTime?.RecTime.AddHours(8)),
GpsTime = gpsRealTime.IsNull() ||
gpsRealTime?.GpsTime < Convert.ToDateTime("2000-01-01 00:00:00.000")
? "2000-01-01 00:00:00.000"
: gpsRealTime?.GpsTime.ToString("yyyy-MM-dd HH:mm-ss"),
ContactPerson = vehicle.ContactPerson,
ContactPhone = vehicle.ContactPhone,
Address = gpsRealTime.IsNull() || gpsRealTime.Address.IsNull() ? "暂无位置" : gpsRealTime?.Address,
};
vehicleGpsOutputsList.Add(vehicleGpsOutput);
}
int allCount = vehicleGpsOutputsList.Count;
int stillCount = vehicleGpsOutputsList.Count(x => x.GpsState == (int)GpsStatusEnum.STILL);
int drivingCount = vehicleGpsOutputsList.Count(x => x.GpsState == (int)GpsStatusEnum.DRIVING);
int offlineCount = vehicleGpsOutputsList.Count(x => x.GpsState == (int)GpsStatusEnum.OFFLINE);
VehicleListOutput result = new VehicleListOutput
{
vehicleGpsOutput = vehicleGpsOutputsList
.WhereIf(status > -1, x => x.GpsState == status)
.WhereIf(key.IsNotEmptyOrNull(), x => x.VehicleCode.Contains(key))
.OrderBy(x => x.VehicleCode)
.Skip((currentPage - 1) * pageSize)
.Take(pageSize)
.ToList(),
AllCount = allCount,
StillCount = stillCount,
DrivingCount = drivingCount,
OfflineCount = offlineCount
};
return result;
}
/// <summary>
/// 修改车辆信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPut]
[Route("api/v1/vehicle")]
public async Task UpdateAsync(VehicleUpdateInput input)
{
await _repository.UpdateIncludeNowAsync(input.Adapt<Vehicle>(),
new[]
{
nameof(Vehicle.VehicleCode), nameof(Vehicle.VehiclePlate), nameof(Vehicle.ContactPerson),
nameof(Vehicle.ContactPhone)
},
true);
//同步修改油耗表设备号
await "update dc_oil set VehicleCode=@vehicleCode where VehicleId=@id And IsDeleted=0".SqlNonQueryAsync(new { id = input.Id, vehicleCode = input.VehicleCode });
//同步修改订单表设备号
await "update dc_order set VehicleCode=@vehicleCode where VehicleId=@id And IsDeleted=0".SqlNonQueryAsync(new { id = input.Id, vehicleCode = input.VehicleCode });
await _cacheService.RemoveVehicleAsync(input.Id);
await _cacheService.RemoveVehicleByCompanyIdAsync(_userManager.CompanyId);
}
/// <summary>
/// 轨迹回放纠偏
/// </summary>
/// <param name="vehicleId"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <returns></returns>
[HttpGet]
[Route("api/v1/trackplayback")]
public async Task<TrackPlaybackListOutput> TrackPlaybackCorrectionAsync(long vehicleId, DateTime startTime,
DateTime endTime)
{
//查询Cache
TrackPlaybackListOutput trackPlaybackListOutput = await _cacheService.GetTrackPlaybackAsync(vehicleId, startTime, endTime);
if (trackPlaybackListOutput.IsNull())
{
//返回轨迹实体
List<TrackPlaybackOutput> reult = new List<TrackPlaybackOutput>();
//公司数据
CompanyOutput company = await _cacheService.GetCompanyAsync(_userManager.CompanyId, _userManager.UserId);
//车辆
Vehicle vehicle = await _cacheService.GetVehicleAsync(vehicleId);
List<VehicleGps> list = await FindGpsByTime(vehicleId, startTime, endTime);
//停留标示数据
int stopTag = (await _dictionaryService.GetAsync(company.StopTag)).Value.ToInt();
//车辆行驶记录
Console.WriteLine("处理前"+list.Count);
//过滤数据
List<VehicleGps> finalGpsList = GpsDataProcessing(list); //处理数据
//纠偏后数据
List<VehicleGps> newFinalGpsList = new List<VehicleGps>(); //处理数据
List<Stop> stopList = new List<Stop>();
TimeSpan stopTimeSpan = new TimeSpan();
if (finalGpsList.Count < 2)
{
Console.WriteLine("处理后"+finalGpsList.Count);
throw Oops.Oh("暂无轨迹,或轨迹点太少");
}
int firstGpsTime = finalGpsList[0].GpsTime.ToTimestamp();
List<TrackPlayBackCorrectInput> rectifyList = finalGpsList.Where(x=>x.Latitude.ToString().Length>14).Select(x => new TrackPlayBackCorrectInput
{
Longitude = x.Longitude.ToString("f6").ToDecimal(),
Latitude = x.Latitude.ToString("f6").ToDecimal(),
Direct = x.Direct,
Timestamp = x.GpsTime.ToTimestamp() > firstGpsTime ? x.GpsTime.ToTimestamp() - firstGpsTime : firstGpsTime,
Speed = x.Speed
}).ToList();
string c = JsonConvert.SerializeObject(rectifyList);
List<Points> rectifyOutput = new List<Points>();
int size = 500; //接口限制
//原始轨迹点
int reultCount = finalGpsList.Count;
int integerCount = (int)Math.Ceiling((decimal)reultCount / size);
for (int i = 0; i < integerCount; i++)
{
//TrackPlayBackCorrectOutput res = JsonConvert.DeserializeObject<TrackPlayBackCorrectOutput>(HttpRequestHelper.HttpPost("https://restapi.amap.com/v4/grasproad/driving?key=89981abaf32ae94b09a639c54845e089",
//rectifyList.Skip(i * size).Take(size)));
//if (res.ErrCode == 0)
//{
// rectifyOutput.AddRange(res.data.points.ToList());
//}
//else
//{
List<Points> residuePoints = rectifyList.Skip(i * size).Select(x => new Points
{
Latitude = x.Latitude,
Longitude = x.Longitude
}).ToList();
rectifyOutput.AddRange(residuePoints);
//}
}
decimal totalDistance = 0;//总里程
int totalPoints = rectifyOutput.Count;//纠偏后的点总数
float index = (float)totalPoints / finalGpsList.Count;
int multiple = totalPoints % finalGpsList.Count == 0 ? totalPoints / finalGpsList.Count : totalPoints / finalGpsList.Count + 1;
for (int i = 0; i < rectifyOutput.Count; i++)
{
TrackPlaybackOutput output = new TrackPlaybackOutput();
int k = (int)Math.Round(i / index);
if (k >= finalGpsList.Count)
{
k = finalGpsList.Count - 1;
}
VehicleGps gps = finalGpsList[k];
gps.Longitude = rectifyOutput[i].Longitude;
gps.Latitude = rectifyOutput[i].Latitude;
gps.Speed = gps.Speed == 0 ? 21 : gps.Speed;
newFinalGpsList.Add(gps);
}
#region 计算停留点
int stopIdx = 0;
VehicleGps firstGps = new VehicleGps();
newFinalGpsList = newFinalGpsList.Distinct().ToList();
for (int i = 0; i < newFinalGpsList.Count; i++)
{
TrackPlaybackOutput output = new TrackPlaybackOutput();
VehicleGps gps = newFinalGpsList[i];
//Console.WriteLine("第一时间"+gps.GpsTime);
output.Longitude = gps.Longitude;
output.Latitude = gps.Latitude;
output.GpsTime = gps.GpsTime.AddHours(8);
output.StartTime = gps.GpsTime.AddHours(8);
output.EndTime = gps.GpsTime.AddHours(8);
output.Speed = gps.Speed;
output.Direct = gps.Direct;
output.DurationTime = "";
output.IsStopPoint = false;
output.StopPointIdx = -1;
output.Address = gps.Address;
output.Acc = gps.Acc;
output.AccDurationTime = "";
output.Work = gps.Work;
output.WorkDurationTime = "";
output.TotalDistance = 0;
//Console.WriteLine("第二时间"+output.GpsTime.ToString());
//获取起点
if (i == 0 )
{
firstGps = newFinalGpsList[0];
string address = firstGps.Address;
Stop stop = new Stop
{
Latitude = firstGps.Latitude,
Longitude = firstGps.Longitude,
GpsTime = firstGps.GpsTime.AddHours(8),
Address = address,
State = "起点",
Status = 0,
Behavior = "",
TotalDistance = 0
};
stopList.Add(stop);
output.Address = address;
continue;
}
if (newFinalGpsList.Count == 1)
{
firstGps = newFinalGpsList[0];
string address = firstGps.Address;
Stop stop = new Stop();
stop.Latitude = firstGps.Latitude;
stop.Longitude = firstGps.Longitude;
stop.GpsTime = endTime;
stop.Address = address;
stop.State = "终点";
stop.Status = 3;
stop.Behavior = "";
stop.TotalDistance = 0;
stopList.Add(stop);
continue;
}
VehicleGps preGps = newFinalGpsList[i - 1];
totalDistance += DistanceHelper.GetDistance(Convert.ToDouble(gps.Latitude),
Convert.ToDouble(gps.Longitude),
Convert.ToDouble(preGps.Latitude), Convert.ToDouble(preGps.Longitude));
output.TotalDistance = totalDistance;
//用于计算停留点
var time = gps.GpsTime.ConvertToTimestamp() - preGps.GpsTime.ConvertToTimestamp();
if (reult.Count >1 && time > stopTag && (gps.Speed != 21 && gps.Speed > 5 || preGps.Speed != 21 && preGps.Speed > 5) )
{
Console.WriteLine("停留点:时间{0},速度{1},{2}", time, preGps.Speed,gps.Speed);
string durationTime = TimeHelper.TimeSpanFormat(gps.GpsTime - preGps.GpsTime, 3);
if(reult.LastOrDefault().IsNull())
Console.WriteLine(reult.Count);
string address = MapHelper.GetLocationByLngLat(reult.LastOrDefault().Longitude,
reult.LastOrDefault().Latitude);
//停留点
reult.LastOrDefault().DurationTime = durationTime;
if (firstGps.GpsTime.ConvertToTimestamp() != preGps.GpsTime.ConvertToTimestamp())
{
reult.LastOrDefault().StopPointIdx = ++stopIdx;
}
reult.LastOrDefault().Address = address;
reult.LastOrDefault().StartTime = preGps.GpsTime.AddHours(8);
reult.LastOrDefault().EndTime = gps.GpsTime.AddHours(8);
stopTimeSpan += (gps.GpsTime - preGps.GpsTime);
//如果第一点是停留点,则将停留时间更新到第一个点上
if (firstGps.GpsTime == preGps.GpsTime)
{
stopList.LastOrDefault().Behavior = "停留" + durationTime;
}
else
{
reult.LastOrDefault().IsStopPoint = true;
//停留点插入轨迹动态列表
Stop stop = new Stop();
stop.GpsTime = preGps.GpsTime.AddHours(8);
stop.Latitude = preGps.Latitude;
stop.Longitude = preGps.Longitude;
stop.Address = address;
stop.State = "停" + stopIdx;
stop.Status = 1;
stop.Behavior = "停留" + durationTime;
stop.TotalDistance = totalDistance != 0 ? totalDistance : 0;
stop.StartTime = preGps.GpsTime;
stop.EndTime = output.GpsTime.AddHours(8);
stopList.Add(stop);
}
}
if (i == newFinalGpsList.Count - 1)
{
Stop stop = new Stop();
VehicleGps lastGps = newFinalGpsList[i];
string address = lastGps.Address;
output.Address = address;
stop.Latitude = lastGps.Latitude;
stop.Longitude = lastGps.Longitude;
stop.GpsTime = lastGps.GpsTime.AddHours(8);
stop.Address = lastGps.Address;
stop.State = "终点";
stop.Status = 3;
stop.Behavior = "";
stop.TotalDistance = totalDistance != 0 ? totalDistance : 0;
stopList.Add(stop);
}
reult.Add(output);
}
#endregion 计算停留点
trackPlaybackListOutput = new TrackPlaybackListOutput
{
VehicleCode = vehicle.VehicleCode,
VehiclePlate = vehicle.VehiclePlate,
TotalDistance = totalDistance != 0 ? totalDistance : 0,
TotalStopTime = TimeHelper.TimeSpanFormat(stopTimeSpan, 3),
trackPlaybackOutputs = reult,
Stops = stopList
};
//若查询时间包含今天,缓存录入10分钟
TimeSpan expire = DateTimeHelper.IsToday(endTime) ? expire = TimeSpan.FromMinutes(15) : TimeSpan.FromDays(7);
await _cacheService.SeTrackPlaybackAsync(trackPlaybackListOutput, vehicleId, startTime, endTime, expire);
}
return trackPlaybackListOutput;
}
/// <summary>
/// 修改超速报警/速度
/// </summary>
/// <param name="vehicleId"></param>
/// <param name="isOverspeedAlarm"></param>
/// <param name="overSpeed"></param>
/// <returns></returns>
[HttpPut]
[Route("api/v1/vehicle/overspeed/{vehicleId}/{isOverspeedAlarm}/{overSpeed}")]
public async Task<bool> UpdateOverSpeedAsync(long vehicleId, bool isOverspeedAlarm, [DataValidation(ValidationTypes.PositiveNumber, ErrorMessage = "超速报警时速必须为数字")] int overSpeed)
{
Vehicle vehicle = await _cacheService.GetVehicleAsync(vehicleId);
vehicle.Overspeed = overSpeed;
vehicle.IsOverspeedAlarm = isOverspeedAlarm;
await _repository.UpdateNowAsync(vehicle);
await _cacheService.SetVehicleAsync(vehicle);
await _cacheService.RemoveVehicleByCompanyIdAsync(_userManager.CompanyId);
return true;
}
/// <summary>
/// 修改停留报警
/// </summary>
/// <param name="vehicleId"></param>
/// <param name="isOverstopAlarm"></param>
/// <param name="overStop"></param>
/// <returns></returns>
[HttpPut]
[Route("api/v1/vehicle/overstop/{vehicleId}/{isOverstopAlarm}/{overStop}")]
public async Task<bool> UpdateOverStopAsync(long vehicleId, bool isOverstopAlarm, [DataValidation(ValidationTypes.PositiveNumber, ErrorMessage = "报警值必须为数字")] int overStop)
{
Vehicle vehicle = await _cacheService.GetVehicleAsync(vehicleId);
vehicle.Overstop = overStop;
vehicle.IsOverstopAlarm = isOverstopAlarm;
await _repository.UpdateIncludeNowAsync(vehicle,
new[] { nameof(Vehicle.IsOverstopAlarm), nameof(Vehicle.Overstop) }, true);
await _cacheService.SetVehicleAsync(vehicle);
await _cacheService.RemoveStopVehicleAsync();
await _cacheService.RemoveVehicleByCompanyIdAsync(_userManager.CompanyId);
return true;
}
/// <summary>
/// 设置车辆离线
/// </summary>
/// <returns></returns>
[HttpPut]
[Route("api/v1/vehicle/overoff/{vehicleId}/{IsOveroffAlarm}")]
public async Task<bool> VehicleOfflineAsync(long vehicleId, bool IsOveroffAlarm)
{
Vehicle vehicle = await _cacheService.GetVehicleAsync(vehicleId);
vehicle.IsOveroffAlarm = IsOveroffAlarm;
await _repository.UpdateIncludeNowAsync(vehicle,
new[] { nameof(Vehicle.IsOveroffAlarm)}, true);
await _cacheService.SetVehicleAsync(vehicle);
await _cacheService.RemoveVehicleByCompanyIdAsync(_userManager.CompanyId);
return true;
}
/// <summary>
/// 超速报警列表
/// </summary>
/// <param name="currentPage"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
[HttpGet]
[UnitOfWork]
[Route("api/v1/vehicles/alertspeeds/{currentPage}/{pageSize}")]
public async Task<PgyAlertStraightDtlListOutput> MbAlertSpeedByTime([Required] int currentPage = 1,
[Required] int pageSize = 10)
{
List<VehicleGpsOutput> vehicleList = await _cacheService.GetVehicleByCompanyIdAsync(_userManager.CompanyId);
if (vehicleList.IsNull() || vehicleList.Count() <= 0)
{
throw Oops.Oh("暂无超速记录");
}
List<PgyAlertStraightDtl> alarmList = await _pgyAlertStraightGtlRepository.FindAlarmPageAsync(_userManager.CompanyId, currentPage, pageSize);
List<PgyAlertStraightDtlOutput> list = alarmList
.Select(x => new PgyAlertStraightDtlOutput
{
VehicleId = vehicleList.Where(v => v.VehicleCode == x.VehicleCode && v.VehiclePlate == x.VehiclePlate).FirstOrDefault().Id,
CompanyId = x.CompanyId,
VehicleCode = x.VehicleCode,
VehiclePlate = x.VehiclePlate,
GpsTime = x.GpsTime.AddHours(8),
Latitude = x.Latitude,
Longitude = x.Longitude,
Direct = x.Direct,
Speed = x.Speed,
Address = x.Address
})
.ToList();
PgyAlertStraightDtlListOutput result = new PgyAlertStraightDtlListOutput()
{
TotalCount = (await _pgyAlertStraightGtlRepository.FindAlarmCountAsync(_userManager.CompanyId)).ToInt(),
List = list
};
await _cacheService.SetUnreadAlarmAsync(_userManager.UserId);
return result;
}
/// <summary>
/// 未读报警消息数
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("api/v1/unreadalarm")]
public async Task<AlarmOutput> UnreadAlarmCountAsync()
{
DateTime readTime = await _cacheService.GetUnreadAlarmAsync(_userManager.UserId);
if (readTime.IsNull() || readTime == Convert.ToDateTime("0001-01-01 00:00:00.000"))
{
readTime = DateTime.Now.Date;
}
IQueryable<Vehicle> vehicleList = _repository.DetachedEntities
.Where(x => x.IsOverspeedAlarm == true && x.CompanyId == _userManager.CompanyId
&& x.Status == (int)CommonStatusEnum.ENABLE);
AlarmOutput result = new AlarmOutput();
if (vehicleList.IsNull() || !vehicleList.Any())
{
return result;
}
List<PgyAlertStraightDtl> alarmList = await _pgyAlertStraightGtlRepository.FindAlarmListByTime(_userManager.CompanyId);
if (alarmList.IsNull())
{
return result;
}
alarmList = alarmList.OrderByDescending(x => x.GpsTime).ToList();
result.OverspeedCount = alarmList.Count(x => x.GpsTime > readTime);
result.OverspeedTime = alarmList.FirstOrDefault()?.GpsTime.AddHours(8);
result.VehicleCode = alarmList.FirstOrDefault()?.VehicleCode;
result.VehiclePlate = alarmList.FirstOrDefault()?.VehiclePlate;
return result;
}
/// <summary>
/// 获取车辆GPS信息
/// </summary>
/// <param name="vehicleId">车辆Id</param>
/// <param name="startTime">开始时间</param>
/// <param name="endTime">结束时间</param>
/// <returns></returns>
private async Task<List<VehicleGps>> FindGpsByTime(long vehicleId, DateTime startTime, DateTime endTime)
{
//startTime = startTime.AddHours(-8);
//endTime = endTime.AddHours(-8);
string smon = startTime.ToString("MM");
string emon = endTime.ToString("MM");
string syear = startTime.ToString("yyyyMM");
string eyear = endTime.ToString("yyyyMM");
List<VehicleGps> list = new List<VehicleGps>();
if (smon == emon)
{
FilterDefinition<VehicleGps> filter = Builders<VehicleGps>.Filter.Gte("GpsTime", startTime) &
Builders<VehicleGps>.Filter.Lt("GpsTime", endTime) &
Builders<VehicleGps>.Filter.Eq("Acc", 1);
string tbName = "Car_" + vehicleId + "_" + syear;
list = await _mongodbBaseRepository.GetVehicleGpsListAsync(tbName, filter);
}
else
{
//取开始时间到次月第一天
DateTime etimeone = DateTime.Parse(startTime.AddMonths(1).ToString("yyyy-MM-01")); //次月第一天
FilterDefinition<VehicleGps> filter1 = Builders<VehicleGps>.Filter.Gt("GpsTime", startTime) &
Builders<VehicleGps>.Filter.Lte("GpsTime", etimeone) &
Builders<VehicleGps>.Filter.Eq("Acc", 1);
string tbName1 = "Car_" + vehicleId + "_" + syear;
List<VehicleGps> list1 = await _mongodbBaseRepository.GetVehicleGpsListAsync(tbName1, filter1);
//取结束时间月份第一天到结束时间
DateTime etimetwo = DateTime.Parse(endTime.ToString("yyyy-MM-01")); //结束月份第一天
FilterDefinition<VehicleGps> filter2 = Builders<VehicleGps>.Filter.Gt("GpsTime", etimetwo) &
Builders<VehicleGps>.Filter.Lte("GpsTime", endTime) &
Builders<VehicleGps>.Filter.Eq("Acc", 1);
string tbName2 = "Car_" + vehicleId + "_" + eyear;
List<VehicleGps> list2 = await _mongodbBaseRepository.GetVehicleGpsListAsync(tbName2, filter2);
list.AddRange(list1);
list.AddRange(list2);
}
return list.Count > 0 ? list : new List<VehicleGps>();
}
/// <summary>
/// 轨迹点预处理(车辆)
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
private List<VehicleGps> GpsDataProcessing(List<VehicleGps> list, int Mub = 20)
{
List<VehicleGps> carGpsList = new List<VehicleGps>();
int moveDistance = 50;
//轨迹点数小于10个, 则提示暂无轨迹
if (list.Count < Mub)
{
return new List<VehicleGps>();
}
//判断前五个点是否正常
for (int i = 0; i < 5; i++)
{
List<VehicleGps> firstToTenGps = new List<VehicleGps>();
for (int j = 0; j < 10 - i; j++)
{
VehicleGps model = list[j];
firstToTenGps.Add(model);
}
if (!firstToTenGps.Any())
{
continue;
}
{
//平均经纬度
double avgLat = Convert.ToDouble(firstToTenGps.Average(x => x.Latitude));
double avgLng = Convert.ToDouble(firstToTenGps.Average(x => x.Longitude));
//所有点距离
List<double> distanceList =
firstToTenGps.Select(
model =>
Convert.ToDouble(DistanceHelper.GetDistance(avgLat, avgLng,
Convert.ToDouble(model.Latitude),
Convert.ToDouble(model.Longitude))) * 1000).ToList();
//找出最大值的位置
double max = distanceList.Max();
int maxIndex = distanceList.IndexOf(max);
//最大值是否是第一个点, 以及距离大于625米, 150 km/h 乘 15秒
if (maxIndex == 0 && max > 400)
{
list.Remove(list.FirstOrDefault());
}
else
{
break;
}
}
}
//去掉太远的点
VehicleGps preGps = null;
foreach (VehicleGps model in list)
{
if (preGps != null)
{
decimal distance = DistanceHelper.GetDistance((double)preGps.Latitude, (double)preGps.Longitude,
(double)model.Latitude, (double)model.Longitude) * 1000;
long ts = model.GpsTime.ConvertToTimestamp() - preGps.GpsTime.ConvertToTimestamp();
if (distance > 0 && distance < 50 * 100)
{
if (distance < (decimal)(120 / 3.6 * ts))
{
carGpsList.Add(model);
preGps = model;
}
}
}
else
{
carGpsList.Add(model);
preGps = model;
}
}
List<VehicleGps> finalGpsList = new List<VehicleGps>(); //处理完后的最终集合
//去掉距离太近的点, 去重
preGps = null;
foreach (VehicleGps gps in carGpsList)
{
if (preGps != null)
{
decimal distance = DistanceHelper.GetDistance((double)preGps.Latitude, (double)preGps.Longitude,
(double)gps.Latitude, (double)gps.Longitude) * 1000;
if (distance > moveDistance)
{
finalGpsList.Add(gps);
preGps = gps;
}
}
else
{
finalGpsList.Add(gps);
preGps = gps;
}
}
return carGpsList;
}
private decimal[] GetGpsLoacInfo(List<VehicleGps> finalGpsList, MapMonitorDataOutput mapMonitorDataOutput, GpsRealTime gpsRealTime)
{
List<decimal> carGpsList = new List<decimal>();
VehicleGps carGpsinfo = new VehicleGps();
if (finalGpsList.Count > 0)
{
//获取上一条状态
if (finalGpsList.Count == 1)
{
carGpsinfo = finalGpsList.Last();
}
else
{
carGpsinfo = finalGpsList[finalGpsList.Count - 2];
}
var start = gpsRealTime.Latitude + "%2C" + gpsRealTime.Longitude;
var end = carGpsinfo.Latitude + "%2C" + carGpsinfo.Longitude;
if (gpsRealTime.Speed != 0 && gpsRealTime.GpsState == 1) //运动状态
{
int j = 1;
bool isEnd = start == end;
while (isEnd && finalGpsList.Count > 2)
{
carGpsinfo = finalGpsList[finalGpsList.Count - (j + 2)];
end = carGpsinfo.Latitude + "%2C" + carGpsinfo.Longitude;
j++;
isEnd = start == end;
}
if (!isEnd)
{
gpsRealTime.Direct = gpsRealTime.Direct < 1 ? gpsRealTime.Direct + 2 : gpsRealTime.Direct - 1;
var gpsres = MapHelper.pointLatLngs(start, end, 10000, gpsRealTime.Direct);
if (gpsres.status != 0)
throw new Exception(String.Format("转换发生异常{0}", gpsres.message));
var coors = gpsres.result.routes[0].polyline;
if (coors.Length < 70)
{
for (var i = 2; i < coors.Length; i++)
{
var Y = (decimal)coors[i - 2];
var x = (decimal)coors[i];
coors[i] = (Y + x / 1000000);
}
carGpsList.Add((decimal)coors[coors.Length - 2]);
carGpsList.Add((decimal)coors[coors.Length - 1]);
Console.WriteLine("动态规划成功:" + gpsRealTime.VehiclePlate +
"规划前开始坐标:{0},规划前结束坐标:{1}。 规划后坐标:{2}", start, end, carGpsList[0] + "," + carGpsList[1]);
}
else
{
for (var i = 2; i < coors.Length; i++)
{
var Y = (decimal)coors[i - 2];
var x = (decimal)coors[i];
coors[i] = (Y + x / 1000000);
}
Console.WriteLine("规划过长,取反:{0}{1}", coors[7], coors[6]);
carGpsList.Add((decimal)coors[6]);
carGpsList.Add((decimal)coors[7]);
}
}
else
{
carGpsList.Add(gpsRealTime.Latitude);
carGpsList.Add(gpsRealTime.Longitude);
}
}
else //静止状态
{
if(gpsRealTime.Acc == 0)
{
carGpsList.Add(gpsRealTime.Latitude);
carGpsList.Add(gpsRealTime.Longitude);
}
else if (carGpsinfo.Speed > 0 && gpsRealTime.Acc == 1)
{
gpsRealTime.Direct = gpsRealTime.Direct < 1 ? gpsRealTime.Direct + 2 : gpsRealTime.Direct - 1;
var gpsres = MapHelper.pointLatLngs(start, end, 10000, gpsRealTime.Direct);
if (gpsres.status != 0)
throw new Exception(String.Format("转换发生异常{0},角度{1}", gpsres.message, gpsRealTime.Direct));
var coors = gpsres.result.routes[0].polyline;
if (coors.Length < 70)
{
for (var i = 2; i < coors.Length; i++)
{
var Y = (decimal)coors[i - 2];
var x = (decimal)coors[i];
coors[i] = (Y + x / 1000000);
}
carGpsList.Add((decimal)coors[coors.Length - 2]);
carGpsList.Add((decimal)coors[coors.Length - 1]);
Console.WriteLine("静态规划成功:" + gpsRealTime.VehiclePlate +
"规划前开始坐标:{0},规划前结束坐标:{1}。 规划后坐标:{2}", start, end, carGpsList[0] + "," + carGpsList[1]);
}
}
else
{
carGpsList.Add(gpsRealTime.Latitude);
carGpsList.Add(gpsRealTime.Longitude);
}
}
}
else
{
carGpsList.Add(gpsRealTime.Latitude);
carGpsList.Add(gpsRealTime.Longitude);
}
var add = MapHelper.geocoder(gpsRealTime.Latitude+","+gpsRealTime.Longitude, 10000);
if (add.status == 0)
gpsRealTime.Address = add.result.pois.Length > 0?add.result.pois[0].address: add.result.address;
Console.WriteLine("最终返回定位:{0}{1},地址:{2}。定位:{3}{4}",gpsRealTime.Longitude,gpsRealTime.Latitude, gpsRealTime.Address, gpsRealTime.Longitude, gpsRealTime.Latitude);
return carGpsList.ToArray();
}
/// <summary>
/// 动态轨迹点预处理(车辆)
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
private List<VehicleGps> GpsDataDynamic(List<VehicleGps> list, int Mub = 20)
{
List<VehicleGps> carGpsList = new List<VehicleGps>();
int moveDistance = 10;
//轨迹点数小于10个, 则提示暂无轨迹
if (list.Count < Mub)
{
return new List<VehicleGps>();
}
//判断前五个点是否正常
for (int i = 0; i < 5; i++)
{
List<VehicleGps> firstToTenGps = new List<VehicleGps>();
for (int j = 0; j < 10 - i; j++)
{
VehicleGps model = list[j];
firstToTenGps.Add(model);
}
if (!firstToTenGps.Any())
{
continue;
}
{
//平均经纬度
double avgLat = Convert.ToDouble(firstToTenGps.Average(x => x.Latitude));
double avgLng = Convert.ToDouble(firstToTenGps.Average(x => x.Longitude));
//所有点距离
List<double> distanceList =
firstToTenGps.Select(
model =>
Convert.ToDouble(DistanceHelper.GetDistance(avgLat, avgLng,
Convert.ToDouble(model.Latitude),
Convert.ToDouble(model.Longitude))) * 1000).ToList();
//找出最大值的位置
double max = distanceList.Max();
int maxIndex = distanceList.IndexOf(max);
//最大值是否是第一个点, 以及距离大于625米, 150 km/h 乘 15秒
if (maxIndex == 0 && max > 150)
{
list.Remove(list.FirstOrDefault());
}
else
{
break;
}
}
}
//去掉太远的点
VehicleGps preGps = null;
foreach (VehicleGps model in list)
{
if (preGps != null)
{
decimal distance = DistanceHelper.GetDistance((double)preGps.Latitude, (double)preGps.Longitude,
(double)model.Latitude, (double)model.Longitude) * 1000;
long ts = model.GpsTime.ConvertToTimestamp() - preGps.GpsTime.ConvertToTimestamp();
if (distance > 0 && distance < 5 * 100)
{
if (distance < (decimal)(120 / 3.6 * ts))
{
carGpsList.Add(model);
preGps = model;
}
}
}
else
{
carGpsList.Add(model);
preGps = model;
}
}
List<VehicleGps> finalGpsList = new List<VehicleGps>(); //处理完后的最终集合
//去掉距离太近的点, 去重
preGps = null;
foreach (VehicleGps gps in carGpsList)
{
if (preGps != null)
{
decimal distance = DistanceHelper.GetDistance((double)preGps.Latitude, (double)preGps.Longitude,
(double)gps.Latitude, (double)gps.Longitude) * 1000;
if (distance > moveDistance)
{
finalGpsList.Add(gps);
preGps = gps;
}
}
else
{
finalGpsList.Add(gps);
preGps = gps;
}
}
return carGpsList;
}
#region 轨迹
/// <summary>
/// 同步轨迹
/// </summary>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
public async Task SyncTrackPlaybackCorrectionAsync(DateTime startTime, DateTime endTime, string type)
{
List<Vehicle> vehicles = await _repository.Where(x => x.Status == (int)CommonStatusEnum.ENABLE && x.IsGps == true && x.IsActivate == true).ToListAsync();
foreach (Vehicle vehicle in vehicles)
{
await SetTrackPlaybackCorrectionAsync(vehicle.Id, vehicle.CompanyId, startTime, endTime, type);
}
}
/// <summary>
/// 轨迹回放纠偏
/// </summary>
/// <param name="vehicleId"></param>
/// <param name="companyId"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <param name="type"></param>
/// <returns></returns>
private async Task SetTrackPlaybackCorrectionAsync(long vehicleId, long companyId, DateTime startTime, DateTime endTime, string type)
{
//查询Cache
TrackPlaybackListOutput trackPlaybackListOutput = new TrackPlaybackListOutput();
//返回轨迹实体
List<TrackPlaybackOutput> reult = new List<TrackPlaybackOutput>();
//公司数据
CompanyOutput company = await _cacheService.GetCompanyAsync(companyId, _userManager.UserId);
//车辆
Vehicle vehicle = await _cacheService.GetVehicleAsync(vehicleId);
//停留标示数据
int stopTag = (await _dictionaryService.GetAsync(company.StopTag)).Value.ToInt();
//车辆行驶记录
List<VehicleGps> list = await FindGpsByTime(vehicleId, startTime, endTime);
//过滤数据
Console.WriteLine(startTime); Console.WriteLine(endTime);
List<VehicleGps> finalGpsList = GpsDataProcessing(list); //处理数据
//纠偏后数据
List<VehicleGps> newFinalGpsList = new List<VehicleGps>(); //处理数据
List<Stop> stopList = new List<Stop>();
TimeSpan stopTimeSpan = new TimeSpan();
if (finalGpsList.Count < 30)
{
return;
}
int firstGpsTime = finalGpsList[0].GpsTime.ToTimestamp();
List<TrackPlayBackCorrectInput> rectifyList = finalGpsList.Select(x => new TrackPlayBackCorrectInput
{
Longitude = x.Longitude.ToString("f6").ToDecimal(),
Latitude = x.Latitude.ToString("f6").ToDecimal(),
Direct = x.Direct,
Timestamp = x.GpsTime.ToTimestamp() > firstGpsTime ? x.GpsTime.ToTimestamp() - firstGpsTime : firstGpsTime,
Speed = x.Speed
}).ToList();
string c = JsonConvert.SerializeObject(rectifyList);
List<Points> rectifyOutput = new List<Points>();
int size = 500;
//原始轨迹点
int reultCount = finalGpsList.Count;
int integerCount = (int)Math.Ceiling((decimal)reultCount / size);
for (int i = 0; i < integerCount; i++)
{
TrackPlayBackCorrectOutput res = JsonConvert.DeserializeObject<TrackPlayBackCorrectOutput>(HttpRequestHelper.HttpPost("https://restapi.amap.com/v4/grasproad/driving?key=89981abaf32ae94b09a639c54845e089",
rectifyList.Skip(i * size).Take(size)));
if (res.ErrCode == 0)
{
rectifyOutput.AddRange(res.data.points.ToList());
}
else
{
List<Points> residuePoints = rectifyList.Skip(i * size).Select(x => new Points
{
Latitude = x.Latitude,
Longitude = x.Longitude
}).ToList();
rectifyOutput.AddRange(residuePoints);
}
}
decimal totalDistance = 0;//总里程
int totalPoints = rectifyOutput.Count;//纠偏后的点总数
float index = (float)totalPoints / finalGpsList.Count;
int multiple = totalPoints % finalGpsList.Count == 0 ? totalPoints / finalGpsList.Count : totalPoints / finalGpsList.Count + 1;
for (int i = 0; i < rectifyOutput.Count; i++)
{
TrackPlaybackOutput output = new TrackPlaybackOutput();
int k = (int)Math.Round(i / index);
if (k >= finalGpsList.Count)
{
k = finalGpsList.Count - 1;
}
VehicleGps gps = finalGpsList[k];
gps.Longitude = rectifyOutput[i].Longitude;
gps.Latitude = rectifyOutput[i].Latitude;
gps.Speed = gps.Speed == 0 ? 21 : gps.Speed;
newFinalGpsList.Add(gps);
}
#region 计算停留点
int stopIdx = 0;
VehicleGps firstGps = new VehicleGps();
newFinalGpsList = newFinalGpsList.Distinct().ToList();
for (int i = 0; i < newFinalGpsList.Count; i++)
{
TrackPlaybackOutput output = new TrackPlaybackOutput();
VehicleGps gps = newFinalGpsList[i];
output.Longitude = gps.Longitude;
output.Latitude = gps.Latitude;
output.GpsTime = gps.GpsTime.AddHours(8);
output.StartTime = gps.GpsTime.AddHours(8);
output.EndTime = gps.GpsTime.AddHours(8);
output.Speed = gps.Speed;
output.Direct = gps.Direct;
output.DurationTime = "";
output.IsStopPoint = false;
output.StopPointIdx = -1;
output.Address = gps.Address;
output.Acc = gps.Acc;
output.AccDurationTime = "";
output.Work = gps.Work;
output.WorkDurationTime = "";
output.TotalDistance = 0;
if (i != 0)
{
VehicleGps preGps = newFinalGpsList[i - 1];
totalDistance += DistanceHelper.GetDistance(Convert.ToDouble(gps.Latitude),
Convert.ToDouble(gps.Longitude),
Convert.ToDouble(preGps.Latitude), Convert.ToDouble(preGps.Longitude));
output.TotalDistance = totalDistance;
//用于计算停留点
if (gps.GpsTime.ConvertToTimestamp() - preGps.GpsTime.ConvertToTimestamp() > 300)
{
string durationTime = TimeHelper.TimeSpanFormat(gps.GpsTime - preGps.GpsTime, 3);
string address = MapHelper.GetLocationByLngLat(reult.LastOrDefault().Longitude,
reult.LastOrDefault().Latitude);
//停留点
reult.LastOrDefault().DurationTime = durationTime;
if (firstGps.GpsTime.ConvertToTimestamp() != preGps.GpsTime.ConvertToTimestamp())
{
reult.LastOrDefault().StopPointIdx = ++stopIdx;
reult.LastOrDefault().IsStopPoint = true;
}
reult.LastOrDefault().Address = address;
reult.LastOrDefault().StartTime = preGps.GpsTime.AddHours(8);
reult.LastOrDefault().EndTime = gps.GpsTime.AddHours(8);
stopTimeSpan += (gps.GpsTime - preGps.GpsTime);
//如果第一点是停留点,则将停留时间更新到第一个点上
if (firstGps.GpsTime == preGps.GpsTime)
{
stopList.LastOrDefault().Behavior = "停留" + durationTime;
}
else
{
//停留点插入轨迹动态列表
Stop stop = new Stop();
stop.GpsTime = preGps.GpsTime.AddHours(8);
stop.Latitude = preGps.Latitude;
stop.Longitude = preGps.Longitude;
stop.Address = address;
stop.State = "停" + stopIdx;
stop.Status = 1;
stop.Behavior = "停留" + durationTime;
stop.TotalDistance = totalDistance != 0 ? totalDistance : 0;
stop.StartTime = preGps.GpsTime;
stop.EndTime = output.GpsTime;
stopList.Add(stop);
}
}
if (i == newFinalGpsList.Count - 1)
{
Stop stop = new Stop();
VehicleGps lastGps = newFinalGpsList[i];
string address = lastGps.Address;
output.Address = address;
stop.Latitude = lastGps.Latitude;
stop.Longitude = lastGps.Longitude;
stop.GpsTime = lastGps.GpsTime.AddHours(8);
stop.Address = lastGps.Address;
stop.State = "终点";
stop.Status = 3;
stop.Behavior = "";
stop.TotalDistance = totalDistance != 0 ? totalDistance : 0;
stopList.Add(stop);
}
}
else
{
firstGps = newFinalGpsList[0];
string address = firstGps.Address;
Stop stop = new Stop
{
Latitude = firstGps.Latitude,
Longitude = firstGps.Longitude,
GpsTime = firstGps.GpsTime.AddHours(8),
Address = address,
State = "起点",
Status = 0,
Behavior = "",
TotalDistance = 0
};
stopList.Add(stop);
output.Address = address;
}
if (newFinalGpsList.Count == 1)
{
firstGps = newFinalGpsList[0];
string address = firstGps.Address;
Stop stop = new Stop();
stop.Latitude = firstGps.Latitude;
stop.Longitude = firstGps.Longitude;
stop.GpsTime = endTime;
stop.Address = address;
stop.State = "终点";
stop.Status = 3;
stop.Behavior = "";
stop.TotalDistance = 0;
stopList.Add(stop);
}
reult.Add(output);
}
#endregion 计算停留点
trackPlaybackListOutput = new TrackPlaybackListOutput
{
VehicleCode = vehicle.VehicleCode,
VehiclePlate = vehicle.VehiclePlate,
TotalDistance = totalDistance != 0 ? totalDistance : 0,
TotalStopTime = TimeHelper.TimeSpanFormat(stopTimeSpan, 3),
trackPlaybackOutputs = reult,
Stops = stopList
};
TimeSpan timeSpan = type == "Today" ? TimeSpan.FromMinutes(10) : TimeSpan.FromDays(3);
await _cacheService.SeTrackPlaybackAsync(trackPlaybackListOutput, vehicleId, startTime, endTime, timeSpan);
}
#endregion
#region v1.2.1
/// <summary>
/// 基础数据-车辆管理列表
/// </summary>
/// <param name="currentPage"></param>
/// <param name="pageSize"></param>
/// <param name="key"></param>
/// <param name="status">0全部,停用-1,正常1</param>
/// <returns></returns>
[HttpGet]
[Route("api/v1/basics/vehicles/search")]
public async Task<VehicleBaiscListPage> BasicsPageAsync([Required] int currentPage, [Required] int pageSize, [FromQuery] int status, [FromQuery] string key)
{
var vehicleGpsList = (await _cacheService.GetVehicleByCompanyIdAsync(_userManager.CompanyId))
.WhereIf(status!=0, x => x.Status == status)
.WhereIf(key.IsNotEmptyOrNull(), x => x.VehicleCode.Contains(key)).Adapt<List<VehicleBaiscListOutput>>();
foreach (var item in vehicleGpsList)
{
//item.VehiclePerson = await _cacheService.GetVehiclePersonByIDAsync(item.Id);
//if (item.VehiclePerson.IsNull())
//{
// item.VehiclePerson = new List<VehiclePersonOutput>();
//}
//else
//{
// item.VehiclePersonName = item.VehiclePerson.Find(x => x.IsDriver == true)?.UserName;
// item.VehiclePersonPhone = item.VehiclePerson.Find(x => x.IsDriver == true)?.UserPhone;
//}
item.VehiclePerson = await _cacheService.GetVehiclePersonAsync(item.Id);
item.VehiclePersonName = item.VehiclePerson.Find(x => x.IsDriver == true)?.UserName;
item.VehiclePersonPhone = item.VehiclePerson.Find(x => x.IsDriver == true)?.UserPhone;
}
var vehicleOutputs = new List<VehicleBaiscListOutputs>();
foreach (var INDEX_STRING in INDEX_STRINGS)
{
vehicleOutputs.Add(new VehicleBaiscListOutputs()
{
Char = INDEX_STRING,
List = vehicleGpsList.Where(x => StringHelper.GetStringFirstSpell(x.VehicleCode) == INDEX_STRING).ToList()
});
};
var data = new VehicleBaiscListPage()
{
VehicleBaiscList = vehicleOutputs,
Total = vehicleGpsList.Count
};
return data;
}
/// <summary>
/// 基础数据-车辆信息
/// </summary>
/// <param name="vehicleId"></param>
/// <returns></returns>
[HttpGet]
[Route("api/v1/basics/vehicle/{vehicleId}")]
public async Task<VehicleBaiscListOutput> GetVehicleBasicsByIdAsync(long vehicleId)
{
//车辆
Vehicle vehicle = await _cacheService.GetVehicleAsync(vehicleId);
if (vehicle.IsNull())
{
Oops.Oh("暂无车辆信息");
}
VehicleBaiscListOutput VehicleBaisc = vehicle.Adapt<VehicleBaiscListOutput>();
VehicleBaisc.VehiclePerson = await _cacheService.GetVehiclePersonAsync(vehicleId);
return VehicleBaisc;
}
/// <summary>
/// 更新车辆基础信息
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[UnitOfWork]
[HttpPut]
[Route("api/v1/basics/vehicle")]
public async Task BasicsUpdateAsync(BasicsVehicleUpdateInput input)
{
var vehicle = await _repository.FirstOrDefaultAsync(x => x.Id == input.Id);
if (vehicle.IsNull()) throw Oops.Oh("暂无该信息");
var repeatVehicle = await _repository.DetachedEntities
.Where(x => x.Id != input.Id && ((x.VehicleCode == input.VehicleCode && x.CompanyId == _userManager.CompanyId) ||
(x.VehiclePlate == input.VehiclePlate && x.Status == (int)CommonStatusEnum.ENABLE)))
.FirstOrDefaultAsync();
if (repeatVehicle.IsNotNull())
{
throw Oops.Bah("车牌号或设备名称重复");
}
//车组人员人数无上限,至少存在一个司机才可保存
if (input.VehiclePersons.Count > 0)
{
var isDriver = input.VehiclePersons.Find(x => x.IsDriver == true);
if (isDriver.IsNull())
{
throw Oops.Bah("车组人员至少需要一个司机");
}
}
#region 修改车组人员
var oldVehiclePersons = await _vehiclePersonRepository.DetachedEntities
.Where(x => x.VehicleId == input.Id && x.IsDeleted == false)
.ToListAsync();
var oldVehiclePersonIds = oldVehiclePersons.IsNotNull() ? oldVehiclePersons.Select(x => x.UserId).ToArray() : new long[] { };
var newVehiclePersonIds = input.VehiclePersons.IsNotNull() ? input.VehiclePersons.Select(x => x.UserId).ToArray() : new long[] { };
var deleteVehiclePersonIds = oldVehiclePersonIds.Except(newVehiclePersonIds).ToArray();
if (deleteVehiclePersonIds.Length > 0)
{
for (int i = 0; i < deleteVehiclePersonIds.Length; i++)
{
var vehiclePerson = oldVehiclePersons.FirstOrDefault(x => x.UserId == deleteVehiclePersonIds[i]);
vehiclePerson.IsDeleted = true;
await _vehiclePersonRepository.UpdateNowAsync(vehiclePerson);
}
}
if (input.VehiclePersons.IsNotNull())
{
foreach (var item in input.VehiclePersons)
{
var oldvehiclePerson = oldVehiclePersons.Find(x => x.UserId == item.UserId);
if (oldvehiclePerson.IsNull())
{
var vehiclePerson = item.Adapt<VehiclePerson>();
vehiclePerson.VehicleId = input.Id;
await _vehiclePersonRepository.InsertNowAsync(vehiclePerson);
}
else
{
var vehiclePerson = item.Adapt<VehiclePerson>();
vehiclePerson.Id = oldvehiclePerson.Id;
await _vehiclePersonRepository.UpdateNowAsync(vehiclePerson);
}
}
}
#endregion
var result = await _repository.UpdateNowAsync(input.Adapt(vehicle));
if (result.IsNull())
{
throw Oops.Oh("修改车辆基础信息失败");
}
//同步修改油耗表和订单表设备号
if (input.VehicleCode != vehicle.VehicleCode)
{
//油耗表
await "update dc_oil set VehicleCode=@vehicleCode where VehicleId=@id And IsDeleted=0".SqlNonQueryAsync(new { id = input.Id, vehicleCode = input.VehicleCode });
//订单表
await "update dc_order set VehicleCode=@vehicleCode where VehicleId=@id And IsDeleted=0".SqlNonQueryAsync(new { id = input.Id, vehicleCode = input.VehicleCode });
}
await _cacheService.RemoveVehiclePersonAsync(input.Id);
await _cacheService.RemoveVehicleAsync(input.Id);
await _cacheService.RemoveVehicleByCompanyIdAsync(_userManager.CompanyId);
}
#endregion
#region 查询车辆
/// <summary>
/// 根据id获取车辆Gps信息
/// </summary>
/// <param name="vehicleId"></param>
/// <returns></returns>
[HttpGet]
[Route("api/v1/vehicle/Vehicles")]
public async Task<List<VehiclesOutPut>> GetVehiclesAsync()
{
var input = new List<VehiclesOutPut>();
//车辆
var vehicles = await _cacheService.GetVehicleByCompanyIdAsync(this._userManager.CompanyId);
if (vehicles.IsNull())
{
var res = await this._repository.DetachedEntities.Where(x => x.CompanyId == this._userManager.CompanyId).ToListAsync();
if (res.IsNull())
throw Oops.Oh("公司无车辆");
vehicles = res.Adapt<List<VehicleGpsOutput>>();
}
foreach (var item in vehicles)
{
VehiclesOutPut vehiclesOut = new VehiclesOutPut();
vehiclesOut.VehiclePlate = item.VehicleCode;
vehiclesOut.Id = item.Id;
input.Add(vehiclesOut);
}
return input;
}
#endregion
#region 初始化车辆
#endregion
}
}