370 lines
11 KiB
C#
Raw Normal View History

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;
}
}
}