代码之家  ›  专栏  ›  技术社区  ›  Jan Kaiser

绘图广场地图

  •  1
  • Jan Kaiser  · 技术社区  · 8 年前

    我需要用卡通画出一张正方形的地图。我目前对我的地图使用以下代码:

    plt.figure(FigSize=(15,15))。
    
    img=cimgt.googletiles()。
    
    ax=plt.轴(投影=img.crs)
    ax.设置范围((d[经度].min()-0.05,d[经度].max()+0.05,
    d[“纬度”].min()-0.05,d[“纬度”].max()+0.05)
    
    ax.添加图像(img,10,interpolation='双三次')
    
    plt.scatter(d[“经度”]、d[“纬度”]、transform=ccrs.platecarree(),
    c=e8175d',s=14)
    

    这很好,除了地图不是方形的。相反,它只是被安装到绘图的(15,15)square中。

    我想在左边和右边多加一点地图,使这张图完全方正而不扭曲。仅仅在经纬度上设置相同的范围并不能完成这项工作,因为在谷歌(以及大多数其他)的地图投影中,经纬度覆盖了不同的距离。我还发现了thispost,but from what I get,the intent here is to distort the map.

    我希望有人知道怎么做。在这方面,漫画似乎不是很直观。

    这很好,除了地图不是方形的。相反,它只是安装在(15, 15)图的平方。

    enter image description here

    我想在左边和右边多加一点地图,使这张图完全方正而不扭曲。仅仅在经纬度上设置相同的范围并不能完成这项工作,因为在谷歌(以及大多数其他)的地图投影中,经纬度覆盖了不同的距离。我也发现了this发帖,但据我所知,这里的目的是扭曲地图。

    我希望有人知道怎么做。在这方面,漫画似乎不是很直观。

    1 回复  |  直到 8 年前
        1
  •  2
  •   swatchai    8 年前

    要获得平方范围,需要在地图投影坐标中指定它。这需要一些坐标变换。这是您需要的代码片段。

    您选择的CRS crg=cimgt.stampenterrain().crs或cimgt.googletiles().crs #设置地图限制(度) lonmin,lonmax=-22,-15 latmin,latmax=63,65 #做坐标变换 ll=crg.变换点(lonmin,latmin,ccrs.geoditic()) ur=crg.转换点(lonmax,latmax,ccrs.geoditic()) ew=ur[0]-ll[0] sn=ur[1]-ll[1] #获取平方范围的边(以地图单位表示,通常为米) 侧边=最大值(ew,sn)较大值有效 中间x,中间y=ll[0]+ew/2.0,ll[1]+sn/2.0中心位置 #范围保留中心位置 范围=[中X侧/2.0,中X+侧/2.0,中Y侧/2.0,中Y+侧/2.0] #这设置了平方范围 #crs=crg表示在一定范围内使用投影坐标 最大设定范围(范围,crs=crg)

    
    

    希望能有所帮助。

    编辑

    下面是一个完整的工作代码及其生成的映射。

    导入matplotlib.pyplot as plt 将cartopy.crs导入为ccr 从cartopy.mpl.gridliner导入经度格式设置工具,经度格式设置工具 将cartopy.io.img_图块导入为cimgt def make_map(投影=ccrs.platecarree()): 图,ax=plt.子批次(图尺寸=(10,10) 子批次_kw=dict(投影=投影) gl=ax.网格线(绘制标签=真) gl.xlabels_top=gl.ylabels_right=false gl.xformatter=经度格式化程序 gl.yFormatter=纬度格式设置工具 返回图,ax 请求=cimgt.stamenterrain()非常响应 crg=投影的请求.crs crs 图,ax=制作图(投影=CRG) #在此处指定映射范围 lonmin,lonmax=-22,-15 latmin,latmax=63,65 ll=crg.变换点(lonmin,latmin,ccrs.geoditic()) ur=crg.转换点(lonmax,latmax,ccrs.geoditic()) ew=ur[0]-ll[0] sn=ur[1]-ll[1] 边=最大值(ew,sn) 中间x,中间y=ll[0]+ew/2.0,ll[1]+sn/2.0中心位置 范围=[中间x边/2.0,中间x边/2.0,中间y边/2.0,中间y边/2.0]地图坐标,米 最大设定范围(范围,crs=crg) ax.添加图像(请求,8) #在地图中心添加标记 plt.plot(中间x,中间y,marker='o',)\ color='red',markersize=10,,\ α=0.7,转换=crg) 请显示())

    
    

    我是你需要的。

    # crs of your choice
    crg = cimgt.StamenTerrain().crs    # or cimgt.GoogleTiles().crs
    
    # set map limits, in degrees
    lonmin, lonmax = -22, -15
    latmin, latmax = 63, 65
    
    # do coordinate transformation
    LL = crg.transform_point(lonmin, latmin, ccrs.Geodetic())
    UR = crg.transform_point(lonmax, latmax, ccrs.Geodetic())
    EW = UR[0] - LL[0]
    SN = UR[1] - LL[1]
    
    # get side of the square extent (in map units, usually meters)
    side = max(EW, SN)    # larger value is in effect
    mid_x, mid_y = LL[0]+EW/2.0, LL[1]+SN/2.0  # center location
    
    # the extent preserves the center location
    extent = [mid_x-side/2.0, mid_x+side/2.0, mid_y-side/2.0, mid_y+side/2.0]
    
    # this sets square extent
    # crs=crg signifies that projection coordinates is used in extent
    ax.set_extent(extent, crs=crg)
    

    希望有帮助。

    编辑

    这里是一个完整的工作代码及其结果图。

    import matplotlib.pyplot as plt
    import cartopy.crs as ccrs
    from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
    import cartopy.io.img_tiles as cimgt
    
    def make_map(projection=ccrs.PlateCarree()):
        fig, ax = plt.subplots(figsize=(10, 10),
                               subplot_kw=dict(projection=projection))
        gl = ax.gridlines(draw_labels=True)
        gl.xlabels_top = gl.ylabels_right = False
        gl.xformatter = LONGITUDE_FORMATTER
        gl.yformatter = LATITUDE_FORMATTER
        return fig, ax
    
    request = cimgt.StamenTerrain()   # very responsive
    crg = request.crs   #crs of the projection
    fig, ax = make_map(projection = crg)
    
    # specify map extent here
    lonmin, lonmax = -22, -15
    latmin, latmax = 63, 65
    
    LL = crg.transform_point(lonmin, latmin, ccrs.Geodetic())
    UR = crg.transform_point(lonmax, latmax, ccrs.Geodetic())
    EW = UR[0] - LL[0]
    SN = UR[1] - LL[1]
    side = max(EW,SN)
    mid_x, mid_y = LL[0]+EW/2.0, LL[1]+SN/2.0  #center location
    
    extent = [mid_x-side/2.0, mid_x+side/2.0, mid_y-side/2.0, mid_y+side/2.0]   # map coordinates, meters
    
    ax.set_extent(extent, crs=crg)
    ax.add_image(request, 8)
    
    # add a marker at center of the map
    plt.plot(mid_x, mid_y, marker='o', \
             color='red', markersize=10, \
             alpha=0.7, transform = crg)
    
    plt.show()
    

    south of iceland