2010-04-15 2 views

답변

5

확실히 GeoName을 체크 아웃해야합니다. 그들은 전 세계를 표준화 된 데이터베이스에 보유하고 있습니다. 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

합니다. .. thanks jonperl .. :) – RameshVel

2

다운로드에게 데이터는 나도 몰라하지만 당신은 흥미로운 야후의 WOEID에서 살펴 본다 찾을 수 있습니다.

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

나는이와 주위 플레이를 했어 그것은 매우 강력합니다.

+0

감사 톰 ..에서 공개 지리 팀의 일원이야 : 나는 매우 유망한 보이는 – RameshVel

1

에서

+0

감사 azp74 .. 들여다 것이다 .. : 그것의 좋은 – RameshVel

3

2013 년 1 월 29 일 업데이트 : 위도/경도 면적 중심과 함께 전 세계 모든 도시 및 인구 밀집 지역의 CSV 데이터 세트를 작성하여 공개 도메인에 배치했습니다. 미국의 경우 USGS GNIS 서버의 데이터를, 다른 모든 국가의 경우 NGA GNS 서버의 데이터를 결합했습니다.

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

열 1 : ISO 3166-1 alpha-2 국가 코드 다음은 데이터 세트에 CSV 파일의 레이아웃과 링크에 대한 메타 데이터입니다.
칼럼 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

Andrew에게 통찰력을 주셔서 감사합니다. 방금 OpenGeoCode.Org 사이트를 확인했습니다 ... OpenGeoCode는 북미 데이터 또는 전세계를 처리합니다 ..? 전세계 지리적 데이터를 다루는 솔루션에 관심이 있습니다 .... – RameshVel

+0

OpenGeoCode는 전 세계적으로 몇 가지 고급 지형 데이터를 제공합니다. 그러나 현재는 북미 지역에 대한 상세한 지형 데이터를 계획하고 있습니다. 우리는 데이터의 높은 정확성에 중점을두고 있으므로 대상이 좁습니다. 파이프 라인에는 더 많은 데이터가 있지만 모두 검토/튜닝 과정을 거칩니다. –

관련 문제