Language agnostic 如何从开放街道地图或谷歌地图中提取地理数据

Language agnostic 如何从开放街道地图或谷歌地图中提取地理数据,language-agnostic,google-maps,geography,openstreetmap,Language Agnostic,Google Maps,Geography,Openstreetmap,我需要使用openstreet地图或谷歌地图检索特定国家的所有城市名称。有API可用吗 或者有没有其他方法可以获取这些世界地理数据?从下载数据,我不知道你是否只限于谷歌地图或openstreet地图,但你可能会发现看看雅虎的woeid很有趣 我已经玩过这个游戏了,它非常强大。你绝对应该签出GeoNames。他们把整个世界都放在一个标准化的数据库中。你可以使用他们的 我下载美国数据库,并使用我在C中创建的连接器在数据库中插入州、市、镇和邮政编码 public static class Ge

我需要使用openstreet地图或谷歌地图检索特定国家的所有城市名称。有API可用吗


或者有没有其他方法可以获取这些世界地理数据?

从下载数据,我不知道你是否只限于谷歌地图或openstreet地图,但你可能会发现看看雅虎的woeid很有趣


我已经玩过这个游戏了,它非常强大。

你绝对应该签出GeoNames。他们把整个世界都放在一个标准化的数据库中。你可以使用他们的

我下载美国数据库,并使用我在C中创建的连接器在数据库中插入州、市、镇和邮政编码

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

}
也有开放的街道地图,你可以使用他们的地图


我不建议雅虎的新API,他们正在左右削减产品,你永远不知道它会持续多久。此外,您当前无法下载整个转储文件。

2013年1月29日更新:我已创建了一个包含世界上所有城市和人口密集地区的CSV数据集,以及一个纬度/经度区域质心,并将其置于公共域中。我将来自美国的USGS GNIS服务器和所有其他国家的NGA GNS服务器的数据合并在一起。以下是CSV文件布局的元数据和到数据集的链接:

第1列:ISO 3166-1 alpha-2国家代码。 第2栏:美国FIPS 5-2一级行政区划代码,例如州/省。 第3列:NGA GNS功能描述DSG代码。 第4列:NGA GNS唯一特征标识符UFI。 第5列:功能名称对应语言的ISO 639-1 alpha-2/3代码。 第6列:要素名称对应的语言脚本,如拉丁语、阿拉伯语、汉语等。 第7列:要素名称。 第8列:区域质心的纬度坐标。 第9列:区域质心的经度坐标

我查看了JonPell的解决方案。它可能需要一些评论。首先,我相信geonames.org从美国地质调查局GNIS服务器获取美国城市数据。你可以直接从他们那里获得下载文件

有人应该知道以下几点: ADM1代表一级行政区划。对美国来说,这是50个州、哥伦比亚特区、5个美国领土和4个自由联系州

ADM2代表二级行政区划。对美国来说,这些是阿拉斯加的县、自治区和人口普查指定区,路易斯安那州的教区,波多黎各的市镇,维尔京群岛的岛屿,马绍尔群岛,美国的小离岛,美属萨摩亚的地区,以及北马里亚纳群岛的市镇

PPL是人口密集的地方。我不知道geonames.org是如何分类的,但这个类别包括城市:大分区、独立区域和大型拖车公园。还包括一些历史古迹

我可以回答很多这样的问题。我是OpenGeoCode.Org公共领域地理空间团队的一员


安德鲁

感谢安德鲁的洞察力。。我刚刚查看了OpenGeoCode.Org网站……OpenGeoCode是只处理北美数据还是全球数据。。?我对覆盖全球地理数据的解决方案感兴趣……OpenGeoCode将在全球范围内提供一些高级地理数据。但现在,我们只计划为北美做详细的地理数据。我们专注于数据的高精度,这就是为什么目标更窄。有更多的数据在管道中,但这一切都要经过一个审查/调整过程。