爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 3564|回复: 1

[vbscript] 计算多边形内的等值线均值

[复制链接]

新浪微博达人勋

发表于 2017-1-17 09:59:48 | 显示全部楼层 |阅读模式

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

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

x
假设有一个等值线图,上面有一些多边形区域,想要计算每个多边形区域内的等值线平均值。

要求有一个 grd 文件,一个含有封闭多边形对象的 bln 文件。

效果如下:

2017-01-17_095907.png

代码如下:

  1. '============================================================
  2. '用途:计算多边形区域内的等值线平均值。
  3. '输入:一个用来绘制等值线图的网格文件,一个包含多边形的边界文件。
  4. '不足:会生成垃圾文件 temp.bln 和 temp.dat
  5. 'holz [AT] live.com
  6. '2017-1-16
  7. 'Golden Software Surfer 13.x + Scripter
  8. 'Use on your own risk!
  9. '============================================================

  10. Option Explicit
  11. Sub Main
  12.         Dim gsApp As IApplication2
  13.         Dim wks As IWksDocument

  14.         Dim grd As String
  15.         Dim bln As String
  16.         Dim dat As String

  17.         Debug.Clear
  18.         Debug.Print "======== " & Date & " " & Time & " ========"
  19.         'grd = GetFilePath(,"grd",,"Select grid file",4)
  20.         grd = "D:\gmt5ex\demogrid.grd"
  21.         If grd = "" Then End
  22.         'bln = GetFilePath(,"bln",,"Select bln file",4)
  23.         bln = "D:\gmt5ex\demogrid_township_range.bln"
  24.         If bln = "" Then End
  25.         dat = Left(bln,Len(bln)-4) & "_Vc.dat"

  26.         On Error Resume Next
  27.         Set gsApp = CreateObject("Surfer.Application")
  28.         If Err.Number <> 0 Then End
  29.         On Error GoTo 0

  30.         Set wks = gsApp.Documents.Open2(bln)

  31.         Dim nBLN As Integer
  32.         Dim blnHeader As Integer, blnFlag As Integer
  33.         Dim tmpBln As String, tmpDat As String
  34.         Dim tmpWks As IWksDocument
  35.         Dim stats As IWksStatistics
  36.         Dim i As Integer
  37.         Dim r As Integer
  38.         Dim zMean As Double
  39.         Dim Xc As Double, Yc As Double

  40.         nBLN = 0
  41.         blnFlag = 0                '白化标志值, 0 表示白化外部, 1 表示白化内部
  42.         r = 1
  43.         Open dat For Output As #1
  44.         Print #1, "Xc, Yc, Zmean"
  45.         Debug.Print "正在处理 BLN 文件 " & bln
  46.         Debug.Print "该文件内含 " & wks.Columns("A").RowCount & " 行数据。"
  47.         While r < wks.Columns("A").RowCount
  48.                 blnHeader = wks.Cells(r, 1).Value
  49.                 blnFlag = wks.Cells(r, 2).Value

  50.                 '只有第一点坐标与最后一点坐标重合才算封闭多边形
  51.                 If Abs(wks.Cells(r+1, 1).Value - wks.Cells(r+blnHeader, 1).Value) < 1e-5 And _
  52.                         Abs(wks.Cells(r+1, 2).Value - wks.Cells(r+blnHeader, 2).Value) < 1e-5 Then
  53.                         nBLN = nBLN + 1                        '计算封闭多边形对象个数
  54.                         tmpBln = "Temp.bln"         '产生的垃圾文件名
  55.                         tmpDat = "Temp.dat"         '产生的另一个垃圾文件名

  56.                         '新增一个空白工作表文档
  57.                         Set tmpWks = gsApp.Documents.Add(srfDocWks)
  58.                         '把当前要处理的多边形数据复制到剪贴板
  59.                         wks.Cells(r, 1, r+blnHeader, 2).Copy
  60.                         '从剪贴板把数据粘贴到新工作表
  61.                         tmpWks.Cells("A1").Paste
  62.                         '设置白化标志值
  63.                         tmpWks.Cells("B1").Value = blnFlag
  64.                         '以下 3 行计算多边形中心坐标
  65.                         Set stats = tmpWks.Cells(2,1,blnHeader+1,2).Statistics(Flags:=wksStatsSum)
  66.                         Xc = stats.Sum(1) / blnHeader
  67.                         Yc = stats.Sum(2) / blnHeader
  68.                         '把新工作表保存为 bln 文件并关闭,此文件有且仅有一个多边形对象
  69.                         tmpWks.SaveAs(FileName:=tmpBln, FileFormat:=srfSaveFormatBln)
  70.                         tmpWks.Close(srfSaveChangesNo)

  71.                         '用刚生成的 bln 文件白化 grd 文件, 得到一个数据文件
  72.                         gsApp.GridBlank(grd, tmpBln, tmpDat, srfGridFmtXYZ)
  73.                         '打开白化结果
  74.                         Set tmpWks = gsApp.Documents.Open2(tmpDat)
  75.                         '对数据按 C 列进行升序排序
  76.                         tmpWks.Columns(1, 3).Sort(Col1:=3, Order1:=wksSortAscending)
  77.                         '发现白化值 1.70141e+38 即把后续行一次性删除,剩下即为有效数值
  78.                         For i = 1 To tmpWks.Columns(1).RowCount
  79.                                 If tmpWks.Cells(i, 3).Value = 1.70141e+38 Then
  80.                                         tmpWks.Rows(i, tmpWks.Columns(1).RowCount).Delete(wksDeleteRows)
  81.                                         Exit For
  82.                                 End If
  83.                         Next
  84.                         '计算均值后关闭
  85.                         Set stats = tmpWks.Columns(3).Statistics(Flags:=wksStatsMean)
  86.                         zMean = stats.Mean
  87.                         tmpWks.Close(srfSaveChangesNo)

  88.                         '显示计算得到的多边形中心和均值,并写入磁盘文件
  89.                         Debug.Print Xc; ", "; Yc; ", "; zMean
  90.                         Print #1,  Xc; ", "; Yc; ", "; zMean
  91.                 End If
  92.                 r = r + blnHeader + 1
  93.         Wend
  94.         Close #1
  95.         Debug.Print "其中发现 " & nBLN & " 个多边形对象。"
  96.         wks.Close(srfSaveChangesNo)

  97.         Debug.Print "开始绘制示意图,使用以下文件:"
  98.         Debug.Print "  1. " & grd
  99.         Debug.Print "  2. " & bln
  100.         Debug.Print "  3. " & dat
  101.         Dim Plot As IPlotDocument
  102.         Set Plot = gsApp.Documents.Add(srfDocPlot)

  103.         Debug.Print "绘制等值线图。"
  104.         Dim MapFrame As IMapFrame2
  105.         Set MapFrame = Plot.Shapes.AddContourMap(grd)
  106.         Dim Axis As IAxis2
  107.         For Each Axis In MapFrame.Axes
  108.                 Axis.MajorTickType = srfTickNone
  109.                 Axis.MinorTickType = srfTickNone
  110.                 Axis.ShowLabels = False
  111.         Next
  112.         Dim ContourLayer As IContourLayer
  113.         Set ContourLayer = MapFrame.Overlays(1)
  114.         With ContourLayer
  115.                 .LevelMethod = SrfConLevelMethodSimple
  116.                 .FillForegroundColorMap.LoadFile(gsApp.Path & "\ColorScales\Rainbow.clr")
  117.                 .FillContours = True
  118.                 '.ApplyFillToLevels(1,2,1)
  119.                 .ShowMajorLabels = False
  120.                 .ShowMinorLabels = False
  121.         End With

  122.         Debug.Print "添加基底图层,对多边形对象做填充。"
  123.         Dim BaseLayer As IBaseLayer
  124.         Set BaseLayer = Plot.Shapes.AddBaseLayer(MapFrame, bln)
  125.         With BaseLayer.Fill
  126.                 .Transparent = True
  127.                 .Pattern = "Diagonal Cross"
  128.                 .ForeColorRGBA.Color = srfColorNavyBlue
  129.                 .ForeColorRGBA.Opacity = 90
  130.                 .BackColorRGBA.Color = srfColorBabyBlue
  131.                 .BackColorRGBA.Opacity = 45
  132.         End With
  133.         BaseLayer.Line.ForeColor = srfColorRed
  134.         BaseLayer.Line.Width = 0.05

  135.         Debug.Print "添加张贴图层,显示多边形内等值线均值。"
  136.         Dim PostLayer As IPostLayer
  137.         Set PostLayer = Plot.Shapes.AddPostLayer(MapFrame, dat, 1, 2, 3)
  138.         With PostLayer
  139.                 .LabelFormat.Type = srfLabFixed
  140.                 .LabelFormat.NumDigits = 2
  141.                 .LabelFont.Color = srfColorYellow
  142.                 .LabelFont.Size = 16
  143.                 .LabelFont.Bold = True
  144.                 .Symbol.Set = "GSI Default Symbols"
  145.                 .Symbol.Index = 33
  146.                 .Symbol.Size = 0.75
  147.                 .Symbol.FillColor = srfColorYellow
  148.                 .Symbol.LineColor = srfColorBlack
  149.         End With

  150.         gsApp.Visible = True
  151.         gsApp.ActiveWindow.Zoom(srfZoomFitToWindow)
  152. End Sub
复制代码


AverageOfContoursWithinPolygon.BAS

5.31 KB, 下载次数: 5, 下载积分: 金钱 -5

评分

参与人数 3威望 +4 金钱 +55 贡献 +13 体力 +120 收起 理由
Rainch + 10 赞一个!
chengxf + 30 + 8 赞一个!
言深深 + 4 + 15 + 5 + 120 赞一个!

查看全部评分

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

新浪微博达人勋

发表于 2017-1-24 19:48:31 | 显示全部楼层
学习了。能不能随时手动一圈就能显示其均值?
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

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

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

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