Как извлечь географические данные из открытой карты улиц или карт Google - PullRequest
5 голосов
/ 15 апреля 2010

Мне нужно получить все названия городов из определенной страны, используя openstreet map или google maps. есть ли доступный API?

или есть какой-нибудь другой способ получить географические данные этого мира?

Ответы [ 4 ]

5 голосов
/ 12 января 2011

Вы обязательно должны проверить GeoNames. У них весь мир в стандартизированной базе данных. Вы можете скачать его или использовать их API .

Я загружаю базу данных США и использую соединитель, созданный в 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 .

Я не предлагаю новый API Yahoo, они сокращают продукты влево и вправо, и вы никогда не знаете, как долго это будет продолжаться. Также вы не можете скачать весь дамп в настоящее время.

3 голосов
/ 18 февраля 2011

Январь 29, 2013 Обновление: я создал CSV-набор данных обо всех городах и населенных пунктах мира, а также о центроиде широты и долготы, который был открыт для общего доступа. Я объединил данные с сервера USGS GNIS для США и сервера NGA GNS для всех других стран. Ниже приведены метаданные для формата файла CSV и ссылка на набор данных:

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

Колонка 1: код страны ISO 3166-1 alpha-2.
Колонка 2: США FIPS 5-2 Код административного деления 1-го уровня (например, штат / провинция).
Колонка 3: Код описания функции NGA GNS (DSG).
Колонка 4: Уникальный идентификатор NGA GNS (UFI).
Колонка 5: ISO 639-1 alpha-2/3 код для языка, соответствующего названию функции.
Колонка 6: языковой скрипт (например, латинский, арабский, китайский и т. Д.), Соответствующий названию объекта.
Колонка 7: Название функции.
Столбец 8: координата широты центроида области.
Столбец 9: долгота координаты центроида области.


Я посмотрел на решение от Jonperl. Это может использовать некоторые комментарии. Во-первых, я считаю, что geonames.org получает данные о городе США с сервера USGS GNIS. С них можно напрямую скачать файл для скачивания.

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

Несколько моментов, которые кто-то должен знать: ADM1 обозначает административное деление первого уровня. Для США это 50 штатов, округ Колумбия, 5 территорий США и 4 свободно ассоциированных штата.

ADM2 обозначает административное деление второго уровня. Для США это округа, районы и переписи, обозначенные для Аляски, приходы для Луизианы, муниципалитеты для Пуэрто-Рико, острова для Виргинских островов, Маршалловы острова, Малые отдаленные острова США, районы для Американского Самоа и муниципалитеты для Северных Марианских островов ,

ППЛ - населенные пункты. Я не уверен, как geonames.org сортирует их, но эта категория включает в себя города: большие подразделения, зоны без регистрации и большие трейлерные парки. Тней также включает в себя некоторые исторические места.

Я могу ответить на многие из этих вопросов. Я являюсь частью геопространственной команды общественного доступа в OpenGeoCode.Org

Андрей

2 голосов
/ 15 апреля 2010

Загрузить данные из http://www.geonames.org/

1 голос
/ 15 апреля 2010

Я не знаю, ограничены ли вы картами Google или openstreet, но вам может показаться интересным взгляд на Yahoo.

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

Я поиграл с этим, и он очень мощный.

...