1173 lines
47 KiB
C#
1173 lines
47 KiB
C#
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|