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

1173 lines
47 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
}