爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 18197|回复: 18

[源程序] 使用python调用surfer绘制等值线图的方法属性问题。

[复制链接]

新浪微博达人勋

发表于 2019-6-10 11:43:11 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 qianz98 于 2019-6-10 16:26 编辑

几年前用VB搞过surfer自动绘制等值线图。最近尝试用PYTHON来实现类似功能,可以实现插值、白化、合并图层。工作环境是python3.6 + surfer16 。但是在调整等值线属性时候遇到问题,编写如下代码:
import win32com.client
import os

def changedate():
    app = win32com.client.gencache.EnsureDispatch('Surfer.Application')
    Plot = app.Documents.Add(1)
    app.Visible = True
    xpath=os.path.dirname(os.path.realpath(__file__))
    datafile=os.path.join(xpath,'temp.dat')
    gridfile=os.path.join(xpath,'temp.grd')
    gridoutf=os.path.join(xpath,'temp-out.dat')
    blankgrid=os.path.join(xpath,'temp_blank.grd')
    outlinefile=os.path.join(xpath,'ZJ_outline.bln')
    LS=os.path.join(xpath,'windlevel.lvl')
    colormap=os.path.join(xpath,'windcolor.clr')
    basefile=os.path.join(xpath,'ZjBack2.bln') #基底图
    postfile=os.path.join(xpath,'StaPotst.dat') #张贴图
    export_img=os.path.join(xpath,'temp.jpg') #输出图像
    #进行插值
    app.GridData(DataFile=datafile,
                           xCol=1,
                           yCol=2,
                           zCol=3,
                           ShowReport=False,
                           Algorithm=2,
                           xMin=117.5,
                           xMax=123.5,
                           yMin=27,
                           yMax=31.5,
                           NumCols="1201",
                           NumRows="901",
                           OutGrid=gridoutf,
                           OutFmt=4)
   
    #白化网格文件
    app.GridBlank(InGrid=gridfile,
            BlankFile=outlinefile,
            OutGrid=blankgrid)
   
   
    ###增加等值线图
    MapFrame1 = Plot.Shapes.AddContourMap(GridFileName=blankgrid)
    #改变等值线图边界范围
    MapFrame1.SetLimits(xMin=118, xMax=123, yMin=27, yMax=31.4)
    MapFrame1.xLength=6
    MapFrame1.yLength=5

    ContourLayer = MapFrame1.Overlays(1)
    ContourLayer.Name = "等值线图"   #修改等值线图名称

    #ContourLayer.Levels.Set(LS)

    ###增加基底图
    MapFrame2 = Plot.Shapes.AddBaseMap(ImportFileName=basefile)
    BaseLayer1 = MapFrame2.Overlays(1)
    BaseLayer1.Name = "基底图"   #修改等值线图名称

    ###增加散点图
    MapFrame3 = Plot.Shapes.AddPostMap(postfile,LabCol=3)
    PostMap = MapFrame3.Overlays(1)
    PostMap.Name = "张贴图"

    ###合并图层生成一个新图层
    MapFrame1.Selected=True
    MapFrame2.Selected=True
    MapFrame3.Selected=True
    NewMapFrame = Plot.Selection.OverlayMaps()
    Plot.Shapes.SelectAll()
    Plot.Export(export_img) #导出图片
   
    #关闭调用程序
    Plot.Close()
    app.Quit()

代码可以执行,能够生成等值线图。
当我打算修改ContourLayer.Levels.Set(LS)
ContourLayer的的Levels属性的时候发现抱错。但是ContourLayer.Name 这个属性是可以修改的。
结论是:
1、PYTHON不是SURFER并不是surfer推荐的开发语言,发现有些语法和对象属性在自带的脚本编辑器中是可用的,但是换成python就不行。网上可参考的PYTHON代码较少。
2、感觉目前用PYTHON还是没法完美的调用surfer绘制等值线图,也用matplotlib库绘制过等值线图,但是插值的方法和效果和克里金法差距还是蛮大。


如果有其他人有更好的办法可以在此交流。






评分

参与人数 1金钱 +1 收起 理由
ObYuri + 1 赞一个!

查看全部评分

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2019-6-10 13:01:29 | 显示全部楼层
要调用 Surfer 的绘图功能,用它的脚本语言,我的经验是:
1、目标计算机安装 Surfer13。没有为什么,上面说了是我的经验。
2、一定要参考 Surfer14 或以上版本的帮助文档,Surfer13 及其以下版本的帮助文档不能用。
3、目标计算机上,Surfer13 一定要能够运行,不能出现要求输入注册码的对话框。
第 1、3 两条,是保证你的程序能够运行的必要条件,第 2 条,那是对你编程的指导。你目前提出的问题,也可以在 Surfer14 的帮助文档里找到答案。
当然,你的程序不能有Bug。

评分

参与人数 1金钱 +2 收起 理由
ObYuri + 2 赞一个!

查看全部评分

密码修改失败请联系微信:mofangbao
回复 支持 2 反对 0

使用道具 举报

新浪微博达人勋

发表于 2019-6-10 18:05:02 | 显示全部楼层
都用python了,何必调用surfer呢
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2019-6-10 20:16:23 | 显示全部楼层
感谢程老师的建议。
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2019-6-10 20:19:44 | 显示全部楼层
本帖最后由 qianz98 于 2019-6-10 20:21 编辑
尽头的尽头 发表于 2019-6-10 18:05
都用python了,何必调用surfer呢

因为我感觉surfer的克里金插值算法比较好,python 调用surfer的方法走不通,所以我现在用matlotlib库的插值算法,它的方法就比较少了,一共就3种,并且感觉都没有克里金效果好。


20180305020200windv.png
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2019-6-14 09:31:04 | 显示全部楼层
楼主这个问题只要好好看帮助文件就可以了。
levels.set() 方法要求的参数是一个数组。
楼主其实想载入一个 .lvl 文件,这时候应该用 levels.loadfile() 方法。

PS:对于用了 python 就无需用 surfer 的说法,我本人持有异议,每个人需求不一样,而且 surfer 自有它的优势所在。虽然我自己用的自动化代码多用 surfer 自带的 scripter,但也有很多时候,VB、C、python 等语言写 surfer 自动化也很必要。

PPS:程老师的意见非常好,surfer 的帮助文件对于其二次开发简直不可或缺。不过我补充两点,一是要用对应版本的帮助,因为每个版本都有可能出现方法、属性、参数的变化;二是用其他语言对 surfer 做二次开发,可以先在 scripter 测试一下自动化代码,对于不熟悉 surfer automation 的人,这可以事半功倍。
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2019-6-18 15:15:48 | 显示全部楼层
本帖最后由 qianz98 于 2019-6-18 15:18 编辑
holz 发表于 2019-6-14 09:31
楼主这个问题只要好好看帮助文件就可以了。
levels.set() 方法要求的参数是一个数组。
楼主其实想载入一 ...

感谢回复,我纠结的不是levels的各种方法的使用,而是python根本不支持levels这个对象,它不仅不支持levels,语句MapFrame.FillContours=1 这样的FillContours对象也不支持。ContourLayer.LevelMethod里的LevelMethod也不支持。另外问一下,如果 scripter 编辑器里面都调试好的文件。不用程序,能否命令行直接执行?
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2019-6-18 16:06:13 | 显示全部楼层
qianz98 发表于 2019-6-18 15:15
感谢回复,我纠结的不是levels的各种方法的使用,而是python根本不支持levels这个对象,它不仅不支持leve ...

一般用 C 语言,我用 Pascal,也不错。这个 Python,不懂。帮不到你。
还有,你说的:“另外问一下,如果 scripter 编辑器里面都调试好的文件。不用程序,能否命令行直接执行?”
请将“能否”两字,还有问号,都去掉,这就是回答。
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2019-6-24 16:06:58 | 显示全部楼层
chengxf 发表于 2019-6-18 16:06
一般用 C 语言,我用 Pascal,也不错。这个 Python,不懂。帮不到你。
还有,你说的:“另外问一下,如 ...

谢谢
  1. "C:\Program Files\Golden Software\Surfer 16\Scripter.exe" -x BaseMap.bas
复制代码
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2019-6-27 09:01:01 | 显示全部楼层
qianz98 发表于 2019-6-18 15:15
感谢回复,我纠结的不是levels的各种方法的使用,而是python根本不支持levels这个对象,它不仅不支持leve ...

刚刚有点时间,试验了一下,一切正常,并没有不支持 levels 对象、方法的现象出现。
我的测试代码:

  1. '''
  2. python 3.7 + win32com + surfer 16.5
  3. '''
  4. import win32com.client as w32c

  5. def main():
  6.     # 获取已经运行的 Surfer 实例
  7.     # gsApp = w32c.GetObject(Class = 'Surfer.Application')

  8.     # 创建新的 Surfer 实例
  9.     gsApp = w32c.Dispatch('Surfer.Application')
  10.     gsApp.visible = True
  11.     Plot = gsApp.documents.add(1)
  12.     MapFrame = Plot.Shapes.AddContourMap(gsApp.Path + '\Samples\demogrid.grd')
  13.     ContourLayer = MapFrame.Overlays(1)
  14.     ContourLayer.Name = '等值线'

  15.     # 首先要设置等值线填充
  16.     ContourLayer.FillContours = True
  17.     # 然后设置的带填充等级属性才能看到
  18.     ContourLayer.Levels.LoadFile(gsApp.Path + '\Samples\Rainbow.lvl')

  19. if __name__ == '__main__':
  20.     main()
复制代码
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

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