【问题标题】:Download data from Natural Earth and OpenStreetMap for Cartopy从 Natural Earth 和 OpenStreetMap 下载 Cartopy 数据
【发布时间】:2016-02-29 19:05:56
【问题描述】:

我正在尝试使用 cartopy 绘制多张地图,并且我想离线使用它们。 Cartopy有一个数据目录,

import cartopy.config
cartopy.config
{'data_dir': '/home/user/.local/share/cartopy',
'downloaders': {('shapefiles',
'gshhs'): <cartopy.io.shapereader.GSHHSShpDownloader at 0x7f3ee33ee7d0>,
('shapefiles',
 'natural_earth'): <cartopy.io.shapereader.NEShpDownloader at 0x7f3ee33ee710>},
'pre_existing_data_dir': '',
'repo_data_dir': '/home/user/bin/virtualenvs/mobi/local/lib/python2.7/site-packages/cartopy/data'}

所以我相信我可以从Natural Earth 站点下载地图。我怎样才能在这个目录上构建这些数据,这样 cartopy 就不会使用互联网来绘图?我怎样才能对 OpenStreetMap 数据做同样的事情?

【问题讨论】:

    标签: python openstreetmap cartopy


    【解决方案1】:

    (仅部分回答)

    在 Natural Earth 网站http://www.naturalearthdata.com/downloads/,您可以找到所有可下载的文件。 例如,此链接提供低分辨率数据:http://www.naturalearthdata.com/downloads/110m-physical-vectors/

    该页面上的其中一个数据文件具有以下链接地址: http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/physical/ne_110m_coastline.zip

    这段代码将下载该文件(如果计算机上没有该文件):-

    import cartopy
    fname = cartopy.io.shapereader.natural_earth( \
      resolution='110m', \
      category='physical', \
      name='110m_coastline')
    

    fname 是下载文件的完整路径。

    你不需要为cartopy安排下载位置。它已经有默认位置,您可以通过以下方式找到:

    cartopy.config['data_dir']   # usually 'C:\\Users\\username\\.local\\share\\cartopy'
    

    您可以查看您下载的文件并查看它们在该位置的结构。

    下次当你使用cartopy函数cartopy.io.shapereader.natural_earth(默认配置)时,它将使用本地文件(如果它们可用)。

    【讨论】:

      【解决方案2】:

      我遇到过类似的问题,其中使用 cartopy,plt.gca().coastlines() 正在触发从外部服务器下载 zip 文件,但由于没有互联网连接,下载失败。

       /home/apps/CARTOPY/0.16.0/lib64/python2.7/site-packages/Cartopy-0.16.0-py2.7-linux-x86_64.egg/cartopy/io/__init__.py:260: DownloadWarning: Downloading: http://naciscdn.org/naturalearth/110m/physical/ne_110m_coastline.zip
        warnings.warn('Downloading: {}'.format(url), DownloadWarning)
      

      我手动下载了 zip 文件,并在 - ~/.local/share/cartopy/shapefiles/natural_earth/physical 下解压。

      ~/.local/share/cartopy/shapefiles/natural_earth/physical> ls
      ne_110m_coastline.README.html  ne_110m_coastline.cpg  ne_110m_coastline.prj  ne_110m_coastline.shx
      ne_110m_coastline.VERSION.txt  ne_110m_coastline.dbf  ne_110m_coastline.shp
      

      然后从某些文件中重命名/删除“ne_”前缀后,我能够解决这个问题。

      ~/PLOT_TEST> ls ~/.local/share/cartopy/shapefiles/natural_earth/physical/
      110m_coastline.cpg  110m_coastline.dbf  110m_coastline.prj  110m_coastline.shp  110m_coastline.shx  ne_110m_coastline.README.html  ne_110m_coastline.VERSION.txt
      

      【讨论】:

        【解决方案3】:

        我准备了一个代码,您可以在其中从自然地球下载 shapefile,然后将它们转换为数据框。注意,自然地球中的国家坐标是多边形和多多边形格式。在处理作为线串的河流的情况下,您需要修改代码。

        您可能需要使用所需的文件名(例如“coastlines”)来操作“名称”。在以下链接中查找更多信息:

        https://www.naturalearthdata.com/downloads/

        import cartopy.io.shapereader as shpreader
        ne_earth_countries = shpreader.natural_earth(resolution = '10m',
                                               category = 'cultural',
                                               name='admin_0_countries')
        countries = shpreader.Reader(ne_earth_countries).records()
        
        def extract_geom_meta(country):
            coords = np.empty(shape=[0,2])
            for geom in country.geometry:
                coords = np.append(coords, geom.exterior.coords, axis=0)
            country_name = country.attributes["ADMIN"]
            return [country_name, coords]
        
        WorldDF = pd.DataFrame([extract_geom_meta(country) for country in countries],
                                                    columns=['countries','coordinates'])
        
        CountryDF = pd.concat([pd.DataFrame(WorldDF['coordinates'][country_idx])
                                    for country_idx in range(len(WorldDF))]).reset_index()
        
        CountryDF['Label'] = CountryDF.apply(lambda row: 1 if row['index'] == 0
                                                                else 0,axis=1).cumsum()-1
        
        CountryDF['Country'] = CountryDF['Label'].apply(lambda row: WorldDF.countries[row])
        
        CountryDF.rename(columns={0:'Longitude', 1:'Latitude'},inplace=True)
        print(CountryDF.head())
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-09
          • 1970-01-01
          • 2019-04-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多