C# 自动化发布GeoServer之NetCDF
最近新接触了GeoServer,从零开始的研究也是折磨了好几天,发现GeoServer这块很多大佬分享各种解决方案,也是帮了我大忙,刚好告一个段落了,所以也贡献一下我这几天的研究成果,希望能帮到大家。目标:使用GeoServer自动化发布NetCDF文件,实现部署在Linux上自动化更新图层
环境:.net6.0,GeoServer 2.21,Linux
先看一下目录结构:
AbstracPublishHandler抽象类中写整体的处理方法,主要是对栅格文件处理的固定流程
附上源码:
1 using System.Runtime.InteropServices;
2
3 namespace ReservoirModelAnalysis.Module.GeoServicePublish.Common
4 {
5 /// <summary>
6 /// 发布抽象类
7 /// </summary>
8 public abstract class AbstracPublishHandler
9 {
10 /// <summary>
11 /// 测试的时候使用cmd命令,部署在linux服务器上的时候使用shell命令
12 /// </summary>
13 private Func<string, string> processCommand = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ProcessHandler.CmdProcess : ProcessHandler.ShellProcess;
14
15 /// <summary>
16 /// 数据仓库配置
17 /// </summary>
18 IDataTypeConfig dataTypeConfig;
19 /// <summary>
20 /// 发布处理
21 /// 1.先判断数据仓库是否存在,不存在直接进行第三步
22 /// 2.更新数据仓库,并且流程结束
23 /// 3.发布新的数据仓库
24 /// 4.发布指定的图层
25 /// 5.图层绑定已发布好的样式
26 /// </summary>
27 /// <param name="config">数据仓库类型配置</param>
28 /// <param name="path">文件路由</param>
29 public void Handling(IDataTypeConfig config, string path)
30 {
31 dataTypeConfig = config;
32 Console.WriteLine($"{DateTime.Now}:GeoServer发布准备开始!");
33
34 if (getCoverageStorebyName())
35 {
36 //仓库存在
37 UpdateCoverageStore(path);
38 }
39 else
40 {
41 //仓库不存在
42
43 //发布栅格存储
44 PublishCoverageStore(path);
45
46 //发布指定图层
47 PublishCoverages();
48
49 //绑定样式
50 SetLayerStyle();
51
52 }
53
54 Console.WriteLine($"{DateTime.Now}:GeoServer发布完成!");
55 }
56
57 /// <summary>
58 /// 获取指定类型的数据仓库名称
59 /// </summary>
60 /// <returns></returns>
61 private bool getCoverageStorebyName()
62 {
63 string url = $"{GeoServerConfig.GeoServerUrl}/workspaces/{dataTypeConfig.WorkSpaceName}/coveragestores/{dataTypeConfig.StoreName}.json";
64 string cmd = $"curl -v -u {GeoServerConfig.User}:{GeoServerConfig.Password} -XGET {url}";
65
66 var result = processCommand.Invoke(cmd);
67 Console.WriteLine($"判断是否有指定的数据仓库:\n【{result}】");
68
69 //简单的判断一下,内容不为nosuch的情况还有可能报其他错
70 return !(result.IndexOf("No such") > -1);
71 }
72
73 /// <summary>
74 /// 发布一个栅格数据存储
75 /// </summary>
76 /// <param name="path">栅格文件路径 使用//分割</param>
77 /// <returns></returns>
78 protected bool PublishCoverageStore(string path)
79 {
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 string cmd = $"curl -v -u {GeoServerConfig.User}:{GeoServerConfig.Password} -XPOST -H \"Content-type: text/xml\" -d \"{xml}\" {GeoServerConfig.GeoServerUrl}/workspaces/{dataTypeConfig.WorkSpaceName}/coveragestores";
82
83 var result = processCommand.Invoke(cmd);
84
85 Console.WriteLine($"发布栅格存储结果:\n【{result}】");
86
87 return true;
88 }
89
90 /// <summary>
91 /// 发布图层
92 /// </summary>
93 /// <returns></returns>
94 protected bool PublishCoverages()
95 {
96 dataTypeConfig.LayerList.ForEach(layerName =>
97 {
98 string xml = $"<coverage><nativeCoverageName>{layerName}</nativeCoverageName><name>{layerName}</name></coverage>";
99 string url = $"{GeoServerConfig.GeoServerUrl}/workspaces/{dataTypeConfig.WorkSpaceName}/coveragestores/{dataTypeConfig.StoreName}/coverages";
100 string cmd = $"curl -v -u {GeoServerConfig.User}:{GeoServerConfig.Password} -XPOST -H \"Content-type: text/xml\" -d \"{xml}\" {url}";
101
102 var result = processCommand.Invoke(cmd);
103
104 Console.WriteLine($"发布{layerName}图层结果:\n【{result}】");
105 });
106
107 return true;
108 }
109 /// <summary>
110 /// 给图层设置样式
111 /// </summary>
112 /// <returns></returns>
113 protected bool SetLayerStyle()
114 {
115 for (int i = 0; i < dataTypeConfig.LayerList.Count; i++)
116 {
117 string layerName = dataTypeConfig.LayerList;
118 string styleName = dataTypeConfig.StyleList;
119
120 string xml = $"<layer><defaultStyle><name>{styleName}</name></defaultStyle></layer>";
121 string url = $"{GeoServerConfig.GeoServerUrl}/layers/{layerName}";
122 string cmd = $"curl -v -u {GeoServerConfig.User}:{GeoServerConfig.Password} -XPUT -H \"Content-type: text/xml\" -d \"{xml}\" {url}";
123
124 var result = processCommand.Invoke(cmd);
125
126 Console.WriteLine($"绑定{layerName}图层{styleName}样式结果:\n【{result}】");
127 }
128 return true;
129 }
130
131 /// <summary>
132 /// 更新数据仓储
133 /// </summary>
134 /// <param name="path">栅格文件路径 使用//分割</param>
135 /// <returns></returns>
136 protected bool UpdateCoverageStore(string path)
137 {
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 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
141 var result = processCommand.Invoke(cmd);
142
143 Console.WriteLine($"更新数据仓库{dataTypeConfig.StoreName}结果:\n【{result}】");
144
145 return true;
146 }
147 }
148 }View Code
DataSourceType中放具体的栅格类型处理方法,目前只用到了NetCDF,NetCDFPublishHandler继承抽象类AbstracPublishHandler直接调用Handling方法即可。
我这边是使用Job定时执行发布任务
Linux上执行结果
1 2023/2/23 下午2:14:00:GeoServer发布准备开始!
2 Note: Unnecessary use of -X or --request, GET is already inferred.
3 * Trying 192.168.1.51:8080...
4 % Total % Received % XferdAverage Speed Time Time TimeCurrent
5 DloadUpload Total Spent LeftSpeed
6 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
7 * Server auth using Basic with user 'admin'
8 > GET /geoserver/rest/workspaces/workspace_demo/coveragestores/demostore.json HTTP/1.1
9 > Host: 192.168.1.51:8080
10 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
11 > User-Agent: curl/7.79.1
12 > Accept: */*
13 >
14 * Mark bundle as not supporting multiuse
15 < HTTP/1.1 200 OK
16 < X-Frame-Options: SAMEORIGIN
17 < Content-Type: application/json
18 < Transfer-Encoding: chunked
19 < Server: Jetty(9.4.44.v20210927)
20 <
21 {
22 100 491 0 491 0 0 8196 0 --:--:-- --:--:-- --:--:--8322
23 * Connection #0 to host 192.168.1.51 left intact
24 判断是否有指定的数据仓库:
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 * Trying 192.168.1.51:8080...
27 % Total % Received % XferdAverage Speed Time Time TimeCurrent
28 DloadUpload Total Spent LeftSpeed
29 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
30 * Server auth using Basic with user 'admin'
31 > PUT /geoserver/rest/workspaces/workspace_demo/coveragestores/demostore HTTP/1.1
32 > Host: 192.168.1.51:8080
33 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
34 > User-Agent: curl/7.79.1
35 > Accept: */*
36 > Content-type: text/xml
37 > Content-Length: 252
38 >
39 }
40 * Mark bundle as not supporting multiuse
41 < HTTP/1.1 200 OK
42 < X-Frame-Options: SAMEORIGIN
43 < Content-Length: 0
44 < Server: Jetty(9.4.44.v20210927)
45 <
46 100 252 0 0100 252 016046 --:--:-- --:--:-- --:--:-- 16800
47 * Connection #0 to host 192.168.1.51 left intact
48 更新数据仓库demostore结果:
49 【】
50 2023/2/23 下午2:14:00:GeoServer发布完成!
51 2023/2/23 下午2:15:00>>>>>>执行GeoService发布
52 2023/2/23 下午2:15:00:GeoServer发布准备开始!
53 Note: Unnecessary use of -X or --request, GET is already inferred.
54 * Trying 192.168.1.51:8080...
55 % Total % Received % XferdAverage Speed Time Time TimeCurrent
56 DloadUpload Total Spent LeftSpeed
57 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
58 * Server auth using Basic with user 'admin'
59 > GET /geoserver/rest/workspaces/workspace_demo/coveragestores/demostore.json HTTP/1.1
60 > Host: 192.168.1.51:8080
61 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
62 > User-Agent: curl/7.79.1
63 > Accept: */*
64 >
65 * Mark bundle as not supporting multiuse
66 < HTTP/1.1 404 Not Found
67 < X-Frame-Options: SAMEORIGIN
68 < Content-Type: text/plain
69 < Transfer-Encoding: chunked
70 < Server: Jetty(9.4.44.v20210927)
71 <
72 {
73 100 48 0 48 0 0 6269 0 --:--:-- --:--:-- --:--:--6857
74 * Connection #0 to host 192.168.1.51 left intact
75 判断是否有指定的数据仓库:
76 【No such coverage store: workspace_demo,demostore】
77 Note: Unnecessary use of -X or --request, POST is already inferred.
78 * Trying 192.168.1.51:8080...
79 % Total % Received % XferdAverage Speed Time Time TimeCurrent
80 DloadUpload Total Spent LeftSpeed
81 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
82 * Server auth using Basic with user 'admin'
83 > POST /geoserver/rest/workspaces/workspace_demo/coveragestores HTTP/1.1
84 > Host: 192.168.1.51:8080
85 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
86 > User-Agent: curl/7.79.1
87 > Accept: */*
88 > Content-type: text/xml
89 > Content-Length: 252
90 >
91 }
92 * Mark bundle as not supporting multiuse
93 < HTTP/1.1 201 Created
94 < X-Frame-Options: SAMEORIGIN
95 < Location: http://192.168.1.51:8080/geoserver/rest/workspaces/workspace_demo/coveragestores/demostore
96 < Content-Type: text/plain
97 < Content-Length: 9
98 < Server: Jetty(9.4.44.v20210927)
99 <
100 {
101 100 261100 9100 252 51014302 --:--:-- --:--:-- --:--:-- 15352
102 * Connection #0 to host 192.168.1.51 left intact
103 发布栅格存储结果:
104 【demostore】
105 Note: Unnecessary use of -X or --request, POST is already inferred.
106 * Trying 192.168.1.51:8080...
107 % Total % Received % XferdAverage Speed Time Time TimeCurrent
108 DloadUpload Total Spent LeftSpeed
109 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
110 * Server auth using Basic with user 'admin'
111 > POST /geoserver/rest/workspaces/workspace_demo/coveragestores/demostore/coverages HTTP/1.1
112 > Host: 192.168.1.51:8080
113 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
114 > User-Agent: curl/7.79.1
115 > Accept: */*
116 > Content-type: text/xml
117 > Content-Length: 91
118 >
119 }
120 * Mark bundle as not supporting multiuse
121 < HTTP/1.1 201 Created
122 < X-Frame-Options: SAMEORIGIN
123 < Location: http://192.168.1.51:8080/geoserver/rest/workspaces/workspace_demo/coveragestores/demostore/coverages/tas_mean
124 < Content-Type: text/plain
125 < Content-Length: 8
126 < Server: Jetty(9.4.44.v20210927)
127 <
128 {
129 100 99100 8100 91 38 436 --:--:-- --:--:-- --:--:-- 478
130 * Connection #0 to host 192.168.1.51 left intact
131 发布tas_mean图层结果:
132 【tas_mean】
133 * Trying 192.168.1.51:8080...
134 % Total % Received % XferdAverage Speed Time Time TimeCurrent
135 DloadUpload Total Spent LeftSpeed
136 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 192.168.1.51 (192.168.1.51) port 8080 (#0)
137 * Server auth using Basic with user 'admin'
138 > PUT /geoserver/rest/layers/tas_mean HTTP/1.1
139 > Host: 192.168.1.51:8080
140 > Authorization: Basic YWRtaW46Z2Vvc2VydmVy
141 > User-Agent: curl/7.79.1
142 > Accept: */*
143 > Content-type: text/xml
144 > Content-Length: 63
145 >
146 }
147 100 63 0 0100 63 0 7387 --:--:-- --:--:-- --:--:--7875* Mark bundle as not supporting multiuse
148 < HTTP/1.1 200 OK
149 < X-Frame-Options: SAMEORIGIN
150 < Content-Length: 0
151 < Server: Jetty(9.4.44.v20210927)
152 <
153 100 63 0 0100 63 0 1837 --:--:-- --:--:-- --:--:--1852
154 * Connection #0 to host 192.168.1.51 left intact
155 绑定tas_mean图层raster样式结果:
156 【】
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】 我们会及时删除侵权内容,谢谢合作!
页:
[1]