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...

BTW, le code que j'ai posté dans la mise à Jour 2 compile et fonctionne très bien avec nominatim et en ajoutant JSon.Net avec Nuget.

OriginalL'auteur B. Clay Shannon | 2012-12-18