2010-04-15 7 views

risposta

5

Si dovrebbe assolutamente verificare GeoNames. Hanno il mondo intero in un database standardizzato. Puoi download it o usare il loro API.

Ho scaricato il database degli Stati Uniti e uso un connettore che ho creato in C# per inserire Stati, città, città e codici postali nel mio database.

public static class GeoNamesConnector 
{ 
    #region GeoName Constants 
    private static readonly string GeoNamesPath = HttpContext.Current.Server.MapPath("~/App_Data/GeoNames/US.txt"); 
    const int GeoNameIdColumn = 0; 
    const int NameColumn = 1; 
    const int LatitudeColumn = 4; 
    const int LongitudeColumn = 5; 
    const int FeatureCodeColumn = 7; 
    const int CountryCodeColumn = 8; 
    const int Admin1CodeColumn = 10; 
    const int Admin2CodeColumn = 11; 
    #endregion 

    #region AlternateName Constants 
    private static readonly string AlternateNamesPath = HttpContext.Current.Server.MapPath("~/App_Data/GeoNames/alternateNames.txt"); 
    const int AlternateNameIdColumn = 0; 
    const int AltNameGeoNameIdColumn = 1; 
    const int IsoLanguageColumn = 2; 
    const int AlternateNameColumn = 3; 
    #endregion 

    public static void AddAllEntities(GeoNamesEntities entities) 
    { 
     //Remember to turn off Intellitrace 
     Stopwatch stopwatch = new Stopwatch(); 
     stopwatch.Start(); 
     var geoNamesSortedList = AddGeoNames(entities); 
     Trace.WriteLine(String.Format("Added GeoNames: {0}", stopwatch.Elapsed)); 
     stopwatch.Restart(); 

     SetupGeoNameChildRelationships(geoNamesSortedList, entities); 
     Trace.WriteLine(String.Format("Setup GeoName parent/child relationships: {0}", stopwatch.Elapsed)); 
     stopwatch.Restart(); 

     AddPostalCodeAlternateNames(geoNamesSortedList, entities); 
     Trace.WriteLine(String.Format("Added postal codes and relationships with parent GeoNames: {0}", stopwatch.Elapsed)); 
    } 

    private static SortedList<int, GeoName> AddGeoNames(GeoNamesEntities entities) 
    { 
     var lineReader = File.ReadLines(GeoNamesPath); 
     var geoNames = from line in lineReader.AsParallel() 
         let fields = line.Split(new char[] { '\t' }) 
         let fieldCount = fields.Length 
         where fieldCount >= 9 
         let featureCode = fields[FeatureCodeColumn] 
         where featureCode == "ADM1" || featureCode == "ADM2" || featureCode == "PPL" 
         let name = fields[NameColumn] 
         let id = string.IsNullOrEmpty(fields[GeoNameIdColumn]) ? 0 : int.Parse(fields[GeoNameIdColumn]) 
         orderby id 
         select new GeoName 
         { 
          Id = Guid.NewGuid(), 
          GeoNameId = id, 
          Name = fields[NameColumn], 
          Latitude = string.IsNullOrEmpty(fields[LatitudeColumn]) ? 0 : Convert.ToDecimal(fields[LatitudeColumn]), 
          Longitude = string.IsNullOrEmpty(fields[LongitudeColumn]) ? 0 : Convert.ToDecimal(fields[LongitudeColumn]), 
          FeatureCode = featureCode, 
          CountryCode = fields[CountryCodeColumn], 
          Admin1Code = fieldCount < 11 ? "" : fields[Admin1CodeColumn], 
          Admin2Code = fieldCount < 12 ? "" : fields[Admin2CodeColumn] 
         }; 
     var sortedList = new SortedList<int, GeoName>(); 
     int i = 1; 
     foreach (var geoname in geoNames) 
     { 
      sortedList.Add(geoname.GeoNameId, geoname); 
      entities.GeographicAreas.AddObject(geoname); 
      if (i++ % 20000 == 0) 
       entities.SaveChanges(); 
     } 
     entities.SaveChanges(); 
     return sortedList; 
    } 

    private static void SetupGeoNameChildRelationships(SortedList<int, GeoName> geoNamesSortedList, GeoNamesEntities entities) 
    { 
     foreach (var geoName in geoNamesSortedList.Where(g => g.Value.FeatureCode == "ADM2" || g.Value.FeatureCode == "ADM1")) 
     { 
      //Setup parent child relationship 
      IEnumerable<KeyValuePair<int, GeoName>> children = null; 
      switch (geoName.Value.FeatureCode) 
      { 
       case "ADM1": 
        children = 
         geoNamesSortedList.Where(
          g => 
          g.Value.FeatureCode == "ADM2" && 
          g.Value.Admin1Code == geoName.Value.Admin1Code); 
        break; 
       case "ADM2": 
        children = 
         geoNamesSortedList.Where(
          g => 
          g.Value.FeatureCode == "PPL" && 
          g.Value.Admin1Code == geoName.Value.Admin1Code && 
          g.Value.Admin2Code == geoName.Value.Admin2Code); 
        break; 
      } 
      if (children != null) 
      { 
       foreach (var child in children) 
        geoName.Value.Children.Add(child.Value); 
      } 
      entities.SaveChanges(); 
     } 
    } 

    private static void AddPostalCodeAlternateNames(SortedList<int, GeoName> geoNamesSortedList, GeoNamesEntities entities) 
    { 
     var lineReader = File.ReadLines(AlternateNamesPath); 
     var alternativeNames = from line in lineReader.AsParallel() 
           let fields = line.Split(new char[] { '\t' }) 
           let fieldCount = fields.Length 
           where fieldCount >= 4 && fields[IsoLanguageColumn] == "post" 
           let geoNameId = int.Parse(fields[AltNameGeoNameIdColumn]) 
           orderby geoNameId 
           select new AlternateName 
           { 
            Id = Guid.NewGuid(), 
            AlternateNameId = int.Parse(fields[AlternateNameIdColumn]), 
            ParentGeoNameId = geoNameId, 
            Name = fields[AlternateNameColumn], 
            IsoLanguage = fields[IsoLanguageColumn] 
           }; 
     //Iterate through to convert from lazy (AsParallel) so it is ready for use 
     foreach (var alternateName in alternativeNames) 
     { 
      int key = alternateName.ParentGeoNameId; 
      if (geoNamesSortedList.ContainsKey(key)) 
      { 
       entities.GeographicAreas.AddObject(alternateName); 
       alternateName.Parent = geoNamesSortedList[key]; 
      } 
     } 
     entities.SaveChanges(); 
    } 

} 

C'è anche Open Street Maps che è possibile download o utilizzare i loro API.

Non suggerisco che la nuova API di Yahoo stia tagliando i prodotti a destra e sinistra e non si sa mai quanto tempo ci sarà in giro. Inoltre non è possibile scaricare un intero dump al momento.

+0

suo bello. .. grazie jonperl .. :) – RameshVel

1

non so se siete limitati a Google Maps o mappa OpenStreet ma si potrebbe trovare dare un'occhiata a WOEID di Yahoo interessante.

http://developer.yahoo.com/geo/geoplanet/

Ho avuto un gioco intorno a questo ed è estremamente potente.

+0

grazie azp74 .. che sembra molto promettente .. :) – RameshVel

3

29 gennaio 2013 Aggiornamento: ho creato un set di dati CSV di tutte le città e i luoghi popolati del mondo, insieme a un centroide di latitudine/longitudine e collocato nel pubblico dominio. Ho combinato i dati dal server US GN GNIS per gli Stati Uniti e il server GNGA GNS per tutti gli altri paesi. Di seguito è riportato i metadati per il layout di file CSV e link per il set di dati:

http://www.opengeocode.org/download.php#cities

Colonna 1: ISO 3166-1 alpha-2 del paese.
Colonna 2: US FIPS 5-2 Codice di divisione amministrativa di primo livello (ad es. Stato/provincia).
Colonna 3: codice di descrizione della funzione GNG (NGA GNS).
Colonna 4: identificatore di caratteristiche univoche NGA GNS (UFI).
Colonna 5: codice ISO 639-1 alfa-2/3 per la lingua corrispondente al nome della funzione.
Colonna 6: script di lingua (ad esempio, latino, arabo, cinese, ecc.) Corrispondente al nome della funzione.
Colonna 7: nome funzione.
Colonna 8: Coordinata della latitudine del baricentro dell'area.
Colonna 9: Coordinata di longitudine del centroide dell'area.


Ho visto la soluzione di Jonperl. Potrebbe usare alcuni commenti. Innanzitutto, credo che geonames.org recuperi i dati della città degli Stati Uniti dal server GNSS di USGS. Si può ottenere direttamente un file di download da loro.

http://geonames.usgs.gov/domestic/download_data.htm

alcuni punti qualcuno dovrebbe sapere: ADM1 acronimo di divisione amministrativa di primo livello.Per gli Stati Uniti, questi sono i 50 stati, District of Columbia, i 5 territori degli Stati Uniti e 4 stati associati liberamente.

ADM2 è la divisione amministrativa di secondo livello. Per gli Stati Uniti, si tratta di aree contee, distretti e censimenti designati per l'Alaska, parrocchie per la Louisiana, municipi per Porto Rico, isole per le Isole Vergini, Isole Marshall, Isole minori secondarie degli Stati Uniti, distretti per Samoa americane e comuni per Isole Marianne del Nord .

PPL sono luoghi popolati. Non sono sicuro di come geonames.org li ordinasse, ma questa categoria include le città: grandi suddivisioni, aree unicorporate e grandi parchi per roulotte. Thney include anche alcuni luoghi storici.

Posso rispondere a molte di queste domande. Sono parte di un pubblico dominio squadra geospaziali a OpenGeoCode.Org

Andrew

+0

grazie Andrew per l'intuizione .. ho appena controllato il sito OpenGeoCode.Org ... è OpenGeoCode si occupa solo di dati del Nord America o in tutto il mondo ..? Sono interessato a una soluzione che copra i dati geografici in tutto il mondo .... – RameshVel

+0

OpenGeoCode fornirà alcuni geodati di alto livello in tutto il mondo. Ma per ora, abbiamo solo intenzione di fare geodati dettagliati per il Nord America. Siamo concentrati sull'alta accuratezza dei dati, ecco perché l'obiettivo più ristretto. Ci sono più dati nella pipeline, ma tutto passa attraverso un processo di revisione/ottimizzazione. –

Problemi correlati