Hello TongXu,
The API involved is Bing Map location. The end point is https://dev.virtualearth.net/REST/v1/Locations. Here is the code used the sample project to reproduce the problem outside the actual application. It is a VS 2017 project (I tried with VS 2019 and encountered the same issue.)
After building the project, I tried to invoke its method in PowerShell, e.g.,
$obj = New-Object -ComObject "BingMapHelper.GeocodingService"
$obj.GeocodeSites("1 Microsoft|Way|Redmond|WA|", <my bing map api key>)
Really appreciate your taking time to look into this.
GeocodingService.cs
namespace BingMapHelper
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class GeocodingService
{
[ComVisible(true)]
public string GeocodeSites(string siteTable, string key)
{
string result = "";
//split into address componenet
string[] tokens = siteTable.Split('|');
GAddress address = new GAddress();
address.Address1 = tokens[0];
address.City = tokens[1];
address.State = tokens[2];
address.Zip = tokens[3];
address.Country = tokens[4];
BingGeocoder geocoder = new BingGeocoder();
geocoder.Key = key;
BingGeoResults response = geocoder.BingGeocodeSite(address);
Trace.WriteLine(response.resourceSets[0].resources[0].ToString());
double lon = response.resourceSets[0].resources[0].geocodePoints[0].coordinates[0];
double lat = response.resourceSets[0].resources[0].geocodePoints[0].coordinates[1];
result = lon.ToString() + " " + lat.ToString();
return result;
}
}
}
BingGeocoder.cs
using BingMapsRESTToolkit;
using Newtonsoft.Json;
namespace BingMapHelper
{
public class BingGeocoder
{
const string BING_LOCATION_SERVICE = "https://dev.virtualearth.net/REST/v1/Locations?q={0}&&maxResults=5&key={1}";
public string Key { get; set; }
public BingGeoResults BingGeocodeSite(GAddress address)
{
if (string.IsNullOrEmpty(Key))
{
throw new MissingFieldException("Your API Key is missing");
}
using (var client = new WebClient())
{
string formatAddress = string.Format(BING_LOCATION_SERVICE, EncodeAddress(address), Key);
var result = client.DownloadString(formatAddress);
var O = JsonConvert.DeserializeObject<BingGeoResults>(result);
// SetGeoResultFlag(O.status);
return O;
}
}
private string EncodeAddress(GAddress address)
{
var sb = new StringBuilder();
if (!string.IsNullOrEmpty(address.Address1))
sb.Append(Uri.EscapeUriString(" " + address.Address1));
if (!string.IsNullOrEmpty(address.Address2))
sb.Append(Uri.EscapeUriString(" " + address.Address2));
if (!string.IsNullOrEmpty(address.City))
sb.Append(Uri.EscapeUriString(" " + address.City));
if (!string.IsNullOrEmpty(address.State))
sb.Append(Uri.EscapeUriString(" " + address.State));
if (!string.IsNullOrEmpty(address.Zip))
sb.Append(Uri.EscapeUriString(" " + address.Zip));
return sb.ToString();
}
}
public class Point
{
public string type { get; set; }
public List<double> coordinates { get; set; }
}
public class Address
{
public string addressLine { get; set; }
public string adminDistrict { get; set; }
public string adminDistrict2 { get; set; }
public string countryRegion { get; set; }
public string formattedAddress { get; set; }
public string locality { get; set; }
public string postalCode { get; set; }
//we may include mora fields if needed.
}
public class GeocodePoint
{
public string type { get; set; }
public List<double> coordinates { get; set; }
public string calculationMethod { get; set; }
public List<string> usageTypes { get; set; }
}
public class Resource
{
public string __type { get; set; }
public List<double> bbox { get; set; }
public string name { get; set; }
public Point point { get; set; }
public Address address { get; set; }
public string confidence { get; set; }
public string entityType { get; set; }
public List<GeocodePoint> geocodePoints { get; set; }
public List<string> matchCodes { get; set; }
}
public class ResourceSet
{
public int estimatedTotal { get; set; }
public List<Resource> resources { get; set; }
}
public class BingGeoResults
{
public string authenticationResultCode { get; set; }
public string brandLogoUri { get; set; }
public string copyright { get; set; }
public List<ResourceSet> resourceSets { get; set; }
public int statusCode { get; set; }
public string statusDescription { get; set; }
public string traceId { get; set; }
}
public class GAddress
{
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string Zip { get; set; }
}
}