提交 27524217be13577d58f8b2f0348779110dc6f993

作者 qianyingz
2 个父辈 dac80d95 874cc380
正在显示 49 个修改的文件 包含 273 行增加4196 行删除

要显示太多修改。

为保证性能只显示 49 of 109 个文件。

@@ -22,6 +22,9 @@ class Api(ApiTemplate): @@ -22,6 +22,9 @@ class Api(ApiTemplate):
22 for cata in catalogs: 22 for cata in catalogs:
23 catalog_guids = [c.guid for c in Catalog.query.filter(Catalog.path.like("%" + cata.guid + "%")).all()] 23 catalog_guids = [c.guid for c in Catalog.query.filter(Catalog.path.like("%" + cata.guid + "%")).all()]
24 table_count = Table.query.filter(Table.catalog_guid.in_(catalog_guids)).count() 24 table_count = Table.query.filter(Table.catalog_guid.in_(catalog_guids)).count()
  25 +
  26 +
  27 +
25 database_alias = cata.relate_database.alias 28 database_alias = cata.relate_database.alias
26 cata_json = ModelVisitor.object_to_json(cata) 29 cata_json = ModelVisitor.object_to_json(cata)
27 cata_json["table_count"]=table_count 30 cata_json["table_count"]=table_count
@@ -9,6 +9,7 @@ from ..models import Database,db @@ -9,6 +9,7 @@ from ..models import Database,db
9 9
10 from app.util.component.ApiTemplate import ApiTemplate 10 from app.util.component.ApiTemplate import ApiTemplate
11 class Api(ApiTemplate): 11 class Api(ApiTemplate):
  12 +
12 api_name = "测试数据库别名" 13 api_name = "测试数据库别名"
13 14
14 def process(self): 15 def process(self):
@@ -12,7 +12,9 @@ from ..models import Database,DES @@ -12,7 +12,9 @@ from ..models import Database,DES
12 12
13 from app.util.component.ApiTemplate import ApiTemplate 13 from app.util.component.ApiTemplate import ApiTemplate
14 class Api(ApiTemplate): 14 class Api(ApiTemplate):
  15 +
15 api_name = "测试数据库连接" 16 api_name = "测试数据库连接"
  17 +
16 def process(self): 18 def process(self):
17 res = {} 19 res = {}
18 try: 20 try:
@@ -56,7 +56,7 @@ class Api(ApiTemplate): @@ -56,7 +56,7 @@ class Api(ApiTemplate):
56 res["msg"] = "数据库连接已存在,请修改数据库连接!" 56 res["msg"] = "数据库连接已存在,请修改数据库连接!"
57 return res 57 return res
58 elif not self.check_space(sqlalchemy_uri): 58 elif not self.check_space(sqlalchemy_uri):
59 - res["msg"] = "数据不是空间数据库!" 59 + res["msg"] = "数据不是空间数据库!"
60 return res 60 return res
61 else: 61 else:
62 this_time = datetime.datetime.now() 62 this_time = datetime.datetime.now()
@@ -8,7 +8,7 @@ from app.util import BlueprintApi @@ -8,7 +8,7 @@ from app.util import BlueprintApi
8 8
9 from flask import send_from_directory 9 from flask import send_from_directory
10 import os 10 import os
11 -from . import data_download,data_download_task 11 +from . import data_download_task
12 from . import get_meta 12 from . import get_meta
13 from . import data_entry_by_meta 13 from . import data_entry_by_meta
14 from . import get_data_list 14 from . import get_data_list
@@ -55,14 +55,6 @@ class DataManager(BlueprintApi): @@ -55,14 +55,6 @@ class DataManager(BlueprintApi):
55 result["message"] ="删除文件失败!" 55 result["message"] ="删除文件失败!"
56 return result 56 return result
57 57
58 - @staticmethod  
59 - @bp.route('/DataDownload', methods=['POST'])  
60 - @swag_from(data_download.Api.api_doc)  
61 - def table_download():  
62 - """  
63 - 下载数据  
64 - """  
65 - return data_download.Api().result  
66 58
67 @staticmethod 59 @staticmethod
68 @bp.route('/DataDownloadTask', methods=['POST']) 60 @bp.route('/DataDownloadTask', methods=['POST'])
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2020/11/27  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -from ..models import *  
8 -  
9 -  
10 -from osgeo.ogr import DataSource,Layer,FeatureDefn,FieldDefn,Feature  
11 -from osgeo import gdal,ogr  
12 -import os  
13 -import uuid  
14 -import configure  
15 -from app.util.component.ApiTemplate import ApiTemplate  
16 -from app.util.component.PGUtil import PGUtil  
17 -from app.util.component.ZipUtil import ZipUtil  
18 -  
19 -class Api(ApiTemplate):  
20 -  
21 - def process(self):  
22 - #获取参数  
23 -  
24 - #返回结果  
25 - result={}  
26 - #设置编码  
27 - encoding = self.para.get("encoding")  
28 - if encoding:  
29 - gdal.SetConfigOption("SHAPE_ENCODING",encoding)  
30 - else:  
31 - gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8")  
32 -  
33 - ds:DataSource = None  
34 - try:  
35 - table_names = self.para.get("table_name").split(",")  
36 - database_guid = self.para.get("database_guid")  
37 - database = Database.query.filter_by(guid=database_guid).one_or_none()  
38 - if not database:  
39 - raise Exception("数据库不存在!")  
40 -  
41 -  
42 - ds:DataSource = PGUtil.open_pg_data_source(0,DES.decode(database.sqlalchemy_uri))  
43 -  
44 - download_type = self.para.get("download_type")  
45 -  
46 - data = None  
47 - if download_type.__eq__("shp"):  
48 - data = self.download_shp(table_names,ds)  
49 - if download_type.__eq__("gdb"):  
50 - data = self.download_gdb(table_names, ds,database_guid)  
51 -  
52 - result["data"] = data  
53 - result["result"] = True  
54 - except Exception as e:  
55 - raise e  
56 -  
57 - finally:  
58 - if ds:  
59 - ds.Destroy()  
60 - return result  
61 -  
62 -  
63 - def download_shp(self,table_names,ds):  
64 - data = []  
65 - for table_name in table_names:  
66 - url = self.download_one(ds, table_name)  
67 - data.append({"name": table_name, "download_url": url})  
68 - return data  
69 -  
70 - def download_one(self,ds,table_name):  
71 -  
72 - layer: Layer = ds.GetLayerByName(table_name)  
73 - driver = ogr.GetDriverByName("ESRI Shapefile")  
74 - uuid_ = uuid.uuid1().__str__()  
75 - parent = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))  
76 - dirpath = os.path.join(parent, "file_tmp", uuid_)  
77 - os.makedirs(dirpath)  
78 - data_source: DataSource = driver.CreateDataSource(dirpath + "/{}.shp".format(table_name))  
79 -  
80 - fid = layer.GetFIDColumn()  
81 - pg_layer: Layer = data_source.CreateLayer(table_name, layer.GetSpatialRef(), layer.GetGeomType())  
82 - schema = [sche for sche in layer.schema if not sche.name.__eq__(fid)]  
83 -  
84 - pg_layer.CreateFields(schema)  
85 - layer.ResetReading()  
86 - for feature in layer:  
87 - pg_layer.CreateFeature(feature)  
88 -  
89 - data_source.Destroy()  
90 -  
91 -  
92 - ZipUtil.create_zip(os.path.join(parent, "file_tmp", table_name+"_"+uuid_) + ".zip", [dirpath])  
93 -  
94 - return "http://" + configure.deploy_ip_host + "/API/IO/Download/{}".format(table_name+"_"+uuid_ + ".zip")  
95 -  
96 -  
97 - def download_gdb(self,table_names,ds,database_guid):  
98 - ogr.RegisterAll()  
99 - data = []  
100 - gdal.UseExceptions()  
101 - gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES")  
102 -  
103 - # 创建一个gdb datasource  
104 - gdb_driver = ogr.GetDriverByName('FileGDB')  
105 - uuid_ = uuid.uuid1().__str__()  
106 - parent = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))  
107 - gdb_path = os.path.join(parent, "file_tmp", uuid_+".gdb")  
108 - gdb_ds: DataSource = gdb_driver.CreateDataSource(gdb_path)  
109 -  
110 -  
111 - for table_name in table_names:  
112 -  
113 - layer: Layer = ds.GetLayerByName(table_name)  
114 - table = Table.query.filter_by(name=table_name, database_guid=database_guid).one_or_none()  
115 - feature_defn: FeatureDefn = layer.GetLayerDefn()  
116 -  
117 - for i in range(feature_defn.GetFieldCount()):  
118 - field_defn:FieldDefn = feature_defn.GetFieldDefn(i)  
119 - field_alias = Columns.query.filter_by(table_guid=table.guid,name=field_defn.GetName()).one_or_none().alias  
120 - field_defn.SetAlternativeName(field_alias)  
121 -  
122 - table_alias= table.alias  
123 -  
124 -  
125 - fid = layer.GetFIDColumn()  
126 - pg_layer: Layer = gdb_ds.CreateLayer(table_name, layer.GetSpatialRef(), layer.GetGeomType(),["LAYER_ALIAS={}".format(table_alias)])  
127 - schema = [sche for sche in layer.schema if not sche.name.__eq__(fid)]  
128 - pg_layer.CreateFields(schema)  
129 -  
130 - # gdb 不支持fid=0的要素,所以识别到后要+1  
131 - offset = 0  
132 - f1:Feature = layer.GetNextFeature()  
133 - if f1:  
134 - if f1.GetFID().__eq__(0):  
135 - offset = 1  
136 - layer.ResetReading()  
137 - for feature in layer:  
138 - feature.SetFID(feature.GetFID()+offset)  
139 - pg_layer.CreateFeature(feature)  
140 -  
141 - gdb_ds.Destroy()  
142 - ZipUtil.create_zip(gdb_path + ".zip", [gdb_path])  
143 - data.append({"name": ",".join(table_names), "download_url": "http://" + configure.deploy_ip_host + "/API/IO/Download/{}".format(uuid_+".gdb" + ".zip")})  
144 -  
145 -  
146 - return data  
147 -  
148 -  
149 -  
150 - api_doc={  
151 - "tags":["IO接口"],  
152 - "description":"下载数据",  
153 - "parameters":[  
154 - {"name": "table_name",  
155 - "in": "formData",  
156 - "type":"string","description":"支持多图层下载,以逗号相隔","required":"true"},  
157 - {"name": "encoding",  
158 - "in": "formData",  
159 - "type": "string",  
160 - "enum":["GBK","UTF-8"]},  
161 - {"name": "download_type",  
162 - "in": "formData",  
163 - "type": "string",  
164 - "enum": ["shp", "gdb"],"required":"true"  
165 - },  
166 - {"name": "database_guid",  
167 - "in": "formData",  
168 - "type": "string","required":"true"  
169 - }  
170 - ],  
171 - "responses":{  
172 - 200:{  
173 - "schema":{  
174 - "properties":{  
175 - "content":{  
176 - "type": "string",  
177 - "description": "The name of the user"  
178 - }  
179 - }  
180 - }  
181 - }  
182 - }  
183 -}  
@@ -101,6 +101,7 @@ class Api(ApiTemplate): @@ -101,6 +101,7 @@ class Api(ApiTemplate):
101 try: 101 try:
102 task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "下载失败"}) 102 task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "下载失败"})
103 task_writer.update_process( e.__str__()) 103 task_writer.update_process( e.__str__())
  104 + task_writer.update_process("任务中止!")
104 except Exception as ee: 105 except Exception as ee:
105 StructurePrint().print(ee.__str__()) 106 StructurePrint().print(ee.__str__())
106 raise e 107 raise e
@@ -132,7 +133,7 @@ class Api(ApiTemplate): @@ -132,7 +133,7 @@ class Api(ApiTemplate):
132 133
133 134
134 fid = layer.GetFIDColumn() 135 fid = layer.GetFIDColumn()
135 - pg_layer: Layer = data_source.CreateLayer(table_name, layer.GetSpatialRef(), layer.GetGeomType()) 136 + pg_layer: Layer = data_source.CreateLayer(table_name, layer.GetSpatialRef(), layer.GetGeomType(),["ENCODING=UTF-8"])
136 schema = [sche for sche in layer.schema if not sche.name.__eq__(fid)] 137 schema = [sche for sche in layer.schema if not sche.name.__eq__(fid)]
137 138
138 pg_layer.CreateFields(schema) 139 pg_layer.CreateFields(schema)
@@ -162,6 +162,8 @@ class Api(ApiTemplate): @@ -162,6 +162,8 @@ class Api(ApiTemplate):
162 for ln in this_task_layer: 162 for ln in this_task_layer:
163 iln = task_writer.session.query(InsertingLayerName).filter_by(name=ln).one_or_none() 163 iln = task_writer.session.query(InsertingLayerName).filter_by(name=ln).one_or_none()
164 task_writer.session.delete(iln) 164 task_writer.session.delete(iln)
  165 + task_writer.update_process(e.__str__())
  166 + task_writer.update_process("任务中止!")
165 StructurePrint().print(e.__str__(), "error") 167 StructurePrint().print(e.__str__(), "error")
166 finally: 168 finally:
167 task_writer.session.commit() 169 task_writer.session.commit()
@@ -160,6 +160,7 @@ class Api(ApiTemplate): @@ -160,6 +160,7 @@ class Api(ApiTemplate):
160 StructurePrint().print(traceback.format_exc()) 160 StructurePrint().print(traceback.format_exc())
161 task_writer.update_task({"state": -1, "update_time": datetime.datetime.now(),"process":"更新失败"}) 161 task_writer.update_task({"state": -1, "update_time": datetime.datetime.now(),"process":"更新失败"})
162 task_writer.update_process(e.__str__()) 162 task_writer.update_process(e.__str__())
  163 + task_writer.update_process("任务中止!")
163 except Exception as ee: 164 except Exception as ee:
164 StructurePrint().print(traceback.format_exc()) 165 StructurePrint().print(traceback.format_exc())
165 finally: 166 finally:
@@ -114,6 +114,7 @@ class Api(ApiTemplate): @@ -114,6 +114,7 @@ class Api(ApiTemplate):
114 114
115 task_writer.update_table(table.guid,{"is_vacuate": 2, "update_time": datetime.datetime.now()}) 115 task_writer.update_table(table.guid,{"is_vacuate": 2, "update_time": datetime.datetime.now()})
116 task_writer.update_task({"state":2,"process":"精华中"}) 116 task_writer.update_task({"state":2,"process":"精华中"})
  117 + task_writer.update_process("开始精化...")
117 118
118 database = task_writer.session.query(Database).filter_by(guid=table.database_guid).one_or_none() 119 database = task_writer.session.query(Database).filter_by(guid=table.database_guid).one_or_none()
119 database_sqlalchemy_uri = str(database.sqlalchemy_uri) 120 database_sqlalchemy_uri = str(database.sqlalchemy_uri)
@@ -168,13 +169,14 @@ class Api(ApiTemplate): @@ -168,13 +169,14 @@ class Api(ApiTemplate):
168 169
169 task_writer.update_task({"state":1,"update_time":datetime.datetime.now(),"process": "精化完成"}) 170 task_writer.update_task({"state":1,"update_time":datetime.datetime.now(),"process": "精化完成"})
170 task_writer.update_table(table.guid, {"is_vacuate": 1, "update_time": datetime.datetime.now()}) 171 task_writer.update_table(table.guid, {"is_vacuate": 1, "update_time": datetime.datetime.now()})
  172 + task_writer.update_process("精化完成!")
171 173
172 except Exception as e: 174 except Exception as e:
173 try: 175 try:
174 task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "精化失败"}) 176 task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "精化失败"})
175 task_writer.update_table(table.guid, {"is_vacuate": 0, "update_time": datetime.datetime.now()}) 177 task_writer.update_table(table.guid, {"is_vacuate": 0, "update_time": datetime.datetime.now()})
176 task_writer.update_process( e.__str__()) 178 task_writer.update_process( e.__str__())
177 - 179 + task_writer.update_process("任务中止!")
178 task_writer.session.commit() 180 task_writer.session.commit()
179 181
180 if vacuate_process: 182 if vacuate_process:
@@ -100,7 +100,7 @@ class Api(ApiTemplate): @@ -100,7 +100,7 @@ class Api(ApiTemplate):
100 100
101 def task(self,table,task_guid,grids): 101 def task(self,table,task_guid,grids):
102 102
103 - task_write = None 103 + task_writer = None
104 pg_session = None 104 pg_session = None
105 pg_ds = None 105 pg_ds = None
106 vacuate_process = None 106 vacuate_process = None
@@ -110,22 +110,23 @@ class Api(ApiTemplate): @@ -110,22 +110,23 @@ class Api(ApiTemplate):
110 110
111 #任务控制,等待执行 111 #任务控制,等待执行
112 TaskController.wait(task_guid) 112 TaskController.wait(task_guid)
113 - task_write = TaskWriter(task_guid) 113 + task_writer = TaskWriter(task_guid)
114 114
115 - task_write.update_table(table.guid,{"is_vacuate": 2, "update_time": datetime.datetime.now()})  
116 - task_write.update_task({"state":2,"process":"精华中"}) 115 + task_writer.update_table(table.guid,{"is_vacuate": 2, "update_time": datetime.datetime.now()})
  116 + task_writer.update_task({"state":2,"process":"精华中"})
  117 + task_writer.update_process("开始精化...")
117 118
118 - database = task_write.session.query(Database).filter_by(guid=table.database_guid).one_or_none() 119 + database = task_writer.session.query(Database).filter_by(guid=table.database_guid).one_or_none()
119 database_sqlalchemy_uri = str(database.sqlalchemy_uri) 120 database_sqlalchemy_uri = str(database.sqlalchemy_uri)
120 pg_session = PGUtil.get_db_session(DES.decode(database_sqlalchemy_uri)) 121 pg_session = PGUtil.get_db_session(DES.decode(database_sqlalchemy_uri))
121 pg_ds :DataSource= PGUtil.open_pg_data_source(1,DES.decode(database_sqlalchemy_uri)) 122 pg_ds :DataSource= PGUtil.open_pg_data_source(1,DES.decode(database_sqlalchemy_uri))
122 123
123 #删除原有数据 124 #删除原有数据
124 for grid in grids: 125 for grid in grids:
125 - tvs = task_write.session.query(TableVacuate).filter_by(pixel_distance=grid,table_guid=table.guid).all() 126 + tvs = task_writer.session.query(TableVacuate).filter_by(pixel_distance=grid,table_guid=table.guid).all()
126 for tv in tvs : 127 for tv in tvs :
127 - task_write.session.delete(tv)  
128 - task_write.session.commit() 128 + task_writer.session.delete(tv)
  129 + task_writer.session.commit()
129 130
130 131
131 # 创建抽稀过程 132 # 创建抽稀过程
@@ -166,16 +167,17 @@ class Api(ApiTemplate): @@ -166,16 +167,17 @@ class Api(ApiTemplate):
166 name=layer_name, 167 name=layer_name,
167 pixel_distance=vacuate_process.this_gridsize[l], 168 pixel_distance=vacuate_process.this_gridsize[l],
168 connectstr=DES.encode(connectstr)) 169 connectstr=DES.encode(connectstr))
169 - task_write.session.add(table_vacuate)  
170 - task_write.update_task({"state":1,"update_time":datetime.datetime.now(),"process" : "精化完成"})  
171 - task_write.update_table(table.guid,{"is_vacuate": 1, "update_time": datetime.datetime.now()})  
172 - 170 + task_writer.session.add(table_vacuate)
  171 + task_writer.update_task({"state":1,"update_time":datetime.datetime.now(),"process" : "精化完成"})
  172 + task_writer.update_table(table.guid,{"is_vacuate": 1, "update_time": datetime.datetime.now()})
  173 + task_writer.update_process("精化完成!")
173 174
174 except Exception as e: 175 except Exception as e:
175 try: 176 try:
176 - task_write.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "精化失败"})  
177 - task_write.update_table(table.guid, {"is_vacuate": origin_vacuate, "update_time": datetime.datetime.now()})  
178 - task_write.update_process( e.__str__()) 177 + task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "精化失败"})
  178 + task_writer.update_table(table.guid, {"is_vacuate": origin_vacuate, "update_time": datetime.datetime.now()})
  179 + task_writer.update_process( e.__str__())
  180 + task_writer.update_process("任务中止!")
179 if vacuate_process: 181 if vacuate_process:
180 vacuate_process.rollback() 182 vacuate_process.rollback()
181 print(traceback.format_exc()) 183 print(traceback.format_exc())
@@ -183,7 +185,7 @@ class Api(ApiTemplate): @@ -183,7 +185,7 @@ class Api(ApiTemplate):
183 print(traceback.format_exc()) 185 print(traceback.format_exc())
184 finally: 186 finally:
185 try: 187 try:
186 - task_write.close() 188 + task_writer.close()
187 if vacuate_process: 189 if vacuate_process:
188 vacuate_process.end() 190 vacuate_process.end()
189 if pg_session: 191 if pg_session:
@@ -18,7 +18,6 @@ class Api(ApiTemplate): @@ -18,7 +18,6 @@ class Api(ApiTemplate):
18 try: 18 try:
19 task_guid = self.para.get("task_guid") 19 task_guid = self.para.get("task_guid")
20 task:Task = Task.query.filter_by(guid=task_guid).one_or_none() 20 task:Task = Task.query.filter_by(guid=task_guid).one_or_none()
21 -  
22 if not task : 21 if not task :
23 raise Exception("任务不存在!") 22 raise Exception("任务不存在!")
24 else: 23 else:
@@ -3,16 +3,16 @@ @@ -3,16 +3,16 @@
3 #createtime: 2020/9/4 3 #createtime: 2020/9/4
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 -from ..models import db,Task,Table,InsertingLayerName 6 +from ..models import db,Task,Table,InsertingLayerName,Process
7 7
8 -from app.modules.service.models import Image  
9 from app.util.component.ApiTemplate import ApiTemplate 8 from app.util.component.ApiTemplate import ApiTemplate
10 from app.util.component.StructuredPrint import StructurePrint 9 from app.util.component.StructuredPrint import StructurePrint
11 import os 10 import os
12 import signal 11 import signal
13 import platform 12 import platform
14 import json 13 import json
15 - 14 +import datetime
  15 +import uuid
16 class Api(ApiTemplate): 16 class Api(ApiTemplate):
17 api_name = "停止任务" 17 api_name = "停止任务"
18 def para_check(self): 18 def para_check(self):
@@ -37,6 +37,7 @@ class Api(ApiTemplate): @@ -37,6 +37,7 @@ class Api(ApiTemplate):
37 37
38 #处理kill任务后的事情 38 #处理kill任务后的事情
39 self.fix_task(task) 39 self.fix_task(task)
  40 +
40 res["msg"] = "Kill成功!" 41 res["msg"] = "Kill成功!"
41 res["result"] = True 42 res["result"] = True
42 except Exception as e: 43 except Exception as e:
@@ -64,9 +65,15 @@ class Api(ApiTemplate): @@ -64,9 +65,15 @@ class Api(ApiTemplate):
64 if task.task_type==4: 65 if task.task_type==4:
65 pass 66 pass
66 if task.task_type==5: 67 if task.task_type==5:
67 - Image.query.filter_by(guid=task.parameter).update({"has_pyramid":0}) 68 + pass
68 69
69 Task.query.filter_by(guid=task.guid).update({"state":-1}) 70 Task.query.filter_by(guid=task.guid).update({"state":-1})
  71 +
  72 + message = "{} 任务被强行中止!".format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
  73 + task_process = Process(guid=uuid.uuid1().__str__(), message=message, time=datetime.datetime.now(),
  74 + task_guid=task.guid)
  75 +
  76 + db.add(task_process)
70 db.session.commit() 77 db.session.commit()
71 return None 78 return None
72 79
@@ -86,7 +86,9 @@ class EntryDataVacuate: @@ -86,7 +86,9 @@ class EntryDataVacuate:
86 this_task.rollback() 86 this_task.rollback()
87 87
88 except Exception as e: 88 except Exception as e:
89 - this_task.write_process("{} 任务结束!".format(e.__str__())) 89 + this_task.write_process(e.__str__())
  90 + this_task.write_process("任务中止!")
  91 +
90 this_task.update({"state": -1, "process": "入库失败", "update_time": datetime.datetime.now()}) 92 this_task.update({"state": -1, "process": "入库失败", "update_time": datetime.datetime.now()})
91 StructurePrint().print(e.__str__(),"ERROR") 93 StructurePrint().print(e.__str__(),"ERROR")
92 # rollback 94 # rollback
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  
@@ -4,10 +4,11 @@ @@ -4,10 +4,11 @@
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 6
7 -from ..models import ServiceCatalog,db,Service 7 +from ..models import ServiceCatalog,db,Service,ServiceEngine
8 8
9 from app.util.component.ApiTemplate import ApiTemplate 9 from app.util.component.ApiTemplate import ApiTemplate
10 from app.util.component.ModelVisitor import ModelVisitor 10 from app.util.component.ModelVisitor import ModelVisitor
  11 +import requests
11 class Api(ApiTemplate): 12 class Api(ApiTemplate):
12 api_name = "下一级目录" 13 api_name = "下一级目录"
13 def process(self): 14 def process(self):
@@ -19,12 +20,28 @@ class Api(ApiTemplate): @@ -19,12 +20,28 @@ class Api(ApiTemplate):
19 20
20 res["data"] = [] 21 res["data"] = []
21 catalogs = ServiceCatalog.query.filter_by(pguid=self.para.get("catalog_guid")).all() 22 catalogs = ServiceCatalog.query.filter_by(pguid=self.para.get("catalog_guid")).all()
  23 +
  24 + # 获取全部影像服务
  25 + image_engines = ServiceEngine.query.filter_by(type="ImageServer").all()
  26 + image_services = []
  27 + for ie in image_engines:
  28 + url = "{}/API/Service/List".format(ie.url)
  29 + response:requests.Response = requests.post(url,{"page_size":1000})
  30 + if not response.json().get("result"):
  31 + raise Exception("获取影像服务List失败!")
  32 + else:
  33 + image_services.extend(response.json()["data"]["list"])
  34 +
22 for cata in catalogs: 35 for cata in catalogs:
23 catalog_guids = [c.guid for c in ServiceCatalog.query.filter(ServiceCatalog.path.like("%" + cata.guid + "%")).all()] 36 catalog_guids = [c.guid for c in ServiceCatalog.query.filter(ServiceCatalog.path.like("%" + cata.guid + "%")).all()]
24 service_count = Service.query.filter(Service.catalog_guid.in_(catalog_guids)).count() 37 service_count = Service.query.filter(Service.catalog_guid.in_(catalog_guids)).count()
25 cata_json = ModelVisitor.object_to_json(cata) 38 cata_json = ModelVisitor.object_to_json(cata)
26 - cata_json["service_count"]=service_count 39 +
  40 + image_service_count = len([igs for igs in image_services if igs["catalog_guid"] in catalog_guids])
  41 +
  42 + cata_json["service_count"]=service_count+image_service_count
27 res["data"].append(cata_json) 43 res["data"].append(cata_json)
  44 +
28 res["result"] = True 45 res["result"] = True
29 except Exception as e: 46 except Exception as e:
30 raise e 47 raise e
@@ -4,9 +4,10 @@ @@ -4,9 +4,10 @@
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 6
7 -from ..models import ServiceCatalog,Service  
8 - 7 +from ..models import ServiceCatalog,Service,ServiceEngine
9 from app.util.component.ApiTemplate import ApiTemplate 8 from app.util.component.ApiTemplate import ApiTemplate
  9 +import requests
  10 +
10 class Api(ApiTemplate): 11 class Api(ApiTemplate):
11 api_name = "目录树" 12 api_name = "目录树"
12 def process(self): 13 def process(self):
@@ -18,11 +19,26 @@ class Api(ApiTemplate): @@ -18,11 +19,26 @@ class Api(ApiTemplate):
18 19
19 catalogs = ServiceCatalog.query.all() 20 catalogs = ServiceCatalog.query.all()
20 21
  22 +
  23 + # 获取全部影像服务
  24 + image_engines = ServiceEngine.query.filter_by(type="ImageServer").all()
  25 + image_services = []
  26 + for ie in image_engines:
  27 + url = "{}/API/Service/List".format(ie.url)
  28 + response:requests.Response = requests.post(url,{"page_size":1000})
  29 + if not response.json().get("result"):
  30 + raise Exception("获取影像服务List失败!")
  31 + else:
  32 + image_services.extend(response.json()["data"]["list"])
  33 +
21 tree_origin = [] 34 tree_origin = []
22 for cata in catalogs: 35 for cata in catalogs:
  36 +
23 catalog_guids = [c.guid for c in ServiceCatalog.query.filter(ServiceCatalog.path.like("%" + cata.guid + "%")).all()] 37 catalog_guids = [c.guid for c in ServiceCatalog.query.filter(ServiceCatalog.path.like("%" + cata.guid + "%")).all()]
24 service_count = Service.query.filter(Service.catalog_guid.in_(catalog_guids)).count() 38 service_count = Service.query.filter(Service.catalog_guid.in_(catalog_guids)).count()
25 39
  40 + image_service_count = len([igs for igs in image_services if igs["catalog_guid"] in catalog_guids])
  41 +
26 cata_json ={} 42 cata_json ={}
27 43
28 cata_json["description"] = cata.description 44 cata_json["description"] = cata.description
@@ -31,7 +47,7 @@ class Api(ApiTemplate): @@ -31,7 +47,7 @@ class Api(ApiTemplate):
31 cata_json["path"] = cata.path 47 cata_json["path"] = cata.path
32 cata_json["pguid"] = cata.pguid 48 cata_json["pguid"] = cata.pguid
33 cata_json["sort"] = cata.sort 49 cata_json["sort"] = cata.sort
34 - cata_json["service_count"]=service_count 50 + cata_json["service_count"]=service_count+image_service_count
35 cata_json["children"] = [] 51 cata_json["children"] = []
36 tree_origin.append(cata_json) 52 tree_origin.append(cata_json)
37 53
@@ -4,7 +4,8 @@ @@ -4,7 +4,8 @@
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 6
7 -from ..models import Service,ServiceCatalog,db 7 +from ..models import Service,ServiceCatalog,db,ServiceEngine
  8 +import requests
8 9
9 from app.util.component.ApiTemplate import ApiTemplate 10 from app.util.component.ApiTemplate import ApiTemplate
10 class Api(ApiTemplate): 11 class Api(ApiTemplate):
@@ -17,9 +18,24 @@ class Api(ApiTemplate): @@ -17,9 +18,24 @@ class Api(ApiTemplate):
17 # 业务逻辑 18 # 业务逻辑
18 catalogs = ServiceCatalog.query.all() 19 catalogs = ServiceCatalog.query.all()
19 res["data"]=[] 20 res["data"]=[]
  21 +
  22 + # 获取全部影像服务
  23 + image_engines = ServiceEngine.query.filter_by(type="ImageServer").all()
  24 + image_services = []
  25 + for ie in image_engines:
  26 + url = "{}/API/Service/List".format(ie.url)
  27 + response:requests.Response = requests.post(url,{"page_size":1000})
  28 + if not response.json().get("result"):
  29 + raise Exception("获取影像服务List失败!")
  30 + else:
  31 + image_services.extend(response.json()["data"]["list"])
  32 +
20 for cata in catalogs: 33 for cata in catalogs:
21 catalog_guids = [c.guid for c in ServiceCatalog.query.filter(ServiceCatalog.path.like("%" + cata.guid + "%")).all()] 34 catalog_guids = [c.guid for c in ServiceCatalog.query.filter(ServiceCatalog.path.like("%" + cata.guid + "%")).all()]
22 service_count = Service.query.filter(Service.catalog_guid.in_(catalog_guids)).count() 35 service_count = Service.query.filter(Service.catalog_guid.in_(catalog_guids)).count()
  36 +
  37 + image_service_count = len([igs for igs in image_services if igs["catalog_guid"] in catalog_guids])
  38 +
23 cata_json ={} 39 cata_json ={}
24 cata_json["description"] = cata.description 40 cata_json["description"] = cata.description
25 cata_json["guid"] = cata.guid 41 cata_json["guid"] = cata.guid
@@ -27,7 +43,7 @@ class Api(ApiTemplate): @@ -27,7 +43,7 @@ class Api(ApiTemplate):
27 cata_json["path"] = cata.path 43 cata_json["path"] = cata.path
28 cata_json["pguid"] = cata.pguid 44 cata_json["pguid"] = cata.pguid
29 cata_json["sort"] = cata.sort 45 cata_json["sort"] = cata.sort
30 - cata_json["service_count"]=service_count 46 + cata_json["service_count"] = service_count + image_service_count
31 res["data"].append(cata_json) 47 res["data"].append(cata_json)
32 48
33 res["result"] = True 49 res["result"] = True
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/12/13
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from flasgger import swag_from
  8 +from flask import Blueprint
  9 +from app.util import BlueprintApi
  10 +from . import service_engine_register
  11 +from . import service_engine_delete
  12 +from . import service_engine_edit
  13 +from . import service_engine_list
  14 +from . import service_engine_info
  15 +
  16 +class EngineManager(BlueprintApi):
  17 +
  18 + bp = Blueprint("Engine", __name__, url_prefix="/API/Service/Engine")
  19 +
  20 + @staticmethod
  21 + @bp.route('/Register', methods=['POST'])
  22 + @swag_from(service_engine_register.Api.api_doc)
  23 + def service_engine_register():
  24 + """
  25 + Engine Register
  26 + """
  27 + return service_engine_register.Api().result
  28 +
  29 + @staticmethod
  30 + @bp.route('/List', methods=['POST'])
  31 + @swag_from(service_engine_list.Api.api_doc)
  32 + def service_engine_list():
  33 + """
  34 + Engine List
  35 + """
  36 + return service_engine_list.Api().result
  37 +
  38 + @staticmethod
  39 + @bp.route('/Info', methods=['POST'])
  40 + @swag_from(service_engine_info.Api.api_doc)
  41 + def service_engine_info():
  42 + """
  43 + Engine Info
  44 + """
  45 + return service_engine_info.Api().result
  46 +
  47 + @staticmethod
  48 + @bp.route('/Edit', methods=['POST'])
  49 + @swag_from(service_engine_edit.Api.api_doc)
  50 + def service_engine_edit():
  51 + """
  52 + Engine Edit
  53 + """
  54 + return service_engine_edit.Api().result
  55 +
  56 +
  57 + @staticmethod
  58 + @bp.route('/Delete', methods=['POST'])
  59 + @swag_from(service_engine_delete.Api.api_doc)
  60 + def service_engine_delete():
  61 + """
  62 + Engine Delete
  63 + """
  64 + return service_engine_delete.Api().result
1 # coding=utf-8 1 # coding=utf-8
2 #author: 4N 2 #author: 4N
3 -#createtime: 2021/7/19 3 +#createtime: 2021/9/14
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 from app.util.component.ApiTemplate import ApiTemplate 6 from app.util.component.ApiTemplate import ApiTemplate
7 -from app.models import db  
8 -from ..models import Image 7 +from app.modules.service.models import ServiceEngine,db
9 class Api(ApiTemplate): 8 class Api(ApiTemplate):
10 -  
11 - api_name = "删除影像数据"  
12 - 9 + api_name = "注销服务引擎"
13 def process(self): 10 def process(self):
14 -  
15 res = {} 11 res = {}
16 -  
17 try: 12 try:
18 guid = self.para.get("guid") 13 guid = self.para.get("guid")
19 - image = Image.query.filter_by(guid=guid).one_or_none()  
20 - db.session.delete(image) 14 + service_engine = ServiceEngine.query.filter_by(guid=guid).one_or_none()
  15 + if not service_engine:
  16 + raise Exception("服务不存在!")
  17 + db.session.delete(service_engine)
21 db.session.commit() 18 db.session.commit()
22 res["result"] = True 19 res["result"] = True
23 -  
24 except Exception as e: 20 except Exception as e:
25 raise e 21 raise e
26 -  
27 return res 22 return res
28 23
29 api_doc = { 24 api_doc = {
30 - "tags": ["影像接口"], 25 + "tags": ["引擎接口"],
31 "parameters": [ 26 "parameters": [
32 {"name": "guid", 27 {"name": "guid",
33 "in": "formData", 28 "in": "formData",
34 - "type": "string"} 29 + "type": "string",
  30 + "description": "guid"},
35 ], 31 ],
36 "responses": { 32 "responses": {
37 200: { 33 200: {
@@ -41,6 +37,4 @@ class Api(ApiTemplate): @@ -41,6 +37,4 @@ class Api(ApiTemplate):
41 } 37 }
42 } 38 }
43 } 39 }
44 - }  
45 -  
46 - 40 + }
1 # coding=utf-8 1 # coding=utf-8
2 #author: 4N 2 #author: 4N
3 -#createtime: 2021/9/8 3 +#createtime: 2021/9/14
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 -  
7 from app.util.component.ApiTemplate import ApiTemplate 6 from app.util.component.ApiTemplate import ApiTemplate
8 -from ..models import ImageTag  
9 -import uuid  
10 -from app.models import db 7 +import requests
  8 +from app.modules.service.models import ServiceEngine,db
11 class Api(ApiTemplate): 9 class Api(ApiTemplate):
12 -  
13 - api_name = "create tag"  
14 - 10 + api_name = "修改服务引擎"
15 def process(self): 11 def process(self):
16 -  
17 - # 返回结果  
18 res = {} 12 res = {}
19 try: 13 try:
20 - tag_guid = uuid.uuid1().__str__()  
21 14
22 - image_tag = ImageTag(guid=tag_guid,name=self.para.get("name"))  
23 - db.session.add(image_tag) 15 + udpate = {}
  16 + guid = self.para.get("guid")
  17 +
  18 + for key in self.para.keys():
  19 + if key in ["name","url","out_url"]:
  20 + udpate[key] = self.para.get(key)
  21 +
  22 + ServiceEngine.query.filter_by(guid=guid).update(udpate)
24 db.session.commit() 23 db.session.commit()
25 - res["data"] = tag_guid  
26 res["result"] = True 24 res["result"] = True
27 except Exception as e: 25 except Exception as e:
28 raise e 26 raise e
29 return res 27 return res
30 28
  29 +
31 api_doc = { 30 api_doc = {
32 - "tags": ["影像接口"], 31 + "tags": ["引擎接口"],
33 "parameters": [ 32 "parameters": [
  33 + {"name": "guid",
  34 + "in": "formData",
  35 + "type": "string",
  36 + "description": "guid"},
34 {"name": "name", 37 {"name": "name",
35 "in": "formData", 38 "in": "formData",
36 "type": "string"}, 39 "type": "string"},
  40 + {"name": "url",
  41 + "in": "formData",
  42 + "type": "string"},
  43 + {"name": "out_url",
  44 + "in": "formData",
  45 + "type": "string"},
  46 +
37 ], 47 ],
38 "responses": { 48 "responses": {
39 200: { 49 200: {
1 # coding=utf-8 1 # coding=utf-8
2 #author: 4N 2 #author: 4N
3 -#createtime: 2021/9/8 3 +#createtime: 2021/9/14
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 -  
7 from app.util.component.ApiTemplate import ApiTemplate 6 from app.util.component.ApiTemplate import ApiTemplate
8 -from app.models import db  
9 -from ..models import ImageTag  
10 -class Api(ApiTemplate):  
11 -  
12 - api_name = "delete tag" 7 +from app.modules.service.models import ServiceEngine
  8 +from app.util.component.ModelVisitor import ModelVisitor
13 9
  10 +class Api(ApiTemplate):
  11 + api_name = "服务引擎Info"
14 def process(self): 12 def process(self):
15 -  
16 - # 返回结果  
17 res = {} 13 res = {}
18 try: 14 try:
19 - image_tag = ImageTag.query.filter_by(guid=self.para.get("guid")).one_or_none()  
20 - if image_tag:  
21 - db.session.delete(image_tag)  
22 - db.session.commit() 15 + guid = self.para.get("guid")
  16 + service_engine = ServiceEngine.query.filter_by(guid=guid).one_or_none()
  17 + if not service_engine:
  18 + raise Exception("服务引擎不存在!")
  19 +
  20 + res["data"] = ModelVisitor.object_to_json(service_engine)
23 res["result"] = True 21 res["result"] = True
24 except Exception as e: 22 except Exception as e:
25 raise e 23 raise e
26 return res 24 return res
27 25
  26 +
28 api_doc = { 27 api_doc = {
29 - "tags": ["影像接口"], 28 + "tags": ["引擎接口"],
30 "parameters": [ 29 "parameters": [
31 {"name": "guid", 30 {"name": "guid",
32 "in": "formData", 31 "in": "formData",
1 # coding=utf-8 1 # coding=utf-8
2 #author: 4N 2 #author: 4N
3 -#createtime: 2021/7/19 3 +#createtime: 2021/9/14
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 -  
7 from app.util.component.ApiTemplate import ApiTemplate 6 from app.util.component.ApiTemplate import ApiTemplate
  7 +from app.modules.service.models import ServiceEngine
8 from app.util.component.ModelVisitor import ModelVisitor 8 from app.util.component.ModelVisitor import ModelVisitor
9 9
10 -from app.modules.service.models import Image,ImageTag  
11 -from app.util.component.FileProcess import FileProcess  
12 -  
13 class Api(ApiTemplate): 10 class Api(ApiTemplate):
14 -  
15 - api_name = "影像数据Info"  
16 - 11 + api_name = "服务引擎List"
17 def process(self): 12 def process(self):
18 -  
19 - # 返回结果  
20 res = {} 13 res = {}
21 try: 14 try:
22 -  
23 - guid = self.para.get("guid")  
24 -  
25 - image = Image.query.filter_by(guid=guid).one_or_none()  
26 - if not image:  
27 - raise Exception("数据不存在!")  
28 - tags:ImageTag = image.image_tags  
29 - # tag_names = [tag.name for tag in tags]  
30 -  
31 - res["data"] = ModelVisitor.object_to_json(image)  
32 -  
33 - #格式化数据  
34 -  
35 - res["data"]["size"] = FileProcess.get_text_size(res["data"]["size"])  
36 - res["data"]["cell_x_size"] = round(res["data"]["cell_x_size"],3)  
37 - res["data"]["cell_y_size"] = round(res["data"]["cell_y_size"], 3)  
38 -  
39 - res["data"]["image_tags"] = ModelVisitor.objects_to_jsonarray(tags)  
40 - res["result"] = True 15 + page_index = int(self.para.get("page_index", "0"))
  16 + page_size = int(self.para.get("page_size", "10"))
  17 + name = self.para.get("name")
  18 + s_type = self.para.get("type")
  19 +
  20 + service_engines = ServiceEngine.query
  21 + if name:
  22 + service_engines = service_engines.filter(ServiceEngine.name.like("%" + name + "%"))
  23 + if s_type:
  24 + service_engines = service_engines.filter_by(type=s_type)
  25 + res["data"] = {}
  26 + res["data"]["count"] = service_engines.count()
  27 + service_engines = service_engines.limit(page_size).offset(page_index * page_size).all()
  28 + res["data"]["list"] = ModelVisitor.objects_to_jsonarray(service_engines)
41 except Exception as e: 29 except Exception as e:
42 raise e 30 raise e
43 -  
44 return res 31 return res
45 32
46 33
47 api_doc = { 34 api_doc = {
48 - "tags": ["影像接口"], 35 + "tags": ["引擎接口"],
49 "parameters": [ 36 "parameters": [
50 - {"name": "guid", 37 + {"name": "page_index",
  38 + "in": "formData",
  39 + "type": "int",
  40 + "description": "页"},
  41 + {"name": "page_size",
  42 + "in": "formData",
  43 + "type": "int",
  44 + "description": "页大小"},
  45 + {"name": "name",
51 "in": "formData", 46 "in": "formData",
52 "type": "string"}, 47 "type": "string"},
  48 + {"name": "type",
  49 + "in": "formData",
  50 + "type": "string",
  51 + "enum":["ImageServer"]},
53 ], 52 ],
54 "responses": { 53 "responses": {
55 200: { 54 200: {
@@ -59,6 +58,4 @@ class Api(ApiTemplate): @@ -59,6 +58,4 @@ class Api(ApiTemplate):
59 } 58 }
60 } 59 }
61 } 60 }
62 - }  
63 -  
64 - 61 + }
1 # coding=utf-8 1 # coding=utf-8
2 #author: 4N 2 #author: 4N
3 -#createtime: 2021/7/19 3 +#createtime: 2021/9/14
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 -  
7 from app.util.component.ApiTemplate import ApiTemplate 6 from app.util.component.ApiTemplate import ApiTemplate
8 -import json  
9 -from ..models import Image 7 +import requests
  8 +from app.modules.service.models import ServiceEngine,db
10 import datetime 9 import datetime
11 -from app.models import db  
12 - 10 +import uuid
13 11
14 class Api(ApiTemplate): 12 class Api(ApiTemplate):
15 -  
16 - api_name = "注册影像数据"  
17 - 13 + api_name = "注册服务引擎"
18 def process(self): 14 def process(self):
19 -  
20 - #可以注册一个目录  
21 - #返回结果  
22 res = {} 15 res = {}
23 -  
24 try: 16 try:
25 - data_server = self.para.get("data_server")  
26 - paths = json.loads(self.para.get("paths"))  
27 -  
28 - for path in paths:  
29 -  
30 - exist_image:Image = Image.query.filter_by(path=path.get("path"),  
31 - size=path.get("real_size")).one_or_none()  
32 - if exist_image:  
33 - servers = exist_image.server.split(",")  
34 - leave_servers = [ser for ser in servers if not ser.__eq__(data_server)]  
35 - if len(leave_servers) ==0:  
36 - db.session.delete(exist_image)  
37 - else:  
38 - Image.query.filter_by(path=path.get("path"),  
39 - size=path.get("real_size")).update({"server":",".join(leave_servers),  
40 - "update_time":datetime.datetime.now()})  
41 - else:  
42 - raise Exception("数据不存在!")  
43 - 17 + url = self.para.get("url")
  18 + name = self.para.get("name")
  19 + response:requests.Response = requests.get(url)
  20 + if response.status_code != 200:
  21 + raise Exception("服务引擎连接失败!")
  22 + service_engine = ServiceEngine(guid=uuid.uuid1().__str__(),
  23 + name=name if name else response.json().get("Name"),
  24 + url=url,
  25 + type=response.json().get("Type"),
  26 + create_time=datetime.datetime.now()
  27 + )
  28 + db.session.add(service_engine)
44 db.session.commit() 29 db.session.commit()
45 res["result"] = True 30 res["result"] = True
46 -  
47 except Exception as e: 31 except Exception as e:
48 - raise e  
49 - 32 + raise Exception("引擎已注册!")
50 return res 33 return res
51 34
52 35
53 api_doc = { 36 api_doc = {
54 - "tags": ["影像接口"], 37 + "tags": ["引擎接口"],
55 "parameters": [ 38 "parameters": [
56 - {"name": "data_server", 39 + {"name": "url",
57 "in": "formData", 40 "in": "formData",
58 "type": "string", 41 "type": "string",
59 - "description": "data_server"},  
60 - {"name": "paths", 42 + "description": "服务地址"},
  43 + {"name": "name",
61 "in": "formData", 44 "in": "formData",
62 "type": "string", 45 "type": "string",
63 - "description": "paths"}, 46 + "description": "name"},
64 ], 47 ],
65 "responses": { 48 "responses": {
66 200: { 49 200: {
@@ -70,6 +53,4 @@ class Api(ApiTemplate): @@ -70,6 +53,4 @@ class Api(ApiTemplate):
70 } 53 }
71 } 54 }
72 } 55 }
73 - }  
74 -  
75 - 56 + }
1 -#!/usr/bin/env python  
2 -#  
3 -# Autogenerated by Thrift Compiler (0.14.2)  
4 -#  
5 -# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING  
6 -#  
7 -# options string: py  
8 -#  
9 -  
10 -import sys  
11 -import pprint  
12 -if sys.version_info[0] > 2:  
13 - from urllib.parse import urlparse  
14 -else:  
15 - from urlparse import urlparse  
16 -from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient  
17 -from thrift.protocol.TBinaryProtocol import TBinaryProtocol  
18 -  
19 -from app.modules.image.ImageDataService import ImageDataService  
20 -from app.modules.image.ImageDataService.ttypes import *  
21 -  
22 -if len(sys.argv) <= 1 or sys.argv[1] == '--help':  
23 - print('')  
24 - print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function [arg1 [arg2...]]')  
25 - print('')  
26 - print('Functions:')  
27 - print(' string getData(string path, queryRange, originRange, bands, i32 width, i32 height)')  
28 - print(' string getInfo(string path)')  
29 - print(' bool buildOverview(string path)')  
30 - print(' string getImageList(string path)')  
31 - print('')  
32 - sys.exit(0)  
33 -  
34 -pp = pprint.PrettyPrinter(indent=2)  
35 -host = 'localhost'  
36 -port = 9090  
37 -uri = ''  
38 -framed = False  
39 -ssl = False  
40 -validate = True  
41 -ca_certs = None  
42 -keyfile = None  
43 -certfile = None  
44 -http = False  
45 -argi = 1  
46 -  
47 -if sys.argv[argi] == '-h':  
48 - parts = sys.argv[argi + 1].split(':')  
49 - host = parts[0]  
50 - if len(parts) > 1:  
51 - port = int(parts[1])  
52 - argi += 2  
53 -  
54 -if sys.argv[argi] == '-u':  
55 - url = urlparse(sys.argv[argi + 1])  
56 - parts = url[1].split(':')  
57 - host = parts[0]  
58 - if len(parts) > 1:  
59 - port = int(parts[1])  
60 - else:  
61 - port = 80  
62 - uri = url[2]  
63 - if url[4]:  
64 - uri += '?%s' % url[4]  
65 - http = True  
66 - argi += 2  
67 -  
68 -if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':  
69 - framed = True  
70 - argi += 1  
71 -  
72 -if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':  
73 - ssl = True  
74 - argi += 1  
75 -  
76 -if sys.argv[argi] == '-novalidate':  
77 - validate = False  
78 - argi += 1  
79 -  
80 -if sys.argv[argi] == '-ca_certs':  
81 - ca_certs = sys.argv[argi+1]  
82 - argi += 2  
83 -  
84 -if sys.argv[argi] == '-keyfile':  
85 - keyfile = sys.argv[argi+1]  
86 - argi += 2  
87 -  
88 -if sys.argv[argi] == '-certfile':  
89 - certfile = sys.argv[argi+1]  
90 - argi += 2  
91 -  
92 -cmd = sys.argv[argi]  
93 -args = sys.argv[argi + 1:]  
94 -  
95 -if http:  
96 - transport = THttpClient.THttpClient(host, port, uri)  
97 -else:  
98 - if ssl:  
99 - socket = TSSLSocket.TSSLSocket(host, port, validate=validate, ca_certs=ca_certs, keyfile=keyfile, certfile=certfile)  
100 - else:  
101 - socket = TSocket.TSocket(host, port)  
102 - if framed:  
103 - transport = TTransport.TFramedTransport(socket)  
104 - else:  
105 - transport = TTransport.TBufferedTransport(socket)  
106 -protocol = TBinaryProtocol(transport)  
107 -client = ImageDataService.Client(protocol)  
108 -transport.open()  
109 -  
110 -if cmd == 'getData':  
111 - if len(args) != 6:  
112 - print('getData requires 6 args')  
113 - sys.exit(1)  
114 - pp.pprint(client.getData(args[0], eval(args[1]), eval(args[2]), eval(args[3]), eval(args[4]), eval(args[5]),))  
115 -  
116 -elif cmd == 'getInfo':  
117 - if len(args) != 1:  
118 - print('getInfo requires 1 args')  
119 - sys.exit(1)  
120 - pp.pprint(client.getInfo(args[0],))  
121 -  
122 -elif cmd == 'buildOverview':  
123 - if len(args) != 1:  
124 - print('buildOverview requires 1 args')  
125 - sys.exit(1)  
126 - pp.pprint(client.buildOverview(args[0],))  
127 -  
128 -elif cmd == 'getImageList':  
129 - if len(args) != 1:  
130 - print('getImageList requires 1 args')  
131 - sys.exit(1)  
132 - pp.pprint(client.getImageList(args[0],))  
133 -  
134 -else:  
135 - print('Unrecognized method %s' % cmd)  
136 - sys.exit(1)  
137 -  
138 -transport.close()  
1 -#  
2 -# Autogenerated by Thrift Compiler (0.14.2)  
3 -#  
4 -# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING  
5 -#  
6 -# options string: py  
7 -#  
8 -  
9 -from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException  
10 -from thrift.protocol.TProtocol import TProtocolException  
11 -from thrift.TRecursive import fix_spec  
12 -  
13 -import sys  
14 -import logging  
15 -from .ttypes import *  
16 -from thrift.Thrift import TProcessor  
17 -from thrift.transport import TTransport  
18 -all_structs = []  
19 -  
20 -  
21 -class Iface(object):  
22 - def getData(self, path, queryRange, originRange, bands, width, height):  
23 - """  
24 - Parameters:  
25 - - path  
26 - - queryRange  
27 - - originRange  
28 - - bands  
29 - - width  
30 - - height  
31 -  
32 - """  
33 - pass  
34 -  
35 - def getInfo(self, path):  
36 - """  
37 - Parameters:  
38 - - path  
39 -  
40 - """  
41 - pass  
42 -  
43 - def buildOverview(self, path):  
44 - """  
45 - Parameters:  
46 - - path  
47 -  
48 - """  
49 - pass  
50 -  
51 - def getImageList(self, path):  
52 - """  
53 - Parameters:  
54 - - path  
55 -  
56 - """  
57 - pass  
58 -  
59 -  
60 -class Client(Iface):  
61 - def __init__(self, iprot, oprot=None):  
62 - self._iprot = self._oprot = iprot  
63 - if oprot is not None:  
64 - self._oprot = oprot  
65 - self._seqid = 0  
66 -  
67 - def getData(self, path, queryRange, originRange, bands, width, height):  
68 - """  
69 - Parameters:  
70 - - path  
71 - - queryRange  
72 - - originRange  
73 - - bands  
74 - - width  
75 - - height  
76 -  
77 - """  
78 - self.send_getData(path, queryRange, originRange, bands, width, height)  
79 - return self.recv_getData()  
80 -  
81 - def send_getData(self, path, queryRange, originRange, bands, width, height):  
82 - self._oprot.writeMessageBegin('getData', TMessageType.CALL, self._seqid)  
83 - args = getData_args()  
84 - args.path = path  
85 - args.queryRange = queryRange  
86 - args.originRange = originRange  
87 - args.bands = bands  
88 - args.width = width  
89 - args.height = height  
90 - args.write(self._oprot)  
91 - self._oprot.writeMessageEnd()  
92 - self._oprot.trans.flush()  
93 -  
94 - def recv_getData(self):  
95 - iprot = self._iprot  
96 - (fname, mtype, rseqid) = iprot.readMessageBegin()  
97 - if mtype == TMessageType.EXCEPTION:  
98 - x = TApplicationException()  
99 - x.read(iprot)  
100 - iprot.readMessageEnd()  
101 - raise x  
102 - result = getData_result()  
103 - result.read(iprot)  
104 - iprot.readMessageEnd()  
105 - if result.success is not None:  
106 - return result.success  
107 - raise TApplicationException(TApplicationException.MISSING_RESULT, "getData failed: unknown result")  
108 -  
109 - def getInfo(self, path):  
110 - """  
111 - Parameters:  
112 - - path  
113 -  
114 - """  
115 - self.send_getInfo(path)  
116 - return self.recv_getInfo()  
117 -  
118 - def send_getInfo(self, path):  
119 - self._oprot.writeMessageBegin('getInfo', TMessageType.CALL, self._seqid)  
120 - args = getInfo_args()  
121 - args.path = path  
122 - args.write(self._oprot)  
123 - self._oprot.writeMessageEnd()  
124 - self._oprot.trans.flush()  
125 -  
126 - def recv_getInfo(self):  
127 - iprot = self._iprot  
128 - (fname, mtype, rseqid) = iprot.readMessageBegin()  
129 - if mtype == TMessageType.EXCEPTION:  
130 - x = TApplicationException()  
131 - x.read(iprot)  
132 - iprot.readMessageEnd()  
133 - raise x  
134 - result = getInfo_result()  
135 - result.read(iprot)  
136 - iprot.readMessageEnd()  
137 - if result.success is not None:  
138 - return result.success  
139 - raise TApplicationException(TApplicationException.MISSING_RESULT, "getInfo failed: unknown result")  
140 -  
141 - def buildOverview(self, path):  
142 - """  
143 - Parameters:  
144 - - path  
145 -  
146 - """  
147 - self.send_buildOverview(path)  
148 - return self.recv_buildOverview()  
149 -  
150 - def send_buildOverview(self, path):  
151 - self._oprot.writeMessageBegin('buildOverview', TMessageType.CALL, self._seqid)  
152 - args = buildOverview_args()  
153 - args.path = path  
154 - args.write(self._oprot)  
155 - self._oprot.writeMessageEnd()  
156 - self._oprot.trans.flush()  
157 -  
158 - def recv_buildOverview(self):  
159 - iprot = self._iprot  
160 - (fname, mtype, rseqid) = iprot.readMessageBegin()  
161 - if mtype == TMessageType.EXCEPTION:  
162 - x = TApplicationException()  
163 - x.read(iprot)  
164 - iprot.readMessageEnd()  
165 - raise x  
166 - result = buildOverview_result()  
167 - result.read(iprot)  
168 - iprot.readMessageEnd()  
169 - if result.success is not None:  
170 - return result.success  
171 - raise TApplicationException(TApplicationException.MISSING_RESULT, "buildOverview failed: unknown result")  
172 -  
173 - def getImageList(self, path):  
174 - """  
175 - Parameters:  
176 - - path  
177 -  
178 - """  
179 - self.send_getImageList(path)  
180 - return self.recv_getImageList()  
181 -  
182 - def send_getImageList(self, path):  
183 - self._oprot.writeMessageBegin('getImageList', TMessageType.CALL, self._seqid)  
184 - args = getImageList_args()  
185 - args.path = path  
186 - args.write(self._oprot)  
187 - self._oprot.writeMessageEnd()  
188 - self._oprot.trans.flush()  
189 -  
190 - def recv_getImageList(self):  
191 - iprot = self._iprot  
192 - (fname, mtype, rseqid) = iprot.readMessageBegin()  
193 - if mtype == TMessageType.EXCEPTION:  
194 - x = TApplicationException()  
195 - x.read(iprot)  
196 - iprot.readMessageEnd()  
197 - raise x  
198 - result = getImageList_result()  
199 - result.read(iprot)  
200 - iprot.readMessageEnd()  
201 - if result.success is not None:  
202 - return result.success  
203 - raise TApplicationException(TApplicationException.MISSING_RESULT, "getImageList failed: unknown result")  
204 -  
205 -  
206 -class Processor(Iface, TProcessor):  
207 - def __init__(self, handler):  
208 - self._handler = handler  
209 - self._processMap = {}  
210 - self._processMap["getData"] = Processor.process_getData  
211 - self._processMap["getInfo"] = Processor.process_getInfo  
212 - self._processMap["buildOverview"] = Processor.process_buildOverview  
213 - self._processMap["getImageList"] = Processor.process_getImageList  
214 - self._on_message_begin = None  
215 -  
216 - def on_message_begin(self, func):  
217 - self._on_message_begin = func  
218 -  
219 - def process(self, iprot, oprot):  
220 - (name, type, seqid) = iprot.readMessageBegin()  
221 - if self._on_message_begin:  
222 - self._on_message_begin(name, type, seqid)  
223 - if name not in self._processMap:  
224 - iprot.skip(TType.STRUCT)  
225 - iprot.readMessageEnd()  
226 - x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))  
227 - oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)  
228 - x.write(oprot)  
229 - oprot.writeMessageEnd()  
230 - oprot.trans.flush()  
231 - return  
232 - else:  
233 - self._processMap[name](self, seqid, iprot, oprot)  
234 - return True  
235 -  
236 - def process_getData(self, seqid, iprot, oprot):  
237 - args = getData_args()  
238 - args.read(iprot)  
239 - iprot.readMessageEnd()  
240 - result = getData_result()  
241 - try:  
242 - result.success = self._handler.getData(args.path, args.queryRange, args.originRange, args.bands, args.width, args.height)  
243 - msg_type = TMessageType.REPLY  
244 - except TTransport.TTransportException:  
245 - raise  
246 - except TApplicationException as ex:  
247 - logging.exception('TApplication exception in handler')  
248 - msg_type = TMessageType.EXCEPTION  
249 - result = ex  
250 - except Exception:  
251 - logging.exception('Unexpected exception in handler')  
252 - msg_type = TMessageType.EXCEPTION  
253 - result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')  
254 - oprot.writeMessageBegin("getData", msg_type, seqid)  
255 - result.write(oprot)  
256 - oprot.writeMessageEnd()  
257 - oprot.trans.flush()  
258 -  
259 - def process_getInfo(self, seqid, iprot, oprot):  
260 - args = getInfo_args()  
261 - args.read(iprot)  
262 - iprot.readMessageEnd()  
263 - result = getInfo_result()  
264 - try:  
265 - result.success = self._handler.getInfo(args.path)  
266 - msg_type = TMessageType.REPLY  
267 - except TTransport.TTransportException:  
268 - raise  
269 - except TApplicationException as ex:  
270 - logging.exception('TApplication exception in handler')  
271 - msg_type = TMessageType.EXCEPTION  
272 - result = ex  
273 - except Exception:  
274 - logging.exception('Unexpected exception in handler')  
275 - msg_type = TMessageType.EXCEPTION  
276 - result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')  
277 - oprot.writeMessageBegin("getInfo", msg_type, seqid)  
278 - result.write(oprot)  
279 - oprot.writeMessageEnd()  
280 - oprot.trans.flush()  
281 -  
282 - def process_buildOverview(self, seqid, iprot, oprot):  
283 - args = buildOverview_args()  
284 - args.read(iprot)  
285 - iprot.readMessageEnd()  
286 - result = buildOverview_result()  
287 - try:  
288 - result.success = self._handler.buildOverview(args.path)  
289 - msg_type = TMessageType.REPLY  
290 - except TTransport.TTransportException:  
291 - raise  
292 - except TApplicationException as ex:  
293 - logging.exception('TApplication exception in handler')  
294 - msg_type = TMessageType.EXCEPTION  
295 - result = ex  
296 - except Exception:  
297 - logging.exception('Unexpected exception in handler')  
298 - msg_type = TMessageType.EXCEPTION  
299 - result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')  
300 - oprot.writeMessageBegin("buildOverview", msg_type, seqid)  
301 - result.write(oprot)  
302 - oprot.writeMessageEnd()  
303 - oprot.trans.flush()  
304 -  
305 - def process_getImageList(self, seqid, iprot, oprot):  
306 - args = getImageList_args()  
307 - args.read(iprot)  
308 - iprot.readMessageEnd()  
309 - result = getImageList_result()  
310 - try:  
311 - result.success = self._handler.getImageList(args.path)  
312 - msg_type = TMessageType.REPLY  
313 - except TTransport.TTransportException:  
314 - raise  
315 - except TApplicationException as ex:  
316 - logging.exception('TApplication exception in handler')  
317 - msg_type = TMessageType.EXCEPTION  
318 - result = ex  
319 - except Exception:  
320 - logging.exception('Unexpected exception in handler')  
321 - msg_type = TMessageType.EXCEPTION  
322 - result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')  
323 - oprot.writeMessageBegin("getImageList", msg_type, seqid)  
324 - result.write(oprot)  
325 - oprot.writeMessageEnd()  
326 - oprot.trans.flush()  
327 -  
328 -# HELPER FUNCTIONS AND STRUCTURES  
329 -  
330 -  
331 -class getData_args(object):  
332 - """  
333 - Attributes:  
334 - - path  
335 - - queryRange  
336 - - originRange  
337 - - bands  
338 - - width  
339 - - height  
340 -  
341 - """  
342 -  
343 -  
344 - def __init__(self, path=None, queryRange=None, originRange=None, bands=None, width=None, height=None,):  
345 - self.path = path  
346 - self.queryRange = queryRange  
347 - self.originRange = originRange  
348 - self.bands = bands  
349 - self.width = width  
350 - self.height = height  
351 -  
352 - def read(self, iprot):  
353 - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:  
354 - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])  
355 - return  
356 - iprot.readStructBegin()  
357 - while True:  
358 - (fname, ftype, fid) = iprot.readFieldBegin()  
359 - if ftype == TType.STOP:  
360 - break  
361 - if fid == 1:  
362 - if ftype == TType.STRING:  
363 - self.path = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()  
364 - else:  
365 - iprot.skip(ftype)  
366 - elif fid == 2:  
367 - if ftype == TType.LIST:  
368 - self.queryRange = []  
369 - (_etype3, _size0) = iprot.readListBegin()  
370 - for _i4 in range(_size0):  
371 - _elem5 = iprot.readDouble()  
372 - self.queryRange.append(_elem5)  
373 - iprot.readListEnd()  
374 - else:  
375 - iprot.skip(ftype)  
376 - elif fid == 3:  
377 - if ftype == TType.LIST:  
378 - self.originRange = []  
379 - (_etype9, _size6) = iprot.readListBegin()  
380 - for _i10 in range(_size6):  
381 - _elem11 = iprot.readDouble()  
382 - self.originRange.append(_elem11)  
383 - iprot.readListEnd()  
384 - else:  
385 - iprot.skip(ftype)  
386 - elif fid == 4:  
387 - if ftype == TType.LIST:  
388 - self.bands = []  
389 - (_etype15, _size12) = iprot.readListBegin()  
390 - for _i16 in range(_size12):  
391 - _elem17 = iprot.readI32()  
392 - self.bands.append(_elem17)  
393 - iprot.readListEnd()  
394 - else:  
395 - iprot.skip(ftype)  
396 - elif fid == 5:  
397 - if ftype == TType.I32:  
398 - self.width = iprot.readI32()  
399 - else:  
400 - iprot.skip(ftype)  
401 - elif fid == 6:  
402 - if ftype == TType.I32:  
403 - self.height = iprot.readI32()  
404 - else:  
405 - iprot.skip(ftype)  
406 - else:  
407 - iprot.skip(ftype)  
408 - iprot.readFieldEnd()  
409 - iprot.readStructEnd()  
410 -  
411 - def write(self, oprot):  
412 - if oprot._fast_encode is not None and self.thrift_spec is not None:  
413 - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))  
414 - return  
415 - oprot.writeStructBegin('getData_args')  
416 - if self.path is not None:  
417 - oprot.writeFieldBegin('path', TType.STRING, 1)  
418 - oprot.writeString(self.path.encode('utf-8') if sys.version_info[0] == 2 else self.path)  
419 - oprot.writeFieldEnd()  
420 - if self.queryRange is not None:  
421 - oprot.writeFieldBegin('queryRange', TType.LIST, 2)  
422 - oprot.writeListBegin(TType.DOUBLE, len(self.queryRange))  
423 - for iter18 in self.queryRange:  
424 - oprot.writeDouble(iter18)  
425 - oprot.writeListEnd()  
426 - oprot.writeFieldEnd()  
427 - if self.originRange is not None:  
428 - oprot.writeFieldBegin('originRange', TType.LIST, 3)  
429 - oprot.writeListBegin(TType.DOUBLE, len(self.originRange))  
430 - for iter19 in self.originRange:  
431 - oprot.writeDouble(iter19)  
432 - oprot.writeListEnd()  
433 - oprot.writeFieldEnd()  
434 - if self.bands is not None:  
435 - oprot.writeFieldBegin('bands', TType.LIST, 4)  
436 - oprot.writeListBegin(TType.I32, len(self.bands))  
437 - for iter20 in self.bands:  
438 - oprot.writeI32(iter20)  
439 - oprot.writeListEnd()  
440 - oprot.writeFieldEnd()  
441 - if self.width is not None:  
442 - oprot.writeFieldBegin('width', TType.I32, 5)  
443 - oprot.writeI32(self.width)  
444 - oprot.writeFieldEnd()  
445 - if self.height is not None:  
446 - oprot.writeFieldBegin('height', TType.I32, 6)  
447 - oprot.writeI32(self.height)  
448 - oprot.writeFieldEnd()  
449 - oprot.writeFieldStop()  
450 - oprot.writeStructEnd()  
451 -  
452 - def validate(self):  
453 - return  
454 -  
455 - def __repr__(self):  
456 - L = ['%s=%r' % (key, value)  
457 - for key, value in self.__dict__.items()]  
458 - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))  
459 -  
460 - def __eq__(self, other):  
461 - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__  
462 -  
463 - def __ne__(self, other):  
464 - return not (self == other)  
465 -all_structs.append(getData_args)  
466 -getData_args.thrift_spec = (  
467 - None, # 0  
468 - (1, TType.STRING, 'path', 'UTF8', None, ), # 1  
469 - (2, TType.LIST, 'queryRange', (TType.DOUBLE, None, False), None, ), # 2  
470 - (3, TType.LIST, 'originRange', (TType.DOUBLE, None, False), None, ), # 3  
471 - (4, TType.LIST, 'bands', (TType.I32, None, False), None, ), # 4  
472 - (5, TType.I32, 'width', None, None, ), # 5  
473 - (6, TType.I32, 'height', None, None, ), # 6  
474 -)  
475 -  
476 -  
477 -class getData_result(object):  
478 - """  
479 - Attributes:  
480 - - success  
481 -  
482 - """  
483 -  
484 -  
485 - def __init__(self, success=None,):  
486 - self.success = success  
487 -  
488 - def read(self, iprot):  
489 - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:  
490 - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])  
491 - return  
492 - iprot.readStructBegin()  
493 - while True:  
494 - (fname, ftype, fid) = iprot.readFieldBegin()  
495 - if ftype == TType.STOP:  
496 - break  
497 - if fid == 0:  
498 - if ftype == TType.STRING:  
499 - self.success = iprot.readBinary()  
500 - else:  
501 - iprot.skip(ftype)  
502 - else:  
503 - iprot.skip(ftype)  
504 - iprot.readFieldEnd()  
505 - iprot.readStructEnd()  
506 -  
507 - def write(self, oprot):  
508 - if oprot._fast_encode is not None and self.thrift_spec is not None:  
509 - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))  
510 - return  
511 - oprot.writeStructBegin('getData_result')  
512 - if self.success is not None:  
513 - oprot.writeFieldBegin('success', TType.STRING, 0)  
514 - oprot.writeBinary(self.success)  
515 - oprot.writeFieldEnd()  
516 - oprot.writeFieldStop()  
517 - oprot.writeStructEnd()  
518 -  
519 - def validate(self):  
520 - return  
521 -  
522 - def __repr__(self):  
523 - L = ['%s=%r' % (key, value)  
524 - for key, value in self.__dict__.items()]  
525 - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))  
526 -  
527 - def __eq__(self, other):  
528 - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__  
529 -  
530 - def __ne__(self, other):  
531 - return not (self == other)  
532 -all_structs.append(getData_result)  
533 -getData_result.thrift_spec = (  
534 - (0, TType.STRING, 'success', 'BINARY', None, ), # 0  
535 -)  
536 -  
537 -  
538 -class getInfo_args(object):  
539 - """  
540 - Attributes:  
541 - - path  
542 -  
543 - """  
544 -  
545 -  
546 - def __init__(self, path=None,):  
547 - self.path = path  
548 -  
549 - def read(self, iprot):  
550 - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:  
551 - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])  
552 - return  
553 - iprot.readStructBegin()  
554 - while True:  
555 - (fname, ftype, fid) = iprot.readFieldBegin()  
556 - if ftype == TType.STOP:  
557 - break  
558 - if fid == 1:  
559 - if ftype == TType.STRING:  
560 - self.path = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()  
561 - else:  
562 - iprot.skip(ftype)  
563 - else:  
564 - iprot.skip(ftype)  
565 - iprot.readFieldEnd()  
566 - iprot.readStructEnd()  
567 -  
568 - def write(self, oprot):  
569 - if oprot._fast_encode is not None and self.thrift_spec is not None:  
570 - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))  
571 - return  
572 - oprot.writeStructBegin('getInfo_args')  
573 - if self.path is not None:  
574 - oprot.writeFieldBegin('path', TType.STRING, 1)  
575 - oprot.writeString(self.path.encode('utf-8') if sys.version_info[0] == 2 else self.path)  
576 - oprot.writeFieldEnd()  
577 - oprot.writeFieldStop()  
578 - oprot.writeStructEnd()  
579 -  
580 - def validate(self):  
581 - return  
582 -  
583 - def __repr__(self):  
584 - L = ['%s=%r' % (key, value)  
585 - for key, value in self.__dict__.items()]  
586 - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))  
587 -  
588 - def __eq__(self, other):  
589 - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__  
590 -  
591 - def __ne__(self, other):  
592 - return not (self == other)  
593 -all_structs.append(getInfo_args)  
594 -getInfo_args.thrift_spec = (  
595 - None, # 0  
596 - (1, TType.STRING, 'path', 'UTF8', None, ), # 1  
597 -)  
598 -  
599 -  
600 -class getInfo_result(object):  
601 - """  
602 - Attributes:  
603 - - success  
604 -  
605 - """  
606 -  
607 -  
608 - def __init__(self, success=None,):  
609 - self.success = success  
610 -  
611 - def read(self, iprot):  
612 - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:  
613 - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])  
614 - return  
615 - iprot.readStructBegin()  
616 - while True:  
617 - (fname, ftype, fid) = iprot.readFieldBegin()  
618 - if ftype == TType.STOP:  
619 - break  
620 - if fid == 0:  
621 - if ftype == TType.STRING:  
622 - self.success = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()  
623 - else:  
624 - iprot.skip(ftype)  
625 - else:  
626 - iprot.skip(ftype)  
627 - iprot.readFieldEnd()  
628 - iprot.readStructEnd()  
629 -  
630 - def write(self, oprot):  
631 - if oprot._fast_encode is not None and self.thrift_spec is not None:  
632 - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))  
633 - return  
634 - oprot.writeStructBegin('getInfo_result')  
635 - if self.success is not None:  
636 - oprot.writeFieldBegin('success', TType.STRING, 0)  
637 - oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)  
638 - oprot.writeFieldEnd()  
639 - oprot.writeFieldStop()  
640 - oprot.writeStructEnd()  
641 -  
642 - def validate(self):  
643 - return  
644 -  
645 - def __repr__(self):  
646 - L = ['%s=%r' % (key, value)  
647 - for key, value in self.__dict__.items()]  
648 - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))  
649 -  
650 - def __eq__(self, other):  
651 - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__  
652 -  
653 - def __ne__(self, other):  
654 - return not (self == other)  
655 -all_structs.append(getInfo_result)  
656 -getInfo_result.thrift_spec = (  
657 - (0, TType.STRING, 'success', 'UTF8', None, ), # 0  
658 -)  
659 -  
660 -  
661 -class buildOverview_args(object):  
662 - """  
663 - Attributes:  
664 - - path  
665 -  
666 - """  
667 -  
668 -  
669 - def __init__(self, path=None,):  
670 - self.path = path  
671 -  
672 - def read(self, iprot):  
673 - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:  
674 - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])  
675 - return  
676 - iprot.readStructBegin()  
677 - while True:  
678 - (fname, ftype, fid) = iprot.readFieldBegin()  
679 - if ftype == TType.STOP:  
680 - break  
681 - if fid == 1:  
682 - if ftype == TType.STRING:  
683 - self.path = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()  
684 - else:  
685 - iprot.skip(ftype)  
686 - else:  
687 - iprot.skip(ftype)  
688 - iprot.readFieldEnd()  
689 - iprot.readStructEnd()  
690 -  
691 - def write(self, oprot):  
692 - if oprot._fast_encode is not None and self.thrift_spec is not None:  
693 - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))  
694 - return  
695 - oprot.writeStructBegin('buildOverview_args')  
696 - if self.path is not None:  
697 - oprot.writeFieldBegin('path', TType.STRING, 1)  
698 - oprot.writeString(self.path.encode('utf-8') if sys.version_info[0] == 2 else self.path)  
699 - oprot.writeFieldEnd()  
700 - oprot.writeFieldStop()  
701 - oprot.writeStructEnd()  
702 -  
703 - def validate(self):  
704 - return  
705 -  
706 - def __repr__(self):  
707 - L = ['%s=%r' % (key, value)  
708 - for key, value in self.__dict__.items()]  
709 - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))  
710 -  
711 - def __eq__(self, other):  
712 - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__  
713 -  
714 - def __ne__(self, other):  
715 - return not (self == other)  
716 -all_structs.append(buildOverview_args)  
717 -buildOverview_args.thrift_spec = (  
718 - None, # 0  
719 - (1, TType.STRING, 'path', 'UTF8', None, ), # 1  
720 -)  
721 -  
722 -  
723 -class buildOverview_result(object):  
724 - """  
725 - Attributes:  
726 - - success  
727 -  
728 - """  
729 -  
730 -  
731 - def __init__(self, success=None,):  
732 - self.success = success  
733 -  
734 - def read(self, iprot):  
735 - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:  
736 - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])  
737 - return  
738 - iprot.readStructBegin()  
739 - while True:  
740 - (fname, ftype, fid) = iprot.readFieldBegin()  
741 - if ftype == TType.STOP:  
742 - break  
743 - if fid == 0:  
744 - if ftype == TType.BOOL:  
745 - self.success = iprot.readBool()  
746 - else:  
747 - iprot.skip(ftype)  
748 - else:  
749 - iprot.skip(ftype)  
750 - iprot.readFieldEnd()  
751 - iprot.readStructEnd()  
752 -  
753 - def write(self, oprot):  
754 - if oprot._fast_encode is not None and self.thrift_spec is not None:  
755 - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))  
756 - return  
757 - oprot.writeStructBegin('buildOverview_result')  
758 - if self.success is not None:  
759 - oprot.writeFieldBegin('success', TType.BOOL, 0)  
760 - oprot.writeBool(self.success)  
761 - oprot.writeFieldEnd()  
762 - oprot.writeFieldStop()  
763 - oprot.writeStructEnd()  
764 -  
765 - def validate(self):  
766 - return  
767 -  
768 - def __repr__(self):  
769 - L = ['%s=%r' % (key, value)  
770 - for key, value in self.__dict__.items()]  
771 - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))  
772 -  
773 - def __eq__(self, other):  
774 - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__  
775 -  
776 - def __ne__(self, other):  
777 - return not (self == other)  
778 -all_structs.append(buildOverview_result)  
779 -buildOverview_result.thrift_spec = (  
780 - (0, TType.BOOL, 'success', None, None, ), # 0  
781 -)  
782 -  
783 -  
784 -class getImageList_args(object):  
785 - """  
786 - Attributes:  
787 - - path  
788 -  
789 - """  
790 -  
791 -  
792 - def __init__(self, path=None,):  
793 - self.path = path  
794 -  
795 - def read(self, iprot):  
796 - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:  
797 - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])  
798 - return  
799 - iprot.readStructBegin()  
800 - while True:  
801 - (fname, ftype, fid) = iprot.readFieldBegin()  
802 - if ftype == TType.STOP:  
803 - break  
804 - if fid == 1:  
805 - if ftype == TType.STRING:  
806 - self.path = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()  
807 - else:  
808 - iprot.skip(ftype)  
809 - else:  
810 - iprot.skip(ftype)  
811 - iprot.readFieldEnd()  
812 - iprot.readStructEnd()  
813 -  
814 - def write(self, oprot):  
815 - if oprot._fast_encode is not None and self.thrift_spec is not None:  
816 - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))  
817 - return  
818 - oprot.writeStructBegin('getImageList_args')  
819 - if self.path is not None:  
820 - oprot.writeFieldBegin('path', TType.STRING, 1)  
821 - oprot.writeString(self.path.encode('utf-8') if sys.version_info[0] == 2 else self.path)  
822 - oprot.writeFieldEnd()  
823 - oprot.writeFieldStop()  
824 - oprot.writeStructEnd()  
825 -  
826 - def validate(self):  
827 - return  
828 -  
829 - def __repr__(self):  
830 - L = ['%s=%r' % (key, value)  
831 - for key, value in self.__dict__.items()]  
832 - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))  
833 -  
834 - def __eq__(self, other):  
835 - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__  
836 -  
837 - def __ne__(self, other):  
838 - return not (self == other)  
839 -all_structs.append(getImageList_args)  
840 -getImageList_args.thrift_spec = (  
841 - None, # 0  
842 - (1, TType.STRING, 'path', 'UTF8', None, ), # 1  
843 -)  
844 -  
845 -  
846 -class getImageList_result(object):  
847 - """  
848 - Attributes:  
849 - - success  
850 -  
851 - """  
852 -  
853 -  
854 - def __init__(self, success=None,):  
855 - self.success = success  
856 -  
857 - def read(self, iprot):  
858 - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:  
859 - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])  
860 - return  
861 - iprot.readStructBegin()  
862 - while True:  
863 - (fname, ftype, fid) = iprot.readFieldBegin()  
864 - if ftype == TType.STOP:  
865 - break  
866 - if fid == 0:  
867 - if ftype == TType.STRING:  
868 - self.success = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()  
869 - else:  
870 - iprot.skip(ftype)  
871 - else:  
872 - iprot.skip(ftype)  
873 - iprot.readFieldEnd()  
874 - iprot.readStructEnd()  
875 -  
876 - def write(self, oprot):  
877 - if oprot._fast_encode is not None and self.thrift_spec is not None:  
878 - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))  
879 - return  
880 - oprot.writeStructBegin('getImageList_result')  
881 - if self.success is not None:  
882 - oprot.writeFieldBegin('success', TType.STRING, 0)  
883 - oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)  
884 - oprot.writeFieldEnd()  
885 - oprot.writeFieldStop()  
886 - oprot.writeStructEnd()  
887 -  
888 - def validate(self):  
889 - return  
890 -  
891 - def __repr__(self):  
892 - L = ['%s=%r' % (key, value)  
893 - for key, value in self.__dict__.items()]  
894 - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))  
895 -  
896 - def __eq__(self, other):  
897 - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__  
898 -  
899 - def __ne__(self, other):  
900 - return not (self == other)  
901 -all_structs.append(getImageList_result)  
902 -getImageList_result.thrift_spec = (  
903 - (0, TType.STRING, 'success', 'UTF8', None, ), # 0  
904 -)  
905 -fix_spec(all_structs)  
906 -del all_structs  
1 -__all__ = ['ttypes', 'constants', 'ImageDataService']  
1 -#  
2 -# Autogenerated by Thrift Compiler (0.14.2)  
3 -#  
4 -# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING  
5 -#  
6 -# options string: py  
7 -#  
8 -  
9 -from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException  
10 -from thrift.protocol.TProtocol import TProtocolException  
11 -from thrift.TRecursive import fix_spec  
12 -  
13 -import sys  
14 -from .ttypes import *  
1 -#  
2 -# Autogenerated by Thrift Compiler (0.14.2)  
3 -#  
4 -# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING  
5 -#  
6 -# options string: py  
7 -#  
8 -  
9 -from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException  
10 -from thrift.protocol.TProtocol import TProtocolException  
11 -from thrift.TRecursive import fix_spec  
12 -  
13 -import sys  
14 -  
15 -from thrift.transport import TTransport  
16 -all_structs = []  
17 -fix_spec(all_structs)  
18 -del all_structs  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/5/18  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -from flasgger import swag_from  
8 -from flask import Blueprint  
9 -from app.util import BlueprintApi  
10 -from . import image_service_register  
11 -from . import image_server_list  
12 -from . import data_list  
13 -from . import capabilities  
14 -from . import image_tile,image_wms  
15 -from . import image_tile_mask  
16 -from . import image_wmts  
17 -from . import image_delete  
18 -from . import image_cancle  
19 -from . import image_register,image_list,image_info,image_edit,image_overview  
20 -from . import image_tag_create,image_tag_delete,image_tag_list  
21 -from . import image_wms_temporary  
22 -from . import image_wms_kv  
23 -from . import image_build_pyramid  
24 -from . import image_refresh  
25 -  
26 -class ImageServerInstance:  
27 - pass  
28 -  
29 -class ImageManager(BlueprintApi):  
30 -  
31 - bp = Blueprint("ImageService", __name__, url_prefix="/API/Service/Image")  
32 - service_type = ["影像服务"]  
33 -  
34 - @staticmethod  
35 - @bp.route('/Register', methods=['POST'])  
36 - @swag_from(image_register.Api.api_doc)  
37 - def image_register():  
38 - """  
39 - 影像注册  
40 - """  
41 - return image_register.Api().result  
42 -  
43 -  
44 - @staticmethod  
45 - @bp.route('/Delete', methods=['POST'])  
46 - @swag_from(image_delete.Api.api_doc)  
47 - def api_image_delete():  
48 - """  
49 - 影像删除  
50 - """  
51 - return image_delete.Api().result  
52 -  
53 - @staticmethod  
54 - @bp.route('/Cancle', methods=['POST'])  
55 - @swag_from(image_cancle.Api.api_doc)  
56 - def api_image_cancle():  
57 - """  
58 - 影像取消注册  
59 - """  
60 - return image_cancle.Api().result  
61 -  
62 - @staticmethod  
63 - @bp.route('/Edit', methods=['POST'])  
64 - @swag_from(image_edit.Api.api_doc)  
65 - def api_image_edit():  
66 - """  
67 - 影像Edit  
68 - """  
69 - return image_edit.Api().result  
70 -  
71 - @staticmethod  
72 - @bp.route('/Info', methods=['POST'])  
73 - @swag_from(image_info.Api.api_doc)  
74 - def api_image_info():  
75 - """  
76 - 影像Info  
77 - """  
78 - return image_info.Api().result  
79 -  
80 -  
81 - @staticmethod  
82 - @bp.route('/Overview', methods=['POST'])  
83 - @swag_from(image_overview.Api.api_doc)  
84 - def api_image_overview():  
85 - """  
86 - 影像缩略图  
87 - """  
88 - return image_overview.Api().result  
89 -  
90 - @staticmethod  
91 - @bp.route('/BuildPyramid', methods=['POST'])  
92 - @swag_from(image_build_pyramid.Api.api_doc)  
93 - def api_image_build_pyramid():  
94 - """  
95 - 创建影像金字塔  
96 - """  
97 - return image_build_pyramid.Api().result  
98 -  
99 - @staticmethod  
100 - @bp.route('/Refresh', methods=['POST'])  
101 - @swag_from(image_refresh.Api.api_doc)  
102 - def api_image_refresh():  
103 - """  
104 - 影像刷新信息  
105 - """  
106 - return image_refresh.Api().result  
107 -  
108 -  
109 - @staticmethod  
110 - @bp.route('/TagCreate', methods=['POST'])  
111 - @swag_from(image_tag_create.Api.api_doc)  
112 - def api_image_tag_create():  
113 - """  
114 - Tag创建  
115 - """  
116 - return image_tag_create.Api().result  
117 -  
118 - @staticmethod  
119 - @bp.route('/TagDelete', methods=['POST'])  
120 - @swag_from(image_tag_delete.Api.api_doc)  
121 - def api_image_tag_delete():  
122 - """  
123 - Tag删除  
124 - """  
125 - return image_tag_delete.Api().result  
126 -  
127 - @staticmethod  
128 - @bp.route('/TagList', methods=['POST'])  
129 - @swag_from(image_tag_list.Api.api_doc)  
130 - def api_image_tag_list():  
131 - """  
132 - TagList  
133 - """  
134 - return image_tag_list.Api().result  
135 -  
136 -  
137 - @staticmethod  
138 - @bp.route('/ServiceRegister', methods=['POST'])  
139 - @swag_from(image_service_register.Api.api_doc)  
140 - def image_service_register():  
141 - """  
142 - 服务注册  
143 - """  
144 - return image_service_register.Api().result  
145 -  
146 -  
147 -  
148 - @staticmethod  
149 - @bp.route('/ServerList', methods=['GET'])  
150 - @swag_from(image_server_list.Api.api_doc)  
151 - def image_server_list():  
152 - """  
153 - 服务器列表  
154 - """  
155 - return image_server_list.Api().result  
156 -  
157 -  
158 - @staticmethod  
159 - @bp.route('/DataList', methods=['POST'])  
160 - @swag_from(data_list.Api.api_doc)  
161 - def data_list():  
162 - """  
163 - 数据列表  
164 - """  
165 - return data_list.Api().result  
166 -  
167 - @staticmethod  
168 - @bp.route('/Capabilities', methods=['GET','POST'])  
169 - @swag_from(capabilities.Api.api_doc)  
170 - def capabilities():  
171 - """  
172 - 能力文档  
173 - """  
174 - return capabilities.Api().result  
175 -  
176 - @staticmethod  
177 - @bp.route('/ImageList', methods=['POST'])  
178 - @swag_from(image_list.Api.api_doc)  
179 - def image_list():  
180 - """  
181 - 影像列表  
182 - """  
183 - return image_list.Api().result  
184 -  
185 -  
186 - @staticmethod  
187 - @bp.route('/Tile/<guid>/<l>/<y>/<z>', methods=['GET'])  
188 - # @swag_from(image_tile.Api.api_doc)  
189 - def api_image_tile(guid,l,y,z):  
190 - """  
191 - 切片服务  
192 - """  
193 - return image_tile.Api(guid,l,y,z).result  
194 -  
195 -  
196 -  
197 -  
198 -  
199 - @staticmethod  
200 - @bp.route('/Tile', methods=['GET','POST'])  
201 - # @swag_from(image_tile.Api.api_doc)  
202 - def api_image_tile_kv():  
203 - """  
204 - 切片服务  
205 - """  
206 - return image_tile.Api("1",1,1,1).result  
207 -  
208 - # @staticmethod  
209 - # @bp.route('/TileMask/<guid>/<l>/<y>/<z>', methods=['GET'])  
210 - # @swag_from(image_tile_mask.Api.api_doc)  
211 - # def api_image_tile_mask(guid,l,y,z):  
212 - # """  
213 - # 切片服务  
214 - # """  
215 - # return image_tile_mask.Api(guid,l,y,z).result  
216 - #  
217 - # @staticmethod  
218 - # @bp.route('/TileMask', methods=['GET','POST'])  
219 - # @swag_from(image_tile_mask.Api.api_doc)  
220 - # def api_image_tile_mask_kv():  
221 - # """  
222 - # 切片服务  
223 - # """  
224 - # return image_tile_mask.Api("1",1,1,1).result  
225 -  
226 -  
227 -  
228 - @staticmethod  
229 - @bp.route('/<service_name>/WMS', methods=['GET','POST'])  
230 - @swag_from(image_wms.Api.api_doc)  
231 - def image_wms(service_name):  
232 - """  
233 - WMS服务  
234 - """  
235 - return image_wms.Api(service_name).result  
236 -  
237 - @staticmethod  
238 - @bp.route('/<service_name>/WMTS', methods=['GET','POST'])  
239 - @swag_from(image_wmts.Api.api_doc)  
240 - def api_image_wmts(service_name):  
241 - """  
242 - 切片服务  
243 - """  
244 - return image_wmts.Api(service_name).result  
245 -  
246 -  
247 -  
248 - @staticmethod  
249 - @bp.route('/WMS', methods=['GET','POST'])  
250 - # @swag_from(image_wms_kv.Api.api_doc)  
251 - def image_wms_kv():  
252 - """  
253 - WMS服务  
254 - """  
255 - return image_wms_kv.Api().result  
256 -  
257 -  
258 - @staticmethod  
259 - @bp.route('/WMSTem', methods=['GET','POST'])  
260 - @swag_from(image_wms_temporary.Api.api_doc)  
261 - def image_wms_temporary():  
262 - """  
263 - WMS服务预览  
264 - """  
265 - return image_wms_temporary.Api().result  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/4/6  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -from flask import Response  
8 -from app.util.component.ApiTemplate import ApiTemplate  
9 -from ..models import ImageService  
10 -from ..models import Service,TileScheme  
11 -import json  
12 -import configure  
13 -  
14 -  
15 -class Api(ApiTemplate):  
16 -  
17 - api_name = "影像能力文档"  
18 -  
19 - def process(self):  
20 -  
21 - guid = self.para.get("guid")  
22 - image_service:ImageService = ImageService.query.filter_by(guid=guid).one_or_none()  
23 - if not image_service:  
24 - raise Exception("服务不存在!")  
25 - service = Service.query.filter_by(guid=image_service.service_guid).one_or_none()  
26 -  
27 - if service.type.__eq__("ImageWMS"):  
28 - xml = self.get_wms_capabilities(image_service)  
29 -  
30 - elif service.type.__eq__("ImageWMTS"):  
31 - #arcgis能加载  
32 - xml = self.get_wmts_capabilities(image_service,service)  
33 - else:  
34 - xml = ""  
35 -  
36 - r = Response(response=xml, status=200, mimetype="application/xml")  
37 - r.headers["Content-Type"] = "text/xml; charset=utf-8"  
38 - return r  
39 -  
40 - def get_wms_capabilities(self,image_service:ImageService):  
41 -  
42 - xml = '''<?xml version="1.0" encoding="utf-8" ?>  
43 - <WMS_Capabilities version="1.2.0">  
44 - <Service>  
45 - <Name>WMS</Name>  
46 - <Title>{service_title}</Title>  
47 - <Abstract>{abstract}</Abstract>  
48 - <Keywords>GIMS</Keywords>  
49 - <OnlineResource/>  
50 - <Fees>none</Fees>  
51 - <AccessConstraints>none</AccessConstraints>  
52 - </Service>  
53 - <Capability>  
54 - <Request>  
55 - <GetCapabilities>  
56 - <Format>text/xml</Format>  
57 - <DCPType>  
58 - <HTTP>  
59 - <Get>  
60 - <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>  
61 - </Get>  
62 - </HTTP>  
63 - </DCPType>  
64 - </GetCapabilities>  
65 - <GetMap>  
66 - <Format>png</Format>  
67 - <Format>jpeg</Format>  
68 - <Format>gif</Format>  
69 - <Format>image/png</Format>  
70 - <Format>image/jpeg</Format>  
71 - <Format>image/gif</Format>  
72 - <DCPType>  
73 - <HTTP>  
74 - <Get>  
75 - <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>  
76 - </Get>  
77 - </HTTP>  
78 - </DCPType>  
79 - </GetMap>  
80 - <Map>  
81 - <Format>  
82 - <PNG/>  
83 - <GIF/>  
84 - <JPG/>  
85 - </Format>  
86 - <DCPType>  
87 - <HTTP>  
88 - <Get onlineResource="{url}"/>  
89 - </HTTP>  
90 - </DCPType>  
91 - </Map>  
92 - <Capabilities>  
93 - <Format>  
94 - <WMS_XML/>  
95 - </Format>  
96 - <DCPType>  
97 - <HTTP>  
98 - <Get onlineResource="{url}"/>  
99 - </HTTP>  
100 - </DCPType>  
101 - </Capabilities>  
102 - <FeatureInfo>  
103 - <Format>  
104 - <XML/>  
105 - <MIME/>  
106 - </Format>  
107 - <DCPType>  
108 - <HTTP>  
109 - <Get onlineResource="{url}"/>  
110 - </HTTP>  
111 - </DCPType>  
112 - </FeatureInfo>  
113 - </Request>  
114 - <Exception>  
115 - <Format>  
116 - <WMS_XML/>  
117 - <INIMAGE/>  
118 - <BLANK/>  
119 - </Format>  
120 - </Exception>  
121 - <Layer>  
122 - <Name>{service_name}</Name>  
123 - <Title>{service_title}</Title>  
124 - <CRS>{crs}</CRS>  
125 - <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/>  
126 - <Layer queryable="1">  
127 - <CRS>{crs}</CRS>  
128 - <Name>{layer_name}</Name>  
129 - <Title>{layer_title}</Title>  
130 - <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/>  
131 - </Layer>  
132 - </Layer>  
133 - </Capability>  
134 - </WMS_Capabilities>'''  
135 -  
136 - extent = json.loads(image_service.extent)  
137 - xml = xml.format(service_title=image_service.name,  
138 - service_name=image_service.name,  
139 - abstract= "None" ,  
140 - crs="ESPG:4326",  
141 - layer_name=image_service.name,  
142 - layer_title=image_service.name,  
143 - maxx=extent[2],  
144 - maxy = extent[3],  
145 - minx = extent[0],  
146 - miny = extent[1],  
147 - url="http://{}/API/Service/Image/WMS?guid={}".format(configure.deploy_ip_host,image_service.guid))  
148 - return xml  
149 -  
150 - def get_wmts_capabilities(self, image_service: ImageService,service:Service):  
151 - tile_scheme:TileScheme = TileScheme.query.filter_by(guid = image_service.scheme_guid).one_or_none()  
152 - if not tile_scheme:  
153 - raise Exception("切片方案不存在!")  
154 -  
155 - 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">  
156 - <!-- Service Identification -->  
157 - <ows:ServiceIdentification>  
158 - <ows:Title>{title}</ows:Title>  
159 - <ows:ServiceType>OGC WMTS</ows:ServiceType>  
160 - <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>  
161 - </ows:ServiceIdentification>  
162 -  
163 - <!-- Operations Metadata -->  
164 - <ows:OperationsMetadata>  
165 - <ows:Operation name="GetCapabilities">  
166 - <ows:DCP>  
167 - <ows:HTTP>  
168 - <ows:Get xlink:href="{capabilities_url}">  
169 - <ows:Constraint name="GetEncoding">  
170 - <ows:AllowedValues>  
171 - <ows:Value>RESTful</ows:Value>  
172 - </ows:AllowedValues>  
173 - </ows:Constraint>  
174 - </ows:Get>  
175 -  
176 - <!-- add KVP binding in 10.1 -->  
177 - <ows:Get xlink:href="{tile_url}?">  
178 - <ows:Constraint name="GetEncoding">  
179 - <ows:AllowedValues>  
180 - <ows:Value>KVP</ows:Value>  
181 - </ows:AllowedValues>  
182 - </ows:Constraint>  
183 - </ows:Get>  
184 - </ows:HTTP>  
185 - </ows:DCP>  
186 - </ows:Operation>  
187 - <ows:Operation name="GetTile">  
188 - <ows:DCP>  
189 - <ows:HTTP>  
190 - <ows:Get xlink:href="{tile_url}">  
191 - <ows:Constraint name="GetEncoding">  
192 - <ows:AllowedValues>  
193 - <ows:Value>RESTful</ows:Value>  
194 - </ows:AllowedValues>  
195 - </ows:Constraint>  
196 - </ows:Get>  
197 - <ows:Get xlink:href="{tile_url}?">  
198 - <ows:Constraint name="GetEncoding">  
199 - <ows:AllowedValues>  
200 - <ows:Value>KVP</ows:Value>  
201 - </ows:AllowedValues>  
202 - </ows:Constraint>  
203 - </ows:Get>  
204 - </ows:HTTP>  
205 - </ows:DCP>  
206 - </ows:Operation>  
207 - </ows:OperationsMetadata>  
208 -  
209 - <Contents>  
210 -  
211 - <!-- Layer -->  
212 -  
213 -  
214 - <Layer>  
215 - <ows:Title>{title}</ows:Title>  
216 - <ows:Identifier>{title}</ows:Identifier>  
217 - <ows:BoundingBox crs="{crs}">  
218 - <ows:LowerCorner>{xmin} {ymin}</ows:LowerCorner>  
219 - <ows:UpperCorner>{xmax} {ymax}</ows:UpperCorner>  
220 - </ows:BoundingBox>  
221 -  
222 - <Style isDefault="true">  
223 - <ows:Title>Default Style</ows:Title>  
224 - <ows:Identifier>default</ows:Identifier>  
225 - </Style>  
226 - <Format>image/png</Format>  
227 - <TileMatrixSetLink>  
228 - <TileMatrixSet>{tile_name}</TileMatrixSet>  
229 - </TileMatrixSetLink>  
230 -  
231 - <ResourceURL format="image/png" resourceType="tile" template="{tile_url}"/>  
232 -  
233 - </Layer>  
234 -  
235 - <!-- TileMatrixSet -->  
236 -  
237 -  
238 - <TileMatrixSet>  
239 -  
240 - <TileMatrix>  
241 - <ows:Title>{tile_title}</ows:Title>  
242 - <ows:Abstract>{tile_description}</ows:Abstract>  
243 - <ows:Identifier>{tile_name}</ows:Identifier>  
244 - <ows:SupportedCRS>{crs}</ows:SupportedCRS>  
245 -  
246 - {tile_matrix}  
247 -  
248 - </TileMatrix>  
249 -  
250 - </TileMatrixSet>  
251 -  
252 -  
253 - </Contents>  
254 - <ServiceMetadataURL xlink:href="{capabilities_url}"/>  
255 - </Capabilities>'''  
256 -  
257 -  
258 -  
259 -  
260 - tile_matrix_each = '''  
261 - <TileMatrix>  
262 - <ows:Identifier>{lev}</ows:Identifier>  
263 - <ScaleDenominator>{scale}</ScaleDenominator>  
264 - <TopLeftCorner>{top_left}</TopLeftCorner>  
265 - <TileWidth>{cols}</TileWidth>  
266 - <TileHeight>{rows}</TileHeight>  
267 - </TileMatrix>  
268 - '''  
269 -  
270 - tile_matrix = ""  
271 - top_left = tile_scheme.top_left  
272 - for level in json.loads(tile_scheme.levels):  
273 - tile_matrix = "{}{}".format(tile_matrix,tile_matrix_each.format(lev=level["level"],  
274 - scale=level["scale"],  
275 - top_left=top_left,  
276 - cols=tile_scheme.cols,  
277 - rows=tile_scheme.rows))  
278 -  
279 - extent = json.loads(image_service.extent)  
280 -  
281 - xml = xml.format(capabilities_url = "http://{}/API/Service/Image/Capabilities?guid={}".format(configure.deploy_ip_host,image_service.guid),  
282 - tile_url = "http://{}/API/Service/Image/Tile?guid={}".format(configure.deploy_ip_host,image_service.guid),  
283 - crs = tile_scheme.crs,  
284 - xmin = extent[0],  
285 - ymin = extent[1],  
286 - xmax = extent[2],  
287 - ymax = extent[3],  
288 - # TileMatrix = "{TileMatrix}",  
289 - # TileRow = "{TileRow}",  
290 - # TileCol = "{TileCol}",  
291 - guid = image_service.guid,  
292 - title = service.title,  
293 - tile_title = tile_scheme.name,  
294 - tile_name = tile_scheme.name,  
295 - tile_description = tile_scheme.description,  
296 - tile_matrix=tile_matrix  
297 - )  
298 -  
299 - return xml  
300 -  
301 -  
302 - api_doc = {  
303 - "tags": ["影像接口"],  
304 - "parameters": [  
305 - {"name": "guid",  
306 - "in": "formData",  
307 - "type": "string",  
308 - "description": "服务guid"},  
309 - ],  
310 - "responses": {  
311 - 200: {  
312 - "schema": {  
313 - "properties": {  
314 - }  
315 - }  
316 - }  
317 - }  
318 -}  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/7/19  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -from app.util.component.ApiTemplate import ApiTemplate  
8 -  
9 -import json  
10 -from app.util.component.FileProcess import FileProcess  
11 -import datetime  
12 -from app.modules.service.image.util.ThriftConnect import ThriftConnect  
13 -import os  
14 -from app.models import db  
15 -from app.modules.service.models import Image  
16 -from .util.ImageType import ImageType  
17 -  
18 -class Api(ApiTemplate):  
19 -  
20 - api_name = "影像数据列表"  
21 -  
22 - def process(self):  
23 -  
24 -  
25 - # 返回结果  
26 - res = {}  
27 -  
28 - try:  
29 - data_server = self.para.get("data_server")  
30 -  
31 - path = self.para.get("path")  
32 -  
33 -  
34 - if data_server.__eq__("本地服务器"):  
35 - project_path = (os.path.dirname(os.path.abspath(__file__)))  
36 -  
37 - base_path = os.path.join(project_path, "data")  
38 - if path:  
39 - base_path = os.path.normpath(path)  
40 -  
41 - data_list: list = []  
42 - for f in os.listdir(base_path):  
43 -  
44 - file_path = os.path.normpath(os.path.join(base_path, f))  
45 - file_size, real_size = FileProcess.get_file_size(file_path)  
46 -  
47 - fctime = datetime.datetime.fromtimestamp(os.path.getctime(file_path)).strftime('%Y-%m-%d %H:%M:%S')  
48 -  
49 - file_info = {"name": f, "path": file_path, "size": file_size, "create_time": fctime,"real_size": real_size}  
50 -  
51 - if file_path.lower().endswith("tiff") or file_path.lower().endswith("tif") or file_path.lower().endswith("img") or os.path.isdir(file_path):  
52 -  
53 - exist_image: Image = Image.query.filter_by(path=os.path.normpath(file_info.get("path")),  
54 - size=file_info.get("real_size")).one_or_none()  
55 - file_info["exist"] = False  
56 - if exist_image:  
57 - if exist_image.server.__contains__(data_server):  
58 - file_info["exist"] = True  
59 -  
60 - file_info["type"] = ImageType.get_type(file_path)  
61 - data_list.append(file_info)  
62 -  
63 -  
64 - info_dir = []  
65 - info_img = []  
66 - for dat in data_list:  
67 -  
68 - if dat["type"].__eq__("dir"):  
69 - info_dir.append(dat)  
70 - else:  
71 - info_img.append(dat)  
72 -  
73 - info_dir = sorted(info_dir,key = lambda x: x["name"])  
74 - info_img = sorted(info_img,key = lambda x: x["name"])  
75 - info_dir.extend(info_img)  
76 -  
77 - res["data"] = info_dir  
78 -  
79 - else:  
80 - thrift_connect = ThriftConnect(data_server)  
81 - info= json.loads(thrift_connect.client.getImageList(path))  
82 - thrift_connect.close()  
83 -  
84 -  
85 - info_dir = []  
86 - info_img = []  
87 - for inf in info:  
88 - if inf["path"].lower().endswith("tiff") or inf["path"].lower().endswith("tif") or inf["path"].lower().endswith("img"):  
89 -  
90 - exist_image = Image.query.filter_by(path=inf.get("path"),  
91 - size=inf.get("real_size")).one_or_none()  
92 - inf["exist"] = False  
93 - if exist_image:  
94 - if exist_image.server.__contains__(data_server):  
95 - inf["exist"] = True  
96 -  
97 - if inf["type"].__eq__("dir"):  
98 - info_dir.append(inf)  
99 - else:  
100 - info_img.append(inf)  
101 -  
102 - info_dir = sorted(info_dir, key = lambda x: x["name"])  
103 - info_img = sorted(info_img, key = lambda x: x["name"])  
104 - info_dir.extend(info_img)  
105 -  
106 - res["data"] = info_dir  
107 -  
108 - res["result"] = True  
109 -  
110 - except Exception as e:  
111 - raise e  
112 -  
113 - return res  
114 -  
115 - api_doc = {  
116 - "tags": ["影像接口"],  
117 - "parameters": [  
118 - {"name": "data_server",  
119 - "in": "formData",  
120 - "type": "string",  
121 - "description": "data_server"},  
122 - {"name": "path",  
123 - "in": "formData",  
124 - "type": "string",  
125 - "description": "path"}  
126 - ],  
127 - "responses": {  
128 - 200: {  
129 - "schema": {  
130 - "properties": {  
131 - }  
132 - }  
133 - }  
134 - }  
135 - }  
136 -  
1 -<?xml version="1.0" encoding="utf-8" ?><CacheInfo xsi:type='typens:CacheInfo' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:typens='http://www.esri.com/schemas/ArcGIS/10.1'><TileCacheInfo xsi:type='typens:TileCacheInfo'><SpatialReference xsi:type='typens:GeographicCoordinateSystem'><WKT>GEOGCS[&quot;GCS_China_Geodetic_Coordinate_System_2000&quot;,DATUM[&quot;D_China_2000&quot;,SPHEROID[&quot;CGCS2000&quot;,6378137.0,298.257222101]],PRIMEM[&quot;Greenwich&quot;,0.0],UNIT[&quot;Degree&quot;,0.0174532925199433],METADATA[&quot;China&quot;,73.66,7.16,134.85,53.59,0.0,0.0174532925199433,0.0,1067],AUTHORITY[&quot;EPSG&quot;,4490]]</WKT><XOrigin>-400</XOrigin><YOrigin>-400</YOrigin><XYScale>11258999068426.24</XYScale><ZOrigin>-100000</ZOrigin><ZScale>10000</ZScale><MOrigin>-100000</MOrigin><MScale>10000</MScale><XYTolerance>8.9831528411952133e-009</XYTolerance><ZTolerance>0.001</ZTolerance><MTolerance>0.001</MTolerance><HighPrecision>true</HighPrecision><LeftLongitude>-180</LeftLongitude><WKID>4490</WKID><LatestWKID>4490</LatestWKID></SpatialReference><TileOrigin xsi:type='typens:PointN'><X>-400</X><Y>399.99999999999977</Y></TileOrigin><TileCols>256</TileCols><TileRows>256</TileRows><DPI>96</DPI><PreciseDPI>96</PreciseDPI><LODInfos xsi:type='typens:ArrayOfLODInfo'><LODInfo xsi:type='typens:LODInfo'><LevelID>0</LevelID><Scale>1154287.473</Scale><Resolution>0.0027465820315218724</Resolution></LODInfo><LODInfo xsi:type='typens:LODInfo'><LevelID>1</LevelID><Scale>577143.73640000005</Scale><Resolution>0.0013732910155229902</Resolution></LODInfo><LODInfo xsi:type='typens:LODInfo'><LevelID>2</LevelID><Scale>288571.86820000003</Scale><Resolution>0.00068664550776149512</Resolution></LODInfo><LODInfo xsi:type='typens:LODInfo'><LevelID>3</LevelID><Scale>144285.93410000001</Scale><Resolution>0.00034332275388074756</Resolution></LODInfo><LODInfo xsi:type='typens:LODInfo'><LevelID>4</LevelID><Scale>72142.967059999995</Scale><Resolution>0.00017166137696416836</Resolution></LODInfo><LODInfo xsi:type='typens:LODInfo'><LevelID>5</LevelID><Scale>36071.483529999998</Scale><Resolution>8.5830688482084179e-005</Resolution></LODInfo><LODInfo xsi:type='typens:LODInfo'><LevelID>6</LevelID><Scale>18035.741760000001</Scale><Resolution>4.2915344229144793e-005</Resolution></LODInfo><LODInfo xsi:type='typens:LODInfo'><LevelID>7</LevelID><Scale>9017.8708819999993</Scale><Resolution>2.1457672119331316e-005</Resolution></LODInfo><LODInfo xsi:type='typens:LODInfo'><LevelID>8</LevelID><Scale>4508.9354409999996</Scale><Resolution>1.0728836059665658e-005</Resolution></LODInfo><LODInfo xsi:type='typens:LODInfo'><LevelID>9</LevelID><Scale>2254.4677200000001</Scale><Resolution>5.3644180286430992e-006</Resolution></LODInfo><LODInfo xsi:type='typens:LODInfo'><LevelID>10</LevelID><Scale>1127.23386</Scale><Resolution>2.6822090143215496e-006</Resolution></LODInfo></LODInfos></TileCacheInfo><TileImageInfo xsi:type='typens:TileImageInfo'><CacheTileFormat>PNG32</CacheTileFormat><CompressionQuality>0</CompressionQuality><Antialiasing>false</Antialiasing></TileImageInfo><CacheStorageInfo xsi:type='typens:CacheStorageInfo'><StorageFormat>esriMapCacheStorageModeCompact</StorageFormat><PacketSize>128</PacketSize></CacheStorageInfo></CacheInfo>  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/7/19  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -from app.util.component.ApiTemplate import ApiTemplate  
8 -import datetime  
9 -from app.modules.service.image.util.ThriftConnect import ThriftConnect  
10 -from app.models import db  
11 -from app.modules.service.models import Image  
12 -from app.modules.data.models import Task  
13 -import multiprocessing  
14 -import uuid  
15 -import configure  
16 -from app.util.component.PGUtil import PGUtil  
17 -from .util.Cache import Cache  
18 -import json  
19 -from osgeo import gdal  
20 -from osgeo.gdal import *  
21 -import traceback  
22 -import os  
23 -from app.util.component.TaskController import TaskController  
24 -from app.util.component.TaskWriter import TaskWriter  
25 -  
26 -class Api(ApiTemplate):  
27 -  
28 - api_name = "创建影像金字塔"  
29 -  
30 - def process(self):  
31 -  
32 - # 返回结果  
33 - res = {}  
34 - try:  
35 - image_guid = self.para.get("guid")  
36 - task_guid = uuid.uuid1().__str__()  
37 - image = Image.query.filter_by(guid=image_guid).one_or_none()  
38 - if not image:  
39 - raise Exception("数据不存在!")  
40 - if image.has_pyramid==-1:  
41 - raise Exception("数据正在创建金字塔!")  
42 -  
43 - image_service_info, zoo, servers = Cache.cache_data(None)  
44 -  
45 - image_servers = image.server.split(",")  
46 - image_servers = [ser for ser in image_servers if ser in servers]  
47 -  
48 - if len(image_servers)==0:  
49 - raise Exception("暂时没有可用数据服务器提供该影像相关服务!")  
50 -  
51 - #创建金字塔的进程  
52 - build_process = multiprocessing.Process(target=self.build_pyramid_task,  
53 - args=(image_guid,task_guid,image_servers,image.path))  
54 - build_process.start()  
55 -  
56 - task = Task(guid=task_guid,  
57 - name="{}创建金字塔".format(image.name),  
58 - create_time=datetime.datetime.now(),  
59 - state=0,  
60 - task_type=5,  
61 - creator=self.para.get("creator"),  
62 - process="创建金字塔",  
63 - task_pid=build_process.pid,  
64 - parameter=image_guid)  
65 -  
66 - db.session.add(task)  
67 - db.session.commit()  
68 -  
69 -  
70 - res["data"] = "创建金字塔任务已提交!"  
71 -  
72 - res["result"] = True  
73 -  
74 - except Exception as e:  
75 - raise e  
76 -  
77 - return res  
78 -  
79 - def build_pyramid_task(self,image_guid,task_guid,data_servers,path):  
80 -  
81 - task_writer = None  
82 -  
83 - try:  
84 - #任务控制,等待执行  
85 - TaskController.wait(task_guid)  
86 - task_writer = TaskWriter(task_guid)  
87 -  
88 - #进入创建金字塔的状态  
89 - task_writer.session.query(Image).filter_by(guid=image_guid).update({"has_pyramid": -1})  
90 - task_writer.update_task({"state": 2})  
91 -  
92 - #所有数据节点的影像都要建金字塔  
93 - update_size = None  
94 - overview_count = None  
95 - for data_server in data_servers:  
96 - if data_server=="本地服务器":  
97 - result = self.buildOverview(path)  
98 - update_size = os.path.getsize(path)  
99 - else:  
100 - thrift_connect = ThriftConnect(data_server)  
101 - image_info = json.loads(thrift_connect.client.getInfo(path))  
102 - if image_info.get("overview_count") > 0:  
103 - overview_count = image_info.get("overview_count")  
104 - continue  
105 - result = thrift_connect.client.buildOverview(path)  
106 - update_size = json.loads(thrift_connect.client.getInfo(path)).get("size")  
107 - thrift_connect.close()  
108 -  
109 - task_writer.update_task({"state":1,"update_time":datetime.datetime.now()})  
110 -  
111 - image:Image = task_writer.session.query(Image).filter_by(guid=image_guid).one_or_none()  
112 -  
113 - if not overview_count:  
114 - overview_count = 0  
115 - raster_x_size = image.raster_x_size  
116 - raster_y_size = image.raster_y_size  
117 - while raster_x_size * raster_y_size > 65536:  
118 - raster_x_size /= 2.0  
119 - raster_y_size /= 2.0  
120 - overview_count += 1  
121 -  
122 - image.has_pyramid = 1  
123 - image.overview_count = overview_count  
124 - if update_size:  
125 - image.size = update_size  
126 - except:  
127 - task_writer.session.query(Image).filter_by(guid=image_guid).update({"has_pyramid": 0})  
128 - task_writer.update_task({"state": -1,"update_time":datetime.datetime.now()})  
129 - finally:  
130 - task_writer.session.commit()  
131 - task_writer.close()  
132 -  
133 - def buildOverview(self,path):  
134 - image: Dataset = gdal.Open(path, 1)  
135 - result =True  
136 - try:  
137 - overviews=[]  
138 - raster_x_size = image.RasterXSize  
139 - raster_y_size = image.RasterYSize  
140 - while raster_x_size*raster_y_size>65536:  
141 - raster_x_size /= 2.0  
142 - raster_y_size /= 2.0  
143 - overviews.append(round(image.RasterXSize/raster_x_size))  
144 - band: Band = image.GetRasterBand(1)  
145 - if len(overviews) == band.GetOverviewCount():  
146 - pass  
147 - else:  
148 - image.BuildOverviews("AVERAGE",overviews)  
149 - except Exception as e:  
150 - print(traceback.format_exc())  
151 - result = False  
152 - finally:  
153 - del image  
154 - return result  
155 -  
156 - api_doc = {  
157 - "tags": ["影像接口"],  
158 - "parameters": [  
159 - {"name": "guid",  
160 - "in": "formData",  
161 - "type": "string",  
162 - "description": "guid"},  
163 - ],  
164 - "responses": {  
165 - 200: {  
166 - "schema": {  
167 - "properties": {  
168 - }  
169 - }  
170 - }  
171 - }  
172 - }  
173 -  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/9/8  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -  
8 -from app.util.component.ApiTemplate import ApiTemplate  
9 -from app.modules.service.models import Image,db,ImageTag  
10 -import datetime  
11 -  
12 -class Api(ApiTemplate):  
13 -  
14 - api_name = "修改影像数据"  
15 -  
16 - def process(self):  
17 -  
18 - # 返回结果  
19 - res = {}  
20 - try:  
21 - para = self.para  
22 - guid = self.para.get("guid")  
23 - tag_guids = self.para.get("tag_guids")  
24 -  
25 - image = Image.query.filter_by(guid=guid)  
26 - this_time = datetime.datetime.now()  
27 -  
28 - del para["guid"]  
29 - if para.get("tag_guids"):  
30 - del para["tag_guids"]  
31 -  
32 - if para or tag_guids:  
33 - para["update_time"] = this_time  
34 - image.update(para)  
35 -  
36 - if tag_guids:  
37 - tags = ImageTag.query.filter(ImageTag.guid.in_(tag_guids.split(","))).all()  
38 - img = Image.query.filter_by(guid=guid).one_or_none()  
39 - img.image_tags = tags  
40 -  
41 -  
42 - db.session.commit()  
43 -  
44 - res["result"] = True  
45 - except Exception as e:  
46 - raise e  
47 -  
48 - return res  
49 -  
50 -  
51 - api_doc = {  
52 - "tags": ["影像接口"],  
53 - "parameters": [  
54 - {"name": "guid",  
55 - "in": "formData",  
56 - "type": "string"},  
57 - {"name": "alias",  
58 - "in": "formData",  
59 - "type": "string"},  
60 - {"name": "collect_time",  
61 - "in": "formData",  
62 - "type": "string","description":"成像时间字符串"},  
63 - {"name": "region",  
64 - "in": "formData",  
65 - "type": "string", "description": "所属区域"},  
66 - {"name": "satellite",  
67 - "in": "formData",  
68 - "type": "string", "description": "卫星类型"},  
69 - {"name": "crs",  
70 - "in": "formData",  
71 - "type": "string", "description": "空间参考"},  
72 - {"name": "band_view",  
73 - "in": "formData",  
74 - "type": "string", "description": "波段设计[1,1,1]"},  
75 - {"name": "tag_guids",  
76 - "in": "formData",  
77 - "type": "string", "description": "tags"},  
78 - ],  
79 - "responses": {  
80 - 200: {  
81 - "schema": {  
82 - "properties": {  
83 - }  
84 - }  
85 - }  
86 - }  
87 - }  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/7/19  
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 app.util.component.FileProcess import FileProcess  
10 -from app.modules.service.models import Image,ImageTag  
11 -from sqlalchemy import or_  
12 -import datetime  
13 -  
14 -class Api(ApiTemplate):  
15 -  
16 - api_name = "影像数据List"  
17 -  
18 - def process(self):  
19 -  
20 - # 返回结果  
21 - res = {}  
22 - try:  
23 - page_index = int(self.para.get("page_index", "0"))  
24 - page_size = int(self.para.get("page_size", "10"))  
25 -  
26 - alias = self.para.get("alias")  
27 - name = self.para.get("name")  
28 - band = self.para.get("band")  
29 - region = self.para.get("region")  
30 - tag_guids = self.para.get("tag_guids")  
31 - collect_time = self.para.get("collect_time")  
32 -  
33 - type = self.para.get("type")  
34 -  
35 - images = Image.query.order_by(Image.update_time.desc())  
36 -  
37 - # 并集  
38 - if alias and name:  
39 - images = images.filter(or_(Image.alias.like("%" + alias + "%") , Image.name.like("%" + name + "%")))  
40 - else:  
41 - if alias:  
42 - images = images.filter(Image.alias.like("%" + alias + "%"))  
43 - if name:  
44 - images = images.filter(Image.name.like("%" + name + "%"))  
45 - if band:  
46 - images = images.filter(Image.band_view.like("%" + str(band) + "%"))  
47 -  
48 - if type:  
49 - images = images.filter_by(type=type)  
50 -  
51 - if region:  
52 - images = images.filter(Image.region.in_(region.split(",")))  
53 -  
54 - if collect_time:  
55 - begin,end = collect_time.split(",")  
56 - begin:datetime.datetime= datetime.datetime.strptime(begin,"%Y-%m-%d")  
57 -  
58 - end = datetime.datetime.strptime(end, "%Y-%m-%d")  
59 - images = images.filter(Image.collect_time.__ge__(begin)).filter(Image.collect_time.__le__(end))  
60 -  
61 - if tag_guids:  
62 - tag_guids = tag_guids.split(",")  
63 - tags = ImageTag.query.filter(ImageTag.guid.in_(tag_guids)).all()  
64 - images_guid = []  
65 - for tag in tags:  
66 - images_guid.extend([img.guid for img in tag.images.all()])  
67 - images = images.filter(Image.guid.in_(images_guid))  
68 -  
69 -  
70 -  
71 -  
72 - res["data"] = {}  
73 - res["data"]["count"] = images.count()  
74 - imgs = images.limit(page_size).offset(page_index * page_size).all()  
75 - res["data"]["list"] = ModelVisitor.objects_to_jsonarray(imgs)  
76 -  
77 - #格式化数据  
78 - for info in res["data"]["list"]:  
79 - info["size"] = FileProcess.get_text_size(info["size"])  
80 - info["cell_x_size"] = round(info["cell_x_size"],3)  
81 - info["cell_y_size"] = round(info["cell_y_size"], 3)  
82 - res["result"] = True  
83 -  
84 - except Exception as e:  
85 - raise e  
86 -  
87 - return res  
88 -  
89 -  
90 - api_doc = {  
91 - "tags": ["影像接口"],  
92 - "parameters": [  
93 - {"name": "page_index",  
94 - "in": "formData",  
95 - "type": "int",  
96 - "description": "页"},  
97 - {"name": "page_size",  
98 - "in": "formData",  
99 - "type": "int",  
100 - "description": "页大小"},  
101 - {"name": "alias",  
102 - "in": "formData",  
103 - "type": "string"},  
104 - {"name": "name",  
105 - "in": "formData",  
106 - "type": "string"},  
107 - {"name": "collect_time",  
108 - "in": "formData",  
109 - "type": "string"},  
110 - {"name": "region",  
111 - "in": "formData",  
112 - "type": "string"},  
113 - {"name": "type",  
114 - "in": "formData",  
115 - "type": "string"},  
116 - {"name": "band",  
117 - "in": "formData",  
118 - "type": "string"},  
119 - {"name": "tag_guids",  
120 - "in": "formData",  
121 - "type": "string"},  
122 - ],  
123 - "responses": {  
124 - 200: {  
125 - "schema": {  
126 - "properties": {  
127 - }  
128 - }  
129 - }  
130 - }  
131 - }  
132 -  
133 -  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/7/19  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -from app.util.component.ApiTemplate import ApiTemplate  
8 -from app.util.component.StructuredPrint import StructurePrint  
9 -  
10 -from app.modules.service.models import Image  
11 -  
12 -import random  
13 -  
14 -import numpy  
15 -import json  
16 -from flask import Response  
17 -from kazoo.client import KazooClient  
18 -import configure  
19 -import traceback  
20 -  
21 -from .util.ImageData import ImageData  
22 -from .util.Opencv import Opencv  
23 -from app.util.component.ModelVisitor import ModelVisitor  
24 -  
25 -class Api(ApiTemplate):  
26 -  
27 - api_name = "影像数据预览功能"  
28 -  
29 - def process(self):  
30 - from app import GLOBAL_DIC  
31 -  
32 - # 返回结果  
33 - res = {}  
34 -  
35 - try:  
36 -  
37 - #获取  
38 - zoo = GLOBAL_DIC.get("zookeeper")  
39 - if zoo is None:  
40 - zoo :KazooClient = KazooClient(hosts=configure.zookeeper, timeout=100)  
41 - zoo.start()  
42 - GLOBAL_DIC["zookeeper"] = zoo  
43 - StructurePrint().print("连接zoo")  
44 - else :  
45 - if not zoo.connected:  
46 - zoo.start()  
47 -  
48 - guid = self.para.get("guid")  
49 -  
50 - width = int(self.para.get("width") if self.para.get("width") else 512)  
51 - height = int(self.para.get("height") if self.para.get("height") else 512)  
52 - format = self.para.get("format") if self.para.get("format") else "image/jpeg"  
53 -  
54 - image = Image.query.filter_by(guid=guid).one_or_none()  
55 - # 该影像的服务器,随机选取一个  
56 - image_servers = image.server.split(",")  
57 - image_servers = [ser for ser in image_servers if zoo.exists("/rpc/{}".format(ser)) or ser.__eq__("本地服务器") ]  
58 - if len(image_servers) > 0:  
59 - indx = int(random.random() * len(image_servers))  
60 - image_server = image_servers[indx]  
61 - else:  
62 - image_server = "None"  
63 -  
64 - bands = json.loads(image.band_view)  
65 -  
66 -  
67 -  
68 - #计算查询范围,保持正常比例  
69 - query_extent = json.loads(image.extent)  
70 - if query_extent[2]-query_extent[0] > query_extent[3]-query_extent[1]:  
71 - offset = ((query_extent[2]-query_extent[0]) - (query_extent[3]-query_extent[1])) / 2.0  
72 - query_extent = [query_extent[0],query_extent[1] - offset ,query_extent[2],query_extent[3] + offset]  
73 - else:  
74 - offset = ((query_extent[3] - query_extent[1]) - (query_extent[2] - query_extent[0])) / 2.0  
75 - query_extent = [query_extent[0] - offset, query_extent[1], query_extent[2] + offset, query_extent[3]]  
76 -  
77 - image_data = ImageData(image_server, ModelVisitor.object_to_json(image))  
78 -  
79 - pixel_array_t = image_data.get_data(query_extent, bands, height, width)  
80 -  
81 - pixel_array = numpy.zeros((height, width, 3), dtype=int)  
82 -  
83 - for ii in [0, 1, 2]:  
84 - # opencv 颜色排序为BGR  
85 - pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii]  
86 -  
87 - # 将图片生成在内存中,然后直接返回response  
88 - im_data = Opencv.create_image(format, pixel_array, 30)  
89 -  
90 - except Exception as e:  
91 - StructurePrint().print(traceback.format_exc())  
92 - raise e  
93 -  
94 - return Response(im_data, mimetype=format)  
95 -  
96 - api_doc = {  
97 - "tags": ["影像接口"],  
98 - "parameters": [  
99 - {"name": "guid",  
100 - "in": "formData",  
101 - "type": "string"},  
102 - {"name": "height",  
103 - "in": "formData",  
104 - "type": "string"},  
105 - {"name": "width",  
106 - "in": "formData",  
107 - "type": "string"},  
108 - {"name": "format",  
109 - "in": "formData",  
110 - "type": "string",  
111 - "enum":["image/jpeg","image/png"]},  
112 - ],  
113 - "responses": {  
114 - 200: {  
115 - "schema": {  
116 - "properties": {  
117 - }  
118 - }  
119 - }  
120 - }  
121 - }  
122 -  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/7/19  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -from osgeo import gdal,osr  
8 -from osgeo.gdal import Dataset,Band  
9 -from app.util.component.ApiTemplate import ApiTemplate  
10 -from app.modules.service.image.util.ThriftConnect import ThriftConnect  
11 -import json  
12 -from ..models import Image  
13 -import datetime  
14 -from app.models import db  
15 -import uuid  
16 -import os  
17 -from .util.ImageType import ImageType  
18 -from .util.Cache import Cache  
19 -  
20 -class Api(ApiTemplate):  
21 -  
22 - api_name = "refresh影像数据"  
23 -  
24 - def process(self):  
25 -  
26 - #可以注册一个目录  
27 - #返回结果  
28 - res = {}  
29 -  
30 - try:  
31 - guid = self.para.get("guid")  
32 - image:Image = Image.query.filter_by(guid=guid).one_or_none()  
33 -  
34 - image_service_info, zoo, servers = Cache.cache_data(None)  
35 - image_servers = image.server.split(",")  
36 - image_servers = [ser for ser in image_servers if ser in servers]  
37 -  
38 - data_server = image_servers[0]  
39 -  
40 -  
41 - if data_server.__eq__("本地服务器"):  
42 -  
43 - img: Dataset = gdal.Open(image.path, 0)  
44 - geo = img.GetGeoTransform()  
45 -  
46 - origin = osr.SpatialReference()  
47 - origin.ImportFromWkt(img.GetProjection())  
48 -  
49 - authority_code = origin.GetAuthorityCode(None)  
50 - band_count = img.RasterCount  
51 - band: Band = img.GetRasterBand(1)  
52 - count = band.GetOverviewCount()  
53 - nodatavalue = band.GetNoDataValue()  
54 - left_top = (geo[0], geo[3])  
55 -  
56 - right_buttom = (geo[0] + geo[1] * img.RasterXSize, geo[3] + geo[5] * img.RasterYSize)  
57 - origin_extent = [left_top[0], right_buttom[1], right_buttom[0], left_top[1]]  
58 -  
59 - update_info = {"band_count": band_count,  
60 - "band_view":image.band_view if band_count>=3 else "[1,1,1]",  
61 - "overview_count": count,  
62 - "raster_x_size": image.RasterXSize,  
63 - "raster_y_size": image.RasterYSize,  
64 - "cell_x_size": geo[1],  
65 - "cell_y_size": geo[5],  
66 - "extent": origin_extent,  
67 - "null_value": nodatavalue,  
68 - "size":os.path.getsize(image.path),  
69 - "crs_wkt": image.GetProjection(),  
70 - "crs": authority_code,  
71 - "crs_proj4": origin.ExportToProj4(),  
72 - "update_time":datetime.datetime.now()  
73 - }  
74 -  
75 - del img  
76 -  
77 - else:  
78 - thrift_connect = ThriftConnect(data_server)  
79 -  
80 - info = json.loads(thrift_connect.client.getInfo(image.path))  
81 - thrift_connect.close()  
82 -  
83 - update_info = {"band_count": info.get("band_count"),  
84 - "band_view":image.band_view if info.get("band_count")>=3 else "[1,1,1]",  
85 - "overview_count": info.get("overview_count"),  
86 - "raster_x_size" : info["xy_size"][0],  
87 - "raster_y_size" : info["xy_size"][1],  
88 - "cell_x_size" : info.get("cell_x_size"),  
89 - "cell_y_size" : abs(info.get("cell_y_size")),  
90 - "extent": json.dumps(info["origin_extent"]),  
91 - "null_value": info.get("null_value"),  
92 - "size":info.get("size"),  
93 - "crs" : str(info.get("crs")),  
94 - "crs_wkt" : info.get("crs_wkt"),  
95 - "crs_proj4" : info.get("crs_proj4"),  
96 - "update_time":datetime.datetime.now()  
97 - }  
98 - Image.query.filter_by(guid=guid).update(update_info)  
99 - db.session.commit()  
100 - except:  
101 - raise Exception("刷新影像数据信息失败!")  
102 -  
103 - res["result"] = True  
104 - return res  
105 -  
106 - api_doc = {  
107 - "tags": ["影像接口"],  
108 - "parameters": [  
109 - {"name": "guid",  
110 - "in": "formData",  
111 - "type": "string",  
112 - "description": "image_guid"},  
113 - ],  
114 - "responses": {  
115 - 200: {  
116 - "schema": {  
117 - "properties": {  
118 - }  
119 - }  
120 - }  
121 - }  
122 - }  
123 -  
124 -  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/7/19  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -from osgeo import gdal,osr  
8 -from osgeo.gdal import Dataset,Band  
9 -from app.util.component.ApiTemplate import ApiTemplate  
10 -from app.modules.service.image.util.ThriftConnect import ThriftConnect  
11 -import json  
12 -from ..models import Image  
13 -import datetime  
14 -from app.models import db  
15 -import uuid  
16 -import os  
17 -from ..models import ImageTag  
18 -from .util.ImageType import ImageType  
19 -  
20 -class Api(ApiTemplate):  
21 -  
22 - api_name = "注册影像数据"  
23 -  
24 - def process(self):  
25 -  
26 - #可以注册一个目录  
27 - #返回结果  
28 - res = {}  
29 -  
30 - try:  
31 - data_server = self.para.get("data_server")  
32 - paths = json.loads(self.para.get("paths"))  
33 - tag_guids = self.para.get("tag_guids")  
34 - if tag_guids:  
35 - tags = db.session.query(ImageTag).filter(ImageTag.guid.in_(tag_guids.split(","))).all()  
36 - else:  
37 - tags = []  
38 -  
39 -  
40 - #注册某影像  
41 - infos = []  
42 -  
43 - if data_server.__eq__("本地服务器"):  
44 -  
45 - image_paths = list(self.recur_paths_local(paths))  
46 -  
47 - for image_info in image_paths:  
48 -  
49 - image: Dataset = gdal.Open(image_info["path"], 0)  
50 - geo = image.GetGeoTransform()  
51 -  
52 - origin = osr.SpatialReference()  
53 - origin.ImportFromWkt(image.GetProjection())  
54 -  
55 - authority_code = origin.GetAuthorityCode(None)  
56 - band_count = image.RasterCount  
57 - band: Band = image.GetRasterBand(1)  
58 - count = band.GetOverviewCount()  
59 - nodatavalue = band.GetNoDataValue()  
60 - left_top = (geo[0], geo[3])  
61 -  
62 - right_buttom = (geo[0] + geo[1] * image.RasterXSize, geo[3] + geo[5] * image.RasterYSize)  
63 -  
64 -  
65 - origin_extent = [left_top[0], right_buttom[1], right_buttom[0], left_top[1]]  
66 -  
67 -  
68 - info = {"band_count": band_count,  
69 - "band_view":"[1,2,3]" if band_count>=3 else "[1,1,1]",  
70 - "overview_count": count,  
71 - "path":image_info["path"],  
72 - "xy_size": [image.RasterXSize, image.RasterYSize],  
73 - "origin_extent": origin_extent,  
74 - "null_value": nodatavalue,  
75 - "size":os.path.getsize(image_info["path"]),  
76 - "crs_wkt": image.GetProjection(),  
77 - "crs": authority_code,  
78 - "crs_proj4": origin.ExportToProj4(),  
79 - "cell_x_size": geo[1],  
80 - "cell_y_size": geo[5]  
81 - }  
82 -  
83 - infos.append(info)  
84 - del image  
85 -  
86 - #分布式下,从thrift获取信息  
87 - else:  
88 - thrift_connect = ThriftConnect(data_server)  
89 - image_paths = list(self.recur_paths_remote(paths,thrift_connect.client))  
90 - for image_info in image_paths:  
91 - infos.append(json.loads(thrift_connect.client.getInfo(image_info["path"])))  
92 - thrift_connect.close()  
93 -  
94 - this_time = datetime.datetime.now()  
95 -  
96 -  
97 - for info in infos:  
98 -  
99 - exist_image = Image.query.filter_by(path=os.path.normpath(info.get("path")), size=info.get("size")).one_or_none()  
100 - if exist_image:  
101 - if exist_image.server.__contains__(data_server):  
102 - pass  
103 - else:  
104 - Image.query.filter_by(path=os.path.normpath(info.get("path")),  
105 - size=info.get("size")).update({"server":"{},{}".format(exist_image.server,data_server)})  
106 - else:  
107 - img:Image = Image(guid= uuid.uuid1().__str__(),  
108 - overview_count=info.get("overview_count"),  
109 - has_pyramid = 1 if info.get("overview_count")>0 else 0,  
110 - raster_x_size=info["xy_size"][0],  
111 - raster_y_size=info["xy_size"][1],  
112 - cell_x_size = info.get("cell_x_size"),  
113 - cell_y_size = abs(info.get("cell_y_size")),  
114 - name=os.path.basename(info.get("path")),  
115 - alias = os.path.basename(info.get("path")),  
116 - extent=json.dumps(info["origin_extent"]),  
117 - null_value=info.get("null_value"),  
118 - server=data_server,  
119 - path = os.path.normpath(info.get("path")),  
120 - size=info.get("size"),  
121 - crs = str(info.get("crs")),  
122 - crs_wkt = info.get("crs_wkt"),  
123 - crs_proj4= info.get("crs_proj4"),  
124 - band_count=info.get("band_count"),  
125 - band_view = "[1,2,3]" if info.get("band_count")>=3 else "[1,1,1]",  
126 - create_time=this_time,  
127 - update_time=this_time,  
128 - type = ImageType.get_type(info.get("path"))  
129 - )  
130 - for tag in tags:  
131 - img.image_tags.append(tag)  
132 - db.session.add(img)  
133 - db.session.commit()  
134 - res["result"] = True  
135 -  
136 - except Exception as e:  
137 - raise e  
138 -  
139 - return res  
140 -  
141 - def recur_paths_local(self,paths):  
142 - for path in paths:  
143 - if path["type"].__eq__("dir"):  
144 - data_list: list = []  
145 - for f in os.listdir(path["path"]):  
146 - file_path = os.path.normpath(os.path.join(path["path"], f))  
147 - file_info = {"name": f, "path": file_path}  
148 - if file_path.lower().endswith("tiff") or file_path.lower().endswith("tif"):  
149 - file_info["type"] = "tif"  
150 - data_list.append(file_info)  
151 - elif file_path.lower().endswith("img"):  
152 - file_info["type"] = "img"  
153 - data_list.append(file_info)  
154 - elif os.path.isdir(file_path):  
155 - file_info["type"] = "dir"  
156 - data_list.append(file_info)  
157 - for p in self.recur_paths_local(data_list):  
158 - yield p  
159 - else:  
160 - yield path  
161 -  
162 - def recur_paths_remote(self,paths,client):  
163 - for path in paths:  
164 - if path["type"].__eq__("dir"):  
165 - path_list = json.loads(client.getImageList(path["path"]))  
166 - for p in self.recur_paths_remote(path_list,client):  
167 - yield p  
168 - else:  
169 - yield path  
170 - api_doc = {  
171 - "tags": ["影像接口"],  
172 - "parameters": [  
173 - {"name": "data_server",  
174 - "in": "formData",  
175 - "type": "string",  
176 - "description": "data_server"},  
177 - {"name": "paths",  
178 - "in": "formData",  
179 - "type": "string",  
180 - "description": "paths"},  
181 - {"name": "tags",  
182 - "in": "formData",  
183 - "type": "string",  
184 - "description": "tags以,相隔"}  
185 - ],  
186 - "responses": {  
187 - 200: {  
188 - "schema": {  
189 - "properties": {  
190 - }  
191 - }  
192 - }  
193 - }  
194 - }  
195 -  
196 -  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/7/19  
4 -#email: nheweijun@sina.com  
5 -  
6 -from app.util.component.ApiTemplate import ApiTemplate  
7 -  
8 -from kazoo.client import KazooClient  
9 -import configure  
10 -class Api(ApiTemplate):  
11 -  
12 - api_name = "获取数据服务器列表"  
13 -  
14 - def process(self):  
15 -  
16 - # 返回结果  
17 - res = {}  
18 - res["data"] = []  
19 - try:  
20 - zoo :KazooClient = KazooClient(hosts=configure.zookeeper, timeout=1)  
21 - zoo.start()  
22 - sers = zoo.get_children("/rpc")  
23 -  
24 - for p in sers:  
25 - bl = str( zoo.get("/rpc/{}".format(p))[0] , encoding = "utf-8")  
26 - res["data"].append({"name": p, "belong": bl})  
27 - zoo.close()  
28 - except Exception as e:  
29 - pass  
30 - res["data"].append({"name": "本地服务器", "belong": ""})  
31 - res["result"] = True  
32 - return res  
33 -  
34 - api_doc = {  
35 - "tags": ["影像接口"],  
36 - "parameters": [  
37 - ],  
38 - "responses": {  
39 - 200: {  
40 - "schema": {  
41 - "properties": {  
42 - }  
43 - }  
44 - }  
45 - }  
46 - }  
47 -  
48 -if __name__ == '__main__':  
49 - zoo: KazooClient = KazooClient(hosts="172.26.99.168:2181", timeout=100)  
50 - zoo.start()  
51 - print(zoo.get_children("/rpc"))  
52 - zoo.stop()  
53 - zoo.close()  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/7/19  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -from app.util.component.ApiTemplate import ApiTemplate  
8 -from ..models import Service,ImageService,Image,db,ServiceFunction  
9 -import datetime  
10 -import json  
11 -import configure  
12 -import uuid  
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  
21 -class Api(ApiTemplate):  
22 -  
23 - api_name = "修改影像服务"  
24 -  
25 - def process(self):  
26 -  
27 - # 返回结果  
28 - res = {}  
29 -  
30 - try:  
31 -  
32 - guid = self.para.get("guid")  
33 - service = Service.query.filter_by(guid=guid)  
34 - this_time = datetime.datetime.now()  
35 - image_guids = self.para.get("image_guids")  
36 - functions = self.para.get("functions")  
37 -  
38 - service_update = {}  
39 - image_update = {}  
40 -  
41 - for key in self.para.keys():  
42 - if key in ["name","title","state","description","catalog_guid"]:  
43 - service_update[key] = self.para.get(key)  
44 - if key in ["name","scheme_guid"]:  
45 - image_update[key] = self.para.get(key)  
46 -  
47 - image_service = ImageService.query.filter_by(service_guid=guid)  
48 -  
49 - # 修改功能  
50 - if functions:  
51 - new_types = functions.split(",")  
52 - old_functions = ServiceFunction.query.filter_by(service_guid=guid).all()  
53 - for function in old_functions:  
54 - if function.type not in new_types:  
55 - db.session.delete(function)  
56 - for new_type in new_types:  
57 - if new_type not in [fun.type for fun in old_functions]:  
58 - service_function = ServiceFunction(guid=uuid.uuid1().__str__(),type=new_type,  
59 - service_guid=guid)  
60 - db.session.add(service_function)  
61 -  
62 - #修改影像  
63 - image_service_exetent = []  
64 - if image_guids:  
65 - imgservice:ImageService = image_service.one_or_none()  
66 - imgservice.images = []  
67 -  
68 - for g in image_guids.split(","):  
69 - image = Image.query.filter_by(guid=g).one_or_none()  
70 - if image:  
71 - image_extent = json.loads(image.extent)  
72 - if not image_service_exetent:  
73 - image_service_exetent = image_extent  
74 - else:  
75 - image_service_exetent[0] = min(image_extent[0], image_service_exetent[0])  
76 - image_service_exetent[1] = min(image_extent[1], image_service_exetent[1])  
77 - image_service_exetent[2] = max(image_extent[2], image_service_exetent[2])  
78 - image_service_exetent[3] = max(image_extent[3], image_service_exetent[3])  
79 - imgservice.images.append(image)  
80 - image_update["extent"] = json.dumps(image_service_exetent)  
81 -  
82 - if image_update:  
83 - image_service.update(image_update)  
84 -  
85 - if service_update or image_update or functions:  
86 - service_update["update_time"] = this_time  
87 -  
88 - if image_guids:  
89 - overview_file = self.get_overview(image_guids,image_service_exetent)  
90 - service_update["overview"] = "http://{}/API/Service/Overview/{}".format(configure.deploy_ip_host, overview_file)  
91 -  
92 - service.update(service_update)  
93 -  
94 - db.session.commit()  
95 - res["result"] = True  
96 -  
97 - except Exception as e:  
98 - db.session.rollback()  
99 - raise e  
100 -  
101 - return res  
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)  
220 -  
221 - api_doc = {  
222 - "tags": ["影像接口"],  
223 - "parameters": [  
224 -  
225 - {"name": "guid",  
226 - "in": "formData",  
227 - "type": "string",  
228 - "description": "[地图服务,切片服务,影像服务]guid"},  
229 -  
230 - {"name": "name",  
231 - "in": "formData",  
232 - "type": "string",  
233 - "description": "[地图服务,切片服务,影像服务]"},  
234 -  
235 -  
236 - {"name": "title",  
237 - "in": "formData",  
238 - "type": "string",  
239 - "description": "[地图服务,切片服务,影像服务]"},  
240 - {"name": "description",  
241 - "in": "formData",  
242 - "type": "string",  
243 - "description": "[地图服务,切片服务,影像服务]"},  
244 -  
245 - {"name": "catalog_guid",  
246 - "in": "formData",  
247 - "type": "string",  
248 - "description": "[地图服务,切片服务,影像服务]"},  
249 -  
250 - {"name": "functions",  
251 - "in": "formData",  
252 - "type": "string",  
253 - "description": "[地图服务,切片服务,影像服务]以逗号相隔,可选WMTS,WMS"},  
254 -  
255 -  
256 - {"name": "image_guids",  
257 - "in": "formData",  
258 - "type": "string","description":"修改该服务的影像,用逗号相隔"},  
259 - ],  
260 - "responses": {  
261 - 200: {  
262 - "schema": {  
263 - "properties": {  
264 - }  
265 - }  
266 - }  
267 - }  
268 - }  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/7/19  
4 -#email: nheweijun@sina.com  
5 -  
6 -  
7 -from ..models import db,Service,ImageService,Image,ServiceFunction  
8 -from app.util.component.ApiTemplate import ApiTemplate  
9 -import uuid  
10 -  
11 -import os  
12 -import json  
13 -import datetime  
14 -from .image_wms import Api as RealApi  
15 -import cv2  
16 -import configure  
17 -  
18 -class Api(ApiTemplate):  
19 -  
20 - api_name = "注册影像服务"  
21 -  
22 - def para_check(self):  
23 - if not self.para.get("function_types"):  
24 - raise Exception("缺乏影像服务类型!")  
25 - if self.para.get("function_types").__contains__("WMTS") and (not self.para.get("scheme_guid")):  
26 - raise Exception("选择WMTS功能,但是缺乏切片方案!")  
27 -  
28 -  
29 - def process(self):  
30 -  
31 - # 返回结果  
32 - res = {}  
33 -  
34 - try:  
35 - guids = self.para.get("image_guids").split(",")  
36 - name = self.para.get("name")  
37 - functions = self.para.get("functions")  
38 -  
39 -  
40 - image_service_guid = uuid.uuid1().__str__()  
41 - service_guid = uuid.uuid1().__str__()  
42 -  
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 - image_service = ImageService(guid=image_service_guid,  
61 - name=name,  
62 - create_time=this_time,  
63 - scheme_guid=self.para.get("scheme_guid"),  
64 - crs = Image.query.filter_by(guid=guids[0]).one_or_none().crs,  
65 - service_guid=service_guid  
66 - )  
67 -  
68 - db.session.add(image_service)  
69 -  
70 - image_service_exetent = []  
71 -  
72 - for g in guids:  
73 - image = Image.query.filter_by(guid=g).one_or_none()  
74 - if image:  
75 - image_extent = json.loads(image.extent)  
76 - if not image_service_exetent:  
77 - image_service_exetent = image_extent  
78 - else:  
79 - image_service_exetent[0] = min(image_extent[0],image_service_exetent[0])  
80 - image_service_exetent[1] = min(image_extent[1], image_service_exetent[1])  
81 - image_service_exetent[2] = max(image_extent[2], image_service_exetent[2])  
82 - image_service_exetent[3] = max(image_extent[3], image_service_exetent[3])  
83 -  
84 - image_service.images.append(image)  
85 - image_service.extent = json.dumps(image_service_exetent)  
86 -  
87 -  
88 - for type in functions.split(","):  
89 - service_function_guid = uuid.uuid1().__str__()  
90 - service_function = ServiceFunction(guid=service_function_guid,  
91 - service_guid=service_guid,  
92 - type=type)  
93 - db.session.add(service_function)  
94 -  
95 -  
96 - #获得overview  
97 - overview_file = self.get_overview(service,image_service)  
98 - service.overview="http://{}/API/Service/Overview/{}".format(  
99 - configure.deploy_ip_host,overview_file)  
100 -  
101 - db.session.commit()  
102 - res["data"] = service_guid  
103 - res["result"] = True  
104 - except Exception as e:  
105 - db.session.rollback()  
106 - raise e  
107 -  
108 - return res  
109 -  
110 - def get_overview(self,service,image_service):  
111 -  
112 - api = RealApi(service.name)  
113 -  
114 -  
115 - query_extent = json.loads(image_service.extent)  
116 - if query_extent[2] - query_extent[0] > query_extent[3] - query_extent[1]:  
117 - offset = ((query_extent[2] - query_extent[0]) - (query_extent[3] - query_extent[1])) / 2.0  
118 - query_extent = [query_extent[0], query_extent[1] - offset, query_extent[2], query_extent[3] + offset]  
119 - else:  
120 - offset = ((query_extent[3] - query_extent[1]) - (query_extent[2] - query_extent[0])) / 2.0  
121 - query_extent = [query_extent[0] - offset, query_extent[1], query_extent[2] + offset, query_extent[3]]  
122 -  
123 - bbox = ",".join([str(x) for x in query_extent])  
124 -  
125 - api.para = {"service_name":service.name,"bbox":bbox,"overview":1,"width":512,"height":512}  
126 - res = api.process()  
127 - dir_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "overview")  
128 - gid = uuid.uuid1().__str__()  
129 - store_file = os.path.join(dir_path, "{}.jpg".format(gid))  
130 - cv2.imwrite(store_file, res, [cv2.IMWRITE_JPEG_QUALITY, 30])  
131 -  
132 - return "{}.jpg".format(gid)  
133 -  
134 -  
135 -  
136 -  
137 - api_doc = {  
138 - "tags": ["影像接口"],  
139 - "parameters": [  
140 -  
141 - # 通用参数  
142 - {"name": "name",  
143 - "in": "formData",  
144 - "type": "string",  
145 - "required": "true",  
146 - "description": "[地图服务,切片服务,影像服务]"},  
147 - {"name": "title",  
148 - "in": "formData",  
149 - "type": "string",  
150 - "description": "[地图服务,切片服务,影像服务]"},  
151 - {"name": "description",  
152 - "in": "formData",  
153 - "type": "string",  
154 - "description": "[地图服务,切片服务,影像服务]"},  
155 - {"name": "type",  
156 - "in": "formData",  
157 - "type": "string",  
158 - "enum": ["地图服务","切片服务","影像服务"],  
159 - "required": "true",  
160 - "description": "[地图服务,切片服务,影像服务]"},  
161 - {"name": "catalog_guid",  
162 - "in": "formData",  
163 - "type": "string",  
164 - "description": "[地图服务,切片服务,影像服务]"},  
165 -  
166 - # 影像参数  
167 - {"name": "image_guids",  
168 - "in": "formData",  
169 - "type": "string",  
170 - "description": "[影像服务]影像guids,以英文逗号相隔"},  
171 - {"name": "scheme_guid",  
172 - "in": "formData",  
173 - "type": "string",  
174 - "description": "[影像服务]切片方案"},  
175 - {"name": "functions",  
176 - "in": "formData",  
177 - "type": "string",  
178 - "description": "[影像服务]功能类型,以逗号相隔,可选WMTS,WMS"},  
179 - {"name": "cql",  
180 - "in": "formData",  
181 - "type": "string",  
182 - "description": "分层分级的CQL"},  
183 - {"name": "cql_table_guid",  
184 - "in": "formData",  
185 - "type": "string",  
186 - "description": "分层分级的CQL table_guid"},  
187 -  
188 - ],  
189 - "responses": {  
190 - 200: {  
191 - "schema": {  
192 - "properties": {  
193 - }  
194 - }  
195 - }  
196 - }  
197 - }  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/3/24  
4 -#email: nheweijun@sina.com  
5 -  
6 -import traceback  
7 -import numpy  
8 -from flask import Response  
9 -from .util.ImageData import ImageData  
10 -  
11 -from app.util.component.ApiTemplate import ApiTemplate  
12 -from app.util.component.SliceScheme import SliceScheme  
13 -from app.util.component.ParameterUtil import ParameterUtil  
14 -import json  
15 -import random  
16 -import copy  
17 -from .util.Opencv import Opencv  
18 -from .util.Cache import Cache  
19 -from .util.MyThread import MyThread  
20 -  
21 -class Api(ApiTemplate):  
22 -  
23 - api_name = "切片"  
24 -  
25 - def __init__(self,guid,level, row, col):  
26 - super().__init__()  
27 - self.guid = guid  
28 - self.level = level  
29 - self.row = row  
30 - self.col = col  
31 -  
32 - def process(self):  
33 -  
34 - result = {}  
35 - parameter: dict = self.para  
36 -  
37 - try:  
38 - if parameter.get("guid"):  
39 - self.guid = parameter.get("guid")  
40 -  
41 - image_service_info, zoo, servers = Cache.cache_data(self.guid)  
42 -  
43 - # bands = [1, 2, 3]  
44 -  
45 - # 转换参数  
46 - parameter = ParameterUtil.to_lower(parameter)  
47 -  
48 - if parameter.get("tilematrix"):  
49 - if parameter.get("tilematrix").__contains__(":"):  
50 - self.level = int(parameter.get("tilematrix").split(":")[-1])  
51 - else:  
52 - self.level = int(parameter.get("tilematrix"))  
53 - if parameter.get("tilerow"):  
54 - self.row = int(parameter.get("tilerow"))  
55 - if parameter.get("tilecol"):  
56 - self.col = int(parameter.get("tilecol"))  
57 -  
58 - image_type = parameter.get("format") if parameter.get("format") else "image/png"  
59 - quality = int(parameter.get("quality")) if parameter.get("quality") else 30  
60 - slice_para = image_service_info["scheme"]  
61 - extent = SliceScheme.get_polygon(slice_para, self.level, self.row, self.col)  
62 -  
63 - height, width = 256,256  
64 -  
65 -  
66 - re = parameter.get("request")  
67 - if re and re.__eq__("GetCapabilities"):  
68 - return self.get_capabilities(image_service_info["service"])  
69 -  
70 - # 多线程获取分布式数据  
71 -  
72 - intersect_image = [im for im in image_service_info["images"] if self.determin_intersect(json.loads(im.extent),extent)]  
73 -  
74 - if len(intersect_image) > 1:  
75 -  
76 - # 结果矩阵  
77 - pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536  
78 -  
79 - thread_list = []  
80 -  
81 - for image in intersect_image:  
82 -  
83 - # 该影像的服务器,随机选取一个  
84 - image_servers = image.server.split(",")  
85 - image_servers = [ser for ser in image_servers if ser in servers]  
86 - if len(image_servers)>0:  
87 - indx = int(random.random() * len(image_servers))  
88 - image_server = image_servers[indx]  
89 - else:  
90 - image_server = "None"  
91 -  
92 - bands = json.loads(image.band_view)  
93 -  
94 - image_data = ImageData(image_server,image)  
95 -  
96 - thread: MyThread = MyThread(image_data.get_data,args=(extent, bands, height, width))  
97 -  
98 - thread.start()  
99 - thread_list.append(thread)  
100 -  
101 - for thread in thread_list:  
102 - thread.join()  
103 - data = thread.get_result()  
104 -  
105 - # 掩膜在中央接口生成,合图  
106 - mask = numpy.zeros((height, width, 3), dtype=int)  
107 - mask_data = numpy.zeros((height, width, 3), dtype=int)  
108 -  
109 - mask[data == 65536] = 1  
110 - mask[data != 65536] = 0  
111 - mask_data[data == 65536] = 0  
112 - mask_data[data != 65536] = 1  
113 -  
114 - # # 掩膜计算  
115 - pixel_array = pixel_array * mask + data * mask_data  
116 -  
117 - # opencv 颜色排序为GBR  
118 - d1 = copy.copy(pixel_array[:,:,0])  
119 - pixel_array[:, :, 0] = pixel_array[:,:,2]  
120 - pixel_array[:, :, 2] = d1  
121 -  
122 -  
123 - elif len(intersect_image) == 1:  
124 - # 该影像的服务器,随机选取一个  
125 - image = intersect_image[0]  
126 - image_servers = image.server.split(",")  
127 - #判断可用服务器  
128 - image_servers = [ser for ser in image_servers if ser in servers]  
129 - if len(image_servers) > 0:  
130 - indx = int(random.random() * len(image_servers))  
131 - image_server = image_servers[indx]  
132 - else:  
133 - image_server = "None"  
134 - # image_server = image_servers[0]  
135 - bands = json.loads(image.band_view)  
136 -  
137 - image_data = ImageData(image_server, image)  
138 - pixel_array_t: numpy.ndarray = image_data.get_data(extent, bands, height, width)  
139 - pixel_array = numpy.zeros((height, width, 3), dtype=int)  
140 -  
141 - for ii in [0, 1, 2]:  
142 - # opencv 颜色排序为GBR  
143 - pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii]  
144 -  
145 - else:  
146 - # 结果矩阵  
147 - pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536  
148 -  
149 -  
150 - # 将图片生成在内存中,然后直接返回response  
151 - im_data = Opencv.create_image(image_type, pixel_array, quality)  
152 - return Response(im_data, mimetype=image_type.lower())  
153 -  
154 -  
155 - except Exception as e:  
156 - print(traceback.format_exc())  
157 - result["result"] = False  
158 - result["message"] = e.__str__()  
159 - return result  
160 -  
161 -  
162 -  
163 -  
164 -  
165 -  
166 - def get_capabilities(self):  
167 - return {}  
168 -  
169 -  
170 -  
171 - def determin_intersect(self, extent1, extent2):  
172 - if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[  
173 - 3] or extent2[3] < extent1[1]:  
174 - return False  
175 - else:  
176 - return True  
177 -  
178 -  
179 - api_doc = {  
180 - "tags": ["影像接口"],  
181 - "parameters": [  
182 - {"name": "guid",  
183 - "in": "formData",  
184 - "type": "string"},  
185 - {"name": "tilematrix",  
186 - "in": "formData",  
187 - "type": "string"},  
188 - {"name": "tilerow",  
189 - "in": "formData",  
190 - "type": "string"},  
191 - {"name": "tilecol",  
192 - "in": "formData",  
193 - "type": "string"},  
194 - {"name": "format",  
195 - "in": "formData",  
196 - "type": "string"},  
197 - {"name": "quality",  
198 - "in": "formData",  
199 - "type": "string"}  
200 -  
201 - ],  
202 - "responses": {  
203 - 200: {  
204 - "schema": {  
205 - "properties": {  
206 - }  
207 - }  
208 - }  
209 - }  
210 - }  
211 -  
212 -  
213 -  
1 -# coding=utf-8  
2 -#author: 4N  
3 -#createtime: 2021/3/24  
4 -#email: nheweijun@sina.com  
5 -  
6 -from app.util import *  
7 -import traceback  
8 -from osgeo import gdal  
9 -from osgeo.gdal import *  
10 -from numpy import ndarray  
11 -import numpy  
12 -from flask import Response  
13 -  
14 -import time  
15 -import cv2  
16 -from app.modules.service.models import ImageService,Image  
17 -from ..models import db,TileScheme  
18 -from app.util.component.ApiTemplate import ApiTemplate  
19 -  
20 -from app.util.component.SliceScheme import SliceScheme  
21 -  
22 -from app.util.component.ParameterUtil import ParameterUtil  
23 -from app.util.component.GeometryAdapter import GeometryAdapter  
24 -from app.util.component.Geometry2Raster import Geometry2Raster  
25 -  
26 -import json  
27 -from kazoo.client import KazooClient  
28 -  
29 -from threading import Thread  
30 -  
31 -from app.modules.service.image.util.ThriftConnect import ThriftConnect  
32 -from flask import current_app  
33 -import gzip  
34 -import random  
35 -class Api(ApiTemplate):  
36 -  
37 - api_name = "切片"  
38 -  
39 - def __init__(self,guid,level, row, col):  
40 - super().__init__()  
41 - self.guid = guid  
42 - self.level = level  
43 - self.row = row  
44 - self.col = col  
45 -  
46 - def process(self):  
47 - from app import GLOBAL_DIC  
48 - result = {}  
49 - parameter: dict = self.para  
50 -  
51 -  
52 -  
53 -  
54 -  
55 - try:  
56 - if parameter.get("guid"):  
57 - self.guid = parameter.get("guid")  
58 -  
59 - #缓存服务信息  
60 - image_service_info = GLOBAL_DIC.get(self.guid)  
61 -  
62 - if image_service_info is None:  
63 - image_service:ImageService = ImageService.query.filter_by(guid = self.guid).one_or_none()  
64 - images = image_service.images.all()  
65 - scheme:TileScheme = TileScheme.query.filter_by(guid=image_service.scheme_guid).one_or_none()  
66 -  
67 - # test mask  
68 - ring = ogr.Geometry(ogr.wkbLinearRing)  
69 - ring.AddPoint(111.62, 29)  
70 - ring.AddPoint(111.62, 29.03)  
71 - ring.AddPoint(111.727, 29.03)  
72 - ring.AddPoint(111.727, 29)  
73 - ring.AddPoint(111.62, 29)  
74 - # Create polygon  
75 - mask_poly = ogr.Geometry(ogr.wkbPolygon)  
76 - mask_poly.AddGeometry(ring)  
77 -  
78 - GLOBAL_DIC[self.guid] = {"service": image_service, "images": images,  
79 - "scheme": json.loads(scheme.parameter),"mask":  
80 - mask_poly}  
81 -  
82 -  
83 - image_service_info = GLOBAL_DIC[self.guid]  
84 - else:  
85 - image_service_info = GLOBAL_DIC[self.guid]  
86 -  
87 - zoo = GLOBAL_DIC.get("zookeeper")  
88 - if zoo is None:  
89 - zoo :KazooClient = KazooClient(hosts=configure.zookeeper, timeout=100)  
90 - zoo.start()  
91 - GLOBAL_DIC["zookeeper"] = zoo  
92 - else :  
93 - if not zoo.connected:  
94 - zoo.start()  
95 -  
96 - bands = [1, 2, 3]  
97 -  
98 -  
99 - # 转换参数  
100 - parameter = ParameterUtil.to_lower(parameter)  
101 -  
102 -  
103 - if parameter.get("tilematrix"):  
104 - if parameter.get("tilematrix").__contains__(":"):  
105 - self.level = int(parameter.get("tilematrix").split(":")[-1])  
106 - else:  
107 - self.level = int(parameter.get("tilematrix"))  
108 - if parameter.get("tilerow"):  
109 - self.row = int(parameter.get("tilerow"))  
110 - if parameter.get("tilecol"):  
111 - self.col = int(parameter.get("tilecol"))  
112 -  
113 - image_type = parameter.get("format") if parameter.get("format") else "image/png"  
114 - quality = int(parameter.get("quality")) if parameter.get("quality") else 30  
115 - slice_para = image_service_info["scheme"]  
116 - extent = SliceScheme.get_polygon(slice_para, self.level, self.row, self.col)  
117 -  
118 -  
119 - height, width = 256,256  
120 -  
121 - # 多线程获取分布式数据  
122 -  
123 - intersect_image = [im for im in image_service_info["images"] if  
124 - self.determin_intersect(json.loads(im.extent), extent,image_service_info["mask"])]  
125 -  
126 - masker_raster = Geometry2Raster.convert(image_service_info["mask"],extent,height)  
127 -  
128 - if len(intersect_image) > 1:  
129 -  
130 - # 结果矩阵  
131 - empty_list = [numpy.zeros((height, width), dtype=int) + 65536,  
132 - numpy.zeros((height, width), dtype=int) + 65536,  
133 - numpy.zeros((height, width), dtype=int) + 65536]  
134 -  
135 - pixel_array = numpy.zeros((height, width, 3), dtype=int)  
136 - thread_list = []  
137 -  
138 - for image in intersect_image:  
139 - # 该影像的服务器,随机选取一个  
140 - image_servers = image.server.split(",")  
141 - image_servers = [ser for ser in image_servers if zoo.exists("/rpc/{}".format(ser))]  
142 - if len(image_servers)>0:  
143 - indx = int(random.random() * len(image_servers))  
144 - image_server = image_servers[indx]  
145 - else:  
146 - image_server = "None"  
147 -  
148 - thread: MyThread = MyThread(self.get_data,  
149 - args=(image_server, image, extent, bands, height, width))  
150 - thread.start()  
151 - thread_list.append(thread)  
152 -  
153 - for thread in thread_list:  
154 - thread.join()  
155 - data = thread.get_result()  
156 -  
157 - # 掩膜在中央接口生成,合图  
158 - mask = numpy.zeros((height, width), dtype=int)  
159 - mask2 = numpy.zeros((height, width), dtype=int)  
160 - jizhun = data[:, :, 0]  
161 - mask[jizhun == 65536] = 1  
162 - mask[jizhun != 65536] = 0  
163 - mask2[jizhun == 65536] = 0  
164 - mask2[jizhun != 65536] = 1  
165 - # 掩膜计算  
166 - for i, d in enumerate(empty_list):  
167 - empty_list[i] = empty_list[i] * mask + data[:, :, i] * mask2  
168 -  
169 - e = numpy.zeros((height, width), dtype=int) + 65536  
170 - e_mask = numpy.zeros((height, width), dtype=int)  
171 - e_mask[masker_raster == 1] = 0  
172 - e_mask[masker_raster == 0] = 1  
173 -  
174 - for ii in [0, 1, 2]:  
175 - # opencv 颜色排序为GBR  
176 - # pixel_array[:, :, 2 - ii] = empty_list[ii]  
177 - #mask  
178 - pixel_array[:, :, 2 - ii] = e * e_mask + empty_list[ii] * masker_raster  
179 -  
180 - elif len(intersect_image) == 1:  
181 - # 该影像的服务器,随机选取一个  
182 - image = intersect_image[0]  
183 - image_servers = image.server.split(",")  
184 - #判断可用服务器  
185 - image_servers = [ser for ser in image_servers if zoo.exists("/rpc/{}".format(ser))]  
186 - if len(image_servers) > 0:  
187 - indx = int(random.random() * len(image_servers))  
188 - image_server = image_servers[indx]  
189 - else:  
190 - image_server = "None"  
191 - pixel_array_t = self.get_data(image_server, image, extent, bands, height, width)  
192 - pixel_array = numpy.zeros((height, width, 3), dtype=int)  
193 -  
194 - e = numpy.zeros((height, width), dtype=int) + 65536  
195 - e_mask = numpy.zeros((height, width), dtype=int)  
196 - e_mask[masker_raster == 1] = 0  
197 - e_mask[masker_raster == 0] = 1  
198 -  
199 - for ii in [0, 1, 2]:  
200 - # opencv 颜色排序为GBR  
201 - # pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii]  
202 - pixel_array[:, :, 2 - ii] = e * e_mask + pixel_array_t[:, :, ii] * masker_raster  
203 - else:  
204 - # 结果矩阵  
205 - pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536  
206 -  
207 -  
208 - # 将图片生成在内存中,然后直接返回response  
209 - im_data = self.create_by_opencv(image_type, pixel_array, quality)  
210 - return Response(im_data, mimetype=image_type.lower())  
211 -  
212 - except Exception as e:  
213 - print(traceback.format_exc())  
214 - result["result"] = False  
215 - result["message"] = e.__str__()  
216 - return result  
217 -  
218 - def determine_level(self, xysize, origin_extent, extent, max_level):  
219 - '''  
220 - 根据范围判断调用金字塔的哪一层  
221 - :param xysize:  
222 - :param origin_extent:  
223 - :param extent:  
224 - :param max_level:  
225 - :return:  
226 - '''  
227 - x = xysize[0]  
228 - y = xysize[1]  
229 - level = -1  
230 - pixel = x * y * (((extent[2] - extent[0]) * (extent[3] - extent[1])) / (  
231 - (origin_extent[2] - origin_extent[0]) * (origin_extent[3] - origin_extent[1])))  
232 - while pixel > 100000 and level < max_level - 1:  
233 - level += 1  
234 - x = x / 2  
235 - y = y / 2  
236 - pixel = x * y * (((extent[2] - extent[0]) * (extent[3] - extent[1])) / (  
237 - (origin_extent[2] - origin_extent[0]) * (origin_extent[3] - origin_extent[1])))  
238 - return level  
239 -  
240 - def create_by_opencv(self, image_type, pixel_array, quality):  
241 -  
242 - if image_type.__eq__("image/jpeg") or image_type.__eq__("image/jpg"):  
243 - r, buf = cv2.imencode(".jpg", pixel_array, [cv2.IMWRITE_JPEG_QUALITY, quality])  
244 - image_out = buf.tobytes()  
245 - else:  
246 - height, width = pixel_array[:, :, 0].shape  
247 - four = numpy.zeros((height, width), dtype=int) + 255  
248 - four[pixel_array[:, :, 0] == 65536] = 0  
249 - r, buf = cv2.imencode(".png", numpy.dstack((pixel_array, four)))  
250 - image_out = buf.tobytes()  
251 - return image_out  
252 -  
253 - def get_data(self,image_server, image, extent, bands, height, width):  
254 -  
255 - if image_server.__eq__("本地服务器"):  
256 - data = self.get_local_wms_data(image, extent, bands, height, width)  
257 - elif image_server.__eq__("None"):  
258 - data = numpy.zeros((height, width, 3), dtype=int) + 65536  
259 - else:  
260 - data = self.get_remote_wms_data(image_server,image, extent, bands, height, width)  
261 - return data  
262 -  
263 - def get_remote_wms_data(self, image_server,image, extent, bands, height, width):  
264 - '''  
265 - 通过RPC获取远程数据  
266 - :param image:  
267 - :param extent:  
268 - :param bands:  
269 - :return:  
270 - '''  
271 -  
272 - #需要做thrift连接的缓存,连接池  
273 - thrift_connect = ThriftConnect(image_server)  
274 - image_extent = image.extent  
275 -  
276 - data = thrift_connect.client.getData(image.path, extent, json.loads(image_extent), bands, width, height)  
277 -  
278 - thrift_connect.close()  
279 -  
280 - data = gzip.decompress(data)  
281 - data = numpy.frombuffer(data, dtype='int64')  
282 - data = data.reshape((height, width, 3))  
283 -  
284 - return data  
285 -  
286 - def get_local_wms_data(self, image, extent, bands, height, width):  
287 - '''  
288 - 获取本地数据  
289 - :param image:  
290 - :param extent:  
291 - :param bands:  
292 - :return:  
293 - '''  
294 - pixel_array = numpy.zeros((height, width, 3), dtype=int)  
295 - ceng = 0  
296 - img: Dataset = gdal.Open(image.path, 0)  
297 - t1 = time.time()  
298 - for band in bands:  
299 -  
300 - # 自决定金字塔等级  
301 - xysize = [img.RasterXSize, img.RasterYSize]  
302 -  
303 - origin_extent = image.extent  
304 - band_data: Band = img.GetRasterBand(band)  
305 -  
306 - max_level = band_data.GetOverviewCount()  
307 -  
308 - # 超出空间范围  
309 - if extent[2] < origin_extent[0] or extent[0] > origin_extent[2] or extent[1] > origin_extent[  
310 - 3] or extent[3] < origin_extent[1]:  
311 - empty = numpy.zeros((height, width), dtype=int) + 65536  
312 - # 空间范围相交  
313 - else:  
314 - image_level = self.determine_level(xysize, origin_extent, extent, max_level)  
315 -  
316 - if image_level == -1:  
317 - overview = band_data  
318 - else:  
319 - try:  
320 - overview: Band = band_data.GetOverview(image_level)  
321 - except:  
322 - raise Exception("该影像不存在该级别的金字塔数据!")  
323 - ox = overview.XSize  
324 - oy = overview.YSize  
325 -  
326 - # 网格大小  
327 - grid_x = (origin_extent[2] - origin_extent[0]) / (ox * 1.0)  
328 - grid_y = (origin_extent[3] - origin_extent[1]) / (oy * 1.0)  
329 -  
330 - # 完全在影像范围内  
331 - if extent[0] > origin_extent[0] and extent[1] > origin_extent[1] and extent[2] < \  
332 - origin_extent[2] and extent[3] < origin_extent[3]:  
333 -  
334 - # 网格偏移量  
335 - off_x = math.floor((extent[0] - origin_extent[0]) / grid_x)  
336 - off_y = math.floor((origin_extent[3] - extent[3]) / grid_y)  
337 -  
338 - # 截取后网格个数  
339 - x_g = math.ceil((extent[2] - extent[0]) / grid_x)  
340 -  
341 - y_g = math.ceil((extent[3] - extent[1]) / grid_y)  
342 -  
343 - empty = overview.ReadAsArray(off_x, off_y, x_g, y_g, width, height)  
344 -  
345 -  
346 - # 部分相交  
347 - else:  
348 -  
349 - inter_extent = [0, 0, 0, 0]  
350 - inter_extent[0] = origin_extent[0] if origin_extent[0] > extent[0] else extent[0]  
351 - inter_extent[1] = origin_extent[1] if origin_extent[1] > extent[1] else extent[1]  
352 - inter_extent[2] = origin_extent[2] if origin_extent[2] < extent[2] else extent[2]  
353 - inter_extent[3] = origin_extent[3] if origin_extent[3] < extent[3] else extent[3]  
354 -  
355 - # 网格偏移量  
356 - off_x = math.floor((inter_extent[0] - origin_extent[0]) / grid_x)  
357 - off_y = math.floor((origin_extent[3] - inter_extent[3]) / grid_y)  
358 -  
359 - # 截取后网格个数  
360 - x_g = math.floor((inter_extent[2] - inter_extent[0]) / grid_x)  
361 - y_g = math.floor((inter_extent[3] - inter_extent[1]) / grid_y)  
362 -  
363 - # 相对于出图的偏移量  
364 -  
365 - # 出图的网格大小  
366 - out_grid_x = (extent[2] - extent[0]) / (width * 1.0)  
367 - out_grid_y = (extent[3] - extent[1]) / (height * 1.0)  
368 -  
369 - out_off_x = int(math.ceil((inter_extent[0] - extent[0]) / out_grid_x))  
370 - out_off_y = int(math.ceil((extent[3] - inter_extent[3]) / out_grid_y))  
371 -  
372 - out_x_g = int(math.floor((inter_extent[2] - inter_extent[0]) / out_grid_x))  
373 - out_y_g = int(math.floor((inter_extent[3] - inter_extent[1]) / out_grid_y))  
374 -  
375 - # 相交部分在出图的哪个位置  
376 -  
377 - overview_raster: ndarray = overview.ReadAsArray(off_x, off_y, x_g, y_g, out_x_g,  
378 - out_y_g)  
379 -  
380 - dat = numpy.zeros((height, width), dtype=int) + 65536  
381 - dat[out_off_y:out_off_y + out_y_g, out_off_x:out_off_x + out_x_g] = overview_raster  
382 -  
383 - empty = dat  
384 -  
385 - pixel_array[:, :, ceng] = empty  
386 - ceng += 1  
387 - return pixel_array  
388 -  
389 -  
390 - def determin_intersect(self, extent1, extent2, mask):  
391 - g1 = GeometryAdapter.bbox_2_polygon(extent1)  
392 - g2 = GeometryAdapter.bbox_2_polygon(extent2)  
393 - if g1.Intersect(g2):  
394 - return g2.Intersect(mask)  
395 - else:  
396 - return False  
397 -  
398 - api_doc = {  
399 - "tags": ["影像接口"],  
400 - "parameters": [  
401 - {"name": "guid",  
402 - "in": "formData",  
403 - "type": "string"},  
404 - {"name": "tilematrix",  
405 - "in": "formData",  
406 - "type": "string"},  
407 - {"name": "tilerow",  
408 - "in": "formData",  
409 - "type": "string"},  
410 - {"name": "tilecol",  
411 - "in": "formData",  
412 - "type": "string"},  
413 - {"name": "format",  
414 - "in": "formData",  
415 - "type": "string"},  
416 - {"name": "quality",  
417 - "in": "formData",  
418 - "type": "string"}  
419 -  
420 - ],  
421 - "responses": {  
422 - 200: {  
423 - "schema": {  
424 - "properties": {  
425 - }  
426 - }  
427 - }  
428 - }  
429 - }  
430 -  
431 -class MyThread(Thread):  
432 - def __init__(self,func,args=()):  
433 - super(MyThread,self).__init__()  
434 - self.func = func  
435 - self.args = args  
436 - def run(self):  
437 - self.result = self.func(*self.args)  
438 - def get_result(self):  
439 - try:  
440 - return self.result  
441 - except Exception:  
442 - return None  
443 -  
444 -  
445 -  
注册登录 后发表评论