loading页&结果页面&代码结构微调

This commit is contained in:
lishuo committed 2021-07-16 18:37:02 +08:00
1 parent eb1803c9ef
commit eed2d13624
99 files changed
+14567 -7299

No files matched your search

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cab9cf5c3f47cbe498f0cab35b09125e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,135 @@
using Assets.Scripts.Apis.Models;
using GeoJSON.Net.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model.CyclingModels
{
public abstract class BaseCycling
{
public CyclingModel Mode { get; private set; }
/// <summary>
/// 是否记录数据
/// </summary>
internal bool IsRecord { get; set; }
/// <summary>
/// 骑行数据记录器
/// </summary>
public RecorderDataModel recorderData { get; protected set; }
public List<BaseRider> riders { get; protected set; }
/// <summary>
/// 骑行的路线
/// </summary>
public Route route;
/// <summary>
/// 计时器
/// </summary>
public int Ticks = 0;
/// <summary>
/// 当前骑行的距离
/// </summary>
protected double currentDistance { get; set; }
public virtual bool CanPause => true;
protected TurfHelper _turfHelper;
protected double Zoom { get; private set; }
protected string Bounds { get; private set; }
protected List<OutUser> realRiders;
protected GeographicPosition CenterPoint { get; private set; }
/// <summary>
/// 结束的时间
/// </summary>
protected DateTime? EndTime { get; set; }
public BaseCycling(Route route, CyclingModel cyclingModel)
{
this.route = route;
this.Mode = cyclingModel;
_turfHelper = new TurfHelper(route.JsonData.List.Select(d => d.Point));
}
public virtual DateTime Now
{
get
{
return UIManager.Now.GetDateTime();
}
}
public virtual string ShowTime
{
get
{
return Helper.FormatTicks(Ticks);
}
}
/// <summary>
/// 骑行函数(如果此方法不满足,可以在子类中重写此方法)
/// </summary>
/// <param name="data"></param>
public virtual void Run(TargetData targetData)
{
//将当前用户的位置发送到udf服务
SendUserPositionToServer();
//OutModel outData = GetSelfTargetData(targetData);
BeforeRunAfterPakcData();//执行前的函数
}
/// <summary>
/// =>发送用户的位置信息到服务端
/// </summary>
private void SendUserPositionToServer()
{
try
{
if (recorderData.RiderDatas.Any())
{
var lastData = recorderData.RiderDatas.Last();
var preDistance = recorderData.PreDistance;
var weightKg = Math.Round(lastData._Power / recorderData.CurrentUser.Weight, 2);
MapUDPService.Send(route.RouteInstance.Id, recorderData.BelongUserId,
new double[] { lastData._Lat, lastData._Lon },
recorderData.IsCompleted, false, recorderData.EndDistance,
true, 1, lastData._Speed, false, preDistance, weightKg, competitionId: recorderData.Competitionid, recorderData.Saved);
}
else if (recorderData.EndDistance > 0)//没有骑,但是有初始位置的情况
{
var point = _turfHelper.Along(recorderData.EndDistance);
//MapUDPService.Send(route.RouteInstance.Id, recorderData.BelongUserId, new double[] { point.Latitude, point.Longitude }, competitionId: recorderData.Competitionid);
MapUDPService.Send(route.RouteInstance.Id, recorderData.BelongUserId, new double[] { point.Latitude, point.Longitude }, endDistance:recorderData.EndDistance,preDistance: recorderData.EndDistance, competitionId: recorderData.Competitionid);
}
else
{
MapUDPService.Send(route.RouteInstance.Id, recorderData.BelongUserId, route.Point.First().Reverse().ToArray(), competitionId: recorderData.Competitionid);
}
}
catch (Exception)
{
}
}
/// <summary>
/// 执行前,数据打包后
/// </summary>
/// <param name="outData"></param>
protected virtual void BeforeRunAfterPakcData() { }
protected double SpeedToDistance(double speed)
{
return Math.Round(speed / 3600, 5, MidpointRounding.AwayFromZero);
//return 0.08;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 89d63056e2fd43e41b30635a0036ba33
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,333 @@
using Assets.Scenes.Ride.Scripts.Model.RiderModels;
using Assets.Scripts;
using Assets.Scripts.Apis;
using Assets.Scripts.Apis.Models;
using Mapbox.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model.CyclingModels
{
public class CompetitionModel : BaseCycling
{
private Vector2d firstPoint { get; set; }
public CompetitionRankingModel competitionRankingModel { get; set; }
private MapCompetitionApi mapCompetitionApi;
public MapCompetition mapCompetition;
private List<CompetitionRankingResultModel> mapWorkoutRecordRankings = new List<CompetitionRankingResultModel>();
/// <summary>
/// 第一个到终点的时间
/// </summary>
private DateTime? FirstEndTime { get; set; }
public override bool CanPause => false;
public override string ShowTime
{
get
{
if (CanStart())
{
var second = Math.Ceiling((Now - mapCompetition.StartTime.ToLocalTime()).TotalSeconds);
var ts = TimeSpan.FromSeconds(second);
return $"{ (int)ts.TotalHours }:{ts:mm}:{ts:ss}";
}
return "00:00:00";
}
}
AbstractPlayer currentPlayer;
public CompetitionModel(Route route1, RouteResultParam param,AbstractPlayer player)
: base(route1, CyclingModel.Competition)
{
currentPlayer = player;//当前选中用户
mapCompetitionApi = new MapCompetitionApi();
//param.EndDistance = 18;
recorderData = new RecorderDataModel()
{
CurrentUser = App.CurrentUser,
//BelongUserId = PubCommData.CurrentUser.Id,
Competitionid = param.CompetitionId??0,
ContinueIndex = param.ContinueIndex == null ? 0 : (int)param.ContinueIndex + 1,
ContinueMark = string.IsNullOrEmpty(param.ContinueMark) ? Guid.NewGuid().ToString() : param.ContinueMark,
EndDistance = param.EndDistance == 0 ? 0 : param.EndDistance,
IsCompleted = false,
IsNeedRanking = true,
CyclingState = CyclingStateEnum.Prepare,
//ManufacturerId = ManufacturerId,
CurrentRoute = route,
CurrentRouteStartDistance = param.EndDistance == 0 ? 0 : param.EndDistance,
//DeviceNumber = DeviceNumber,
//AntModelId = antModelId
};
IsRecord = true;
riders = new List<BaseRider>();
var rider = new OnlineRiderModel()
{
NickName = App.CurrentUser.Nickname,
UserId = App.CurrentUser.Id,
WxHeadImg = App.CurrentUser.WxHeadImg,
EndDistance = param.EndDistance == 0 ? 0 : param.EndDistance
};
if (recorderData.CurrentRouteStartDistance > 0)
{
rider.Point = _turfHelper.Along(param.EndDistance);
}
else
{
rider.Point = new GeoJSON.Net.Geometry.GeographicPosition(this.route.RouteInstance.Point[0], this.route.RouteInstance.Point[1]);
}
//riders.Add(rider);//剔除自己
var result = mapCompetitionApi.GetById(param.CompetitionId??0);
if (result.result == false || result.data == null)
{
return;
}
mapCompetition = result.data;
FirstEndTime = mapCompetition.FirstEndTime;
}
protected override void BeforeRunAfterPakcData()
{
//#region 设置第一名的坐标
//if (!FirstEndTime.HasValue)
//{
// var firstItem = base.realRiders.OrderByDescending(w => w.NextDistance).FirstOrDefault();
// if (firstItem != null)
// {
// firstPoint = new Vector2d(firstItem.Point.Latitude, firstItem.Point.Longitude);
// }
//}
//#endregion
var userList = MapUDPService.GetCompetitionOnlineUsers(recorderData.Competitionid).OrderByDescending(u => u.IsCompleted).ThenByDescending(d => d.EndDistance);
riders.RemoveAll(r => r.IsSelf == false);
int index = 0;
List<CompetitionRankingSortModel> sort = new List<CompetitionRankingSortModel>();
if (userList.Any())
{
var currentDistance = currentPlayer.TotalDistance;
foreach (var item in userList)
{
#region 记录第一个冲线的时间
if (item.IsCompleted && !FirstEndTime.HasValue)
{
FirstEndTime = Now;
}
#endregion
if (item.IsSelf == false)
{
riders.Add(new OnlineRiderModel
{
NickName = item.Name,
UserId = item.Id,
WxHeadImg = item.HeadImage,
Point = new GeoJSON.Net.Geometry.GeographicPosition(item.Point[0], item.Point[1]),
EndDistance = item.EndDistance,
PreDistance = item.PreDistance
});
}
index++;
double near = Math.Round(item.EndDistance - currentDistance,2); //Math.Round(TurfHelper.GetDistances(point, item.Point), 2);
sort.Add(new CompetitionRankingSortModel
{
Index = index,
Name = item.Name,
Near = near,
KGWeight = Math.Round(item.WeightKg, 2).ToString(),
Speed = Math.Round(item.Speed, 1),
CountryImg = ConfigHelper.Host + $"User/GetCountryImg?userid={ item.Id }",
UserId = item.Id,
IsSelf = item.IsSelf,
Headimage =item.HeadImage
});
}
}
#region 骑行结束,比赛结果展示数据
var results = new List<CompetitionResultModel>();
if (recorderData.IsCompleted || recorderData.Saved || mapCompetition.HasRecord)
{
var users1 = userList.Where(d => d.IsCompleted || d.Saved);
if ((users1.Any() && users1.Any(d => mapWorkoutRecordRankings.All(u => u.UserId != d.Id)))
|| mapWorkoutRecordRankings.All(u => u.UserId != recorderData.BelongUserId))
{
var rrr = mapCompetitionApi.GetRankingList(recorderData.Competitionid);
if (rrr.result)
{
mapWorkoutRecordRankings = rrr.data;
}
}
foreach (var ranking in mapWorkoutRecordRankings)
{
//var ranking = mapWorkoutRecordRankings.SingleOrDefault(r => r.UserId == item.Id);
var createTime = "";
if (ranking != null)
{
createTime = ranking.CreateTime; //.ToString("yyyy-MM-dd HH:mm:ss");
}
results.Add(new CompetitionResultModel
{
Index = ranking.Index,
Name = ranking.NickName,
UserId = ranking.UserId,
Weight = ranking?.Weight ?? 0,
WeightKg = ranking?.WeightKg ?? 0,
//Time = ranking?.TotalTime ?? "",
Power = ranking?.AveragePower ?? 0,
BicycleWeight = ranking?.BicycleWeight ?? 0,
HeartRate = ranking?.AverageHeartRate ?? 0,
DeviceType = ranking?.DeviceType ?? "",
CreateTime = createTime,
TripTime = ranking?.TripTime ?? "",
CompleteTime = ranking?.CompleteTime,
Gap = ranking?.Gap ?? ""
});
}
}
#endregion
competitionRankingModel = new CompetitionRankingModel
{
Sorts = sort,//骑行实时排名
MyRanking = sort.FindIndex(n => n.UserId == currentPlayer.UserId) + 1,//切换人物显示对应人物的排名
Total = sort.Count,//总人数
Results = results//比赛结果列表
};
}
/// <summary>
/// 赛事模式有继续骑行,重写执行方法
/// </summary>
/// <param name="targetData"></param>
public override void Run(TargetData targetData)
{
#region 获取当前路线在线用户
riders.RemoveAll(r => r.IsSelf == false);
var onlineUsers = MapUDPService.GetCompetitionOnlineUsers(mapCompetition.Id).Where(d => d.IsSelf == false)
.ToList();
foreach (var item in onlineUsers)
{
riders.Add(new OnlineRiderModel()
{
NickName = item.Name,
UserId = item.Id,
WxHeadImg = item.HeadImage,
Point = new GeoJSON.Net.Geometry.GeographicPosition(item.Point[0], item.Point[1]),
EndDistance = item.EndDistance,
PreDistance = item.PreDistance,
WeightKg = item.WeightKg,
});
}
#endregion
//TODO:接力赛
////base.BeforeRun(targetData);
//if (recorderData.CyclingState == CyclingStateEnum.Prepare)
//{
// if (recorderData.EndDistance != 0)
// {
// currentDistance = recorderData.EndDistance;
// }
// else
// {
// currentDistance = 0;
// }
//}
//else if (recorderData.CyclingState == CyclingStateEnum.Cycling)
//{
// currentDistance = recorderData.EndDistance + SpeedToDistance(targetData._Speed);
//}
base.Run(targetData);
}
//显示结果当前用户保存或者产生第一名
public bool CanShowResult()
{
return mapCompetition?.HasRecord ?? false || mapCompetition ?.FirstEndTime != null;
}
//关门时间到了退出骑行场景
public bool CanQuit()
{
if (mapCompetition?.FirstEndTime.HasValue??false)
{
var closeDateTime = mapCompetition?.FirstEndTime.Value.ToLocalTime().AddMinutes(mapCompetition?.CloseTime??0 );
return Now >= closeDateTime;
}
return false;
}
public bool CanStart()
{
if (mapCompetition == null)
{
return false;
}
//if (mapCompetition.CanStart)
//{
// return true;
//}
if (mapCompetition.HasRecord)
{
return false;
}
//已结束
if (mapCompetition.Status == 4)
{
return false;
}
if (mapCompetition.StartTime.ToLocalTime() <= Now && mapCompetition.EndTime.ToLocalTime() > Now)
{
return true;
}
return false;
}
public int StartCountdown()
{
if (CanStart()) return 0;
return (int)Math.Floor((mapCompetition.StartTime.ToLocalTime() - Now).TotalSeconds);
}
/// <summary>
/// 结束倒计时,bool值为true说明倒计时是关门时间
/// </summary>
/// <returns></returns>
public (int, bool) EndCountDown()
{
if (CanStart() == false) return (0, false);
//if (recorderData.IsCompleted) return 0;
var end1 = (int)Math.Floor((mapCompetition.EndTime.ToLocalTime() - Now).TotalSeconds);
if (!FirstEndTime.HasValue)
{
return (end1, false);
}
//var end2 = (int)Math.Floor((FirstEndTime.Value - Now).TotalSeconds);
var end2 = (int)Math.Floor((FirstEndTime.Value.AddMinutes(mapCompetition.CloseTime) - Now).TotalSeconds);
if (end1 < end2)
{
return (end1, false);
}
//return Math.Min(end1, end2);
return (end2, true);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 44b357cbe9541fa448708b42ff5bf3d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,90 @@
using Assets.Scenes.Ride.Scripts.Model.RiderModels;
using Assets.Scripts;
using Assets.Scripts.Apis.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model.CyclingModels
{
public class ReviewModel : BaseCycling
{
public List<MapRecordRanking> rankings;
public ReviewModel(Route route1, RouteResultParam param)
: base(route1, CyclingModel.Review)
{
//rankings = service.GetMapRecordRankingsFromServe(param.RankingsId);
riders = new List<BaseRider>();
//riders.Add(new OnlineRiderModel()
//{
// NickName = App.CurrentUser.Nickname,
// UserId = App.CurrentUser.Id,
// WxHeadImg = App.CurrentUser.WxHeadImg,
// Point = new GeoJSON.Net.Geometry.GeographicPosition(this.route.RouteInstance.Point[0], this.route.RouteInstance.Point[1])
//});
//foreach (var item in rankings)
//{
// riders.Add(new ReviewRiderModel()
// {
// NickName = item.NickName,
// UserId = item.UserId,
// WxHeadImg = item.WxHeadImg,
// record = item.record,
// Point = new GeoJSON.Net.Geometry.GeographicPosition(this.route.RouteInstance.Point[0], this.route.RouteInstance.Point[1])
// });
//}
recorderData = new RecorderDataModel()
{
CurrentUser = App.CurrentUser,
//BelongUserId = PubCommData.CurrentUser.Id,
Competitionid = 0,
ContinueIndex = 0,
ContinueMark = Guid.NewGuid().ToString(),
EndDistance = 0,
PreDistance = 0,
IsCompleted = false,
IsNeedRanking = true,
CyclingState = CyclingStateEnum.Prepare,
//ManufacturerId = ManufacturerId,
CurrentRoute = route,
CurrentRouteStartDistance = 0,
//DeviceNumber = DeviceNumber,
//AntModelId = antModelId
};
//recorderData = recorderData1;
this.IsRecord = true;
//riders = riders1;
}
public override void Run(TargetData targetData)
{
#region 获取当前路线在线用户
riders.RemoveAll(r => r.IsSelf == false);
var onlineUsers = MapUDPService.GetOnlineUsers(recorderData.CurrentRoute.RouteInstance.Id).Where(d => d.IsSelf == false)
.ToList();
foreach (var item in onlineUsers)
{
riders.Add(new OnlineRiderModel()
{
NickName = item.Name,
UserId = item.Id,
WxHeadImg = item.HeadImage,
Point = new GeoJSON.Net.Geometry.GeographicPosition(item.Point[0], item.Point[1]),
EndDistance = item.EndDistance,
PreDistance = item.PreDistance,
WeightKg = item.WeightKg,
});
}
#endregion
base.Run(targetData);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 363f64631c874c84198aa481f8899911
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,89 @@
using Assets.Scenes.Ride.Scripts.Model.RiderModels;
using Assets.Scripts.Apis.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model.CyclingModels
{
public class SingleModel : BaseCycling
{
public SingleModel(Route route,RouteResultParam param)
: base(route, CyclingModel.Single)
{
this.IsRecord = true;
recorderData = new RecorderDataModel()
{
CurrentUser = App.CurrentUser,
Competitionid = 0,
ContinueIndex = 0,
ContinueMark = Guid.NewGuid().ToString(),
EndDistance = 0,
IsCompleted = false,
IsNeedRanking = true,
CyclingState = CyclingStateEnum.Prepare,
CurrentRoute = route,
CurrentRouteStartDistance = 0,
StartTime = UIManager.Now.GetDateTime(),//DateTime.Now
};
if (param != null)
{
recorderData.EndDistance = param.EndDistance;
recorderData.CurrentRouteStartDistance = param.EndDistance;
if (!string.IsNullOrWhiteSpace(param.ContinueMark))
{
recorderData.ContinueMark = param.ContinueMark;
}
else
{
param.ContinueMark = recorderData.ContinueMark;
}
recorderData.ContinueIndex = param.ContinueIndex.GetValueOrDefault(0);
}
recorderData.PreDistance = recorderData.EndDistance;
riders = new List<BaseRider>();
//var rider = new OnlineRiderModel()
//{
// NickName = App.CurrentUser.Nickname,
// UserId = App.CurrentUser.Id,
// WxHeadImg = App.CurrentUser.WxHeadImg + "?t=1",
// //Point = new GeoJSON.Net.Geometry.GeographicPosition(this.route.RouteInstance.Point[0], this.route.RouteInstance.Point[1]),
// EndDistance = recorderData.EndDistance
//};
//rider.Point = _turfHelper.Along(rider.EndDistance);
//riders.Add(rider);
}
public override void Run(TargetData targetData)
{
#region 获取当前路线在线用户
riders.RemoveAll(r => r.IsSelf == false);
var onlineUsers = MapUDPService.GetOnlineUsers(recorderData.CurrentRoute.RouteInstance.Id).Where(d => d.IsSelf == false)
.ToList();
foreach (var item in onlineUsers)
{
riders.Add(new OnlineRiderModel()
{
NickName = item.Name,
UserId = item.Id,
WxHeadImg = item.HeadImage,
Point = new GeoJSON.Net.Geometry.GeographicPosition(item.Point[0], item.Point[1]),
EndDistance = item.EndDistance,
PreDistance = item.PreDistance,
WeightKg = item.WeightKg,
});
}
#endregion
base.Run(targetData);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1057f786065eded488dd73a935cc1b93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
/// <summary>
/// 骑行模式
/// </summary>
public enum CyclingModel
{
/// <summary>
/// 单人模式
/// </summary>
Single = 0,
/// <summary>
/// 在线模式
/// </summary>
Online = 1,
/// <summary>
/// 多人历史数据回顾模式
/// </summary>
Review = 2,
/// <summary>
/// 比赛模式
/// </summary>
Competition = 3,
/// <summary>
/// 环球骑行
/// </summary>
GlobalCycling = 4
}
/// <summary>
/// 骑手类型
/// </summary>
public enum RiderType
{
//Real,//真实的人
Online,//在线人
Review,//回顾人(历史数据中的人)
Virtual
}
/// <summary>
/// 骑行状态(状态变更示意图:Paush=>Cycling=>Stop=>Cycling=>Stop)
/// </summary>
public enum CyclingStateEnum
{
/// <summary>
/// 准备阶段
/// </summary>
Prepare,
/// 骑行中
/// </summary>
Cycling,
/// <summary>
/// 暂停
/// </summary>
Stop
}
/// <summary>
/// 发送数据模式
/// </summary>
public enum SendDataMode
{
/// <summary>
/// 自由骑
/// </summary>
Freedom,
/// <summary>
/// 阻力模式
/// </summary>
Resistance,
/// <summary>
/// 轨道模式
/// </summary>
Track
}
/// <summary>
/// 浏览器窗口
/// </summary>
public enum BrowserWindow
{
/// <summary>
/// 主页面窗口
/// </summary>
Main,
/// <summary>
/// 骑行页面窗口
/// </summary>
Cycling
}
public enum CurrentPage
{
index,
list,
detial,
review,
competition,
cycling
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d3d3dd3c4d6e2694eb9d94bc819a12f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,563 @@
using GeoJSON.Net.Geometry;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
/// <summary>
/// 排名
/// </summary>
public class CompetitionRankingSortModel
{
public int Index { get; set; }
public string Name { get; set; }
public string Headimage { get; set; }
public double Near { get; set; }
public string KGWeight { get; set; }
public double Speed { get; set; }
public string CountryImg { get; set; }
public int UserId { get; set; }
public bool IsSelf { get; set; }
}
/// <summary>
/// 结果页模型
/// </summary>
public class CompetitionResultModel
{
public int Index { get; set; }
public int UserId { get; set; }
public string Name { get; set; }
public string HeadUrl { get; set; }
//public string Time { get; set; }
public double Power { get; set; }
public double WeightKg { get; set; }
public double Weight { get; set; }
public double BicycleWeight { get; set; }
public double HeartRate { get; set; }
public string DeviceType { get; set; }
public string CreateTime { get; set; }
/// <summary>
/// 骑行时长
/// </summary>
public string TripTime { get; set; }
public string CompleteTime { get; set; }
/// <summary>
/// 与冲线时间的差距
/// </summary>
public string Gap { get; set; }
}
public class RankingDataModel
{
public int UserId { get; set; }
public TargetData data { get; set; }
}
public class RankingSortData
{
public int Index { get; set; }
public int UserId { get; set; }
public string WxHeadImg { get; set; }
public string NickName { get; set; }
/// <summary>
/// 注意这里TotalTime不是时间是距离,为了重用前端组件,没改名称
/// </summary>
public double TotalTime { get; set; }
public int Ticks { get; set; }
/// <summary>
/// 其他人和我的距离(m)
/// </summary>
public double Near { get; set; }
}
public class CyclingFrameRankingModel
{
public List<RankingDataModel> data { get; set; }
public List<RankingSortData> sort { get; set; }
public int myranking { get; set; }
}
/// <summary>
/// 比赛的排名
/// </summary>
public class CompetitionRankingModel
{
public List<CompetitionRankingSortModel> Sorts { get; set; }
public int Total { get; set; }
public int MyRanking { get; set; }
public List<CompetitionResultModel> Results { get; set; }
}
/// <summary>
/// 骑行中 输出的数据模型
/// </summary>
public class OutModel
{
public double progress { get; set; }
public double? Elevation { get; set; }
public string Seconds { get; set; }
public int? EleIndex { get; set; }
//public long ExcuteTime { get; set; }
//public double? Bearing { get; set; }
/// <summary>
/// 坡度
/// </summary>
public double SlopeGrade { get; set; }
public TargetData targetData { get; set; }
public List<OutUser> baseRiders { get; set; }
public CyclingFrameRankingModel Ranking { get; set; }
public CompetitionRankingModel CompetitionRanking { get; set; }
public bool CanStart { get; set; } = true;
/// <summary>
/// 开始倒计时
/// </summary>
public int StartCountDown { get; set; }
/// <summary>
/// 结束倒计时
/// </summary>
public int EndCountDown { get; set; }
/// <summary>
/// 标识比赛的倒计时是关门时间
/// </summary>
public bool IsClosed { get; set; }
///// <summary>
///// 是否已保存
///// </summary>
//public bool Saved { get; set; }
/// <summary>
/// 比赛模式下,第一名的坐标
/// </summary>
public GeographicPosition FirstPoint { get; set; }
public ChartSymbol ChartSymbol { get; set; }
}
public class OutUser
{
public int UserId { get; set; }
public string InMapId { get; set; }
public double NextDistance { get; set; }
public double PreDistance { get; set; }
//public TargetData targetData { get; set; }//暂时不需要此字段
public List<double[]> NextFrameArray { get; set; }
//private List<object> _nextFrameArray { get; set; }
//public List<object> NextFrameArray
//{
// get
// {
// if (_nextFrameArray != null)
// {
// return _nextFrameArray;
// }
// _nextFrameArray = (List<object>)CefBrowserPool.GetFrame(BrowserWindow.Main).EvaluateScriptAsync($"getFrameArray({PreDistance},{NextDistance})").ConfigureAwait(false).GetAwaiter().GetResult().Result;
// return _nextFrameArray;
// }
//}
public string NickName { get; set; }
public string WxHeadImg { get; set; }
public bool IsSelf
{
get
{
return this.UserId == App.CurrentUser.Id;
}
}
public GeographicPosition Point { get; set; }
public double Bearing { get; set; }
}
public class ChartSymbol
{
private double _grade = 0;
private double _nextGrade = 0;
public string GradeSymbol
{
get
{
if (_grade > 0)
{
return "+";
}
if (_grade < 0)
{
return "-";
}
return "";
}
}
public string GradeDisplay
{
get
{
if (_grade < 0)
{
return (_grade * -1).ToString("0.#");
}
if (_grade > 0)
{
return _grade.ToString("0.#");
}
return "0";
}
}
public string NextGrade
{
get
{
if (_nextGrade > 0)
{
return "+" + _nextGrade.ToString("0.#");
}
return _nextGrade.ToString("0.#");
}
}
/// <summary>
/// 单位m
/// </summary>
public double Distance { get; set; }
/// <summary>
///
/// </summary>
/// <param name="grade"></param>
/// <param name="nextGrade"></param>
/// <param name="distance">单位m</param>
public ChartSymbol(double grade, double nextGrade, double distance)
{
this._grade = grade;
this._nextGrade = nextGrade;
this.Distance = Math.Round(distance, 1);
}
}
public class NearRiderModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Headimage { get; set; }
public double Near { get; set; }
public string KGWeight { get; set; }
public double Speed { get; set; }
public string CountryImg { get; set; }
public string Country { get; set; }
public bool IsSelf { get; set; }
}
public class MsgModel
{
public int RouteId { get; set; }
public int MemberId { get; set; }
public double[] Point { get; set; }
//public bool exit { get; set; }
public double Speed { get; set; }
public bool IsCompleted { get; set; }
/// <summary>
/// 需要展示的属性
/// </summary>
//public string Prop { get; set; }
public double EndDistance { get; set; }
///// <summary>
///// 是否展示在线的人
///// </summary>
//public bool ShowVirtual { get; set; }
/// <summary>
/// 命令类型,0命令,1消息
/// </summary>
public byte CommandType { get; set; }
//public bool IsVirtual { get; set; }
/// <summary>
/// 功率体重比
/// </summary>
public double WeightKg { get; set; }
public double PreDistance { get; set; }
public int Competitionid { get; set; }
/// <summary>
/// 客户端通过是否有用户保存了数据,来拉取相应的已经被保存的数据。(主要用在比赛)
/// </summary>
public bool Saved { get; set; }
//public int V { get; set; }
}
public class GzipMsgModel
{
public int CommandType { get; set; }
public int V { get; set; }
public string Encoding { get; set; }
public string Client { get; set; }
public int MemberId { get; set; }
public int Competitionid { get; set; }
public bool IsWatch { get; set; }
}
public class ReceiveMsgModel
{
public int RouteId { get; set; }
public int MemberId { get; set; }
public double[] Point { get; set; }
//public bool exit { get; set; }
public double Speed { get; set; }
public bool IsCompleted { get; set; }
/// <summary>
/// 需要展示的属性
/// </summary>
//public string Prop { get; set; }
public double EndDistance { get; set; }
/// <summary>
/// 是否展示在线的人
/// </summary>
//public bool ShowVirtual { get; set; }
/// <summary>
/// 命令类型,0命令,1消息
/// </summary>
//public byte CommandType { get; set; }
//public bool IsVirtual { get; set; }
public double PreDistance { get; set; }
/// <summary>
/// 功率体重比
/// </summary>
public double WeightKg { get; set; }
public int Competitionid { get; set; }
public bool Saved { get; set; }
public string WatchIdList { get; set; }
public static ReceiveMsgModel Parse(string str)
{
var list = str.Split(',');
if (list.Length != 10)
{
return null;
}
try
{
return new ReceiveMsgModel
{
RouteId = Convert.ToInt32(list[0],CultureInfo.InvariantCulture),
MemberId = Convert.ToInt32(list[1], CultureInfo.InvariantCulture),
Point = new double[] { double.Parse(list[2].Split(':')[0], CultureInfo.InvariantCulture), double.Parse(list[2].Split(':')[1], CultureInfo.InvariantCulture) },
IsCompleted = ToBoolean(list[3]),
//exit = ToBoolean(list[4]),
Speed = Convert.ToDouble(list[4], CultureInfo.InvariantCulture),
PreDistance = Convert.ToDouble(list[5], CultureInfo.InvariantCulture),
EndDistance = Convert.ToDouble(list[6], CultureInfo.InvariantCulture),
WeightKg = Convert.ToDouble(list[7], CultureInfo.InvariantCulture),
Competitionid = Convert.ToInt32(list[8], CultureInfo.InvariantCulture),
Saved = ToBoolean(list[9])
};
}
catch
{
return null;
}
}
private static bool ToBoolean(string str)
{
return Convert.ToBoolean(int.Parse(str));
}
}
public class OnlineUser
{
/// <summary>
/// 用户Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 在地图中的ID
/// </summary>
public string InMapId
{
get
{
//if (IsVirtual)
//{
// return "Online-Virtual-" + this.Id;
//}
return "Online-" + this.Id;
}
}
public bool IsVirtual { get; set; }
/// <summary>
/// 虚拟人物名称
/// </summary>
public string Name { get; set; }
public double Weight { get; set; }
/// <summary>
/// 头像地址
/// </summary>
public string HeadImage { get; set; }
/// <summary>
/// 路线Id
/// </summary>
public int RouteId { get; set; }
/// <summary>
/// FTP
/// </summary>
public int FTP { get; set; }
/// <summary>
/// 点位
/// </summary>
public double[] Point { get; set; }
/// <summary>
/// 需要展示的属性
/// </summary>
//public List<KeyPaire> Show { get; set; }
/// <summary>
/// 需要隐藏的属性
/// </summary>
public List<KeyPaire> Hide { get; set; }
/// <summary>
/// 是否骑行完毕
/// </summary>
public bool IsCompleted { get; set; }
public bool IsWatcher { get; set; }
public List<int> WatcherList { get; set; }
public double PreDistance { get; set; }
/// <summary>
/// 最后距离
/// </summary>
public double EndDistance { get; set; }
///// <summary>
///// 是否退出
///// </summary>
//public bool exit { get; set; }
/// <summary>
/// 速度(km/h)
/// </summary>
public double Speed { get; set; }
///// <summary>
///// 圆形头像
///// </summary>
//public string CircHeadImg
//{
// get; set;
//}
public bool IsSelf
{
get
{
return Id == App.CurrentUser.Id;
}
}
public double WeightKg { get; set; }
public int CompetitionId { get; set; }
/// <summary>
/// 已保存的
/// </summary>
public bool Saved { get; set; }
public DateTime LastActiveTime { get; set; }
public bool IsLost
{
get
{
return (DateTime.Now - LastActiveTime).TotalSeconds > 3;
}
}
public string Country { get; set; }
}
public class KeyPaire
{
public object Key { get; set; }
public object Value { get; set; }
public KeyPaire(object key, object value)
{
this.Key = key;
this.Value = value;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d5741018b26c4d94dbd42daf26d87f3f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,258 @@
using Assets.Scripts;
using Assets.Scripts.Apis;
using Assets.Scripts.Apis.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace Assets.Scenes.Ride.Scripts.Model
{
public class RecorderDataModel
{
//private readonly MapWorkoutService service = new MapWorkoutService();
public UserResultModel CurrentUser { get; set; }
/// <summary>
/// 所属人ID
/// </summary>
public int BelongUserId
{
get
{
return CurrentUser.Id;
}
}
/// <summary>
/// 记录是否完毕
/// </summary>
public bool IsCompleted { get; set; }
/// <summary>
/// 是否需要计算排名
/// </summary>
public bool IsNeedRanking { get; set; }
/// <summary>
/// 骑行记录索引(用于中断骑行,继续骑行)
/// </summary>
public int ContinueIndex { get; set; }
/// <summary>
/// 骑行状态
/// </summary>
public CyclingStateEnum CyclingState { get; set; }
/// <summary>
/// 赛事Id
/// </summary>
public int Competitionid { get; set; }
/// <summary>
/// 当前已经骑行的距离(表示用户现在在的距离,并不是实际骑的距离)
/// </summary>
public double EndDistance { get; set; }
/// <summary>
/// 上次骑行的距离
/// </summary>
public double PreDistance { get; set; }
/// <summary>
/// 继续骑行记录标志
/// </summary>
public string ContinueMark { get; set; }
/// <summary>
/// 厂商Id
/// </summary>
public int? ManufacturerId { get; set; }
public string ManufacturerName { get; set; }
public int? AntModelId { get; set; }
/// <summary>
/// 骑行数据
/// </summary>
public List<TargetData> RiderDatas = new List<TargetData>();
/// <summary>
/// 当前路线
/// </summary>
public Route CurrentRoute { get; set; }
/// <summary>
/// 骑行记录Id
/// </summary>
//public string RecordId { get; private set; }
/// <summary>
/// 设备号
/// </summary>
public string DeviceNumber { get; set; }
/// <summary>
/// 当前给骑行台发送数据的模式
/// </summary>
public SendDataMode SendDataMode { get; set; }
/// <summary>
/// 临时使用的坡度
/// </summary>
public double SlopeGrade { get; set; }
/// <summary>
/// 临时使用的海拔
/// </summary>
public double Elevation { get; set; }
/// <summary>
/// 当前路书开始的距离
/// </summary>
public double CurrentRouteStartDistance { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
/// <summary>
/// 是否已经保存成功
/// </summary>
public bool Saved { get; set; }
public int GlobalCyclingId { get; set; }
public double? TwentyMinutesMaxAP { get; set; }
public double? FiveSecondsMaxAP { get; set; }
public double? TenSecondsMaxAP { get; set; }
public double? OneMinuteMaxAP { get; set; }
public double? FiveMinutesMaxAp { get; set; }
public void SaveWithLocalRecordAysnc(CyclingModel cyclingModel, RouteResultParam selectParam, string imageName,string recordId,string path)
{
Dictionary<MapInterruptRecord, List<string>> recordData = new Dictionary<MapInterruptRecord, List<string>>();
if (RiderDatas.Count <= 0)
{
return ;
}
string newFileName = Guid.NewGuid().ToString();
int FTP = Helper.GetFtp();
double NP = Helper.GetNP(RiderDatas);
//强度
double IF = NP / FTP;
//训练量
double TSS = (RiderDatas.Count * NP * IF) / (FTP * 3600) * 100;
var averagePower = Helper.AveragePower(RiderDatas);
// AntManufacturer manufacturer = service.GetAntManufacturer(ManufacturerId).data;
//var recordId = Guid.NewGuid().ToString();
var ticks = RiderDatas.Last().Ticks;
var interruptRecord = new MapInterruptRecord
{
Id = recordId,
RouteId = CurrentRoute.RouteInstance.Id,
RouteName = CurrentRoute.RouteInstance.Name,
TotalDistance = CurrentRoute.RouteInstance.Distance,
UserId = BelongUserId,
RecordFileName = newFileName + ".txt",
Ftp = FTP,//FTP设置
IF = Math.Round(IF, 2),
Kj = RiderDatas.Sum(a => a._Power) / 1000,//消耗
Tss = Math.Round(TSS, 2),
EndDistance = EndDistance,
IsCompleted = IsCompleted,
//TrainingTime = TimeHelper.FormatSeconds(RiderDatas.Last().Ticks),//训练时间
NormalizedPower = Math.Floor(NP),//标准化功率
AveragePower = averagePower,//平均功率
MaxPower = RiderDatas.Max(a => a._Power),//最大功率
WeightKg = Math.Round(averagePower / App.CurrentUser.Weight, 2),
Weight = App.CurrentUser.Weight,
BicycleWeight = App.CurrentUser.BicycleWeight,
ContinueMark = ContinueMark,
ContinueIndex = ContinueIndex,
IsDelete = false,
MapCompetitionId = Competitionid,
ManufacturerName = ManufacturerName,//manufacturer == null ? "" : manufacturer.Name,
DeviceNumber = DeviceNumber,
IsRanking = IsNeedRanking,
CurrentRouteStartDistance = CurrentRouteStartDistance,
ManufacturerId = ManufacturerId,
AntModelId = AntModelId,
StartTime = StartTime,
CreateTime = EndTime, //StartTime.AddSeconds(ticks),
Ticks = ticks,
Mode = cyclingModel.ToString(),
Param = Newtonsoft.Json.JsonConvert.SerializeObject(selectParam),
GlobalCyclingId = 0,
Source = "",
};
//var range = new MapSpeedRange().GetSpeedRange(RiderDatas, CurrentRoute.RouteInstance.Distance);
interruptRecord.SpeedRange = null; //JsonConvert.SerializeObject(range);
double process = Math.Round((EndDistance - interruptRecord.CurrentRouteStartDistance) / CurrentRoute.RouteInstance.Distance, 2);
interruptRecord.Progress = process > 1 ? 1 : process;
var cadences = RiderDatas.Where(a => a._Cadence.HasValue && a._Cadence.Value > 0);
if (cadences.Any())
{
interruptRecord.AverageCadence = Math.Round(cadences.Average(a => a._Cadence.GetValueOrDefault(0)));
}
interruptRecord.MaxCadence = Math.Round(RiderDatas.Max(a => a._Cadence.GetValueOrDefault(0)));
interruptRecord.AverageHeartRate = Math.Round(RiderDatas.Average(a => a._HeartRate.GetValueOrDefault(0)));
interruptRecord.MaxHeartRate = RiderDatas.Max(a => a._HeartRate.GetValueOrDefault(0));
//service.CreateRecordCyclingData(interruptRecord);
//保存骑行记录txt
//var path = Helper.GetDataDir("MapWorkoutRecords" + "/" + interruptRecord.Id);
//var path = PFConstants.MapWorkoutRecordFolder + "/" + interruptRecord.Id;
var fname = path + "/" + newFileName + ".txt";
var files = new List<string>();
using (var fs = new FileInfo(fname).OpenWrite())
{
var stream = new StreamWriter(fs);
stream.BaseStream.Seek(0, SeekOrigin.End);
foreach (var item in RiderDatas)
{
stream.Write(item.Write() + "\r\n");
}
stream.Flush();
stream.Close();
files.Add(fname);
}
//图片
if (!string.IsNullOrEmpty(imageName))
{
files.Add(imageName);
}
//持久化序列化对象
var recordString = JsonConvert.SerializeObject(interruptRecord);
var recordFilePath = path + "/" + "record" + ".txt";
System.IO.File.WriteAllText(recordFilePath, recordString);
recordData.Add(interruptRecord, files);
Saved = true;
SaveDataAysnc(recordData, path);
}
/// <summary>
/// 保存数据
/// </summary>
/// <param name="base64Image"></param>
/// <returns></returns>
public void SaveDataAysnc(Dictionary<MapInterruptRecord, List<string>> data,string path)
{
if (data != null && data.Count > 0)
{
//var path = Helper.GetDataDir("MapWorkoutRecords");
Task.Run(() => {
var record = data.FirstOrDefault();
MapInterruptRecordApi service = new MapInterruptRecordApi();
var result = service.Add(record.Key, record.Value);
//删除文件
try
{
if (result.result && Directory.Exists(path))
{
Helper.DelectDir(path);
Saved = true;
}
}
catch (Exception e)
{
Debug.Log(e.Message);
}
});
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 11c5f863a5d0baa49b7b374090197f99
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
public class RideSetting
{
public double Sensitivity { set; get; }
public bool ShowOtherHead { set; get; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2bdb001023de8f942b52de4e72bc45e6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c7b3cc03af7b19e44b20d0b929a53d45
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
public abstract class BaseRider
{
//internal static MapWorkoutService service = new MapWorkoutService();
public abstract RiderType riderType { get; }
/// <summary>
/// 用户Id
/// </summary>
public int UserId { get; set; }
public string InMapId
{
get
{
return this.riderType.ToString() + "-" + UserId;
}
}
/// <summary>
/// 用户姓名
/// </summary>
public string NickName { get; set; }
/// <summary>
/// 微信头像
/// </summary>
public string WxHeadImg { get; set; }
/// <summary>
/// 最后骑行的距离
/// </summary>
public double EndDistance { get; set; }
/// <summary>
/// 是否是当前登陆人
/// </summary>
public bool IsSelf
{
get
{
return this.UserId == App.CurrentUser.Id;
}
}
/// <summary>
/// 圆形头像
/// </summary>
public string CircHeadImg
{
get
{
return "";
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9a318f90ef1c36742a0ffa27baa04c98
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,61 @@
using GeoJSON.Net.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model.RiderModels
{
public class OnlineRiderModel : BaseRider
{
public override RiderType riderType => RiderType.Online;
public double PreDistance { get; set; } = 0;
public double WeightKg { get; set; } = 0;
/// <summary>
///
/// </summary>
public GeographicPosition Point { get; set; }
public OutUser GetOutUser(double preDistance, double currentDistance, TurfHelper turfHelper, CyclingStateEnum cyclingState)
{
if (this.IsSelf)
{
var newRealUser = new OutUser()
{
NickName = this.NickName,
WxHeadImg = this.WxHeadImg,
UserId = this.UserId,
//targetData = targetData,
InMapId = this.InMapId,
PreDistance = preDistance,
NextDistance = currentDistance,
Point = turfHelper.Along(currentDistance),
};
if (cyclingState != CyclingStateEnum.Cycling)
{
newRealUser.NextDistance = preDistance;
}
return newRealUser;
}
else
{
var newRealUser = new OutUser()
{
NickName = this.NickName,
WxHeadImg = this.WxHeadImg,
UserId = this.UserId,
//targetData = targetData,
InMapId = this.InMapId,
PreDistance = this.PreDistance,
NextDistance = this.EndDistance,
Point = this.Point, //turfHelper.Along(this.EndDistance)
};
return newRealUser;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 83879fd24afab69418f97cb56eaebda7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,55 @@
using GeoJSON.Net.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model.RiderModels
{
/// <summary>
/// 骑行伴侣
/// </summary>
public class ReviewRiderModel : BaseRider
{
public override RiderType riderType => RiderType.Review;
public GeographicPosition Point { get; set; }
/// <summary>
/// 骑行记录数据
/// </summary>
public string[] record { get; set; }
public OutUser GetOutUser(int ticks, TurfHelper turfHelper)
{
var reviewer = this;
TargetData revierData = null;
if (ticks >= reviewer.record.Length)
{
revierData = TargetData.Read(reviewer.record[reviewer.record.Length - 1]);
}
else if (ticks > 0)
{
revierData = TargetData.Read(reviewer.record[ticks - 1]);
}
//(Ticks >= reviewer.record.Length ? TargetData.Read(reviewer.record[reviewer.record.Length - 1]) :
//TargetData.Read(reviewer.record[Ticks]));
var reivewPreDistance = ticks == 1 || ticks == 0 ? 0 :
(ticks >= reviewer.record.Length ? TargetData.Read(reviewer.record[reviewer.record.Length - 1])._Distance :
TargetData.Read(reviewer.record[ticks - 2])._Distance);
var result = new OutUser()
{
UserId = this.UserId,
//targetData = revierData,
InMapId = this.InMapId,
PreDistance = reivewPreDistance,
NextDistance = ticks == 0 ? 0 : revierData._Distance,
NickName = this.NickName,
WxHeadImg = this.WxHeadImg
};
result.Point = turfHelper.Along(result.NextDistance);
return result;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8d265479686613e418a745e888533ec5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+369
View File
@@ -0,0 +1,369 @@
using Assets.Scripts.Apis.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
public class Route
{
/// <summary>
/// 路线实例
/// </summary>
public MapRoute RouteInstance { get; private set; }
/// <summary>
/// 从服务端获取的Json数据
/// </summary>
public MapDataModel JsonData { get; set; }
/// <summary>
/// 当前路书的排行榜信息
/// </summary>
public List<MapRecordRanking> RecordRankings { get; set; }
private List<double[]> _Point = null;
/// <summary>
/// 点位信息
/// </summary>
public List<double[]> Point
{
get
{
if (_Point == null)
{
_Point = JsonData.List.Select(n => n.Point.Reverse().ToArray()).ToList();
}
return _Point;
}
}
private List<double> _Elevation { get; set; }
/// <summary>
/// 海拔信息
/// </summary>
public List<double> Elevation
{
get
{
if (_Elevation == null)
{
_Elevation = JsonData.List.Select(n => n.Elevation).ToList();
}
return _Elevation;
}
}
private List<double> _SlopeGrade { get; set; }
/// <summary>
/// 坡度信息
/// </summary>
public List<double> SlopeGrade
{
get
{
if (_SlopeGrade == null)
{
//_SlopeGrade = CalPatch();
_SlopeGrade = JsonData.List.Select(d => d.Grade).ToList();
}
return _SlopeGrade;
}
}
private List<double> _StepDistance { get; set; }
/// <summary>
/// 每两点的距离
/// </summary>
public List<double> StepDistance
{
get
{
if (_StepDistance == null)
{
_StepDistance = JsonData.List.Select(n => n.Distance).ToList();
}
return _StepDistance;
}
}
public double? _TotalDistance { get; set; }
public double TotalDistance
{
get
{
if (_TotalDistance == null)
{
_TotalDistance = GetTotalDistance();
}
return (double)_TotalDistance;
}
}
/// <summary>
/// 每一小步到起点的距离
/// </summary>
private List<double> _StepToStartDistance;
public List<double> StepToStartDistance
{
get
{
if (_StepToStartDistance == null)
{
_StepToStartDistance = GetStepToStartDistance();
}
return _StepToStartDistance;
}
}
public Route(MapDataModel data)
{
JsonData = data;
}
public Route(MapDataModel data, MapRoute mapRoute)
{
RouteInstance = mapRoute;
JsonData = data;
}
/// <summary>
/// km
/// </summary>
/// <returns></returns>
public double GetTotalDistance()
{
var total = 0d;
for (int i = 0; i < JsonData.List.Count - 1; i++)
{
var current = JsonData.List[i];
var next = JsonData.List[i + 1];
total += TurfHelper.GetDistances(new double[] { current.Point[1], current.Point[0] }, new double[] { next.Point[1], next.Point[0] });
}
return total / 1000;
}
/// <summary>
/// 根据下标获取海拔
/// </summary>
/// <returns></returns>
public double GetElevationByIndex(int index)
{
if (index > this.Elevation.Count)
{
return this.Elevation.Last();
}
else
{
return this.Elevation[index];
}
}
/// <summary>
/// 根据下标获取距离的小段
/// </summary>
/// <returns></returns>
public double GetDistanceStepByIndex(int index)
{
if (index > this.StepDistance.Count)
{
return this.StepDistance.Last();
}
else
{
return this.StepDistance[index];
}
}
/// <summary>
/// 根据索引获取坡度
/// </summary>
/// <param name="index">索引</param>
/// <param name="average">是否需要平均坡度</param>
/// <returns></returns>
public double GetPatchByIndex(int index, bool average, double endDistance = 0, double cacheDistance = 5)
{
double slop = 0;
if (average)
{
//每一小段的距离
double step = GetDistanceStepByIndex(index);
//每一段到起点的距离
double stepToStart = GetStepToStartDistanceByIndex(index);
//当前骑行距离与前一段的绝对值之差
double absoluteValue = step - (stepToStart - endDistance);
//绝对值之差是否大于多少米,如果大于则返回原始坡度,如果小于则返回平均坡度
if (absoluteValue < cacheDistance && cacheDistance < step)
{
if (index >= this.SlopeGrade.Count - 1)
{
double slope = this.SlopeGrade.Last();
//if (slope > 10)
//{
// slop = 10;
//}
//else if (slope < -10)
//{
// slop = -10;
//}
//else
{
slop = slope / 2;
}
}
else
{
double slope = this.SlopeGrade[index];
//if (slope > 10)
//{
// slop = 10;
//}
//else if (slope < -10)
//{
// slop = -10;
//}
//else
{
slop = slope / 2;
}
}
}
}
else
{
if (index >= this.SlopeGrade.Count - 1)
{
slop = this.SlopeGrade.Last();
}
else
{
slop = this.SlopeGrade[index];
}
}
//if (slop > 10)
//{
// return 10;
//}
//if (slop < -10)
//{
// return -10;
//}
return slop;
}
/// <summary>
/// 根据距离获取点位下标
/// </summary>
/// <returns></returns>
public int GetStepIndex(double distance)
{
distance *= 1000;//将距离转化为米
var totalDistance = 0D;
var index = 0;
foreach (var item in this.StepDistance)
{
totalDistance += item;
if (totalDistance > distance)
{
return index;
}
index++;
}
if (distance > this.StepDistance[this.StepDistance.Count - 1])
{
return this.StepDistance.Count - 1;
}
return 0;
}
/// <summary>
/// 通过索引获取当前到起点的距离(单位m)
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public double GetStepToStartDistanceByIndex(int index)
{
if (index >= this.StepToStartDistance.Count - 1)
{
return this.StepToStartDistance.Last();
}
else
{
return this.StepToStartDistance[index];
}
}
/// <summary>
/// 计算每一段路程的斜率
/// </summary>
private List<double> CalPatch()
{
if (this.Elevation != null)
{
List<double> grade = new List<double>();
for (int i = 0; i < this.Point.Count - 1; i++)
{
var a = this.Elevation[i + 1] - this.Elevation[i];
if (a == 0)
{
grade.Add(0);
continue;
}
//勾股定理
var c = this.StepDistance[i];//如果车停了下来,c为0
if (c == 0 && i > 0)
{
grade.Add(grade[grade.Count - 1]);
}
else
{
var b = Math.Sqrt(c * c - a * a);
if (b == 0)//如果b等于,这就是垂直的墙壁
{
grade.Add(grade[grade.Count - 1]);
}
else
{
grade.Add(a / b * 100);
}
}
}
//检是否有NaN的值
for (int i = 0; i < grade.Count; i++)
{
if (double.IsNaN(grade[i]) && i != 0)
{
grade[i] = grade[i - 1];
}
else if (double.IsNaN(grade[i]) && i == 0)
{
grade[i] = 0;
}
}
return grade;
}
return null;
}
/// <summary>
/// 获取每一段到起点的距离
/// </summary>
/// <returns></returns>
private List<double> GetStepToStartDistance()
{
if (StepDistance != null)
{
List<double> stepToStartDis = new List<double>();
double start = 0;
for (int i = 0; i < StepDistance.Count; i++)
{
start += StepDistance[i];
stepToStartDis.Add(start);
}
return stepToStartDis;
}
return null;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9b4a6fa5405752242a577299e27df510
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
public class SelectParamModel
{
/// <summary>
/// 在线用户ID,跟骑选的用户
/// </summary>
public int OnlineUserId { get; set; }
/// <summary>
/// 继续骑行的标志
/// </summary>
public string ContinueMark { get; set; }
/// <summary>
/// 当前第几次骑行
/// </summary>
public int? ContinueIndex { get; set; }
/// <summary>
/// 路线Id
/// </summary>
public int RouteId { get; set; }
/// <summary>
/// 赛事Id
/// </summary>
public int CompetitionId { get; set; }
/// <summary>
/// 最后一次骑行的距离
/// </summary>
public double EndDistance { get; set; }
/// <summary>
/// 排名信息Id,用于骑行回顾,多人
/// </summary>
public List<string> RankingsId { get; set; }
///// <summary>
///// 是否为全球骑行的继续骑行
///// </summary>
//public bool GlobalContinue { get; set; }
public int GlobalCyclingId { get; set; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fab2eae6e723baa46ad8c972556f38c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
/// <summary>
/// 指标数据
/// </summary>
public class TargetData
{
public double _Power = 0d;
public double _Speed = 0;
/// <summary>
/// km
/// </summary>
public double _Distance { get; set; } = 0D;
public double? _Cadence = 0;
public int? _HeartRate = 0;
public int Ticks = 0;
/// <summary>
/// 纬度
/// </summary>
public double _Lat { get; set; } = 0d;
/// <summary>
/// 经度
/// </summary>
public double _Lon { get; set; } = 0d;
public double _TotalClimb { get; set; } = 0d;
//public double _Bearing = 0d;
public TargetData Clone()
{
return (TargetData)MemberwiseClone();
}
public override string ToString()
{
return string.Format($"Ticks:{Ticks} Power:{_Power} Speed:{_Speed} Distance:{_Distance} Cadence:{_Cadence} HeartRate:{_HeartRate} Lat:{_Lat} Lon:{_Lon}");
}
public string Write()
{
return string.Format($"{ Ticks },{ _Power.ToString(CultureInfo.InvariantCulture) },{ _Speed.ToString(CultureInfo.InvariantCulture) },{ Math.Round(_Distance, 6).ToString(CultureInfo.InvariantCulture) },{ (_Cadence == null ? "" : _Cadence.Value.ToString(CultureInfo.InvariantCulture)) },{ (_HeartRate == null ? "null" : _HeartRate.Value.ToString(CultureInfo.InvariantCulture)) },{ Math.Round(_Lat, 6).ToString(CultureInfo.InvariantCulture) },{ Math.Round(_Lon, 6).ToString(CultureInfo.InvariantCulture) }");//,{_Bearing}
}
public static TargetData Read(string data)
{
string[] split = data.Split(',');
var target = new TargetData();
target.Ticks = Convert.ToInt32(split[0], CultureInfo.InvariantCulture); //int.Parse(split[0]);
target._Power = Convert.ToDouble(split[1], CultureInfo.InvariantCulture);
target._Speed = Convert.ToDouble(split[2], CultureInfo.InvariantCulture);// double.Parse(split[2]);
target._Distance = Convert.ToDouble(split[3], CultureInfo.InvariantCulture); //double.Parse(split[3]);
target._Cadence = Convert.ToDouble(split[4], CultureInfo.InvariantCulture); //double.Parse(split[4]);
if (!string.IsNullOrWhiteSpace(split[5]) && split[5] != "null")
{
target._HeartRate = Convert.ToInt32(split[5], CultureInfo.InvariantCulture); //int.Parse(split[5]);
}
if (split.Length > 6)
{
target._Lat = Convert.ToDouble(split[6], CultureInfo.InvariantCulture); //double.Parse(split[6]);
target._Lon = Convert.ToDouble(split[7], CultureInfo.InvariantCulture); //double.Parse(split[7]);
//target._Bearing = double.Parse(split[8]);
}
return target;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 79850d6cccee69445927e491750a500b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scenes.Ride.Scripts.Model
{
public class t_user
{
public int Id { get; set; }
public string Nickname { get; set; }
/// <summary>
/// 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
/// </summary>
public int Sex { get; set; }
public int Unit { get; set; }
public double Weight { get; set; }
public int FTP { get; set; }
public int WheelDiameter { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Pass { get; set; }
public string OtherPlatforms { get; set; }
public string Country { get; set; }
public string Province { get; set; }
public string City { get; set; }
public string Area { get; set; }
public string WxHeadImg { get; set; }
public DateTime LastLoginTime { get; set; }
/// <summary>
/// 自动暂停
/// </summary>
public bool AutoPause { get; set; }
/// <summary>
/// 最大心率
/// </summary>
public int MaxHeartRate { get; set; }
public bool CanEditRoom { get; set; }
/// <summary>
/// 自行车重
/// </summary>
public double BicycleWeight { get; set; }
public string Contact { get; set; }
public string ContactPhone { get; set; }
public string ContactAddress { get; set; }
/// <summary>
/// 阻力灵敏度
/// </summary>
public int Sensitivity { get; set; }
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0d977fd7941debf4b90f950a8fd3c0a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: