370 lines
11 KiB
C#
370 lines
11 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|