爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
12
返回列表 发新帖
楼主: xhw0734

[作图] shapefile_mask_data做地图mask时报错

[复制链接]

新浪微博达人勋

发表于 2020-4-5 20:39:25 | 显示全部楼层
xhw0734 发表于 2016-9-9 18:04
shapefile_mask_data: Error: not a valid rectilinear, curvilinear, or unstructured grid;这个错误已解 ...

请问怎么指定呀,原数据是1d
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2020-6-8 20:02:58 | 显示全部楼层
你好请问这个问题怎样解决的,
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2021-4-1 11:30:40 | 显示全部楼层
subtropical 发表于 2018-7-25 17:27
楼主 我也用这个shapefile_mask_data,但是报错是这样的,请问要怎么修改?

你好,我也遇到了相同的问题,请问你是怎样解决的呢
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2021-6-8 13:01:14 | 显示全部楼层
lb369 发表于 2018-9-10 12:30
目前该函数只能再二维中使用,且数据必须具有经纬度属性。所以用conform_dims函数填充三维数组,但是每个格 ...

你好,咨询一下,有点不太明白您说的conform_dims函数填充三维数组,因为这个函数只能处理2d数据,那我该怎么拿它去选择3d数据呢
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2021-6-21 17:04:35 | 显示全部楼层
楼主好,我也是这个问题,一直没解决,是否可以提供一份修改好的shapefile_utils.ncl,万分感谢,397022276@qq.com
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2022-1-18 21:52:52 | 显示全部楼层
15104562864 发表于 2021-6-21 17:04
楼主好,我也是这个问题,一直没解决,是否可以提供一份修改好的shapefile_utils.ncl,万分感谢,
  1. ;======================================================================
  2. ; This function masks a rectilinear, curvilinear, or unstructured
  3. ; data array based on either all the outlines in a shapefile, or
  4. ; based on a string variable name in a shapefile and a list of strings
  5. ; to check for, like "Water body" or (/"Ohio","Michigan"/).
  6. ;
  7. ; You have the option to return the mask array, rather than the masked
  8. ; data array.
  9. ;
  10. ; Input paramaters
  11. ;  data         : numeric - 1D or 2D data to mask or base mask array on
  12. ;  shp_file_name[1] : string  - Name of shapefile
  13. ;  opt[1]       : logical - Use to set options for this function. If
  14. ;                           set to False, then all options will be ignored.
  15. ;
  16. ;  "opt" can have the following attributes:
  17. ;
  18. ;   "keep"        - Whether to keep the values in the given shapefile
  19. ;                   areas or toss them.
  20. ;                   [default True]
  21. ;
  22. ;   "shape_var"   - Name of variable on shapefile that contains the
  23. ;                   string names of specific areas you want to mask.
  24. ;                   [default is to use the whole shapefile]
  25. ;
  26. ;   "shape_names" - List of string names in "shape_name" to mask against
  27. ;                   [no default]
  28. ;
  29. ;   "return_mask" - Whether to return a mask array (0s and 1s)
  30. ;                   instead of the masked data.
  31. ;                   [default False]
  32. ;
  33. ;   "minlat", "maxlat", "minlon", "maxlon" - You can tell the masking
  34. ;                   routine what rough lat/lon box you are interested
  35. ;                   in, so that it doesn't check every lat/lon segment
  36. ;                   in the shapefile.
  37. ;                   [default is the min/max of the lat/lon on shapefile]
  38. ;
  39. ;   "loop_check"  - Whether to do a min/max lat/lon check for every loop iteration.
  40. ;                   I tested this on four examples, and it sped every one of them up.
  41. ;                   I decided to make this True by default.;
  42. ;                   [default True]

  43. ;   "debug"       - Whether to print debug information.
  44. ;                   [default False]
  45. ;
  46. ;  - If a rectilinear grid, then "data" must have coordinate arrays
  47. ;    attached.
  48. ;  - If a curvilinear grid, then "data" must have the special lat2d
  49. ;    and lon2d attributes attached.
  50. ;  - If a unstructured grid, then "data"must have the special lat1d
  51. ;    and lon1d attributes attached.
  52. ;======================================================================
  53. undef("shapefile_mask_data")
  54. function shapefile_mask_data(data:numeric,shp_file_name[1]:string,\
  55.                              opt[1]:logical)
  56. local mask_start_time, mask_end_time,keep_true_value, keep_false_value, \
  57. dims, rank, grid_type, lat1d, lon1d, nlatlon1d, f, segments, geometry, \
  58. segsDims, geomDims, geom_segIndex, geom_numSegs, segs_xyzIndex,
  59. segs_numPnts,numFeatures, lat, lon, shp_mask_names, found, nf, numFeatures, \
  60. startSegment, numSegments, seg, startPT, endPT, lon_sub, lat_sub, \
  61. min_lat_shp, max_lat_shp, min_lon_shp, max_lon_shp
  62. begin
  63.   mask_start_time = get_cpu_time()

  64. ;---Make sure we can open shapefile
  65.   if(.not.isfilepresent(shp_file_name)) then
  66.     print("shapefile_mask_data : Error: " + shp_file_name + \
  67.           " either doesn't exist or is not a valid shapefile.")
  68.     exit
  69.   end if
  70.   f = addfile(shp_file_name,"r")

  71. ;---Parse options and check for errors
  72.   DEBUG       = get_res_value_keep(opt,"debug",False)
  73.   KEEP        = get_res_value_keep(opt,"keep",True)
  74.   RETURN_MASK = get_res_value_keep(opt,"return_mask",False)
  75.   LOOP_CHECK  = get_res_value_keep(opt,"loop_check",True)
  76.   SHP_VAR     = opt.and.isatt(opt,"shape_var")
  77.   if(opt.and.isatt(opt,"shape_var")) then
  78.     if(.not.isatt(opt,"shape_names")) then
  79.       print("shapefile_mask_data : Error: if you set 'shape_var' you must also set 'shape_names'")
  80.       exit
  81.     end if
  82.     shp_var_name   = opt@shape_var
  83.     usr_mask_names = opt@shape_names

  84. ;---Make sure shp_var_name is on shapefile.
  85.     if(isfilevar(f,shp_var_name)) then
  86.       shp_mask_names = f->$shp_var_name$
  87.     else
  88.       print("shapefile_mask_data : Error: The given variable name to use does not exist on the given shapefile.")
  89.       exit
  90.     end if

  91. ;---Make sure usr_mask_names has at least one match in shp_mask_names
  92.     num_found = 0
  93.     nusr_mask_names = dimsizes(usr_mask_names)
  94.     do i=0,nusr_mask_names-1
  95.       if(any(usr_mask_names(i).eq.shp_mask_names)) then
  96.         num_found = num_found+1
  97.       end if
  98.     end do
  99.     if(num_found.eq.0) then
  100.       print("shapefile_mask_data : Error: none of the given mask_names match the names on the shapefile.")
  101.       exit
  102.     end if
  103.     if(num_found.lt.nusr_mask_names) then
  104.       print("shapefile_mask_data : warning: Only found " + num_found + \
  105.             " of the " + nusr_mask_names)
  106.       print("                      given mask_names on the shapefile.")
  107.     end if
  108.   end if

  109.   if(KEEP) then
  110.     keep_true_value  = 1  ; 1 ==> values inside given mask areas will be kept
  111.     keep_false_value = 0
  112.   else
  113.     keep_true_value  = 0  ; 0 ==> values inside given mask areas will be tossed
  114.     keep_false_value = 1
  115.   end if

  116. ;---Determine the grid type
  117.   dims = dimsizes(data)
  118.   rank = dimsizes(dims)

  119.   grid_type = ""
  120.   if(rank.eq.2.and.\
  121.      isdimnamed(data,0).and.iscoord(data,data!0).and.\
  122.      isdimnamed(data,1).and.iscoord(data,data!1)) then
  123.     lat1d = ndtooned(conform_dims(dims,data&$data!0$,0))
  124.     lon1d = ndtooned(conform_dims(dims,data&$data!1$,1))
  125.     grid_type = "rectilinear"
  126.   else if(rank.eq.2.and.all(isatt(data,(/"lat2d","lon2d"/)))) then
  127. ;---Curvilinear
  128.     lat1d = ndtooned(data@lat2d)
  129.     lon1d = ndtooned(data@lon2d)
  130.     if(product(dims).eq.dimsizes(lat1d).and.\
  131.        product(dims).eq.dimsizes(lon1d)) then
  132.       grid_type = "curvilinear"
  133.     end if
  134.   else if(rank.eq.1.and.all(isatt(data,(/"lat1d","lon1d"/)))) then
  135. ;---Unstructured
  136.     lat1d = data@lat1d
  137.     lon1d = data@lon1d
  138.     if(dims.eq.dimsizes(lat1d).and.\
  139.        product(dims).eq.dimsizes(lon1d)) then
  140.       grid_type = "unstructured"
  141.     end if
  142.   end if
  143.   end if
  144.   end if

  145.   if(grid_type.eq."") then
  146.     print("shapefile_mask_data: Error: not a valid rectilinear, curvilinear, or unstructured grid")
  147.     exit
  148.   end if
  149.   nlatlon1d = dimsizes(lat1d)

  150. ;---Read data off the shapefile
  151.   segments = f->segments
  152.   geometry = f->geometry
  153.   segsDims = dimsizes(segments)
  154.   geomDims = dimsizes(geometry)

  155. ;---Read global attributes  
  156.   geom_segIndex = f@geom_segIndex
  157.   geom_numSegs  = f@geom_numSegs
  158.   segs_xyzIndex = f@segs_xyzIndex
  159.   segs_numPnts  = f@segs_numPnts
  160.   numFeatures   = geomDims(0)

  161. ;---Read shapefile lat/lon
  162.   lon = f->x
  163.   lat = f->y
  164. ;
  165. ; If shp_var_name is specified, then get the approximate lat/lon box that
  166. ; encloses the shapefile areas of interest. This can make the
  167. ; gc_inout checking go faster later. If the user has input
  168. ; all four "usr_min/max_lat/lon" attributes, then don't do the check.
  169. ;
  170.   if(SHP_VAR.and..not.(opt.and.isatt(opt,"minlat").and.isatt(opt,"maxlat").and.\
  171.                                isatt(opt,"minlon").and.isatt(opt,"maxlon"))) then
  172.     found = False
  173.     do nf=0,numFeatures-1
  174.       if(any(shp_mask_names(nf).eq.usr_mask_names)) then
  175.         startSegment = geometry(nf, geom_segIndex)
  176.         numSegments  = geometry(nf, geom_numSegs)
  177.         do seg=startSegment, startSegment+numSegments-1
  178.           startPT = segments(seg, segs_xyzIndex)
  179.           endPT   = startPT + segments(seg, segs_numPnts) - 1
  180.           lat_sub := lat(startPT:endPT)
  181.           lon_sub := lon(startPT:endPT)
  182.           if(found) then
  183.             min_lat_shp = min((/min_lat_shp,min(lat_sub)/))
  184.             max_lat_shp = max((/max_lat_shp,max(lat_sub)/))
  185.             min_lon_shp = min((/min_lon_shp,min(lon_sub)/))
  186.             max_lon_shp = max((/max_lon_shp,max(lon_sub)/))
  187.           else
  188.             min_lat_shp = min(lat_sub)
  189.             max_lat_shp = max(lat_sub)
  190.             min_lon_shp = min(lon_sub)
  191.             max_lon_shp = max(lon_sub)
  192.             found       = True
  193.           end if
  194.         end do
  195.       end if
  196.     end do
  197.   else
  198. ;---Use the whole shapefile
  199.     min_lat_shp = min(lat)
  200.     max_lat_shp = max(lat)
  201.     min_lon_shp = min(lon)
  202.     max_lon_shp = max(lon)
  203.   end if
  204.   
  205. ;--lat/lon coordinates of data array
  206.   min_lat_data = min(lat1d)
  207.   max_lat_data = max(lat1d)
  208.   min_lon_data = min(lon1d)
  209.   max_lon_data = max(lon1d)

  210. ;---min/max lat/lon to use for checking the data lat/lon
  211.   min_lat_chk = get_res_value(opt,"minlat",min_lat_shp)
  212.   max_lat_chk = get_res_value(opt,"maxlat",max_lat_shp)
  213.   min_lon_chk = get_res_value(opt,"minlon",min_lon_shp)
  214.   max_lon_chk = get_res_value(opt,"maxlon",max_lon_shp)

  215. ;---Get index values where data lat/lon values fall inside this "box".
  216.   if(.not.LOOP_CHECK) then
  217.     ii_latlon = ind(min_lat_chk.le.lat1d.and.lat1d.le.max_lat_chk.and.\
  218.                     min_lon_chk.le.lon1d.and.lon1d.le.max_lon_chk)
  219.     nii = dimsizes(ii_latlon)
  220.   end if

  221.   if(DEBUG) then
  222.     print("==================================================")
  223.     print("Shapefile:         " + shp_file_name)
  224.     if(SHP_VAR) then
  225.       print("Areas of interest: " + str_join(usr_mask_names,","))
  226.     else
  227.       print("Areas of interest: the whole shapefile")
  228.     end if
  229.     print("min_lat_chk:       " + min_lat_chk)
  230.     print("max_lat_chk:       " + max_lat_chk)
  231.     print("min_lon_chk:       " + min_lon_chk)
  232.     print("max_lon_chk:       " + max_lon_chk)
  233.     print("min_lat_data:      " + min_lat_data)
  234.     print("max_lat_data:      " + max_lat_data)
  235.     print("min_lon_data:      " + min_lon_data)
  236.     print("max_lon_data:      " + max_lon_data)
  237.     print(dimsizes(lat1d) + " data values originally")
  238.     if(.not.LOOP_CHECK) then
  239.       print(nii + " data values within given shapefile areas.")
  240.     end if
  241.     if(keep_true_value.eq.1) then
  242.       print("Will keep data values inside given shapefile areas")
  243.     else
  244.       print("Will toss data values inside given shapefile areas")
  245.     end if
  246.   end if

  247. ;---Create array to hold new data mask
  248.   data_mask_1d = new(nlatlon1d,integer)
  249.   data_mask_1d = keep_false_value

  250. ;
  251. ; Setting opt@loop_check = True seems to produce the best results, timing-wise.
  252. ; Maybe get rid of the "else" part of this "if" statement at some point?
  253. ;
  254.   if(LOOP_CHECK) then
  255.     do nf=0,numFeatures-1
  256.       if(.not.SHP_VAR.or.(SHP_VAR.and.\
  257.          any(shp_mask_names(nf).eq.usr_mask_names))) then
  258.         startSegment = geometry(nf, geom_segIndex)
  259.         numSegments  = geometry(nf, geom_numSegs)
  260.         do seg=startSegment, startSegment+numSegments-1
  261.           startPT = segments(seg, segs_xyzIndex)
  262.           endPT   = startPT + segments(seg, segs_numPnts) - 1
  263.           lat_sub := lat(startPT:endPT)
  264.           lon_sub := lon(startPT:endPT)
  265.           ii_latlon := ind(min(lat_sub).le.lat1d.and.lat1d.le.max(lat_sub).and.\
  266.                            min(lon_sub).le.lon1d.and.lon1d.le.max(lon_sub))
  267.           if(any(ismissing(ii_latlon))) then
  268.             continue
  269.           end if         
  270.           nii = dimsizes(ii_latlon)
  271.           do n=0,nii-1
  272.             iltln = ii_latlon(n)
  273.             if(data_mask_1d(iltln).ne.keep_true_value.and.\
  274.                gc_inout(lat1d(iltln),lon1d(iltln),lat_sub,lon_sub)) then
  275.               data_mask_1d(iltln) = keep_true_value
  276.             end if
  277.           end do
  278.         end do
  279.       end if
  280.     end do
  281.   else
  282.     do n=0,nii-1
  283.       iltln = ii_latlon(n)
  284.       do nf=0,numFeatures-1
  285.         if(data_mask_1d(iltln).ne.keep_true_value.and.\
  286.            (.not.SHP_VAR.or.(SHP_VAR.and.\
  287.            any(shp_mask_names(nf).eq.usr_mask_names)))) then
  288.           startSegment = geometry(nf, geom_segIndex)
  289.           numSegments  = geometry(nf, geom_numSegs)
  290.           do seg=startSegment, startSegment+numSegments-1
  291.             startPT = segments(seg, segs_xyzIndex)
  292.             endPT   = startPT + segments(seg, segs_numPnts) - 1
  293.             lat_sub := lat(startPT:endPT)
  294.             lon_sub := lon(startPT:endPT)
  295.             if(.not.(all(lon_sub.lt.min_lon_data).or. \
  296.                      all(lon_sub.gt.max_lon_data).or. \
  297.                      all(lat_sub.lt.min_lat_data).or. \
  298.                      all(lat_sub.gt.max_lat_data)).and.\
  299.                gc_inout(lat1d(iltln),lon1d(iltln),lat_sub,lon_sub)) then
  300.               data_mask_1d(iltln) = keep_true_value
  301.               break
  302.             end if
  303.           end do
  304.         end if
  305.       end do
  306.     end do
  307.   end if
  308.   if(DEBUG) then
  309.     print("==================================================")
  310.     if(KEEP) then
  311.       print(num(data_mask_1d.eq.keep_true_value) + " data values kept")
  312.    else
  313.       print(num(data_mask_1d.ne.keep_true_value) + " data values kept")
  314.     end if
  315.   end if
  316. ;
  317. ; Create a 2D data array of same size as original data,
  318. ; but with appropriate values masked. Create a missing
  319. ; value if our data doesn't have one.
  320. ;
  321.   if(.not.isatt(data,"_FillValue")) then
  322.     data_msg = default_fillvalue(typeof(data))
  323.   else
  324.     data_msg = data@_FillValue
  325.   end if

  326. ;---Keep all the locations where the mask array is 1.
  327.   if(RETURN_MASK) then
  328.     data_mask = onedtond(data_mask_1d,dims)
  329.   else
  330.     data_mask = where(onedtond(data_mask_1d,dims).eq.1,data,data_msg)
  331.     copy_VarMeta(data,data_mask)      ; Copy all metadata

  332.     if(.not.isatt(data,"_FillValue")) then
  333.       data_mask@_FillValue = data_msg
  334.     end if
  335.   end if

  336.   if(DEBUG) then
  337. ;---Print timings
  338.     mask_end_time = get_cpu_time()
  339.     print("shapefile_mask_data: elapsed time: " + \
  340.           (mask_end_time-mask_start_time) + " CPU seconds.")
  341.     print("==================================================")
  342.   end if
  343.   return(data_mask)
  344. end
复制代码

保存为ncl文件 然后load一下,不知道怎么插入文件只能这样了
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2023-4-11 11:10:49 | 显示全部楼层
yybubble 发表于 2018-9-9 21:08
您好,我指定了lon2d和lat2d还是没有用,依然报错,是什么情况呢~

你检查一下经纬度数据的行列数与你的二维数据行列数是否一致?我改正了这个错误就解决了。
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表