2026-02-03 16:00:02 +08:00
using Newtonsoft.Json ;
using Newtonsoft.Json.Linq ;
using OpenAuth.App.Request ;
using OpenAuth.App.Response ;
using SqlSugar ;
using System ;
using System.Collections.Generic ;
using System.Data ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
namespace OpenAuth.App.BasicQueryService
{
public class CommonDataManager
{
ISqlSugarClient client ;
public CommonDataManager ( ISqlSugarClient client )
{
this . client = client ;
}
/// <summary>
/// wkt转geom数据
/// </summary>
/// <param name="wkt"></param>
/// <param name="wkid"></param>
/// <returns></returns>
public string WktToGeometry ( string wkt , int wkid )
{
StringBuilder geomsql = new StringBuilder ( ) ;
geomsql . AppendFormat ( " SELECT CAST(st_geomfromtext('{0}',{1}) AS text) geom" , wkt , wkid ) ;
var model_geom = client . SqlQueryable < dynamic > ( geomsql . ToString ( ) ) . First ( ) ;
return model_geom . geom ;
}
/// <summary>
/// Pgsql获取GeoJson数据
/// </summary>
/// <param name="req"></param>
/// <param name="_configuration"></param>
/// <returns></returns>
public JToken PgsqlGeoJsonCommon ( QueryGeoJsonCommonReq req )
{
//如果有的参数为空,设置参数的默认值
req . init ( ) ;
//查询列的数据
StringBuilder sqlColumn = new StringBuilder ( ) ;
sqlColumn . AppendFormat ( " select {1} from {0} {3} order by \"{2}\"" , req . tablename , req . column , req . order ,
req . where ) ;
StringBuilder sqlGeo = new StringBuilder ( ) ;
sqlGeo . AppendFormat ( " select st_asgeojson(\"{0}\") geom from \"{1}\" {3} order by \"{2}\"" , req . geom ,
req . tablename , req . order , req . where ) ;
return PgsqlGeoJsonCommon ( sqlColumn , sqlGeo , req . pageIndex , req . limit ) ;
}
/// <summary>
/// 查询GeoJson公共方法
/// </summary>
/// <param name="sqlColumn"></param>
/// <param name="sqlGeom"></param>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="_configuration"></param>
/// <returns></returns>
public JToken PgsqlGeoJsonCommon ( StringBuilder sqlColumn , StringBuilder sqlGeom , int pageIndex , int pageSize )
{
//获取到数据库操作实例
int total = 0 ;
int totalPage = 0 ;
//查询列
var dt_properties = client . SqlQueryable < dynamic > ( sqlColumn . ToString ( ) )
. ToPageList ( pageIndex , pageSize , ref total , ref totalPage ) ;
//列数据转换为字符串
string str_properties = JsonConvert . SerializeObject ( dt_properties ) ;
//列数据转换为json对象
JToken jtoken_properties = ( JToken ) JsonConvert . DeserializeObject ( str_properties ) ;
//查询geojson数据
var dt_geom = client . SqlQueryable < dynamic > ( sqlGeom . ToString ( ) ) . ToDataTablePage ( pageIndex , pageSize ) ;
//组装最终数据
JObject obj = new JObject ( ) ;
JArray array = new JArray ( ) ;
obj . Add ( "type" , "FeatureCollection" ) ;
obj . Add ( "totalNumber" , total ) ;
obj . Add ( "totalPage" , totalPage ) ;
//遍历geojson数据
for ( var i = 0 ; i < dt_geom . Rows . Count ; i + + )
{
//行数据
DataRow item = dt_geom . Rows [ i ] ;
//单条geojson
string _geom = item [ "geom" ] = = DBNull . Value ? "" : item [ "geom" ] . ToString ( ) ;
//给数据赋值
JObject featureObj = new JObject ( ) ;
featureObj . Add ( "type" , "Feature" ) ;
featureObj . Add ( "geometry" , ( JToken ) JsonConvert . DeserializeObject ( _geom ) ) ;
featureObj . Add ( "properties" , jtoken_properties [ i ] ) ;
//添加到数组
array . Add ( featureObj ) ;
}
obj . Add ( "features" , array ) ;
return obj ;
}
/// <summary>
/// 获取列名
/// </summary>
/// <param name="tablename"></param>
/// <returns></returns>
public List < dynamic > SearchColumnsList ( string tablename )
{
//查询列名和注释描述
StringBuilder columnSql = new StringBuilder ( ) ;
columnSql . AppendFormat (
@ $ " SELECT a.attname column_name,col_description(a.attrelid,a.attnum) as description,format_type(a.atttypid,a.atttypmod) as column_type
FROM pg_class as c , pg_attribute as a
where c . relname = ' { tablename } '
and a . attrelid = c . oid
and a . attnum > 0
and attstattarget = - 1 ");
//查询结果
var column_list = client . SqlQueryable < dynamic > ( columnSql . ToString ( ) ) . ToList ( ) ;
return column_list ;
}
2026-02-10 14:14:30 +08:00
///// <summary>
///// 矢量切片公共方法
///// </summary>
///// <param name="req"></param>
///// <param name="_configuration"></param>
///// <returns></returns>
//public byte[] VectorTile(VectorTileSearchModel req)
//{
// req.Init();
// List<double> lons = getLon(req.x, req.z);
// List<double> lats = getLat(req.y, req.z);
// double lonmin = lons[0];
// double lonmax = lons[1];
// double latmin = lats[1];
// double latmax = lats[0];
// StringBuilder sql = new StringBuilder();
// sql.AppendFormat(
// $" SELECT ST_AsMVT(tile, '{req.source_layer}', 4096, 'geom') tile FROM (SELECT {req.field}ST_AsMVTGeom(geom, ST_Transform(ST_MakeEnvelope({lonmin},{latmin},{lonmax},{latmax}, 4326),4326),4096, 256, true) AS geom FROM public.{req.table} where {req.filter} ) AS tile");
// var dataTable = client.Ado.GetDataTable(sql.ToString());
// byte[] result = (Byte[])dataTable.Rows[0]["tile"];
// client.Ado.Close();
// client.Dispose();
// return result;
//}
2026-02-03 16:00:02 +08:00
public async Task < byte [ ] > VectorTileAsync ( VectorTileSearchModel req )
{
req . Init ( ) ;
List < double > lons = getLon ( req . x , req . z ) ;
List < double > lats = getLat ( req . y , req . z ) ;
double lonmin = lons [ 0 ] ;
double lonmax = lons [ 1 ] ;
double latmin = lats [ 1 ] ;
double latmax = lats [ 0 ] ;
StringBuilder sql = new StringBuilder ( ) ;
sql . AppendFormat (
$" SELECT ST_AsMVT(tile, '{req.source_layer}', 4096, 'geom') tile FROM (SELECT {req.field}ST_AsMVTGeom(geom, ST_Transform(ST_MakeEnvelope({lonmin},{latmin},{lonmax},{latmax}, 4326),4326),4096, 256, true) AS geom FROM public.{req.table} where {req.filter} ) AS tile" ) ;
var dataTable = await client . Ado . GetDataTableAsync ( sql . ToString ( ) ) ;
byte [ ] result = ( Byte [ ] ) dataTable . Rows [ 0 ] [ "tile" ] ;
client . Ado . Close ( ) ;
client . Dispose ( ) ;
return result ;
}
/// <summary>
/// 查询最新的主键
/// </summary>
/// <param name="_columm"></param>
/// <param name="tablename"></param>
/// <param name="_gid_const"></param>
/// <returns></returns>
public string GetMaxKeyVal ( string _column , string tablename , int _gid_const )
{
string _val = "" ;
//查询最大的gid
var column_list = SearchColumnsList ( tablename ) ;
string _type = column_list [ 0 ] . column_type ;
if ( _type ! = "integer" )
{
_val = Guid . NewGuid ( ) . ToString ( ) ;
return _val ;
}
var _maxgid = client
. SqlQueryable < dynamic > (
$"SELECT max(\" { _column } \ ") \"maxGid\" FROM \"{tablename}\" where \"{_column}\" < 6000000" ) . First ( )
. maxGid ;
//gid为空时, 说明一条数据都没有
if ( _maxgid = = null )
_val = _gid_const . ToString ( ) ;
else
{
//如果大于设定值,在此基础上加一,否则设置为默认值
if ( _maxgid > = _gid_const )
_val = ( _maxgid + 1 ) . ToString ( ) ;
else
_val = _gid_const . ToString ( ) ;
}
return _val ;
}
/// <summary>
/// 格式化wkt数据, 兼容多个地块
/// </summary>
/// <param name="_wkt"></param>
/// <param name="_newType"></param>
/// <param name="_len"></param>
/// <returns></returns>
public string WktDataConvert ( string _wkt , string _newType , int _len )
{
//使用逗号分割
var list = _wkt . Split ( "," ) ;
//返回值
StringBuilder res = new StringBuilder ( ) ;
//扩展的维度,用 0补齐
string extStr = "" ;
for ( int i = 0 ; i < list . Length ; i + + )
{
//当前项
var item = list [ i ] ;
extStr = GetWktDemension ( item , _len ) ;
if ( i = = 0 )
{
//第一项数据先去除前缀
item = item . Substring ( item . IndexOf ( "(" ) ) . TrimStart ( '(' ) ;
if ( _newType = = "MULTIPOLYGON ZM" )
item = "(((" + item ;
else if ( _newType = = "MULTILINESTRING" )
item = "((" + item ;
//扩展后的值
item = _newType + item + extStr ;
}
else if ( i = = list . Length - 1 )
{
//最后一项
item = item . TrimEnd ( ')' ) ;
if ( _newType = = "MULTIPOLYGON ZM" )
item = item + extStr + ")))" ;
else if ( _newType = = "MULTILINESTRING" )
item = item + extStr + "))" ;
}
else
{
//判断是否存在右括号
if ( item . IndexOf ( ")" ) > - 1 )
{
//在第一个右括号前插入维度数据
item = item . Insert ( item . IndexOf ( ")" ) , extStr ) ;
}
else
{
//在后面追加维度数据
item = item + extStr ;
}
}
//追加数据
res . Append ( $"{item}," ) ;
}
string strRes = res . ToString ( ) ;
//把最后一个逗号截取掉
return strRes . Substring ( 0 , strRes . Length - 1 ) ;
}
private string GetWktDemension ( string item , int _len )
{
if ( item . IndexOf ( "(" ) > - 1 )
{
item = item . Substring ( item . IndexOf ( "(" ) ) ;
item = item . TrimStart ( '(' ) ;
}
string extStr = "" ;
//数据的维度
var _count = _len - item . Split ( " " , StringSplitOptions . RemoveEmptyEntries ) . Length ;
//扩展维度
if ( _count = = 1 )
extStr = " 0" ;
else if ( _count = = 2 )
extStr = " 0 0" ;
return extStr ;
}
#region Util
/// <summary>
/// 瓦片转经度
/// </summary>
/// <param name="x">列号</param>
/// <param name="z">缩放级别</param>
/// <returns></returns>
public static double tile2lon ( int x , int z )
{
return x / Math . Pow ( 2.0 , z ) * 360.0 - 180 ;
}
/// <summary>
/// 瓦片转纬度
/// </summary>
/// <param name="y">行号</param>
/// <param name="z">缩放级别</param>
/// <returns></returns>
public static double tile2lat ( int y , int z )
{
double n = Math . PI - ( 2.0 * Math . PI * y ) / Math . Pow ( 2.0 , z ) ;
return Math . Atan ( Math . Sinh ( n ) ) * 180 / Math . PI ;
}
/// <summary>
/// 获取经度最大值和经度最小值
/// </summary>
/// <param name="x">列号</param>
/// <param name="z">缩放级别</param>
/// <returns></returns>
public static List < double > getLon ( int x , int z )
{
List < double > lonExtent = new List < double > ( ) ;
lonExtent . Add ( tile2lon ( x , z ) ) ;
lonExtent . Add ( tile2lon ( x + 1 , z ) ) ;
return lonExtent ;
}
/// <summary>
/// 获取纬度最大值和经度最小值
/// </summary>
/// <param name="y">列号</param>
/// <param name="z">缩放级别</param>
/// <returns></returns>
public static List < double > getLat ( int y , int z )
{
List < double > latExtent = new List < double > ( ) ;
latExtent . Add ( tile2lat ( y , z ) ) ;
latExtent . Add ( tile2lat ( y + 1 , z ) ) ;
return latExtent ;
}
# endregion
public byte [ ] VectorTile1 ( VectorTileSearchModel req )
{
req . Init ( ) ;
List < double > lons = getLon ( req . x , req . z ) ;
List < double > lats = getLat ( req . y , req . z ) ;
double lonmin = lons [ 0 ] ;
double lonmax = lons [ 1 ] ;
double latmin = lats [ 1 ] ;
double latmax = lats [ 0 ] ;
StringBuilder sql = new StringBuilder ( ) ;
sql . AppendFormat (
$" SELECT ST_AsMVT(tile, '{req.source_layer}', 4096, 'geom') tile FROM (SELECT {req.field}ST_AsMVTGeom(geometry, ST_Transform(ST_MakeEnvelope({lonmin},{latmin},{lonmax},{latmax}, 4326),4326),4096, 256, true) AS geom FROM public.{req.table} where {req.filter} ) AS tile" ) ;
var dataTable = client . Ado . GetDataTable ( sql . ToString ( ) ) ;
byte [ ] result = ( Byte [ ] ) dataTable . Rows [ 0 ] [ "tile" ] ;
client . Ado . Close ( ) ;
client . Dispose ( ) ;
return result ;
}
2026-02-10 14:14:30 +08:00
/// <summary>
/// 矢量切片公共方法
/// </summary>
/// <param name="req"></param>
/// <param name="_configuration"></param>
/// <returns></returns>
public byte [ ] VectorTile ( VectorTileSearchModel req )
{
req . Init ( ) ;
List < double > lons = getLon ( req . x , req . z ) ;
List < double > lats = getLat ( req . y , req . z ) ;
double lonmin = lons [ 0 ] ;
double lonmax = lons [ 1 ] ;
double latmin = lats [ 1 ] ;
double latmax = lats [ 0 ] ;
StringBuilder sql = new StringBuilder ( ) ;
sql . AppendFormat (
$" SELECT ST_AsMVT(tile, '{req.source_layer}', 4096, 'geom') tile FROM (SELECT {req.field}ST_AsMVTGeom(geom, ST_Transform(ST_MakeEnvelope({lonmin},{latmin},{lonmax},{latmax}, 4326),4326),4096, 256, true) AS geom FROM public.{req.table} where {req.filter} ) AS tile" ) ;
var dataTable = client . Ado . GetDataTable ( sql . ToString ( ) ) ;
byte [ ] result = ( Byte [ ] ) dataTable . Rows [ 0 ] [ "tile" ] ;
return result ;
}
2026-02-03 16:00:02 +08:00
}
}