Comment obtenir les Coordonnées lorsque l'Adresse est Connue?
J'ai tiré et adapté le code suivant à partir d'Adam Freeman livre "Métro a Révélé: la Construction d'applications Windows 8 avec XAML et C#" pour obtenir l'Adresse lorsque les Coordonnées sont connues:
public static async Task<string> GetAddressForCoordinates(double latitude, double longitude)
{
HttpClient httpClient = new HttpClient {BaseAddress = new Uri("http://nominatim.openstreetmap.org")};
HttpResponseMessage httpResult = await httpClient.GetAsync(
String.Format("reverse?format=json&lat={0}&lon={1}", latitude, longitude));
JsonObject jsonObject = JsonObject.Parse(await httpResult.Content.ReadAsStringAsync());
return jsonObject.GetNamedObject("address").GetNamedString("road");
}
Comment puis-je obtenir le contraire (les Coordonnées si l'Adresse est connue)?
Mise à JOUR
Je suis en ajoutant une prime à cela; ce que j'ai déjà (voir ci-dessus) est le géocodage inversé (l'obtention de l'adresse pour les coordonnées); ce dont j'ai besoin est de géocodage (obtenir les coordonnées de l'adresse).
Basé sur mon géocodage inversé code ci-dessus, j'imagine qu'il pourrait être quelque chose comme ceci:
public static async Task<string> GetCoordinatesForAddress(string address)
{
HttpClient httpClient = new HttpClient {BaseAddress = new Uri("http://nominatim.openstreetmap.org")};
HttpResponseMessage httpResult = await httpClient.GetAsync(
String.Format("format=json&address={0}", address));
JsonObject jsonObject = JsonObject.Parse(await httpResult.Content.ReadAsStringAsync());
return jsonObject.GetNamedObject("address").GetNamedString("lat"); //<-- what about "lon"?
}
...mais je ne sais pas comment combiner les deux coordonnées (longitude et latitude) valeurs (en supposant que cela est correct, ou proche de l'être correct). Quelqu'un peut-il vérifier cela, il faut la nettoyer, ou de fournir un meilleur exemple (soit à l'aide de nominatim ou autre)?
Mise à JOUR 2
Pour répondre à Pierre Ritchie question/commentaire ci-dessous:
Dans l'original (géocodage inversé code), j'ai:
return jsonObject.GetNamedObject("address").GetNamedString("road");
Il renvoie simplement la route; donc quelque chose comme "157 Riverside Avenue" je suppose.
Mais pour le géocodage (besoin de deux valeurs, une longitude et une latitude), j'ai ce pseudo-code:
return jsonObject.GetNamedObject("address").GetNamedString("lat"); //<-- what about "lon"?
Donc je ne sais pas si j'ai besoin de changer la valeur de retour de la Tâche<string
> à la Tâche<List
et appel (commentaires pseudo-code) [Note: je vais avoir un moment difficile de s'échapper de la chevrons pour Tâche avec une Liste de string]:
var latitude jsonObject.GetNamedObject("address").GetNamedString("lat");
var longitude jsonObject.GetNamedObject("address").GetNamedString("lat");
List<string> listCoordinates = new List<string>();
listCoordinates.Add(latitude);
listCoordinates.Add(longitude);
return listCoordinates;
...ou comme:
string latitude jsonObject.GetNamedObject("address").GetNamedString("lat");
string longtude jsonObject.GetNamedObject("address").GetNamedString("long");
return string.Format("{0};{1}", latitude, longitude);
...ou ???
Mise à JOUR 3
En réponse à la offerte code Json pour le géocodage:
Basé sur l'original de géocodage inversé code, ne devrait pas l'appeler plus comme ceci:
HttpClient httpClient = new HttpClient { BaseAddress = new Uri("http://nominatim.openstreetmap.org/") };
var httpResult = await httpClient.GetAsync(
String.Format("search?format=json&addressdetails={0}", address);
...mais en tout cas:
Le JArray type n'est pas reconnu, si JsonArray est.
Le JValue type n'est pas reconnu, si JsonValue est.
Le JsonConverter type n'est pas reconnu; peut-être une partie de Json.Net?
Le plus proche que je peux venir à l'obtention de la proferred code à compiler est:
var result = await httpResult.Content.ReadAsStringAsync();
var r = (JsonArray)JsonConverter.DeserializeObject(result);//<-- JsonConvert[er] not recognized; part of Json.NET?
var latString = ((JsonValue)r[0]["lat"]).ValueType as string;
var longString = ((JsonValue)r[0]["lon"]).ValueType as string;
...mais même avec ce (proche, mais pas de Bob Seger), JsonConvert ainsi que JsonConverter ne sont pas reconnus.
Mise à JOUR 4
Après piocher de manière plus concertée par le biais de la documentation à http://wiki.openstreetmap.org/wiki/Nominatim#Search, je pense que mon original (géocodage inversé) méthode peut-être mieux que:
public static async Task`<string`> GetAddressForCoordinates(double latitude, double longitude)
{
HttpClient httpClient = new HttpClient {BaseAddress = new Uri("http://nominatim.openstreetmap.org/")};
HttpResponseMessage httpResult = await httpClient.GetAsync(
String.Format("reverse?format=json&lat={0}&lon={1}", latitude, longitude));
JsonObject jsonObject = JsonObject.Parse(await httpResult.Content.ReadAsStringAsync());
string house = jsonObject.GetNamedObject("addressparts").GetNamedString("house");
string road = jsonObject.GetNamedObject("addressparts").GetNamedString("road");
string city = jsonObject.GetNamedObject("addressparts").GetNamedString("city");
string state = jsonObject.GetNamedObject("addressparts").GetNamedString("state");
string postcode = jsonObject.GetNamedObject("addressparts").GetNamedString("postcode");
string country = jsonObject.GetNamedObject("addressparts").GetNamedString("country");
return string.Format("{0} {1}, {2}, {3} {4} ({5})", house, road, city, state, postcode, country);
}
Ce serait de retour, pour la coordonnée correspondante args passé, quelque chose comme: "157 Riverside Avenue, Champaign, IL 55555 (états-unis)"
Ce que je trouve bizarre dans la documentation il n'y a pas "d'état" élément parmi les parties de l'adresse; si c'est vraiment vrai, et pas seulement une documentation de surveillance, mon code ci-dessus ne parviennent pas à l'appel de GetNamedString("etat").
Je ne suis toujours pas sûr de ce que le droit de la syntaxe, etc., devrait être pour le contraire (géocodage) méthode, obtenir les coordonnées de retour après passage dans une adresse.
Mise à JOUR 5
Ok, j'ai téléchargé Json.NET et il a obtenu de la compilation. Je n'ai pas encore testé, mais j'ai marqué Pierre Ritchie, comme L' (50 points) réponse.
C'est le code que j'utilise:
public static async Task<string> GetCoordinatesForAddress(string address)
{
HttpClient httpClient = new HttpClient { BaseAddress = new Uri("http://nominatim.openstreetmap.org/") };
HttpResponseMessage httpResult = await httpClient.GetAsync(
String.Format("search?q={0}&format=json&addressdetails=1", Pluggify(address))); //In my Pluggify() method, I replace spaces with + and then lowercase it all
var result = await httpResult.Content.ReadAsStringAsync();
var r = (JArray)JsonConvert.DeserializeObject(result);
var latString = ((JValue)r[0]["lat"]).Value as string;
var longString = ((JValue)r[0]["lon"]).Value as string;
return string.Format("{0};{1}", latString, longString);
}
Aussi:
Une drôle de chose s'est passé sur le chemin du retour de ce forum: lors de l'installation Json.NET via NuGet, j'ai aussi vu ".NET plus rapide du Sérialiseur JSON par ServiceStack" qui prétend être 3X plus rapide que Json.NET. FIWW, il a été mis à jour plus récemment que Json.NET. Pensées/réaction?
Mise à JOUR 6
J'ai ce code pour mettre en œuvre cette (app id et le code ont été changés pour protéger les semi-innocent
(moi)):
//If address has not been explicitly entered, try to suss it out:
address = textBoxAddress1.Text.Trim();
lat = textBoxLatitude1.Text.Trim();
lng = textBoxLongitude1.Text.Trim();
if (string.IsNullOrWhiteSpace(address))
{
address = await SOs_Classes.SOs_Utils.GetAddressForCoordinates(lat, lng);
}
. . .
public async static Task<string> GetAddressForCoordinates(string latitude, string longitude)
{
string currentgeoLoc = string.Format("{0},{1}", latitude, longitude);
string queryString = string.Empty;
string nokiaAppID = "j;dsfj;fasdkdf";
object nokiaAppCode = "-14-14-1-7-47-178-78-4";
var hereNetUrl = string.Format(
"http://demo.places.nlp.nokia.com/places/v1/discover/search?at={0}&q={1}&app_id={2}
&app_code={3}&accept=application/json",
currentgeoLoc, queryString, nokiaAppID, nokiaAppCode);
//get data from HERE.net REST API
var httpClient = new HttpClient();
var hereNetResponse = await httpClient.GetStringAsync(hereNetUrl);
//deseralize JSON from Here.net
using (var tr = new StringReader(hereNetResponse))
using (var jr = new JsonTextReader(tr))
{
var rootObjectResponse = new JsonSerializer
().Deserialize<JsonDOTNetHelperClasses.RootObject>(jr);
var firstplace = rootObjectResponse.results.items.First();
return HtmlUtilities.ConvertToText(firstplace.vicinity);
//NOTE: There is also a title (such as "Donut Shop", "Fire stations", etc.?) and type (such as "residence" or "business", etc.?)
}
}
...mais sur cette ligne dans GetAddressForCoordinates():
var firstplace = rootObjectResponse.results.items.First();
...Je reçois ce message d'erreur: "*Système d'.InvalidOperationException est pas gérée par le code de l'utilisateur
HResult=-2146233079
Message=Séquence contient pas d'éléments
Source=Système.De base
StackTrace:
au Système.Linq.Énumérable.Première[TSource](IEnumerable`1 source)
au SpaceOverlays.SOs_Classes.SOs_Utils.d__12.MoveNext() en c:...*"
La valeur de hereNetResponse est:
{"results":{"items":[]},"search":{"context":{"location":{"position":[38.804967,-90.113183],"address":
{"postalCode":"62048","city":"Hartford","stateCode":"IL","county":"Madison","countryCode":"USA","country":"
USA","text":"Hartford IL 62048
USA"}},"type":"urn:nlp-types:place","href":"http://demo.places.nlp.nokia.com/places/v1/places/loc-
dmVyc2lvbj0xO3RpdGxlPUhhcnRmb3JkO2xhdD0zOC44MDQ5Njc7bG9uPS05MC4xMTMxODM7Y2l0eT1IY
XJ0Zm9yZDtwb3N0YWxDb2RlPTYyMDQ4O2NvdW50cnk9VVNBO3N0YXRlQ29kZT1JTDtjb3VudHk9TWFka
XNvbjtjYXRlZ29yeUlkPWNpdHktdG93bi12aWxsYWdl;context=Zmxvdy1pZD02YmUzZDM4Yi0wNGVhLTUyM
jgtOWZmNy1kNWNkZGM0ODI5OThfMTM1NzQyMDI1NTg1M18wXzE2MA?
app_id=F6zpNc3TjnkiCLwl_Xmh&app_code=QoAM_5BaVDZvkE2jRvc0mw"}}}
...donc, il semblerait qu'il y est de la validité des informations à l'intérieur de là-bas, comme devrait revenir "Hartford, IL"
Et dans tous les cas, un vide valeur de retour ne devrait pas lancer une exception, je pense...
OriginalL'auteur B. Clay Shannon | 2012-12-18
Vous devez vous connecter pour publier un commentaire.
Ce que vous demandez est tout simplement "géocodage". Si vous souhaitez utiliser Nominatim plus précisément, ils appellent cela "Recherche". C'est, dans une certaine mesure, la validation de l'adresse; mais une partie de la "validation" est, y compris les coordonnées (boîte englobante, lat/long, etc.; selon ce qui est recherché et du type de résultat). Il y a beaucoup de détails sur les résultats, trop de simplement poster ici; mais ce détail peut être trouvé ici: http://wiki.openstreetmap.org/wiki/Nominatim#Search (y compris examles).
Vous aurez à analyser les résultats (XML, JSON, ou HTML) pour obtenir les champs qui vous intéressent.
Mise à jour 1:
Quoi faire avec les valeurs réelles: il dépend. Si vous souhaitez afficher les coordonnées dans un formulaire, vous pouvez simplement mettre la lat et long chaînes en contrôles individuels. Si vous voulez le mettre dans un seul contrôle, pourraient utiliser
string.Format("{0}, {1}", latString, longString)
. Si vous souhaitez utiliser les coords avec diverses méthodes/types pour une application du Windows Store, vous pourriez avoir besoin d'utiliser laMicrosoft.Maps.MapControl.Location
classe. Par exemple:Ci-dessus suppose que vous avez extrait la lat et long à partir de la réponse et les mettre dans
latString
,longString
respectivement.Certaines interfaces peuvent exiger lat/long en tant que double séparée de valeurs, auquel cas il suffit d'utiliser
latNumber
etlongNumber
ci-dessus.Ci-dessus, cela dépend vraiment spécifiquement sur les interfaces que vous souhaitez utiliser. Mais, le ci-dessus devrait vous donner assez d'utiliser la plupart des interfaces.
Mise à jour 2:
Si la question n'est pas "comment obtenir les coordonnées", mais "comment analyser les objets json", alors je vous recommande d'utiliser JSon.Net pour obtenir les coordonnées lat/long des chaînes dans le résultat json. Par exemple:
...voir ci-dessus.w.r.t. que faire avec
latString
etlongString
"comment combiner les coordonnées" pour faire quoi?
Ma réponse est trop long pour un commentaire, donc il est maintenant mise à Jour 2 ci-dessus.
C'est un peu pas clair ce que vous demandez, il apparaît que c'est pas "comment obtenir les coordonnées", mais "comment analyser Json"; j'ai donc ajouté un couple de mises à jour de ma réponse.
Ce que je vous demande est ce que le code devrait être de retour une liste de chaîne de caractères contenant la latitude de la première chaîne et la longitude de la deuxième chaîne, ou un point-virgule séparés valeur dans une chaîne de caractères.
OriginalL'auteur Peter Ritchie
Si vous cherchez des cartes google geocoding, vous pouvez le trouver ici:
https://developers.google.com/maps/documentation/geocoding/
et un exemple d'utilisation est:
http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false
convertir en Json, et de prendre la Géométrie de l'objet.
en ce qui concerne comment, en gros, de retour de deux valeurs d'une fonction en C# vous avez 4 options:
OriginalL'auteur Alon Bar David
Microsoft Mappoint aussi contaisn une API vous pourriez faire usage de. Il est capable de retourner geocoordinates.
Ne peux pas dire cela, mais son facilement utilisé avec C# en général.
En fait, il est maintenant l'API Bing Maps et il fonctionne très bien avec les Applications du Windows Store. Il y a un Bing SDK dans les Outils|menu Extension pour Visual Studio. Télécharger le kit de développement et d'ajouter la référence à votre projet. Vous aurez besoin d'une clé (actuellement libre) vous pouvez obtenir ici, microsoft.com/maps/developers/web.aspx
OriginalL'auteur CSharpie