骑行界面调整,底层逻辑细化
This commit is contained in:
1 parent
d5133ee7b0
commit
9a7830f46a
168 files changed
+19164
-393
No files matched your search
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e8389fe2e69de14ba5b9b48f580dd81
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,108 @@
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 骑行函数(如果此方法不满足,可以在子类中重写此方法)
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
protected virtual void Run(TargetData targetData)
|
||||
{
|
||||
//将当前用户的位置发送到udf服务
|
||||
SendUserPositionToServer();
|
||||
|
||||
}
|
||||
|
||||
/// <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);
|
||||
}
|
||||
else
|
||||
{
|
||||
MapUDPService.Send(route.RouteInstance.Id, recorderData.BelongUserId, route.Point.First().Reverse().ToArray(), competitionId: recorderData.Competitionid);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89d63056e2fd43e41b30635a0036ba33
|
||||
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,536 @@
|
||||
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
|
||||
{
|
||||
/// <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 string Name { 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 == PubCommData.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 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 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 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 static ReceiveMsgModel Parse(string str)
|
||||
{
|
||||
var list = str.Split(',');
|
||||
if (list.Length != 10)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return new ReceiveMsgModel
|
||||
{
|
||||
RouteId = Convert.ToInt32(list[0]),
|
||||
MemberId = Convert.ToInt32(list[1]),
|
||||
Point = new double[] { double.Parse(list[2].Split(':')[0]), double.Parse(list[2].Split(':')[1]) },
|
||||
IsCompleted = ToBoolean(list[3]),
|
||||
//exit = ToBoolean(list[4]),
|
||||
Speed = Convert.ToDouble(list[4]),
|
||||
PreDistance = Convert.ToDouble(list[5]),
|
||||
EndDistance = Convert.ToDouble(list[6]),
|
||||
WeightKg = Convert.ToDouble(list[7]),
|
||||
Competitionid = Convert.ToInt32(list[8]),
|
||||
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 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 == PubCommData.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 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,216 @@
|
||||
using Assets.Scripts.Apis;
|
||||
using Assets.Scripts.Apis.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scenes.Ride.Scripts.Model
|
||||
{
|
||||
public class RecorderDataModel
|
||||
{
|
||||
//private readonly MapWorkoutService service = new MapWorkoutService();
|
||||
|
||||
public t_user 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 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; }
|
||||
/// <summary>
|
||||
/// 是否已经保存成功
|
||||
/// </summary>
|
||||
public bool Saved { get; set; }
|
||||
|
||||
public int GlobalCyclingId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 保存数据
|
||||
/// </summary>
|
||||
/// <param name="base64Image"></param>
|
||||
/// <returns></returns>
|
||||
public JsonResult<AddMapRecordResultModel> SaveData(CyclingModel cyclingModel, SelectParamModel selectParam, DateTime createTime, string base64Image = "")
|
||||
{
|
||||
if (RiderDatas.Count <= 0)
|
||||
{
|
||||
return new JsonResult<AddMapRecordResultModel> { result = true };
|
||||
}
|
||||
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);
|
||||
MapInterruptRecordApi service = new MapInterruptRecordApi();
|
||||
//AntManufacturer manufacturer = service.GetAntManufacturer(ManufacturerId);
|
||||
var recordId = Guid.NewGuid().ToString();
|
||||
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 / PubCommData.CurrentUser.Weight, 2),
|
||||
Weight = PubCommData.CurrentUser.Weight,
|
||||
BicycleWeight = PubCommData.CurrentUser.BicycleWeight,
|
||||
ContinueMark = ContinueMark,
|
||||
ContinueIndex = ContinueIndex,
|
||||
IsDelete = false,
|
||||
MapCompetitionId = Competitionid,
|
||||
ManufacturerName = "TODO",//manufacturer == null ? "" : manufacturer.Name,
|
||||
DeviceNumber = DeviceNumber,
|
||||
IsRanking = IsNeedRanking,
|
||||
CurrentRouteStartDistance = CurrentRouteStartDistance,
|
||||
ManufacturerId = ManufacturerId,
|
||||
AntModelId = AntModelId,
|
||||
StartTime = StartTime,
|
||||
CreateTime = createTime,
|
||||
Ticks = RiderDatas.Last().Ticks,
|
||||
Mode = cyclingModel.ToString(),
|
||||
Param = Newtonsoft.Json.JsonConvert.SerializeObject(selectParam),
|
||||
GlobalCyclingId = selectParam.GlobalCyclingId
|
||||
};
|
||||
//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);
|
||||
var path = Helper.GetDataDire("MapWorkoutRecords");
|
||||
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);
|
||||
}
|
||||
//TODO 截图
|
||||
if (!string.IsNullOrEmpty(base64Image))
|
||||
{
|
||||
//var imageName = path + "/" + Guid.NewGuid().ToString() + ".png";
|
||||
//base64Image = base64Image.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "").Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", ""); ;
|
||||
//byte[] image = Convert.FromBase64String(base64Image);
|
||||
//using (MemoryStream ms = new MemoryStream(image))
|
||||
//using (Image img = Image.FromStream(ms))
|
||||
//{
|
||||
// img.Save(imageName, System.Drawing.Imaging.ImageFormat.Png);
|
||||
// //img.Dispose();
|
||||
//}
|
||||
//files.Add(imageName);
|
||||
}
|
||||
var result = service.Add(interruptRecord, files);
|
||||
return new JsonResult<AddMapRecordResultModel> { result = result.result, errMsg = result.errMsg, data = result.data };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11c5f863a5d0baa49b7b374090197f99
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb74a9f48e6075b4098a071b7c41755b
|
||||
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 == PubCommData.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,60 @@
|
||||
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;
|
||||
/// <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:
|
||||
@@ -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,72 @@
|
||||
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 _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 = int.Parse(split[0]);
|
||||
target._Power = double.Parse(split[1]);
|
||||
target._Speed = double.Parse(split[2]);
|
||||
target._Distance = double.Parse(split[3]);
|
||||
target._Cadence = double.Parse(split[4]);
|
||||
if (!string.IsNullOrWhiteSpace(split[5]) && split[5] != "null")
|
||||
{
|
||||
target._HeartRate = int.Parse(split[5]);
|
||||
}
|
||||
if (split.Length > 6)
|
||||
{
|
||||
target._Lat = double.Parse(split[6]);
|
||||
target._Lon = 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:
|
||||
Reference in new issue
Block a user