提交 237b014b5792f920fe89457466a5f4e399857600

作者 nheweijun
1 个父辈 00fdfd17

2021.11.25

正在显示 45 个修改的文件 包含 752 行增加193 行删除
@@ -78,7 +78,7 @@ def create_app(): @@ -78,7 +78,7 @@ def create_app():
78 db.create_all(app=app) 78 db.create_all(app=app)
79 79
80 # 日志 80 # 日志
81 - logging.basicConfig(level=logging.INFO) 81 + logging.basicConfig(level=configure.log_level)
82 log_file = os.path.join(os.path.dirname(os.path.dirname( 82 log_file = os.path.join(os.path.dirname(os.path.dirname(
83 os.path.realpath(__file__))), "logs", "log.txt") 83 os.path.realpath(__file__))), "logs", "log.txt")
84 handler = logging.FileHandler( 84 handler = logging.FileHandler(
@@ -37,10 +37,12 @@ class Api(ApiTemplate): @@ -37,10 +37,12 @@ class Api(ApiTemplate):
37 elif self.para.get("data_path").endswith("shp"): 37 elif self.para.get("data_path").endswith("shp"):
38 data_path=self.para.get("data_path") 38 data_path=self.para.get("data_path")
39 encoding_cpg_path = data_path.split(".shp")[0]+".cpg" 39 encoding_cpg_path = data_path.split(".shp")[0]+".cpg"
40 - with open(encoding_cpg_path) as fd:  
41 - encoding_cpg = fd.readline().strip()  
42 if not os.path.exists(encoding_cpg_path): 40 if not os.path.exists(encoding_cpg_path):
43 encoding_cpg=None 41 encoding_cpg=None
  42 + else:
  43 + with open(encoding_cpg_path) as fd:
  44 + encoding_cpg = fd.readline().strip()
  45 +
44 spatial_files.append((data_path, encoding_cpg)) 46 spatial_files.append((data_path, encoding_cpg))
45 elif self.para.get("data_path").endswith("gdb"): 47 elif self.para.get("data_path").endswith("gdb"):
46 data_path=self.para.get("data_path") 48 data_path=self.para.get("data_path")
@@ -22,6 +22,7 @@ from . import table_vacuate_one @@ -22,6 +22,7 @@ from . import table_vacuate_one
22 from . import table_vacuate_info 22 from . import table_vacuate_info
23 from . import table_vacuate_ref 23 from . import table_vacuate_ref
24 from . import table_vacuate_delete 24 from . import table_vacuate_delete
  25 +from . import field_value
25 class DataManager(BlueprintApi): 26 class DataManager(BlueprintApi):
26 27
27 bp = Blueprint("DataManager", __name__, url_prefix="/API/Manager") 28 bp = Blueprint("DataManager", __name__, url_prefix="/API/Manager")
@@ -45,6 +46,15 @@ class DataManager(BlueprintApi): @@ -45,6 +46,15 @@ class DataManager(BlueprintApi):
45 return field_list.Api().result 46 return field_list.Api().result
46 47
47 @staticmethod 48 @staticmethod
  49 + @bp.route('/FieldValue', methods=['POST'])
  50 + @swag_from(field_value.Api.api_doc)
  51 + def field_value():
  52 + """
  53 + 属性值
  54 + """
  55 + return field_value.Api().result
  56 +
  57 + @staticmethod
48 @bp.route('/TableList', methods=['POST']) 58 @bp.route('/TableList', methods=['POST'])
49 @swag_from(table_list.Api.api_doc) 59 @swag_from(table_list.Api.api_doc)
50 def table_list(): 60 def table_list():
@@ -18,9 +18,18 @@ class Api(ApiTemplate): @@ -18,9 +18,18 @@ class Api(ApiTemplate):
18 res={} 18 res={}
19 19
20 column_guid = self.para.get("column_guid") 20 column_guid = self.para.get("column_guid")
  21 + update_dict = {}
21 try: 22 try:
22 - Columns.query.filter_by(guid = column_guid).update({"alias":self.para.get("column_alias"),"update_time":datetime.datetime.now()}) 23 + if self.para.get("column_alias"):
  24 + update_dict["alias"] = self.para.get("column_alias")
  25 + if self.para.get("is_for_partition") is not None:
  26 + update_dict["is_for_partition"] = int(self.para.get("is_for_partition"))
  27 + if update_dict:
  28 + update_dict["update_time"] = datetime.datetime.now()
  29 + Columns.query.filter_by(guid = column_guid).update(update_dict)
  30 +
23 db.session.commit() 31 db.session.commit()
  32 +
24 res["result"] = True 33 res["result"] = True
25 res["msg"] = "属性别名修改成功!" 34 res["msg"] = "属性别名修改成功!"
26 35
@@ -29,6 +38,9 @@ class Api(ApiTemplate): @@ -29,6 +38,9 @@ class Api(ApiTemplate):
29 38
30 return res 39 return res
31 40
  41 +
  42 +
  43 +
32 api_doc={ 44 api_doc={
33 "tags":["管理接口"], 45 "tags":["管理接口"],
34 "parameters":[ 46 "parameters":[
@@ -39,7 +51,11 @@ class Api(ApiTemplate): @@ -39,7 +51,11 @@ class Api(ApiTemplate):
39 {"name": "column_alias", 51 {"name": "column_alias",
40 "in": "formData", 52 "in": "formData",
41 "type": "string", 53 "type": "string",
42 - "description": "属性别名","required":"true"}, 54 + "description": "属性别名"},
  55 + {"name": "is_for_partition",
  56 + "in": "formData",
  57 + "type": "int",
  58 + "description": "是否用于分层分级", "enum": [0, 1]},
43 59
44 ], 60 ],
45 "responses":{ 61 "responses":{
@@ -18,10 +18,13 @@ class Api(ApiTemplate): @@ -18,10 +18,13 @@ class Api(ApiTemplate):
18 18
19 try: 19 try:
20 table_guid = self.para.get("guid") 20 table_guid = self.para.get("guid")
  21 + is_for_partition = self.para.get("is_for_partition")
21 table:Table = Table.query.filter_by(guid=table_guid).one_or_none() 22 table:Table = Table.query.filter_by(guid=table_guid).one_or_none()
22 if table: 23 if table:
23 res["result"]=True 24 res["result"]=True
24 res["data"] = ModelVisitor.objects_to_jsonarray(table.relate_columns) 25 res["data"] = ModelVisitor.objects_to_jsonarray(table.relate_columns)
  26 + if is_for_partition:
  27 + res["data"] = [data for data in res["data"] if data["is_for_partition"] == int(is_for_partition)]
25 else: 28 else:
26 res["result"]=False 29 res["result"]=False
27 res["msg"] = "数据表不存在!" 30 res["msg"] = "数据表不存在!"
@@ -38,6 +41,10 @@ class Api(ApiTemplate): @@ -38,6 +41,10 @@ class Api(ApiTemplate):
38 "in": "formData", 41 "in": "formData",
39 "type": "string", 42 "type": "string",
40 "description": "表guid"}, 43 "description": "表guid"},
  44 + {"name": "is_for_partition",
  45 + "in": "formData",
  46 + "type": "int",
  47 + "description": "是否用于分层分级", "enum": [0, 1]},
41 48
42 ], 49 ],
43 "responses":{ 50 "responses":{
  1 +#author: 4N
  2 +#createtime: 2021/1/27
  3 +#email: nheweijun@sina.com
  4 +
  5 +
  6 +import traceback
  7 +from ..models import Table,Columns,DES
  8 +from app.util.component.ApiTemplate import ApiTemplate
  9 +from app.util.component.PGUtil import PGUtil
  10 +from app.util.component.ModelVisitor import ModelVisitor
  11 +from sqlalchemy.orm import Session
  12 +
  13 +
  14 +class Api(ApiTemplate):
  15 + api_name = "属性列表"
  16 + def process(self):
  17 +
  18 + #返回结果
  19 + res={}
  20 + system_session = None
  21 +
  22 + try:
  23 + table_guid = self.para.get("table_guid")
  24 + column_guid = self.para.get("column_guid")
  25 +
  26 + page_index = int(self.para.get("page_index", "0"))
  27 + page_size = int(self.para.get("page_size", "10"))
  28 +
  29 +
  30 +
  31 + table:Table = Table.query.filter_by(guid=table_guid).one_or_none()
  32 + column:Columns = Columns.query.filter_by(guid=column_guid).one_or_none()
  33 + system_session: Session = PGUtil.get_db_session(DES.decode(table.relate_database.sqlalchemy_uri))
  34 +
  35 + if self.para.get("key"):
  36 + query = '''where "{}" like '%{}%' '''.format(column.name,self.para.get("key"))
  37 + else :
  38 + query = ""
  39 +
  40 +
  41 +
  42 + query_sql = 'select distinct "{}" from public."{}" {} order by "{}" limit {} offset {}'.format(
  43 + column.name,table.name,query, column.name,page_size,page_index * page_size
  44 + )
  45 +
  46 +
  47 + query_res = system_session.execute(query_sql).fetchall()
  48 +
  49 + query_count = system_session.execute('select count(distinct {}) from public."{}" {} '.format(
  50 + column.name,table.name,query
  51 + )).fetchone()
  52 +
  53 + res["data"] = {}
  54 + res["data"]["count"] = query_count[0]
  55 + res["data"]["list"] = [dat[0] for dat in query_res]
  56 + res["result"] = True
  57 +
  58 + except Exception as e:
  59 + print(traceback.format_exc())
  60 + raise e
  61 + finally:
  62 + try:
  63 + system_session.close()
  64 + except:
  65 + pass
  66 + return res
  67 +
  68 + api_doc={
  69 + "tags":["管理接口"],
  70 + "parameters":[
  71 + {"name": "table_guid",
  72 + "in": "formData",
  73 + "type": "string",
  74 + "description": "表guid"},
  75 + {"name": "column_guid",
  76 + "in": "formData",
  77 + "type": "string",
  78 + "description": "表guid"},
  79 + {"name": "page_index",
  80 + "in": "formData",
  81 + "type": "int",
  82 + "description": "页"},
  83 + {"name": "page_size",
  84 + "in": "formData",
  85 + "type": "int",
  86 + "description": "页大小"},
  87 + {"name": "key",
  88 + "in": "formData",
  89 + "type": "string",
  90 + "description": "key检索关键字"},
  91 +
  92 + ],
  93 + "responses":{
  94 + 200:{
  95 + "schema":{
  96 + "properties":{
  97 + }
  98 + }
  99 + }
  100 + }
  101 + }
@@ -26,7 +26,7 @@ class Api(ApiTemplate): @@ -26,7 +26,7 @@ class Api(ApiTemplate):
26 description = self.para.get("description") 26 description = self.para.get("description")
27 name = self.para.get("name") 27 name = self.para.get("name")
28 columns_edit = self.para.get("columns_edit") 28 columns_edit = self.para.get("columns_edit")
29 - 29 + is_for_partition = self.para.get("is_for_partition")
30 30
31 table = Table.query.filter_by(guid=table_guid) 31 table = Table.query.filter_by(guid=table_guid)
32 if not table.one_or_none(): 32 if not table.one_or_none():
@@ -54,6 +54,8 @@ class Api(ApiTemplate): @@ -54,6 +54,8 @@ class Api(ApiTemplate):
54 54
55 if self.para.__contains__("alias"): 55 if self.para.__contains__("alias"):
56 table.update({"alias":table_alias}) 56 table.update({"alias":table_alias})
  57 + if is_for_partition is not None:
  58 + table.update({"is_for_partition": int(is_for_partition)})
57 59
58 if self.para.__contains__("description"): 60 if self.para.__contains__("description"):
59 table.update({"description":description}) 61 table.update({"description":description})
@@ -61,7 +63,13 @@ class Api(ApiTemplate): @@ -61,7 +63,13 @@ class Api(ApiTemplate):
61 if columns_edit: 63 if columns_edit:
62 columns_edit_list = json.loads(columns_edit) 64 columns_edit_list = json.loads(columns_edit)
63 for ce in columns_edit_list: 65 for ce in columns_edit_list:
64 - Columns.query.filter_by(guid=ce["guid"]).update({"alias": ce.get("alias")}) 66 + columns_update_dict = {}
  67 + if ce.get("alias"):
  68 + columns_update_dict["alias"] = ce.get("alias")
  69 + if ce.get("is_for_partition") is not None:
  70 + columns_update_dict["is_for_partition"] = int(ce.get("is_for_partition"))
  71 + if columns_update_dict:
  72 + Columns.query.filter_by(guid=ce["guid"]).update(columns_update_dict)
65 73
66 if name: 74 if name:
67 sys_session=None 75 sys_session=None
@@ -110,6 +118,10 @@ class Api(ApiTemplate): @@ -110,6 +118,10 @@ class Api(ApiTemplate):
110 "in": "formData", 118 "in": "formData",
111 "type": "string", 119 "type": "string",
112 "description": "表名"}, 120 "description": "表名"},
  121 + {"name": "is_for_partition",
  122 + "in": "formData",
  123 + "type": "int",
  124 + "description": "是否用于分层分级", "enum": [0, 1]},
113 {"name": "description", 125 {"name": "description",
114 "in": "formData", 126 "in": "formData",
115 "type": "string", 127 "type": "string",
@@ -30,7 +30,7 @@ class Api(ApiTemplate): @@ -30,7 +30,7 @@ class Api(ApiTemplate):
30 30
31 start_time = self.para.get("start_time") 31 start_time = self.para.get("start_time")
32 end_time = self.para.get("end_time") 32 end_time = self.para.get("end_time")
33 - 33 + is_for_partition = self.para.get("is_for_partition")
34 34
35 35
36 recursion = int(self.para.get("recursion","0")) 36 recursion = int(self.para.get("recursion","0"))
@@ -46,6 +46,8 @@ class Api(ApiTemplate): @@ -46,6 +46,8 @@ class Api(ApiTemplate):
46 46
47 if database_guid: 47 if database_guid:
48 tables = tables.filter_by(database_guid=database_guid) 48 tables = tables.filter_by(database_guid=database_guid)
  49 + if is_for_partition:
  50 + tables = tables.filter_by(is_for_partition=int(is_for_partition))
49 if catalog_guid: 51 if catalog_guid:
50 52
51 if recursion.__eq__(0): 53 if recursion.__eq__(0):
@@ -80,10 +82,7 @@ class Api(ApiTemplate): @@ -80,10 +82,7 @@ class Api(ApiTemplate):
80 except Exception as e: 82 except Exception as e:
81 raise e 83 raise e
82 return res 84 return res
83 -  
84 -  
85 -  
86 - 85 +
87 86
88 api_doc={ 87 api_doc={
89 "tags":["管理接口"], 88 "tags":["管理接口"],
@@ -108,6 +107,10 @@ class Api(ApiTemplate): @@ -108,6 +107,10 @@ class Api(ApiTemplate):
108 "in": "formData", 107 "in": "formData",
109 "type": "int", 108 "type": "int",
110 "description": "点线面123","enum":[1,2,3]}, 109 "description": "点线面123","enum":[1,2,3]},
  110 + {"name": "is_for_partition",
  111 + "in": "formData",
  112 + "type": "int",
  113 + "description": "是否用于分层分级", "enum": [0, 1]},
111 {"name": "database_guid", 114 {"name": "database_guid",
112 "in": "formData", 115 "in": "formData",
113 "type": "string", 116 "type": "string",
@@ -501,10 +501,10 @@ class Api(ApiTemplate): @@ -501,10 +501,10 @@ class Api(ApiTemplate):
501 "type": "string", 501 "type": "string",
502 "description": "数据库guid", 502 "description": "数据库guid",
503 "required":"true"}, 503 "required":"true"},
504 - {"name": "user", 504 + {"name": "creator",
505 "in": "formData", 505 "in": "formData",
506 "type": "string", 506 "type": "string",
507 - "description": "用户"} 507 + "description": "创建者"}
508 508
509 ], 509 ],
510 "responses":{ 510 "responses":{
@@ -5,25 +5,30 @@ @@ -5,25 +5,30 @@
5 5
6 import datetime 6 import datetime
7 import traceback 7 import traceback
  8 +import multiprocessing
  9 +import uuid
  10 +import configure
  11 +
8 from ..models import Table, Database, Task,db,TableVacuate,Process,DES 12 from ..models import Table, Database, Task,db,TableVacuate,Process,DES
9 13
10 -from sqlalchemy.engine import ResultProxy  
11 from app.util.component.ApiTemplate import ApiTemplate 14 from app.util.component.ApiTemplate import ApiTemplate
12 -  
13 from app.util.component.StructuredPrint import StructurePrint 15 from app.util.component.StructuredPrint import StructurePrint
14 from app.util.component.PGUtil import PGUtil 16 from app.util.component.PGUtil import PGUtil
15 -import multiprocessing  
16 -import uuid  
17 -import configure  
18 -from osgeo.ogr import DataSource,Layer,Geometry  
19 -from osgeo import ogr  
20 from app.util.component.VacuateConf import VacuateConf 17 from app.util.component.VacuateConf import VacuateConf
21 from app.util.component.GeometryAdapter import GeometryAdapter 18 from app.util.component.GeometryAdapter import GeometryAdapter
22 19
23 -from .table_vacuate_ref import Api as RefApi 20 +
  21 +from osgeo.ogr import DataSource,Layer,Geometry
  22 +from osgeo import ogr
  23 +
  24 +
  25 +from sqlalchemy.orm import Session
  26 +
24 27
25 class Api(ApiTemplate): 28 class Api(ApiTemplate):
  29 +
26 api_name = "数据抽稀" 30 api_name = "数据抽稀"
  31 +
27 def process(self): 32 def process(self):
28 33
29 res = {} 34 res = {}
@@ -59,21 +64,15 @@ class Api(ApiTemplate): @@ -59,21 +64,15 @@ class Api(ApiTemplate):
59 res["msg"] = "非空间表!" 64 res["msg"] = "非空间表!"
60 return res 65 return res
61 66
62 - # if table.is_vacuate==1:  
63 - # res["state"] = -1  
64 - # res["message"] = "已精化!"  
65 - # return res  
66 -  
67 -  
68 67
69 # 初始化task 68 # 初始化task
70 task_guid = uuid.uuid1().__str__() 69 task_guid = uuid.uuid1().__str__()
71 vacuate_process = multiprocessing.Process(target=self.task,args=(table,task_guid)) 70 vacuate_process = multiprocessing.Process(target=self.task,args=(table,task_guid))
72 vacuate_process.start() 71 vacuate_process.start()
73 72
74 - ref_api = RefApi()  
75 - ref_api.para["guid"] = table_guid  
76 - ref_grids = ref_api.process()["data"] 73 + # ref_api = RefApi()
  74 + # ref_api.para["guid"] = table_guid
  75 + # ref_grids = ref_api.process()["data"]
77 76
78 task = Task(guid=task_guid, 77 task = Task(guid=task_guid,
79 name="{}精化".format(table.name), 78 name="{}精化".format(table.name),
@@ -85,7 +84,8 @@ class Api(ApiTemplate): @@ -85,7 +84,8 @@ class Api(ApiTemplate):
85 file_name=None, 84 file_name=None,
86 database_guid=table.database_guid, 85 database_guid=table.database_guid,
87 process="精化中", 86 process="精化中",
88 - parameter=",".join([str(x) for x in ref_grids])) 87 + # parameter=",".join([str(x) for x in ref_grids])
  88 + )
89 89
90 db.session.add(task) 90 db.session.add(task)
91 db.session.commit() 91 db.session.commit()
@@ -108,12 +108,12 @@ class Api(ApiTemplate): @@ -108,12 +108,12 @@ class Api(ApiTemplate):
108 vacuate_process = None 108 vacuate_process = None
109 try: 109 try:
110 sys_session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI) 110 sys_session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
111 - sys_session.query(Table).filter_by(guid=table.guid).update(  
112 - {"is_vacuate": 2, "update_time": datetime.datetime.now()})  
113 - sys_session.commit() 111 +
  112 + sys_session.query(Table).filter_by(guid=table.guid).update({"is_vacuate": 2, "update_time": datetime.datetime.now()})
114 113
115 114
116 database = sys_session.query(Database).filter_by(guid=table.database_guid).one_or_none() 115 database = sys_session.query(Database).filter_by(guid=table.database_guid).one_or_none()
  116 + database_sqlalchemy_uri = str(database.sqlalchemy_uri)
117 pg_session = PGUtil.get_db_session(DES.decode(database.sqlalchemy_uri)) 117 pg_session = PGUtil.get_db_session(DES.decode(database.sqlalchemy_uri))
118 118
119 pg_ds :DataSource= PGUtil.open_pg_data_source(0,DES.decode(database.sqlalchemy_uri)) 119 pg_ds :DataSource= PGUtil.open_pg_data_source(0,DES.decode(database.sqlalchemy_uri))
@@ -123,10 +123,10 @@ class Api(ApiTemplate): @@ -123,10 +123,10 @@ class Api(ApiTemplate):
123 tvs = sys_session.query(TableVacuate).filter_by(table_guid=table.guid).all() 123 tvs = sys_session.query(TableVacuate).filter_by(table_guid=table.guid).all()
124 for tv in tvs : 124 for tv in tvs :
125 sys_session.delete(tv) 125 sys_session.delete(tv)
126 - # try:  
127 - # pg_ds.DeleteLayer(tv.name)  
128 - # except Exception as e :  
129 - # StructurePrint().print("抽稀图层不存在!","warn") 126 +
  127 + sys_session.commit()
  128 + #长时间的连接,导致后续的session超时,现在先断开
  129 + sys_session.close()
130 130
131 # 创建抽稀过程 131 # 创建抽稀过程
132 options = ["OVERWRITE=yes", "GEOMETRY_NAME={}".format(PGUtil.get_geo_column(table.name,pg_session)), 132 options = ["OVERWRITE=yes", "GEOMETRY_NAME={}".format(PGUtil.get_geo_column(table.name,pg_session)),
@@ -134,7 +134,7 @@ class Api(ApiTemplate): @@ -134,7 +134,7 @@ class Api(ApiTemplate):
134 134
135 layer = pg_ds.GetLayerByName(table.name) 135 layer = pg_ds.GetLayerByName(table.name)
136 136
137 - vacuate_process:VacuateProcess = VacuateProcess(layer, table.guid, options,database.sqlalchemy_uri) 137 + vacuate_process:VacuateProcess = VacuateProcess(layer, table.guid, options,database_sqlalchemy_uri)
138 138
139 139
140 for feature in layer: 140 for feature in layer:
@@ -145,11 +145,14 @@ class Api(ApiTemplate): @@ -145,11 +145,14 @@ class Api(ApiTemplate):
145 145
146 vacuate_process.set_vacuate_count() 146 vacuate_process.set_vacuate_count()
147 147
  148 + # 重连
  149 + sys_session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
  150 +
148 #新增 151 #新增
149 if configure.VACUATE_DB_URI: 152 if configure.VACUATE_DB_URI:
150 user, passwd, host, port, datab = PGUtil.get_info_from_sqlachemy_uri(configure.VACUATE_DB_URI) 153 user, passwd, host, port, datab = PGUtil.get_info_from_sqlachemy_uri(configure.VACUATE_DB_URI)
151 else: 154 else:
152 - user, passwd, host, port, datab = PGUtil.get_info_from_sqlachemy_uri(DES.decode(database.sqlalchemy_uri)) 155 + user, passwd, host, port, datab = PGUtil.get_info_from_sqlachemy_uri(DES.decode(database_sqlalchemy_uri))
153 connectstr = "hostaddr={} port={} dbname='{}' user='{}' password='{}'".format(host, port, datab, user, 156 connectstr = "hostaddr={} port={} dbname='{}' user='{}' password='{}'".format(host, port, datab, user,
154 passwd) 157 passwd)
155 for l in range(vacuate_process.max_level): 158 for l in range(vacuate_process.max_level):
@@ -171,6 +174,8 @@ class Api(ApiTemplate): @@ -171,6 +174,8 @@ class Api(ApiTemplate):
171 174
172 except Exception as e: 175 except Exception as e:
173 try: 176 try:
  177 + if not sys_session.is_active:
  178 + sys_session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
174 sys_session.query(Task).filter_by(guid=task_guid).update({"state": -1,"update_time":datetime.datetime.now(), 179 sys_session.query(Task).filter_by(guid=task_guid).update({"state": -1,"update_time":datetime.datetime.now(),
175 "process": "精化失败"}) 180 "process": "精化失败"})
176 sys_session.query(Table).filter_by(guid=table.guid).update( 181 sys_session.query(Table).filter_by(guid=table.guid).update(
@@ -189,16 +194,18 @@ class Api(ApiTemplate): @@ -189,16 +194,18 @@ class Api(ApiTemplate):
189 except Exception as ee: 194 except Exception as ee:
190 print(traceback.format_exc()) 195 print(traceback.format_exc())
191 finally: 196 finally:
192 - if vacuate_process:  
193 - vacuate_process.end()  
194 - if sys_session:  
195 - sys_session.close()  
196 - if pg_session:  
197 - pg_session.close()  
198 - if pg_ds:  
199 - pg_ds.Destroy()  
200 -  
201 - 197 + try:
  198 + if vacuate_process:
  199 + vacuate_process.end()
  200 + if sys_session:
  201 + sys_session.close()
  202 + if pg_session:
  203 + pg_session.close()
  204 + if pg_ds:
  205 + pg_ds.Destroy()
  206 +
  207 + except Exception as e:
  208 + StructurePrint.print(traceback.format_exc())
202 api_doc = { 209 api_doc = {
203 "tags": ["管理接口"], 210 "tags": ["管理接口"],
204 "parameters": [ 211 "parameters": [
@@ -206,6 +213,10 @@ class Api(ApiTemplate): @@ -206,6 +213,10 @@ class Api(ApiTemplate):
206 "in": "formData", 213 "in": "formData",
207 "type": "string", 214 "type": "string",
208 "description": "表guid", "required": "true"}, 215 "description": "表guid", "required": "true"},
  216 + {"name": "creator",
  217 + "in": "formData",
  218 + "type": "string",
  219 + "description": "创建者"}
209 ], 220 ],
210 "responses": { 221 "responses": {
211 200: { 222 200: {
@@ -217,6 +228,16 @@ class Api(ApiTemplate): @@ -217,6 +228,16 @@ class Api(ApiTemplate):
217 } 228 }
218 } 229 }
219 230
  231 +class SysSession:
  232 + def __init__(self):
  233 + self.session : Session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
  234 +
  235 + def close(self):
  236 + try:
  237 + self.session.close()
  238 + except:
  239 + pass
  240 +
220 class VacuateProcess: 241 class VacuateProcess:
221 242
222 max_level=0 243 max_level=0
@@ -274,8 +295,7 @@ class VacuateProcess: @@ -274,8 +295,7 @@ class VacuateProcess:
274 295
275 layer.SetSpatialFilter(None) 296 layer.SetSpatialFilter(None)
276 layer.ResetReading() 297 layer.ResetReading()
277 - # 固有疏密程度  
278 - original_density=8 298 +
279 299
280 300
281 # 额外一层 301 # 额外一层
@@ -295,7 +315,7 @@ class VacuateProcess: @@ -295,7 +315,7 @@ class VacuateProcess:
295 if ((extent[1] - extent[0]) * (extent[3] - extent[2])) / (grid_size**2)>self.least_vacuate_count: 315 if ((extent[1] - extent[0]) * (extent[3] - extent[2])) / (grid_size**2)>self.least_vacuate_count:
296 # 要素数量大于网格数量 316 # 要素数量大于网格数量
297 # 要考虑图层的疏密程度,original_density*(100.0/fill_precent) 为疏密指数 317 # 要考虑图层的疏密程度,original_density*(100.0/fill_precent) 为疏密指数
298 - if lc * original_density * (100.0/fill_precent)>((extent[1] - extent[0])*(extent[3] - extent[2]))/(grid_size**2) : 318 + if lc * VacuateConf.original_density * (100.0/fill_precent)>((extent[1] - extent[0])*(extent[3] - extent[2]))/(grid_size**2) :
299 print(grid_size) 319 print(grid_size)
300 self.this_gridsize.append(grid_size) 320 self.this_gridsize.append(grid_size)
301 self.max_level += 1 321 self.max_level += 1
@@ -400,7 +420,8 @@ class VacuateProcess: @@ -400,7 +420,8 @@ class VacuateProcess:
400 vacuate_layer.CreateFeature(feat) 420 vacuate_layer.CreateFeature(feat)
401 self.fill_dict[key] += 1 421 self.fill_dict[key] += 1
402 #超大的还有机会 422 #超大的还有机会
403 - elif (long_extent > 10*this_grid_len or lat_extent >10*this_grid_len) and self.fill_dict[key]<5: 423 + # elif (long_extent > 10*this_grid_len or lat_extent >10*this_grid_len) and self.fill_dict[key]<5:
  424 + elif long_extent > 10 * this_grid_len or lat_extent > 10 * this_grid_len:
404 vacuate_layer: Layer = self.vacuate_layers.get(level) 425 vacuate_layer: Layer = self.vacuate_layers.get(level)
405 feat = ogr.Feature(vacuate_layer.GetLayerDefn()) 426 feat = ogr.Feature(vacuate_layer.GetLayerDefn())
406 feat.SetGeometry(g) 427 feat.SetGeometry(g)
@@ -113,16 +113,24 @@ class Api(ApiTemplate): @@ -113,16 +113,24 @@ class Api(ApiTemplate):
113 sys_session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI) 113 sys_session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
114 sys_session.query(Table).filter_by(guid=table.guid).update( 114 sys_session.query(Table).filter_by(guid=table.guid).update(
115 {"is_vacuate": 2, "update_time": datetime.datetime.now()}) 115 {"is_vacuate": 2, "update_time": datetime.datetime.now()})
116 - sys_session.commit()  
117 -  
118 116
119 database = sys_session.query(Database).filter_by(guid=table.database_guid).one_or_none() 117 database = sys_session.query(Database).filter_by(guid=table.database_guid).one_or_none()
120 - pg_session = PGUtil.get_db_session(DES.decode(database.sqlalchemy_uri))  
121 118
122 - pg_ds :DataSource= PGUtil.open_pg_data_source(1,DES.decode(database.sqlalchemy_uri)) 119 + database_sqlalchemy_uri = str(database.sqlalchemy_uri)
  120 +
  121 + pg_session = PGUtil.get_db_session(DES.decode(database_sqlalchemy_uri))
123 122
  123 + pg_ds :DataSource= PGUtil.open_pg_data_source(1,DES.decode(database_sqlalchemy_uri))
124 124
  125 + #删除原有数据
  126 + for grid in grids:
  127 + tvs = sys_session.query(TableVacuate).filter_by(pixel_distance=grid,table_guid=table.guid).all()
  128 + for tv in tvs :
  129 + sys_session.delete(tv)
125 130
  131 + sys_session.commit()
  132 + #长时间的连接,导致后续的session超时,现在先断开
  133 + sys_session.close()
126 134
127 # 创建抽稀过程 135 # 创建抽稀过程
128 options = ["OVERWRITE=yes", "GEOMETRY_NAME={}".format(PGUtil.get_geo_column(table.name,pg_session)), 136 options = ["OVERWRITE=yes", "GEOMETRY_NAME={}".format(PGUtil.get_geo_column(table.name,pg_session)),
@@ -130,7 +138,7 @@ class Api(ApiTemplate): @@ -130,7 +138,7 @@ class Api(ApiTemplate):
130 138
131 layer = pg_ds.GetLayerByName(table.name) 139 layer = pg_ds.GetLayerByName(table.name)
132 140
133 - vacuate_process:VacuateProcess = VacuateProcess(layer, table.guid, options,database.sqlalchemy_uri,grids) 141 + vacuate_process:VacuateProcess = VacuateProcess(layer, table.guid, options,database_sqlalchemy_uri,grids)
134 142
135 143
136 for feature in layer: 144 for feature in layer:
@@ -141,18 +149,14 @@ class Api(ApiTemplate): @@ -141,18 +149,14 @@ class Api(ApiTemplate):
141 149
142 vacuate_process.set_vacuate_count() 150 vacuate_process.set_vacuate_count()
143 151
144 - #删除原有数据  
145 - for grid in grids:  
146 - tvs = sys_session.query(TableVacuate).filter_by(pixel_distance=grid,table_guid=table.guid).all()  
147 - for tv in tvs :  
148 - sys_session.delete(tv)  
149 - 152 + #重新连接
  153 + sys_session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
150 154
151 #新增 155 #新增
152 if configure.VACUATE_DB_URI: 156 if configure.VACUATE_DB_URI:
153 user, passwd, host, port, datab = PGUtil.get_info_from_sqlachemy_uri(configure.VACUATE_DB_URI) 157 user, passwd, host, port, datab = PGUtil.get_info_from_sqlachemy_uri(configure.VACUATE_DB_URI)
154 else: 158 else:
155 - user, passwd, host, port, datab = PGUtil.get_info_from_sqlachemy_uri(DES.decode(database.sqlalchemy_uri)) 159 + user, passwd, host, port, datab = PGUtil.get_info_from_sqlachemy_uri(DES.decode(database_sqlalchemy_uri))
156 connectstr = "hostaddr={} port={} dbname='{}' user='{}' password='{}'".format(host, port, datab, user, 160 connectstr = "hostaddr={} port={} dbname='{}' user='{}' password='{}'".format(host, port, datab, user,
157 passwd) 161 passwd)
158 for l in range(vacuate_process.max_level): 162 for l in range(vacuate_process.max_level):
@@ -175,6 +179,8 @@ class Api(ApiTemplate): @@ -175,6 +179,8 @@ class Api(ApiTemplate):
175 179
176 except Exception as e: 180 except Exception as e:
177 try: 181 try:
  182 + if not sys_session.is_active:
  183 + sys_session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
178 sys_session.query(Task).filter_by(guid=task_guid).update({"state": -1,"update_time":datetime.datetime.now(), 184 sys_session.query(Task).filter_by(guid=task_guid).update({"state": -1,"update_time":datetime.datetime.now(),
179 "process": "精化失败"}) 185 "process": "精化失败"})
180 sys_session.query(Table).filter_by(guid=table.guid).update( 186 sys_session.query(Table).filter_by(guid=table.guid).update(
@@ -215,7 +221,12 @@ class Api(ApiTemplate): @@ -215,7 +221,12 @@ class Api(ApiTemplate):
215 {"name": "grids", 221 {"name": "grids",
216 "in": "formData", 222 "in": "formData",
217 "type": "string", 223 "type": "string",
218 - "description": "需要抽稀的网格大小,以逗号相隔", "required": "true"} 224 + "description": "需要抽稀的网格大小,以逗号相隔", "required": "true"},
  225 + {"name": "creator",
  226 + "in": "formData",
  227 + "type": "string",
  228 + "description": "创建者"}
  229 +
219 ], 230 ],
220 "responses": { 231 "responses": {
221 200: { 232 200: {
@@ -369,7 +380,8 @@ class VacuateProcess: @@ -369,7 +380,8 @@ class VacuateProcess:
369 self.fill_dict[key] += 1 380 self.fill_dict[key] += 1
370 381
371 #超大的还有机会 382 #超大的还有机会
372 - elif (long_extent > 10*this_grid_len or lat_extent >10*this_grid_len) and self.fill_dict[key]<5: 383 + # elif (long_extent > 10*this_grid_len or lat_extent >10*this_grid_len) and self.fill_dict[key]<5:
  384 + elif long_extent > 10 * this_grid_len or lat_extent > 10 * this_grid_len:
373 vacuate_layer: Layer = self.vacuate_layers.get(level) 385 vacuate_layer: Layer = self.vacuate_layers.get(level)
374 feat = ogr.Feature(vacuate_layer.GetLayerDefn()) 386 feat = ogr.Feature(vacuate_layer.GetLayerDefn())
375 feat.SetGeometry(g) 387 feat.SetGeometry(g)
@@ -55,7 +55,8 @@ class Table(db.Model): @@ -55,7 +55,8 @@ class Table(db.Model):
55 creator = Column(Text) 55 creator = Column(Text)
56 #是否已抽稀 56 #是否已抽稀
57 is_vacuate=Column(Integer,default=0) 57 is_vacuate=Column(Integer,default=0)
58 - 58 + #是否用于分层分级
  59 + is_for_partition = Column(Integer,default=0)
59 # 目录外键 60 # 目录外键
60 catalog_guid = Column(String(256), ForeignKey('dmap_catalog.guid')) 61 catalog_guid = Column(String(256), ForeignKey('dmap_catalog.guid'))
61 62
@@ -89,6 +90,8 @@ class Columns(db.Model): @@ -89,6 +90,8 @@ class Columns(db.Model):
89 alias = Column(String(256)) 90 alias = Column(String(256))
90 create_time = Column(DateTime) 91 create_time = Column(DateTime)
91 update_time = Column(DateTime) 92 update_time = Column(DateTime)
  93 + #是否用于分层分级
  94 + is_for_partition = Column(Integer,default=0)
92 95
93 class Task(db.Model): 96 class Task(db.Model):
94 ''' 97 '''
@@ -111,9 +114,11 @@ class Task(db.Model): @@ -111,9 +114,11 @@ class Task(db.Model):
111 #1:入库任务 114 #1:入库任务
112 #2:抽稀任务 115 #2:抽稀任务
113 #3:数据库刷新任务 116 #3:数据库刷新任务
114 - #4:影像金字塔任务  
115 - #5:数据下载任务  
116 - task_type=Column(Integer) 117 + #4:数据下载任务
  118 + #5:影像金字塔任务
  119 + task_type = Column(Integer)
  120 + #任务的pid,用于kill
  121 + task_pid = Column(Integer)
117 creator = Column(Text) 122 creator = Column(Text)
118 file_name = Column(Text) 123 file_name = Column(Text)
119 relate_processes = relationship('Process', backref='relate_task', lazy='dynamic') 124 relate_processes = relationship('Process', backref='relate_task', lazy='dynamic')
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2020/9/4
  4 +#email: nheweijun@sina.com
  5 +
  6 +from ..models import db,Task,Table
  7 +
  8 +
  9 +from app.util.component.ApiTemplate import ApiTemplate
  10 +import os
  11 +import signal
  12 +import platform
  13 +
  14 +
  15 +class Api(ApiTemplate):
  16 + api_name = "停止任务"
  17 + def para_check(self):
  18 + pass
  19 +
  20 + def process(self):
  21 + res = {}
  22 + try:
  23 + task_guid = self.para.get("task_guid")
  24 + task = Task.query.filter_by(guid=task_guid).one_or_none()
  25 + pid = task.task_pid
  26 + if platform.system().lower().__contains__("windows"):
  27 + os.popen('taskkill.exe /pid:' + str(pid))
  28 + else:
  29 + os.kill(pid,signal.SIGILL)
  30 + #处理kill任务后的事情
  31 + self.fix_task()
  32 + res["msg"] = "Kill成功!"
  33 + res["result"] = True
  34 + except Exception as e:
  35 + db.session.rollback()
  36 + raise e
  37 + return res
  38 +
  39 +
  40 + def fix_task(self,task):
  41 + if task.task_type==1:
  42 + pass
  43 + if task.task_type==2:
  44 + table = Table.query.filter_by(guid=task.table_guid).one_or_none()
  45 + if len(table.relate_table_vacuates.all())>0:
  46 + Table.query.filter_by(guid=task.table_guid).update({"is_vacuate":1})
  47 + if task.task_type==3:
  48 + pass
  49 + if task.task_type==3:
  50 + pass
  51 +
  52 + db.session.commit()
  53 +
  54 + api_doc = {
  55 + "tags": ["任务接口"],
  56 + "parameters": [
  57 + {"name": "task_guid",
  58 + "in": "formData",
  59 + "type": "string"},
  60 + ],
  61 + "responses": {
  62 + 200: {
  63 + "schema": {
  64 + "properties": {
  65 + }
  66 + }
  67 + }
  68 + }
  69 + }
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/11/2
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +class DmpProject:
  8 + pass
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/11/2
  4 +#email: nheweijun@sina.com
  5 +
  6 +from .DmpProject import DmpProject
  7 +
  8 +
  9 +class DmpServerProject:
  10 +
  11 + project:DmpProject = None
  12 + flag : int = None
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/11/2
  4 +#email: nheweijun@sina.com
  5 +
  6 +from .DmpServerProject import DmpServerProject
  7 +
  8 +class ImageServer:
  9 + dmp_server_projects = []
  10 +
  11 +
  12 +
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/11/2
  4 +#email: nheweijun@sina.com
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/11/2
  4 +#email: nheweijun@sina.com
@@ -9,6 +9,7 @@ from app.util import BlueprintApi @@ -9,6 +9,7 @@ from app.util import BlueprintApi
9 from . import service_register 9 from . import service_register
10 from . import service_exist_type 10 from . import service_exist_type
11 from . import service_list 11 from . import service_list
  12 +from . import service_list_base
12 from . import service_delete 13 from . import service_delete
13 from . import service_state 14 from . import service_state
14 from . import service_info 15 from . import service_info
@@ -59,6 +60,16 @@ class DataManager(BlueprintApi): @@ -59,6 +60,16 @@ class DataManager(BlueprintApi):
59 """ 60 """
60 return service_list.Api().result 61 return service_list.Api().result
61 62
  63 +
  64 + @staticmethod
  65 + @bp.route('/BaseMapList', methods=['POST'])
  66 + @swag_from(service_list_base.Api.api_doc)
  67 + def api_service_list_base():
  68 + """
  69 + 底图服务列表
  70 + """
  71 + return service_list_base.Api().result
  72 +
62 @staticmethod 73 @staticmethod
63 @bp.route('/Info', methods=['POST']) 74 @bp.route('/Info', methods=['POST'])
64 @swag_from(service_info.Api.api_doc) 75 @swag_from(service_info.Api.api_doc)
@@ -20,6 +20,7 @@ import traceback @@ -20,6 +20,7 @@ import traceback
20 20
21 from .util.ImageData import ImageData 21 from .util.ImageData import ImageData
22 from .util.Opencv import Opencv 22 from .util.Opencv import Opencv
  23 +from app.util.component.ModelVisitor import ModelVisitor
23 24
24 class Api(ApiTemplate): 25 class Api(ApiTemplate):
25 26
@@ -44,10 +45,8 @@ class Api(ApiTemplate): @@ -44,10 +45,8 @@ class Api(ApiTemplate):
44 if not zoo.connected: 45 if not zoo.connected:
45 zoo.start() 46 zoo.start()
46 47
47 -  
48 guid = self.para.get("guid") 48 guid = self.para.get("guid")
49 49
50 -  
51 width = int(self.para.get("width") if self.para.get("width") else 512) 50 width = int(self.para.get("width") if self.para.get("width") else 512)
52 height = int(self.para.get("height") if self.para.get("height") else 512) 51 height = int(self.para.get("height") if self.para.get("height") else 512)
53 format = self.para.get("format") if self.para.get("format") else "image/jpeg" 52 format = self.para.get("format") if self.para.get("format") else "image/jpeg"
@@ -75,8 +74,7 @@ class Api(ApiTemplate): @@ -75,8 +74,7 @@ class Api(ApiTemplate):
75 offset = ((query_extent[3] - query_extent[1]) - (query_extent[2] - query_extent[0])) / 2.0 74 offset = ((query_extent[3] - query_extent[1]) - (query_extent[2] - query_extent[0])) / 2.0
76 query_extent = [query_extent[0] - offset, query_extent[1], query_extent[2] + offset, query_extent[3]] 75 query_extent = [query_extent[0] - offset, query_extent[1], query_extent[2] + offset, query_extent[3]]
77 76
78 -  
79 - image_data = ImageData(image_server, image) 77 + image_data = ImageData(image_server, ModelVisitor.object_to_json(image))
80 78
81 pixel_array_t = image_data.get_data(query_extent, bands, height, width) 79 pixel_array_t = image_data.get_data(query_extent, bands, height, width)
82 80
@@ -12,29 +12,23 @@ class Api(ApiTemplate): @@ -12,29 +12,23 @@ class Api(ApiTemplate):
12 api_name = "获取数据服务器列表" 12 api_name = "获取数据服务器列表"
13 13
14 def process(self): 14 def process(self):
15 - from app import GLOBAL_DIC  
16 15
17 # 返回结果 16 # 返回结果
18 res = {} 17 res = {}
  18 + res["data"] = []
19 try: 19 try:
20 - zoo = GLOBAL_DIC.get("zookeeper")  
21 - if zoo is None:  
22 - zoo :KazooClient = KazooClient(hosts=configure.zookeeper, timeout=100)  
23 - zoo.start()  
24 - GLOBAL_DIC["zookeeper"] = zoo  
25 - else :  
26 - if not zoo.connected:  
27 - zoo.start() 20 + zoo :KazooClient = KazooClient(hosts=configure.zookeeper, timeout=1)
  21 + zoo.start()
28 sers = zoo.get_children("/rpc") 22 sers = zoo.get_children("/rpc")
29 - res["data"] = [] 23 +
30 for p in sers: 24 for p in sers:
31 bl = str( zoo.get("/rpc/{}".format(p))[0] , encoding = "utf-8") 25 bl = str( zoo.get("/rpc/{}".format(p))[0] , encoding = "utf-8")
32 res["data"].append({"name": p, "belong": bl}) 26 res["data"].append({"name": p, "belong": bl})
33 -  
34 - res["data"].append({"name":"本地服务器","belong":""})  
35 - res["result"] = True 27 + zoo.close()
36 except Exception as e: 28 except Exception as e:
37 - raise e 29 + pass
  30 + res["data"].append({"name": "本地服务器", "belong": ""})
  31 + res["result"] = True
38 return res 32 return res
39 33
40 api_doc = { 34 api_doc = {
@@ -4,15 +4,20 @@ @@ -4,15 +4,20 @@
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 6
7 -  
8 from app.util.component.ApiTemplate import ApiTemplate 7 from app.util.component.ApiTemplate import ApiTemplate
9 from ..models import Service,ImageService,Image,db,ServiceFunction 8 from ..models import Service,ImageService,Image,db,ServiceFunction
10 import datetime 9 import datetime
11 import json 10 import json
12 -from .image_service_register import Api as RegisterApi  
13 import configure 11 import configure
14 import uuid 12 import uuid
15 - 13 +import os
  14 +import cv2
  15 +import numpy
  16 +import random
  17 +from kazoo.client import KazooClient
  18 +from .util.ImageData import ImageData
  19 +from .util.MyThread import MyThread
  20 +from app.util.component.ModelVisitor import ModelVisitor
16 class Api(ApiTemplate): 21 class Api(ApiTemplate):
17 22
18 api_name = "修改影像服务" 23 api_name = "修改影像服务"
@@ -55,8 +60,8 @@ class Api(ApiTemplate): @@ -55,8 +60,8 @@ class Api(ApiTemplate):
55 db.session.add(service_function) 60 db.session.add(service_function)
56 61
57 #修改影像 62 #修改影像
  63 + image_service_exetent = []
58 if image_guids: 64 if image_guids:
59 - image_service_exetent = []  
60 imgservice:ImageService = image_service.one_or_none() 65 imgservice:ImageService = image_service.one_or_none()
61 imgservice.images = [] 66 imgservice.images = []
62 67
@@ -72,30 +77,146 @@ class Api(ApiTemplate): @@ -72,30 +77,146 @@ class Api(ApiTemplate):
72 image_service_exetent[2] = max(image_extent[2], image_service_exetent[2]) 77 image_service_exetent[2] = max(image_extent[2], image_service_exetent[2])
73 image_service_exetent[3] = max(image_extent[3], image_service_exetent[3]) 78 image_service_exetent[3] = max(image_extent[3], image_service_exetent[3])
74 imgservice.images.append(image) 79 imgservice.images.append(image)
75 -  
76 image_update["extent"] = json.dumps(image_service_exetent) 80 image_update["extent"] = json.dumps(image_service_exetent)
77 81
  82 + if image_update:
  83 + image_service.update(image_update)
  84 +
78 if service_update or image_update or functions: 85 if service_update or image_update or functions:
79 service_update["update_time"] = this_time 86 service_update["update_time"] = this_time
  87 +
80 if image_guids: 88 if image_guids:
81 - register_api = RegisterApi()  
82 - overview_file = register_api.get_overview(service, image_service) 89 + overview_file = self.get_overview(image_guids,image_service_exetent)
83 service_update["overview"] = "http://{}/API/Service/Overview/{}".format(configure.deploy_ip_host, overview_file) 90 service_update["overview"] = "http://{}/API/Service/Overview/{}".format(configure.deploy_ip_host, overview_file)
84 91
85 service.update(service_update) 92 service.update(service_update)
86 93
87 - if image_update:  
88 - image_service.update(image_update)  
89 -  
90 db.session.commit() 94 db.session.commit()
91 -  
92 res["result"] = True 95 res["result"] = True
  96 +
93 except Exception as e: 97 except Exception as e:
94 db.session.rollback() 98 db.session.rollback()
95 raise e 99 raise e
96 100
97 return res 101 return res
98 102
  103 + def get_overview(self,guids,image_service_exetent):
  104 + from app import GLOBAL_DIC
  105 +
  106 + intersect_image = Image.query.filter(Image.guid.in_(guids.split(","))).all()
  107 + query_extent = image_service_exetent
  108 +
  109 + if query_extent[2] - query_extent[0] > query_extent[3] - query_extent[1]:
  110 + offset = ((query_extent[2] - query_extent[0]) - (query_extent[3] - query_extent[1])) / 2.0
  111 + query_extent = [query_extent[0], query_extent[1] - offset, query_extent[2],
  112 + query_extent[3] + offset]
  113 + else:
  114 + offset = ((query_extent[3] - query_extent[1]) - (query_extent[2] - query_extent[0])) / 2.0
  115 + query_extent = [query_extent[0] - offset, query_extent[1], query_extent[2] + offset,
  116 + query_extent[3]]
  117 +
  118 + height = 512
  119 + width = 512
  120 +
  121 +
  122 + # 缓存zookeeper
  123 + zoo = GLOBAL_DIC.get("zookeeper")
  124 + if zoo is None:
  125 + zoo: KazooClient = KazooClient(hosts=configure.zookeeper, timeout=100)
  126 + zoo.start()
  127 + GLOBAL_DIC["zookeeper"] = zoo
  128 + else:
  129 + if not zoo.connected:
  130 + zoo.start()
  131 +
  132 + servers = GLOBAL_DIC.get("servers")
  133 + if servers is None:
  134 + servers = zoo.get_children("/rpc")
  135 + servers.append("本地服务器")
  136 + GLOBAL_DIC["servers"] = servers
  137 + else:
  138 + servers = GLOBAL_DIC.get("servers")
  139 +
  140 +
  141 + if len(intersect_image) > 1:
  142 +
  143 + # 结果矩阵
  144 + empty_list = [numpy.zeros((height, width), dtype=int) + 65536,
  145 + numpy.zeros((height, width), dtype=int) + 65536,
  146 + numpy.zeros((height, width), dtype=int) + 65536]
  147 +
  148 + pixel_array = numpy.zeros((height, width, 3), dtype=int)
  149 + thread_list = []
  150 +
  151 + for image in intersect_image:
  152 + # 该影像的服务器,随机选取一个
  153 + image_servers = image.server.split(",")
  154 + image_servers = [ser for ser in image_servers if ser in servers]
  155 + if len(image_servers) > 0:
  156 + indx = int(random.random() * len(image_servers))
  157 + image_server = image_servers[indx]
  158 + else:
  159 + image_server = "None"
  160 + bands = json.loads(image.band_view)
  161 +
  162 + image_data = ImageData(image_server, ModelVisitor.object_to_json(image))
  163 +
  164 + thread: MyThread = MyThread(image_data.get_data, args=(query_extent, bands, height, width))
  165 + thread.start()
  166 + thread_list.append(thread)
  167 +
  168 + for thread in thread_list:
  169 + thread.join()
  170 + data = thread.get_result()
  171 +
  172 + # 掩膜在中央接口生成,合图
  173 + mask = numpy.zeros((height, width), dtype=int)
  174 + mask2 = numpy.zeros((height, width), dtype=int)
  175 + jizhun = data[:, :, 0]
  176 + mask[jizhun == 65536] = 1
  177 + mask[jizhun != 65536] = 0
  178 + mask2[jizhun == 65536] = 0
  179 + mask2[jizhun != 65536] = 1
  180 + # 掩膜计算
  181 + for i, d in enumerate(empty_list):
  182 + empty_list[i] = empty_list[i] * mask + data[:, :, i] * mask2
  183 +
  184 + for ii in [0, 1, 2]:
  185 + # opencv 颜色排序为GBR
  186 + pixel_array[:, :, 2 - ii] = empty_list[ii]
  187 +
  188 +
  189 + elif len(intersect_image) == 1:
  190 + # 该影像的服务器,随机选取一个
  191 + image = intersect_image[0]
  192 + image_servers = image.server.split(",")
  193 + image_servers = [ser for ser in image_servers if ser in servers]
  194 + if len(image_servers) > 0:
  195 + indx = int(random.random() * len(image_servers))
  196 + image_server = image_servers[indx]
  197 + else:
  198 + image_server = "None"
  199 +
  200 + bands = json.loads(image.band_view)
  201 +
  202 + image_data = ImageData(image_server,ModelVisitor.object_to_json(image))
  203 +
  204 + pixel_array_t = image_data.get_data(query_extent, bands, height, width)
  205 +
  206 + pixel_array = numpy.zeros((height, width, 3), dtype=int)
  207 + for ii in [0, 1, 2]:
  208 + # opencv 颜色排序为GBR
  209 + pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii]
  210 + else:
  211 + # 结果矩阵
  212 + pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536
  213 +
  214 + dir_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "overview")
  215 + gid = uuid.uuid1().__str__()
  216 + store_file = os.path.join(dir_path, "{}.jpg".format(gid))
  217 + cv2.imwrite(store_file, pixel_array, [cv2.IMWRITE_JPEG_QUALITY, 30])
  218 +
  219 + return "{}.jpg".format(gid)
99 220
100 api_doc = { 221 api_doc = {
101 "tags": ["影像接口"], 222 "tags": ["影像接口"],
@@ -32,23 +32,42 @@ class Api(ApiTemplate): @@ -32,23 +32,42 @@ class Api(ApiTemplate):
32 res = {} 32 res = {}
33 33
34 try: 34 try:
35 - guids = self.para.get("guids").split(",") 35 + guids = self.para.get("image_guids").split(",")
36 name = self.para.get("name") 36 name = self.para.get("name")
37 functions = self.para.get("functions") 37 functions = self.para.get("functions")
38 38
39 39
40 image_service_guid = uuid.uuid1().__str__() 40 image_service_guid = uuid.uuid1().__str__()
41 service_guid = uuid.uuid1().__str__() 41 service_guid = uuid.uuid1().__str__()
42 - service_function_guid = uuid.uuid1().__str__()  
43 -  
44 42
45 this_time = datetime.datetime.now() 43 this_time = datetime.datetime.now()
  44 +
  45 + service = Service(
  46 + guid = service_guid,
  47 + name = name,
  48 + title = self.para.get("title"),
  49 + state = 1,
  50 + create_time = this_time,
  51 + update_time = this_time,
  52 + description = self.para.get("description"),
  53 + #node = Column(Integer),
  54 + type = self.para.get("type"),
  55 + catalog_guid = self.para.get("catalog_guid")
  56 + )
  57 +
  58 + db.session.add(service)
  59 +
  60 +
46 image_service = ImageService(guid=image_service_guid, 61 image_service = ImageService(guid=image_service_guid,
47 name=name, 62 name=name,
48 create_time=this_time, 63 create_time=this_time,
49 scheme_guid=self.para.get("scheme_guid"), 64 scheme_guid=self.para.get("scheme_guid"),
50 crs = self.para.get("crs"), 65 crs = self.para.get("crs"),
51 - service_guid=service_guid) 66 + service_guid=service_guid
  67 + )
  68 +
  69 + db.session.add(image_service)
  70 +
52 image_service_exetent = [] 71 image_service_exetent = []
53 72
54 for g in guids: 73 for g in guids:
@@ -62,35 +81,18 @@ class Api(ApiTemplate): @@ -62,35 +81,18 @@ class Api(ApiTemplate):
62 image_service_exetent[1] = min(image_extent[1], image_service_exetent[1]) 81 image_service_exetent[1] = min(image_extent[1], image_service_exetent[1])
63 image_service_exetent[2] = max(image_extent[2], image_service_exetent[2]) 82 image_service_exetent[2] = max(image_extent[2], image_service_exetent[2])
64 image_service_exetent[3] = max(image_extent[3], image_service_exetent[3]) 83 image_service_exetent[3] = max(image_extent[3], image_service_exetent[3])
  84 +
65 image_service.images.append(image) 85 image_service.images.append(image)
66 image_service.extent = json.dumps(image_service_exetent) 86 image_service.extent = json.dumps(image_service_exetent)
67 87
68 88
69 -  
70 - service = Service(  
71 - guid = service_guid,  
72 - name = name,  
73 - title = self.para.get("title"),  
74 - state = 1,  
75 - create_time = this_time,  
76 - update_time = this_time,  
77 - description = self.para.get("description"),  
78 - #node = Column(Integer),  
79 - type = self.para.get("type"),  
80 - catalog_guid = self.para.get("catalog_guid")  
81 - )  
82 -  
83 -  
84 -  
85 for type in functions.split(","): 89 for type in functions.split(","):
  90 + service_function_guid = uuid.uuid1().__str__()
86 service_function = ServiceFunction(guid=service_function_guid, 91 service_function = ServiceFunction(guid=service_function_guid,
87 service_guid=service_guid, 92 service_guid=service_guid,
88 type=type) 93 type=type)
89 db.session.add(service_function) 94 db.session.add(service_function)
90 95
91 - db.session.add(service)  
92 - db.session.add(image_service)  
93 -  
94 96
95 #获得overview 97 #获得overview
96 overview_file = self.get_overview(service,image_service) 98 overview_file = self.get_overview(service,image_service)
@@ -163,7 +165,7 @@ class Api(ApiTemplate): @@ -163,7 +165,7 @@ class Api(ApiTemplate):
163 "description": "[地图服务,切片服务,影像服务]"}, 165 "description": "[地图服务,切片服务,影像服务]"},
164 166
165 # 影像参数 167 # 影像参数
166 - {"name": "guids", 168 + {"name": "image_guids",
167 "in": "formData", 169 "in": "formData",
168 "type": "string", 170 "type": "string",
169 "description": "[影像服务]影像guids,以英文逗号相隔"}, 171 "description": "[影像服务]影像guids,以英文逗号相隔"},
@@ -19,8 +19,8 @@ from .util.MyThread import MyThread @@ -19,8 +19,8 @@ from .util.MyThread import MyThread
19 from .util.ImageData import ImageData 19 from .util.ImageData import ImageData
20 from .util.Opencv import Opencv 20 from .util.Opencv import Opencv
21 from .util.Cache import Cache 21 from .util.Cache import Cache
22 -  
23 - 22 +from app.util.component.ModelVisitor import ModelVisitor
  23 +from app.util.component.ParameterUtil import StructurePrint
24 class Api(ApiTemplate): 24 class Api(ApiTemplate):
25 25
26 api_name = "发布服务时预览" 26 api_name = "发布服务时预览"
@@ -91,7 +91,7 @@ class Api(ApiTemplate): @@ -91,7 +91,7 @@ class Api(ApiTemplate):
91 image_server = "None" 91 image_server = "None"
92 bands = json.loads(image.band_view) 92 bands = json.loads(image.band_view)
93 93
94 - image_data = ImageData(image_server, image) 94 + image_data = ImageData(image_server, ModelVisitor.object_to_json(image))
95 95
96 thread: MyThread = MyThread(image_data.get_data, args=(extent,bands,height,width)) 96 thread: MyThread = MyThread(image_data.get_data, args=(extent,bands,height,width))
97 thread.start() 97 thread.start()
@@ -132,7 +132,7 @@ class Api(ApiTemplate): @@ -132,7 +132,7 @@ class Api(ApiTemplate):
132 132
133 bands = json.loads(image.band_view) 133 bands = json.loads(image.band_view)
134 134
135 - image_data = ImageData(image_server, image) 135 + image_data = ImageData(image_server,ModelVisitor.object_to_json(image))
136 136
137 pixel_array_t = image_data.get_data(extent,bands,height,width) 137 pixel_array_t = image_data.get_data(extent,bands,height,width)
138 pixel_array = numpy.zeros((height, width, 3), dtype=int) 138 pixel_array = numpy.zeros((height, width, 3), dtype=int)
@@ -151,10 +151,8 @@ class Api(ApiTemplate): @@ -151,10 +151,8 @@ class Api(ApiTemplate):
151 return Response(im_data, mimetype=image_type.lower()) 151 return Response(im_data, mimetype=image_type.lower())
152 152
153 except Exception as e: 153 except Exception as e:
154 - print(traceback.format_exc())  
155 - result["result"] = False  
156 - result["message"] = e.__str__()  
157 - return result 154 + raise e
  155 +
158 156
159 def determin_intersect(self, extent1, extent2): 157 def determin_intersect(self, extent1, extent2):
160 if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[ 158 if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[
@@ -9,6 +9,8 @@ import configure @@ -9,6 +9,8 @@ import configure
9 import time 9 import time
10 from app.modules.service.models import ImageService 10 from app.modules.service.models import ImageService
11 from app.modules.service.models import TileScheme,Service 11 from app.modules.service.models import TileScheme,Service
  12 +from app.util.component.ModelVisitor import ModelVisitor
  13 +
12 import json 14 import json
13 15
14 class Cache: 16 class Cache:
@@ -21,7 +23,7 @@ class Cache: @@ -21,7 +23,7 @@ class Cache:
21 # 缓存zookeeper 23 # 缓存zookeeper
22 zoo = GLOBAL_DIC.get("zookeeper") 24 zoo = GLOBAL_DIC.get("zookeeper")
23 if zoo is None: 25 if zoo is None:
24 - zoo: KazooClient = KazooClient(hosts=configure.zookeeper, timeout=100) 26 + zoo: KazooClient = KazooClient(hosts=configure.zookeeper, timeout=1)
25 zoo.start() 27 zoo.start()
26 GLOBAL_DIC["zookeeper"] = zoo 28 GLOBAL_DIC["zookeeper"] = zoo
27 else: 29 else:
@@ -54,18 +56,23 @@ class Cache: @@ -54,18 +56,23 @@ class Cache:
54 image_service: ImageService = ImageService.query.filter_by(guid=guid_or_name).one_or_none() 56 image_service: ImageService = ImageService.query.filter_by(guid=guid_or_name).one_or_none()
55 else: 57 else:
56 image_service: ImageService = ImageService.query.filter_by(name=guid_or_name).one_or_none() 58 image_service: ImageService = ImageService.query.filter_by(name=guid_or_name).one_or_none()
  59 +
57 images = image_service.images.all() 60 images = image_service.images.all()
58 61
59 if image_service.scheme_guid: 62 if image_service.scheme_guid:
60 scheme: TileScheme = TileScheme.query.filter_by(guid=image_service.scheme_guid).one_or_none() 63 scheme: TileScheme = TileScheme.query.filter_by(guid=image_service.scheme_guid).one_or_none()
61 - GLOBAL_DIC[guid_or_name] = {"service": image_service, "images": images,  
62 - "scheme": json.loads(scheme.parameter)} 64 +
  65 + GLOBAL_DIC[guid_or_name] = {"service": ModelVisitor.object_to_json(image_service),
  66 + "images": ModelVisitor.objects_to_jsonarray(images),
  67 + "scheme": json.loads(scheme.parameter)}
63 else: 68 else:
64 69
65 - GLOBAL_DIC[guid_or_name] = {"service": image_service, "images": images} 70 + GLOBAL_DIC[guid_or_name] = {"service": ModelVisitor.object_to_json(image_service),
  71 + "images": ModelVisitor.objects_to_jsonarray(images)}
  72 +
  73 +
66 GLOBAL_DIC["service_updatetime"] = time.time() 74 GLOBAL_DIC["service_updatetime"] = time.time()
67 image_service_info = GLOBAL_DIC[guid_or_name] 75 image_service_info = GLOBAL_DIC[guid_or_name]
68 -  
69 else: 76 else:
70 image_service_info = GLOBAL_DIC[guid_or_name] 77 image_service_info = GLOBAL_DIC[guid_or_name]
71 else: 78 else:
@@ -41,9 +41,9 @@ class ImageData: @@ -41,9 +41,9 @@ class ImageData:
41 41
42 # 需要做thrift连接的缓存,连接池 42 # 需要做thrift连接的缓存,连接池
43 thrift_connect = ThriftConnect(self.image_server) 43 thrift_connect = ThriftConnect(self.image_server)
44 - image_extent = self.image.extent 44 + image_extent = self.image.get("extent")
45 45
46 - data = thrift_connect.client.getData(self.image.path, extent, json.loads(image_extent), bands, width, height) 46 + data = thrift_connect.client.getData(self.image.get("path"), extent, json.loads(image_extent), bands, width, height)
47 47
48 thrift_connect.close() 48 thrift_connect.close()
49 49
@@ -65,9 +65,9 @@ class ImageData: @@ -65,9 +65,9 @@ class ImageData:
65 65
66 # 需要做thrift连接的缓存,连接池 66 # 需要做thrift连接的缓存,连接池
67 thrift_connect = ThriftConnect(image_server) 67 thrift_connect = ThriftConnect(image_server)
68 - image_extent = image.extent 68 + image_extent = image.get("extent")
69 69
70 - data = thrift_connect.client.getData(image.path, extent, json.loads(image_extent), bands, width, height) 70 + data = thrift_connect.client.getData(image.get("path"), extent, json.loads(image_extent), bands, width, height)
71 71
72 thrift_connect.close() 72 thrift_connect.close()
73 73
@@ -84,14 +84,14 @@ class ImageData: @@ -84,14 +84,14 @@ class ImageData:
84 ''' 84 '''
85 pixel_array = numpy.zeros((height, width, 3), dtype=int) 85 pixel_array = numpy.zeros((height, width, 3), dtype=int)
86 ceng = 0 86 ceng = 0
87 - img: Dataset = gdal.Open(self.image.path, 0) 87 + img: Dataset = gdal.Open(self.image.get("path"), 0)
88 88
89 for band in bands: 89 for band in bands:
90 90
91 # 自决定金字塔等级 91 # 自决定金字塔等级
92 xysize = [img.RasterXSize, img.RasterYSize] 92 xysize = [img.RasterXSize, img.RasterYSize]
93 93
94 - origin_extent = json.loads(self.image.extent) 94 + origin_extent = json.loads(self.image.get("extent"))
95 band_data: Band = img.GetRasterBand(band) 95 band_data: Band = img.GetRasterBand(band)
96 96
97 max_level = band_data.GetOverviewCount() 97 max_level = band_data.GetOverviewCount()
@@ -52,7 +52,7 @@ class ImageWMSServer(ImageServer): @@ -52,7 +52,7 @@ class ImageWMSServer(ImageServer):
52 extent = [float(x) for x in bbox.split(",")] 52 extent = [float(x) for x in bbox.split(",")]
53 53
54 intersect_image = [im for im in image_service_info["images"] if 54 intersect_image = [im for im in image_service_info["images"] if
55 - self.determin_intersect(json.loads(im.extent), extent)] 55 + self.determin_intersect(json.loads(im.get("extent")), extent)]
56 56
57 if len(intersect_image) > 1: 57 if len(intersect_image) > 1:
58 58
@@ -66,14 +66,14 @@ class ImageWMSServer(ImageServer): @@ -66,14 +66,14 @@ class ImageWMSServer(ImageServer):
66 66
67 for image in intersect_image: 67 for image in intersect_image:
68 # 该影像的服务器,随机选取一个 68 # 该影像的服务器,随机选取一个
69 - image_servers = image.server.split(",") 69 + image_servers = image.get("server").split(",")
70 image_servers = [ser for ser in image_servers if ser in servers] 70 image_servers = [ser for ser in image_servers if ser in servers]
71 if len(image_servers) > 0: 71 if len(image_servers) > 0:
72 indx = int(random.random() * len(image_servers)) 72 indx = int(random.random() * len(image_servers))
73 image_server = image_servers[indx] 73 image_server = image_servers[indx]
74 else: 74 else:
75 image_server = "None" 75 image_server = "None"
76 - bands = json.loads(image.band_view) 76 + bands = json.loads(image.get("band_view"))
77 77
78 image_data = ImageData(image_server, image) 78 image_data = ImageData(image_server, image)
79 79
@@ -105,7 +105,7 @@ class ImageWMSServer(ImageServer): @@ -105,7 +105,7 @@ class ImageWMSServer(ImageServer):
105 elif len(intersect_image) == 1: 105 elif len(intersect_image) == 1:
106 # 该影像的服务器,随机选取一个 106 # 该影像的服务器,随机选取一个
107 image = intersect_image[0] 107 image = intersect_image[0]
108 - image_servers = image.server.split(",") 108 + image_servers = image.get("server").split(",")
109 image_servers = [ser for ser in image_servers if ser in servers] 109 image_servers = [ser for ser in image_servers if ser in servers]
110 if len(image_servers) > 0: 110 if len(image_servers) > 0:
111 indx = int(random.random() * len(image_servers)) 111 indx = int(random.random() * len(image_servers))
@@ -113,7 +113,7 @@ class ImageWMSServer(ImageServer): @@ -113,7 +113,7 @@ class ImageWMSServer(ImageServer):
113 else: 113 else:
114 image_server = "None" 114 image_server = "None"
115 115
116 - bands = json.loads(image.band_view) 116 + bands = json.loads(image.get("band_view"))
117 117
118 image_data = ImageData(image_server, image) 118 image_data = ImageData(image_server, image)
119 119
@@ -232,19 +232,19 @@ class ImageWMSServer(ImageServer): @@ -232,19 +232,19 @@ class ImageWMSServer(ImageServer):
232 </Capability> 232 </Capability>
233 </WMS_Capabilities>''' 233 </WMS_Capabilities>'''
234 234
235 - extent = json.loads(image_service.extent)  
236 - xml = xml.format(service_title=image_service.name,  
237 - service_name=image_service.name, 235 + extent = json.loads(image_service.get("extent"))
  236 + xml = xml.format(service_title=image_service.get("name"),
  237 + service_name=image_service.get("name"),
238 abstract="None", 238 abstract="None",
239 crs="ESPG:4326", 239 crs="ESPG:4326",
240 - layer_name=image_service.name,  
241 - layer_title=image_service.name, 240 + layer_name=image_service.get("name"),
  241 + layer_title=image_service.get("name"),
242 maxx=extent[2], 242 maxx=extent[2],
243 maxy=extent[3], 243 maxy=extent[3],
244 minx=extent[0], 244 minx=extent[0],
245 miny=extent[1], 245 miny=extent[1],
246 url="http://{}/API/Service/Image/WMS?guid={}".format(configure.deploy_ip_host, 246 url="http://{}/API/Service/Image/WMS?guid={}".format(configure.deploy_ip_host,
247 - image_service.guid)) 247 + image_service.get("guid")))
248 248
249 r = Response(response=xml, status=200, mimetype="application/xml") 249 r = Response(response=xml, status=200, mimetype="application/xml")
250 r.headers["Content-Type"] = "text/xml; charset=utf-8" 250 r.headers["Content-Type"] = "text/xml; charset=utf-8"
@@ -18,6 +18,7 @@ import random @@ -18,6 +18,7 @@ import random
18 import copy 18 import copy
19 import configure 19 import configure
20 from app.util.component.SliceScheme import SliceScheme 20 from app.util.component.SliceScheme import SliceScheme
  21 +from app.util.component.ModelVisitor import ModelVisitor
21 import threading 22 import threading
22 from .ImageServer import ImageServer 23 from .ImageServer import ImageServer
23 24
@@ -44,7 +45,7 @@ class ImageWMTSServer(ImageServer): @@ -44,7 +45,7 @@ class ImageWMTSServer(ImageServer):
44 45
45 re = parameter.get("request") 46 re = parameter.get("request")
46 if re and re.__eq__("GetCapabilities"): 47 if re and re.__eq__("GetCapabilities"):
47 - service = Service.query.filter_by(guid=image_service_info["service"].service_guid).one_or_none() 48 + service = Service.query.filter_by(guid=image_service_info["service"].get("service_guid")).one_or_none()
48 return self.get_wmts_capabilities(image_service_info["service"], service) 49 return self.get_wmts_capabilities(image_service_info["service"], service)
49 50
50 if parameter.get("tilematrix"): 51 if parameter.get("tilematrix"):
@@ -67,7 +68,7 @@ class ImageWMTSServer(ImageServer): @@ -67,7 +68,7 @@ class ImageWMTSServer(ImageServer):
67 # 多线程获取分布式数据 68 # 多线程获取分布式数据
68 69
69 intersect_image = [im for im in image_service_info["images"] if 70 intersect_image = [im for im in image_service_info["images"] if
70 - self.determin_intersect(json.loads(im.extent), extent)] 71 + self.determin_intersect(json.loads(im.get("extent")), extent)]
71 72
72 if len(intersect_image) > 1: 73 if len(intersect_image) > 1:
73 74
@@ -79,7 +80,7 @@ class ImageWMTSServer(ImageServer): @@ -79,7 +80,7 @@ class ImageWMTSServer(ImageServer):
79 for image in intersect_image: 80 for image in intersect_image:
80 81
81 # 该影像的服务器,随机选取一个 82 # 该影像的服务器,随机选取一个
82 - image_servers = image.server.split(",") 83 + image_servers = image.get("server").split(",")
83 image_servers = [ser for ser in image_servers if ser in servers] 84 image_servers = [ser for ser in image_servers if ser in servers]
84 if len(image_servers) > 0: 85 if len(image_servers) > 0:
85 indx = int(random.random() * len(image_servers)) 86 indx = int(random.random() * len(image_servers))
@@ -87,7 +88,7 @@ class ImageWMTSServer(ImageServer): @@ -87,7 +88,7 @@ class ImageWMTSServer(ImageServer):
87 else: 88 else:
88 image_server = "None" 89 image_server = "None"
89 90
90 - bands = json.loads(image.band_view) 91 + bands = json.loads(image.get("band_view"))
91 92
92 image_data = ImageData(image_server, image) 93 image_data = ImageData(image_server, image)
93 94
@@ -121,7 +122,7 @@ class ImageWMTSServer(ImageServer): @@ -121,7 +122,7 @@ class ImageWMTSServer(ImageServer):
121 elif len(intersect_image) == 1: 122 elif len(intersect_image) == 1:
122 # 该影像的服务器,随机选取一个 123 # 该影像的服务器,随机选取一个
123 image = intersect_image[0] 124 image = intersect_image[0]
124 - image_servers = image.server.split(",") 125 + image_servers = image.get("server").split(",")
125 # 判断可用服务器 126 # 判断可用服务器
126 image_servers = [ser for ser in image_servers if ser in servers] 127 image_servers = [ser for ser in image_servers if ser in servers]
127 if len(image_servers) > 0: 128 if len(image_servers) > 0:
@@ -130,7 +131,7 @@ class ImageWMTSServer(ImageServer): @@ -130,7 +131,7 @@ class ImageWMTSServer(ImageServer):
130 else: 131 else:
131 image_server = "None" 132 image_server = "None"
132 # image_server = image_servers[0] 133 # image_server = image_servers[0]
133 - bands = json.loads(image.band_view) 134 + bands = json.loads(image.get("band_view"))
134 135
135 image_data = ImageData(image_server, image) 136 image_data = ImageData(image_server, image)
136 pixel_array_t: numpy.ndarray = image_data.get_data(extent, bands, height, width) 137 pixel_array_t: numpy.ndarray = image_data.get_data(extent, bands, height, width)
@@ -149,11 +150,11 @@ class ImageWMTSServer(ImageServer): @@ -149,11 +150,11 @@ class ImageWMTSServer(ImageServer):
149 return Response(im_data, mimetype=image_type.lower()) 150 return Response(im_data, mimetype=image_type.lower())
150 151
151 152
152 - def get_wmts_capabilities(self, image_service: ImageService, service: Service):  
153 - tile_scheme: TileScheme = TileScheme.query.filter_by(guid=image_service.scheme_guid).one_or_none() 153 + def get_wmts_capabilities(self, image_service, service: Service):
  154 + tile_scheme: TileScheme = TileScheme.query.filter_by(guid=image_service.get("scheme_guid")).one_or_none()
154 if not tile_scheme: 155 if not tile_scheme:
155 raise Exception("切片方案不存在!") 156 raise Exception("切片方案不存在!")
156 - 157 + tile_scheme = ModelVisitor.object_to_json(tile_scheme)
157 xml = '''<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0"> 158 xml = '''<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
158 <!-- Service Identification --> 159 <!-- Service Identification -->
159 <ows:ServiceIdentification> 160 <ows:ServiceIdentification>
@@ -267,21 +268,21 @@ class ImageWMTSServer(ImageServer): @@ -267,21 +268,21 @@ class ImageWMTSServer(ImageServer):
267 ''' 268 '''
268 269
269 tile_matrix = "" 270 tile_matrix = ""
270 - top_left = tile_scheme.top_left  
271 - for level in json.loads(tile_scheme.levels): 271 + top_left = tile_scheme.get("top_left")
  272 + for level in json.loads(tile_scheme.get("levels")):
272 tile_matrix = "{}{}".format(tile_matrix, tile_matrix_each.format(lev=level["level"], 273 tile_matrix = "{}{}".format(tile_matrix, tile_matrix_each.format(lev=level["level"],
273 scale=level["scale"], 274 scale=level["scale"],
274 top_left=top_left, 275 top_left=top_left,
275 - cols=tile_scheme.cols,  
276 - rows=tile_scheme.rows)) 276 + cols=tile_scheme.get("cols"),
  277 + rows=tile_scheme.get("rows")))
277 278
278 - extent = json.loads(image_service.extent) 279 + extent = json.loads(image_service.get("extent"))
279 280
280 xml = xml.format( 281 xml = xml.format(
281 capabilities_url="http://{}/API/Service/Image/Capabilities?guid={}".format(configure.deploy_ip_host, 282 capabilities_url="http://{}/API/Service/Image/Capabilities?guid={}".format(configure.deploy_ip_host,
282 - image_service.guid),  
283 - tile_url="http://{}/API/Service/Image/Tile?guid={}".format(configure.deploy_ip_host, image_service.guid),  
284 - crs=tile_scheme.crs, 283 + image_service.get("guid")),
  284 + tile_url="http://{}/API/Service/Image/Tile?guid={}".format(configure.deploy_ip_host, image_service.get("guid")),
  285 + crs=tile_scheme.get("crs"),
285 xmin=extent[0], 286 xmin=extent[0],
286 ymin=extent[1], 287 ymin=extent[1],
287 xmax=extent[2], 288 xmax=extent[2],
@@ -289,11 +290,11 @@ class ImageWMTSServer(ImageServer): @@ -289,11 +290,11 @@ class ImageWMTSServer(ImageServer):
289 # TileMatrix = "{TileMatrix}", 290 # TileMatrix = "{TileMatrix}",
290 # TileRow = "{TileRow}", 291 # TileRow = "{TileRow}",
291 # TileCol = "{TileCol}", 292 # TileCol = "{TileCol}",
292 - guid=image_service.guid, 293 + guid=image_service.get("guid"),
293 title=service.title, 294 title=service.title,
294 - tile_title=tile_scheme.name,  
295 - tile_name=tile_scheme.name,  
296 - tile_description=tile_scheme.description, 295 + tile_title=tile_scheme.get("name"),
  296 + tile_name=tile_scheme.get("name"),
  297 + tile_description=tile_scheme.get("description"),
297 tile_matrix=tile_matrix 298 tile_matrix=tile_matrix
298 ) 299 )
299 300
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 6
7 from app.util.component.ApiTemplate import ApiTemplate 7 from app.util.component.ApiTemplate import ApiTemplate
8 from app.util.component.ModelVisitor import ModelVisitor 8 from app.util.component.ModelVisitor import ModelVisitor
9 -from .models import Service,ServiceFunction 9 +from .models import Service,ServiceFunction,ImageService
10 from sqlalchemy import or_ 10 from sqlalchemy import or_
11 11
12 12
@@ -26,10 +26,14 @@ class Api(ApiTemplate): @@ -26,10 +26,14 @@ class Api(ApiTemplate):
26 name = self.para.get("name") 26 name = self.para.get("name")
27 type = self.para.get("type") 27 type = self.para.get("type")
28 function_type = self.para.get("function_type") 28 function_type = self.para.get("function_type")
  29 + state = self.para.get("state")
29 30
30 catalog_guid = self.para.get("catalog_guid") 31 catalog_guid = self.para.get("catalog_guid")
31 32
32 services = Service.query.order_by(Service.update_time.desc()) 33 services = Service.query.order_by(Service.update_time.desc())
  34 +
  35 + if state:
  36 + services = services.filter_by(state=int(state))
33 if type: 37 if type:
34 services = services.filter_by(type=type) 38 services = services.filter_by(type=type)
35 39
@@ -44,6 +48,11 @@ class Api(ApiTemplate): @@ -44,6 +48,11 @@ class Api(ApiTemplate):
44 services = services.filter(Service.title.like("%" + title + "%")) 48 services = services.filter(Service.title.like("%" + title + "%"))
45 if name: 49 if name:
46 services = services.filter(Service.name.like("%" + name + "%")) 50 services = services.filter(Service.name.like("%" + name + "%"))
  51 +
  52 + if onlyWMTS:
  53 + services = services.join(ServiceFunction).filter(ServiceFunction.type=="WMTS")
  54 +
  55 +
47 res["data"] = {} 56 res["data"] = {}
48 res["data"]["count"] = services.count() 57 res["data"]["count"] = services.count()
49 services = services.limit(page_size).offset(page_index * page_size).all() 58 services = services.limit(page_size).offset(page_index * page_size).all()
@@ -61,6 +70,9 @@ class Api(ApiTemplate): @@ -61,6 +70,9 @@ class Api(ApiTemplate):
61 70
62 return res 71 return res
63 72
  73 + def judge(self,name):
  74 + return name.__contains__("演示")
  75 +
64 api_doc = { 76 api_doc = {
65 "tags": ["服务接口"], 77 "tags": ["服务接口"],
66 "parameters": [ 78 "parameters": [
@@ -80,6 +92,11 @@ class Api(ApiTemplate): @@ -80,6 +92,11 @@ class Api(ApiTemplate):
80 "in": "formData", 92 "in": "formData",
81 "type": "string", 93 "type": "string",
82 "description": "服务名"}, 94 "description": "服务名"},
  95 + {"name": "state",
  96 + "in": "formData",
  97 + "type": "string",
  98 + "description": "状态",
  99 + "enum":[0,1]},
83 {"name": "type", 100 {"name": "type",
84 "in": "formData", 101 "in": "formData",
85 "type": "string", 102 "type": "string",
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/9/14
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from app.util.component.ApiTemplate import ApiTemplate
  8 +from app.util.component.ModelVisitor import ModelVisitor
  9 +from .models import Service,ServiceFunction,ImageService
  10 +from sqlalchemy import or_
  11 +from app.util.component.GeometryAdapter import GeometryAdapter
  12 +
  13 +import json
  14 +
  15 +class Api(ApiTemplate):
  16 +
  17 + api_name = "底图服务列表"
  18 +
  19 + def process(self):
  20 +
  21 + # 返回结果
  22 + res = {}
  23 +
  24 + try:
  25 + page_index = int(self.para.get("page_index", "0"))
  26 + page_size = int(self.para.get("page_size", "10"))
  27 + bbox = self.para.get("bbox")
  28 + state = self.para.get("state")
  29 +
  30 + services = Service.query.order_by(Service.update_time.desc())
  31 +
  32 + if state:
  33 + services = services.filter_by(state=int(state))
  34 +
  35 + services = services.join(ServiceFunction).filter(ServiceFunction.type=="WMTS")
  36 + services = services.all()
  37 +
  38 +
  39 + fit_services = []
  40 + if bbox:
  41 + g1 = GeometryAdapter.bbox_2_polygon([float(x) for x in bbox.split(",")])
  42 + for ser in services:
  43 + if ser.type.__eq__("切片服务"):
  44 + layer_exetent = ser.relate_tile_service.one_or_none().layer_extent
  45 +
  46 + g2 = GeometryAdapter.envelop_2_polygon([float(x) for x in layer_exetent.split(",")])
  47 + if g1.Intersect(g2):
  48 + fit_services.append(ser)
  49 + if ser.type.__eq__("影像服务"):
  50 + image_extent = ser.relate_image_service.one_or_none().extent
  51 + g2 = GeometryAdapter.bbox_2_polygon(json.loads(image_extent))
  52 + if g1.Intersect(g2):
  53 + fit_services.append(ser)
  54 + else:
  55 + fit_services = services
  56 +
  57 + res["data"] = {}
  58 + res["data"]["count"] = len(fit_services)
  59 +
  60 + res["data"]["list"] = ModelVisitor.objects_to_jsonarray(fit_services[page_index * page_size:(page_index+1) * page_size])
  61 +
  62 + for service_json in res["data"]["list"]:
  63 + service_json["functions"] = sorted(ModelVisitor.objects_to_jsonarray(ServiceFunction.query.filter_by(service_guid=service_json["guid"]).all()),
  64 + key=lambda x:x["type"])
  65 +
  66 + res["result"] = True
  67 +
  68 +
  69 + except Exception as e:
  70 + raise e
  71 +
  72 + return res
  73 +
  74 + def judge(self,name):
  75 + return name.__contains__("演示")
  76 +
  77 + api_doc = {
  78 + "tags": ["服务接口"],
  79 + "parameters": [
  80 + {"name": "page_index",
  81 + "in": "formData",
  82 + "type": "int",
  83 + "description": "页"},
  84 + {"name": "page_size",
  85 + "in": "formData",
  86 + "type": "int",
  87 + "description": "页大小"},
  88 +
  89 + {"name": "state",
  90 + "in": "formData",
  91 + "type": "string",
  92 + "description": "状态",
  93 + "enum":[0,1]},
  94 +
  95 + {"name": "bbox",
  96 + "in": "formData",
  97 + "type": "String",
  98 + "description": "x1,y1,x2,y2"},
  99 +
  100 + ],
  101 + "responses": {
  102 + 200: {
  103 + "schema": {
  104 + "properties": {
  105 + }
  106 + }
  107 + }
  108 + }
  109 + }
@@ -60,7 +60,7 @@ class Api(ApiTemplate): @@ -60,7 +60,7 @@ class Api(ApiTemplate):
60 "description": "[地图服务,切片服务,影像服务]"}, 60 "description": "[地图服务,切片服务,影像服务]"},
61 61
62 #影像参数 62 #影像参数
63 - {"name": "guids", 63 + {"name": "image_guids",
64 "in": "formData", 64 "in": "formData",
65 "type": "string", 65 "type": "string",
66 "description": "[影像服务]影像guids,以英文逗号相隔"}, 66 "description": "[影像服务]影像guids,以英文逗号相隔"},
@@ -144,7 +144,10 @@ class EntryDataVacuate: @@ -144,7 +144,10 @@ class EntryDataVacuate:
144 144
145 145
146 for i in range(ds.GetLayerCount()): 146 for i in range(ds.GetLayerCount()):
  147 +
147 layer: Layer = ds.GetLayer(i) 148 layer: Layer = ds.GetLayer(i)
  149 + if layer.GetName().lower() not in meta.get("layer").keys():
  150 + continue
148 is_success, new_layer_name = self.entry_one_layer(layer,this_task,meta) 151 is_success, new_layer_name = self.entry_one_layer(layer,this_task,meta)
149 new_layer_names.append(new_layer_name) 152 new_layer_names.append(new_layer_name)
150 is_successes.append(is_success) 153 is_successes.append(is_success)
@@ -330,7 +333,12 @@ class ThisTask: @@ -330,7 +333,12 @@ class ThisTask:
330 is_vacuate=is_vacuate 333 is_vacuate=is_vacuate
331 ) 334 )
332 # 删除遗留业务数据 335 # 删除遗留业务数据
333 - history_table = self.sys_session.query(Table).filter_by(name=new_layer_name,database_guid=self.database.guid).all() 336 + try:
  337 + history_table = self.sys_session.query(Table).filter_by(name=new_layer_name,database_guid=self.database.guid).all()
  338 + except:
  339 + self.sys_session: Session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI)
  340 + history_table = self.sys_session.query(Table).filter_by(name=new_layer_name,database_guid=self.database.guid).all()
  341 +
334 if history_table: 342 if history_table:
335 for ht in history_table: 343 for ht in history_table:
336 self.sys_session.delete(ht) 344 self.sys_session.delete(ht)
@@ -56,8 +56,6 @@ class SliceScheme: @@ -56,8 +56,6 @@ class SliceScheme:
56 maxy = -detaxy * row + int(parameter.get("y")) 56 maxy = -detaxy * row + int(parameter.get("y"))
57 maxx = detaxy + minx 57 maxx = detaxy + minx
58 miny = -detaxy + maxy 58 miny = -detaxy + maxy
59 -  
60 -  
61 return [minx,miny,maxx,maxy] 59 return [minx,miny,maxx,maxy]
62 60
63 61
@@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
5 5
6 6
7 class VacuateConf: 7 class VacuateConf:
  8 + original_density = 4
8 least_vacuate_count = 20000 9 least_vacuate_count = 20000
9 lonlat_gridsize = [0.00008, 0.00016, 0.00032, 0.00064, 0.00128, 0.00256, 0.00512, 0.01024, 0.02048,0.04096, 0.08192] 10 lonlat_gridsize = [0.00008, 0.00016, 0.00032, 0.00064, 0.00128, 0.00256, 0.00512, 0.01024, 0.02048,0.04096, 0.08192]
10 project_gridsize = [8,16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192] 11 project_gridsize = [8,16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192]
1 # coding=utf-8 1 # coding=utf-8
2 - 2 +import logging
3 # 程序部署ip:host 3 # 程序部署ip:host
4 deploy_ip_host = "172.26.40.105:8840" 4 deploy_ip_host = "172.26.40.105:8840"
5 # 系统数据库 5 # 系统数据库
@@ -27,3 +27,5 @@ entry_data_thread = 3 @@ -27,3 +27,5 @@ entry_data_thread = 3
27 scan_module = ["app.modules"] # API所在的模块 27 scan_module = ["app.modules"] # API所在的模块
28 SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/' 28 SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/'
29 29
  30 +log_level = logging.INFO
  31 +
@@ -24,7 +24,7 @@ fi @@ -24,7 +24,7 @@ fi
24 #启动容器和apache 24 #启动容器和apache
25 echo "正在启动容器..." 25 echo "正在启动容器..."
26 set="--privileged=true -e TZ="Asia/Shanghai" --restart=always -e ALLOW_IP_RANGE=0.0.0.0/0" 26 set="--privileged=true -e TZ="Asia/Shanghai" --restart=always -e ALLOW_IP_RANGE=0.0.0.0/0"
27 -docker run -d --name $dn $set -p $port:80 -v $curPath:/usr/src/app -v $curPath/httpd.conf:/etc/httpd/conf/httpd.conf dci/dmapmanager:4.0 /usr/sbin/init 27 +docker run -d --name $dn $set -p $port:80 -v $curPath/logs/apache.error:/var/log/httpd/error_log -v $curPath:/usr/src/app -v $curPath/httpd.conf:/etc/httpd/conf/httpd.conf dci/dmapmanager:4.0 /usr/sbin/init
28 docker exec -d $dn systemctl start httpd 28 docker exec -d $dn systemctl start httpd
29 sleep 5 29 sleep 5
30 curl localhost:$port/release 30 curl localhost:$port/release
@@ -53,12 +53,6 @@ def query_thread(): @@ -53,12 +53,6 @@ def query_thread():
53 ses.close() 53 ses.close()
54 # query_thread() 54 # query_thread()
55 if __name__ == '__main__': 55 if __name__ == '__main__':
56 - time1 = time.time()  
57 - ps=[]  
58 - for i in range(20):  
59 - t = multiprocessing.Process(target=query_thread)  
60 - t.start()  
61 - ps.append(t)  
62 - for p in ps:  
63 - p.join()  
64 - print(time.time()-time1)  
  56 + kk = [1,2,3,4,5,6,7,8,9,10,11]
  57 + print(len(kk))
  58 + print(kk[10:20])
注册登录 后发表评论