提交 32e7e6d4328e2f06a496a884ca10c22f9e13b602

作者 qianyingz
2 个父辈 a223c79e 6fdf6a52
... ... @@ -4,6 +4,7 @@
4 4 #email: nheweijun@sina.com
5 5 import datetime
6 6 from ..models import Database,db,Table,Columns,TableVacuate,DES
  7 +from app.models import AESHelper
7 8
8 9 import uuid
9 10 from . import database_test
... ... @@ -30,8 +31,10 @@ class Api(ApiTemplate):
30 31 passwd = self.para.get("passwd")
31 32 database = self.para.get("database")
32 33 encryption = int(self.para.get("encryption","0"))
33   - if encryption:
34   - passwd = DES.decode(passwd)
  34 + if encryption == 1:
  35 + # passwd = DES.decode(passwd)
  36 + passwd = AESHelper.decode(passwd)
  37 +
35 38
36 39 sqlalchemy_uri = "postgresql://{}:{}@{}:{}/{}".format(user,passwd,host,port,database)
37 40 connectsrt = "hostaddr={} port={} dbname='{}' user='{}' password='{}'".format(host,port,database,user,passwd)
... ... @@ -309,6 +312,9 @@ class Api(ApiTemplate):
309 312 {"name": "alias",
310 313 "in": "formData",
311 314 "type": "string","description":"数据库别名","required": "true"},
  315 + {"name": "encryption",
  316 + "in": "formData",
  317 + "type": "int", "description": "密码是否加密", "enum": [0, 1]}
312 318 ],
313 319 "responses":{
314 320 200:{
... ...
... ... @@ -7,7 +7,7 @@ from contextlib import closing
7 7 from sqlalchemy import create_engine
8 8
9 9 from ..models import Database,db,DES
10   -
  10 +from app.models import AESHelper
11 11
12 12 from sqlalchemy.orm import sessionmaker
13 13 from app.util.component.ApiTemplate import ApiTemplate
... ... @@ -26,8 +26,9 @@ class Api(ApiTemplate):
26 26 database = self.para.get("database")
27 27
28 28 encryption = int(self.para.get("encryption", "0"))
29   - if encryption:
30   - passwd = DES.decode(passwd)
  29 + if encryption == 1:
  30 + #passwd = DES.decode(passwd)
  31 + passwd = AESHelper.decode(passwd)
31 32
32 33 sqlalchemy_uri = "postgresql://{}:{}@{}:{}/{}".format(user,passwd,host,port,database)
33 34
... ...
... ... @@ -92,7 +92,7 @@ class Api(ApiTemplate):
92 92 if data_path.endswith("shp"):
93 93 info["type"]="shp"
94 94 driver: Driver = ogr.GetDriverByName("ESRI Shapefile")
95   - ds: DataSource = driver.Open(data_path, 1)
  95 + ds: DataSource = driver.Open(data_path, 0)
96 96 if not ds:
97 97 raise Exception("打开数据失败!")
98 98 layer: Layer = ds.GetLayer(0)
... ... @@ -112,8 +112,7 @@ class Api(ApiTemplate):
112 112 layer_name[layer.GetName()] = layer.GetName()
113 113
114 114 except Exception as e :
115   - print(traceback.format_exc())
116   - info={}
  115 + raise e
117 116 finally:
118 117 if ds:
119 118 ds.Destroy()
... ...
... ... @@ -120,7 +120,7 @@ class EntryDataVacuate:
120 120 '''
121 121
122 122 driver: Driver = ogr.GetDriverByName("ESRI Shapefile")
123   - ds: DataSource = driver.Open(data_path, 1)
  123 + ds: DataSource = driver.Open(data_path, 0)
124 124 if not ds:
125 125 raise Exception("打开数据失败!")
126 126 layer: Layer = ds.GetLayer(0)
... ...
... ... @@ -80,7 +80,7 @@ class Api(ApiTemplate):
80 80 rename_sql = 'alter table "{}" rename to "{}"'.format(this_table.name,name)
81 81 sys_session.execute(rename_sql)
82 82 sys_session.commit()
83   - print(rename_sql)
  83 +
84 84 # 更新所有相关业务表
85 85 same_databases = Database.query.filter_by(sqlalchemy_uri=this_table.relate_database.sqlalchemy_uri).all()
86 86 same_databases_database_guid = [d.guid for d in same_databases]
... ...
... ... @@ -14,6 +14,7 @@ class Api(ApiTemplate):
14 14 api_name = "表信息"
15 15 def process(self):
16 16 res = {}
  17 + pg_ds = None
17 18 try:
18 19 table_guid = self.para.get("guid")
19 20 table = Table.query.filter_by(guid=table_guid).one_or_none()
... ... @@ -48,6 +49,9 @@ class Api(ApiTemplate):
48 49
49 50 except Exception as e:
50 51 raise e
  52 + finally:
  53 + if pg_ds:
  54 + pg_ds.Destroy()
51 55 return res
52 56
53 57 api_doc={
... ...
... ... @@ -58,10 +58,11 @@ class Api(ApiTemplate):
58 58 if pg_ds:
59 59 pg_ds.Destroy()
60 60
61   - if Task.query.filter_by(table_guid=table_guid,state=0).one_or_none():
  61 + if Task.query.filter_by(table_guid=table_guid,state=0).one_or_none() or table.is_vacuate==2:
62 62 res["result"] = False
63 63 res["msg"] = "矢量金字塔构建中!"
64 64 return res
  65 +
65 66 if table.table_type==0:
66 67 res["result"] = False
67 68 res["msg"] = "非空间表!"
... ...
... ... @@ -64,11 +64,13 @@ class Api(ApiTemplate):
64 64 res["result"] = False
65 65 res["msg"] = "矢量金字塔构建中!"
66 66 return res
67   - if table.table_type==0:
  67 +
  68 + if Task.query.filter_by(table_guid=table_guid,state=0).one_or_none() or table.is_vacuate==2:
68 69 res["result"] = False
69   - res["msg"] = "非空间表!"
  70 + res["msg"] = "矢量金字塔构建中!"
70 71 return res
71 72
  73 +
72 74 # 初始化task
73 75 task_guid = uuid.uuid1().__str__()
74 76
... ...
... ... @@ -6,10 +6,11 @@
6 6 from flasgger import swag_from
7 7 from flask import Blueprint
8 8 from app.util import BlueprintApi
9   -from . import map_service_register, map_service_edit
  9 +from . import map_service_register, map_service_edit, map_service_sample_register
10 10 from app.decorators.token_decorator import token_decorator
11 11 from ..util.ServiceType import ServiceType
12 12
  13 +
13 14 class DataManager(BlueprintApi):
14 15
15 16 bp = Blueprint("MapService", __name__,
... ... @@ -27,6 +28,15 @@ class DataManager(BlueprintApi):
27 28 return map_service_register.Api().result
28 29
29 30 @staticmethod
  31 + @bp.route('/SampleRegister', methods=['POST'])
  32 + @swag_from(map_service_sample_register.Api.api_doc)
  33 + def api_wms_sample_register():
  34 + """
  35 + 注册简单MapService
  36 + """
  37 + return map_service_sample_register.Api().result
  38 +
  39 + @staticmethod
30 40 @bp.route('/Edit', methods=['POST'])
31 41 @swag_from(map_service_edit.Api.api_doc)
32 42 @token_decorator("profile")
... ...
... ... @@ -47,7 +47,8 @@ class Api(ApiTemplate):
47 47 else:
48 48 raise Exception("调用矢量服务的注册服务接口失败!")
49 49 # 并获得服务缩略图
50   -
  50 + if Service.query.filter_by(name = self.para.get("name")).one_or_none():
  51 + raise Exception("同名服务已存在!")
51 52 service = Service(
52 53 guid = service_guid,
53 54 name = self.para.get("name"),
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/9/17
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from app.util.component.ApiTemplate import ApiTemplate
  8 +from app.util.component.PGUtil import PGUtil
  9 +from app.util.component.GeometryAdapter import GeometryAdapter
  10 +import uuid
  11 +from ..models import Service,db,MapService,ServiceFunction
  12 +from app.modules.data.models import Database,Table,DES,Columns
  13 +import datetime
  14 +import configure
  15 +import requests
  16 +import json
  17 +from osgeo.ogr import DataSource,Layer,FeatureDefn,FieldDefn
  18 +import base64
  19 +
  20 +
  21 +class Api(ApiTemplate):
  22 +
  23 + api_name = "注册MapService服务"
  24 +
  25 + def para_check(self):
  26 + if not self.para.get("name"):
  27 + raise Exception("缺乏服务名!")
  28 + if not self.para.get("title"):
  29 + raise Exception("缺乏标题!")
  30 + if not self.para.get("database_guid"):
  31 + raise Exception("缺乏数据库id!")
  32 + if not self.para.get("table_name"):
  33 + raise Exception("缺乏表名!")
  34 +
  35 + def process(self):
  36 + # 返回结果
  37 + res = {}
  38 +
  39 + try:
  40 +
  41 + this_time = datetime.datetime.now()
  42 + service_guid = uuid.uuid1().__str__()
  43 + map_service_guid = uuid.uuid1().__str__()
  44 +
  45 + # 逻辑是,先调用引擎接口,引擎说可以,才做持久化
  46 + project_file = self.create_projectfile(self.para)
  47 + para = {"name":self.para.get("name"),
  48 + "title":self.para.get("title"),
  49 + "type":"mapserver",
  50 + "capabilities":2,
  51 + "project":project_file}
  52 +
  53 +
  54 + map_service_register_url = "{}/dmap/api/manager/regservice".format(configure.dmap_engine)
  55 + resp: requests.Response = requests.post(map_service_register_url,data=json.dumps(para),
  56 + headers={'Content-Type':'application/json'},timeout=3
  57 + )
  58 +
  59 + if resp.status_code == 200:
  60 + resp.encoding="utf-8"
  61 + resp_json = resp.json()
  62 + if not resp_json["status"]=="1":
  63 + raise Exception("调用矢量服务的注册服务接口失败!")
  64 + else:
  65 + raise Exception("调用矢量服务的注册服务接口失败!")
  66 + # 并获得服务缩略图
  67 +
  68 + if Service.query.filter_by(name = self.para.get("name")).one_or_none():
  69 + raise Exception("同名服务已存在!")
  70 +
  71 + service = Service(
  72 + guid = service_guid,
  73 + name = self.para.get("name"),
  74 + title = self.para.get("title"),
  75 + creator=self.para.get("creator"),
  76 + state = 1,
  77 + create_time = this_time,
  78 + update_time = this_time,
  79 + description = self.para.get("description"),
  80 + node = 1 ,
  81 + overview = resp_json["url"],
  82 + type = "矢量地图",
  83 + catalog_guid = self.para.get("catalog_guid")
  84 + )
  85 +
  86 + map_service = MapService(
  87 + guid = map_service_guid,
  88 + name = self.para.get("name"),
  89 + title = self.para.get("title"),
  90 + type = "mapserver",
  91 + capabilities = int(self.para.get("capabilities",2)),
  92 + project = project_file,
  93 + service_guid = service_guid
  94 + )
  95 +
  96 + service_function_wms = ServiceFunction(guid=uuid.uuid1().__str__(),type="WMS",service_guid=service_guid)
  97 + service_function_wfs = ServiceFunction(guid=uuid.uuid1().__str__(),type="WFS",service_guid=service_guid)
  98 +
  99 + db.session.add(service)
  100 + db.session.add(map_service)
  101 + db.session.add(service_function_wms)
  102 + db.session.add(service_function_wfs)
  103 + db.session.commit()
  104 +
  105 + res["data"] = service_guid
  106 + res["result"] = True
  107 + except Exception as e:
  108 + db.session.rollback()
  109 + raise e
  110 + return res
  111 +
  112 +
  113 + def create_projectfile(self,para):
  114 +
  115 + database = Database.query.filter_by(guid=para.get("database_guid")).one_or_none()
  116 + if not database:
  117 + raise Exception("数据库不存在,请先注册数据库!")
  118 + pg_ds: DataSource = PGUtil.open_pg_data_source(0, DES.decode(database.sqlalchemy_uri))
  119 + table = Table.query.filter_by(database_guid=database.guid,name=self.para.get("table_name")).first()
  120 + layer: Layer = pg_ds.GetLayerByName(self.para.get("table_name"))
  121 + #注册数据表
  122 + if not table:
  123 + if not layer:
  124 + raise Exception("图层不存在!")
  125 + table = self.register_table(layer,para)
  126 +
  127 + gemetry_type = ["MULTIPOINT","MULTILINESTRING","MULTIPOLYGON"][table.table_type-1]
  128 +
  129 + geom_column = layer.GetGeometryColumn()
  130 + srid = PGUtil.get_srid(pg_ds,self.para.get("table_name"))
  131 + if not table.table_type in [1,2,3]:
  132 + raise Exception("数据表是非空间表!")
  133 +
  134 + xml_format='''
  135 +<dmap projectname="{name}" version="">
  136 + <projectCrs>
  137 + <spatialrefsys>
  138 + <wkt/>
  139 + <proj4/>
  140 + <srid>0</srid>
  141 + </spatialrefsys>
  142 + </projectCrs>
  143 + <projectlayers>
  144 + <maplayer alias="" alwaysShow="false" featurecount="{feature_count}" geometry="{gemetry_type}" geomfield="{geom_column}" id="{table_guid}" name="{table_name}" schema="public" srid="{srid}" tag="" type="1" visible="true" workspace="">
  145 + <extent>
  146 + <xmin>{xmin}</xmin>
  147 + <ymin>{ymin}</ymin>
  148 + <xmax>{xmax}</xmax>
  149 + <ymax>{ymax}</ymax>
  150 + </extent>
  151 + <datasource>{database_guid}</datasource>
  152 + {renderer}
  153 + </maplayer>
  154 + </projectlayers>
  155 +</dmap>
  156 + '''
  157 + point_renderer='''
  158 + <renderer>
  159 + <GROUPRENDERER>
  160 + <SIMPLERENDERER alwaysShow="false" maxscale="10000000000" minscale="0">
  161 + <SIMPLEMARKERSYMBOL png="" type="circle" color="255,255,255" transparency="1" boundary="true" outline="0,0,0" outlinetransparency="1" width="1.5" size="10.00" />
  162 + </SIMPLERENDERER>
  163 + </GROUPRENDERER>
  164 + </renderer>
  165 + '''
  166 + line_renderer = '''
  167 + <renderer>
  168 + <GROUPRENDERER>
  169 + <SIMPLERENDERER alwaysShow="true" maxscale="10000000000" minscale="0">
  170 + <SIMPLELINESYMBOL type="solid" png="" color="0,0,0" transparency="1.00" width="2.00" captype="cap_butt" jiontype="jion_miter" />
  171 + </SIMPLERENDERER>
  172 + </GROUPRENDERER>
  173 + </renderer>
  174 + '''
  175 +
  176 + polygon_renderer='''
  177 + <renderer>
  178 + <GROUPRENDERER>
  179 + <SIMPLERENDERER alwaysShow="true" maxscale="10000000000" minscale="0">
  180 + <SIMPLEPOLYGONSYMBOL png="" boundary="true" linetype="solid" width="0.5" boundarycolor="0,0,0" boundarytransparency="1.00" needfill="false" filltype="solid" filltransparency="1.00" fillinterval="1" font="" fontname="" fillsize="0" fillcolor="0,0,0" icon="" needbackground="true" diagalignment="true" backgroundcolor="255,255,255" backgroundtransparency="1.00" />
  181 + </SIMPLERENDERER>
  182 + </GROUPRENDERER>
  183 + </renderer>
  184 + '''
  185 +
  186 + renderer = point_renderer
  187 + if table.table_type==2:
  188 + renderer = line_renderer
  189 + if table.table_type==3:
  190 + renderer = polygon_renderer
  191 +
  192 + extent = [float(x) for x in table.extent.split(",")]
  193 +
  194 + xml = xml_format.format(name = para.get("name"),
  195 + xmin = extent[0],
  196 + xmax = extent[1],
  197 + ymin = extent[2],
  198 + ymax = extent[3],
  199 + feature_count = table.feature_count,
  200 + database_guid = table.database_guid,
  201 + gemetry_type = gemetry_type,
  202 + geom_column = geom_column,
  203 + table_guid = table.guid,
  204 + table_name = table.name,
  205 + srid = srid,
  206 + renderer= renderer
  207 + )
  208 +
  209 +
  210 + if pg_ds:
  211 + pg_ds.Destroy()
  212 +
  213 + project_xml = xml.strip()
  214 + print(project_xml)
  215 + return str(base64.b64encode(project_xml.encode('utf-8')), encoding="utf8")
  216 +
  217 + def register_table(self, layer: Layer,para):
  218 + '''
  219 + 注册表
  220 + :param layer: 图层
  221 + :param new_layer_name: 图层名
  222 + :return: 表名
  223 + '''
  224 +
  225 + table_guid = uuid.uuid1().__str__()
  226 + this_time = datetime.datetime.now()
  227 + ext = layer.GetExtent()
  228 + if ext[0] < 360:
  229 + ext = [round(e, 6) for e in ext]
  230 + else:
  231 + ext = [round(e, 2) for e in ext]
  232 +
  233 + geom_type = GeometryAdapter.get_geometry_type(layer)
  234 +
  235 + extent = "{},{},{},{}".format(ext[0], ext[1], ext[2], ext[3])
  236 +
  237 + table = Table(guid=table_guid,
  238 + database_guid=para.get("database_guid"),
  239 + name=layer.GetName(),
  240 + create_time=this_time, update_time=this_time,
  241 + table_type=GeometryAdapter.get_table_type(geom_type),
  242 + extent=extent,
  243 + feature_count=layer.GetFeatureCount()
  244 + )
  245 + # 删除遗留业务数据
  246 + history_table = Table.query.filter_by(name=layer.GetName(),database_guid=para.get("database_guid")).all()
  247 +
  248 + if history_table:
  249 + for ht in history_table:
  250 + db.session.delete(ht)
  251 + db.session.add(table)
  252 +
  253 + feature_defn: FeatureDefn = layer.GetLayerDefn()
  254 +
  255 + for i in range(feature_defn.GetFieldCount()):
  256 +
  257 + field_defn: FieldDefn = feature_defn.GetFieldDefn(i)
  258 + field_name = field_defn.GetName()
  259 +
  260 + field_alias = field_name if field_defn.GetAlternativeName() is None or field_defn.GetAlternativeName().__eq__(
  261 + "") else field_defn.GetAlternativeName()
  262 +
  263 + column = Columns(guid=uuid.uuid1().__str__(), table_guid=table_guid,
  264 + name=field_name, alias=field_alias, create_time=this_time, update_time=this_time)
  265 + db.session.add(column)
  266 + db.session.commit()
  267 +
  268 + return table
  269 +
  270 +
  271 +
  272 +
  273 + api_doc = {
  274 + "tags": ["矢量地图接口"],
  275 + "parameters": [
  276 +
  277 + {"name": "name",
  278 + "in": "formData",
  279 + "type": "string",
  280 + "required": "true"},
  281 +
  282 + {"name": "title",
  283 + "in": "formData",
  284 + "type": "string",
  285 + "required": "true"},
  286 +
  287 + {"name": "database_guid",
  288 + "in": "formData",
  289 + "type": "string",
  290 + "description": "DMapServer中数据库的guid",
  291 + "required": "true"},
  292 +
  293 + {"name": "table_name",
  294 + "in": "formData",
  295 + "type": "string",
  296 + "description": "表名",
  297 + "required": "true"},
  298 + ],
  299 + "responses": {
  300 + 200: {
  301 + "schema": {
  302 + "properties": {
  303 + }
  304 + }
  305 + }
  306 + }
  307 + }
\ No newline at end of file
... ...
... ... @@ -49,6 +49,9 @@ class Api(ApiTemplate):
49 49 else:
50 50 raise Exception("调用电子地图的注册服务接口失败!")
51 51
  52 + if Service.query.filter_by(name = self.para.get("name")).one_or_none():
  53 + raise Exception("同名服务已存在!")
  54 +
52 55 service = Service(
53 56 guid = service_guid,
54 57 name = self.para.get("name"),
... ...
... ... @@ -184,6 +184,7 @@ class GeometryAdapter:
184 184 layer.ResetReading()
185 185 return geom_type
186 186
  187 +
187 188 @classmethod
188 189 def convert(cls, geometry: Geometry, bbox, xy_res):
189 190 '''
... ...
... ... @@ -122,6 +122,21 @@ class PGUtil:
122 122
123 123
124 124 @classmethod
  125 + def get_srid(cls,pg_ds,table_name):
  126 + layer = pg_ds.GetLayerByName(table_name)
  127 + if not layer:
  128 + return None
  129 + srid_sql = '''select st_srid({}) from public."{}" limit 1'''.format(layer.GetGeometryColumn(), layer.GetName())
  130 + srid_layer = pg_ds.ExecuteSQL(srid_sql)
  131 + srid_feature = srid_layer.GetNextFeature()
  132 + if srid_feature:
  133 + if srid_feature.GetField(0):
  134 + return int(srid_feature.GetField(0))
  135 + else:
  136 + return None
  137 +
  138 +
  139 + @classmethod
125 140 def check_database_privilege(cls,table_name,pri_type,user,session):
126 141 pass
127 142
... ...
... ... @@ -42,7 +42,6 @@ class SQLUtil:
42 42 return False
43 43
44 44
45   -
46 45 @classmethod
47 46 def check_database_privilege(cls,table_name,pri_type,user,session):
48 47 pass
... ...
... ... @@ -11,7 +11,7 @@ VACUATE_DB_URI = None
11 11 #VACUATE_DB_URI = SQLALCHEMY_DATABASE_URI
12 12
13 13 #DMap引擎
14   -dmap_engine = "http://172.26.99.160:8820"
  14 +dmap_engine = "http://172.26.60.101:8820"
15 15
16 16 # 固定配置不需要修改
17 17
... ...
注册登录 后发表评论