using System.Net; using System.Net.Http.Headers; using System.Text; using System.Xml.Linq; using DocumentFormat.OpenXml.Wordprocessing; using Infrastructure; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OSGeo.GDAL; using OSGeo.OSR; namespace OpenAuth.App.ServiceApp.ShpGeo.Utils; public class GeoUtil { private static GeoContext _geoContext = GeoContext.Instance; // geosever 地址 public static readonly string GeoserverUrl = _geoContext.GeoserverUrl; // 默认工作空间 public static readonly string Workspace = _geoContext.Workspace; // geoserver 用户名 public static readonly string Username = _geoContext.Username; // geoserver 密码 public static readonly string Password = _geoContext.Password; // geosever 地址 public static readonly string JobwebUrl = _geoContext.JobwebUrl; // 默认数据库 schema public static readonly string DbSchema = _geoContext.DbSchema; public static readonly string DbStoreName = _geoContext.DbStoreName; public static readonly string ConnectionString = _geoContext.ConnectionString; /// /// 创建数据存储和图层,样式存在的话,绑定样式 /// /// /// /// public static async Task CreateStoreAndLayer(string workspace, string srs, string layerName, string styleName) { //{"PORT":"5432","Database":"drone_enforcement_linyi_20240712","HOST":"192.168.10.102","PASSWORD":"123456","USER ID":"postgres"} var dbElement = ParseConnectionString(ConnectionString); using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } // 判断是否存在工作空间 var existWorkspaceResponse = await ExistWorkspace(workspace); if (!existWorkspaceResponse.Result) { var createWorkspaceResponse = await CreateWorkspace(workspace); if (!createWorkspaceResponse.Result) { throw new Exception("创建工作空间失败"); } } // 判断Db仓库是否存在 var dbStoreExUrl = GeoserverUrl + "/rest/workspaces/" + workspace + "/datastores/" + DbStoreName + ".xml"; var response = await client.GetAsync(dbStoreExUrl); if (response.StatusCode == HttpStatusCode.NotFound) { // 创建数据存储 var contentStr = "" + "" + DbStoreName + "" + "PostGIS" + "true" + "" + "" + dbElement["HOST"] + "" + "" + dbElement["PORT"] + "" + "" + DbSchema + "" + "" + dbElement["Database"] + "" + "" + dbElement["USER ID"] + "" + "" + dbElement["PASSWORD"] + "" + "postgis" + //"" + layerName + "
" + "
" + "
"; var createDataStoreUrl = GeoserverUrl + "/rest/workspaces/" + workspace + "/datastores"; var content = new StringContent(contentStr, Encoding.UTF8, "text/xml"); // 执行创建数据存储 var result = await client.PostAsync(createDataStoreUrl, content); var resultStr = result.Content.ReadAsStringAsync(); // 未校验,一般失败就是已存在 Console.WriteLine("创建数据存储StatusCode:" + result.StatusCode); Console.WriteLine("创建数据存储返回结果:" + resultStr.Result); } // 判断图层存不存在 var layerExUrl = GeoserverUrl + "/rest/layers/" + workspace + ":" + layerName + ".xml"; var layerExResult = await client.GetAsync(layerExUrl); if (layerExResult.StatusCode == HttpStatusCode.OK) { // 图层存在时间直接更新数据表即可 return true; /*var deleteLayerUrl = GeoserverUrl + "/rest/layers/" + Workspace + ":" + layerName; var deleteLayerResult = await client.DeleteAsync(deleteLayerUrl); var deleteLayerResultStr = deleteLayerResult.Content.ReadAsStringAsync(); Console.WriteLine("删除图层返回结果:" + deleteLayerResultStr.Result); if (deleteLayerResult.StatusCode != HttpStatusCode.OK) { throw new Exception("图层已存在但删除失败"); }*/ // 结束 } // 创建图层1 var createLayerUrl = GeoserverUrl + "/rest/workspaces/" + workspace + "/datastores/" + DbStoreName + "/featuretypes"; // var createLayerUrl = GEOSERVER_URL + "/rest/workspaces/"+WORKSPACE+"layers"; var createLayerContentStr = "" + "true" + "" + "" + "" + "" + "" + layerName + "" + "" + layerName + "" + "" + srs + "" + "" + layerName + "" + ""; Console.WriteLine("创建图层参数:" + createLayerContentStr); var createLayerContent = new StringContent(createLayerContentStr, Encoding.UTF8, "text/xml"); var createLayerResult = await client.PostAsync(createLayerUrl, createLayerContent); var createLayerResultStr = createLayerResult.Content.ReadAsStringAsync(); Console.WriteLine("创建图层返回code:" + createLayerResult.StatusCode); Console.WriteLine("创建图层返回结果:" + createLayerResultStr.Result); // 发布图层 var publishLayerUrl = GeoserverUrl + "/rest/layers/" + workspace + ":" + layerName + ""; var styleXmlPart = ""; if (!string.IsNullOrEmpty(styleName)) { styleXmlPart = "" + "" + styleName + "" + "" + workspace + "" + ""; } var publishContentStr = "" + "true" + "" + "" + "" + styleXmlPart + ""; Console.WriteLine("发布图层参数:" + publishContentStr); var publishContent = new StringContent(publishContentStr, Encoding.UTF8, "text/xml"); var publishLayerResult = await client.PutAsync(publishLayerUrl, publishContent); Console.WriteLine("发布图层返回结果:" + publishLayerResult.Content); if (publishLayerResult.StatusCode != HttpStatusCode.OK) { throw new Exception("发布图层失败"); } return true; } /// /// 判断样式是否存在 /// /// /// public static async Task ExistStyle(string workspace, string styleName) { using var client = new HttpClient(); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); var existStyleUrl = GeoserverUrl + "/rest/workspaces/" + workspace + "/styles/" + styleName + ".xml"; var response = await client.GetAsync(existStyleUrl); return response.StatusCode == HttpStatusCode.OK; } /// /// 创建SLD样式并发布 /// /// /// public static async Task PublishSldStyle(string sldPath, string styleName) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); // 样式名称 var sldFileName = Path.GetFileName(sldPath); //var styleName = Path.GetFileNameWithoutExtension(sldPath); // todo 判断样式是否存在 // 如何存在更新样式 //string apiUrl = GEOSERVER_URL + "/rest/styles?format=json&namespace=default&type=style&name={styleName}"; // 发布SLD样式两步骤 curl -v -u admin:geoserver -XPOST -H "Content-type: text/xml" -d "" http://localhost:8080/geoserver/rest/styles var prePublicSld = GeoserverUrl + "/rest/workspaces/" + Workspace + "/styles"; // "" var prePublishSldXml = ""; var response = await client.PostAsync(prePublicSld, new StringContent(prePublishSldXml, Encoding.UTF8, "text/xml")); if (response.StatusCode == HttpStatusCode.Created) { Console.WriteLine("SLD样式预发布返回结果:" + response.Content.ReadAsStringAsync().Result); // 发布SLD样式第二步 // curl -v -u admin:geoserver -XPUT -H "Content-type: application/vnd.ogc.sld+xml" -d @roads.sld http://localhost:8080/geoserver/rest/styles/roads_style //var publishSldToWorkspaceUrl = GeoserverUrl + "/rest/workspaces/" + Workspace + "/styles?name=" + Uri.EscapeDataString(styleName); var publishSldToWorkspaceUrl = GeoserverUrl + "/rest/workspaces/" + Workspace + "/styles/" + styleName; // SLD文件内容 var sldContent = await File.ReadAllTextAsync(sldPath, Encoding.UTF8); // 创建请求 var content = new StringContent(sldContent, Encoding.UTF8, "application/vnd.ogc.sld+xml"); // 执行创建数据存储 response = await client.PutAsync(publishSldToWorkspaceUrl, content); // 检查响应 Console.WriteLine(response.StatusCode); Console.WriteLine("SLD样式发布返回结果:" + response.Content.ReadAsStringAsync().Result); if (response.StatusCode == HttpStatusCode.OK) { Console.WriteLine("SLD发布成功"); return true; } } else { Console.WriteLine("SLD图层已存在"); return false; } Console.WriteLine($"SLD发布失败,状态码:{response.StatusCode}"); return false; } // # 创建工作区(如果不存在) //curl -u $USERNAME:$PASSWORD -X POST -H "Content-type: text/xml" -d "$WORKSPACE" $GEOSERVER_URL/rest/workspaces /// /// 解析数据库连接字符串 /// /// /// static Dictionary ParseConnectionString(string connectionString) { var details = new Dictionary(); var parts = connectionString.Split(';'); foreach (var part in parts) { var index = part.IndexOf('='); if (index != -1) { var key = part.Substring(0, index); var value = part.Substring(index + 1); details[key] = value; } } return details; } /// /// 获取图层bbox /// /// /// /// /// public static async Task> GetDBLayerBBox(string workspace, string storeName, string layerName) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } var dbStoreExUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/datastores/{storeName}/featuretypes/{layerName}.json"; var dbStoreExResult = await client.GetAsync(dbStoreExUrl); var resultObj = JsonConvert.DeserializeObject(dbStoreExResult.Content.ReadAsStringAsync().Result); if (dbStoreExResult.StatusCode == HttpStatusCode.OK) { var bbox = resultObj["featureType"]["latLonBoundingBox"]; var minx = bbox["minx"]; var miny = bbox["miny"]; var maxx = bbox["maxx"]; var maxy = bbox["maxy"]; Console.WriteLine("minx:" + minx); Console.WriteLine("miny:" + miny); Console.WriteLine("maxx:" + maxx); Console.WriteLine("maxy:" + maxy); Console.WriteLine("信息:" + dbStoreExResult.Content.ReadAsStringAsync().Result); return new Response { Result = minx + "," + miny + "," + maxx + "," + maxy, Code = 200 }; } return new Response { Code = 500 }; } /// /// 取得bbox 及 srs 信息 /// /// 工作空间名称 /// 存储仓库名称 /// 图层名称 /// public static async Task> GetTiffLayerInfo(string workspace, string storeName, string layerName) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } var dbStoreExUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}/coverages/{layerName}.json"; var dbStoreExResult = await client.GetAsync(dbStoreExUrl); if (dbStoreExResult.StatusCode == HttpStatusCode.OK) { var resultObj = JsonConvert.DeserializeObject(dbStoreExResult.Content.ReadAsStringAsync().Result); Console.WriteLine("GetTiffLayerInfo信息:" + dbStoreExResult.Content.ReadAsStringAsync().Result); var bbox = resultObj["coverage"]?["nativeBoundingBox"]; var srs = resultObj["coverage"]?["srs"]; var minx = bbox["minx"]; var miny = bbox["miny"]; var maxx = bbox["maxx"]; var maxy = bbox["maxy"]; Console.WriteLine("minx:" + minx); Console.WriteLine("miny:" + miny); Console.WriteLine("maxx:" + maxx); Console.WriteLine("maxy:" + maxy); return new Response { Result = new { bbox = minx + "," + miny + "," + maxx + "," + maxy, srs = srs }, Code = 200 }; } return new Response { Code = 500, Message = dbStoreExResult.Content.ReadAsStringAsync().Result }; } /// /// 删除栅格仓库 /// /// /// /// 递归删除(true 仓库下所有资源都将被删除) /// public static async Task> DeleteCoveragesStore(string workspace, string storeName, bool recurse = false) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } // 删除 coverageStore // The recurse controls recursive deletion. When set to true all resources contained in the store are also removed. The default value is "false". var deleteTiffStoreUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}"; if (recurse) { deleteTiffStoreUrl += "?recurse=true"; } else { deleteTiffStoreUrl += "?recurse=false"; } var deleteTiffStoreResult = await client.DeleteAsync(deleteTiffStoreUrl); Console.WriteLine("删除栅格仓库"); Console.WriteLine(deleteTiffStoreResult.Content.ReadAsStringAsync().Result); Console.WriteLine(deleteTiffStoreResult.StatusCode); switch (deleteTiffStoreResult.StatusCode) { case HttpStatusCode.OK: return new Response { Result = true, Code = 200 }; case HttpStatusCode.NotFound: return new Response { Result = false, Code = 404 }; default: return new Response { Result = false, Code = 500, Message = deleteTiffStoreResult.Content.ReadAsStringAsync().Result }; } } /// /// 删除图层 /// /// 工作空间,可不填 /// /// public static async Task> DeleteLayer(string workspace, string layerName) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } var deleteLayerUrl = $"{GeoserverUrl}/rest/layers/{workspace}:{layerName}"; var deleteLayerResponse = await client.DeleteAsync(deleteLayerUrl); Console.WriteLine("删除图层返回结果:"); Console.WriteLine(deleteLayerResponse.Content.ReadAsStringAsync().Result); Console.WriteLine(deleteLayerResponse.StatusCode); if (deleteLayerResponse.StatusCode == HttpStatusCode.OK) { return new Response { Result = true, Code = 200 }; } return new Response { Result = false, Code = 500 }; } /// /// 发布GeoTiff /// /// /// tif文件全路径 /// 栅格仓库名称 /// 图层名称 /// public static async Task> PublishExternalGeoTIFF(string workspace, string tifFullName, string storeName, string layerName) { var srs = "4548"; Console.WriteLine("传入影像全路径:" + tifFullName); /*var tifCrs = GetTifCrs(tifFullName); if (tifCrs.srs != null) { srs = tifCrs.srs; }*/ if (string.IsNullOrEmpty(tifFullName) || string.IsNullOrEmpty(storeName) || string.IsNullOrEmpty(layerName)) { return new Response { Result = false, Message = "参数不能为空" }; } using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } var existWorkspaceResponse = await ExistWorkspace(workspace); if (!existWorkspaceResponse.Result) { var createWorkspaceResponse = await CreateWorkspace(workspace); if (!createWorkspaceResponse.Result) { throw new Exception("创建工作空间失败,请检查geoserver状态"); } } // 创建 coverageStore var createTiffStoreUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores"; var tiffXml = $"" + $"{storeName}{workspace}" + "true" + "GeoTIFF" + $"file://{tifFullName}" + ""; //Console.WriteLine("栅格仓库xml: " + tiffXml); //GeoUtil.DeleteCoveragesStore(workspace, storeName, false); var content = new StringContent(tiffXml, Encoding.UTF8, "application/xml"); var response = await client.PostAsync(createTiffStoreUrl, content); if (response.StatusCode != HttpStatusCode.Created) { var msg = await response.Content.ReadAsStringAsync(); Console.Write("创建栅格仓库code: " + response.StatusCode + "错误信息:" + msg); return new Response { Result = false, Message = "创建仓库失败:" + msg }; } // 创建coverages var createTiffCoveragesUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}/coverages"; var tiffFileName = Path.GetFileNameWithoutExtension(tifFullName); // nativeName 参数必须是tiff文件名称 var createTiffCoveragesXml = @$" {storeName} {tiffFileName} true {layerName} {layerName} EPSG:{srs}REPROJECT_TO_DECLARED InputTransparentColor #000000 "; var createTiffCoveragesContent = new StringContent(createTiffCoveragesXml, Encoding.UTF8, "text/xml"); var createTiffCoveragesResponse = await client.PostAsync(createTiffCoveragesUrl, createTiffCoveragesContent); if (createTiffCoveragesResponse.StatusCode != HttpStatusCode.Created) { var msg = await createTiffCoveragesResponse.Content.ReadAsStringAsync(); //Console.Write(createTiffCoveragesResponse.StatusCode + " "); //Console.WriteLine(msg); return new Response { Result = false, Message = "创建仓库失败:" + msg }; } var publishTiffLayerUrl = $"{GeoserverUrl}/rest/layers/{workspace}:{layerName}"; var publishTiffLayerXml = "true"; var publishTiffLayerContent = new StringContent(publishTiffLayerXml, Encoding.UTF8, "text/xml"); var publishTiffLayerResponse = await client.PutAsync(publishTiffLayerUrl, publishTiffLayerContent); if (publishTiffLayerResponse.StatusCode != HttpStatusCode.OK) { var msg = await publishTiffLayerResponse.Content.ReadAsStringAsync(); //Console.Write(publishTiffLayerResponse.StatusCode + " "); //Console.WriteLine(msg); return new Response { Result = false, Message = "发布图层失败:" + msg }; } return new Response { Result = true }; } /// /// 判断工作空间是否存在 /// /// /// public static async Task> ExistWorkspace(string workspace) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); var url = $"{GeoserverUrl}/rest/workspaces/{workspace}.xml"; var response = await client.GetAsync(url); Console.WriteLine($"状态码:{response.StatusCode} 返回结果:{response.Content.ReadAsStringAsync().Result}"); if (response.StatusCode == HttpStatusCode.NotFound) { return new Response { Result = false }; } return new Response { Result = true }; } /// /// 创建工作空间 /// /// /// public static async Task> CreateWorkspace(string workspace) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); var createWorkspaceUrl = $"{GeoserverUrl}/rest/workspaces"; var createWorkspaceXml = $"{workspace}"; var createWorkspaceContent = new StringContent(createWorkspaceXml, Encoding.UTF8, "text/xml"); var createWorkspaceResponse = await client.PostAsync(createWorkspaceUrl, createWorkspaceContent); if (createWorkspaceResponse.StatusCode == HttpStatusCode.Created) { return new Response { Result = true }; } return new Response { Result = false }; } /// /// 删除工作空间 /// /// /// public static async Task> DeleteWorkspace(string workspace) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); var deleteWorkspaceUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}" + "?recurse=true"; var deleteWorkspaceResponse = await client.DeleteAsync(deleteWorkspaceUrl); Console.WriteLine("删除工作空间返回结果:"); Console.WriteLine(deleteWorkspaceResponse.Content.ReadAsStringAsync().Result); Console.WriteLine(deleteWorkspaceResponse.StatusCode); if (deleteWorkspaceResponse.StatusCode == HttpStatusCode.OK) { return new Response { Result = true, Code = 200 }; } return new Response { Result = false, Code = 500 }; } public static async Task> SettingLayerReturnFormat(string workspace, string layerName) { using var client = new HttpClient(); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); var queryLayerUrl = GeoserverUrl + "/gwc/rest/layers/" + workspace + ":" + layerName + ".xml"; var queryResult = await client.GetAsync(queryLayerUrl); Console.WriteLine( $" 结果:{queryResult.Content.ReadAsStringAsync().Result} code: {queryResult.StatusCode}"); if (queryResult.StatusCode == HttpStatusCode.OK) { var split = queryResult.Content.ReadAsStringAsync().Result.Split(""); var xml = split[0] + "" + "application/json;type=geojson" + "application/json;type=topojson" + "application/vnd.mapbox-vector-tile" + "application/json;type=utfgrid" + split[1]; var setGwc = GeoserverUrl + "/gwc/rest/layers/" + workspace + ":" + layerName; var content = new StringContent(xml, Encoding.UTF8, "application/xml"); var result = await client.PostAsync(setGwc, content); if (result.StatusCode == HttpStatusCode.OK) { return new Response() { Result = true, Code = 200 }; } } return new Response { Result = false, Code = 500 }; } /// /// 更新样式名,更新样式 /// /// /// /// public static async Task UpdateSldStyle(string sldPath, string styleName) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); var publishSldToWorkspaceUrl = GeoserverUrl + "/rest/workspaces/" + Workspace + "/styles/" + styleName; // SLD文件内容 var sldContent = await File.ReadAllTextAsync(sldPath, Encoding.UTF8); // 创建请求 var content = new StringContent(sldContent, Encoding.UTF8, "application/vnd.ogc.sld+xml"); // 执行创建数据存储 var response = await client.PutAsync(publishSldToWorkspaceUrl, content); // 检查响应 Console.WriteLine(response.StatusCode); Console.WriteLine("SLD样式发布返回结果:" + response.Content.ReadAsStringAsync().Result); if (response.StatusCode == HttpStatusCode.OK) { Console.WriteLine("SLD发布成功"); return true; } return false; } public static async Task> UpdateStyle(string workspace, string layerName, string styleName) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } var url = $"{GeoserverUrl}/rest/layers/{workspace}:{layerName}.xml"; //var xml = $"{styleName}"; var xml = $@" {styleName} "; var content = new StringContent(xml, Encoding.UTF8, "application/xml"); var result = await client.PutAsync(url, content); if (result.StatusCode == HttpStatusCode.OK) { return new Response { Result = true, }; } return new Response { Result = false, Code = 500 }; } public static async Task> publishLayerGroup(string workspace, string layers, string layerGroupName) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } var url = $"{GeoserverUrl}/rest/workspaces/{workspace}/layergroups"; var xml = "" + "" + " " + layerGroupName + "" + " " + layerGroupName + "" + " " + " " + workspace + "" + " " + " " + layers + " " + ""; var content = new StringContent(xml, Encoding.UTF8, "text/xml"); var result = await client.PostAsync(url, content); if (result.StatusCode == HttpStatusCode.OK) { return new Response { Result = true, }; } return new Response { Result = false, Code = 500 }; } /// /// 发布GeoTiff /// /// /// tif文件全路径 /// 栅格仓库名称 /// 图层名称 /// public static async Task> PublishSingleGeoTIFF(string workspace, string tifFullName, string storeName, string layerName) { if (string.IsNullOrEmpty(tifFullName) || string.IsNullOrEmpty(storeName) || string.IsNullOrEmpty(layerName)) { return new Response { Result = false, Message = "参数不能为空" }; } using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } var existWorkspaceResponse = await ExistWorkspace(workspace); if (!existWorkspaceResponse.Result) { var createWorkspaceResponse = await CreateWorkspace(workspace); if (!createWorkspaceResponse.Result) { throw new Exception("创建工作空间失败,请检查geoserver状态"); } } // 创建 coverageStore var createTiffStoreUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores"; var tiffXml = $"" + $"{storeName}{workspace}" + "true" + "GeoTIFF" + $"file://{tifFullName}" + ""; //Console.WriteLine("栅格仓库xml: " + tiffXml); //GeoUtil.DeleteCoveragesStore(workspace, storeName, false); var content = new StringContent(tiffXml, Encoding.UTF8, "application/xml"); var response = await client.PostAsync(createTiffStoreUrl, content); if (response.StatusCode != HttpStatusCode.Created) { var msg = await response.Content.ReadAsStringAsync(); Console.Write("创建栅格仓库code: " + response.StatusCode + "错误信息:" + msg); return new Response { Result = false, Message = "创建仓库失败:" + msg }; } // 创建coverages var createTiffCoveragesUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}/coverages"; var tiffFileName = Path.GetFileName(tifFullName).Replace(Path.GetExtension(tifFullName), ""); // nativeName 参数必须是tiff文件名称 var createTiffCoveragesXml = @$" true {layerName} {layerName} EPSG:4548REPROJECT_TO_DECLARED "; var createTiffCoveragesContent = new StringContent(createTiffCoveragesXml, Encoding.UTF8, "text/xml"); var createTiffCoveragesResponse = await client.PostAsync(createTiffCoveragesUrl, createTiffCoveragesContent); if (createTiffCoveragesResponse.StatusCode != HttpStatusCode.Created) { var msg = await createTiffCoveragesResponse.Content.ReadAsStringAsync(); Console.Write(createTiffCoveragesResponse.StatusCode + " "); Console.WriteLine(msg); return new Response { Result = false, Message = "创建仓库失败:" + msg }; } var publishTiffLayerUrl = $"{GeoserverUrl}/rest/layers/{workspace}:{layerName}"; var publishTiffLayerXml = "true"; var publishTiffLayerContent = new StringContent(publishTiffLayerXml, Encoding.UTF8, "text/xml"); var publishTiffLayerResponse = await client.PutAsync(publishTiffLayerUrl, publishTiffLayerContent); if (publishTiffLayerResponse.StatusCode != HttpStatusCode.OK) { var msg = await publishTiffLayerResponse.Content.ReadAsStringAsync(); Console.Write(publishTiffLayerResponse.StatusCode + " "); Console.WriteLine(msg); return new Response { Result = false, Message = "发布图层失败:" + msg }; } return new Response { Result = true }; } public static async Task GetTiffLayerInfo1(string workspace, string storeName, string layerName) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; } var dbStoreExUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}/coverages/{layerName}.json"; var dbStoreExResult = await client.GetAsync(dbStoreExUrl); if (dbStoreExResult.StatusCode == HttpStatusCode.OK) { var resultObj = JsonConvert.DeserializeObject(dbStoreExResult.Content.ReadAsStringAsync().Result); return JsonConvert.SerializeObject(resultObj); } return "执行失败"; } /// /// 查询图层组是否存在 /// /// 工作空间名称 /// 图层组名称 /// 图层组是否存在 public static async Task ExistLayerGroup(string workspace, string layerGroupName) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; // 如果没有指定工作空间,默认使用 "default" } var existLayerGroupUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/layergroups/{layerGroupName}.json"; var response = await client.GetAsync(existLayerGroupUrl); return response.StatusCode == HttpStatusCode.OK; } /// /// 向图层组中添加图层 /// /// 工作空间名称 /// 图层组名称 /// 要添加的图层名称列表 /// 操作是否成功 public static async Task AddLayersToLayerGroup(string workspace, string layerGroupName, List layerNames) { using var client = new HttpClient(); var usernamePassword = Username + ":" + Password; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword))); if (string.IsNullOrEmpty(workspace)) { workspace = Workspace; // 如果没有指定工作空间 } var addLayersUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/layergroups/{layerGroupName}.xml"; var groupResponse = client.GetAsync(addLayersUrl).Result.Content.ReadAsStringAsync(); var existingLayers = XDocument.Parse(groupResponse.Result).Descendants("publishables").Descendants("published") .Descendants("name").Select(l => l.Value).ToList(); var layersXml = string.Join("", layerNames.Select(layerName => $"{workspace}:{layerName}") .Union(existingLayers.Select(x => $"{x}")).Distinct()); layerNames.AddRange(existingLayers); //var stylesXml = string.Join("", layerNames.Select(layerName => "")); // todo 发布图层组 var url = $"{GeoserverUrl}/rest/workspaces/{workspace}/layergroups"; var xml = "" + "" + " " + layerGroupName + "" + " " + layerGroupName + "" + " " + " " + workspace + "" + " " + " " + layersXml + " " + ""; var content = new StringContent(xml, Encoding.UTF8, "text/xml"); var result = await client.PostAsync(url, content); return result.IsSuccessStatusCode; ; /*const string fixedBbox = "117.34046403513817,34.331716698906675,119.27763051149853,36.263686454243626"; var requestBody = $@" {layerGroupName} {workspace} {layerGroupName} {layersXml} {fixedBbox.Split(',')[0]} {fixedBbox.Split(',')[1]} {fixedBbox.Split(',')[2]} {fixedBbox.Split(',')[3]} EPSG:4326 {stylesXml} "; var content = new StringContent(requestBody, Encoding.UTF8, "text/xml"); // 发送 PUT 请求 var response = await client.PutAsync(addLayersUrl, content); // 检查响应状态码 return response.IsSuccessStatusCode;*/ } public static dynamic GetTifCrs(string filePath) { GdalConfiguration.ConfigureGdal(); GdalConfiguration.ConfigureOgr(); //矢量 GdalConfiguration.ConfigureOgr(); // 初始化 GDAL Gdal.AllRegister(); // 打开 TIFF 文件 //string filePath = "C:/ChengGuoFinal/tiff/无人机巡飞影像数据/20240713/兰山区/20240713兰山区马厂湖_0.2.tif.aux_更新.tif"; Dataset dataset = Gdal.Open(filePath, Access.GA_ReadOnly); if (dataset == null) { Console.WriteLine("无法打开 TIFF 文件"); throw new Exception("无法打开 TIFF 文件"); } // 获取投影信息 string projection = dataset.GetProjection(); var x = dataset.GetProjectionRef(); if (!string.IsNullOrEmpty(projection)) { Console.WriteLine("投影信息:"); Console.WriteLine(projection); } else { Console.WriteLine("无法获取投影信息"); } // 获取空间参照信息 SpatialReference srs = dataset.GetSpatialRef(); Console.WriteLine("空间参照信息:"); // 解析EPSG代码 // 如果没有EPSG代码,可以尝试其他方法获取 var epsgCode = srs.GetAuthorityCode(null); Console.WriteLine($"EPSG代码: {epsgCode}"); // 关闭数据集 dataset.Dispose(); dynamic obj = new System.Dynamic.ExpandoObject(); obj.projection = projection; obj.srs = epsgCode; return obj; } }