Pergunta

Preciso recuperar todos os nomes da cidade de um país específico usando o OpenStreet Mapa ou o Google Maps. Existe alguma API disponível?

Ou existe outra maneira de obter dados geográficos deste mundo?

Foi útil?

Solução

Você definitivamente deve fazer o checkout geonoms. Eles têm o mundo inteiro em um banco de dados padronizado. Você pode baixe ou use o deles API.

Baixar o banco de dados dos EUA e uso um conector que criei em C# para inserir estados, cidades, cidades e códigos postais no meu banco de dados.

    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();
    }

}

Há também mapas de rua abertos que você pode download ou use o deles API.

Eu não sugiro a nova API do Yahoo que eles estejam cortando produtos para a esquerda e para a direita e você nunca sabe quanto tempo vai por perto. Além disso, você não pode baixar um dump inteiro atualmente.

Outras dicas

29 de janeiro de 2013 Atualização: criei um conjunto de dados CSV de todas as cidades e lugares povoados do mundo, juntamente com um centróide da área de latitude/longitude, e colocado no domínio público. Combinei dados do servidor USGS GNIS para os EUA e do servidor NGA GNS para todos os outros países. Abaixo está os metadados para o layout do arquivo CSV e o link para o conjunto de dados:

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

Coluna 1: ISO 3166-1 Código do país alfa-2.
Coluna 2: US FIPS 5-2 Código de divisão administrativa do 1º nível (por exemplo, estado/província).
Coluna 3: Código de descrição do recurso NGA GNS (DSG).
Coluna 4: NGA GNS Identificador de recurso exclusivo (UFI).
Coluna 5: Código ISO 639-1 Alpha-2/3 para o idioma correspondente ao nome do recurso.
Coluna 6: Script de idioma (por exemplo, latim, árabe, chinês, etc.) correspondente ao nome do recurso.
Coluna 7: Nome do recurso.
Coluna 8: coordenada de latitude da área centróide.
Coluna 9: coordenada de longitude da área centróide.


Eu olhei para a solução de Jonperl. Pode usar alguns comentários. Primeiro, acredito que geonoms.org obtém os dados da cidade dos EUA do servidor USGS GNIS. Pode -se obter diretamente um arquivo de download deles.

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

Alguns pontos que alguém deve saber: ADM1 significa divisão administrativa de primeiro nível. Para os EUA, esses são os 50 estados, o Distrito de Columbia, os 5 territórios dos EUA e 4 estados associados livremente.

ADM2 significa divisão administrativa de segundo nível. Para os EUA, esses são condados, bairros e áreas designadas pelo Censo para o Alasca, paróquias para a Louisiana, municípios para Porto Rico, ilhas para as Ilhas Virgens, Ilhas Marshall, ilhas existentes da US Islands, distritos da Samoa Americana e municípios para Nothern Mariana .

PPL são locais povoados. Não tenho certeza de como o geonames.org os classifica, mas essa categoria inclui com cidades: grandes subdivisões, áreas unicorporadas e grandes parques de reboques. Thney também inclui alguns lugares históricos.

Eu posso responder muitas dessas perguntas. Faço parte de uma equipe geoespacial de domínio público em opengeocode.org

Andrew

Baixar os dados de http://www.geonames.org/

Não sei se você está restrito ao mapa do Google Maps ou OpenStreet, mas pode achar interessante o Woeid do Yahoo.

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

Eu tive uma brincadeira com isso e é extremamente poderoso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top