azureasp.net-coreazure-maps

Azure Maps rejecting Route Request with ZipCode


When i submit a Zip code as a location to AzureMaps, it returns bad request.

My theory is that the centralized point on the Zipcode is not a navigable point by road.

I've tried a few things:

-Deviation I added the deviation parameter of 2.5km to the request, but it still returned bad request. -Snaptoroad api This api returned as nonexistent. I may have formed the url incorrectly. But either way, looking at the documentation, this is more about visual. The only goal here is to return a travel duration for a route -Reverse geocoding Someone suggested reverse geocoding forces Azure to find the nearest navigable address, which i thought was creative, but also didnt work.

Im going to try Snaptoroad api again, but i dont think thats correct. I also have to try fuzzy inputs.

For more context, the method takes in a hubId and a list of locations. "Locations" are typically full or near full addresses, but can be zip codes or cities and states. Commas are not allowed in the parameter.

The return is a simple double of route minutes.

This is all in c# asp core

UPDATE: Fuzzy search did not work. My method here:

public async Task<double> HubRouteCalculate(DateTime sDate, TimeSpan sTime, string sHub, List<string> sLocations)
{
    // Combine date and time
    var localDateTime = sDate.Add(sTime); // Local time
    var utcDateTime = TimeZoneInfo.ConvertTimeToUtc(localDateTime, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));

    // Look up the hub address
    if (string.IsNullOrWhiteSpace(sHub) || sLocations == null || sLocations.Count == 0)
    {
        throw new ArgumentException("Invalid hub or destination addresses.");
    }
    if(sHub.Substring(0,1) != "H") { sHub = "H" + sHub; }
    var hub = _context.ListHubs.FirstOrDefault(m => m.HubId == sHub);
    if (hub == null)
    {
        throw new Exception("Hub not found.");
    } //**return error
    //var hubCoordinates = await GeocodeAddress(hub.Address);
    var hubCoordinates = await FuzzySearchAddressGeoCode(hub.Address);

    // Construct waypoints starting and ending at the hub
    // Geocode all destination locations
    var waypointCoordinates = new List<string>
    {
        $"{hubCoordinates.lat},{hubCoordinates.lon}" // Starting point (hub)
    };

    foreach (var location in sLocations)
    {
        //var coordinates = await GeocodeAddress(location);
        //waypointCoordinates.Add($"{coordinates.lat},{coordinates.lon}");
        var coordinates = await FuzzySearchAddressGeoCode(location);
        waypointCoordinates.Add($"{coordinates.lat},{coordinates.lon}");
    }

    waypointCoordinates.Add($"{hubCoordinates.lat},{hubCoordinates.lon}"); // Return to hub

    // Construct the query parameter with all waypoints
    var route = string.Join(":", waypointCoordinates);

    // Construct the Azure Maps Routing API URL
    var url = $"https://atlas.microsoft.com/route/directions/json?api-version=1.0" +
              $"&query={route}" +
              $"&minDeviationDistance = 100" +
              $"&travelMode=truck" +
              $"&routeType=fastest" +
              $"&vehicleHeight=3.9" +   // Example vehicle dimensions (meters) 13ft => 3.9
              $"&vehicleWidth=2.43" +  //8ft => 2.43
              $"&vehicleLength=10.97" + //36ft => 10.97
              $"&vehicleWeight=11800" + // Example weight (kg) 26000lbs => 11800
              $"&departureTime={Uri.EscapeDataString(utcDateTime.ToString("yyyy-MM-ddTHH:mm:ssZ"))}" +
              $"&subscription-key={_azureMapsKey}";

    try
    {
        using (var client = new HttpClient())
        {
            var response = await client.GetAsync(url);

            if (!response.IsSuccessStatusCode)
            {
                throw new Exception($"Azure Maps API error: {response.StatusCode} - {response.ReasonPhrase}");
            }

            var content = await response.Content.ReadAsStringAsync();
            var routeData = System.Text.Json.JsonSerializer.Deserialize<AzureMapsRouteResponse>(content);

            // Extract total travel time in seconds and convert to minutes
            var travelTimeInSeconds = routeData.routes[0].summary.travelTimeInSeconds;
            return travelTimeInSeconds / 60.0; // Return travel time in minutes
        }
    }
    catch (Exception ex)
    {
        throw new Exception($"Error calculating route: {ex.Message}");
    }
}

The error here: Error calculating route: Azure Maps API error: BadRequest - Bad Request

The request here: https://atlas.microsoft.com/route/directions/json?api-version=1.0&query=40.765073,-73.902279:23.672831,53.745517:40.765073,-73.902279&minDeviationDistance = 100&travelMode=truck&routeType=fastest&vehicleHeight=3.9&vehicleWidth=2.43&vehicleLength=10.97&vehicleWeight=11800&departureTime=2024-12-23T16%3A00%3A39Z&subscription-key=AHqc5ekSrA5PhfZM9joRnP0THz0ub03uGIuqqsy51GYCV8iUFJOLJQQJ99ALACYeBjFLbQ9fAAAgAZMP1RSB


Solution

  • Yes, your code will work when you provide the country with it . Below is the minimalized code without classes which worked for me:

    using System.Text.Json;
    
    class Program
    {
        private const string Key_Az_mp = "4DtMNZ90CPDohp7g1fgAZMP41UE";
    
        static async Task Main(string[] args)
        {
            string rithzipCde = "29089";
            List<string> dest_rith_add = new List<string> { "80909", "20901" };
    
            double gettime = await Rith_Timetakes(rithzipCde, dest_rith_add);
            Console.WriteLine($"Hello Rithwik, The Total time that may take is: {gettime} minutes");
    
        }
    
        static async Task<double> Rith_Timetakes(string tstadd, List<string> dest_rith_add)
        {
            using HttpClient ricl = new HttpClient();
            const string rith_cntry_code = "US";
    
            var tstcrdts = await Rith_Cordinates($"{tstadd}, {rith_cntry_code}", ricl);
    
            List<string> tstpnts = new List<string> { $"{tstcrdts.lat},{tstcrdts.lon}" };
            foreach (var rith in dest_rith_add)
            {
                var crds = await Rith_Cordinates($"{rith}, {rith_cntry_code}", ricl);
                tstpnts.Add($"{crds.lat},{crds.lon}");
            }
            tstpnts.Add($"{tstcrdts.lat},{tstcrdts.lon}"); 
            string routeQuery = string.Join(":", tstpnts);
    
            string url = $"https://atlas.microsoft.com/route/directions/json?api-version=1.0&query={routeQuery}&subscription-key={Key_Az_mp}";
            HttpResponseMessage ri_out = await ricl.GetAsync(url);
            ri_out.EnsureSuccessStatusCode();
    
            string ri_data = await ri_out.Content.ReadAsStringAsync();
            using JsonDocument cho = JsonDocument.Parse(ri_data);
            double ri_secs = cho.RootElement.GetProperty("routes")[0].GetProperty("summary").GetProperty("travelTimeInSeconds").GetDouble();
            return ri_secs / 60.0; 
        }
    
        static async Task<(double lat, double lon)> Rith_Cordinates(string address, HttpClient client)
        {
            string ri_uri = $"https://atlas.microsoft.com/search/address/json?api-version=1.0&query={Uri.EscapeDataString(address)}&subscription-key={Key_Az_mp}";
            HttpResponseMessage ri_out = await client.GetAsync(ri_uri);
            ri_out.EnsureSuccessStatusCode();
    
            string ridata = await ri_out.Content.ReadAsStringAsync();
            using JsonDocument cho = JsonDocument.Parse(ridata);
            JsonElement ri = cho.RootElement.GetProperty("results")[0].GetProperty("position");
            return (ri.GetProperty("lat").GetDouble(), ri.GetProperty("lon").GetDouble());
        }
    }
    

    Output:

    enter image description here