2010-04-15 1 views
5

Мне нужно получить все названия городов из определенной страны, используя открытую карту или карты Google. есть ли доступный API?Как извлечь географические данные с открытой карты улиц или карт Google

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

ответ

5

Обязательно проверьте GeoNames. У них есть весь мир в стандартизованной базе данных. Вы можете download it или использовать их 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(); 
    } 

} 

Существует также Open Street Maps, которые вы можете download или использовать их API.

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

+0

Его приятно. .. спасибо jonperl .. :) – RameshVel

1

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

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

У меня было играть вокруг с этим, и это очень мощный.

+0

благодаря azp74 .. что выглядит очень перспективным .. :) – RameshVel

3

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

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

Колонка 1: ISO 3166-1 альфа-2 код страны.
Колонка 2: US 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 получает данные города США с сервера GNG USGS. Можно напрямую получить от них файл загрузки.

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

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

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

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

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

Эндрю

+0

благодарит Андрея за понимание. Я только что проверил сайт OpenGeoCode.Org ... OpenGeoCode занимается только данными Северной Америки или по всему миру ..? Я заинтересован в решении, которое охватывает глобальные географические данные .... – RameshVel

+0

OpenGeoCode предоставит некоторые геоданные высокого уровня по всему миру. Но пока мы планируем делать подробные геоданные для Северной Америки. Мы ориентируемся на высокую точность данных, поэтому более узкая цель. В конвейере есть больше данных, но все идет через процесс обзора/настройки. –