提交 27524217be13577d58f8b2f0348779110dc6f993

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

要显示太多修改。

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

... ... @@ -22,6 +22,9 @@ class Api(ApiTemplate):
22 22 for cata in catalogs:
23 23 catalog_guids = [c.guid for c in Catalog.query.filter(Catalog.path.like("%" + cata.guid + "%")).all()]
24 24 table_count = Table.query.filter(Table.catalog_guid.in_(catalog_guids)).count()
  25 +
  26 +
  27 +
25 28 database_alias = cata.relate_database.alias
26 29 cata_json = ModelVisitor.object_to_json(cata)
27 30 cata_json["table_count"]=table_count
... ...
... ... @@ -9,6 +9,7 @@ from ..models import Database,db
9 9
10 10 from app.util.component.ApiTemplate import ApiTemplate
11 11 class Api(ApiTemplate):
  12 +
12 13 api_name = "测试数据库别名"
13 14
14 15 def process(self):
... ...
... ... @@ -12,7 +12,9 @@ from ..models import Database,DES
12 12
13 13 from app.util.component.ApiTemplate import ApiTemplate
14 14 class Api(ApiTemplate):
  15 +
15 16 api_name = "测试数据库连接"
  17 +
16 18 def process(self):
17 19 res = {}
18 20 try:
... ...
... ... @@ -56,7 +56,7 @@ class Api(ApiTemplate):
56 56 res["msg"] = "数据库连接已存在,请修改数据库连接!"
57 57 return res
58 58 elif not self.check_space(sqlalchemy_uri):
59   - res["msg"] = "数据不是空间数据库!"
  59 + res["msg"] = "数据不是空间数据库!"
60 60 return res
61 61 else:
62 62 this_time = datetime.datetime.now()
... ...
... ... @@ -8,7 +8,7 @@ from app.util import BlueprintApi
8 8
9 9 from flask import send_from_directory
10 10 import os
11   -from . import data_download,data_download_task
  11 +from . import data_download_task
12 12 from . import get_meta
13 13 from . import data_entry_by_meta
14 14 from . import get_data_list
... ... @@ -55,14 +55,6 @@ class DataManager(BlueprintApi):
55 55 result["message"] ="删除文件失败!"
56 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 59 @staticmethod
68 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   -}
\ No newline at end of file
... ... @@ -101,6 +101,7 @@ class Api(ApiTemplate):
101 101 try:
102 102 task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "下载失败"})
103 103 task_writer.update_process( e.__str__())
  104 + task_writer.update_process("任务中止!")
104 105 except Exception as ee:
105 106 StructurePrint().print(ee.__str__())
106 107 raise e
... ... @@ -132,7 +133,7 @@ class Api(ApiTemplate):
132 133
133 134
134 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 137 schema = [sche for sche in layer.schema if not sche.name.__eq__(fid)]
137 138
138 139 pg_layer.CreateFields(schema)
... ...
... ... @@ -162,6 +162,8 @@ class Api(ApiTemplate):
162 162 for ln in this_task_layer:
163 163 iln = task_writer.session.query(InsertingLayerName).filter_by(name=ln).one_or_none()
164 164 task_writer.session.delete(iln)
  165 + task_writer.update_process(e.__str__())
  166 + task_writer.update_process("任务中止!")
165 167 StructurePrint().print(e.__str__(), "error")
166 168 finally:
167 169 task_writer.session.commit()
... ...
... ... @@ -160,6 +160,7 @@ class Api(ApiTemplate):
160 160 StructurePrint().print(traceback.format_exc())
161 161 task_writer.update_task({"state": -1, "update_time": datetime.datetime.now(),"process":"更新失败"})
162 162 task_writer.update_process(e.__str__())
  163 + task_writer.update_process("任务中止!")
163 164 except Exception as ee:
164 165 StructurePrint().print(traceback.format_exc())
165 166 finally:
... ...
... ... @@ -114,6 +114,7 @@ class Api(ApiTemplate):
114 114
115 115 task_writer.update_table(table.guid,{"is_vacuate": 2, "update_time": datetime.datetime.now()})
116 116 task_writer.update_task({"state":2,"process":"精华中"})
  117 + task_writer.update_process("开始精化...")
117 118
118 119 database = task_writer.session.query(Database).filter_by(guid=table.database_guid).one_or_none()
119 120 database_sqlalchemy_uri = str(database.sqlalchemy_uri)
... ... @@ -168,13 +169,14 @@ class Api(ApiTemplate):
168 169
169 170 task_writer.update_task({"state":1,"update_time":datetime.datetime.now(),"process": "精化完成"})
170 171 task_writer.update_table(table.guid, {"is_vacuate": 1, "update_time": datetime.datetime.now()})
  172 + task_writer.update_process("精化完成!")
171 173
172 174 except Exception as e:
173 175 try:
174 176 task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "精化失败"})
175 177 task_writer.update_table(table.guid, {"is_vacuate": 0, "update_time": datetime.datetime.now()})
176 178 task_writer.update_process( e.__str__())
177   -
  179 + task_writer.update_process("任务中止!")
178 180 task_writer.session.commit()
179 181
180 182 if vacuate_process:
... ...
... ... @@ -100,7 +100,7 @@ class Api(ApiTemplate):
100 100
101 101 def task(self,table,task_guid,grids):
102 102
103   - task_write = None
  103 + task_writer = None
104 104 pg_session = None
105 105 pg_ds = None
106 106 vacuate_process = None
... ... @@ -110,22 +110,23 @@ class Api(ApiTemplate):
110 110
111 111 #任务控制,等待执行
112 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 120 database_sqlalchemy_uri = str(database.sqlalchemy_uri)
120 121 pg_session = PGUtil.get_db_session(DES.decode(database_sqlalchemy_uri))
121 122 pg_ds :DataSource= PGUtil.open_pg_data_source(1,DES.decode(database_sqlalchemy_uri))
122 123
123 124 #删除原有数据
124 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 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 167 name=layer_name,
167 168 pixel_distance=vacuate_process.this_gridsize[l],
168 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 175 except Exception as e:
175 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 181 if vacuate_process:
180 182 vacuate_process.rollback()
181 183 print(traceback.format_exc())
... ... @@ -183,7 +185,7 @@ class Api(ApiTemplate):
183 185 print(traceback.format_exc())
184 186 finally:
185 187 try:
186   - task_write.close()
  188 + task_writer.close()
187 189 if vacuate_process:
188 190 vacuate_process.end()
189 191 if pg_session:
... ...
... ... @@ -18,7 +18,6 @@ class Api(ApiTemplate):
18 18 try:
19 19 task_guid = self.para.get("task_guid")
20 20 task:Task = Task.query.filter_by(guid=task_guid).one_or_none()
21   -
22 21 if not task :
23 22 raise Exception("任务不存在!")
24 23 else:
... ...
... ... @@ -3,16 +3,16 @@
3 3 #createtime: 2020/9/4
4 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 8 from app.util.component.ApiTemplate import ApiTemplate
10 9 from app.util.component.StructuredPrint import StructurePrint
11 10 import os
12 11 import signal
13 12 import platform
14 13 import json
15   -
  14 +import datetime
  15 +import uuid
16 16 class Api(ApiTemplate):
17 17 api_name = "停止任务"
18 18 def para_check(self):
... ... @@ -37,6 +37,7 @@ class Api(ApiTemplate):
37 37
38 38 #处理kill任务后的事情
39 39 self.fix_task(task)
  40 +
40 41 res["msg"] = "Kill成功!"
41 42 res["result"] = True
42 43 except Exception as e:
... ... @@ -64,9 +65,15 @@ class Api(ApiTemplate):
64 65 if task.task_type==4:
65 66 pass
66 67 if task.task_type==5:
67   - Image.query.filter_by(guid=task.parameter).update({"has_pyramid":0})
  68 + pass
68 69
69 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 77 db.session.commit()
71 78 return None
72 79
... ...
... ... @@ -86,7 +86,9 @@ class EntryDataVacuate:
86 86 this_task.rollback()
87 87
88 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 92 this_task.update({"state": -1, "process": "入库失败", "update_time": datetime.datetime.now()})
91 93 StructurePrint().print(e.__str__(),"ERROR")
92 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
\ No newline at end of file
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
\ No newline at end of file
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 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 9 from app.util.component.ApiTemplate import ApiTemplate
10 10 from app.util.component.ModelVisitor import ModelVisitor
  11 +import requests
11 12 class Api(ApiTemplate):
12 13 api_name = "下一级目录"
13 14 def process(self):
... ... @@ -19,12 +20,28 @@ class Api(ApiTemplate):
19 20
20 21 res["data"] = []
21 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 35 for cata in catalogs:
23 36 catalog_guids = [c.guid for c in ServiceCatalog.query.filter(ServiceCatalog.path.like("%" + cata.guid + "%")).all()]
24 37 service_count = Service.query.filter(Service.catalog_guid.in_(catalog_guids)).count()
25 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 43 res["data"].append(cata_json)
  44 +
28 45 res["result"] = True
29 46 except Exception as e:
30 47 raise e
... ...
... ... @@ -4,9 +4,10 @@
4 4 #email: nheweijun@sina.com
5 5
6 6
7   -from ..models import ServiceCatalog,Service
8   -
  7 +from ..models import ServiceCatalog,Service,ServiceEngine
9 8 from app.util.component.ApiTemplate import ApiTemplate
  9 +import requests
  10 +
10 11 class Api(ApiTemplate):
11 12 api_name = "目录树"
12 13 def process(self):
... ... @@ -18,11 +19,26 @@ class Api(ApiTemplate):
18 19
19 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 34 tree_origin = []
22 35 for cata in catalogs:
  36 +
23 37 catalog_guids = [c.guid for c in ServiceCatalog.query.filter(ServiceCatalog.path.like("%" + cata.guid + "%")).all()]
24 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 42 cata_json ={}
27 43
28 44 cata_json["description"] = cata.description
... ... @@ -31,7 +47,7 @@ class Api(ApiTemplate):
31 47 cata_json["path"] = cata.path
32 48 cata_json["pguid"] = cata.pguid
33 49 cata_json["sort"] = cata.sort
34   - cata_json["service_count"]=service_count
  50 + cata_json["service_count"]=service_count+image_service_count
35 51 cata_json["children"] = []
36 52 tree_origin.append(cata_json)
37 53
... ...
... ... @@ -4,7 +4,8 @@
4 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 10 from app.util.component.ApiTemplate import ApiTemplate
10 11 class Api(ApiTemplate):
... ... @@ -17,9 +18,24 @@ class Api(ApiTemplate):
17 18 # 业务逻辑
18 19 catalogs = ServiceCatalog.query.all()
19 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 33 for cata in catalogs:
21 34 catalog_guids = [c.guid for c in ServiceCatalog.query.filter(ServiceCatalog.path.like("%" + cata.guid + "%")).all()]
22 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 39 cata_json ={}
24 40 cata_json["description"] = cata.description
25 41 cata_json["guid"] = cata.guid
... ... @@ -27,7 +43,7 @@ class Api(ApiTemplate):
27 43 cata_json["path"] = cata.path
28 44 cata_json["pguid"] = cata.pguid
29 45 cata_json["sort"] = cata.sort
30   - cata_json["service_count"]=service_count
  46 + cata_json["service_count"] = service_count + image_service_count
31 47 res["data"].append(cata_json)
32 48
33 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 1 # coding=utf-8
2 2 #author: 4N
3   -#createtime: 2021/7/19
  3 +#createtime: 2021/9/14
4 4 #email: nheweijun@sina.com
5 5
6 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 8 class Api(ApiTemplate):
10   -
11   - api_name = "删除影像数据"
12   -
  9 + api_name = "注销服务引擎"
13 10 def process(self):
14   -
15 11 res = {}
16   -
17 12 try:
18 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 18 db.session.commit()
22 19 res["result"] = True
23   -
24 20 except Exception as e:
25 21 raise e
26   -
27 22 return res
28 23
29 24 api_doc = {
30   - "tags": ["影像接口"],
  25 + "tags": ["引擎接口"],
31 26 "parameters": [
32 27 {"name": "guid",
33 28 "in": "formData",
34   - "type": "string"}
  29 + "type": "string",
  30 + "description": "guid"},
35 31 ],
36 32 "responses": {
37 33 200: {
... ... @@ -41,6 +37,4 @@ class Api(ApiTemplate):
41 37 }
42 38 }
43 39 }
44   - }
45   -
46   -
  40 + }
\ No newline at end of file
... ...
1 1 # coding=utf-8
2 2 #author: 4N
3   -#createtime: 2021/9/8
  3 +#createtime: 2021/9/14
4 4 #email: nheweijun@sina.com
5 5
6   -
7 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 9 class Api(ApiTemplate):
12   -
13   - api_name = "create tag"
14   -
  10 + api_name = "修改服务引擎"
15 11 def process(self):
16   -
17   - # 返回结果
18 12 res = {}
19 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 23 db.session.commit()
25   - res["data"] = tag_guid
26 24 res["result"] = True
27 25 except Exception as e:
28 26 raise e
29 27 return res
30 28
  29 +
31 30 api_doc = {
32   - "tags": ["影像接口"],
  31 + "tags": ["引擎接口"],
33 32 "parameters": [
  33 + {"name": "guid",
  34 + "in": "formData",
  35 + "type": "string",
  36 + "description": "guid"},
34 37 {"name": "name",
35 38 "in": "formData",
36 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 48 "responses": {
39 49 200: {
... ...
1 1 # coding=utf-8
2 2 #author: 4N
3   -#createtime: 2021/9/8
  3 +#createtime: 2021/9/14
4 4 #email: nheweijun@sina.com
5 5
6   -
7 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 12 def process(self):
15   -
16   - # 返回结果
17 13 res = {}
18 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 21 res["result"] = True
24 22 except Exception as e:
25 23 raise e
26 24 return res
27 25
  26 +
28 27 api_doc = {
29   - "tags": ["影像接口"],
  28 + "tags": ["引擎接口"],
30 29 "parameters": [
31 30 {"name": "guid",
32 31 "in": "formData",
... ...
1 1 # coding=utf-8
2 2 #author: 4N
3   -#createtime: 2021/7/19
  3 +#createtime: 2021/9/14
4 4 #email: nheweijun@sina.com
5 5
6   -
7 6 from app.util.component.ApiTemplate import ApiTemplate
  7 +from app.modules.service.models import ServiceEngine
8 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 10 class Api(ApiTemplate):
14   -
15   - api_name = "影像数据Info"
16   -
  11 + api_name = "服务引擎List"
17 12 def process(self):
18   -
19   - # 返回结果
20 13 res = {}
21 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 29 except Exception as e:
42 30 raise e
43   -
44 31 return res
45 32
46 33
47 34 api_doc = {
48   - "tags": ["影像接口"],
  35 + "tags": ["引擎接口"],
49 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 46 "in": "formData",
52 47 "type": "string"},
  48 + {"name": "type",
  49 + "in": "formData",
  50 + "type": "string",
  51 + "enum":["ImageServer"]},
53 52 ],
54 53 "responses": {
55 54 200: {
... ... @@ -59,6 +58,4 @@ class Api(ApiTemplate):
59 58 }
60 59 }
61 60 }
62   - }
63   -
64   -
  61 + }
\ No newline at end of file
... ...
1 1 # coding=utf-8
2 2 #author: 4N
3   -#createtime: 2021/7/19
  3 +#createtime: 2021/9/14
4 4 #email: nheweijun@sina.com
5 5
6   -
7 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 9 import datetime
11   -from app.models import db
12   -
  10 +import uuid
13 11
14 12 class Api(ApiTemplate):
15   -
16   - api_name = "注册影像数据"
17   -
  13 + api_name = "注册服务引擎"
18 14 def process(self):
19   -
20   - #可以注册一个目录
21   - #返回结果
22 15 res = {}
23   -
24 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 29 db.session.commit()
45 30 res["result"] = True
46   -
47 31 except Exception as e:
48   - raise e
49   -
  32 + raise Exception("引擎已注册!")
50 33 return res
51 34
52 35
53 36 api_doc = {
54   - "tags": ["影像接口"],
  37 + "tags": ["引擎接口"],
55 38 "parameters": [
56   - {"name": "data_server",
  39 + {"name": "url",
57 40 "in": "formData",
58 41 "type": "string",
59   - "description": "data_server"},
60   - {"name": "paths",
  42 + "description": "服务地址"},
  43 + {"name": "name",
61 44 "in": "formData",
62 45 "type": "string",
63   - "description": "paths"},
  46 + "description": "name"},
64 47 ],
65 48 "responses": {
66 49 200: {
... ... @@ -70,6 +53,4 @@ class Api(ApiTemplate):
70 53 }
71 54 }
72 55 }
73   - }
74   -
75   -
  56 + }
\ No newline at end of file
... ...
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
\ No newline at end of file
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>
\ No newline at end of file
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()
\ No newline at end of file
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   - }
\ No newline at end of file
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   -
注册登录 后发表评论