71 messaggi dal 06 gennaio 2019
Buongiorno a tutti,
attraverso la richiesta URL https://mioserver/nominatim/search.php?q=via+Tuscolana+roma&format=json&limit=1
ottengo il seguente risultato:
[{"place_id":251190227,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"way","osm_id":665226866,"boundingbox":["41.8099822","41.8116608","12.6601041","12.6685664"],"lat":"41.8108529","lon":"12.6650077","display_name":"Via Tuscolana, Colle Maria, Frascati, RM, Lazio, 00044, Italia","class":"highway","type":"primary","importance":0.30000000000000004}]


questo è l'output in formato json della mia richiesta.

adesso vorrei poter leggere tale output e estrarre i dati relativi a latitudine e longitudine ma non riesco a venirne a capo...

di seguito posto il codice che sto usando, purtroppo con pessimi risultati...

   
using System.Net;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace GICS.Models
{
    public class Geo_convert
    {
        public void converti_indirizzo(string indirizzo, string citta)
        {
            string address = indirizzo + "," + citta;
            WebClient webClient = new WebClient();
            var jsondata = webClient.DownloadData("http://mioserver/nominatim/search?q=" + address + "&format=json&limit=1");
           var json = System.Text.Encoding.UTF8.GetString(jsondata).TrimEnd('\0'); 
            var obj = JsonConvert.DeserializeObject<RootObject>(json);
           foreach (var item in obj.response)
            {
                Console.WriteLine(item.Lat);
            }

        }
    }
class RootObject
    {
        public List<Item> response { get; set; }
    }
    class Item
    {

        public string Lat { get; set; }
        public string Lon { get; set; }
        public string Display_name { get; set; }
        public string _class { get; set; }
        public string Type { get; set; }
    }


Qualcuno potrebbe darmi qualche aiuto su come correggere, qualora io sia sulla buona strada, il codice che ho scritto? Grazie mille
71 messaggi dal 06 gennaio 2019
Avevo dimenticato di scrivere che sto sviluppando in asp.net Mvc c#
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
vedo che il json che ti viene restituito rappresenta un array. Tu invece stai cercando di deserializzarlo in un oggetto "RootObject" che dentro ha una proprietà "response" ma nel json non vedo alcuna proprietà "response". È probabilmente per questo che hai un errore.

Allora, prova a deserializzare il JSON direttamente su un array di Item.
string address = HttpUtility.UrlEncode(indirizzo + "," + citta);
using (WebClient webClient = new WebClient())
{
  var json = webClient.DownloadString("http://mioserver/nominatim/search?q=" + address + "&format=json&limit=1");
  var obj = JsonConvert.DeserializeObject<Item[]>(json);
  foreach (var item in obj)
  {
    Console.WriteLine(item.Lat);
  }
}


ciao,
Moreno

P.S. Ho aggiunto un blocco using attorno al WebClient, in modo da assicurarmi che venisse distrutto correttamente al termine del suo utilizzo, dato che è una classe che implementa IDisposable.
Inoltre ho usato HttpUtility.UrlEncode, dato che l'address deve essere usato in un URL e perciò alcuni caratteri speciali devono essere codificati altrimenti rischieresti che il webserver di nominatim non riesca ad interpretare correttamente la richiesta.
E infine ho usato il metodo DownloadString del WebClient che ti evita di dover fare la conversione.

Cerca di usare i metodi asincroni quando hai a che fare con operazioni che richiedono un'attesa che non è legata ai calcoli della CPU. Cioè: anziché usare DownloadString usa DownloadStringAsync e rendi la tua action asincrona. Questo migliorerà le prestazioni dell'applicazione se hai tanti utenti contemporanei.

ciao,
Moreno
Modificato da BrightSoul il 21 marzo 2019 08:47 -

Enjoy learning and just keep making
71 messaggi dal 06 gennaio 2019
Ciao Moreno,
grazie mille per la tua risposta.
ho modificato il codice ma non capisco perchè mi dice che non viene restituito un valore su tutti i percorsi.
            public (double Lati, double Long) Converti_indirizzo(string indirizzo, string citta)
            {
               double Lati = -1000;
               double Long = -1000;

                string address = HttpUtility.UrlEncode(indirizzo + "," + citta);
                using (WebClient webClient = new WebClient())
                {
                    var json = webClient.DownloadString("http://mioip/nominatim/search?q=" + address + "&format=json&limit=1");
                    var obj = JsonConvert.DeserializeObject<Item[]>(json);
                foreach (var item in obj)

                    return (Lati, Long);
                }

            }
        }
        class Item
        {

            public double Lat { get; set; }
            public double Lon { get; set; }
            public string Display_name { get; set; }
            public string _class { get; set; }
            public string Type { get; set; }
        }


Inoltre se tento di usare il DownloadStringAsync

var json = webClient.DownloadStringAsync("http://mioip/nominatim/search?q=" + address + "&format=json&limit=1");


mi viene restituito l'errore che non è possibile assegnare void a una variabile tipizzata in modo implicito.
11.886 messaggi dal 09 febbraio 2002
Contributi

perchè mi dice che non viene restituito un valore su tutti i percorsi.

Te lo dice perché il tuo array di Item potrebbe essere vuoto e in questa situazione il foreach non ciclerebbe neanche una volta, per cui il return non verrebbe eseguito.

Non ho capito se vuoi restituire solo la prima coppia latitudine/longitudine trovata oppure se vuoi restituirle tutte, prese da tutti gli Item.

Per ora prova a restituirle tutte, in questo modo. Nota che ho modificato il valore di ritorno in List<(double Lati, double Long)> perché ora sto restituendo una lista di tuple.

public List<(double Lati, double Long)> Converti_indirizzo(string indirizzo, string citta)
{

  string address = HttpUtility.UrlEncode(indirizzo + "," + citta);
  using (WebClient webClient = new WebClient())
  {
    var json = webClient.DownloadString("http://mioip/nominatim/search?q=" + address + "&format=json&limit=1");
    return JsonConvert.DeserializeObject<Item[]>(json)
      .Select(item => (item.Lat, item.Lon)) //Di ogni Item selezioniamo solo la tupla con Lat e Lon
      .ToList();
  }
}


Per ora lascia stare il metodo asincrono. Prima verifica che in questo modo funzioni.

ciao,
Moreno
Modificato da BrightSoul il 22 marzo 2019 08:47 -

Enjoy learning and just keep making
71 messaggi dal 06 gennaio 2019
.Select(item => (item.Lat, item.Lon))

qui mi dice che non contiene una definizione per Select
71 messaggi dal 06 gennaio 2019
shadow76 ha scritto:
.Select(item => (item.Lat, item.Lon))

qui mi dice che non contiene una definizione per Select


Risolto con using System.Linq
71 messaggi dal 06 gennaio 2019
Grazie mille Moreno,

sono riuscito e funziona adesso mi restituisce le coordinate.


per il discorso del metodo asincrono?

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.