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