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