I currently have the following method being called whenever a location is selected.
Instead of passing the city name as the parameter to search by, I would like to search locations by using latitudes and longitudes.
I will be retrieving the latitude and longitude of the selected city.
How would I need to modify this code in order to obtain this?
Thank you
private void xgrdLocation_SelectedItemChanged(object sender, SelectedItemChangedEventArgs e)
{
this.Cursor = Cursors.AppStarting;
lblFooter.Content = "Searching ...";
pushpin = new MapPushpin();
if (xgrdLocation.SelectedItem != null)
{
City selectedCity = xgrdLocation.SelectedItem as City;
//GeocodeService.Location point = new GeocodeService.Location();
pushpin.Text = selectedCity.CityName;
searchDataProvider.Search(pushpin.Text);
//lblSelectedCity.Content = selectedCity.CityName;
}
}
If you want to get the city that a latitude/longitude value is in, you can use the Reverse Geocoding. The Bing Maps REST Location API has such a feature. https://msdn.microsoft.com/en-us/library/ff701710.aspx
You can also find documentation on how to use the REST services in .NET here: https://msdn.microsoft.com/en-us/library/jj819168.aspx
Not sure, but it looks like you might be using the old legacy SOAP services in your application to do the geocoding currently. Avoid the SOAP services, they are old, slow and nearing end of life.
Related
I've a game where I'm trying to keep my own analytics. No pin point location, is there something similar to SystemInfo class that could give approximate location of the player?
I know I can tap into the GPS but I don't want to make things complicated. Just a simple city or country will do.
Please advise.
I had this problem too, so I wanted to make as simple of a solution as possible. Unfortunately, it wasn't easy:
[Serializable]
public class IpApiData
{
public string country_name;
public static IpApiData CreateFromJSON(string jsonString)
{
return JsonUtility.FromJson<IpApiData>(jsonString);
}
}
public static IEnumerator SetCountry()
{
string ip = new System.Net.WebClient().DownloadString("https://api.ipify.org");
string uri = $"https://ipapi.co/{ip}/json/";
using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
{
yield return webRequest.SendWebRequest();
string[] pages = uri.Split('/');
int page = pages.Length - 1;
IpApiData ipApiData = IpApiData.CreateFromJSON(webRequest.downloadHandler.text);
Debug.Log(ipApiData.country_name);
}
}
This will get the country, no problem. If you want to change it to city, or anything else, you'll just have to add some fields to IpApiData, as per this link: https://ipapi.co/api/#complete-location
You can either ask the user for their details or send a request to your web server where that uses something like ipdata.co to track where the IP address came from.
You can first take the IP of the player. I think this might help answers.unity.com/questions/518346/get-ipv4-adress.
Then use any site IP-tracker to find the location. (like ipstack)
I am developing a UWP app using the Maps control that allows a user to plan a route by adding waypoints on the map using various methods such as clicking on the UWP Map control. One of the ways I want to allow a user to add a waypoint or location is to search by actual address. I use the BING Maps REST services code below but if I don't supply the language and culture of where the app is currently being used it always returns American addresses first which are clearly no use to users not in the USA (Yes Microsoft, some of us actually live outside the USA - shock, horror!). I discovered if I supplied the language-culture string such as "en-AU" for Australia then it will search Australian addresses first, and this works really well.
public async Task<List<WayPoint>> FindAddress(string address)
{
List<WayPoint> matchingWaypoints = new List<WayPoint>();
//Create a Geocode request to submit to the BING Maps REST service.
var request = new GeocodeRequest()
{
Query = address.Trim(),
Culture = "en-AU", //HOW CAN I GET THIS FROM THE DEVICE'S CURRENT LOCATION???
IncludeIso2 = true,
IncludeNeighborhood = true,
MaxResults = 10,
BingMapsKey = MapServiceToken
};
//Process the request by using the BING Maps REST services.
var response = await ServiceManager.GetResponseAsync(request);
if (response != null &&
response.ResourceSets != null &&
response.ResourceSets.Length > 0 &&
response.ResourceSets[0].Resources != null &&
response.ResourceSets[0].Resources.Length > 0)
{
int wpNumber = 0;
foreach (BingMapsRESTToolkit.Location loc in response.ResourceSets[0].Resources)
matchingWaypoints.Add(new WayPoint(wpNumber++, loc.Address.FormattedAddress, loc.Point.Coordinates[0], loc.Point.Coordinates[1]));
}
return matchingWaypoints;
}
So what I obviously want to do is derive this string based on the device's current location (i.e: country) NOT from the device's region settings. So for example if someone is using the app the USA I want to specify en-US, if they're in New Zealand it would be en-NZ, if in France it would be "fr-FR" etc. Does anyone know how I could do this? All the stuff I've read about localisation uses the device settings NOT the current physical location so I'm still trying to work out how to do it.
If anyone can help out I'd really appreciate it :-)
There is an official sample of how to get location at https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/Geolocation
This will return the latitude and longitude. You can then use a different Bing API to get the country based on that lat/long.
This will give you a country name. With this you can lookup against a pre-generated list of codes to country names (created with CultureInfo.GetCultures() on your machine) or you could look at this for a way of doing this at runtime as GetCultures() isn't supported in UWP.
Using the Regional settings is simpler but if you want to use the actual location then this is the way to go. For devices where access to location isn't available then regional settings could be a good back up.
Another approach would be one of various public APIs which will give you information such as location based on IP address. This also isn't perfect though due to the use of proxies in different countries, etc.
Thanks for the reply Matt but I worked out how to do it with the help of the Bing Maps forum. Instead of using the REST API am using the FindLocationsAsync call as part of the UWP Map API passing in the address, the local geopoint to use a starting reference (aka a 'hint' location) and the max number of matches to return... here's the code I used which works perfectly. (Note that WayPoint is an object from my model to store various info about a waypoint on the route.)
public async Task<List<WayPoint>> FindAddress(string address)
{
List<WayPoint> matchingWaypoints = new List<WayPoint>();
// Use current location as a query hint so nearest addresses are returned.
BasicGeoposition queryHint = new BasicGeoposition();
queryHint.Latitude = this.CurrentLocation.Position.Latitude;
queryHint.Longitude = this.CurrentLocation.Position.Longitude;
Geopoint hintPoint = new Geopoint(queryHint);
MapLocationFinderResult result =
await MapLocationFinder.FindLocationsAsync(address.Trim(), hintPoint, 5);
// If the query returns results, store in collection of WayPoint objects.
string addresses = "";
if (result.Status == MapLocationFinderStatus.Success)
{
int i = 0;
foreach (MapLocation res in result.Locations)
{
matchingWaypoints.Add(new WayPoint(i++, res.Address.FormattedAddress, res.Point.Position.Latitude, res.Point.Position.Longitude));
}
}
return matchingWaypoints;
}
I have some problems with my bing maps.
The first one happens when I click on My Location - from almost all locations I were it worked fine, but there are some locations that returns null, why? (It happened me in a new building that hasn't address yet and also happened in a building with no internet connections).
The method:
private async void MyLocation_Click(object sender, RoutedEventArgs e)
{
Bing.Maps.Location location = await GeoLocation.GetCurrentLocationAsync();
MapLayer.SetPosition(_flagPin, location);
map.SetView(location, 15);
}
The first line calls to my static function:
public static async Task<Bing.Maps.Location> GetCurrentLocationAsync()
{
Geolocator geo = new Geolocator();
geo.DesiredAccuracy = PositionAccuracy.Default;
Geoposition currentPosition = null;
currentPosition = await geo.GetGeopositionAsync();
return new Bing.Maps.Location()
{
Latitude = currentPosition.Coordinate.Latitude,
Longitude = currentPosition.Coordinate.Longitude
};
}
What is the problem? How to fix it?
And the second question is about addresses.
When I get an Address object, there are many formats I can select such as FormattedAddress, CountryRegion, PostalTown, I selected The FormattedAddress and there is a problem with it.
My code:
GeocodeResponse GP = await GeoLocation.ReverseGeocodeAsync(location.Latitude, location.Longitude);
EventContext.Address = GP.Results[0].Address.FormattedAddress;
The problem is when I want to send an Address and get the Location.
Sometimes this code returns null, why?
GeocodeResponse GP = await GeoLocation.GeocodeAsync(EventContext.Address);
I thought that maybe the problem is that sometimes the Address (Formatted) is not good, sometimes it gives weird addresses, such as, "Street, st. Canada", which is not found and therefore, it returns null. But what can I do to send a correctly Address? Does FomattedAddress is good?
Here are the two GeoCodeAsync and ReverseGeocodeAsync functions:
public static async Task<GeocodeResponse> GeocodeAsync(string address)
{
GeocodeService.GeocodeRequest geocodeRequest = new GeocodeService.GeocodeRequest();
// Set credentials using a Bing Maps key
geocodeRequest.Credentials = new GeocodeService.Credentials();
geocodeRequest.Credentials.ApplicationId = Application.Current.Resources["BingCredentials"] as string;
// Set the address
geocodeRequest.Query = address;
// Make the geocode request
GeocodeService.GeocodeServiceClient geocodeService = new GeocodeServiceClient(GeocodeServiceClient.EndpointConfiguration.BasicHttpBinding_IGeocodeService);
GeocodeResponse geocodeResponse = await geocodeService.GeocodeAsync(geocodeRequest);
return geocodeResponse;
}
public static async Task<GeocodeResponse> ReverseGeocodeAsync(double latitude, double longitude)
{
ReverseGeocodeRequest reverseGeocodeRequest = new ReverseGeocodeRequest();
// Set credentials using a Bing Maps key
reverseGeocodeRequest.Credentials = new GeocodeService.Credentials();
reverseGeocodeRequest.Credentials.ApplicationId = Application.Current.Resources["BingCredentials"] as string;
// Set the coordinates
reverseGeocodeRequest.Location = new GeocodeService.GeocodeLocation() { Latitude = latitude, Longitude = longitude };
// Make the reverse geocode request
GeocodeServiceClient geocodeService = new GeocodeServiceClient(GeocodeServiceClient.EndpointConfiguration.BasicHttpBinding_IGeocodeService);
GeocodeResponse geocodeResponse = await geocodeService.ReverseGeocodeAsync(reverseGeocodeRequest);
return geocodeResponse;
}
To clarify your first issue, are you getting null from the GPS or is it the address information in the result that is null the issue? If the GPS is returning null then it's possible that your GPS isn't able to get the current position where you are. This has nothing to do with Bing Maps and more so just an issue which your mobile device getting a clear view to the GPS satellites. If the issue is that the address information in the result is null then this is to be expected with new buildings that might not yet be known in the Bing Maps data set. It usually takes several months for new buildings to be found and added to the map data set. If you have no internet connection then the mobile device won't be able to connect to Bing Maps to get the address information. Note that Bing Maps is over 9 Petabytes in size so there is no local copy of the data on your mobile device.
If you already have the coordinates and the address information you shouldn't be geocoding it again. This is a waste of time and will cause issues. The geocoder will sometimes return "street" or "ramp" if the coordinate in which you pass to the reverse geocoder is on an unnamed street. Note geocoders are not designed to clean/validate addresses. They are designed to take an address and return a coordinate. Reverse geocoders are designed to take a coordinate and find the nearest address. Mixing the results from one with the other can result in odd results as the coordinates for each could be significantly different. It rare cases it's possible to loop between both services and get different results each time as the results will slightly be different and end up "walking" along a street.
For my studying and university I have a project where I need to make an application using C# WPF. This application must allow me to select a path between two adresses and show the path on the map like google map.
How can I implement the google webservice API ? I am a bit lost with it and I don't understand how I can make my application and fit in the google map itself.
With this i must be able to calculate the distance as well.
This is what i have done with the webBrowser but it displays the whole website of google maps:
I know that the WebBrowser control can display the google maps but it doesnt actually work
This is my code actually
private void btnCharger_Click(object sender, RoutedEventArgs e)
{
//Use static or WebControl we don't know yet.
//This is the case we use webControl
string street = "";
string city = "";
string zipcode = "";
StringBuilder adresseQuery = new StringBuilder();
adresseQuery.Append("http://maps.google.com/maps?q=");
street = tbStreet.Text.Replace(" ", "+");
adresseQuery.Append(street + ",+");
city = tbCity.Text;
adresseQuery.Append(city + ",+");
zipcode = tbZipCode.Text;
webBrowser1.Navigate(adresseQuery.ToString());*/
}
So in this code i have created the adresse and sent it to the webbrowser through google maps. But is shows the whole google map page with the left bar and everything. I would like to only display the map ! How can i only display the map and not the bars present on the https://maps.google.com/
I have already checked this Link and am currently working on it but this is static.
For the part of routing/getting the directions (and for some of others functions you need as well), you can use a .NET wrapper around Google Maps API:
GoogleApi
google-maps
gmaps-api-net is outdated (at this time of answering) - the last update for the Directions API was made in 2016.
Usage example for GoogleApi:
using GoogleApi.Entities.Common;
using GoogleApi.Entities.Maps.Directions.Request;
using GoogleApi.Entities.Maps.Directions.Response;
public void GetRoute()
{
DirectionsRequest request = new DirectionsRequest();
request.Key = "AIzaSyAJgBs8LYok3rt15rZUg4aUxYIAYyFzNcw";
request.Origin = new Location("Brasov");
request.Destination = new Location("Merghindeal");
var response = GoogleApi.GoogleMaps.Directions.Query(request);
Console.WriteLine(response.Routes.First().Legs.First().DurationInTraffic);
Console.WriteLine(response.Routes.First().Legs.First().Distance);
Console.WriteLine(response.Routes.First().Legs.First().Steps);
}
I'm doing a school project, I need to make a simple web site, add google maps on it, read, lets say, 100 diffrent addresses from a text file and show those locations on google maps with markers.
Now I'm trying to add google maps to my ASP.net page with javascript which I saw on google maps tutorials. And there's that problem which I have to convert adresses to coordinates. So for that I'm using
function addAddressToMap(response) {
if (!response || response.Status.code != 200) {
alert("Sorry, we were unable to geocode that address");
}
else {
place = response.Placemark[0];
point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
marker = new GMarker(point);
map.addOverlay(marker);
marker.openInfoWindowHtml(place.address + '<br>' + '<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
}
}
// showLocation() is called when you click on the Search button
// in the form. It geocodes the address entered into the form
// and adds a marker to the map at that location.
function showLocation() {
var address = "izmit";
var address2 = "ağrı";
geocoder.getLocations(address, addAddressToMap);
geocoder.getLocations(address2, addAddressToMap);
}
these functions and they are working fine. But my problem here is, I need to get these address informations from a text file. But to get them, I need to use a few diffrent codes. And I want to make it on the server side with C# codes. But I don't know how to write some codes on server side and then return something to HTML side as address. I hope you understand. Thank you for your helps.
Update:
Server code:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Page.ClientScript.RegisterArrayDeclaration("Skills", "'asa'");
Page.ClientScript.RegisterArrayDeclaration("Skills", "'bell'");
Page.ClientScript.RegisterArrayDeclaration("Skills", "'C'");
Page.ClientScript.RegisterArrayDeclaration("Skills", "'C++'");
}
}
Client side:
function showLocation()
{
var address = "izmit";
var address2 = "ağrı";
geocoder.getLocations(Skills[0], addAddressToMap);
}
Now if I use "asa" instead of Skills[0] it will show the location and mark, but with Skills[0] it's not working. And thank you for your answer that was what I'm looking for.
even if I try var MyValue = Skills[0]; and then use MyValue instead of Skills[0] it's still not working
If I understood your question correctly, you want to create an array on the server side and read it in the client.
See this link for a tutorial on how to pass an array from the server to the client.
Basically, you want to use the ClientScriptManager.RegisterArrayDeclaration method to add values to the array.
You can then easily read it in javascript.
Server Side:
string arrayName = "MyArray";
Page.ClientScript.RegisterArrayDeclaration(arrayName , "'value1'");
Page.ClientScript.RegisterArrayDeclaration(arrayName , "'value2'");
Javascript on Client Side:
function readArray()
{
for (var i = 0; i < MyArray.length; i++)
{
//Reading Element From Array
var myValue = MyArray[i];
}
}