用pip安装cartopy(windows平台),解决GEOS库的问题

对象:cartopy

Cartopy官方网站介绍:

Cartopy is a Python package designed for geospatial data processing in order to produce maps and other geospatial data analyses.

Cartopy是一个Python包,旨在进行地理空间数据处理,以生成地图和其他地理空间数据分析。

Cartopy makes use of the powerful PROJ, NumPy and Shapely libraries and includes a programmatic interface built on top of Matplotlib for the creation of publication quality maps.

Cartopy使用强大的PROJ,NumPy和Shapely库,并包括在Matplotlib之上构建的用于创建出版质量地图的编程接口。

Key features of cartopy are its object oriented projection definitions, and its ability to transform points, lines, vectors, polygons and images between those projections.

主要功能是其面向对象的投影定义,以及在这些投影之间转换点,线,矢量,多边形和图像的能力。

You will find cartopy especially useful for large area / small scale data, where Cartesian assumptions of spherical data traditionally break down. If you’ve ever experienced a singularity at the pole or a cut-off at the dateline, it is likely you will appreciate cartopy’s unique features!

Cartopy在以下方面特别有用:大面积/小比例尺数据,其中球形数据的笛卡尔假设传统上会崩溃。如果您曾经在极点经历过奇点或在日期线上截断,那么您可能会欣赏cartopy的独特功能!

问题

  • windows平台
  • 用pip安装cartopy
  • 编译过程无法通过,错误提示:找不到geos_c.h

解决步骤

其他贴子里提到的安装的问题,多半是集中在几个py包,实际上唯一存在问题是geos库。其他包,pypi的源都已经解决了。

前提:

  • 安装microsoft visual studio社区版
  • 安装cmake

步骤:

  1. 下载libgeos源码
  2. 解压源代码
  3. 运行msvc的x64 Native Tools Command Prompt for VS 2022
  4. 切换到源代码目录:geos-3.11.2
  5. mkdir build
  6. cd build
  7. cmake ..
  8. msbuild GOES.slu -property:configuration=Release
  9. 等待完成之后激活要安装的python环境,xxx/venv/Script/activate
  10. set PATH=%PATH%;C:\prjs\geos-3.11.2\build\bin\Release
  11. set LIB=%LIB%;C:\prjs\geos-3.11.2\build\lib\Release
  12. set INCLUDE=%INCLUDE%;C:\prjs\geos-3.11.2\build\capi;C:\prjs\geos-3.11.2\include
  13. 接下来就直接安装cartopy,pip install cartopy
  14. 其中要涉及到编译环节,按照上面的设置就可以顺利通过;
  15. 安装好之后,如果在这个命令行窗口里,可能不存在问题,因为已经设置了PATH,换个终端还在运行import cartopy提示dll找不到:
    1. 就把C:\prjs\geos-3.11.2\build\bin\Release目录下的两个dll文件geos.dllgeos_c.dll拷贝到,对应的venv/Lib/site-packages/cartopy目录下
    2. C:\prjs\geos-3.11.2\build\bin\Release添加到系统的目录下。

例子

安装好了之后就可以运行一大堆例子:

def plot_carree():
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.coastlines()

    # Save the plot by calling plt.savefig() BEFORE plt.show()
    plt.savefig('coastlines.pdf')
    plt.savefig('coastlines.png', dpi=600)

    plt.show()


def plot_data():
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.stock_img()

    ny_lon, ny_lat = -75, 43
    delhi_lon, delhi_lat = 77.23, 28.61

    plt.plot([ny_lon, delhi_lon], [ny_lat, delhi_lat],
             color='blue', linewidth=2, marker='o',
             transform=ccrs.Geodetic(),
             )

    plt.plot([ny_lon, delhi_lon], [ny_lat, delhi_lat],
             color='gray', linestyle='--',
             transform=ccrs.PlateCarree(),
             )

    plt.text(ny_lon - 3, ny_lat - 12, 'New York',
             horizontalalignment='right',
             transform=ccrs.Geodetic())

    plt.text(delhi_lon + 3, delhi_lat - 12, 'Delhi',
             horizontalalignment='left',
             transform=ccrs.Geodetic())

    plt.show()


def plot_sphere():
    ax = plt.axes(projection=ccrs.Mollweide())
    ax.stock_img()
    plt.show()


import os

from cartopy import config
from scipy.io import netcdf_file


def plot_contour():
    # get the path of the file. It can be found in the repo data directory.
    fname = os.path.join(config["repo_data_dir"],
                         'netcdf', 'HadISST1_SST_update.nc'
                         )

    dataset = netcdf_file(fname, maskandscale=True, mmap=False)
    sst = dataset.variables['sst'][0, :, :]
    lats = dataset.variables['lat'][:]
    lons = dataset.variables['lon'][:]

    ax = plt.axes(projection=ccrs.PlateCarree())

    plt.contourf(lons, lats, sst, 60,
                 transform=ccrs.PlateCarree())

    ax.coastlines()

    plt.show()


def plot_fig():
    fig = plt.figure(figsize=(8, 12))

    # get the path of the file. It can be found in the repo data directory.
    fname = os.path.join(config["repo_data_dir"],
                         'raster', 'sample', 'Miriam.A2012270.2050.2km.jpg'
                         )
    img_extent = (-120.67660000000001, -106.32104523100001, 13.2301484511245, 30.766899999999502)
    img = plt.imread(fname)

    ax = plt.axes(projection=ccrs.PlateCarree())
    plt.title('Hurricane Miriam from the Aqua/MODIS satellite\n'
              '2012 09/26/2012 20:50 UTC')

    ax.use_sticky_edges = False
    # set a margin around the data
    ax.set_xmargin(0.05)
    ax.set_ymargin(0.10)

    # add the image. Because this image was a tif, the "origin" of the image is in the
    # upper left corner
    ax.imshow(img, origin='upper', extent=img_extent, transform=ccrs.PlateCarree())
    ax.coastlines(resolution='50m', color='black', linewidth=1)

    # mark a known place to help us geo-locate ourselves
    ax.plot(-117.1625, 32.715, 'bo', markersize=7, transform=ccrs.Geodetic())
    ax.text(-117, 33, 'San Diego', transform=ccrs.Geodetic())

    plt.show()


def plot_tick():
    rotated_crs = ccrs.RotatedPole(pole_longitude=120.0, pole_latitude=70.0)

    ax = plt.axes(projection=rotated_crs)
    ax.set_extent([-6, 3, 48, 58], crs=ccrs.PlateCarree())
    ax.coastlines(resolution='50m')
    ax.gridlines(draw_labels=True, dms=True, x_inline=False, y_inline=False)

    plt.show()


import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import cartopy.crs as ccrs

from cartopy.mpl.ticker import (LongitudeFormatter, LatitudeFormatter,
                                LatitudeLocator)


def plot_ticker():
    ax = plt.axes(projection=ccrs.Mercator())
    ax.coastlines()

    gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
                      linewidth=2, color='gray', alpha=0.5, linestyle='--')
    gl.top_labels = False
    gl.left_labels = False
    gl.xlines = False
    gl.xlocator = mticker.FixedLocator([-180, -45, 0, 45, 180])
    gl.ylocator = LatitudeLocator()
    gl.xformatter = LongitudeFormatter()
    gl.yformatter = LatitudeFormatter()
    gl.xlabel_style = {'size': 15, 'color': 'gray'}
    gl.xlabel_style = {'color': 'red', 'weight': 'bold'}

    plt.show()


if __name__ == '__main__':
    plot_ticker()

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

  1. windows下也可以从源程序编译libgeos;
  2. 虽然没有linux下面方便,但是也基本能用;
  3. cartopy真是好用啊……
posted @ 2023-05-22 22:01  大福是小强  阅读(138)  评论(0编辑  收藏  举报  来源