feixian_weifajianguan/OpenAuth.App/ServiceApp/ShpGeo/Utils/GeoUtil.cs

1173 lines
47 KiB
C#
Raw Permalink Normal View History

2026-02-03 16:00:02 +08:00
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;
/// <summary>
/// 创建数据存储和图层,样式存在的话,绑定样式
/// </summary>
/// <param name="srs"></param>
/// <param name="layerName"></param>
/// <param name="styleName"></param>
public static async Task<bool> 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 = "<dataStore>" +
"<name>" + DbStoreName + "</name>" +
"<type>PostGIS</type>" +
"<enabled>true</enabled>" +
"<connectionParameters>" +
"<host>" + dbElement["HOST"] + "</host>" +
"<port>" + dbElement["PORT"] + "</port>" +
"<schema>" + DbSchema + "</schema>" +
"<database>" + dbElement["Database"] + "</database>" +
"<user>" + dbElement["USER ID"] + "</user>" +
"<passwd>" + dbElement["PASSWORD"] + "</passwd>" +
"<dbtype>postgis</dbtype>" +
//"<table>" + layerName + "</table>" +
"</connectionParameters>" +
"</dataStore>";
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 = "<featureType>" +
"<enabled>true</enabled>" +
"<metadata />" +
"<keywords />" +
"<metadataLinks />" +
"<attributes />" +
"<title>" + layerName + "</title>" +
"<name>" + layerName + "</name>" +
"<srs>" + srs + "</srs>" +
"<description>" + layerName + "</description>" +
"</featureType>";
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 = "<defaultStyle>" +
"<name>" + styleName + "</name>" +
"<workspace>" + workspace + "</workspace>" +
"</defaultStyle>";
}
var publishContentStr =
"<layer>" +
"<enabled>true</enabled>" +
"<styles />" +
"<authorityURLs />" +
"<identifiers />" +
styleXmlPart +
"</layer>";
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;
}
/// <summary>
/// 判断样式是否存在
/// </summary>
/// <param name="styleName"></param>
/// <returns></returns>
public static async Task<bool> 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;
}
/// <summary>
/// 创建SLD样式并发布
/// </summary>
/// <param name="sldPath"></param>
/// <returns></returns>
public static async Task<bool> 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 "<style><name>roads_style</name><filename>roads.sld</filename></style>" http://localhost:8080/geoserver/rest/styles
var prePublicSld = GeoserverUrl + "/rest/workspaces/" + Workspace + "/styles";
// "<style><name>roads_style</name><filename>roads.sld</filename></style>"
var prePublishSldXml = "<style><name>" + styleName + "</name><filename>" + sldFileName + "</filename></style>";
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><name>$WORKSPACE</name></workspace>" $GEOSERVER_URL/rest/workspaces
/// <summary>
/// 解析数据库连接字符串
/// </summary>
/// <param name="connectionString"></param>
/// <returns></returns>
static Dictionary<string, string> ParseConnectionString(string connectionString)
{
var details = new Dictionary<string, string>();
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;
}
/// <summary>
/// 获取图层bbox
/// </summary>
/// <param name="workspace"></param>
/// <param name="storeName"></param>
/// <param name="layerName"></param>
/// <returns></returns>
public static async Task<Response<string>> 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<JObject>(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<string>
{
Result = minx + "," + miny + "," + maxx + "," + maxy,
Code = 200
};
}
return new Response<string>
{
Code = 500
};
}
/// <summary>
/// 取得bbox 及 srs 信息
/// </summary>
/// <param name="workspace">工作空间名称</param>
/// <param name="storeName">存储仓库名称</param>
/// <param name="layerName">图层名称</param>
/// <returns></returns>
public static async Task<Response<dynamic>> 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<JObject>(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<dynamic>
{
Result = new { bbox = minx + "," + miny + "," + maxx + "," + maxy, srs = srs },
Code = 200
};
}
return new Response<dynamic>
{
Code = 500,
Message = dbStoreExResult.Content.ReadAsStringAsync().Result
};
}
/// <summary>
/// 删除栅格仓库
/// </summary>
/// <param name="workspace"></param>
/// <param name="storeName"></param>
/// <param name="recurse">递归删除true 仓库下所有资源都将被删除)</param>
/// <returns></returns>
public static async Task<Response<bool>> 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<bool>
{
Result = true,
Code = 200
};
case HttpStatusCode.NotFound:
return new Response<bool>
{
Result = false,
Code = 404
};
default:
return new Response<bool>
{
Result = false,
Code = 500,
Message = deleteTiffStoreResult.Content.ReadAsStringAsync().Result
};
}
}
/// <summary>
/// 删除图层
/// </summary>
/// <param name="workspace">工作空间,可不填</param>
/// <param name="layerName"></param>
/// <returns></returns>
public static async Task<Response<bool>> 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<bool>
{
Result = true,
Code = 200
};
}
return new Response<bool>
{
Result = false,
Code = 500
};
}
/// <summary>
/// 发布GeoTiff
/// </summary>
/// <param name="workspace"></param>
/// <param name="tifFullName">tif文件全路径</param>
/// <param name="storeName">栅格仓库名称</param>
/// <param name="layerName">图层名称</param>
/// <returns></returns>
public static async Task<Response<bool>> 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<bool>
{
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 = $"<coverageStore>" +
$"<name>{storeName}</name><workspace>{workspace}</workspace>" +
"<enabled>true</enabled>" +
"<type>GeoTIFF</type>" +
$"<url>file://{tifFullName}</url>" +
"</coverageStore>";
//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<bool>
{
Result = false,
Message = "创建仓库失败:" + msg
};
}
// 创建coverages
var createTiffCoveragesUrl = $"{GeoserverUrl}/rest/workspaces/{workspace}/coveragestores/{storeName}/coverages";
var tiffFileName = Path.GetFileNameWithoutExtension(tifFullName);
// nativeName 参数必须是tiff文件名称
var createTiffCoveragesXml = @$"<coverage>
<nativeName>{storeName}</nativeName>
<nativeCoverageName>{tiffFileName}</nativeCoverageName>
<enabled>true</enabled>
<metadata />
<keywords />
<metadataLinks />
<name>{layerName}</name>
<title>{layerName}</title>
<srs>EPSG:{srs}</srs><projectionPolicy>REPROJECT_TO_DECLARED</projectionPolicy>
<parameters>
<entry>
<string>InputTransparentColor</string>
<string>#000000</string>
</entry>
</parameters>
</coverage>";
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<bool>
{
Result = false,
Message = "创建仓库失败:" + msg
};
}
var publishTiffLayerUrl =
$"{GeoserverUrl}/rest/layers/{workspace}:{layerName}";
var publishTiffLayerXml = "<layer><enabled>true</enabled></layer>";
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<bool>
{
Result = false,
Message = "发布图层失败:" + msg
};
}
return new Response<bool>
{
Result = true
};
}
/// <summary>
/// 判断工作空间是否存在
/// </summary>
/// <param name="workspace"></param>
/// <returns></returns>
public static async Task<Response<bool>> 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<bool>
{
Result = false
};
}
return new Response<bool>
{
Result = true
};
}
/// <summary>
/// 创建工作空间
/// </summary>
/// <param name="workspace"></param>
/// <returns></returns>
public static async Task<Response<bool>> 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><name>{workspace}</name></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<bool>
{
Result = true
};
}
return new Response<bool>
{
Result = false
};
}
/// <summary>
/// 删除工作空间
/// </summary>
/// <param name="workspace"></param>
/// <returns></returns>
public static async Task<Response<bool>> 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<bool>
{
Result = true,
Code = 200
};
}
return new Response<bool>
{
Result = false,
Code = 500
};
}
public static async Task<Response<bool>> 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("<mimeFormats>");
var xml = split[0] + "<mimeFormats>" +
"<string>application/json;type=geojson</string>" +
"<string>application/json;type=topojson</string>" +
"<string>application/vnd.mapbox-vector-tile</string>" +
"<string>application/json;type=utfgrid</string>" +
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<bool>()
{
Result = true,
Code = 200
};
}
}
return new Response<bool>
{
Result = false,
Code = 500
};
}
/// <summary>
/// 更新样式名,更新样式
/// </summary>
/// <param name="sldPath"></param>
/// <param name="styleName"></param>
/// <returns></returns>
public static async Task<bool> 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<Response<bool>> 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 = $"<layer><defaultStyle><name>{styleName}</name></defaultStyle></layer>";
var xml = $@"
<layer>
<defaultStyle>
<name>{styleName}</name>
</defaultStyle>
</layer>";
var content = new StringContent(xml, Encoding.UTF8,
"application/xml");
var result = await client.PutAsync(url, content);
if (result.StatusCode == HttpStatusCode.OK)
{
return new Response<bool>
{
Result = true,
};
}
return new Response<bool>
{
Result = false,
Code = 500
};
}
public static async Task<Response<bool>> 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 = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<layerGroup>" +
" <name>" + layerGroupName + "</name>" +
" <title>" + layerGroupName + "</title>" +
" <workspace>" +
" <name>" + workspace + "</name>" +
" </workspace>" +
" <layers>" +
layers +
" </layers>" +
"</layerGroup>";
var content = new StringContent(xml, Encoding.UTF8,
"text/xml");
var result = await client.PostAsync(url, content);
if (result.StatusCode == HttpStatusCode.OK)
{
return new Response<bool>
{
Result = true,
};
}
return new Response<bool>
{
Result = false,
Code = 500
};
}
/// <summary>
/// 发布GeoTiff
/// </summary>
/// <param name="workspace"></param>
/// <param name="tifFullName">tif文件全路径</param>
/// <param name="storeName">栅格仓库名称</param>
/// <param name="layerName">图层名称</param>
/// <returns></returns>
public static async Task<Response<bool>> PublishSingleGeoTIFF(string workspace, string tifFullName,
string storeName, string layerName)
{
if (string.IsNullOrEmpty(tifFullName) || string.IsNullOrEmpty(storeName) || string.IsNullOrEmpty(layerName))
{
return new Response<bool>
{
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 = $"<coverageStore>" +
$"<name>{storeName}</name><workspace>{workspace}</workspace>" +
"<enabled>true</enabled>" +
"<type>GeoTIFF</type>" +
$"<url>file://{tifFullName}</url>" +
"</coverageStore>";
//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<bool>
{
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 = @$"<coverage>
<enabled>true</enabled>
<metadata />
<keywords />
<metadataLinks />
<name>{layerName}</name>
<title>{layerName}</title>
<srs>EPSG:4548</srs><projectionPolicy>REPROJECT_TO_DECLARED</projectionPolicy>
</coverage>";
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<bool>
{
Result = false,
Message = "创建仓库失败:" + msg
};
}
var publishTiffLayerUrl =
$"{GeoserverUrl}/rest/layers/{workspace}:{layerName}";
var publishTiffLayerXml = "<layer><enabled>true</enabled></layer>";
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<bool>
{
Result = false,
Message = "发布图层失败:" + msg
};
}
return new Response<bool>
{
Result = true
};
}
public static async Task<string> 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<JObject>(dbStoreExResult.Content.ReadAsStringAsync().Result);
return JsonConvert.SerializeObject(resultObj);
}
return "执行失败";
}
/// <summary>
/// 查询图层组是否存在
/// </summary>
/// <param name="workspace">工作空间名称</param>
/// <param name="layerGroupName">图层组名称</param>
/// <returns>图层组是否存在</returns>
public static async Task<bool> 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;
}
/// <summary>
/// 向图层组中添加图层
/// </summary>
/// <param name="workspace">工作空间名称</param>
/// <param name="layerGroupName">图层组名称</param>
/// <param name="layerNames">要添加的图层名称列表</param>
/// <returns>操作是否成功</returns>
public static async Task<bool> AddLayersToLayerGroup(string workspace, string layerGroupName,
List<string> 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 => $"<layer>{workspace}:{layerName}</layer>")
.Union(existingLayers.Select(x => $"<layer>{x}</layer>")).Distinct());
layerNames.AddRange(existingLayers);
//var stylesXml = string.Join("", layerNames.Select(layerName => "<style><name>default</name></style>"));
// todo 发布图层组
var url = $"{GeoserverUrl}/rest/workspaces/{workspace}/layergroups";
var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<layerGroup>" +
" <name>" + layerGroupName + "</name>" +
" <title>" + layerGroupName + "</title>" +
" <workspace>" +
" <name>" + workspace + "</name>" +
" </workspace>" +
" <layers>" +
layersXml +
" </layers>" +
"</layerGroup>";
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 = $@"
<layerGroup>
<name>{layerGroupName}</name>
<workspace>
<name>{workspace}</name>
</workspace>
<title>{layerGroupName}</title>
<layers>
{layersXml}
</layers>
<bounds>
<minx>{fixedBbox.Split(',')[0]}</minx>
<miny>{fixedBbox.Split(',')[1]}</miny>
<maxx>{fixedBbox.Split(',')[2]}</maxx>
<maxy>{fixedBbox.Split(',')[3]}</maxy>
<crs>EPSG:4326</crs>
</bounds>
<styles>
{stylesXml}
</styles>
</layerGroup>";
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;
}
}