Ejemplo n.º 1
0
        public virtual async Task <ReGeocodeLocation> ReGeocodeAsync(double lat, double lng, int radius = 1000)
        {
            var requestParamters = new Dictionary <string, string>
            {
                { "callback", Options.Callback },
                { "get_poi", Options.GetPoi },
                { "key", Options.AccessKey },
                { "location", $"{lat},{lng}" },
                { "output", Options.Output },
                { "poi_options", "radius=" + radius.ToString() }
            };
            var tencentMapUrl  = "https://apis.map.qq.com";
            var tencentMapPath = "/ws/geocoder/v1";

            if (!Options.SecretKey.IsNullOrWhiteSpace())
            {
                var sig = TencentSecretKeyCaculater.CalcSecretKey(tencentMapPath, Options.SecretKey, requestParamters);
                requestParamters.Add("sig", sig);
            }
            var tencentLocationResponse = await GetTencentMapResponseAsync <TencentReGeocodeResponse>(tencentMapUrl, tencentMapPath, requestParamters);

            var location = new ReGeocodeLocation
            {
                Street           = tencentLocationResponse.Result.AddressComponent.Street,
                AdCode           = tencentLocationResponse.Result.AddressInfo?.NationCode,
                Address          = tencentLocationResponse.Result.Address,
                FormattedAddress = tencentLocationResponse.Result.FormattedAddress?.ReCommend,
                City             = tencentLocationResponse.Result.AddressComponent.City,
                Country          = tencentLocationResponse.Result.AddressComponent.Nation,
                District         = tencentLocationResponse.Result.AddressComponent.District,
                Number           = tencentLocationResponse.Result.AddressComponent.StreetNumber,
                Province         = tencentLocationResponse.Result.AddressComponent.Province,
                Town             = tencentLocationResponse.Result.AddressReference.Town.Title,
                Pois             = tencentLocationResponse.Result.Pois.Select(p =>
                {
                    var poi = new Poi
                    {
                        Address  = p.Address,
                        Name     = p.Title,
                        Tag      = p.Id,
                        Type     = p.CateGory,
                        Distance = Convert.ToInt32(p.Distance)
                    };

                    return(poi);
                }).ToList()
            };

            if ((location.Address.IsNullOrWhiteSpace() ||
                 location.FormattedAddress.IsNullOrWhiteSpace()) &&
                location.Pois.Any())
            {
                var nearPoi = location.Pois.OrderBy(x => x.Distance).FirstOrDefault();
                location.Address          = nearPoi.Address;
                location.FormattedAddress = nearPoi.Name;
            }
            location.AddAdditional("TencentLocation", tencentLocationResponse.Result);

            return(location);
        }
Ejemplo n.º 2
0
        public virtual async Task <ReGeocodeLocation> ReGeocodeAsync(double lat, double lng, int radius = 1000)
        {
            var requestParamters = new Dictionary <string, string>
            {
                { "ak", Options.AccessKey },
                { "output", Options.Output },
                { "radius", radius.ToString() },
                { "language", Options.Language },
                { "coordtype", Options.CoordType },
                { "extensions_poi", Options.ExtensionsPoi },
                { "ret_coordtype", Options.ReturnCoordType },
                { "location", string.Format("{0},{1}", lat, lng) },
                { "extensions_road", Options.ExtensionsRoad ? "true" : "false" },
                { "extensions_town", Options.ExtensionsTown ? "true" : "false" },
            };
            var baiduMapUrl  = "http://api.map.baidu.com";
            var baiduMapPath = "/reverse_geocoding/v3";

            if (Options.CaculateAKSN)
            {
                // TODO: 百度的文档不明不白,sn的算法在遇到特殊字符会验证失败,有待完善
                var sn = BaiduAKSNCaculater.CaculateAKSN(Options.AccessSecret, baiduMapPath, requestParamters);
                requestParamters.Add("sn", sn);
            }
            requestParamters["location"] = string.Format("{0}%2C{1}", lat, lng);
            var requestUrl      = BuildRequestUrl(baiduMapUrl, baiduMapPath, requestParamters);
            var responseContent = await MakeRequestAndGetResultAsync(requestUrl);

            var baiduLocationResponse = JsonSerializer.Deserialize <BaiduReGeocodeResponse>(responseContent);

            if (!baiduLocationResponse.IsSuccess())
            {
                var localizerFactory          = ServiceProvider.GetRequiredService <IStringLocalizerFactory>();
                var localizerErrorMessage     = baiduLocationResponse.GetErrorMessage().Localize(localizerFactory);
                var localizerErrorDescription = baiduLocationResponse.GetErrorDescription().Localize(localizerFactory);
                var localizer = ServiceProvider.GetRequiredService <IStringLocalizer <BaiduLocationResource> >();
                localizerErrorMessage = localizer["ResolveLocationFailed", localizerErrorMessage, localizerErrorDescription];
                if (Options.VisableErrorToClient)
                {
                    throw new UserFriendlyException(localizerErrorMessage);
                }
                throw new AbpException($"Resolution address failed:{localizerErrorMessage}!");
            }
            var location = new ReGeocodeLocation
            {
                Street   = baiduLocationResponse.Result.AddressComponent.Street,
                AdCode   = baiduLocationResponse.Result.AddressComponent.AdCode.ToString(),
                Address  = baiduLocationResponse.Result.Address,
                City     = baiduLocationResponse.Result.AddressComponent.City,
                Country  = baiduLocationResponse.Result.AddressComponent.Country,
                District = baiduLocationResponse.Result.AddressComponent.District,
                Number   = baiduLocationResponse.Result.AddressComponent.StreetNumber,
                Province = baiduLocationResponse.Result.AddressComponent.Province,
                Town     = baiduLocationResponse.Result.AddressComponent.Town,
                Pois     = baiduLocationResponse.Result.Pois.Select(p => new Poi
                {
                    Address = p.Address,
                    Name    = p.Name,
                    Tag     = p.Tag,
                    Type    = p.PoiType
                }).ToList(),
                Roads = baiduLocationResponse.Result.Roads.Select(r => new Road
                {
                    Name = r.Name
                }).ToList()
            };

            location.AddAdditional("BaiduLocation", baiduLocationResponse.Result);

            return(location);
        }