2010-04-15 116 views

回答

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

} 

還有,你可以download或使用他們的API開放街道地圖。

我不建議雅虎的新API,他們正在左右切割產品,你永遠不知道它會在多久。此外,您目前無法下載整個轉儲。

+0

其漂亮。 ..謝謝jonperl .. :) – RameshVel 2011-01-13 05:27:46

1

的數據我不知道你是否僅限於谷歌地圖或地圖openstreet,但你可能會發現考慮看看雅虎的WOEID有趣。

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

我已經受夠了這種圍繞一齣戲,它的功能非常強大。

+0

感謝azp74 ..這看起來非常有前途.. :) – RameshVel 2010-04-15 07:01:35

3

2013年1月29日更新:我創建了世界上所有城市和人口稠密的地方的CSV數據集,以及經緯度區域的質心,並將其放置到公共領域。我將來自美國USGS GNIS服務器的數據和所有其他國家的NGA GNS服務器的數據相結合。下面是CSV文件的佈局和鏈接到數據集元數據:

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

第1欄:ISO 3166-1α-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代表二級行政區劃。對於美國,這些是阿拉斯加州的縣,自治市鎮和人口普查指定區域,路易斯安那州的教區,波多黎各的市政區,維爾京羣島的島嶼,馬紹爾羣島,美屬外島,美屬薩摩亞的地區以及北馬裏亞納羣島的市鎮。

PPL是人口稠密的地方。我不確定geonames.org是如何分類的,但是這個類別包括城市:大型分區,非公共區域和大型拖車公園。 Thney還包括一些歷史名勝。

我可以回答很多這些問題。我是一個公有領域的地理空間團隊的一員,在OpenGeoCode.Org

安德魯

+0

感謝安德魯的洞察力..我剛剛檢查了OpenGeoCode.Org網站...是OpenGeoCode只處理北美數據或全球..?我對一個涵蓋全球地理數據的解決方案感興趣...... – RameshVel 2011-02-18 01:24:38

+0

OpenGeoCode將在全球提供一些高級別的地理數據。但現在,我們只打算爲北美做詳細的地理數據。我們專注於數據的高精度,所以這就是爲什麼更窄的目標。數據中還有更多的數據,但都是通過審查/調整過程。 – 2011-02-18 07:05:32

相關問題