370 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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