Convert lat long into address using NuGet - windows-phone-8

I am developing a windows phone application which requires to convert the current latitude and longitude into the address on the map.
how to convert a Geo-coordinate to address pointing to the map using GoogleMaps.LocationServices Nu Get package.

GoogleMaps.LocationServices NuGet package doesn't have method to find street address. Try the below code.
const string API_ADDRESS_FROM_LATLONG = "http://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&sensor=false";
public void GetAddressFromLatLong(string Lat, string Long)
{
try
{
var webClient = new WebClient();
webClient.DownloadStringAsync(new Uri(string.Format(API_ADDRESS_FROM_LATLONG, Lat, Long)));
webClient.DownloadStringCompleted += webClient_DownloadStringCompleted;
}
catch (Exception)
{
}
}
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
try
{
XDocument doc = XDocument.Parse(e.Result);
var Address = doc.Descendants("result").FirstOrDefault().Descendants("formatted_address").FirstOrDefault().Value;
MessageBox.Show(Address);
}
catch (Exception)
{
}
}

Related

Bad location Google Maps Xamarin Forms (Middle of the ocean)

I'm using Xamarin.forms.Maps and ExtendedMap, I did make a custom control, here I can get the location when the user tap on map but by default the map position is in the middle of the occean, something like this 0.0756931, 0.0786793. I was seaching and trying for a while but I did not find the solution.
I did see that the map is loading the region.LatitudeDegrees and region.LongitudeDegrees but I really don't why is this happen.
Xamarin.Forms 3.0.0.482510
Xamarin.Forms.Maps 3.0.0.482510
Xamarin.Plugin.ExternalMaps 4.0.1
MapGoogleView.xaml
<local:ExtendedMap
WidthRequest="320" HeightRequest="200"
x:Name="MyMap" Tap="OnTap"
IsShowingUser="true"
MapType="Street"/>
MapGoogleView.xaml.cs
public MapGoogleView(double lat, double lon)
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
var map = new ExtendedMap(
MapSpan.FromCenterAndRadius(
new Position(lat, lon), Distance.FromMiles(0.3)))
{
IsShowingUser = true,
HeightRequest = 100,
WidthRequest = 900,
VerticalOptions = LayoutOptions.FillAndExpand,
MapType = MapType.Street
};
var stack = new StackLayout { Spacing = 0 };
stack.Children.Add(map);
Content = stack;
var position = new Position(lat, lon); // Latitude, Longitude
var pin = new Pin
{
Type = PinType.Generic,
Position = position,
Label = "UbicaciĆ³n",
Address = "Latitud: " + lat.ToString() + ", Longitud: " + lon.ToString(),
};
MyMap.Pins.Add(pin);
map.MoveToRegion(
MapSpan.FromCenterAndRadius(
new Position(lat, lon), Distance.FromMiles(1)));
}
ExtendedMap.cs
public class ExtendedMap : Map
{
public event EventHandler<TapEventArgs> Tap;
public ExtendedMap()
{
}
public ExtendedMap(MapSpan region) : base(region)
{
}
public void OnTap(Position coordinate)
{
OnTap(new TapEventArgs { Position = coordinate });
}
public async void OnTap(Position coordinate)
{
try
{
OnTap(new TapEventArgs { Position = coordinate });
}
catch (Exception error)
{
await Application.Current.MainPage.DisplayAlert(
"Error",
error.Message,
"Aceptar");
return;
}
}
protected virtual void OnTap(TapEventArgs e)
{
var handler = Tap;
if (handler != null) handler(this, e);
}
}
public class TapEventArgs : EventArgs
{
public Position Position { get; set; }
}
}
Droid
ExtendedMapRenderer.cs
public class ExtendedMapRenderer : MapRenderer, IOnMapReadyCallback
{
private GoogleMap _map;
public void OnMapReady(GoogleMap googleMap)
{
_map = googleMap;
if (_map != null)
//_map.GestureRecognizer.Add(new);
_map.MapClick += googleMap_MapClick;
}
public ExtendedMapRenderer()
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Map> e) //cambiar a xamarin.forms.view
{
if (_map != null)
_map.MapClick -= googleMap_MapClick;
base.OnElementChanged(e);
if (Control != null)
((MapView)Control).GetMapAsync(this);
}
private void googleMap_MapClick(object sender, GoogleMap.MapClickEventArgs e)
{
((ExtendedMap)Element).OnTap(new Position(e.Point.Latitude, e.Point.Longitude));
}
}
If you're struggling to obtain the Latitude and Longitude coordinates using the plugins described above, you could obtain your devices lon/lat by doing the following:
Download and install into your application the Geolocator Plugin. Made by the man the myth the legend James Montemagno.
Following that, you can follow this guide to obtain your devices longitude and latitude coordinates.
On doing that you can assign your global lat and lon variables to the values retrieved using that plugin. I don't know if you did this prior to instantiating your maps or have used a different method but this is how I get my devices Lat & Lon.
As a fallback if a device has location disabled or does not have the ability to retrieve its GPS data I always set my default lat & lon to the capital city of the devices country region.
RegionInfo.CurrentRegion
then if UK set the lat & lon to london city center for example.

400 error - The given location is invalid

I am trying to retrieve JSON data via an API and parsing it into my Android. I am trying to log the JSON data retrieved but I keep getting a "400 error - given location is invalid." The parameters to access the API seem correct but I am not sure why I can't retrieve the data.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
temperatureLabel = (TextView) findViewById(R.id.temperatureLabel);
timeLabel = (TextView) findViewById(R.id.timeLabel);
refreshButton = (ImageView) findViewById(R.id.refreshImage);
final double latitude = -104.8319;
final double longtitude = 39.7294;
refreshButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getWeatherForecast(latitude, longtitude);
}
});
getWeatherForecast(latitude, longtitude);
}
public void getWeatherForecast(double latitude, double longtitude) {
String apiKey = "SECRET-KEY;
String forecastURL = "https://api.darksky.net/forecast/" + apiKey + "/" + latitude + ","
+ longtitude;
if (isNetworkAvailable()) {
//Build and HTTP request
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(forecastURL).build();
//Make an Api call
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
alertUserError();
}
});
}
#Override
public void onResponse(Response response) throws IOException {
try {
String jsonData = response.body().string();
Log.e(TAG, "JASON DATA" + jsonData);
if (response.isSuccessful()) {
mcurrentWeather = getCurrentWeatherDetails(jsonData);
// You want to update the display In the UI.
runOnUiThread(new Runnable() {
#Override
public void run() {
updateDisplay();
}
});
} else {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "API call failed", Toast.LENGTH_LONG).show();
}
});
}
} catch (IOException e) {
Log.e(TAG, "Exception Caught");
} catch (JSONException e) {
Log.e(TAG, "JSONexception Caught");
}
}
});
} else {
alertUserError();
}
}
If you are trying to check what request you send to the API and what the API sends to you, then you should implement OkHttp logging interceptor. It's simple and easy to work with it.
First of all, I have deleted your secret key from your answer and replaced it with "SECRET-KEY". DarkSky is only free 1000 requests per day, so someone could grab that key and reuse it. You'd have to pay for it.
I would to go to https://darksky.net/dev/account and reset the secret key to avoid risks.
Second, your coordinates are swapped. You currently have
final double latitude = -104.8319;
final double longtitude = 39.7294;
String forecastURL = "https://api.darksky.net/forecast/" + apiKey + "/"
+ latitude + ","
+ longtitude;
That result of:
https://api.darksky.net/forecast/SECRET-KEY/-104.8319,39.7294?exclude=minutely,hourly,daily,flags,alerts
is then "400, Location invalid" because there is no location in the world with latitude -104 and longitude 39.
The correct one is
final double latitude = 39.7294;
final double longtitude = -104.8319;
Then your urlString is:
https://api.darksky.net/forecast/SECRET-KEY/39.7294,-104.8319?exclude=minutely,hourly,daily,flags,alerts
which outputs in the browser:
{
"latitude":39.7294,
"longitude":-104.8319,
"timezone":"America/Denver",
"currently":{
"time":1583068320,
"summary":"Mostly Cloudy",
"icon":"partly-cloudy-night",
"nearestStormDistance":9,
"nearestStormBearing":145,
"precipIntensity":0,
"precipProbability":0,
"temperature":37.32,
"apparentTemperature":33.14,
"dewPoint":18.62,
"humidity":0.46,
"pressure":1011.5,
"windSpeed":5.24,
"windGust":7.61,
"windBearing":157,
"cloudCover":0.87,
"uvIndex":0,
"visibility":10,
"ozone":309},
"offset":-7
}
P.S: Notice I included the exclude query item to shorten the response to show the example. Delete that part and you will have all the response, with minutely, daily and so on fields.

WP8 : WebClient API DownloadStringAsync throwing System.Net.WebException when downloading any RSS feed

I'm trying to download an RSS feed in my WP8 app using the WebClient api and is getting a System.Net.WebException: NotFound, I tried it various different RSS feeds and the result is the same, am I missing something, here is the sample code
public class RssFeedDownloader
{
public Task<string> GetRssFeed(string feedUrl)
{
var tcs = new TaskCompletionSource<string>();
var client = new WebClient();
client.DownloadStringCompleted += (s, e) =>
{
if (e.Error == null)
{
tcs.SetResult(e.Result);
}
else
{
tcs.SetException(e.Error);
}
};
client.DownloadStringAsync(new Uri(feedUrl));
return tcs.Task;
}
}

How can I get Lat/Lng of two points (train station) on google maps?

I'm about to trace with direction service the railway between two station.
The problem is I can't get the Lat/Lng of the two station, it get always a neighbour points.
The route is (search on google maps website) :
Ceres, TO to Stazione Porta Nuova, Corso Vittorio Emanuele II, 58, Torino
I need Lat/Lng of Ceres (train station) and Stazione Porta Nuova, Corso Vittorio Emanuele II, 58, Torino (train station). How can I get them?
So I can draw in my maps the same railway (brown line).
public class GetXMLTask
{
static double longitute;
static double latitude;
public JSONObject getLocationInfo(String address)
{
StringBuilder stringBuilder = new StringBuilder();
try
{
address = address.replaceAll(" ","%20");
HttpPost httppost = new HttpPost("http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false");
HttpClient client = new DefaultHttpClient();
HttpResponse response;
stringBuilder = new StringBuilder();
response = client.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
int b;
while ((b = stream.read()) != -1)
{
stringBuilder.append((char) b);
}
}
catch (ClientProtocolException e)
{
Log.i("getLocationInfo ClientProtocolException", e.toString());
}
catch (IOException e)
{
Log.i("getLocationInfo IOException", e.toString());
}
JSONObject jsonObject = new JSONObject();
try
{
jsonObject = new JSONObject(stringBuilder.toString());
}
catch (JSONException e)
{
Log.i("getLocationInfo JSONException", e.toString());
}
return jsonObject;
}
public ArrayList<Double> getLatLong(JSONObject jsonObject)
{
ArrayList<Double> latlng = new ArrayList<Double>();
try
{
longitute = ((JSONArray)jsonObject.get("results")).getJSONObject(0).getJSONObject("geometry").getJSONObject("location").getDouble("lng");
latitude = ((JSONArray)jsonObject.get("results")).getJSONObject(0).getJSONObject("geometry").getJSONObject("location").getDouble("lat");
latlng.add(latitude);
latlng.add(longitute);
}
catch (JSONException e)
{
longitute = 0;
latitude = 0;
Log.i("getLatLong", e.toString());
}
return latlng;
}
}
now we can call it inside our class by
latitude = new GetXMLTask().getLatLong(new GetXMLTask().getLocationInfo(address)).get(0);
longitude = new GetXMLTask().getLatLong(new GetXMLTask().getLocationInfo(address)).get(1);
I may not have the super optimised code , but this is working pretty fine for me , give it a try , just passed the address in your calling class

How to deserialize a small amount of JSON in WP7 using DataContractJsonSerializer

I'm trying to deserialize the JSON results from a web request.
Here is my code.
void myButton_Click(object sender, RoutedEventArgs e)
{
try
{
WebClient webClient = new WebClient();
Uri uri = new Uri("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/1/query?text=&geometry=&geometryType=esriGeometryPoint&inSR=&spatialRel=esriSpatialRelIntersects&relationParam=&objectIds=&where=POP1999%3E15000000&time=&returnCountOnly=true&returnIdsOnly=false&returnGeometry=false&maxAllowableOffset=&outSR=&outFields=STATE_NAME%2CMALES%2CFEMALES%2CPOP1999&f=json");
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
webClient.OpenReadAsync(uri);
//RESULT {"count":4}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
DataContractJsonSerializer ser = null;
try
{
//countertext.Text = DESERIALIZE COUNT HERE
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public class Counter
{
public int count { get; set; }
}
}
It seems like it should be pretty simple, but I cannot figure it out.
I want to use this code during a background agent and I can't use the ArcGIS runtime for windows Phone API during an Background agent because it is a third party API.
It should deserialize without a problem:
var ser = new DataContractJsonSerializer(typeof(Counter));
Counter r = (Counter) ser.ReadObject(e.Result);
System.Diagnostics.Debug.WriteLine(r.count); // 4