384 lines
13 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.Scenes.Ride.Scripts.Model;
using Assets.Scripts;
using Assets.Scripts.Apis.Models;
using System;
using System.Text;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
namespace Assets.Scenes.Ride.Scripts
{
public class Helper
{
public static string GetDataDir(string pathName)
{
var dirName = Application.dataPath + "/" + pathName;
if (!Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}
return dirName;
}
public static void DelectDir(string srcPath)
{
try
{
DirectoryInfo dir = new DirectoryInfo(srcPath);
FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //返回目录中所有文件和子目录
foreach (FileSystemInfo i in fileinfo)
{
if (i is DirectoryInfo) //判断是否文件夹
{
DirectoryInfo subdir = new DirectoryInfo(i.FullName);
subdir.Delete(true); //删除子目录和文件
}
else
{
File.Delete(i.FullName); //删除指定文件
}
}
//删除当前文件夹
Directory.Delete(srcPath);
}
catch (Exception e)
{
throw;
}
}
public static double AveragePower(IList<TargetData> list)
{
return Math.Floor(list.Where(p => p._Power > -1).Average(a => a._Power));
}
/// <summary>
/// 优化功率
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public static double GetNP(List<TargetData> list)
{
var _npinterval = new List<double>();
var count = list.Count / 28;
for (int i = 0; i < count; i++)
{
var list1 = list.Skip(i * 28).Take(28);
double avgpower = Math.Pow((int)list1.Where(d => d._Power > -1).Average(a => a._Power), 4);
_npinterval.Add(avgpower);
}
double n = 0.25;
if (_npinterval.Count == 0) return 0;
return Math.Pow((_npinterval.Sum() / _npinterval.Count), n);
}
/// <summary>
/// 获取Ftp
/// </summary>
/// <returns></returns>
public static int GetFtp()
{
return App.CurrentUser.FTP;
}
public static string FormatTicks(int seconds)
{
int h, m, s;
h = seconds / 3600;
m = (seconds - (3600 * h)) / 60;
s = seconds - (3600 * h + 60 * m);
string H, M, S;
H = M = S = string.Empty;
if (h < 10)
H = "0" + h;
else
H = h.ToString();
if (m < 10)
M = "0" + m;
else
M = m.ToString();
if (s < 10)
S = "0" + s;
else
S = s.ToString();
return $"{H}:{M}:{S}";
}
/// <summary>
/// 计算速度
/// 参考 http://bikecalculator.com/index.html
/// </summary>
/// <param name="elevationv">海拔</param>
/// <param name="gradev">坡度%</param>
/// <param name="powerv">功率</param>
/// <param name="rweightv">体重</param>
/// <param name="bweightv">自行车重量</param>
/// <returns>km/h</returns>
public static double CalculateSpeed(double elevationv, double gradev, double powerv, double rweightv, double bweightv)
{
if (powerv < 0)
{
return 0;
}
if (gradev < -10)
{
gradev = -10;
}
var tireValues = new double[] { 0.005, 0.004, 0.012 };
var aeroValues = new double[] { 0.388, 0.445, 0.420, 0.300, 0.233, 0.200 };
var units = 0;
//温度
var temperaturev = 25;
//海拔
//var elevationv = 100;
//坡度
//var gradev = 6 * 0.01 * -1;
//风转换成m/s
var headwindv = 0 / 3.6;
var frontalArea = aeroValues[0];
var transv = 0.95; // no one knows what this is, so why bother presenting a choice?
var rollingRes = tireValues[0];
//应该是空气密度
var density = (1.293 - 0.00426 * temperaturev) * Math.Exp(-elevationv / 7000.0);
//全空气阻力参数
var a2 = 0.5 * frontalArea * density; // full air resistance parameter
var twt = 9.8 * (rweightv + bweightv); // total weight in newtons
var tres = twt * (gradev * 0.01 + rollingRes); // gravity and rolling resistance
//var powerv = 195;
var v = Newton(a2, headwindv, tres, transv, powerv) * 3.6;// convert to km/h
//Trace.WriteLine($"速度为:{ v }");
var t1 = makeDecimal2(v * (units == 1 ? 1.609 : 1.0));
return double.Parse(t1, CultureInfo.InvariantCulture);
}
private static double Newton(double aero, double hw, double tr, double tran, double p)
{
var vel = 20D;
var MAX = 10;
var TOL = 0.05;
for (int i = 0; i < MAX; i++)
{
var tv = vel + hw;
var aeroEff = (tv > 0.0) ? aero : -aero; // wind in face, must reverse effect
var f = vel * (aeroEff * tv * tv + tr) - tran * p; // the function
var fp = aeroEff * (3.0 * vel + hw) * tv + tr; // the derivative
var vNew = vel - f / fp;
if (Math.Abs(vNew - vel) < TOL)
{
return vNew; // success
}
vel = vNew;
}
return 0.0;
}
private static string makeDecimal2(double value)
{
if (value != 0)
{
var x = Math.Round(value * 100);
int d;
if (x < 100)
{
d = 0;
}
else
{
d = Convert.ToInt32(Math.Floor(x / 100), CultureInfo.InvariantCulture);
};
var c = x % 100;
var g = (c >= 10) ? "" : "0";
return "" + d + "." + g + c;
}
return value.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Decode google style polyline coordinates.
/// </summary>
/// <param name="encodedPoints"></param>
/// <returns></returns>
private static IEnumerable<CoordinateEntity> Decode(string encodedPoints)
{
if (string.IsNullOrEmpty(encodedPoints))
throw new ArgumentNullException("encodedPoints");
char[] polylineChars = encodedPoints.ToCharArray();
int index = 0;
int currentLat = 0;
int currentLng = 0;
int next5bits;
int sum;
int shifter;
while (index < polylineChars.Length)
{
// calculate next latitude
sum = 0;
shifter = 0;
do
{
next5bits = (int)polylineChars[index++] - 63;
sum |= (next5bits & 31) << shifter;
shifter += 5;
} while (next5bits >= 32 && index < polylineChars.Length);
if (index >= polylineChars.Length)
break;
currentLat += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);
//calculate next longitude
sum = 0;
shifter = 0;
do
{
next5bits = (int)polylineChars[index++] - 63;
sum |= (next5bits & 31) << shifter;
shifter += 5;
} while (next5bits >= 32 && index < polylineChars.Length);
if (index >= polylineChars.Length && next5bits >= 32)
break;
currentLng += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);
yield return new CoordinateEntity
{
Latitude = Convert.ToDouble(currentLat) / 1E5,
Longitude = Convert.ToDouble(currentLng) / 1E5
};
}
}
/// <summary>
/// Encode it
/// </summary>
/// <param name="points"></param>
/// <returns></returns>
private static string Encode(IEnumerable<CoordinateEntity> points)
{
var str = new StringBuilder();
var encodeDiff = (Action<int>)(diff =>
{
int shifted = diff << 1;
if (diff < 0)
shifted = ~shifted;
int rem = shifted;
while (rem >= 0x20)
{
str.Append((char)((0x20 | (rem & 0x1f)) + 63));
rem >>= 5;
}
str.Append((char)(rem + 63));
});
int lastLat = 0;
int lastLng = 0;
foreach (var point in points)
{
int lat = (int)Math.Round(point.Latitude * 1E5);
int lng = (int)Math.Round(point.Longitude * 1E5);
encodeDiff(lat - lastLat);
encodeDiff(lng - lastLng);
lastLat = lat;
lastLng = lng;
}
return str.ToString();
}
public struct CoordinateEntity
{
public double Latitude;
public double Longitude;
public CoordinateEntity(double x, double y) { this.Latitude = x; this.Longitude = y; }
}
public static async Task<byte[]> DownloadImgAsync(List<MapDataModel.Item> list)
{
var result = new List<CoordinateEntity>();
var count = list.Count;
int segement = (int)Math.Ceiling((double)(count / 1000D));
for (int i = 0; i <= count - 1; i++)
{
if (i % segement == 0)
{
result.Add(new CoordinateEntity
{
Latitude = Math.Round(list[i].Point[0], 6),
Longitude = Math.Round(list[i].Point[1], 6),
});
}
}
return await DownloadImgAsync(result);
}
public static async Task<byte[]> DownloadImgAsync(List<CoordinateEntity> list)
{
var polyline = Encode(list);
var encodeline = UnityWebRequest.EscapeURL(polyline); //HttpUtility.UrlEncode(polyline);
//获取封面图片
var url = $"https://api.mapbox.com/styles/v1/juzetest/ckmkdjwsa1nvt17nr1ps4fqgs/static/path-4+fff-1({encodeline})/auto/1280x1280?access_token={App.MapBoxAccessToken}";
HttpClient c = new HttpClient();
var response = await c.GetAsync(url);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
byte[] content = await response.Content.ReadAsByteArrayAsync();
return content;
}
return null;
}
public static string GetMapboxApiUrl(List<MapDataModel.Item> list)
{
var result = new List<CoordinateEntity>();
var count = list.Count;
int segement = (int)Math.Ceiling((double)(count / 1000D));
for (int i = 0; i <= count - 1; i++)
{
if (i % segement == 0)
{
result.Add(new CoordinateEntity
{
Latitude = Math.Round(list[i].Point[0], 6),
Longitude = Math.Round(list[i].Point[1], 6),
});
}
}
var polyline = Encode(result);
var encodeline = UnityWebRequest.EscapeURL(polyline); //HttpUtility.UrlEncode(polyline);
//获取封面图片
var url = $"https://api.mapbox.com/styles/v1/juzetest/ckmkdjwsa1nvt17nr1ps4fqgs/static/path-4+fff-1({encodeline})/auto/1280x768?access_token={App.MapBoxAccessToken}&padding=200&pitch=30";
return url;
}
}
}