Пример #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);
        }
Пример #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);
        }
Пример #3
0
        public virtual async Task <ReGeocodeLocation> InverseAsync(AmapInverseHttpRequestParamter requestParamter)
        {
            if (requestParamter.Locations.Length > 20)
            {
                var localizer      = ServiceProvider.GetRequiredService <IStringLocalizer <AmapLocationResource> >();
                var localizerError = localizer["SupportsResolveAddress", 20];
                localizerError = localizer["ResolveLocationFailed", localizerError];
                if (Options.VisableErrorToClient)
                {
                    throw new UserFriendlyException(localizerError);
                }
                throw new AbpException($"Resolution address failed:{localizerError}!");
            }
            var client            = HttpClientFactory.CreateClient(AmapHttpConsts.HttpClientName);
            var requestUrlBuilder = new StringBuilder(128);

            requestUrlBuilder.Append("http://restapi.amap.com/v3/geocode/regeo");
            requestUrlBuilder.AppendFormat("?key={0}", Options.ApiKey);
            requestUrlBuilder.AppendFormat("&batch={0}", requestParamter.Batch);
            requestUrlBuilder.AppendFormat("&output={0}", requestParamter.Output);
            requestUrlBuilder.AppendFormat("&radius={0}", requestParamter.Radius);
            requestUrlBuilder.AppendFormat("&extensions={0}", requestParamter.Extensions);
            requestUrlBuilder.AppendFormat("&homeorcorp={0}", requestParamter.HomeOrCorp);
            requestUrlBuilder.AppendFormat("&location=");
            for (int i = 0; i < requestParamter.Locations.Length; i++)
            {
                requestUrlBuilder.AppendFormat("{0},{1}", Math.Round(requestParamter.Locations[i].Longitude, 6),
                                               Math.Round(requestParamter.Locations[i].Latitude, 6));
                if (i < requestParamter.Locations.Length - 1)
                {
                    requestUrlBuilder.Append("|");
                }
            }
            if (!requestParamter.PoiType.IsNullOrWhiteSpace())
            {
                requestUrlBuilder.AppendFormat("&poitype={0}", requestParamter.PoiType);
            }
            if (!requestParamter.PoiType.IsNullOrWhiteSpace())
            {
                requestUrlBuilder.AppendFormat("&poitype={0}", requestParamter.PoiType);
            }
            if (!requestParamter.Sig.IsNullOrWhiteSpace())
            {
                requestUrlBuilder.AppendFormat("&sig={0}", requestParamter.Sig);
            }
            if (requestParamter.RoadLevel.HasValue)
            {
                requestUrlBuilder.AppendFormat("&roadlevel={0}", requestParamter.RoadLevel);
            }

            var requestMessage = new HttpRequestMessage(HttpMethod.Get, requestUrlBuilder.ToString());

            var response = await client.SendAsync(requestMessage, GetCancellationToken());

            if (!response.IsSuccessStatusCode)
            {
                throw new AbpException($"Amap request service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");
            }

            var resultContent = await response.Content.ReadAsStringAsync();

            var amapResponse = JsonSerializer.Deserialize <AmapInverseLocationResponse>(resultContent);

            if (!amapResponse.IsSuccess())
            {
                var localizerFactory = ServiceProvider.GetRequiredService <IStringLocalizerFactory>();
                var localizerError   = amapResponse.GetErrorMessage().Localize(localizerFactory);
                if (Options.VisableErrorToClient)
                {
                    var localizer = ServiceProvider.GetRequiredService <IStringLocalizer <AmapLocationResource> >();
                    localizerError = localizer["ResolveLocationFailed", localizerError];
                    throw new UserFriendlyException(localizerError);
                }
                throw new AbpException($"Resolution address failed:{localizerError}!");
            }
            var inverseLocation = new ReGeocodeLocation
            {
                Street   = amapResponse.Regeocode.AddressComponent.StreetNumber.Street,
                AdCode   = amapResponse.Regeocode.AddressComponent.AdCode,
                Address  = amapResponse.Regeocode.Address,
                City     = amapResponse.Regeocode.AddressComponent.City.JoinAsString(","),
                Country  = amapResponse.Regeocode.AddressComponent.Country,
                District = amapResponse.Regeocode.AddressComponent.District,
                Number   = amapResponse.Regeocode.AddressComponent.StreetNumber.Number,
                Province = amapResponse.Regeocode.AddressComponent.Province,
                Town     = amapResponse.Regeocode.AddressComponent.TownShip.JoinAsString(" ")
            };

            return(inverseLocation);
        }