翼度科技»论坛 编程开发 .net 查看内容

C# 自动化发布GeoServer之NetCDF

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
最近新接触了GeoServer,从零开始的研究也是折磨了好几天,发现GeoServer这块很多大佬分享各种解决方案,也是帮了我大忙,刚好告一个段落了,所以也贡献一下我这几天的研究成果,希望能帮到大家。
目标:使用GeoServer自动化发布NetCDF文件,实现部署在Linux上自动化更新图层
环境:.net6.0,GeoServer 2.21,Linux
先看一下目录结构:

 
 
 AbstracPublishHandler抽象类中写整体的处理方法,主要是对栅格文件处理的固定流程

 
附上源码:
  1.   1 using System.Runtime.InteropServices;
  2.   2
  3.   3 namespace ReservoirModelAnalysis.Module.GeoServicePublish.Common
  4.   4 {
  5.   5     /// <summary>
  6.   6     /// 发布抽象类
  7.   7     /// </summary>
  8.   8     public abstract class AbstracPublishHandler
  9.   9     {
  10. 10         /// <summary>
  11. 11         /// 测试的时候使用cmd命令,部署在linux服务器上的时候使用shell命令
  12. 12         /// </summary>
  13. 13         private Func<string, string> processCommand = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ProcessHandler.CmdProcess : ProcessHandler.ShellProcess;
  14. 14
  15. 15         /// <summary>
  16. 16         /// 数据仓库配置
  17. 17         /// </summary>
  18. 18         IDataTypeConfig dataTypeConfig;
  19. 19         /// <summary>
  20. 20         /// 发布处理
  21. 21         /// 1.先判断数据仓库是否存在,不存在直接进行第三步
  22. 22         /// 2.更新数据仓库,并且流程结束
  23. 23         /// 3.发布新的数据仓库
  24. 24         /// 4.发布指定的图层
  25. 25         /// 5.图层绑定已发布好的样式
  26. 26         /// </summary>
  27. 27         /// <param name="config">数据仓库类型配置</param>
  28. 28         /// <param name="path">文件路由</param>
  29. 29         public void Handling(IDataTypeConfig config, string path)
  30. 30         {
  31. 31             dataTypeConfig = config;
  32. 32             Console.WriteLine($"{DateTime.Now}:GeoServer发布准备开始!");
  33. 33
  34. 34             if (getCoverageStorebyName())
  35. 35             {
  36. 36                 //仓库存在
  37. 37                 UpdateCoverageStore(path);
  38. 38             }
  39. 39             else
  40. 40             {
  41. 41                 //仓库不存在
  42. 42
  43. 43                 //发布栅格存储
  44. 44                 PublishCoverageStore(path);
  45. 45
  46. 46                 //发布指定图层
  47. 47                 PublishCoverages();
  48. 48
  49. 49                 //绑定样式
  50. 50                 SetLayerStyle();
  51. 51
  52. 52             }
  53. 53
  54. 54             Console.WriteLine($"{DateTime.Now}:GeoServer发布完成!");
  55. 55         }
  56. 56
  57. 57         /// <summary>
  58. 58         /// 获取指定类型的数据仓库名称
  59. 59         /// </summary>
  60. 60         /// <returns></returns>
  61. 61         private bool getCoverageStorebyName()
  62. 62         {
  63. 63             string url = $"{GeoServerConfig.GeoServerUrl}/workspaces/{dataTypeConfig.WorkSpaceName}/coveragestores/{dataTypeConfig.StoreName}.json";
  64. 64             string cmd = $"curl -v -u {GeoServerConfig.User}:{GeoServerConfig.Password} -XGET {url}";
  65. 65
  66. 66             var result = processCommand.Invoke(cmd);
  67. 67             Console.WriteLine($"判断是否有指定的数据仓库:\n【{result}】");
  68. 68
  69. 69             //简单的判断一下,内容不为nosuch的情况还有可能报其他错
  70. 70             return !(result.IndexOf("No such") > -1);
  71. 71         }
  72. 72
  73. 73         /// <summary>
  74. 74         /// 发布一个栅格数据存储
  75. 75         /// </summary>
  76. 76         /// <param name="path">栅格文件路径 使用//分割</param>
  77. 77         /// <returns></returns>
  78. 78         protected bool PublishCoverageStore(string path)
  79. 79         {
  80. 80             string xml = $"<coverageStore><name>{dataTypeConfig.StoreName}</name><type>NetCDF</type><enabled>true</enabled><workspace><name>{dataTypeConfig.WorkSpaceName}</name></workspace><__default>false</__default><url>file://{path}</url></coverageStore>";
  81. 81             string cmd = $"curl -v -u {GeoServerConfig.User}:{GeoServerConfig.Password} -XPOST -H "Content-type: text/xml" -d "{xml}" {GeoServerConfig.GeoServerUrl}/workspaces/{dataTypeConfig.WorkSpaceName}/coveragestores";
  82. 82
  83. 83             var result = processCommand.Invoke(cmd);
  84. 84
  85. 85             Console.WriteLine($"发布栅格存储结果:\n【{result}】");
  86. 86
  87. 87             return true;
  88. 88         }
  89. 89
  90. 90         /// <summary>
  91. 91         /// 发布图层
  92. 92         /// </summary>
  93. 93         /// <returns></returns>
  94. 94         protected bool PublishCoverages()
  95. 95         {
  96. 96             dataTypeConfig.LayerList.ForEach(layerName =>
  97. 97             {
  98. 98                 string xml = $"<coverage><nativeCoverageName>{layerName}</nativeCoverageName><name>{layerName}</name></coverage>";
  99. 99                 string url = $"{GeoServerConfig.GeoServerUrl}/workspaces/{dataTypeConfig.WorkSpaceName}/coveragestores/{dataTypeConfig.StoreName}/coverages";
  100. 100                 string cmd = $"curl -v -u {GeoServerConfig.User}:{GeoServerConfig.Password} -XPOST -H "Content-type: text/xml" -d "{xml}" {url}";
  101. 101
  102. 102                 var result = processCommand.Invoke(cmd);
  103. 103
  104. 104                 Console.WriteLine($"发布{layerName}图层结果:\n【{result}】");
  105. 105             });
  106. 106
  107. 107             return true;
  108. 108         }
  109. 109         /// <summary>
  110. 110         /// 给图层设置样式
  111. 111         /// </summary>
  112. 112         /// <returns></returns>
  113. 113         protected bool SetLayerStyle()
  114. 114         {
  115. 115             for (int i = 0; i < dataTypeConfig.LayerList.Count; i++)
  116. 116             {
  117. 117                 string layerName = dataTypeConfig.LayerList[i];
  118. 118                 string styleName = dataTypeConfig.StyleList[i];
  119. 119
  120. 120                 string xml = $"<layer><defaultStyle><name>{styleName}</name></defaultStyle></layer>";
  121. 121                 string url = $"{GeoServerConfig.GeoServerUrl}/layers/{layerName}";
  122. 122                 string cmd = $"curl -v -u {GeoServerConfig.User}:{GeoServerConfig.Password} -XPUT -H "Content-type: text/xml" -d "{xml}" {url}";
  123. 123
  124. 124                 var result = processCommand.Invoke(cmd);
  125. 125
  126. 126                 Console.WriteLine($"绑定{layerName}图层{styleName}样式结果:\n【{result}】");
  127. 127             }
  128. 128             return true;
  129. 129         }
  130. 130
  131. 131         /// <summary>
  132. 132         /// 更新数据仓储
  133. 133         /// </summary>
  134. 134         /// <param name="path">栅格文件路径 使用//分割</param>
  135. 135         /// <returns></returns>
  136. 136         protected bool UpdateCoverageStore(string path)
  137. 137         {
  138. 138             string xml = $"<coverageStore><name>{dataTypeConfig.StoreName}</name><type>NetCDF</type><enabled>true</enabled><workspace><name>{dataTypeConfig.WorkSpaceName}</name></workspace><__default>false</__default><url>file://{path}</url></coverageStore>";
  139. 139             string cmd = $"curl -v -u {GeoServerConfig.User}:{GeoServerConfig.Password} -XPUT -H "Content-type: text/xml" -d "{xml}" {GeoServerConfig.GeoServerUrl}/workspaces/{dataTypeConfig.WorkSpaceName}/coveragestores/{dataTypeConfig.StoreName}";
  140. 140
  141. 141             var result = processCommand.Invoke(cmd);
  142. 142
  143. 143             Console.WriteLine($"更新数据仓库{dataTypeConfig.StoreName}结果:\n【{result}】");
  144. 144
  145. 145             return true;
  146. 146         }
  147. 147     }
  148. 148 }
复制代码
View Code 
 DataSourceType中放具体的栅格类型处理方法,目前只用到了NetCDF,NetCDFPublishHandler继承抽象类AbstracPublishHandler直接调用Handling方法即可。
我这边是使用Job定时执行发布任务

 
 Linux上执行结果
  1.   1 2023/2/23 下午2:14:00:GeoServer发布准备开始!
  2.   2 Note: Unnecessary use of -X or --request, GET is already inferred.
  3.   3 *   Trying 192.168.1.51:8080...
  4.   4   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
  5.   5                                  Dload  Upload   Total   Spent    Left  Speed
  6.   6   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
  7.   7 * Server auth using Basic with user 'admin'
  8.   8 > GET /geoserver/rest/workspaces/workspace_demo/coveragestores/demostore.json HTTP/1.1
  9.   9 > Host: 192.168.1.51:8080
  10. 10 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
  11. 11 > User-Agent: curl/7.79.1
  12. 12 > Accept: */*
  13. 13 >
  14. 14 * Mark bundle as not supporting multiuse
  15. 15 < HTTP/1.1 200 OK
  16. 16 < X-Frame-Options: SAMEORIGIN
  17. 17 < Content-Type: application/json
  18. 18 < Transfer-Encoding: chunked
  19. 19 < Server: Jetty(9.4.44.v20210927)
  20. 20 <
  21. 21 { [496 bytes data]
  22. 22 100   491    0   491    0     0   8196      0 --:--:-- --:--:-- --:--:--  8322
  23. 23 * Connection #0 to host 192.168.1.51 left intact
  24. 24 判断是否有指定的数据仓库:
  25. 25 【{"coverageStore":{"name":"demostore","type":"NetCDF","enabled":true,"workspace":{"name":"workspace_demo","href":"http://192.168.1.51:8080/geoserver/rest/workspaces/workspace_demo.json"},"_default":false,"dateCreated":"2023-02-23 05:33:01.37 UTC","dateModified":"2023-02-23 05:34:01.101 UTC","url":"file://D:\\gsFile\\HadCRUT.5.0.1.0.analysis.anomalies.ensemble_mean.nc","coverages":"http://192.168.1.51:8080/geoserver/rest/workspaces/workspace_demo/coveragestores/demostore/coverages.json"}}】
  26. 26 *   Trying 192.168.1.51:8080...
  27. 27   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
  28. 28                                  Dload  Upload   Total   Spent    Left  Speed
  29. 29   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
  30. 30 * Server auth using Basic with user 'admin'
  31. 31 > PUT /geoserver/rest/workspaces/workspace_demo/coveragestores/demostore HTTP/1.1
  32. 32 > Host: 192.168.1.51:8080
  33. 33 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
  34. 34 > User-Agent: curl/7.79.1
  35. 35 > Accept: */*
  36. 36 > Content-type: text/xml
  37. 37 > Content-Length: 252
  38. 38 >
  39. 39 } [252 bytes data]
  40. 40 * Mark bundle as not supporting multiuse
  41. 41 < HTTP/1.1 200 OK
  42. 42 < X-Frame-Options: SAMEORIGIN
  43. 43 < Content-Length: 0
  44. 44 < Server: Jetty(9.4.44.v20210927)
  45. 45 <
  46. 46 100   252    0     0  100   252      0  16046 --:--:-- --:--:-- --:--:-- 16800
  47. 47 * Connection #0 to host 192.168.1.51 left intact
  48. 48 更新数据仓库demostore结果:
  49. 49 【】
  50. 50 2023/2/23 下午2:14:00:GeoServer发布完成!
  51. 51 2023/2/23 下午2:15:00>>>>>>执行GeoService发布
  52. 52 2023/2/23 下午2:15:00:GeoServer发布准备开始!
  53. 53 Note: Unnecessary use of -X or --request, GET is already inferred.
  54. 54 *   Trying 192.168.1.51:8080...
  55. 55   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
  56. 56                                  Dload  Upload   Total   Spent    Left  Speed
  57. 57   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
  58. 58 * Server auth using Basic with user 'admin'
  59. 59 > GET /geoserver/rest/workspaces/workspace_demo/coveragestores/demostore.json HTTP/1.1
  60. 60 > Host: 192.168.1.51:8080
  61. 61 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
  62. 62 > User-Agent: curl/7.79.1
  63. 63 > Accept: */*
  64. 64 >
  65. 65 * Mark bundle as not supporting multiuse
  66. 66 < HTTP/1.1 404 Not Found
  67. 67 < X-Frame-Options: SAMEORIGIN
  68. 68 < Content-Type: text/plain
  69. 69 < Transfer-Encoding: chunked
  70. 70 < Server: Jetty(9.4.44.v20210927)
  71. 71 <
  72. 72 { [52 bytes data]
  73. 73 100    48    0    48    0     0   6269      0 --:--:-- --:--:-- --:--:--  6857
  74. 74 * Connection #0 to host 192.168.1.51 left intact
  75. 75 判断是否有指定的数据仓库:
  76. 76 【No such coverage store: workspace_demo,demostore】
  77. 77 Note: Unnecessary use of -X or --request, POST is already inferred.
  78. 78 *   Trying 192.168.1.51:8080...
  79. 79   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
  80. 80                                  Dload  Upload   Total   Spent    Left  Speed
  81. 81   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
  82. 82 * Server auth using Basic with user 'admin'
  83. 83 > POST /geoserver/rest/workspaces/workspace_demo/coveragestores HTTP/1.1
  84. 84 > Host: 192.168.1.51:8080
  85. 85 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
  86. 86 > User-Agent: curl/7.79.1
  87. 87 > Accept: */*
  88. 88 > Content-type: text/xml
  89. 89 > Content-Length: 252
  90. 90 >
  91. 91 } [252 bytes data]
  92. 92 * Mark bundle as not supporting multiuse
  93. 93 < HTTP/1.1 201 Created
  94. 94 < X-Frame-Options: SAMEORIGIN
  95. 95 < Location: http://192.168.1.51:8080/geoserver/rest/workspaces/workspace_demo/coveragestores/demostore
  96. 96 < Content-Type: text/plain
  97. 97 < Content-Length: 9
  98. 98 < Server: Jetty(9.4.44.v20210927)
  99. 99 <
  100. 100 { [9 bytes data]
  101. 101 100   261  100     9  100   252    510  14302 --:--:-- --:--:-- --:--:-- 15352
  102. 102 * Connection #0 to host 192.168.1.51 left intact
  103. 103 发布栅格存储结果:
  104. 104 【demostore】
  105. 105 Note: Unnecessary use of -X or --request, POST is already inferred.
  106. 106 *   Trying 192.168.1.51:8080...
  107. 107   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
  108. 108                                  Dload  Upload   Total   Spent    Left  Speed
  109. 109   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
  110. 110 * Server auth using Basic with user 'admin'
  111. 111 > POST /geoserver/rest/workspaces/workspace_demo/coveragestores/demostore/coverages HTTP/1.1
  112. 112 > Host: 192.168.1.51:8080
  113. 113 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
  114. 114 > User-Agent: curl/7.79.1
  115. 115 > Accept: */*
  116. 116 > Content-type: text/xml
  117. 117 > Content-Length: 91
  118. 118 >
  119. 119 } [91 bytes data]
  120. 120 * Mark bundle as not supporting multiuse
  121. 121 < HTTP/1.1 201 Created
  122. 122 < X-Frame-Options: SAMEORIGIN
  123. 123 < Location: http://192.168.1.51:8080/geoserver/rest/workspaces/workspace_demo/coveragestores/demostore/coverages/tas_mean
  124. 124 < Content-Type: text/plain
  125. 125 < Content-Length: 8
  126. 126 < Server: Jetty(9.4.44.v20210927)
  127. 127 <
  128. 128 { [8 bytes data]
  129. 129 100    99  100     8  100    91     38    436 --:--:-- --:--:-- --:--:--   478
  130. 130 * Connection #0 to host 192.168.1.51 left intact
  131. 131 发布tas_mean图层结果:
  132. 132 【tas_mean】
  133. 133 *   Trying 192.168.1.51:8080...
  134. 134   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
  135. 135                                  Dload  Upload   Total   Spent    Left  Speed
  136. 136   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
  137. 137 * Server auth using Basic with user 'admin'
  138. 138 > PUT /geoserver/rest/layers/tas_mean HTTP/1.1
  139. 139 > Host: 192.168.1.51:8080
  140. 140 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
  141. 141 > User-Agent: curl/7.79.1
  142. 142 > Accept: */*
  143. 143 > Content-type: text/xml
  144. 144 > Content-Length: 63
  145. 145 >
  146. 146 } [63 bytes data]
  147. 147 100    63    0     0  100    63      0   7387 --:--:-- --:--:-- --:--:--  7875* Mark bundle as not supporting multiuse
  148. 148 < HTTP/1.1 200 OK
  149. 149 < X-Frame-Options: SAMEORIGIN
  150. 150 < Content-Length: 0
  151. 151 < Server: Jetty(9.4.44.v20210927)
  152. 152 <
  153. 153 100    63    0     0  100    63      0   1837 --:--:-- --:--:-- --:--:--  1852
  154. 154 * Connection #0 to host 192.168.1.51 left intact
  155. 155 绑定tas_mean图层raster样式结果:
  156. 156 【】
  157. 157 2023/2/23 下午2:15:00:GeoServer发布完成!
复制代码
Linux执行结果目前只是一个简单跑通的状态,里面其实还有许多需要完善的地方,包括对curl命令执行结果的判断,多个仓库的发布等等,后面再持续更新吧!

来源:https://www.cnblogs.com/JessieR/archive/2023/02/23/17147851.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具