|
- 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_";
-
- /// <summary>
- /// 兼容高德缓存
- /// </summary>
- // 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<WayzService> _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<AppsettingsConfig> optConfigAppSettings, IOptions<WayzServicesConfig> optConfigWayzServices,
- HttpHelper httpHelper, DeviceIotOpenService serviceDeviceIot, ILogger<WayzService> 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;
- }
-
- /// <summary>
- /// wifi解析
- /// </summary>
- /// <param name="serialno"></param>
- /// <param name="model"></param>
- /// <returns></returns>
- public async Task<GetWayzPositionServiceResult> 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<WayzWifiResponseInfo>(cacheKey).ConfigureAwait(false);
- var info = await RedisHelperWayz.GetAsync<WayzWifiResponseInfo>(cacheKey).ConfigureAwait(false);
- //var cacheKey = CACHE_KEY_GAODE + $"{hash}";
- //var info = await RedisHelper.GetAsync<GaodeWifiResponseInfo>(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<SingleWifiLocation>(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<WayzWifiResponseInfo>(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;
- }
-
- /// <summary>
- /// lbs解析
- /// </summary>
- /// <param name="serialno"></param>
- /// <param name="model"></param>
- /// <returns></returns>
- public async Task<GetWayzPositionServiceResult> 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<WayzLbsResponseInfo>(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<WayzLbsResponseInfo>(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<WayzLbsResponseInfo>(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;
- }
-
- /// <summary>
- /// gps解析
- /// </summary>
- /// <param name="serialno">设备imei</param>
- /// <param name="model">经纬度</param>
- /// <returns></returns>
- public async Task<GetWayzPositionServiceResult> 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<WayzGpsResponseInfo>(cacheKey).ConfigureAwait(false);
- var info = await RedisHelperWayz.GetAsync<WayzGpsResponseInfo>(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<WayzGpsResponseInfo>(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;
- }
-
- /// <summary>
- /// 从poi和nearbyPlaces 中获取小学和中学优先地址
- /// </summary>
- /// <param name="info"></param>
- /// <returns></returns>
- private string GetFinalPlace(WayzResponseInfo info)
- {
- string finalPlace;
- try
- {
- string GetEducationPlaceName(List<NearbyPlace> 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<string>();
- 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;
- }
- }
-
-
- /// <summary>
- /// 维智纠偏
- /// </summary>
- /// <returns></returns>
- 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}");
- }
- }
-
- }
- }
|