using GpsCardGatewayPosition.Common.Helper;
using GpsCardGatewayPosition.Model.Cache;
using GpsCardGatewayPosition.Model.Config;
using GpsCardGatewayPosition.Model.Enum;
using GpsCardGatewayPosition.Service.Biz.Iot;
using GpsCardGatewayPosition.Service.Biz.Location.Dto.Wayz;
using GpsCardGatewayPosition.Service.Cache;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using static GpsCardGatewayPosition.Service.Biz.Location.Dto.Wayz.WayzResponseInfo;
namespace GpsCardGatewayPosition.Service.Biz.Location
{
public class WayzService
{
private const string CACHE_KEY_WAYZ = "Wayz_";
///
/// 兼容高德缓存
///
// private const string CACHE_KEY_GAODE = "Gaode_";
private const string CACHE_HASH_KEY_LOCATION_SINGLE_WIFI = "#LOCATION_WIFI_INFO_HASH";
public static readonly string[] WAYZ_POI_TYPES =
{ "Airport", "Campus", "Education",
"Finance", "Food", "Government",
"Health", "Hospital", "Hotel",
"Institute", "Mall", "Hotel",
"Market", "Office", "Port",
"Residential", "Scenic", "Station" ,
"Tower", "Venue","Entity"};
private readonly DeviceCacheManager _deviceCacheMgr;
private readonly AppsettingsConfig _configAppSettings;
private readonly WayzServicesConfig _configWayzServices;
private readonly HttpHelper _httpHelper;
private readonly DeviceIotOpenService _serviceDeviceIot;
private readonly ILogger _logger;
private readonly IMemoryCache _localCache;
private static object _syncLocker = new object();
private MD5 _md5;
private int _idx = 0; //轮询索引
private int _count = 1; //高德服务接口key组数量
private int WayzDurationSeconds { get; }
public WayzService(DeviceCacheManager deviceCacheMgr,
IOptions optConfigAppSettings, IOptions optConfigWayzServices,
HttpHelper httpHelper, DeviceIotOpenService serviceDeviceIot, ILogger logger)
{
_deviceCacheMgr = deviceCacheMgr;
_configAppSettings = optConfigAppSettings.Value;
_httpHelper = httpHelper;
_serviceDeviceIot = serviceDeviceIot;
_logger = logger;
_md5 = MD5.Create();
_localCache = new MemoryCache(new MemoryCacheOptions());
//维智接口
_configWayzServices = optConfigWayzServices.Value;
_configWayzServices.Items = _configWayzServices.Items.Where(e => e.EnableConfig == true).ToList();
_count = _configWayzServices.Items.Count;
WayzDurationSeconds = _configAppSettings.WayzDurationSeconds;
}
///
/// wifi解析
///
///
///
///
public async Task GetWayzWifiAddressAsync(string serialno, WayzWifiRequest model)
{
int wifiCount = model.Location.Wifis.Count;
string wifiMacs = string.Empty;
for (int i = 0; i < wifiCount; i++)
{
wifiMacs += model.Location.Wifis[i].MacAddress;
}
var hashModel = new
{
wifiMacs
};
//model.Asset.Id = serialno;
//var hash = ComputeHash(model);
var hash = ComputeHash(hashModel);
var serviceResult = new GetWayzPositionServiceResult
{
HashParam = hash
};
var cacheKey = CACHE_KEY_WAYZ + $"{hash}";
lock (_syncLocker)
{
var value = _localCache.Get(cacheKey);
if (value != null)
{
_logger.LogWarning($"击中本地缓存 {nameof(_localCache)} 维智地址解析异常(404 position not found),GetWayzWifiAddress wifi解析失败, 参数: {JsonConvert.SerializeObject(value)}");
serviceResult.Flag = false;
serviceResult.CanRetry = false;
return serviceResult;
}
}
// var info = await RedisHelper.GetAsync(cacheKey).ConfigureAwait(false);
var info = await RedisHelperWayz.GetAsync(cacheKey).ConfigureAwait(false);
//var cacheKey = CACHE_KEY_GAODE + $"{hash}";
//var info = await RedisHelper.GetAsync(cacheKey).ConfigureAwait(false);
var wayzOriginalInputLog = string.Empty;
var wayzOriginalOutputLog = string.Empty;
string result;
try
{
//优先判断查询参数是否有效
if (
model.Location.Wifis.Count == 1
&&
model.Location.Wifis[0].MacAddress.Equals("00:00:00:00:00:00")
)
//if (
// model.Location.Wifis.Count == 1
// ||
// model.Location.Wifis[0].MacAddress.Equals("00:00:00:00:00:00")
// )
{
_logger.LogWarning($"GetWayzWifiAddressAsync wifi解析失败, 定位参数无效: {JsonConvert.SerializeObject(model)}");
serviceResult.CanRetry = false;
return serviceResult;
}
// 判断单wifi
else if (
model.Location.Wifis.Count == 1
&&
!model.Location.Wifis[0].MacAddress.Equals("00:00:00:00:00:00")
)
{
// 通过读取 redis 获取地址
var infoDb7SingleWifi = await RedisHelperDb7.HGetAsync(CACHE_HASH_KEY_LOCATION_SINGLE_WIFI, model.Location.Wifis[0].MacAddress).ConfigureAwait(false);
if (infoDb7SingleWifi == null)
{
serviceResult.CanRetry = false;
return serviceResult;
}
_logger.LogInformation($"单 wifi 定位,从 Redis Db7 中读取 KEY: {CACHE_HASH_KEY_LOCATION_SINGLE_WIFI}, FIELD: {model.Location.Wifis[0].MacAddress}");
// infoDb7SingleWifi 的 olat和olng 是 经纬度
var lat = infoDb7SingleWifi.Latitude;//info.Location.Position.Point.Latitude; //
var lng = infoDb7SingleWifi.Longitude;//info.Location.Position.Point.Longitude;
// 地球系 --> 火星系
GeoConvert.Transform(lat, lng, out double mgLat, out double mgLon);
GeoConvert.G2Gps((double)mgLat, (double)mgLon, out double gLat, out double gLng);
serviceResult.Accuracy = 50;
serviceResult.AdCode = "";
serviceResult.Flag = true;
serviceResult.Lat = (decimal)gLat;
serviceResult.Lon = (decimal)gLng;
serviceResult.Poi = "";
serviceResult.Province = infoDb7SingleWifi.Province;
serviceResult.City = infoDb7SingleWifi.City;
serviceResult.CityCode = infoDb7SingleWifi.CityCode;
serviceResult.District = infoDb7SingleWifi.District;
serviceResult.Address = infoDb7SingleWifi.Address;
serviceResult.FullAddress = string.Format("{0}|{1}", "SingleWifi", infoDb7SingleWifi.Address);
return serviceResult;
}
_idx = (_idx + 1) % _count;
string accessKey = _configWayzServices.Items[_idx].AccessKey; //智能硬件解析接口key:wifi解析,lbs解析
string positionBaseUrl = _configWayzServices.Items[_idx].PositionUrl; //高德wifi,lbs解析地址
if (info == null
|| info.Location.Address == null
|| string.IsNullOrEmpty(info.Location.Address.Name)
|| info.Location.Place == null
|| string.IsNullOrEmpty(info.Location.Place.Name)
)
// debug
// if (info = null)
{
var url = string.Format(positionBaseUrl, accessKey);
// result = await _httpHelper.HttpToGetAsync(url).ConfigureAwait(false);
//result = await _httpHelper.HttpToPostAsync(url, model).ConfigureAwait(false);
//_logger.LogInformation($"{nameof(GetWayzWifiAddressAsync)}维智请求原始报文: {JsonConvert.SerializeObject(model)}");
//result = await _httpHelper.HttpToPostAsync(url, model).ConfigureAwait(false);
//_logger.LogInformation($"{nameof(GetWayzWifiAddressAsync)}维智返回原始报文: {result}");
wayzOriginalInputLog = $"{nameof(GetWayzWifiAddressAsync)}维智请求原始报文: {JsonConvert.SerializeObject(model)}";
_logger.LogInformation(wayzOriginalInputLog);
result = await _httpHelper.HttpToPostAsync(url, model).ConfigureAwait(false);
var resultText = result.Length >= 2000 ? result.Substring(0, 2000) : result;
wayzOriginalOutputLog = $"{nameof(GetWayzWifiAddressAsync)}维智返回原始报文: {resultText}";
_logger.LogInformation(wayzOriginalOutputLog);
if (!string.IsNullOrWhiteSpace(result))
{
info = JsonConvert.DeserializeObject(result);
// 返回原始相应的数据
// serviceResult.OriginalResponse = result;
//if (info != null && info.Status + "" == "1") RedisHelper.SetAsync(cacheKey, info, WayzDurationSeconds);
//if (info != null) RedisHelper.SetAsync(cacheKey, info, WayzDurationSeconds);
Random random = new Random(); // 随机1-2天
if (info != null) await RedisHelperWayz.SetAsync(cacheKey, info, random.Next(7200, 14400));
}
// 没有返回结果,使用本地缓存记录
else
{
_localCache.Set(cacheKey, model, DateTimeOffset.Now.AddMinutes(120));
_logger.LogInformation($"本地缓存 {nameof(_localCache)} 储存维智Wifi地址解析异常(404 position not found),参数: {JsonConvert.SerializeObject(model)}");
}
}
else _logger.LogInformation($"{nameof(GetWayzWifiAddressAsync)}维智Wifi请求击中缓存 {cacheKey}|{JsonConvert.SerializeObject(model.Location.Wifis)}");
//if (info == null || info.Result == null || info.Info + "" != "OK" || info.Status + "" != "1")
if (info == null)
{
serviceResult.Flag = false;
}
else
{
int contextCont = info.Location.Address.Context.Count;
//if (info.Location.Address.Context.Count > 0)
if (contextCont > 0)
{
// 解析地址
int radius;
var accuracy = info.Location.Position.Accuracy.ToString();
_logger.LogInformation($"wayz wifi精度:{accuracy}");
radius = int.TryParse(accuracy, out radius) && radius > 50 ? radius : 50;
// 经纬度
var loc = string.Format("{0},{1}", info.Location.Position.Point.Longitude, info.Location.Position.Point.Latitude) + "";
var poi = info.Location.Place == null ? string.Empty : info.Location.Place.Name;
var adCode = "";
var lat = info.Location.Position.Point.Latitude;
var lng = info.Location.Position.Point.Longitude;
double gLat, gLng;
GeoConvert.G2Gps((double)lat, (double)lng, out gLat, out gLng);
serviceResult.Accuracy = radius;
serviceResult.AdCode = adCode;
serviceResult.Flag = true;
serviceResult.Lat = (decimal)gLat;
serviceResult.Lon = (decimal)gLng;
serviceResult.Poi = poi;
//地址解析
string county = string.Empty;
string province = string.Empty;
string city = string.Empty;
string district = string.Empty;
string addr = string.Empty;
/**
info.Location.Address.Context.ForEach((item) =>
{
switch (item.Type)
{
case "Country":
county = item.Name;
break;
case "Province":
province = item.Name;
break;
case "City":
city = item.Name;
adCode = item.Code;
break;
case "District":
district = item.Name;
break;
default:
addr += item.Name;
break;
}
});
*/
for (int i = 0; i < contextCont; i++)
{
switch (info.Location.Address.Context[i].Type)
{
case "Country":
county = info.Location.Address.Context[i].Name;
break;
case "Province":
province = info.Location.Address.Context[i].Name;
break;
case "City":
city = info.Location.Address.Context[i].Name;
adCode = info.Location.Address.Context[i].Code;
break;
case "District":
district = info.Location.Address.Context[i].Name;
break;
default:
addr += info.Location.Address.Context[i].Name;
break;
}
}
// 判断poi是否在分配中显示
// addr = WAYZ_POI_TYPES.Contains(info.Location.Place.Type)?addr+info.Location.Place.Name:addr;
// addr += info.Location.Place == null ? string.Empty : info.Location.Place.Name;//info.Location.Place.Name; // 开放poi
addr += GetFinalPlace(info);
serviceResult.Province = province;
serviceResult.City = city;
serviceResult.CityCode = adCode;
serviceResult.AdCode = adCode;
serviceResult.District = district;
serviceResult.Address = addr;
serviceResult.FullAddress = string.Format("{0}|{1}", info.Location.Place == null ? string.Empty : info.Location.Place.Type, info.Location.Address.Name);
return serviceResult;
}
else
{
serviceResult.Flag = false;
}
}
if (!serviceResult.Flag)
{
_logger.LogWarning($"维智地址解析异常,GetWayzWifiAddressAsync wifi解析失败, 参数: {JsonConvert.SerializeObject(model)}| \n{wayzOriginalInputLog}| \n{wayzOriginalOutputLog}");
}
}
catch (Exception ex)
{
serviceResult.Flag = false;
_logger.LogError($"维智地址解析异常,GetWayzWifiAddressAsync wifi解析异常, 参数: {JsonConvert.SerializeObject(model)}| \n{wayzOriginalInputLog}| \n{wayzOriginalOutputLog}| \n {ex.Message}, {ex.StackTrace}");
}
return serviceResult;
}
///
/// lbs解析
///
///
///
///
public async Task GetWayzLbsAddressAsync(string serialno, WayzLbsRequest model)
{
/**
* CellId = int.Parse(bts[3]),
//RadioType = "lte",
MobileCountryCode = int.Parse(bts[0]),
MobileNetworkCode = int.Parse(bts[1]),
LocationAreaCode = int.Parse(bts[2]),
*/
int lbsCount = model.Location.Cellulars.Count;
string lbsBts = model.Location.Cellulars[0].MobileCountryCode.ToString()
+ model.Location.Cellulars[0].MobileCountryCode.ToString()
+ model.Location.Cellulars[0].LocationAreaCode.ToString()
+ model.Location.Cellulars[0].CellId.ToString()
;
//for (int i = 0; i < lbsCount; i++)
//{
// lbsBts += model.Location.Cellulars[i].MobileCountryCode.;
//}
var wayzOriginalInputLog = string.Empty;
var wayzOriginalOutputLog = string.Empty;
var hashModel = new
{
lbsBts
//LBSBts = model.Location.Cellulars
};
var hash = ComputeHash(hashModel);
// model.Asset.Id = serialno;
// var hash = ComputeHash(model);
var serviceResult = new GetWayzPositionServiceResult
{
HashParam = hash
};
var cacheKey = CACHE_KEY_WAYZ + $"{hash}";
// var info = await RedisHelper.GetAsync(cacheKey).ConfigureAwait(false);
lock (_syncLocker)
{
var value = _localCache.Get(cacheKey);
if (value != null)
{
_logger.LogWarning($"击中本地缓存 {nameof(_localCache)} 维智地址解析异常(404 position not found),GetWayzLbsAddress lbs解析失败, 参数: {JsonConvert.SerializeObject(value)}");
serviceResult.Flag = false;
serviceResult.CanRetry = false;
return serviceResult;
}
}
var info = await RedisHelperWayz.GetAsync(cacheKey).ConfigureAwait(false);
string result;
try
{
_idx = (_idx + 1) % _count;
string accessKey = _configWayzServices.Items[_idx].AccessKey;
string positionBaseUrl = _configWayzServices.Items[_idx].PositionUrl;
if (info == null
|| info.Location.Address == null
|| string.IsNullOrEmpty(info.Location.Address.Name)
|| info.Location.Place == null
|| string.IsNullOrEmpty(info.Location.Place.Name)
)
{
var url = string.Format(positionBaseUrl, accessKey);
url += "&poi_search_radius=500"; // LBS 要 500 米的 poi 半径
// result = await _httpHelper.HttpToGetAsync(url).ConfigureAwait(false);
//result = await _httpHelper.HttpToPostAsync(url, model).ConfigureAwait(false);
//_logger.LogInformation($"{nameof(GetWayzLbsAddressAsync)}维智请求原始报文: {JsonConvert.SerializeObject(model)}");
//result = await _httpHelper.HttpToPostAsync(url, model).ConfigureAwait(false);
//_logger.LogInformation($"{nameof(GetWayzLbsAddressAsync)}维智返回原始报文: {result}");
wayzOriginalInputLog = $"{nameof(GetWayzLbsAddressAsync)}维智请求原始报文: {JsonConvert.SerializeObject(model)}";
_logger.LogInformation(wayzOriginalInputLog);
result = await _httpHelper.HttpToPostAsync(url, model).ConfigureAwait(false);
var resultText = result.Length >= 2000 ? result.Substring(0, 2000) + "..." : result;
wayzOriginalOutputLog = $"{nameof(GetWayzLbsAddressAsync)}维智返回原始报文: {resultText}";
_logger.LogInformation(wayzOriginalOutputLog);
if (!string.IsNullOrWhiteSpace(result))
{
info = JsonConvert.DeserializeObject(result);
// 返回原始相应的数据
// serviceResult.OriginalResponse = result;
//if (info != null && info.Status + "" == "1") RedisHelper.SetAsync(cacheKey, info, WayzDurationSeconds);
//if (info != null) RedisHelper.SetAsync(cacheKey, info, WayzDurationSeconds);
Random random = new Random(); // 随机1-2天
if (info != null) await RedisHelperWayz.SetAsync(cacheKey, info, random.Next(7200, 14400));
}
// 没有返回结果,使用本地缓存记录
else
{
_localCache.Set(cacheKey, model, DateTimeOffset.Now.AddMinutes(120));
_logger.LogInformation($"本地缓存 {nameof(_localCache)} 储存维智lbs地址解析异常(404 position not found),参数: {JsonConvert.SerializeObject(model)}");
}
}
else _logger.LogInformation($"{nameof(GetWayzLbsAddressAsync)}维智LBS请求击中缓存 {cacheKey}|{JsonConvert.SerializeObject(model.Location.Cellulars)}");
if (info == null)
{
serviceResult.Flag = false;
}
else
{
int contextCont = info.Location.Address.Context.Count;
if (contextCont > 0)
{
// 解析地址
int radius;
var accuracy = info.Location.Position.Accuracy.ToString();
_logger.LogInformation($"wayz lbs精度:{accuracy}");
radius = int.TryParse(accuracy, out radius) && radius > 500 ? radius : 500;
// 经纬度
var loc = string.Format("{0},{1}", info.Location.Position.Point.Longitude, info.Location.Position.Point.Latitude) + "";
var poi = info.Location.Place == null ? string.Empty : info.Location.Place.Name;
var adCode = "";
var lat = info.Location.Position.Point.Latitude;
var lng = info.Location.Position.Point.Longitude;
double gLat, gLng;
GeoConvert.G2Gps((double)lat, (double)lng, out gLat, out gLng);
serviceResult.Accuracy = radius;
// serviceResult.AdCode = adCode;
serviceResult.Flag = true;
serviceResult.Lat = (decimal)gLat;
serviceResult.Lon = (decimal)gLng;
serviceResult.Poi = poi;
// 地址解析
string county = string.Empty;
string province = string.Empty;
string city = string.Empty;
string district = string.Empty;
string addr = string.Empty;
/**
info.Location.Address.Context.ForEach((item) =>
{
switch (item.Type)
{
case "Country":
county = item.Name;
break;
case "Province":
province = item.Name;
break;
case "City":
city = item.Name;
adCode = item.Code;
break;
case "District":
district = item.Name;
break;
default:
addr += item.Name;
break;
}
});
*/
//int contextCont = info.Location.Address.Context.Count;
for (int i = 0; i < contextCont; i++)
{
switch (info.Location.Address.Context[i].Type)
{
case "Country":
county = info.Location.Address.Context[i].Name;
break;
case "Province":
province = info.Location.Address.Context[i].Name;
break;
case "City":
city = info.Location.Address.Context[i].Name;
adCode = info.Location.Address.Context[i].Code;
break;
case "District":
district = info.Location.Address.Context[i].Name;
break;
default:
addr += info.Location.Address.Context[i].Name;
break;
}
}
// 判断poi是否在分配中显示
// addr = WAYZ_POI_TYPES.Contains(info.Location.Place.Type)?addr+info.Location.Place.Name:addr;
//addr += info.Location.Place == null ? string.Empty : info.Location.Place.Name;//info.Location.Place.Name; // 开放poi
addr += GetFinalPlace(info);
serviceResult.Province = province;
serviceResult.City = city;
serviceResult.CityCode = adCode;
serviceResult.AdCode = adCode;
serviceResult.District = district;
serviceResult.Address = addr;
serviceResult.FullAddress = string.Format("{0}|{1}", info.Location.Place == null ? string.Empty : info.Location.Place.Type, info.Location.Address.Name);
return serviceResult;
}
else
{
serviceResult.Flag = false;
}
}
if (!serviceResult.Flag)
{
_logger.LogWarning($"维智地址解析异常,GetWayzLbsAddress lbs解析失败, 参数: {JsonConvert.SerializeObject(model)}| \n{wayzOriginalInputLog}| \n{wayzOriginalOutputLog}");
}
}
catch (Exception ex)
{
serviceResult.Flag = false;
_logger.LogError($"维智地址解析异常,GetWayzLbsAddress lbs解析异常, 参数: {JsonConvert.SerializeObject(model)}| \n{wayzOriginalInputLog}| \n{wayzOriginalOutputLog}| \n {ex.Message}, {ex.StackTrace}");
}
return serviceResult;
}
///
/// gps解析
///
/// 设备imei
/// 经纬度
///
public async Task GetWayzReGeoAddressAsync(string serialno, WayzGpsRequest model)
{
//model.Asset.Id = serialno;
//var hash = ComputeHash(model);
var serviceResult = new GetWayzPositionServiceResult();
var hash = string.Empty;
var logModelStr = string.Empty;
var wayzOriginalInputLog = string.Empty;
var wayzOriginalOutputLog = string.Empty;
if (model.Location.Gnss != null)
{
var Gnss = model.Location.Gnss.Point.Latitude.ToString() + model.Location.Gnss.Point.Longitude.ToString();
var hashModel = new
{
Gnss
};
hash = ComputeHash(hashModel);
logModelStr = "地球系坐标: " + JsonConvert.SerializeObject(model.Location.Gnss);
}
if (model.Location.Position != null)
{
var Position = model.Location.Position.Point.Latitude.ToString() + model.Location.Position.Point.Longitude.ToString();
var hashModel = new
{
Position
};
hash = ComputeHash(hashModel);
logModelStr = "火星系坐标: " + JsonConvert.SerializeObject(model.Location.Position);
}
serviceResult = new GetWayzPositionServiceResult
{
HashParam = hash
};
var cacheKey = CACHE_KEY_WAYZ + $"{hash}";
lock (_syncLocker)
{
var value = _localCache.Get(cacheKey);
if (value != null)
{
_logger.LogWarning($"击中本地缓存 {nameof(_localCache)} 维智地址解析异常(404 position not found),GetWayzReGeoAddressAddress 逆地理解析失败, 参数: {JsonConvert.SerializeObject(value)}");
serviceResult.Flag = false;
serviceResult.CanRetry = false;
return serviceResult;
}
}
//var info = await RedisHelper.GetAsync(cacheKey).ConfigureAwait(false);
var info = await RedisHelperWayz.GetAsync(cacheKey).ConfigureAwait(false);
//var info = new WayzGpsResponseInfo();
string result;
try
{
_idx = (_idx + 1) % _count;
string accessKey = _configWayzServices.Items[_idx].AccessKey;
string positionBaseUrl = _configWayzServices.Items[_idx].PositionUrl;
if (info == null
|| info.Location.Address == null
|| string.IsNullOrEmpty(info.Location.Address.Name)
|| info.Location.Place == null
|| string.IsNullOrEmpty(info.Location.Place.Name)
)
{
var url = string.Format(positionBaseUrl, accessKey);
// result = await _httpHelper.HttpToGetAsync(url).ConfigureAwait(false);
wayzOriginalInputLog = $"{nameof(GetWayzReGeoAddressAsync)}维智请求原始报文: {JsonConvert.SerializeObject(model)}";
_logger.LogInformation(wayzOriginalInputLog);
result = await _httpHelper.HttpToPostAsync(url, model).ConfigureAwait(false);
var resultText = result.Length >= 2000 ? result.Substring(0, 2000) + "..." : result;
wayzOriginalOutputLog = $"{nameof(GetWayzReGeoAddressAsync)}维智返回原始报文: {resultText}";
_logger.LogInformation(wayzOriginalOutputLog);
if (!string.IsNullOrWhiteSpace(result))
{
info = JsonConvert.DeserializeObject(result);
// 返回原始相应的数据
// serviceResult.OriginalResponse = result;
//if (info != null && info.Status + "" == "1") RedisHelper.SetAsync(cacheKey, info, WayzDurationSeconds);
//if (info != null) RedisHelper.SetAsync(cacheKey, info, WayzDurationSeconds);
Random random = new Random(); // 随机1-2天
if (info != null) await RedisHelperWayz.SetAsync(cacheKey, info, random.Next(7200, 14400));
}// 没有返回结果,使用本地缓存记录
else
{
_localCache.Set(cacheKey, model, DateTimeOffset.Now.AddMinutes(120));
_logger.LogInformation($"本地缓存 {nameof(_localCache)} 储存维智GPS逆地址解析异常(404 position not found),参数: {JsonConvert.SerializeObject(model)}");
}
}
else _logger.LogInformation($"{nameof(GetWayzReGeoAddressAsync)}维智GPS击中缓存 {cacheKey}|{logModelStr}");
if (info == null)
{
serviceResult.Flag = false;
}
else
{
int contextCont = info.Location.Address.Context.Count;
if (contextCont > 0)
{
// 解析地址
int radius;
var accuracy = info.Location.Position.Accuracy.ToString();
radius = int.TryParse(accuracy, out radius) ? radius : 50;
// 经纬度
var loc = string.Format("{0},{1}", info.Location.Position.Point.Longitude, info.Location.Position.Point.Latitude) + "";
var poi = info.Location.Place == null ? string.Empty : info.Location.Place.Name;
var adCode = "";
var lat = info.Location.Position.Point.Latitude;
var lng = info.Location.Position.Point.Longitude;
//double gLat, gLng;
//GeoConvert.G2Gps((double)lat, (double)lng, out gLat, out gLng);
serviceResult.Accuracy = radius;
serviceResult.AdCode = adCode;
serviceResult.Flag = true;
serviceResult.Lat = (decimal)lat;
serviceResult.Lon = (decimal)lng;
serviceResult.Poi = poi;
//地址解析
string county = string.Empty;
string province = string.Empty;
string city = string.Empty;
string district = string.Empty;
string addr = string.Empty;
/**
info.Location.Address.Context.ForEach((item) =>
{
switch (item.Type)
{
case "Country":
county = item.Name;
break;
case "Province":
province = item.Name;
break;
case "City":
city = item.Name;
adCode = item.Code;
break;
case "District":
district = item.Name;
break;
default:
addr += item.Name;
break;
}
});
*/
for (int i = 0; i < contextCont; i++)
{
switch (info.Location.Address.Context[i].Type)
{
case "Country":
county = info.Location.Address.Context[i].Name;
break;
case "Province":
province = info.Location.Address.Context[i].Name;
break;
case "City":
city = info.Location.Address.Context[i].Name;
adCode = info.Location.Address.Context[i].Code;
break;
case "District":
district = info.Location.Address.Context[i].Name;
break;
default:
addr += info.Location.Address.Context[i].Name;
break;
}
}
// 判断poi是否在分配中显示
// addr = WAYZ_POI_TYPES.Contains(info.Location.Place.Type)?addr+info.Location.Place.Name:addr;
// addr += info.Location.Place == null ? string.Empty : info.Location.Place.Name;//info.Location.Place.Name; // 开放poi
addr += GetFinalPlace(info);
/**
var finalPlace = string.Empty;
if (info.Location.Place == null)
{
if (info.Location.NearbyPlaces != null)
{
foreach (var item in info.Location.NearbyPlaces)
{
var isSchool = item.Name.Contains("小学") || item.Name.Contains("中学");
if (item.Type.Equals("Education")&& isSchool)
{
finalPlace=item.Name;
break;
}
}
}
}
else
{
finalPlace = info.Location.Place.Name;
var isSchool = info.Location.Place.Name.Contains("小学") || info.Location.Place.Name.Contains("中学");
if (info.Location.Place.Type.Equals("Education") && isSchool)
{
}
else
{
if (info.Location.NearbyPlaces != null)
{
foreach (var item in info.Location.NearbyPlaces)
{
isSchool = item.Name.Contains("小学") || item.Name.Contains("中学");
if (item.Type.Equals("Education") && isSchool)
{
finalPlace = item.Name;
break;
}
}
}
}
}
addr += finalPlace;
*/
serviceResult.Province = province;
serviceResult.City = city;
serviceResult.CityCode = adCode;
serviceResult.AdCode = adCode;
serviceResult.District = district;
serviceResult.Address = addr;
serviceResult.FullAddress = string.Format("{0}|{1}", info.Location.Place == null ? string.Empty : info.Location.Place.Type, info.Location.Address.Name);
return serviceResult;
}
else
{
serviceResult.Flag = false;
}
}
if (!serviceResult.Flag)
{
_logger.LogWarning($"维智地址解析异常,GetWayzGpsAddressAsync 逆地理解析失败, 参数: {JsonConvert.SerializeObject(model)}| \n{wayzOriginalInputLog}| \n{wayzOriginalOutputLog}");
}
}
catch (Exception ex)
{
serviceResult.Flag = false;
// _logger.LogError($"GetWayzGpsAddressAsync 逆地理解析异常, ({model.Location.Gnss.Point.Longitude},{model.Location.Gnss.Point.Latitude}) \n{ex.Message}, {ex.StackTrace}");
_logger.LogError($"维智地址解析异常,GetWayzGpsAddressAsync 逆地理解析异常, ({logModelStr})| \n{wayzOriginalInputLog}| \n{wayzOriginalOutputLog}| \n{ex.Message}, {ex.StackTrace}");
}
return serviceResult;
}
///
/// 从poi和nearbyPlaces 中获取小学和中学优先地址
///
///
///
private string GetFinalPlace(WayzResponseInfo info)
{
string finalPlace;
try
{
string GetEducationPlaceName(List nearbyPlaces)
{
if (nearbyPlaces != null)
{
foreach (var item in nearbyPlaces)
{
var isSchool = item.Name.Contains("小学") || item.Name.Contains("中学");
if (item.Type.Equals("Education") && isSchool)
{
return item.Name;
}
}
}
return info.Location.Place == null ? string.Empty : info.Location.Place.Name;
}
if (info.Location.Place == null)
{
finalPlace = GetEducationPlaceName(info.Location.NearbyPlaces);
}
else
{
var isSchool = info.Location.Place.Name.Contains("小学") || info.Location.Place.Name.Contains("中学");
if (info.Location.Place.Type.Equals("Education") && isSchool)
{
finalPlace = info.Location.Place.Name;
}
else
{
finalPlace = GetEducationPlaceName(info.Location.NearbyPlaces);
}
}
}
catch (Exception ex)
{
_logger.LogError($"{nameof(WayzResponseInfo)} 地址解析出错\n{JsonConvert.SerializeObject(info)},\n{ex.Message}\n{ex.StackTrace}");
return info.Location.Place == null ? string.Empty : info.Location.Place.Name;
}
return finalPlace;
}
public async Task SendRealtimeLocationAsync(string imei, DateTime time, RealtimeLocationTypeFlag type = RealtimeLocationTypeFlag.None)
{
var now = DateTime.Now;
//定位信息的时间早于平台当前时间4分钟的,则不进行下发实时定位指令的处理
if (now.Subtract(time).TotalMinutes >= 4) return;
//在30分钟内,只发起一次实时定位给设备
var status = await _deviceCacheMgr.GetPositionStatusCacheAsync(imei);
if (status?.SendGetLocationTime != null && now.Subtract(status.SendGetLocationTime.Value).TotalMinutes < 30) return;
var flags = new List();
if ((type & RealtimeLocationTypeFlag.Gps) == RealtimeLocationTypeFlag.Gps) flags.Add("GPS");
if ((type & RealtimeLocationTypeFlag.Lbs) == RealtimeLocationTypeFlag.Lbs) flags.Add("LBS");
if ((type & RealtimeLocationTypeFlag.Wifi) == RealtimeLocationTypeFlag.Wifi) flags.Add("WIFI");
if (flags.Count == 0) throw new ArgumentException($"请提供有效的实时定位类型{nameof(type)}");
//DeviceOpenApi api = new DeviceOpenApi(_configIot,_serviceGuardMq, _logger);
string args = "{\"command\":\"getLocation\",\"parameter\":\"" + string.Join("|", flags.ToArray()) + "\"}";
var bResult = await _serviceDeviceIot.InvokeThingServiceAsync(imei, "getGeoLocation", args).ConfigureAwait(false);
_logger.LogInformation($"定位解析失败[{imei}],下发立即定位指令,结果: {bResult}");
if (status == null) status = new DevicePositionStatus();
status.SendGetLocationTime = DateTime.Now;
_deviceCacheMgr.SetPositionStatusCache(imei, status);
}
private string ComputeHash(object data)
{
lock (_syncLocker)
{
var value = JsonConvert.SerializeObject(data);
value = Convert.ToBase64String(_md5.ComputeHash(Encoding.UTF8.GetBytes(value)));
return value;
}
}
///
/// 维智纠偏
///
///
public async Task WayzWifiCalbration(WayzWifiRequest request)
{
try
{
var model = new
{
Location = new
{
request.Location.Wifis
}
};
var url = $"https://lotboard-dev.newayz.com/wifis?force=true";
var res = await _httpHelper.HttpToPostAsync(url, model).ConfigureAwait(false);
_logger.LogInformation($"维智纠偏结果{JsonConvert.SerializeObject(res)}");
}
catch (Exception ex)
{
_logger.LogError($"请求纠偏出错\n{ex.Message}\n{ex.StackTrace}");
}
}
}
}