提交 27524217be13577d58f8b2f0348779110dc6f993

作者 qianyingz
2 个父辈 dac80d95 874cc380
正在显示 109 个修改的文件 包含 1498 行增加7689 行删除
... ... @@ -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   -
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/3/24
4   -#email: nheweijun@sina.com
5   -
6   -
7   -from app.util.component.ApiTemplate import ApiTemplate
8   -
9   -from .util.ImageWMSServer import ImageWMSServer
10   -
11   -class Api(ApiTemplate):
12   -
13   - api_name = "WMS"
14   -
15   -
16   - def __init__(self,service_name):
17   - super().__init__()
18   - self.service_name = service_name
19   -
20   - def process(self):
21   - try:
22   - instance = ImageWMSServer()
23   - response = instance.wms(self.service_name,self.para)
24   -
25   - except Exception as e:
26   - raise e
27   - return response
28   -
29   -
30   -
31   - api_doc = {
32   - "tags": ["影像接口"],
33   - "parameters": [
34   - {"name": "request",
35   - "in": "query",
36   - "type": "string",
37   - "enum":["GetMap","GetCapabilities"]},
38   - {"name": "bbox",
39   - "in": "query",
40   - "type": "string"},
41   - {"name": "width",
42   - "in": "query",
43   - "type": "string"},
44   - {"name": "height",
45   - "in": "query",
46   - "type": "string"},
47   - {"name": "format",
48   - "in": "query",
49   - "type": "string"},
50   - {"name": "quality",
51   - "in": "query",
52   - "type": "string"}
53   - ],
54   - "responses": {
55   - 200: {
56   - "schema": {
57   - "properties": {
58   - }
59   - }
60   - }
61   - }
62   - }
63   -
64   -
65   -
66   -
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/3/24
4   -#email: nheweijun@sina.com
5   -
6   -from app.util.component.ApiTemplate import ApiTemplate
7   -
8   -
9   -from .util.ImageWMSServer import ImageWMSServer
10   -class Api(ApiTemplate):
11   -
12   - api_name = "WMS"
13   -
14   - def process(self):
15   - try:
16   - instance = ImageWMSServer()
17   - if self.para.get("guid"):
18   - response = instance.wms(self.para.get("service_name"),self.para)
19   - else:
20   - response = instance.wms(self.para.get("guid"), self.para,type="guid")
21   - except Exception as e:
22   - raise e
23   - return response
24   -
25   - api_doc = {
26   - "tags": ["影像接口"],
27   - "parameters": [
28   - {"name": "guid",
29   - "in": "query",
30   - "type": "string"},
31   - {"name": "service_name",
32   - "in": "query",
33   - "type": "string"},
34   - {"name": "bbox",
35   - "in": "query",
36   - "type": "string"},
37   - {"name": "width",
38   - "in": "query",
39   - "type": "string"},
40   - {"name": "height",
41   - "in": "query",
42   - "type": "string"},
43   - {"name": "format",
44   - "in": "query",
45   - "type": "string"},
46   - {"name": "quality",
47   - "in": "query",
48   - "type": "string"}
49   - ],
50   - "responses": {
51   - 200: {
52   - "schema": {
53   - "properties": {
54   - }
55   - }
56   - }
57   - }
58   - }
59   -
60   -
61   -
62   -
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/3/24
4   -#email: nheweijun@sina.com
5   -
6   -import traceback
7   -
8   -import numpy
9   -from flask import Response
10   -import random
11   -
12   -from app.modules.service.models import Image
13   -from app.util.component.ApiTemplate import ApiTemplate
14   -
15   -from app.util.component.ParameterUtil import ParameterUtil
16   -import json
17   -
18   -from .util.MyThread import MyThread
19   -from .util.ImageData import ImageData
20   -from .util.Opencv import Opencv
21   -from .util.Cache import Cache
22   -from app.util.component.ModelVisitor import ModelVisitor
23   -from app.util.component.ParameterUtil import StructurePrint
24   -class Api(ApiTemplate):
25   -
26   - api_name = "发布服务时预览"
27   -
28   - def process(self):
29   -
30   -
31   - result = {}
32   - parameter: dict = self.para
33   -
34   - try:
35   -
36   - parameter = ParameterUtil.to_lower(parameter)
37   -
38   - image_guids = parameter.get("image_guids")
39   -
40   - get_extent = parameter.get("get_extent")
41   - if get_extent and (get_extent == True or get_extent.lower().__eq__("true")):
42   -
43   - sr_set = set()
44   -
45   -
46   - tmp_extent = []
47   - for g in image_guids.split(","):
48   - image = Image.query.filter_by(guid=g).one_or_none()
49   - if image:
50   - image_extent = json.loads(image.extent)
51   - if not tmp_extent:
52   - tmp_extent = image_extent
53   - else:
54   - tmp_extent[0] = min(image_extent[0], tmp_extent[0])
55   - tmp_extent[2] = max(image_extent[2], tmp_extent[2])
56   - tmp_extent[1] = min(image_extent[1], tmp_extent[1])
57   - tmp_extent[3] = max(image_extent[3], tmp_extent[3])
58   - sr_set.add(image.crs)
59   - if len(sr_set)>1:
60   - result["result"] = False
61   - result["msg"] = "影像坐标不一致"
62   - return result
63   -
64   - result["result"] = True
65   - result["data"] = tmp_extent
66   - return result
67   -
68   - bbox = parameter.get("bbox")
69   - width = int(parameter.get("width")) if parameter.get("width") else 256
70   - height = int(parameter.get("height")) if parameter.get("height") else 256
71   - image_type = parameter.get("format") if parameter.get("format") else "image/png"
72   - quality = int(parameter.get("quality")) if parameter.get("quality") else 30
73   -
74   - image_service_info ,zoo, servers = Cache.cache_data(None)
75   -
76   - extent = [float(x) for x in bbox.split(",")]
77   -
78   - images = Image.query.filter(Image.guid.in_(image_guids.split(","))).all()
79   -
80   - intersect_image = [im for im in images if self.determin_intersect(json.loads(im.extent),extent)]
81   -
82   - if len(intersect_image)>1:
83   -
84   - # 结果矩阵
85   - empty_list = [numpy.zeros((height,width), dtype=int) + 65536,
86   - numpy.zeros((height,width), dtype=int) + 65536,
87   - numpy.zeros((height,width), dtype=int) + 65536]
88   -
89   - pixel_array = numpy.zeros((height,width,3), dtype=int)
90   - thread_list = []
91   -
92   - for image in intersect_image:
93   - #该影像的服务器,随机选取一个
94   - image_servers = image.server.split(",")
95   - image_servers = [ser for ser in image_servers if ser in servers]
96   - if len(image_servers)>0:
97   - indx = int(random.random() * len(image_servers))
98   - image_server = image_servers[indx]
99   - else:
100   - image_server = "None"
101   - bands = json.loads(image.band_view)
102   -
103   - image_data = ImageData(image_server, ModelVisitor.object_to_json(image))
104   -
105   - thread: MyThread = MyThread(image_data.get_data, args=(extent,bands,height,width))
106   - thread.start()
107   - thread_list.append(thread)
108   -
109   -
110   - for thread in thread_list:
111   - thread.join()
112   - data = thread.get_result()
113   -
114   - # 掩膜在中央接口生成,合图
115   - mask = numpy.zeros((height,width), dtype=int)
116   - mask2 = numpy.zeros((height,width), dtype=int)
117   - jizhun = data[:, :, 0]
118   - mask[jizhun == 65536] = 1
119   - mask[jizhun != 65536] = 0
120   - mask2[jizhun == 65536] = 0
121   - mask2[jizhun != 65536] = 1
122   - # 掩膜计算
123   - for i, d in enumerate(empty_list):
124   - empty_list[i] = empty_list[i] * mask + data[:, :, i] * mask2
125   -
126   - for ii in [0, 1, 2]:
127   - # opencv 颜色排序为GBR
128   - pixel_array[:, :, 2 - ii] = empty_list[ii]
129   -
130   -
131   - elif len(intersect_image)==1:
132   - # 该影像的服务器,随机选取一个
133   - image = intersect_image[0]
134   - image_servers = image.server.split(",")
135   - image_servers = [ser for ser in image_servers if ser in servers]
136   - if len(image_servers) > 0:
137   - indx = int(random.random() * len(image_servers))
138   - image_server = image_servers[indx]
139   - else:
140   - image_server = "None"
141   -
142   - bands = json.loads(image.band_view)
143   -
144   - image_data = ImageData(image_server,ModelVisitor.object_to_json(image))
145   -
146   - pixel_array_t = image_data.get_data(extent,bands,height,width)
147   - pixel_array = numpy.zeros((height, width, 3), dtype=int)
148   - for ii in [0, 1, 2]:
149   - # opencv 颜色排序为GBR
150   - pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii]
151   - else:
152   - # 结果矩阵
153   - pixel_array = numpy.zeros((height, width, 3), dtype=int)+65536
154   -
155   - # 将图片生成在内存中,然后直接返回response
156   - im_data = Opencv.create_image(image_type, pixel_array, quality)
157   -
158   - if self.para.get("overview"):
159   - return pixel_array
160   - return Response(im_data, mimetype=image_type.lower())
161   -
162   - except Exception as e:
163   - raise e
164   -
165   -
166   - def determin_intersect(self, extent1, extent2):
167   - if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[
168   - 3] or extent2[3] < extent1[1]:
169   - return False
170   - else:
171   - return True
172   -
173   - api_doc = {
174   - "tags": ["影像接口"],
175   - "parameters": [
176   - {"name": "image_guids",
177   - "in": "query",
178   - "type": "string"},
179   - {"name": "get_extent",
180   - "in": "query",
181   - "type": "boolean",
182   - "enum":[True,False]},
183   - {"name": "bbox",
184   - "in": "query",
185   - "type": "string"},
186   - {"name": "width",
187   - "in": "query",
188   - "type": "string"},
189   - {"name": "height",
190   - "in": "query",
191   - "type": "string"},
192   - {"name": "format",
193   - "in": "query",
194   - "type": "string"},
195   - {"name": "quality",
196   - "in": "query",
197   - "type": "string"}
198   - ],
199   - "responses": {
200   - 200: {
201   - "schema": {
202   - "properties": {
203   - }
204   - }
205   - }
206   - }
207   - }
208   -
209   -
210   -
211   -
212   -
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/3/24
4   -#email: nheweijun@sina.com
5   -
6   -import traceback
7   -from app.util.component.ApiTemplate import ApiTemplate
8   -from .util.ImageWMTSServer import ImageWMTSServer
9   -class Api(ApiTemplate):
10   - api_name = "切片"
11   - def __init__(self,service_name):
12   - super().__init__()
13   - self.service_name = service_name
14   -
15   - def process(self):
16   - try:
17   - instance = ImageWMTSServer()
18   - response = instance.wmts(self.service_name,self.para)
19   - except Exception as e:
20   - print(traceback.format_exc())
21   - raise e
22   - return response
23   -
24   -
25   - api_doc = {
26   - "tags": ["影像接口"],
27   - "parameters": [
28   - {"name": "request",
29   - "in": "formData",
30   - "type": "string",
31   - "enum": ["GetTile", "GetCapabilities"]},
32   - {"name": "tilematrix",
33   - "in": "formData",
34   - "type": "string"},
35   - {"name": "tilerow",
36   - "in": "formData",
37   - "type": "string"},
38   - {"name": "tilecol",
39   - "in": "formData",
40   - "type": "string"},
41   - {"name": "format",
42   - "in": "formData",
43   - "type": "string"},
44   - {"name": "quality",
45   - "in": "formData",
46   - "type": "string"}
47   -
48   - ],
49   - "responses": {
50   - 200: {
51   - "schema": {
52   - "properties": {
53   - }
54   - }
55   - }
56   - }
57   - }
58   -
59   -
60   -
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 tutorial import Calculator
20   -from tutorial.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(' getData(string path, queryRange, originRange, bands, i32 width, i32 height)')
28   - print(' Raster getInfo(string path)')
29   - print(' bool buildOverview(string path)')
30   - print(' 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 = Calculator.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   - """
23   - Ahh, now onto the cool part, defining a service. Services just need a name
24   - and can optionally inherit from another service using the extends keyword.
25   -
26   - """
27   - def getData(self, path, queryRange, originRange, bands, width, height):
28   - """
29   - Parameters:
30   - - path
31   - - queryRange
32   - - originRange
33   - - bands
34   - - width
35   - - height
36   -
37   - """
38   - pass
39   -
40   - def getInfo(self, path):
41   - """
42   - Parameters:
43   - - path
44   -
45   - """
46   - pass
47   -
48   - def buildOverview(self, path):
49   - """
50   - Parameters:
51   - - path
52   -
53   - """
54   - pass
55   -
56   - def getImageList(self, path):
57   - """
58   - Parameters:
59   - - path
60   -
61   - """
62   - pass
63   -
64   -
65   -class Client(Iface):
66   - """
67   - Ahh, now onto the cool part, defining a service. Services just need a name
68   - and can optionally inherit from another service using the extends keyword.
69   -
70   - """
71   - def __init__(self, iprot, oprot=None):
72   - self._iprot = self._oprot = iprot
73   - if oprot is not None:
74   - self._oprot = oprot
75   - self._seqid = 0
76   -
77   - def getData(self, path, queryRange, originRange, bands, width, height):
78   - """
79   - Parameters:
80   - - path
81   - - queryRange
82   - - originRange
83   - - bands
84   - - width
85   - - height
86   -
87   - """
88   - self.send_getData(path, queryRange, originRange, bands, width, height)
89   - return self.recv_getData()
90   -
91   - def send_getData(self, path, queryRange, originRange, bands, width, height):
92   - self._oprot.writeMessageBegin('getData', TMessageType.CALL, self._seqid)
93   - args = getData_args()
94   - args.path = path
95   - args.queryRange = queryRange
96   - args.originRange = originRange
97   - args.bands = bands
98   - args.width = width
99   - args.height = height
100   - args.write(self._oprot)
101   - self._oprot.writeMessageEnd()
102   - self._oprot.trans.flush()
103   -
104   - def recv_getData(self):
105   - iprot = self._iprot
106   - (fname, mtype, rseqid) = iprot.readMessageBegin()
107   - if mtype == TMessageType.EXCEPTION:
108   - x = TApplicationException()
109   - x.read(iprot)
110   - iprot.readMessageEnd()
111   - raise x
112   - result = getData_result()
113   - result.read(iprot)
114   - iprot.readMessageEnd()
115   - if result.success is not None:
116   - return result.success
117   - raise TApplicationException(TApplicationException.MISSING_RESULT, "getData failed: unknown result")
118   -
119   - def getInfo(self, path):
120   - """
121   - Parameters:
122   - - path
123   -
124   - """
125   - self.send_getInfo(path)
126   - return self.recv_getInfo()
127   -
128   - def send_getInfo(self, path):
129   - self._oprot.writeMessageBegin('getInfo', TMessageType.CALL, self._seqid)
130   - args = getInfo_args()
131   - args.path = path
132   - args.write(self._oprot)
133   - self._oprot.writeMessageEnd()
134   - self._oprot.trans.flush()
135   -
136   - def recv_getInfo(self):
137   - iprot = self._iprot
138   - (fname, mtype, rseqid) = iprot.readMessageBegin()
139   - if mtype == TMessageType.EXCEPTION:
140   - x = TApplicationException()
141   - x.read(iprot)
142   - iprot.readMessageEnd()
143   - raise x
144   - result = getInfo_result()
145   - result.read(iprot)
146   - iprot.readMessageEnd()
147   - if result.success is not None:
148   - return result.success
149   - raise TApplicationException(TApplicationException.MISSING_RESULT, "getInfo failed: unknown result")
150   -
151   - def buildOverview(self, path):
152   - """
153   - Parameters:
154   - - path
155   -
156   - """
157   - self.send_buildOverview(path)
158   - return self.recv_buildOverview()
159   -
160   - def send_buildOverview(self, path):
161   - self._oprot.writeMessageBegin('buildOverview', TMessageType.CALL, self._seqid)
162   - args = buildOverview_args()
163   - args.path = path
164   - args.write(self._oprot)
165   - self._oprot.writeMessageEnd()
166   - self._oprot.trans.flush()
167   -
168   - def recv_buildOverview(self):
169   - iprot = self._iprot
170   - (fname, mtype, rseqid) = iprot.readMessageBegin()
171   - if mtype == TMessageType.EXCEPTION:
172   - x = TApplicationException()
173   - x.read(iprot)
174   - iprot.readMessageEnd()
175   - raise x
176   - result = buildOverview_result()
177   - result.read(iprot)
178   - iprot.readMessageEnd()
179   - if result.success is not None:
180   - return result.success
181   - raise TApplicationException(TApplicationException.MISSING_RESULT, "buildOverview failed: unknown result")
182   -
183   - def getImageList(self, path):
184   - """
185   - Parameters:
186   - - path
187   -
188   - """
189   - self.send_getImageList(path)
190   - return self.recv_getImageList()
191   -
192   - def send_getImageList(self, path):
193   - self._oprot.writeMessageBegin('getImageList', TMessageType.CALL, self._seqid)
194   - args = getImageList_args()
195   - args.path = path
196   - args.write(self._oprot)
197   - self._oprot.writeMessageEnd()
198   - self._oprot.trans.flush()
199   -
200   - def recv_getImageList(self):
201   - iprot = self._iprot
202   - (fname, mtype, rseqid) = iprot.readMessageBegin()
203   - if mtype == TMessageType.EXCEPTION:
204   - x = TApplicationException()
205   - x.read(iprot)
206   - iprot.readMessageEnd()
207   - raise x
208   - result = getImageList_result()
209   - result.read(iprot)
210   - iprot.readMessageEnd()
211   - if result.success is not None:
212   - return result.success
213   - raise TApplicationException(TApplicationException.MISSING_RESULT, "getImageList failed: unknown result")
214   -
215   -
216   -class Processor(Iface, TProcessor):
217   - def __init__(self, handler):
218   - self._handler = handler
219   - self._processMap = {}
220   - self._processMap["getData"] = Processor.process_getData
221   - self._processMap["getInfo"] = Processor.process_getInfo
222   - self._processMap["buildOverview"] = Processor.process_buildOverview
223   - self._processMap["getImageList"] = Processor.process_getImageList
224   - self._on_message_begin = None
225   -
226   - def on_message_begin(self, func):
227   - self._on_message_begin = func
228   -
229   - def process(self, iprot, oprot):
230   - (name, type, seqid) = iprot.readMessageBegin()
231   - if self._on_message_begin:
232   - self._on_message_begin(name, type, seqid)
233   - if name not in self._processMap:
234   - iprot.skip(TType.STRUCT)
235   - iprot.readMessageEnd()
236   - x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))
237   - oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
238   - x.write(oprot)
239   - oprot.writeMessageEnd()
240   - oprot.trans.flush()
241   - return
242   - else:
243   - self._processMap[name](self, seqid, iprot, oprot)
244   - return True
245   -
246   - def process_getData(self, seqid, iprot, oprot):
247   - args = getData_args()
248   - args.read(iprot)
249   - iprot.readMessageEnd()
250   - result = getData_result()
251   - try:
252   - result.success = self._handler.getData(args.path, args.queryRange, args.originRange, args.bands, args.width, args.height)
253   - msg_type = TMessageType.REPLY
254   - except TTransport.TTransportException:
255   - raise
256   - except TApplicationException as ex:
257   - logging.exception('TApplication exception in handler')
258   - msg_type = TMessageType.EXCEPTION
259   - result = ex
260   - except Exception:
261   - logging.exception('Unexpected exception in handler')
262   - msg_type = TMessageType.EXCEPTION
263   - result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
264   - oprot.writeMessageBegin("getData", msg_type, seqid)
265   - result.write(oprot)
266   - oprot.writeMessageEnd()
267   - oprot.trans.flush()
268   -
269   - def process_getInfo(self, seqid, iprot, oprot):
270   - args = getInfo_args()
271   - args.read(iprot)
272   - iprot.readMessageEnd()
273   - result = getInfo_result()
274   - try:
275   - result.success = self._handler.getInfo(args.path)
276   - msg_type = TMessageType.REPLY
277   - except TTransport.TTransportException:
278   - raise
279   - except TApplicationException as ex:
280   - logging.exception('TApplication exception in handler')
281   - msg_type = TMessageType.EXCEPTION
282   - result = ex
283   - except Exception:
284   - logging.exception('Unexpected exception in handler')
285   - msg_type = TMessageType.EXCEPTION
286   - result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
287   - oprot.writeMessageBegin("getInfo", msg_type, seqid)
288   - result.write(oprot)
289   - oprot.writeMessageEnd()
290   - oprot.trans.flush()
291   -
292   - def process_buildOverview(self, seqid, iprot, oprot):
293   - args = buildOverview_args()
294   - args.read(iprot)
295   - iprot.readMessageEnd()
296   - result = buildOverview_result()
297   - try:
298   - result.success = self._handler.buildOverview(args.path)
299   - msg_type = TMessageType.REPLY
300   - except TTransport.TTransportException:
301   - raise
302   - except TApplicationException as ex:
303   - logging.exception('TApplication exception in handler')
304   - msg_type = TMessageType.EXCEPTION
305   - result = ex
306   - except Exception:
307   - logging.exception('Unexpected exception in handler')
308   - msg_type = TMessageType.EXCEPTION
309   - result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
310   - oprot.writeMessageBegin("buildOverview", msg_type, seqid)
311   - result.write(oprot)
312   - oprot.writeMessageEnd()
313   - oprot.trans.flush()
314   -
315   - def process_getImageList(self, seqid, iprot, oprot):
316   - args = getImageList_args()
317   - args.read(iprot)
318   - iprot.readMessageEnd()
319   - result = getImageList_result()
320   - try:
321   - result.success = self._handler.getImageList(args.path)
322   - msg_type = TMessageType.REPLY
323   - except TTransport.TTransportException:
324   - raise
325   - except TApplicationException as ex:
326   - logging.exception('TApplication exception in handler')
327   - msg_type = TMessageType.EXCEPTION
328   - result = ex
329   - except Exception:
330   - logging.exception('Unexpected exception in handler')
331   - msg_type = TMessageType.EXCEPTION
332   - result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
333   - oprot.writeMessageBegin("getImageList", msg_type, seqid)
334   - result.write(oprot)
335   - oprot.writeMessageEnd()
336   - oprot.trans.flush()
337   -
338   -# HELPER FUNCTIONS AND STRUCTURES
339   -
340   -
341   -class getData_args(object):
342   - """
343   - Attributes:
344   - - path
345   - - queryRange
346   - - originRange
347   - - bands
348   - - width
349   - - height
350   -
351   - """
352   -
353   -
354   - def __init__(self, path=None, queryRange=None, originRange=None, bands=None, width=None, height=None,):
355   - self.path = path
356   - self.queryRange = queryRange
357   - self.originRange = originRange
358   - self.bands = bands
359   - self.width = width
360   - self.height = height
361   -
362   - def read(self, iprot):
363   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
364   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
365   - return
366   - iprot.readStructBegin()
367   - while True:
368   - (fname, ftype, fid) = iprot.readFieldBegin()
369   - if ftype == TType.STOP:
370   - break
371   - if fid == 1:
372   - if ftype == TType.STRING:
373   - self.path = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
374   - else:
375   - iprot.skip(ftype)
376   - elif fid == 2:
377   - if ftype == TType.LIST:
378   - self.queryRange = []
379   - (_etype38, _size35) = iprot.readListBegin()
380   - for _i39 in range(_size35):
381   - _elem40 = iprot.readDouble()
382   - self.queryRange.append(_elem40)
383   - iprot.readListEnd()
384   - else:
385   - iprot.skip(ftype)
386   - elif fid == 3:
387   - if ftype == TType.LIST:
388   - self.originRange = []
389   - (_etype44, _size41) = iprot.readListBegin()
390   - for _i45 in range(_size41):
391   - _elem46 = iprot.readDouble()
392   - self.originRange.append(_elem46)
393   - iprot.readListEnd()
394   - else:
395   - iprot.skip(ftype)
396   - elif fid == 4:
397   - if ftype == TType.LIST:
398   - self.bands = []
399   - (_etype50, _size47) = iprot.readListBegin()
400   - for _i51 in range(_size47):
401   - _elem52 = iprot.readI32()
402   - self.bands.append(_elem52)
403   - iprot.readListEnd()
404   - else:
405   - iprot.skip(ftype)
406   - elif fid == 5:
407   - if ftype == TType.I32:
408   - self.width = iprot.readI32()
409   - else:
410   - iprot.skip(ftype)
411   - elif fid == 6:
412   - if ftype == TType.I32:
413   - self.height = iprot.readI32()
414   - else:
415   - iprot.skip(ftype)
416   - else:
417   - iprot.skip(ftype)
418   - iprot.readFieldEnd()
419   - iprot.readStructEnd()
420   -
421   - def write(self, oprot):
422   - if oprot._fast_encode is not None and self.thrift_spec is not None:
423   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
424   - return
425   - oprot.writeStructBegin('getData_args')
426   - if self.path is not None:
427   - oprot.writeFieldBegin('path', TType.STRING, 1)
428   - oprot.writeString(self.path.encode('utf-8') if sys.version_info[0] == 2 else self.path)
429   - oprot.writeFieldEnd()
430   - if self.queryRange is not None:
431   - oprot.writeFieldBegin('queryRange', TType.LIST, 2)
432   - oprot.writeListBegin(TType.DOUBLE, len(self.queryRange))
433   - for iter53 in self.queryRange:
434   - oprot.writeDouble(iter53)
435   - oprot.writeListEnd()
436   - oprot.writeFieldEnd()
437   - if self.originRange is not None:
438   - oprot.writeFieldBegin('originRange', TType.LIST, 3)
439   - oprot.writeListBegin(TType.DOUBLE, len(self.originRange))
440   - for iter54 in self.originRange:
441   - oprot.writeDouble(iter54)
442   - oprot.writeListEnd()
443   - oprot.writeFieldEnd()
444   - if self.bands is not None:
445   - oprot.writeFieldBegin('bands', TType.LIST, 4)
446   - oprot.writeListBegin(TType.I32, len(self.bands))
447   - for iter55 in self.bands:
448   - oprot.writeI32(iter55)
449   - oprot.writeListEnd()
450   - oprot.writeFieldEnd()
451   - if self.width is not None:
452   - oprot.writeFieldBegin('width', TType.I32, 5)
453   - oprot.writeI32(self.width)
454   - oprot.writeFieldEnd()
455   - if self.height is not None:
456   - oprot.writeFieldBegin('height', TType.I32, 6)
457   - oprot.writeI32(self.height)
458   - oprot.writeFieldEnd()
459   - oprot.writeFieldStop()
460   - oprot.writeStructEnd()
461   -
462   - def validate(self):
463   - return
464   -
465   - def __repr__(self):
466   - L = ['%s=%r' % (key, value)
467   - for key, value in self.__dict__.items()]
468   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
469   -
470   - def __eq__(self, other):
471   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
472   -
473   - def __ne__(self, other):
474   - return not (self == other)
475   -all_structs.append(getData_args)
476   -getData_args.thrift_spec = (
477   - None, # 0
478   - (1, TType.STRING, 'path', 'UTF8', None, ), # 1
479   - (2, TType.LIST, 'queryRange', (TType.DOUBLE, None, False), None, ), # 2
480   - (3, TType.LIST, 'originRange', (TType.DOUBLE, None, False), None, ), # 3
481   - (4, TType.LIST, 'bands', (TType.I32, None, False), None, ), # 4
482   - (5, TType.I32, 'width', None, None, ), # 5
483   - (6, TType.I32, 'height', None, None, ), # 6
484   -)
485   -
486   -
487   -class getData_result(object):
488   - """
489   - Attributes:
490   - - success
491   -
492   - """
493   -
494   -
495   - def __init__(self, success=None,):
496   - self.success = success
497   -
498   - def read(self, iprot):
499   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
500   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
501   - return
502   - iprot.readStructBegin()
503   - while True:
504   - (fname, ftype, fid) = iprot.readFieldBegin()
505   - if ftype == TType.STOP:
506   - break
507   - if fid == 0:
508   - if ftype == TType.LIST:
509   - self.success = []
510   - (_etype59, _size56) = iprot.readListBegin()
511   - for _i60 in range(_size56):
512   - _elem61 = []
513   - (_etype65, _size62) = iprot.readListBegin()
514   - for _i66 in range(_size62):
515   - _elem67 = iprot.readI16()
516   - _elem61.append(_elem67)
517   - iprot.readListEnd()
518   - self.success.append(_elem61)
519   - iprot.readListEnd()
520   - else:
521   - iprot.skip(ftype)
522   - else:
523   - iprot.skip(ftype)
524   - iprot.readFieldEnd()
525   - iprot.readStructEnd()
526   -
527   - def write(self, oprot):
528   - if oprot._fast_encode is not None and self.thrift_spec is not None:
529   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
530   - return
531   - oprot.writeStructBegin('getData_result')
532   - if self.success is not None:
533   - oprot.writeFieldBegin('success', TType.LIST, 0)
534   - oprot.writeListBegin(TType.LIST, len(self.success))
535   - for iter68 in self.success:
536   - oprot.writeListBegin(TType.I16, len(iter68))
537   - for iter69 in iter68:
538   - oprot.writeI16(iter69)
539   - oprot.writeListEnd()
540   - oprot.writeListEnd()
541   - oprot.writeFieldEnd()
542   - oprot.writeFieldStop()
543   - oprot.writeStructEnd()
544   -
545   - def validate(self):
546   - return
547   -
548   - def __repr__(self):
549   - L = ['%s=%r' % (key, value)
550   - for key, value in self.__dict__.items()]
551   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
552   -
553   - def __eq__(self, other):
554   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
555   -
556   - def __ne__(self, other):
557   - return not (self == other)
558   -all_structs.append(getData_result)
559   -getData_result.thrift_spec = (
560   - (0, TType.LIST, 'success', (TType.LIST, (TType.I16, None, False), False), None, ), # 0
561   -)
562   -
563   -
564   -class getInfo_args(object):
565   - """
566   - Attributes:
567   - - path
568   -
569   - """
570   -
571   -
572   - def __init__(self, path=None,):
573   - self.path = path
574   -
575   - def read(self, iprot):
576   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
577   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
578   - return
579   - iprot.readStructBegin()
580   - while True:
581   - (fname, ftype, fid) = iprot.readFieldBegin()
582   - if ftype == TType.STOP:
583   - break
584   - if fid == 1:
585   - if ftype == TType.STRING:
586   - self.path = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
587   - else:
588   - iprot.skip(ftype)
589   - else:
590   - iprot.skip(ftype)
591   - iprot.readFieldEnd()
592   - iprot.readStructEnd()
593   -
594   - def write(self, oprot):
595   - if oprot._fast_encode is not None and self.thrift_spec is not None:
596   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
597   - return
598   - oprot.writeStructBegin('getInfo_args')
599   - if self.path is not None:
600   - oprot.writeFieldBegin('path', TType.STRING, 1)
601   - oprot.writeString(self.path.encode('utf-8') if sys.version_info[0] == 2 else self.path)
602   - oprot.writeFieldEnd()
603   - oprot.writeFieldStop()
604   - oprot.writeStructEnd()
605   -
606   - def validate(self):
607   - return
608   -
609   - def __repr__(self):
610   - L = ['%s=%r' % (key, value)
611   - for key, value in self.__dict__.items()]
612   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
613   -
614   - def __eq__(self, other):
615   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
616   -
617   - def __ne__(self, other):
618   - return not (self == other)
619   -all_structs.append(getInfo_args)
620   -getInfo_args.thrift_spec = (
621   - None, # 0
622   - (1, TType.STRING, 'path', 'UTF8', None, ), # 1
623   -)
624   -
625   -
626   -class getInfo_result(object):
627   - """
628   - Attributes:
629   - - success
630   -
631   - """
632   -
633   -
634   - def __init__(self, success=None,):
635   - self.success = success
636   -
637   - def read(self, iprot):
638   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
639   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
640   - return
641   - iprot.readStructBegin()
642   - while True:
643   - (fname, ftype, fid) = iprot.readFieldBegin()
644   - if ftype == TType.STOP:
645   - break
646   - if fid == 0:
647   - if ftype == TType.STRUCT:
648   - self.success = Raster()
649   - self.success.read(iprot)
650   - else:
651   - iprot.skip(ftype)
652   - else:
653   - iprot.skip(ftype)
654   - iprot.readFieldEnd()
655   - iprot.readStructEnd()
656   -
657   - def write(self, oprot):
658   - if oprot._fast_encode is not None and self.thrift_spec is not None:
659   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
660   - return
661   - oprot.writeStructBegin('getInfo_result')
662   - if self.success is not None:
663   - oprot.writeFieldBegin('success', TType.STRUCT, 0)
664   - self.success.write(oprot)
665   - oprot.writeFieldEnd()
666   - oprot.writeFieldStop()
667   - oprot.writeStructEnd()
668   -
669   - def validate(self):
670   - return
671   -
672   - def __repr__(self):
673   - L = ['%s=%r' % (key, value)
674   - for key, value in self.__dict__.items()]
675   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
676   -
677   - def __eq__(self, other):
678   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
679   -
680   - def __ne__(self, other):
681   - return not (self == other)
682   -all_structs.append(getInfo_result)
683   -getInfo_result.thrift_spec = (
684   - (0, TType.STRUCT, 'success', [Raster, None], None, ), # 0
685   -)
686   -
687   -
688   -class buildOverview_args(object):
689   - """
690   - Attributes:
691   - - path
692   -
693   - """
694   -
695   -
696   - def __init__(self, path=None,):
697   - self.path = path
698   -
699   - def read(self, iprot):
700   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
701   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
702   - return
703   - iprot.readStructBegin()
704   - while True:
705   - (fname, ftype, fid) = iprot.readFieldBegin()
706   - if ftype == TType.STOP:
707   - break
708   - if fid == 1:
709   - if ftype == TType.STRING:
710   - self.path = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
711   - else:
712   - iprot.skip(ftype)
713   - else:
714   - iprot.skip(ftype)
715   - iprot.readFieldEnd()
716   - iprot.readStructEnd()
717   -
718   - def write(self, oprot):
719   - if oprot._fast_encode is not None and self.thrift_spec is not None:
720   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
721   - return
722   - oprot.writeStructBegin('buildOverview_args')
723   - if self.path is not None:
724   - oprot.writeFieldBegin('path', TType.STRING, 1)
725   - oprot.writeString(self.path.encode('utf-8') if sys.version_info[0] == 2 else self.path)
726   - oprot.writeFieldEnd()
727   - oprot.writeFieldStop()
728   - oprot.writeStructEnd()
729   -
730   - def validate(self):
731   - return
732   -
733   - def __repr__(self):
734   - L = ['%s=%r' % (key, value)
735   - for key, value in self.__dict__.items()]
736   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
737   -
738   - def __eq__(self, other):
739   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
740   -
741   - def __ne__(self, other):
742   - return not (self == other)
743   -all_structs.append(buildOverview_args)
744   -buildOverview_args.thrift_spec = (
745   - None, # 0
746   - (1, TType.STRING, 'path', 'UTF8', None, ), # 1
747   -)
748   -
749   -
750   -class buildOverview_result(object):
751   - """
752   - Attributes:
753   - - success
754   -
755   - """
756   -
757   -
758   - def __init__(self, success=None,):
759   - self.success = success
760   -
761   - def read(self, iprot):
762   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
763   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
764   - return
765   - iprot.readStructBegin()
766   - while True:
767   - (fname, ftype, fid) = iprot.readFieldBegin()
768   - if ftype == TType.STOP:
769   - break
770   - if fid == 0:
771   - if ftype == TType.BOOL:
772   - self.success = iprot.readBool()
773   - else:
774   - iprot.skip(ftype)
775   - else:
776   - iprot.skip(ftype)
777   - iprot.readFieldEnd()
778   - iprot.readStructEnd()
779   -
780   - def write(self, oprot):
781   - if oprot._fast_encode is not None and self.thrift_spec is not None:
782   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
783   - return
784   - oprot.writeStructBegin('buildOverview_result')
785   - if self.success is not None:
786   - oprot.writeFieldBegin('success', TType.BOOL, 0)
787   - oprot.writeBool(self.success)
788   - oprot.writeFieldEnd()
789   - oprot.writeFieldStop()
790   - oprot.writeStructEnd()
791   -
792   - def validate(self):
793   - return
794   -
795   - def __repr__(self):
796   - L = ['%s=%r' % (key, value)
797   - for key, value in self.__dict__.items()]
798   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
799   -
800   - def __eq__(self, other):
801   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
802   -
803   - def __ne__(self, other):
804   - return not (self == other)
805   -all_structs.append(buildOverview_result)
806   -buildOverview_result.thrift_spec = (
807   - (0, TType.BOOL, 'success', None, None, ), # 0
808   -)
809   -
810   -
811   -class getImageList_args(object):
812   - """
813   - Attributes:
814   - - path
815   -
816   - """
817   -
818   -
819   - def __init__(self, path=None,):
820   - self.path = path
821   -
822   - def read(self, iprot):
823   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
824   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
825   - return
826   - iprot.readStructBegin()
827   - while True:
828   - (fname, ftype, fid) = iprot.readFieldBegin()
829   - if ftype == TType.STOP:
830   - break
831   - if fid == 1:
832   - if ftype == TType.STRING:
833   - self.path = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
834   - else:
835   - iprot.skip(ftype)
836   - else:
837   - iprot.skip(ftype)
838   - iprot.readFieldEnd()
839   - iprot.readStructEnd()
840   -
841   - def write(self, oprot):
842   - if oprot._fast_encode is not None and self.thrift_spec is not None:
843   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
844   - return
845   - oprot.writeStructBegin('getImageList_args')
846   - if self.path is not None:
847   - oprot.writeFieldBegin('path', TType.STRING, 1)
848   - oprot.writeString(self.path.encode('utf-8') if sys.version_info[0] == 2 else self.path)
849   - oprot.writeFieldEnd()
850   - oprot.writeFieldStop()
851   - oprot.writeStructEnd()
852   -
853   - def validate(self):
854   - return
855   -
856   - def __repr__(self):
857   - L = ['%s=%r' % (key, value)
858   - for key, value in self.__dict__.items()]
859   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
860   -
861   - def __eq__(self, other):
862   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
863   -
864   - def __ne__(self, other):
865   - return not (self == other)
866   -all_structs.append(getImageList_args)
867   -getImageList_args.thrift_spec = (
868   - None, # 0
869   - (1, TType.STRING, 'path', 'UTF8', None, ), # 1
870   -)
871   -
872   -
873   -class getImageList_result(object):
874   - """
875   - Attributes:
876   - - success
877   -
878   - """
879   -
880   -
881   - def __init__(self, success=None,):
882   - self.success = success
883   -
884   - def read(self, iprot):
885   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
886   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
887   - return
888   - iprot.readStructBegin()
889   - while True:
890   - (fname, ftype, fid) = iprot.readFieldBegin()
891   - if ftype == TType.STOP:
892   - break
893   - if fid == 0:
894   - if ftype == TType.LIST:
895   - self.success = []
896   - (_etype73, _size70) = iprot.readListBegin()
897   - for _i74 in range(_size70):
898   - _elem75 = Image()
899   - _elem75.read(iprot)
900   - self.success.append(_elem75)
901   - iprot.readListEnd()
902   - else:
903   - iprot.skip(ftype)
904   - else:
905   - iprot.skip(ftype)
906   - iprot.readFieldEnd()
907   - iprot.readStructEnd()
908   -
909   - def write(self, oprot):
910   - if oprot._fast_encode is not None and self.thrift_spec is not None:
911   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
912   - return
913   - oprot.writeStructBegin('getImageList_result')
914   - if self.success is not None:
915   - oprot.writeFieldBegin('success', TType.LIST, 0)
916   - oprot.writeListBegin(TType.STRUCT, len(self.success))
917   - for iter76 in self.success:
918   - iter76.write(oprot)
919   - oprot.writeListEnd()
920   - oprot.writeFieldEnd()
921   - oprot.writeFieldStop()
922   - oprot.writeStructEnd()
923   -
924   - def validate(self):
925   - return
926   -
927   - def __repr__(self):
928   - L = ['%s=%r' % (key, value)
929   - for key, value in self.__dict__.items()]
930   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
931   -
932   - def __eq__(self, other):
933   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
934   -
935   - def __ne__(self, other):
936   - return not (self == other)
937   -all_structs.append(getImageList_result)
938   -getImageList_result.thrift_spec = (
939   - (0, TType.LIST, 'success', (TType.STRUCT, [Image, None], False), None, ), # 0
940   -)
941   -fix_spec(all_structs)
942   -del all_structs
1   -__all__ = ['ttypes', 'constants', 'Calculator']
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   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/9/27
4   -#email: nheweijun@sina.com
5   -
6   -
7   -# from .ttypes import RasterData
8   -
9   -from thrift.transport import TSocket
10   -from thrift.transport import TTransport
11   -from thrift.protocol import TBinaryProtocol
12   -
13   -from app.modules.service.image.tutorial import Calculator
14   -from app.modules.service.image.ImageDataService import ImageDataService
15   -import time
16   -
17   -def test1():
18   -
19   - host = "172.26.60.100"
20   - port = 8850
21   -
22   - transport: TSocket = TSocket.TSocket(host, port)
23   - transport = TTransport.TBufferedTransport(transport)
24   - protocol = TBinaryProtocol.TBinaryProtocol(transport)
25   - client = Calculator.Client(protocol)
26   -
27   -
28   - transport.open()
29   - import sys
30   - test = client.getData("江南_01.tif",[1340.27, -1911.31, 4351.79, 5410.6],[1340.27, -1911.31, 4351.79, 5410.6],[3,2,1],768,768)
31   - print(sys.getsizeof(test[1]))
32   - # print(test)
33   -
34   -def test2():
35   - host = "172.26.60.100"
36   - port = 9090
37   -
38   - transport: TSocket = TSocket.TSocket(host, port)
39   - transport = TTransport.TBufferedTransport(transport)
40   - protocol = TBinaryProtocol.TBinaryProtocol(transport)
41   - client = ImageDataService.Client(protocol)
42   -
43   - transport.open()
44   -
45   - test = client.getData("/usr/src/data/江南_01.tif", [1340.27, -1911.31, 4351.79, 5410.6], [1340.27, -1911.31, 4351.79, 5410.6],
46   - [1,2,3], 768, 768)
47   -
48   - import gzip,numpy
49   - data = gzip.decompress(test)
50   - # data = numpy.frombuffer(data, dtype='int64')
51   - # data = data.reshape((768, 768, 3))
52   -
53   - import sys
54   - print(sys.getsizeof(data))
55   - # print(test)
56   -
57   -if __name__ == '__main__':
58   - t1 = time.time()
59   - # test1()
60   - print(time.time()-t1)
61   - t2 = time.time()
62   - test2()
63   - print(time.time()-t2)
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   -
18   -
19   -class Image(object):
20   - """
21   - Structs are the basic complex data structures. They are comprised of fields
22   - which each have an integer identifier, a type, a symbolic name, and an
23   - optional default value.
24   -
25   - Fields can be declared "optional", which ensures they will not be included
26   - in the serialized output if they aren't set. Note that this requires some
27   - manual management in some languages.
28   -
29   - Attributes:
30   - - name
31   - - path
32   - - size
33   - - create_time
34   - - type
35   -
36   - """
37   -
38   -
39   - def __init__(self, name=None, path=None, size=None, create_time=None, type=None,):
40   - self.name = name
41   - self.path = path
42   - self.size = size
43   - self.create_time = create_time
44   - self.type = type
45   -
46   - def read(self, iprot):
47   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
48   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
49   - return
50   - iprot.readStructBegin()
51   - while True:
52   - (fname, ftype, fid) = iprot.readFieldBegin()
53   - if ftype == TType.STOP:
54   - break
55   - if fid == 1:
56   - if ftype == TType.STRING:
57   - self.name = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
58   - else:
59   - iprot.skip(ftype)
60   - elif fid == 2:
61   - if ftype == TType.STRING:
62   - self.path = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
63   - else:
64   - iprot.skip(ftype)
65   - elif fid == 3:
66   - if ftype == TType.STRING:
67   - self.size = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
68   - else:
69   - iprot.skip(ftype)
70   - elif fid == 4:
71   - if ftype == TType.STRING:
72   - self.create_time = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
73   - else:
74   - iprot.skip(ftype)
75   - elif fid == 5:
76   - if ftype == TType.STRING:
77   - self.type = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
78   - else:
79   - iprot.skip(ftype)
80   - else:
81   - iprot.skip(ftype)
82   - iprot.readFieldEnd()
83   - iprot.readStructEnd()
84   -
85   - def write(self, oprot):
86   - if oprot._fast_encode is not None and self.thrift_spec is not None:
87   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
88   - return
89   - oprot.writeStructBegin('Image')
90   - if self.name is not None:
91   - oprot.writeFieldBegin('name', TType.STRING, 1)
92   - oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
93   - oprot.writeFieldEnd()
94   - if self.path is not None:
95   - oprot.writeFieldBegin('path', TType.STRING, 2)
96   - oprot.writeString(self.path.encode('utf-8') if sys.version_info[0] == 2 else self.path)
97   - oprot.writeFieldEnd()
98   - if self.size is not None:
99   - oprot.writeFieldBegin('size', TType.STRING, 3)
100   - oprot.writeString(self.size.encode('utf-8') if sys.version_info[0] == 2 else self.size)
101   - oprot.writeFieldEnd()
102   - if self.create_time is not None:
103   - oprot.writeFieldBegin('create_time', TType.STRING, 4)
104   - oprot.writeString(self.create_time.encode('utf-8') if sys.version_info[0] == 2 else self.create_time)
105   - oprot.writeFieldEnd()
106   - if self.type is not None:
107   - oprot.writeFieldBegin('type', TType.STRING, 5)
108   - oprot.writeString(self.type.encode('utf-8') if sys.version_info[0] == 2 else self.type)
109   - oprot.writeFieldEnd()
110   - oprot.writeFieldStop()
111   - oprot.writeStructEnd()
112   -
113   - def validate(self):
114   - return
115   -
116   - def __repr__(self):
117   - L = ['%s=%r' % (key, value)
118   - for key, value in self.__dict__.items()]
119   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
120   -
121   - def __eq__(self, other):
122   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
123   -
124   - def __ne__(self, other):
125   - return not (self == other)
126   -
127   -
128   -class RasterData(object):
129   - """
130   - Attributes:
131   - - R
132   - - G
133   - - B
134   -
135   - """
136   -
137   -
138   - def __init__(self, R=None, G=None, B=None,):
139   - self.R = R
140   - self.G = G
141   - self.B = B
142   -
143   - def read(self, iprot):
144   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
145   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
146   - return
147   - iprot.readStructBegin()
148   - while True:
149   - (fname, ftype, fid) = iprot.readFieldBegin()
150   - if ftype == TType.STOP:
151   - break
152   - if fid == 1:
153   - if ftype == TType.LIST:
154   - self.R = []
155   - (_etype3, _size0) = iprot.readListBegin()
156   - for _i4 in range(_size0):
157   - _elem5 = iprot.readI16()
158   - self.R.append(_elem5)
159   - iprot.readListEnd()
160   - else:
161   - iprot.skip(ftype)
162   - elif fid == 2:
163   - if ftype == TType.LIST:
164   - self.G = []
165   - (_etype9, _size6) = iprot.readListBegin()
166   - for _i10 in range(_size6):
167   - _elem11 = iprot.readI16()
168   - self.G.append(_elem11)
169   - iprot.readListEnd()
170   - else:
171   - iprot.skip(ftype)
172   - elif fid == 3:
173   - if ftype == TType.LIST:
174   - self.B = []
175   - (_etype15, _size12) = iprot.readListBegin()
176   - for _i16 in range(_size12):
177   - _elem17 = iprot.readI16()
178   - self.B.append(_elem17)
179   - iprot.readListEnd()
180   - else:
181   - iprot.skip(ftype)
182   - else:
183   - iprot.skip(ftype)
184   - iprot.readFieldEnd()
185   - iprot.readStructEnd()
186   -
187   - def write(self, oprot):
188   - if oprot._fast_encode is not None and self.thrift_spec is not None:
189   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
190   - return
191   - oprot.writeStructBegin('RasterData')
192   - if self.R is not None:
193   - oprot.writeFieldBegin('R', TType.LIST, 1)
194   - oprot.writeListBegin(TType.I16, len(self.R))
195   - for iter18 in self.R:
196   - oprot.writeI16(iter18)
197   - oprot.writeListEnd()
198   - oprot.writeFieldEnd()
199   - if self.G is not None:
200   - oprot.writeFieldBegin('G', TType.LIST, 2)
201   - oprot.writeListBegin(TType.I16, len(self.G))
202   - for iter19 in self.G:
203   - oprot.writeI16(iter19)
204   - oprot.writeListEnd()
205   - oprot.writeFieldEnd()
206   - if self.B is not None:
207   - oprot.writeFieldBegin('B', TType.LIST, 3)
208   - oprot.writeListBegin(TType.I16, len(self.B))
209   - for iter20 in self.B:
210   - oprot.writeI16(iter20)
211   - oprot.writeListEnd()
212   - oprot.writeFieldEnd()
213   - oprot.writeFieldStop()
214   - oprot.writeStructEnd()
215   -
216   - def validate(self):
217   - return
218   -
219   - def __repr__(self):
220   - L = ['%s=%r' % (key, value)
221   - for key, value in self.__dict__.items()]
222   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
223   -
224   - def __eq__(self, other):
225   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
226   -
227   - def __ne__(self, other):
228   - return not (self == other)
229   -
230   -
231   -class Raster(object):
232   - """
233   - Attributes:
234   - - band_count
235   - - overview_count
236   - - xy_size
237   - - origin_extent
238   - - null_value
239   - - sr_wkt
240   - - epsg
241   - - sr_proj4
242   - - size
243   - - path
244   - - cell_x_size
245   - - cell_y_size
246   -
247   - """
248   -
249   -
250   - def __init__(self, band_count=None, overview_count=None, xy_size=None, origin_extent=None, null_value=None, sr_wkt=None, epsg=None, sr_proj4=None, size=None, path=None, cell_x_size=None, cell_y_size=None,):
251   - self.band_count = band_count
252   - self.overview_count = overview_count
253   - self.xy_size = xy_size
254   - self.origin_extent = origin_extent
255   - self.null_value = null_value
256   - self.sr_wkt = sr_wkt
257   - self.epsg = epsg
258   - self.sr_proj4 = sr_proj4
259   - self.size = size
260   - self.path = path
261   - self.cell_x_size = cell_x_size
262   - self.cell_y_size = cell_y_size
263   -
264   - def read(self, iprot):
265   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
266   - iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
267   - return
268   - iprot.readStructBegin()
269   - while True:
270   - (fname, ftype, fid) = iprot.readFieldBegin()
271   - if ftype == TType.STOP:
272   - break
273   - if fid == 1:
274   - if ftype == TType.I32:
275   - self.band_count = iprot.readI32()
276   - else:
277   - iprot.skip(ftype)
278   - elif fid == 2:
279   - if ftype == TType.I32:
280   - self.overview_count = iprot.readI32()
281   - else:
282   - iprot.skip(ftype)
283   - elif fid == 3:
284   - if ftype == TType.LIST:
285   - self.xy_size = []
286   - (_etype24, _size21) = iprot.readListBegin()
287   - for _i25 in range(_size21):
288   - _elem26 = iprot.readI32()
289   - self.xy_size.append(_elem26)
290   - iprot.readListEnd()
291   - else:
292   - iprot.skip(ftype)
293   - elif fid == 4:
294   - if ftype == TType.LIST:
295   - self.origin_extent = []
296   - (_etype30, _size27) = iprot.readListBegin()
297   - for _i31 in range(_size27):
298   - _elem32 = iprot.readDouble()
299   - self.origin_extent.append(_elem32)
300   - iprot.readListEnd()
301   - else:
302   - iprot.skip(ftype)
303   - elif fid == 5:
304   - if ftype == TType.DOUBLE:
305   - self.null_value = iprot.readDouble()
306   - else:
307   - iprot.skip(ftype)
308   - elif fid == 6:
309   - if ftype == TType.STRING:
310   - self.sr_wkt = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
311   - else:
312   - iprot.skip(ftype)
313   - elif fid == 7:
314   - if ftype == TType.STRING:
315   - self.epsg = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
316   - else:
317   - iprot.skip(ftype)
318   - elif fid == 8:
319   - if ftype == TType.STRING:
320   - self.sr_proj4 = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
321   - else:
322   - iprot.skip(ftype)
323   - elif fid == 9:
324   - if ftype == TType.I32:
325   - self.size = iprot.readI32()
326   - else:
327   - iprot.skip(ftype)
328   - elif fid == 10:
329   - if ftype == TType.STRING:
330   - self.path = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
331   - else:
332   - iprot.skip(ftype)
333   - elif fid == 11:
334   - if ftype == TType.DOUBLE:
335   - self.cell_x_size = iprot.readDouble()
336   - else:
337   - iprot.skip(ftype)
338   - elif fid == 12:
339   - if ftype == TType.DOUBLE:
340   - self.cell_y_size = iprot.readDouble()
341   - else:
342   - iprot.skip(ftype)
343   - else:
344   - iprot.skip(ftype)
345   - iprot.readFieldEnd()
346   - iprot.readStructEnd()
347   -
348   - def write(self, oprot):
349   - if oprot._fast_encode is not None and self.thrift_spec is not None:
350   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
351   - return
352   - oprot.writeStructBegin('Raster')
353   - if self.band_count is not None:
354   - oprot.writeFieldBegin('band_count', TType.I32, 1)
355   - oprot.writeI32(self.band_count)
356   - oprot.writeFieldEnd()
357   - if self.overview_count is not None:
358   - oprot.writeFieldBegin('overview_count', TType.I32, 2)
359   - oprot.writeI32(self.overview_count)
360   - oprot.writeFieldEnd()
361   - if self.xy_size is not None:
362   - oprot.writeFieldBegin('xy_size', TType.LIST, 3)
363   - oprot.writeListBegin(TType.I32, len(self.xy_size))
364   - for iter33 in self.xy_size:
365   - oprot.writeI32(iter33)
366   - oprot.writeListEnd()
367   - oprot.writeFieldEnd()
368   - if self.origin_extent is not None:
369   - oprot.writeFieldBegin('origin_extent', TType.LIST, 4)
370   - oprot.writeListBegin(TType.DOUBLE, len(self.origin_extent))
371   - for iter34 in self.origin_extent:
372   - oprot.writeDouble(iter34)
373   - oprot.writeListEnd()
374   - oprot.writeFieldEnd()
375   - if self.null_value is not None:
376   - oprot.writeFieldBegin('null_value', TType.DOUBLE, 5)
377   - oprot.writeDouble(self.null_value)
378   - oprot.writeFieldEnd()
379   - if self.sr_wkt is not None:
380   - oprot.writeFieldBegin('sr_wkt', TType.STRING, 6)
381   - oprot.writeString(self.sr_wkt.encode('utf-8') if sys.version_info[0] == 2 else self.sr_wkt)
382   - oprot.writeFieldEnd()
383   - if self.epsg is not None:
384   - oprot.writeFieldBegin('epsg', TType.STRING, 7)
385   - oprot.writeString(self.epsg.encode('utf-8') if sys.version_info[0] == 2 else self.epsg)
386   - oprot.writeFieldEnd()
387   - if self.sr_proj4 is not None:
388   - oprot.writeFieldBegin('sr_proj4', TType.STRING, 8)
389   - oprot.writeString(self.sr_proj4.encode('utf-8') if sys.version_info[0] == 2 else self.sr_proj4)
390   - oprot.writeFieldEnd()
391   - if self.size is not None:
392   - oprot.writeFieldBegin('size', TType.I32, 9)
393   - oprot.writeI32(self.size)
394   - oprot.writeFieldEnd()
395   - if self.path is not None:
396   - oprot.writeFieldBegin('path', TType.STRING, 10)
397   - oprot.writeString(self.path.encode('utf-8') if sys.version_info[0] == 2 else self.path)
398   - oprot.writeFieldEnd()
399   - if self.cell_x_size is not None:
400   - oprot.writeFieldBegin('cell_x_size', TType.DOUBLE, 11)
401   - oprot.writeDouble(self.cell_x_size)
402   - oprot.writeFieldEnd()
403   - if self.cell_y_size is not None:
404   - oprot.writeFieldBegin('cell_y_size', TType.DOUBLE, 12)
405   - oprot.writeDouble(self.cell_y_size)
406   - oprot.writeFieldEnd()
407   - oprot.writeFieldStop()
408   - oprot.writeStructEnd()
409   -
410   - def validate(self):
411   - return
412   -
413   - def __repr__(self):
414   - L = ['%s=%r' % (key, value)
415   - for key, value in self.__dict__.items()]
416   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
417   -
418   - def __eq__(self, other):
419   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
420   -
421   - def __ne__(self, other):
422   - return not (self == other)
423   -
424   -
425   -class InvalidOperation(TException):
426   - """
427   - Structs can also be exceptions, if they are nasty.
428   -
429   - Attributes:
430   - - whatOp
431   - - why
432   -
433   - """
434   -
435   -
436   - def __init__(self, whatOp=None, why=None,):
437   - super(InvalidOperation, self).__setattr__('whatOp', whatOp)
438   - super(InvalidOperation, self).__setattr__('why', why)
439   -
440   - def __setattr__(self, *args):
441   - raise TypeError("can't modify immutable instance")
442   -
443   - def __delattr__(self, *args):
444   - raise TypeError("can't modify immutable instance")
445   -
446   - def __hash__(self):
447   - return hash(self.__class__) ^ hash((self.whatOp, self.why, ))
448   -
449   - @classmethod
450   - def read(cls, iprot):
451   - if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and cls.thrift_spec is not None:
452   - return iprot._fast_decode(None, iprot, [cls, cls.thrift_spec])
453   - iprot.readStructBegin()
454   - whatOp = None
455   - why = None
456   - while True:
457   - (fname, ftype, fid) = iprot.readFieldBegin()
458   - if ftype == TType.STOP:
459   - break
460   - if fid == 1:
461   - if ftype == TType.I32:
462   - whatOp = iprot.readI32()
463   - else:
464   - iprot.skip(ftype)
465   - elif fid == 2:
466   - if ftype == TType.STRING:
467   - why = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
468   - else:
469   - iprot.skip(ftype)
470   - else:
471   - iprot.skip(ftype)
472   - iprot.readFieldEnd()
473   - iprot.readStructEnd()
474   - return cls(
475   - whatOp=whatOp,
476   - why=why,
477   - )
478   -
479   - def write(self, oprot):
480   - if oprot._fast_encode is not None and self.thrift_spec is not None:
481   - oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
482   - return
483   - oprot.writeStructBegin('InvalidOperation')
484   - if self.whatOp is not None:
485   - oprot.writeFieldBegin('whatOp', TType.I32, 1)
486   - oprot.writeI32(self.whatOp)
487   - oprot.writeFieldEnd()
488   - if self.why is not None:
489   - oprot.writeFieldBegin('why', TType.STRING, 2)
490   - oprot.writeString(self.why.encode('utf-8') if sys.version_info[0] == 2 else self.why)
491   - oprot.writeFieldEnd()
492   - oprot.writeFieldStop()
493   - oprot.writeStructEnd()
494   -
495   - def validate(self):
496   - return
497   -
498   - def __str__(self):
499   - return repr(self)
500   -
501   - def __repr__(self):
502   - L = ['%s=%r' % (key, value)
503   - for key, value in self.__dict__.items()]
504   - return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
505   -
506   - def __eq__(self, other):
507   - return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
508   -
509   - def __ne__(self, other):
510   - return not (self == other)
511   -all_structs.append(Image)
512   -Image.thrift_spec = (
513   - None, # 0
514   - (1, TType.STRING, 'name', 'UTF8', None, ), # 1
515   - (2, TType.STRING, 'path', 'UTF8', None, ), # 2
516   - (3, TType.STRING, 'size', 'UTF8', None, ), # 3
517   - (4, TType.STRING, 'create_time', 'UTF8', None, ), # 4
518   - (5, TType.STRING, 'type', 'UTF8', None, ), # 5
519   -)
520   -all_structs.append(RasterData)
521   -RasterData.thrift_spec = (
522   - None, # 0
523   - (1, TType.LIST, 'R', (TType.I16, None, False), None, ), # 1
524   - (2, TType.LIST, 'G', (TType.I16, None, False), None, ), # 2
525   - (3, TType.LIST, 'B', (TType.I16, None, False), None, ), # 3
526   -)
527   -all_structs.append(Raster)
528   -Raster.thrift_spec = (
529   - None, # 0
530   - (1, TType.I32, 'band_count', None, None, ), # 1
531   - (2, TType.I32, 'overview_count', None, None, ), # 2
532   - (3, TType.LIST, 'xy_size', (TType.I32, None, False), None, ), # 3
533   - (4, TType.LIST, 'origin_extent', (TType.DOUBLE, None, False), None, ), # 4
534   - (5, TType.DOUBLE, 'null_value', None, None, ), # 5
535   - (6, TType.STRING, 'sr_wkt', 'UTF8', None, ), # 6
536   - (7, TType.STRING, 'epsg', 'UTF8', None, ), # 7
537   - (8, TType.STRING, 'sr_proj4', 'UTF8', None, ), # 8
538   - (9, TType.I32, 'size', None, None, ), # 9
539   - (10, TType.STRING, 'path', 'UTF8', None, ), # 10
540   - (11, TType.DOUBLE, 'cell_x_size', None, None, ), # 11
541   - (12, TType.DOUBLE, 'cell_y_size', None, None, ), # 12
542   -)
543   -all_structs.append(InvalidOperation)
544   -InvalidOperation.thrift_spec = (
545   - None, # 0
546   - (1, TType.I32, 'whatOp', None, None, ), # 1
547   - (2, TType.STRING, 'why', 'UTF8', None, ), # 2
548   -)
549   -fix_spec(all_structs)
550   -del all_structs
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/10/18
4   -#email: nheweijun@sina.com
5   -
6   -
7   -from kazoo.client import KazooClient
8   -import configure
9   -import time
10   -from app.modules.service.models import ImageService
11   -from app.modules.service.models import TileScheme,Service
12   -from app.util.component.ModelVisitor import ModelVisitor
13   -from app.util.component.StructuredPrint import StructurePrint
14   -import json
15   -import traceback
16   -
17   -class Cache:
18   -
19   - @classmethod
20   - def cache_data(cls,guid_or_name,type="guid"):
21   -
22   - from app import GLOBAL_DIC
23   -
24   - # 缓存zookeeper
25   - zoo = GLOBAL_DIC.get("zookeeper")
26   - if zoo is None:
27   - zoo: KazooClient = KazooClient(hosts=configure.zookeeper, timeout=1)
28   - zoo.start()
29   - GLOBAL_DIC["zookeeper"] = zoo
30   - GLOBAL_DIC["zookeeper_updatetime"] = time.time()
31   - else:
32   - if not zoo.connected:
33   - try:
34   - zoo.start()
35   - except:
36   - pass
37   -
38   - # 更新zoo
39   - if not GLOBAL_DIC.get("zookeeper_updatetime"):
40   - GLOBAL_DIC["zookeeper_updatetime"] = time.time()
41   - if time.time() - GLOBAL_DIC["zookeeper_updatetime"] > 15:
42   - #释放,高并发下可行吗,线程安全问题
43   - try:
44   - zoo.stop()
45   - zoo.close()
46   - del zoo
47   - except Exception as e:
48   - StructurePrint().print("关闭zoo失败")
49   - StructurePrint().print(e.__str__())
50   - zoo: KazooClient = KazooClient(hosts=configure.zookeeper, timeout=1)
51   - zoo.start()
52   - GLOBAL_DIC["zookeeper"] = zoo
53   - GLOBAL_DIC["zookeeper_updatetime"] = time.time()
54   -
55   - # 缓存数据服务器
56   - servers = GLOBAL_DIC.get("servers")
57   - if servers is None:
58   - servers = zoo.get_children("/rpc")
59   - servers.append("本地服务器")
60   - GLOBAL_DIC["servers"] = servers
61   - GLOBAL_DIC["servers_updatetime"] = time.time()
62   - else:
63   - servers = GLOBAL_DIC.get("servers")
64   -
65   - # 更新缓存
66   - if time.time() - GLOBAL_DIC["servers_updatetime"] > 15:
67   - servers = zoo.get_children("/rpc")
68   - servers.append("本地服务器")
69   - GLOBAL_DIC["servers"] = servers
70   - GLOBAL_DIC["servers_updatetime"] = time.time()
71   -
72   -
73   - # 缓存服务信息
74   - if guid_or_name:
75   - image_service_info = GLOBAL_DIC.get(guid_or_name)
76   - if image_service_info is None or time.time() - GLOBAL_DIC.get("service_updatetime") > 15:
77   - if type.__eq__("guid"):
78   - image_service: ImageService = ImageService.query.filter_by(guid=guid_or_name).one_or_none()
79   - else:
80   - image_service: ImageService = ImageService.query.filter_by(name=guid_or_name).one_or_none()
81   -
82   - images = image_service.images.all()
83   -
84   - if image_service.scheme_guid:
85   - scheme: TileScheme = TileScheme.query.filter_by(guid=image_service.scheme_guid).one_or_none()
86   -
87   - GLOBAL_DIC[guid_or_name] = {"service": ModelVisitor.object_to_json(image_service),
88   - "images": ModelVisitor.objects_to_jsonarray(images),
89   - "scheme": json.loads(scheme.parameter)}
90   - else:
91   -
92   - GLOBAL_DIC[guid_or_name] = {"service": ModelVisitor.object_to_json(image_service),
93   - "images": ModelVisitor.objects_to_jsonarray(images)}
94   -
95   -
96   - GLOBAL_DIC["service_updatetime"] = time.time()
97   - image_service_info = GLOBAL_DIC[guid_or_name]
98   - else:
99   - image_service_info = GLOBAL_DIC[guid_or_name]
100   - else:
101   - image_service_info = None
102   -
103   - return image_service_info,zoo,servers
104   -
105   -
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/10/15
4   -#email: nheweijun@sina.com
5   -
6   -from app.util import *
7   -from osgeo import gdal
8   -from osgeo.gdal import *
9   -from numpy import ndarray
10   -import numpy
11   -from app.modules.service.image.util.ThriftConnect import ThriftConnect,ThriftPool
12   -import json
13   -import gzip
14   -
15   -class ImageData:
16   -
17   -
18   - def __init__(self,image_server,image):
19   - self.image_server = image_server
20   - self.image = image
21   -
22   -
23   - def get_data(self, extent, bands, height, width):
24   - if self.image_server.__eq__("本地服务器"):
25   - data = self.get_local_wms_data(extent, bands, height, width)
26   - elif self.image_server.__eq__("None"):
27   - data = numpy.zeros((height, width, 3), dtype=int) + 65536
28   - else:
29   - data = self.get_remote_wms_data(extent, bands, height, width)
30   - return data
31   -
32   -
33   - def get_remote_wms_data(self, extent, bands, height, width):
34   - '''
35   - 通过RPC获取远程数据
36   - :param image:
37   - :param extent:
38   - :param bands:
39   - :return:
40   - '''
41   -
42   - # 需要做thrift连接的缓存,连接池
43   - thrift_connect = ThriftConnect(self.image_server)
44   - image_extent = self.image.get("extent")
45   -
46   - data = thrift_connect.client.getData(self.image.get("path"), extent, json.loads(image_extent), bands, width, height)
47   -
48   - thrift_connect.close()
49   -
50   - data = gzip.decompress(data)
51   - data = numpy.frombuffer(data, dtype='int64')
52   - data = data.reshape((height, width, 3))
53   -
54   - return data
55   -
56   -
57   - def get_remote_wms_data_cpp(self, image_server, image, extent, bands, height, width):
58   - '''
59   - 通过RPC获取远程数据
60   - :param image:
61   - :param extent:
62   - :param bands:
63   - :return:
64   - '''
65   -
66   - # 需要做thrift连接的缓存,连接池
67   - thrift_connect = ThriftConnect(image_server)
68   - image_extent = image.get("extent")
69   -
70   - data = thrift_connect.client.getData(image.get("path"), extent, json.loads(image_extent), bands, width, height)
71   -
72   - thrift_connect.close()
73   -
74   - return data
75   -
76   -
77   - def get_local_wms_data(self, extent, bands, height, width):
78   - '''
79   - 获取本地数据
80   - :param image:
81   - :param extent:
82   - :param bands:
83   - :return:
84   - '''
85   - pixel_array = numpy.zeros((height, width, 3), dtype=int)
86   - ceng = 0
87   - img: Dataset = gdal.Open(self.image.get("path"), 0)
88   -
89   - for band in bands:
90   -
91   - # 自决定金字塔等级
92   - xysize = [img.RasterXSize, img.RasterYSize]
93   -
94   - origin_extent = json.loads(self.image.get("extent"))
95   - band_data: Band = img.GetRasterBand(band)
96   -
97   - max_level = band_data.GetOverviewCount()
98   -
99   - # 超出空间范围
100   - if extent[2] < origin_extent[0] or extent[0] > origin_extent[2] or extent[1] > origin_extent[
101   - 3] or extent[3] < origin_extent[1]:
102   - empty = numpy.zeros((height, width), dtype=int) + 65536
103   - # 空间范围相交
104   - else:
105   - image_level = self.determine_level(xysize, origin_extent, extent, max_level)
106   -
107   - if image_level == -1:
108   - overview = band_data
109   - else:
110   - try:
111   - overview: Band = band_data.GetOverview(image_level)
112   - except:
113   - raise Exception("该影像不存在该级别的金字塔数据!")
114   - ox = overview.XSize
115   - oy = overview.YSize
116   -
117   - # 网格大小
118   - grid_x = (origin_extent[2] - origin_extent[0]) / (ox * 1.0)
119   - grid_y = (origin_extent[3] - origin_extent[1]) / (oy * 1.0)
120   -
121   - # 完全在影像范围内
122   - if extent[0] > origin_extent[0] and extent[1] > origin_extent[1] and extent[2] < \
123   - origin_extent[2] and extent[3] < origin_extent[3]:
124   -
125   - # 网格偏移量
126   - off_x = math.floor((extent[0] - origin_extent[0]) / grid_x)
127   - off_y = math.floor((origin_extent[3] - extent[3]) / grid_y)
128   -
129   - # 截取后网格个数
130   - x_g = math.ceil((extent[2] - extent[0]) / grid_x)
131   -
132   - y_g = math.ceil((extent[3] - extent[1]) / grid_y)
133   -
134   - empty = overview.ReadAsArray(off_x, off_y, x_g, y_g, width, height)
135   -
136   -
137   - # 部分相交
138   - else:
139   -
140   - inter_extent = [0, 0, 0, 0]
141   - inter_extent[0] = origin_extent[0] if origin_extent[0] > extent[0] else extent[0]
142   - inter_extent[1] = origin_extent[1] if origin_extent[1] > extent[1] else extent[1]
143   - inter_extent[2] = origin_extent[2] if origin_extent[2] < extent[2] else extent[2]
144   - inter_extent[3] = origin_extent[3] if origin_extent[3] < extent[3] else extent[3]
145   -
146   - # 网格偏移量
147   - off_x = math.floor((inter_extent[0] - origin_extent[0]) / grid_x)
148   - off_y = math.floor((origin_extent[3] - inter_extent[3]) / grid_y)
149   -
150   - # 截取后网格个数
151   - x_g = math.floor((inter_extent[2] - inter_extent[0]) / grid_x)
152   - y_g = math.floor((inter_extent[3] - inter_extent[1]) / grid_y)
153   -
154   - # 相对于出图的偏移量
155   -
156   - # 出图的网格大小
157   - out_grid_x = (extent[2] - extent[0]) / (width * 1.0)
158   - out_grid_y = (extent[3] - extent[1]) / (height * 1.0)
159   -
160   - out_off_x = int(math.ceil((inter_extent[0] - extent[0]) / out_grid_x))
161   - out_off_y = int(math.ceil((extent[3] - inter_extent[3]) / out_grid_y))
162   -
163   - out_x_g = int(math.floor((inter_extent[2] - inter_extent[0]) / out_grid_x))
164   - out_y_g = int(math.floor((inter_extent[3] - inter_extent[1]) / out_grid_y))
165   -
166   - # 相交部分在出图的哪个位置
167   -
168   - overview_raster: ndarray = overview.ReadAsArray(off_x, off_y, x_g, y_g, out_x_g,
169   - out_y_g)
170   -
171   - dat = numpy.zeros((height, width), dtype=int) + 65536
172   - dat[out_off_y:out_off_y + out_y_g, out_off_x:out_off_x + out_x_g] = overview_raster
173   -
174   - empty = dat
175   -
176   - pixel_array[:, :, ceng] = empty
177   - ceng += 1
178   - return pixel_array
179   -
180   -
181   - def determine_level(self, xysize, origin_extent, extent, max_level):
182   - '''
183   - 根据范围判断调用金字塔的哪一层
184   - :param xysize:
185   - :param origin_extent:
186   - :param extent:
187   - :param max_level:
188   - :return:
189   - '''
190   - x = xysize[0]
191   - y = xysize[1]
192   - level = -1
193   - pixel = x * y * (((extent[2] - extent[0]) * (extent[3] - extent[1])) / (
194   - (origin_extent[2] - origin_extent[0]) * (origin_extent[3] - origin_extent[1])))
195   - while pixel > 100000 and level < max_level - 1:
196   - level += 1
197   - x = x / 2
198   - y = y / 2
199   - pixel = x * y * (((extent[2] - extent[0]) * (extent[3] - extent[1])) / (
200   - (origin_extent[2] - origin_extent[0]) * (origin_extent[3] - origin_extent[1])))
201   - return level
\ No newline at end of file
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/10/26
4   -#email: nheweijun@sina.com
5   -
6   -
7   -class ImageServer:
8   - pass
\ No newline at end of file
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/10/18
4   -#email: nheweijun@sina.com
5   -import os
6   -
7   -class ImageType:
8   -
9   - @classmethod
10   - def get_type(cls,path):
11   -
12   - if os.path.isdir(path):
13   - type = "dir"
14   - elif path.lower().endswith(".tiff") or path.lower().endswith(".tif"):
15   - type = "tif"
16   - elif path.lower().endswith(".img"):
17   - type = "img"
18   - else:
19   - type = None
20   - return type
21   -
22   -
23   -if __name__ == '__main__':
24   - print(ImageType.get_type("/da/d/ftif"))
\ No newline at end of file
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/10/26
4   -#email: nheweijun@sina.com
5   -
6   -
7   -import numpy
8   -from app.util.component.ParameterUtil import ParameterUtil
9   -from .Cache import Cache
10   -from app.modules.service.models import ImageService
11   -from flask import Response
12   -from .ImageData import ImageData
13   -from .MyThread import MyThread
14   -from .Opencv import Opencv
15   -import json
16   -import random
17   -import configure
18   -import threading
19   -from .ImageServer import ImageServer
20   -
21   -
22   -class ImageWMSServer(ImageServer):
23   -
24   - _instance_lock = threading.Lock()
25   - singleton = None
26   -
27   - def __init__(self):
28   - pass
29   -
30   - def __new__(cls, *args, **kwargs):
31   - if not cls.singleton:
32   - with ImageWMSServer._instance_lock:
33   - cls.singleton = super().__new__(cls)
34   - return cls.singleton
35   -
36   - def wms(self,service_name,parameter,type="name"):
37   -
38   - # 获取缓存信息
39   - image_service_info, zoo, servers = Cache.cache_data(service_name, type=type)
40   - # 转换参数
41   - parameter = ParameterUtil.to_lower(parameter)
42   - re = parameter.get("request")
43   - if re and re.__eq__("GetCapabilities"):
44   - return self.get_wms_capabilities(image_service_info["service"])
45   -
46   - bbox = parameter.get("bbox")
47   - width = int(parameter.get("width")) if parameter.get("width") else 256
48   - height = int(parameter.get("height")) if parameter.get("height") else 256
49   - image_type = parameter.get("format") if parameter.get("format") else "image/png"
50   - quality = int(parameter.get("quality")) if parameter.get("quality") else 30
51   -
52   - extent = [float(x) for x in bbox.split(",")]
53   -
54   - intersect_image = [im for im in image_service_info["images"] if
55   - self.determin_intersect(json.loads(im.get("extent")), extent)]
56   -
57   - if len(intersect_image) > 1:
58   -
59   - # 结果矩阵
60   - empty_list = [numpy.zeros((height, width), dtype=int) + 65536,
61   - numpy.zeros((height, width), dtype=int) + 65536,
62   - numpy.zeros((height, width), dtype=int) + 65536]
63   -
64   - pixel_array = numpy.zeros((height, width, 3), dtype=int)
65   - thread_list = []
66   -
67   - for image in intersect_image:
68   - # 该影像的服务器,随机选取一个
69   - image_servers = image.get("server").split(",")
70   - image_servers = [ser for ser in image_servers if ser in servers]
71   - if len(image_servers) > 0:
72   - indx = int(random.random() * len(image_servers))
73   - image_server = image_servers[indx]
74   - else:
75   - image_server = "None"
76   - bands = json.loads(image.get("band_view"))
77   -
78   - image_data = ImageData(image_server, image)
79   -
80   - thread: MyThread = MyThread(image_data.get_data, args=(extent, bands, height, width))
81   - thread.start()
82   - thread_list.append(thread)
83   -
84   - for thread in thread_list:
85   - thread.join()
86   - data = thread.get_result()
87   -
88   - # 掩膜在中央接口生成,合图
89   - mask = numpy.zeros((height, width), dtype=int)
90   - mask2 = numpy.zeros((height, width), dtype=int)
91   - jizhun = data[:, :, 0]
92   - mask[jizhun == 65536] = 1
93   - mask[jizhun != 65536] = 0
94   - mask2[jizhun == 65536] = 0
95   - mask2[jizhun != 65536] = 1
96   - # 掩膜计算
97   - for i, d in enumerate(empty_list):
98   - empty_list[i] = empty_list[i] * mask + data[:, :, i] * mask2
99   -
100   - for ii in [0, 1, 2]:
101   - # opencv 颜色排序为GBR
102   - pixel_array[:, :, 2 - ii] = empty_list[ii]
103   -
104   -
105   - elif len(intersect_image) == 1:
106   - # 该影像的服务器,随机选取一个
107   - image = intersect_image[0]
108   - image_servers = image.get("server").split(",")
109   - image_servers = [ser for ser in image_servers if ser in servers]
110   - if len(image_servers) > 0:
111   - indx = int(random.random() * len(image_servers))
112   - image_server = image_servers[indx]
113   - else:
114   - image_server = "None"
115   -
116   - bands = json.loads(image.get("band_view"))
117   -
118   - image_data = ImageData(image_server, image)
119   -
120   - pixel_array_t = image_data.get_data(extent, bands, height, width)
121   -
122   - pixel_array = numpy.zeros((height, width, 3), dtype=int)
123   - for ii in [0, 1, 2]:
124   - # opencv 颜色排序为GBR
125   - pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii]
126   - else:
127   - # 结果矩阵
128   - pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536
129   -
130   - # 将图片生成在内存中,然后直接返回response
131   - im_data = Opencv.create_image(image_type, pixel_array, quality)
132   -
133   - if parameter.get("overview"):
134   - return pixel_array
135   - return Response(im_data, mimetype=image_type.lower())
136   -
137   -
138   - def get_wms_capabilities(self, image_service: ImageService):
139   -
140   - xml = '''<?xml version="1.0" encoding="utf-8" ?>
141   - <WMS_Capabilities version="1.2.0">
142   - <Service>
143   - <Name>WMS</Name>
144   - <Title>{service_title}</Title>
145   - <Abstract>{abstract}</Abstract>
146   - <Keywords>GIMS</Keywords>
147   - <OnlineResource/>
148   - <Fees>none</Fees>
149   - <AccessConstraints>none</AccessConstraints>
150   - </Service>
151   - <Capability>
152   - <Request>
153   - <GetCapabilities>
154   - <Format>text/xml</Format>
155   - <DCPType>
156   - <HTTP>
157   - <Get>
158   - <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
159   - </Get>
160   - </HTTP>
161   - </DCPType>
162   - </GetCapabilities>
163   - <GetMap>
164   - <Format>png</Format>
165   - <Format>jpeg</Format>
166   - <Format>gif</Format>
167   - <Format>image/png</Format>
168   - <Format>image/jpeg</Format>
169   - <Format>image/gif</Format>
170   - <DCPType>
171   - <HTTP>
172   - <Get>
173   - <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
174   - </Get>
175   - </HTTP>
176   - </DCPType>
177   - </GetMap>
178   - <Map>
179   - <Format>
180   - <PNG/>
181   - <GIF/>
182   - <JPG/>
183   - </Format>
184   - <DCPType>
185   - <HTTP>
186   - <Get onlineResource="{url}"/>
187   - </HTTP>
188   - </DCPType>
189   - </Map>
190   - <Capabilities>
191   - <Format>
192   - <WMS_XML/>
193   - </Format>
194   - <DCPType>
195   - <HTTP>
196   - <Get onlineResource="{url}"/>
197   - </HTTP>
198   - </DCPType>
199   - </Capabilities>
200   - <FeatureInfo>
201   - <Format>
202   - <XML/>
203   - <MIME/>
204   - </Format>
205   - <DCPType>
206   - <HTTP>
207   - <Get onlineResource="{url}"/>
208   - </HTTP>
209   - </DCPType>
210   - </FeatureInfo>
211   - </Request>
212   - <Exception>
213   - <Format>
214   - <WMS_XML/>
215   - <INIMAGE/>
216   - <BLANK/>
217   - </Format>
218   - </Exception>
219   - <Layer>
220   - <Name>{service_name}</Name>
221   - <Title>{service_title}</Title>
222   - <CRS>{crs}</CRS>
223   - <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/>
224   -
225   - <Layer queryable="1">
226   - <CRS>{crs}</CRS>
227   - <Name>{layer_name}</Name>
228   - <Title>{layer_title}</Title>
229   - <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/>
230   - </Layer>
231   - </Layer>
232   - </Capability>
233   - </WMS_Capabilities>'''
234   -
235   - extent = json.loads(image_service.get("extent"))
236   - xml = xml.format(service_title=image_service.get("name"),
237   - service_name=image_service.get("name"),
238   - abstract="None",
239   - crs="ESPG:4326",
240   - layer_name=image_service.get("name"),
241   - layer_title=image_service.get("name"),
242   - maxx=extent[2],
243   - maxy=extent[3],
244   - minx=extent[0],
245   - miny=extent[1],
246   - url="http://{}/API/Service/Image/WMS?guid={}".format(configure.deploy_ip_host,
247   - image_service.get("guid")))
248   -
249   - r = Response(response=xml, status=200, mimetype="application/xml")
250   - r.headers["Content-Type"] = "text/xml; charset=utf-8"
251   - return r
252   -
253   - def determin_intersect(self, extent1, extent2):
254   - if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[
255   - 3] or extent2[3] < extent1[1]:
256   - return False
257   - else:
258   - return True
\ No newline at end of file
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/10/26
4   -#email: nheweijun@sina.com
5   -
6   -
7   -import numpy
8   -from app.util.component.ParameterUtil import ParameterUtil
9   -from .Cache import Cache
10   -from app.modules.service.models import ImageService
11   -from flask import Response
12   -from .ImageData import ImageData
13   -from .MyThread import MyThread
14   -from .Opencv import Opencv
15   -from app.modules.service.models import Service,TileScheme
16   -import json
17   -import random
18   -import copy
19   -import configure
20   -from app.util.component.SliceScheme import SliceScheme
21   -from app.util.component.ModelVisitor import ModelVisitor
22   -import threading
23   -from .ImageServer import ImageServer
24   -
25   -class ImageWMTSServer(ImageServer):
26   - _instance_lock = threading.Lock()
27   - singleton = None
28   -
29   - def __init__(self):
30   - pass
31   -
32   - def __new__(cls, *args, **kwargs):
33   - if not cls.singleton:
34   - with ImageWMTSServer._instance_lock:
35   - cls.singleton = super().__new__(cls)
36   - return cls.singleton
37   -
38   -
39   - def wmts(self,service_name,parameter,type="name"):
40   -
41   - image_service_info, zoo, servers = Cache.cache_data(service_name, type=type)
42   -
43   - # 转换参数
44   - parameter = ParameterUtil.to_lower(parameter)
45   -
46   - re = parameter.get("request")
47   - if re and re.__eq__("GetCapabilities"):
48   - service = Service.query.filter_by(guid=image_service_info["service"].get("service_guid")).one_or_none()
49   - return self.get_wmts_capabilities(image_service_info["service"], service)
50   -
51   - if parameter.get("tilematrix"):
52   - if parameter.get("tilematrix").__contains__(":"):
53   - self.level = int(parameter.get("tilematrix").split(":")[-1])
54   - else:
55   - self.level = int(parameter.get("tilematrix"))
56   - if parameter.get("tilerow"):
57   - self.row = int(parameter.get("tilerow"))
58   - if parameter.get("tilecol"):
59   - self.col = int(parameter.get("tilecol"))
60   -
61   - image_type = parameter.get("format") if parameter.get("format") else "image/png"
62   - quality = int(parameter.get("quality")) if parameter.get("quality") else 30
63   - slice_para = image_service_info["scheme"]
64   - extent = SliceScheme.get_polygon(slice_para, self.level, self.row, self.col)
65   -
66   - height, width = 256, 256
67   -
68   - # 多线程获取分布式数据
69   -
70   - intersect_image = [im for im in image_service_info["images"] if
71   - self.determin_intersect(json.loads(im.get("extent")), extent)]
72   -
73   - if len(intersect_image) > 1:
74   -
75   - # 结果矩阵
76   - pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536
77   -
78   - thread_list = []
79   -
80   - for image in intersect_image:
81   -
82   - # 该影像的服务器,随机选取一个
83   - image_servers = image.get("server").split(",")
84   - image_servers = [ser for ser in image_servers if ser in servers]
85   - if len(image_servers) > 0:
86   - indx = int(random.random() * len(image_servers))
87   - image_server = image_servers[indx]
88   - else:
89   - image_server = "None"
90   -
91   - bands = json.loads(image.get("band_view"))
92   -
93   - image_data = ImageData(image_server, image)
94   -
95   - thread: MyThread = MyThread(image_data.get_data, args=(extent, bands, height, width))
96   -
97   - thread.start()
98   - thread_list.append(thread)
99   -
100   - for thread in thread_list:
101   - thread.join()
102   - data = thread.get_result()
103   -
104   - # 掩膜在中央接口生成,合图
105   - mask = numpy.zeros((height, width, 3), dtype=int)
106   - mask_data = numpy.zeros((height, width, 3), dtype=int)
107   -
108   - mask[data == 65536] = 1
109   - mask[data != 65536] = 0
110   - mask_data[data == 65536] = 0
111   - mask_data[data != 65536] = 1
112   -
113   - # # 掩膜计算
114   - pixel_array = pixel_array * mask + data * mask_data
115   -
116   - # opencv 颜色排序为GBR
117   - d1 = copy.copy(pixel_array[:, :, 0])
118   - pixel_array[:, :, 0] = pixel_array[:, :, 2]
119   - pixel_array[:, :, 2] = d1
120   -
121   -
122   - elif len(intersect_image) == 1:
123   - # 该影像的服务器,随机选取一个
124   - image = intersect_image[0]
125   - image_servers = image.get("server").split(",")
126   - # 判断可用服务器
127   - image_servers = [ser for ser in image_servers if ser in servers]
128   - if len(image_servers) > 0:
129   - indx = int(random.random() * len(image_servers))
130   - image_server = image_servers[indx]
131   - else:
132   - image_server = "None"
133   - # image_server = image_servers[0]
134   - bands = json.loads(image.get("band_view"))
135   -
136   - image_data = ImageData(image_server, image)
137   - pixel_array_t: numpy.ndarray = image_data.get_data(extent, bands, height, width)
138   - pixel_array = numpy.zeros((height, width, 3), dtype=int)
139   -
140   - for ii in [0, 1, 2]:
141   - # opencv 颜色排序为GBR
142   - pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii]
143   -
144   - else:
145   - # 结果矩阵
146   - pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536
147   -
148   - # 将图片生成在内存中,然后直接返回response
149   - im_data = Opencv.create_image(image_type, pixel_array, quality)
150   - return Response(im_data, mimetype=image_type.lower())
151   -
152   -
153   - def get_wmts_capabilities(self, image_service, service: Service):
154   - tile_scheme: TileScheme = TileScheme.query.filter_by(guid=image_service.get("scheme_guid")).one_or_none()
155   - if not tile_scheme:
156   - raise Exception("切片方案不存在!")
157   - tile_scheme = ModelVisitor.object_to_json(tile_scheme)
158   -
159   - 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">
160   - <!-- Service Identification -->
161   - <ows:ServiceIdentification>
162   - <ows:Title>{title}</ows:Title>
163   - <ows:ServiceType>OGC WMTS</ows:ServiceType>
164   - <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>
165   - </ows:ServiceIdentification>
166   -
167   - <!-- Operations Metadata -->
168   - <ows:OperationsMetadata>
169   - <ows:Operation name="GetCapabilities">
170   - <ows:DCP>
171   - <ows:HTTP>
172   - <ows:Get xlink:href="{capabilities_url}">
173   - <ows:Constraint name="GetEncoding">
174   - <ows:AllowedValues>
175   - <ows:Value>RESTful</ows:Value>
176   - </ows:AllowedValues>
177   - </ows:Constraint>
178   - </ows:Get>
179   -
180   - <!-- add KVP binding in 10.1 -->
181   - <ows:Get xlink:href="{tile_url}?">
182   - <ows:Constraint name="GetEncoding">
183   - <ows:AllowedValues>
184   - <ows:Value>KVP</ows:Value>
185   - </ows:AllowedValues>
186   - </ows:Constraint>
187   - </ows:Get>
188   - </ows:HTTP>
189   - </ows:DCP>
190   - </ows:Operation>
191   - <ows:Operation name="GetTile">
192   - <ows:DCP>
193   - <ows:HTTP>
194   - <ows:Get xlink:href="{tile_url}">
195   - <ows:Constraint name="GetEncoding">
196   - <ows:AllowedValues>
197   - <ows:Value>RESTful</ows:Value>
198   - </ows:AllowedValues>
199   - </ows:Constraint>
200   - </ows:Get>
201   - <ows:Get xlink:href="{tile_url}?">
202   - <ows:Constraint name="GetEncoding">
203   - <ows:AllowedValues>
204   - <ows:Value>KVP</ows:Value>
205   - </ows:AllowedValues>
206   - </ows:Constraint>
207   - </ows:Get>
208   - </ows:HTTP>
209   - </ows:DCP>
210   - </ows:Operation>
211   - </ows:OperationsMetadata>
212   -
213   - <Contents>
214   -
215   - <!-- Layer -->
216   -
217   -
218   - <Layer>
219   - <ows:Title>{title}</ows:Title>
220   - <ows:Identifier>{title}</ows:Identifier>
221   - <ows:BoundingBox crs="{crs}">
222   - <ows:LowerCorner>{xmin} {ymin}</ows:LowerCorner>
223   - <ows:UpperCorner>{xmax} {ymax}</ows:UpperCorner>
224   - </ows:BoundingBox>
225   -
226   - <Style isDefault="true">
227   - <ows:Title>Default Style</ows:Title>
228   - <ows:Identifier>default</ows:Identifier>
229   - </Style>
230   - <Format>image/png</Format>
231   - <TileMatrixSetLink>
232   - <TileMatrixSet>{tile_name}</TileMatrixSet>
233   - </TileMatrixSetLink>
234   -
235   - <ResourceURL format="image/png" resourceType="tile" template="{tile_url}"/>
236   -
237   - </Layer>
238   -
239   - <!-- TileMatrixSet -->
240   -
241   -
242   - <TileMatrixSet>
243   -
244   - <TileMatrix>
245   - <ows:Title>{tile_title}</ows:Title>
246   - <ows:Abstract>{tile_description}</ows:Abstract>
247   - <ows:Identifier>{tile_name}</ows:Identifier>
248   - <ows:SupportedCRS>{crs}</ows:SupportedCRS>
249   -
250   - {tile_matrix}
251   -
252   - </TileMatrix>
253   -
254   - </TileMatrixSet>
255   -
256   -
257   - </Contents>
258   - <ServiceMetadataURL xlink:href="{capabilities_url}"/>
259   - </Capabilities>'''
260   -
261   - tile_matrix_each = '''
262   - <TileMatrix>
263   - <ows:Identifier>{lev}</ows:Identifier>
264   - <ScaleDenominator>{scale}</ScaleDenominator>
265   - <TopLeftCorner>{top_left}</TopLeftCorner>
266   - <TileWidth>{cols}</TileWidth>
267   - <TileHeight>{rows}</TileHeight>
268   - </TileMatrix>
269   - '''
270   -
271   - tile_matrix = ""
272   - top_left = tile_scheme.get("top_left")
273   - for level in json.loads(tile_scheme.get("levels")):
274   - tile_matrix = "{}{}".format(tile_matrix, tile_matrix_each.format(lev=level["level"],
275   - scale=level["scale"],
276   - top_left=top_left,
277   - cols=tile_scheme.get("cols"),
278   - rows=tile_scheme.get("rows")))
279   -
280   - extent = json.loads(image_service.get("extent"))
281   -
282   - xml = xml.format(
283   - capabilities_url="http://{}/API/Service/Image/Capabilities?guid={}".format(configure.deploy_ip_host,
284   - image_service.get("guid")),
285   - tile_url="http://{}/API/Service/Image/Tile?guid={}".format(configure.deploy_ip_host, image_service.get("guid")),
286   - crs=tile_scheme.get("crs"),
287   - xmin=extent[0],
288   - ymin=extent[1],
289   - xmax=extent[2],
290   - ymax=extent[3],
291   - # TileMatrix = "{TileMatrix}",
292   - # TileRow = "{TileRow}",
293   - # TileCol = "{TileCol}",
294   - guid=image_service.get("guid"),
295   - title=service.title,
296   - tile_title=tile_scheme.get("name"),
297   - tile_name=tile_scheme.get("name"),
298   - tile_description=tile_scheme.get("description"),
299   - tile_matrix=tile_matrix
300   - )
301   -
302   - r = Response(response=xml, status=200, mimetype="application/xml")
303   - r.headers["Content-Type"] = "text/xml; charset=utf-8"
304   -
305   - return r
306   -
307   -
308   -
309   - def determin_intersect(self, extent1, extent2):
310   - if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[
311   - 3] or extent2[3] < extent1[1]:
312   - return False
313   - else:
314   - return True
\ No newline at end of file
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/10/18
4   -#email: nheweijun@sina.com
5   -
6   -from threading import Thread
7   -class MyThread(Thread):
8   - def __init__(self,func,args=()):
9   - super(MyThread,self).__init__()
10   - self.func = func
11   - self.args = args
12   - def run(self):
13   - self.result = self.func(*self.args)
14   - def get_result(self):
15   - try:
16   - return self.result
17   - except Exception:
18   - return None
\ No newline at end of file
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/10/18
4   -#email: nheweijun@sina.com
5   -import cv2
6   -import numpy
7   -
8   -class Opencv:
9   -
10   - @classmethod
11   - def create_image(cls,image_type, pixel_array, quality):
12   -
13   - if image_type.__eq__("image/jpeg") or image_type.__eq__("image/jpg"):
14   - r, buf = cv2.imencode(".jpg", pixel_array, [cv2.IMWRITE_JPEG_QUALITY, quality])
15   - image_out = buf.tobytes()
16   - else:
17   - height, width = pixel_array[:, :, 0].shape
18   - four = numpy.zeros((height,width), dtype=int) + 255
19   - four[pixel_array[:, :, 0] == 65536] = 0
20   - r, buf = cv2.imencode(".png", numpy.dstack((pixel_array, four)))
21   - image_out = buf.tobytes()
22   - return image_out
\ No newline at end of file
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/9/8
4   -#email: nheweijun@sina.com
5   -
6   -from thrift.transport import TSocket
7   -from thrift.transport import TTransport
8   -from thrift.protocol import TBinaryProtocol
9   -from app.modules.service.image.ImageDataService import ImageDataService
10   -
11   -class ThriftConnect:
12   - '''
13   - thrift连接类
14   - '''
15   -
16   - client = None
17   - transport = None
18   -
19   - def __init__(self,data_server):
20   - host = data_server.split(":")[0]
21   - port = int(data_server.split(":")[1])
22   - socket: TSocket = TSocket.TSocket(host, port)
23   - self.transport = TTransport.TBufferedTransport(socket)
24   - protocol = TBinaryProtocol.TBinaryProtocol(self.transport)
25   - self.client = ImageDataService.Client(protocol)
26   - self.transport.open()
27   -
28   - def close(self):
29   - self.transport.close()
30   -
31   -class ThriftConnectCpp:
32   - '''
33   - thrift连接类
34   - '''
35   -
36   - client = None
37   - transport = None
38   -
39   - def __init__(self,data_server):
40   - host = data_server.split(":")[0]
41   - port = int(data_server.split(":")[1])
42   - self.transport: TSocket = TSocket.TSocket(host, port)
43   - self.transport = TTransport.TBufferedTransport(self.transport)
44   - protocol = TBinaryProtocol.TBinaryProtocol(self.transport)
45   - # self.client = ImageDataService.Client(protocol)
46   - self.transport.open()
47   -
48   - def close(self):
49   - self.transport.close()
50   -
51   -class ThriftPool:
52   - '''
53   - thrift线程池
54   - '''
55   - clients = []
56   - transports = []
57   - host = None
58   - port = None
59   - index = -1
60   -
61   - def __init__(self,data_server):
62   - self.host = data_server.split(":")[0]
63   - self.port = int(data_server.split(":")[1])
64   -
65   - def get_client(self):
66   - if len(self.clients) < 20:
67   - socket: TSocket = TSocket.TSocket(self.host, self.port)
68   - transport = TTransport.TBufferedTransport(socket)
69   - protocol = TBinaryProtocol.TBinaryProtocol(transport)
70   - client = ImageDataService.Client(protocol)
71   - self.clients.append(client)
72   - self.transports.append(transport)
73   - return client,transport
74   - else:
75   - self.index += 1
76   - if self.index == 20:
77   - self.index = 0
78   - return self.clients[self.index],self.transports[self.index]
79   -
80   -
81   - def close(self):
82   - pass
\ No newline at end of file
1   -# coding=utf-8
2   -#author: 4N
3   -#createtime: 2021/9/14
4   -#email: nheweijun@sina.com
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/12/15
  4 +#email: nheweijun@sina.com
  5 +
  6 +from flasgger import swag_from
  7 +from flask import Blueprint
  8 +from app.util import BlueprintApi
  9 +from . import image_service_delete,image_service_register,image_service_edit,image_build_pyramid
  10 +
  11 +class DataManager(BlueprintApi):
  12 +
  13 + bp = Blueprint("ImageService", __name__, url_prefix="/API/Service/ImageService")
  14 + service_type = []
  15 +
  16 +
  17 + @staticmethod
  18 + @bp.route('/BuildPyramid', methods=['POST'])
  19 + @swag_from(image_build_pyramid.Api.api_doc)
  20 + def api_image_build_pyramid():
  21 + """
  22 + 创建影像金字塔
  23 + """
  24 + return image_build_pyramid.Api().result
  25 +
  26 + @staticmethod
  27 + @bp.route('/Register', methods=['POST'])
  28 + @swag_from(image_service_register.Api.api_doc)
  29 + def api_image_service_register():
  30 + """
  31 + 注册ImageService
  32 + """
  33 + return image_service_register.Api().result
  34 +
  35 + @staticmethod
  36 + @bp.route('/Edit', methods=['POST'])
  37 + @swag_from(image_service_edit.Api.api_doc)
  38 + def api_image_service_edit():
  39 + """
  40 + 修改ImageService
  41 + """
  42 + return image_service_edit.Api().result
  43 +
  44 + @staticmethod
  45 + @bp.route('/Delete', methods=['POST'])
  46 + @swag_from(image_service_delete.Api.api_doc)
  47 + def api_image_service_delete():
  48 + """
  49 + ImageService Delete
  50 + """
  51 + return image_service_delete.Api().result
... ...
  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 +from app.models import db
  10 +from app.modules.data.models import Task
  11 +import multiprocessing
  12 +import uuid
  13 +import datetime
  14 +import requests
  15 +from app.util.component.TaskController import TaskController
  16 +from app.util.component.TaskWriter import TaskWriter
  17 +class Api(ApiTemplate):
  18 +
  19 + api_name = "创建影像金字塔"
  20 +
  21 + def process(self):
  22 +
  23 + # 返回结果
  24 + res = {}
  25 + try:
  26 + task_guid = uuid.uuid1().__str__()
  27 +
  28 +
  29 + pyramid_process = multiprocessing.Process(target=self.task, args=(task_guid,self.para))
  30 + pyramid_process.start()
  31 +
  32 + task = Task(guid=task_guid,
  33 + name="{}构建影像金字塔".format(self.para.get("alias")),
  34 + create_time=datetime.datetime.now(),
  35 + state=0,
  36 + task_type=5,
  37 + creator=self.para.get("creator"),
  38 + process="影像创建金字塔中",
  39 + task_pid=pyramid_process.pid)
  40 +
  41 + db.session.add(task)
  42 + db.session.commit()
  43 +
  44 + res["data"] = "创建影像金字塔任务已提交!"
  45 + res["result"] = True
  46 +
  47 + except Exception as e:
  48 + raise Exception("数据库错误!")
  49 +
  50 + return res
  51 +
  52 +
  53 + def task(self,task_guid,para):
  54 + task_writer = None
  55 + try:
  56 +
  57 + #任务控制,等待执行
  58 + TaskController.wait(task_guid)
  59 + task_writer = TaskWriter(task_guid)
  60 +
  61 + task_writer.update_task({"state":2,"update_time":datetime.datetime.now(),"process" : "创建中"})
  62 + task_writer.update_process("开始创建...")
  63 +
  64 + url = "{}/API/Service/Image/BuildPyramid".format(para.get("url"))
  65 + response:requests.Response = requests.post(url,data=self.para)
  66 + if not response.json().get("result"):
  67 + raise Exception("由于{},影像服务修改失败!".format(response.json().get("msg")))
  68 +
  69 + task_writer.update_task({"state":1,"update_time":datetime.datetime.now(),"process" : "创建完成"})
  70 + task_writer.update_process("创建完成!")
  71 +
  72 + except Exception as e:
  73 + try:
  74 + task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "下载失败"})
  75 + task_writer.update_process( e.__str__())
  76 + task_writer.update_process("任务中止!")
  77 + except Exception as ee:
  78 + StructurePrint().print(ee.__str__())
  79 + raise e
  80 + finally:
  81 + try:
  82 + task_writer.close()
  83 + except Exception as e:
  84 + StructurePrint().print(e.__str__())
  85 +
  86 +
  87 + api_doc = {
  88 + "tags": ["影像服务接口"],
  89 + "parameters": [
  90 + {"name": "guid",
  91 + "in": "formData",
  92 + "type": "string",
  93 + "description": "guid"},
  94 + {"name": "url",
  95 + "in": "formData",
  96 + "type": "string",
  97 + "description": "url"},
  98 + {"name": "alias",
  99 + "in": "formData",
  100 + "type": "string",
  101 + "description": "影像alias"},
  102 + ],
  103 + "responses": {
  104 + 200: {
  105 + "schema": {
  106 + "properties": {
  107 + }
  108 + }
  109 + }
  110 + }
  111 + }
  112 +
... ...
1 1 # coding=utf-8
2 2 #author: 4N
3   -#createtime: 2021/9/8
  3 +#createtime: 2021/9/17
4 4 #email: nheweijun@sina.com
5 5
6 6
7 7 from app.util.component.ApiTemplate import ApiTemplate
8   -from app.util.component.ModelVisitor import ModelVisitor
9   -from ..models import ImageTag
  8 +import requests
  9 +
10 10 class Api(ApiTemplate):
11 11
12   - api_name = "获取tag列表"
  12 + api_name = "删除ImageService服务"
13 13
14 14 def process(self):
15   -
16 15 # 返回结果
17 16 res = {}
18 17 try:
19   - image_tags = ImageTag.query.all()
20   -
21   - res["data"] = {}
22   - res["data"]["count"] = ImageTag.query.count()
23   - res["data"]["list"] = ModelVisitor.objects_to_jsonarray(image_tags)
  18 + url = "{}/API/Service/Delete".format(self.para.get("url"))
  19 + response:requests.Response = requests.post(url,data=self.para)
  20 + if not response.json().get("result"):
  21 + raise Exception("由于{},影像服务删除失败!".format(response.json().get("msg")))
24 22 res["result"] = True
25   -
26 23 except Exception as e:
27 24 raise e
28 25 return res
29 26
30 27 api_doc = {
31   - "tags": ["影像接口"],
  28 + "tags": ["影像服务接口"],
32 29 "parameters": [
  30 + {"name": "guid",
  31 + "in": "formData",
  32 + "type": "string",
  33 + "description": "guid"},
  34 + {"name": "url",
  35 + "in": "formData",
  36 + "type": "string",
  37 + "description": "url"},
33 38 ],
34 39 "responses": {
35 40 200: {
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/9/17
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from app.util.component.ApiTemplate import ApiTemplate
  8 +import requests
  9 +
  10 +class Api(ApiTemplate):
  11 +
  12 + api_name = "修改ImageService服务"
  13 +
  14 + def process(self):
  15 + # 返回结果
  16 + res = {}
  17 + try:
  18 + url = "{}/API/Service/Edit".format(self.para.get("url"))
  19 + response:requests.Response = requests.post(url,data=self.para)
  20 + if not response.json().get("result"):
  21 + raise Exception("由于{},影像服务修改失败!".format(response.json().get("msg")))
  22 + res["result"] = True
  23 + except Exception as e:
  24 + raise e
  25 + return res
  26 +
  27 + api_doc = {
  28 + "tags": ["影像服务接口"],
  29 + "parameters": [
  30 +
  31 + {"name": "guid",
  32 + "in": "formData",
  33 + "type": "string",
  34 + "description": "服务guid"},
  35 +
  36 + {"name": "type",
  37 + "in": "formData",
  38 + "type": "string",
  39 + "enum": ["地图服务","切片服务","影像服务"],
  40 + "description": "[地图服务,切片服务,影像服务]"},
  41 +
  42 + {"name": "url",
  43 + "in": "formData",
  44 + "type": "string",
  45 + "description": "服务地址"},
  46 +
  47 + {"name": "name",
  48 + "in": "formData",
  49 + "type": "string",
  50 + "description": "[地图服务,切片服务,影像服务]"},
  51 + {"name": "title",
  52 + "in": "formData",
  53 + "type": "string",
  54 + "description": "[地图服务,切片服务,影像服务]"},
  55 + {"name": "description",
  56 + "in": "formData",
  57 + "type": "string",
  58 + "description": "[地图服务,切片服务,影像服务]"},
  59 +
  60 + {"name": "catalog_guid",
  61 + "in": "formData",
  62 + "type": "string",
  63 + "description": "[地图服务,切片服务,影像服务]"},
  64 +
  65 + {"name": "functions",
  66 + "in": "formData",
  67 + "type": "string",
  68 + "description": "[地图服务,影像服务]以逗号相隔,可选WMTS,WMS"},
  69 +
  70 + # 影像参数
  71 + {"name": "image_guids",
  72 + "in": "formData",
  73 + "type": "string",
  74 + "description": "[影像服务]影像guids,以英文逗号相隔"},
  75 + {"name": "scheme",
  76 + "in": "formData",
  77 + "type": "string",
  78 + "description": "切片方案"},
  79 +
  80 +
  81 + ],
  82 + "responses": {
  83 + 200: {
  84 + "schema": {
  85 + "properties": {
  86 + }
  87 + }
  88 + }
  89 + }
  90 + }
\ No newline at end of file
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/9/17
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from app.util.component.ApiTemplate import ApiTemplate
  8 +import requests
  9 +
  10 +class Api(ApiTemplate):
  11 +
  12 + api_name = "注册ImageService服务"
  13 +
  14 + def process(self):
  15 + # 返回结果
  16 + res = {}
  17 + try:
  18 + url = "{}/API/Service/Register".format(self.para.get("url"))
  19 + response:requests.Response = requests.post(url,data=self.para)
  20 + if not response.json().get("result"):
  21 + raise Exception("由于{},影像服务注册失败!".format(response.json().get("msg")))
  22 + res["result"] = True
  23 + except Exception as e:
  24 + raise e
  25 + return res
  26 +
  27 +
  28 + api_doc = {
  29 + "tags": ["影像服务接口"],
  30 + "parameters": [
  31 +
  32 + #通用参数
  33 + {"name": "name",
  34 + "in": "formData",
  35 + "type": "string",
  36 + "required": "true",
  37 + "description": "[地图服务,切片服务,影像服务]"},
  38 +
  39 + {"name": "title",
  40 + "in": "formData",
  41 + "type": "string",
  42 + "description": "[地图服务,切片服务,影像服务]"},
  43 +
  44 + {"name": "url",
  45 + "in": "formData",
  46 + "type": "string"},
  47 +
  48 + {"name": "description",
  49 + "in": "formData",
  50 + "type": "string",
  51 + "description": "[地图服务,切片服务,影像服务]"},
  52 + {"name": "type",
  53 + "in": "formData",
  54 + "type": "string",
  55 + "enum":["影像服务"],
  56 + "required": "true",
  57 + "description": "[地图服务,切片服务,影像服务]"},
  58 + {"name": "catalog_guid",
  59 + "in": "formData",
  60 + "type": "string",
  61 + "description": "[地图服务,切片服务,影像服务]"},
  62 +
  63 + #影像参数
  64 + {"name": "image_guids",
  65 + "in": "formData",
  66 + "type": "string",
  67 + "description": "[影像服务]影像guids,以英文逗号相隔"},
  68 +
  69 + {"name": "scheme",
  70 + "in": "formData",
  71 + "type": "string",
  72 + "description": "影像服务切片方案,json形式"},
  73 +
  74 + {"name": "functions",
  75 + "in": "formData",
  76 + "type": "string",
  77 + "description": "[影像服务]functions",
  78 + "enum": ["WMS","WMTS"]},
  79 +
  80 + ],
  81 + "responses": {
  82 + 200: {
  83 + "schema": {
  84 + "properties": {
  85 + }
  86 + }
  87 + }
  88 + }
  89 + }
\ No newline at end of file
... ...
... ... @@ -25,12 +25,8 @@ class Api(ApiTemplate):
25 25 service_function_guid = uuid.uuid1().__str__()
26 26
27 27
28   -
29 28 # 逻辑是,先调用引擎接口,引擎说可以,才做持久化
30   -
31   -
32   -
33   -
  29 + # 并获得服务缩略图
34 30
35 31 service = Service(
36 32 guid = service_guid,
... ...
... ... @@ -30,9 +30,10 @@ class Service(db.Model):
30 30 # 目录外键
31 31 catalog_guid = Column(String(256), ForeignKey('dmap_service_catalog.guid'))
32 32
  33 + url = Column(String(256))
  34 +
33 35 relate_service_functions = relationship('ServiceFunction', backref='relate_service', lazy='dynamic')
34 36 relate_tile_service = relationship('TileService', backref='relate_service', lazy='dynamic')
35   - relate_image_service = relationship('ImageService', backref='relate_service', lazy='dynamic')
36 37 relate_map_service = relationship('MapService', backref='relate_service', lazy='dynamic')
37 38
38 39 class ServiceFunction(db.Model):
... ... @@ -84,101 +85,6 @@ class TileScheme(db.Model):
84 85 parameter = Column(Text)
85 86
86 87
87   -class Image(db.Model):
88   - '''
89   - 影像元数据
90   - '''
91   - __tablename__ = 'dmap_image'
92   - guid = Column(String(256), primary_key=True)
93   - name = Column(String)
94   - alias = Column(String)
95   - raster_y_size = Column(Integer)#图像y 分辨率
96   - raster_x_size = Column(Integer)#图像x 分辨率
97   - overview_count = Column(Integer)#金字塔等级
98   - extent = Column(String)#范围
99   - # geo_origin_extent = Column(String)
100   - null_value = Column(Integer)#空值
101   - available = Column(Integer)#影像是否可用,不可用可能在创建金字塔中
102   - band_count = Column(Integer)#波段数
103   - band_view = Column(String)#波段设置
104   - path = Column(String)
105   - server = Column(String)
106   -
107   - size = Column(Float)
108   - #坐标wkt
109   - crs_wkt = Column(Text) #坐标wkt
110   - crs_proj4 = Column(Text)#坐标proj
111   - crs = Column(String)#坐标
112   - create_time = Column(DateTime)
113   - update_time = Column(DateTime)
114   - cell_x_size = Column(Float)#像元x大小
115   - cell_y_size = Column(Float)#像元y大小
116   - region = Column(Text)
117   -
118   - has_pyramid = Column(Integer,default=0)#是否已经创建金字塔
119   -
120   - collect_time = Column(DateTime) #成像时间年份
121   -
122   - satellite = Column(String)#卫星类型
123   - type = Column(String(128))
124   -
125   -
126   -dmap_image_rel = db.Table('dmap_image_rel',
127   - Column('image_guid',String, ForeignKey('dmap_image.guid')),
128   - Column('service_guid', String, ForeignKey('dmap_image_service.guid'))
129   - )
130   -
131   -
132   -
133   -class ImageService(db.Model):
134   - '''
135   - 影像服务
136   - '''
137   - __tablename__ = 'dmap_image_service'
138   - guid = Column(String(256), primary_key=True)
139   - name = Column(String,unique = True)
140   - #切片方案
141   - scheme = Column(Text)
142   -
143   - scheme_guid = Column(String)
144   -
145   - extent = Column(String(256))
146   - # node = Column(Integer)
147   - #可视范围geojson
148   - visual_region = Column(Text)
149   - crs = Column(String(256))
150   - create_time = Column(DateTime)
151   - service_guid = Column(String, ForeignKey('dmap_service.guid'))
152   -
153   - #分层分级设置
154   - # cql = Column(String(256))
155   - # table_guid = Column(String(256))
156   -
157   - images = db.relationship('Image',
158   - secondary=dmap_image_rel,
159   - backref='image_services',
160   - lazy='dynamic'
161   - )
162   -
163   -
164   -dmap_image_tag_rel = db.Table('dmap_image_tag_rel',
165   - Column('image_guid',String, ForeignKey('dmap_image.guid')),
166   - Column('tag_guid', String, ForeignKey('dmap_image_tag.guid'))
167   - )
168   -
169   -class ImageTag(db.Model):
170   - '''
171   - 影像标签
172   - '''
173   - __tablename__ = 'dmap_image_tag'
174   - guid = Column(String(256), primary_key=True)
175   - name=Column(String(256))
176   - alias = Column(String(256))
177   - images = db.relationship('Image',
178   - secondary=dmap_image_tag_rel,
179   - backref='image_tags',
180   - lazy='dynamic')
181   -
182 88 class TileService(db.Model):
183 89 '''
184 90 切片元数据
... ... @@ -253,3 +159,16 @@ class MapService(db.Model):
253 159 thumbnail = Column(String)
254 160 layer_style = Column(Text)
255 161 service_guid = Column(String,ForeignKey('dmap_service.guid'))
  162 +
  163 +class ServiceEngine(db.Model):
  164 + '''
  165 + 服务引擎
  166 + '''
  167 + __tablename__ = 'dmap_service_engine'
  168 +
  169 + guid = Column(String(256), primary_key=True)
  170 + name = Column(String)
  171 + url = Column(String(256), unique=True)
  172 + out_url = Column(String(256))
  173 + type = Column(String(256))
  174 + create_time = Column(DateTime)
\ No newline at end of file
... ...
... ... @@ -21,7 +21,6 @@ class Api(ApiTemplate):
21 21
22 22 try:
23 23 # 业务逻辑
24   -
25 24 guid = self.para.get("guid")
26 25 scheme = TileScheme.query.filter_by(guid=guid).one_or_none()
27 26 if not scheme:
... ...
... ... @@ -6,9 +6,9 @@ from app.util.component.ApiTemplate import ApiTemplate
6 6
7 7 from app.models import db
8 8 from app.modules.service.models import Service
9   -from app.modules.service.models import ImageService
10 9 from app.modules.service.models import TileService
11 10 from app.modules.service.models import MapService
  11 +import requests
12 12 class Api(ApiTemplate):
13 13
14 14 api_name = "服务删除"
... ... @@ -20,22 +20,36 @@ class Api(ApiTemplate):
20 20
21 21 try:
22 22 guid = self.para.get("guid")
  23 + s_type = self.para.get("type")
  24 +
  25 + #删除本地服务
  26 + if s_type in ["切片服务","地图服务"]:
  27 + service = Service.query.filter_by(guid=guid).one_or_none()
  28 +
  29 + if service:
  30 + if service.type.__eq__("切片服务"):
  31 + #调用接口
  32 + #172.26.99.160:6060/dmap/api/manager/deleteService?servername=tileserver&servicename=GDMap
  33 + tile_service = TileService.query.filter_by(service_guid=guid).one_or_none()
  34 + db.session.delete(tile_service)
  35 +
  36 + if service.type.__eq__("地图服务"):
  37 + map_service = MapService.query.filter_by(service_guid=guid).one_or_none()
  38 + db.session.delete(map_service)
  39 + service_functions = service.relate_service_functions.all()
  40 + for function in service_functions:
  41 + db.session.delete(function)
  42 + db.session.delete(service)
  43 +
  44 + else:
  45 + raise Exception("服务不存在!")
  46 + # 删除影像服务
  47 + else:
  48 + from app.modules.service.image_service.image_service_delete import Api as RealApi
  49 + api = RealApi()
  50 + api.para = self.para
  51 + res = api.process()
23 52
24   - service = Service.query.filter_by(guid=guid).one_or_none()
25   - if service.type.__eq__("影像服务"):
26   - image_service = ImageService.query.filter_by(service_guid=guid).one_or_none()
27   - db.session.delete(image_service)
28   - if service.type.__eq__("切片服务"):
29   - tile_service = TileService.query.filter_by(service_guid=guid).one_or_none()
30   - db.session.delete(tile_service)
31   - if service.type.__eq__("地图服务"):
32   - map_service = MapService.query.filter_by(service_guid=guid).one_or_none()
33   - db.session.delete(map_service)
34   -
35   - service_functions = service.relate_service_functions.all()
36   - for function in service_functions:
37   - db.session.delete(function)
38   - db.session.delete(service)
39 53 db.session.commit()
40 54 res["result"] = True
41 55 except Exception as e:
... ... @@ -50,6 +64,14 @@ class Api(ApiTemplate):
50 64 "in": "formData",
51 65 "type": "string",
52 66 "description": "guid"},
  67 + {"name": "type",
  68 + "in": "formData",
  69 + "type": "string",
  70 + "description": "type"},
  71 + {"name": "url",
  72 + "in": "formData",
  73 + "type": "string",
  74 + "description": "url"},
53 75 ],
54 76 "responses": {
55 77 200: {
... ...
... ... @@ -3,39 +3,42 @@
3 3 #createtime: 2021/9/14
4 4 #email: nheweijun@sina.com
5 5
6   -
7   -
8   -
9 6 from app.util.component.ApiTemplate import ApiTemplate
10   -from app.models import db
11 7 from app.modules.service.models import Service
12   -from app.modules.service.models import ImageService
13   -from app.modules.service.models import TileService
14   -from app.modules.service.models import MapService
  8 +import requests
15 9
16 10 class Api(ApiTemplate):
17 11 api_name = "修改服务"
18 12 def process(self):
19 13 res = {}
20 14 try:
21   - service = Service.query.filter_by(guid=self.para.get("guid")).one_or_none()
22   - if not service:
23   - raise Exception("服务不存在!")
24   -
25   - if service.type.__eq__("影像服务"):
26   - from app.modules.service.image.image_service_edit import Api as RealApi
27   - elif service.type.__eq__("地图服务"):
28   - from app.modules.service.map_service.map_service_edit import Api as RealApi
29   - elif service.type.__eq__("切片服务"):
30   - from app.modules.service.tile_service.tile_service_edit import Api as RealApi
  15 +
  16 +
  17 + guid = self.para.get("guid")
  18 + s_type = self.para.get("type")
  19 +
  20 + # 修改本地服务
  21 + if s_type in ["切片服务", "地图服务"]:
  22 +
  23 + service = Service.query.filter_by(guid=guid).one_or_none()
  24 + if not service:
  25 + raise Exception("服务不存在!")
  26 +
  27 + if service.type.__eq__("地图服务"):
  28 + from app.modules.service.map_service.map_service_edit import Api as RealApi
  29 + elif service.type.__eq__("切片服务"):
  30 + from app.modules.service.tile_service.tile_service_edit import Api as RealApi
  31 + else:
  32 + return res
  33 + elif s_type.__eq__("影像服务"):
  34 + from app.modules.service.image_service.image_service_edit import Api as RealApi
31 35 else:
32 36 return res
33 37 api = RealApi()
34 38 api.para = self.para
35 39 res = api.process()
36   -
37 40 except Exception as e:
38   - raise e
  41 + raise Exception("修改服务失败")
39 42 return res
40 43
41 44
... ... @@ -46,7 +49,7 @@ class Api(ApiTemplate):
46 49 {"name": "guid",
47 50 "in": "formData",
48 51 "type": "string",
49   - "description": "[服务guid]"},
  52 + "description": "服务guid"},
50 53
51 54 {"name": "type",
52 55 "in": "formData",
... ... @@ -54,6 +57,11 @@ class Api(ApiTemplate):
54 57 "enum": ["地图服务","切片服务","影像服务"],
55 58 "description": "[地图服务,切片服务,影像服务]"},
56 59
  60 + {"name": "url",
  61 + "in": "formData",
  62 + "type": "string",
  63 + "description": "服务地址"},
  64 +
57 65 {"name": "name",
58 66 "in": "formData",
59 67 "type": "string",
... ... @@ -82,16 +90,20 @@ class Api(ApiTemplate):
82 90 "in": "formData",
83 91 "type": "string",
84 92 "description": "[影像服务]影像guids,以英文逗号相隔"},
85   - {"name": "scheme_guid",
  93 + {"name": "scheme",
86 94 "in": "formData",
87 95 "type": "string",
88   - "description": "[切片服务,影像服务]切片方案"},
  96 + "description": "切片方案"},
89 97
90 98 # 切片参数
91 99 {"name": "overview",
92 100 "in": "formData",
93 101 "type": "string",
94 102 "description": "[切片服务]缩略图"},
  103 + {"name": "scheme_guid",
  104 + "in": "formData",
  105 + "type": "string",
  106 + "description": "切片服务切片方案"},
95 107 {"name": "tile_type",
96 108 "in": "formData",
97 109 "type": "string",
... ...
... ... @@ -6,7 +6,7 @@
6 6
7 7
8 8 from app.util.component.ApiTemplate import ApiTemplate
9   -import configure
  9 +from .models import ServiceEngine
10 10 from app.util import find_class,BlueprintApi
11 11
12 12
... ... @@ -21,7 +21,10 @@ class Api(ApiTemplate):
21 21 try:
22 22 for scan in ["app.modules.service"]:
23 23 for api in find_class(scan, BlueprintApi):
24   - service_types.extend(api.service_type)
  24 + if hasattr(api,"service_type"):
  25 + service_types.extend(api.service_type)
  26 + if ServiceEngine.query.filter_by(type="ImageServer").first():
  27 + service_types.append("影像服务")
25 28 res["data"] = service_types
26 29 res["result"] = True
27 30
... ...
... ... @@ -7,37 +7,52 @@
7 7 from app.util.component.ApiTemplate import ApiTemplate
8 8 from app.util.component.ModelVisitor import ModelVisitor
9 9 from .models import Service
10   -
  10 +import requests
11 11 class Api(ApiTemplate):
12 12 api_name = "服务Info"
13 13 def process(self):
14 14 res = {}
15 15 try:
  16 +
16 17 guid = self.para.get("guid")
17   - service = Service.query.filter_by(guid=guid).one_or_none()
18   - if not service:
19   - raise Exception("服务不存在!")
20   - res["data"] = {}
21   -
22   - if service.type.__eq__("影像服务"):
23   - speci_service = service.relate_image_service.one_or_none()
24   - relate_images = speci_service.images.all()
25   - res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service)
26   - res["data"]["speci_service"]["images"] = [{"name":im["name"],"guid":im["guid"]} for im in ModelVisitor.objects_to_jsonarray(relate_images)]
27   - res["data"]["speci_service"]["images"] = sorted(res["data"]["speci_service"]["images"], key=lambda x: x["name"])
28   -
29   - elif service.type.__eq__("切片服务"):
30   - speci_service = service.relate_tile_service.one_or_none()
31   - res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service)
32   - elif service.type.__eq__("地图服务"):
33   - speci_service = service.relate_map_service.one_or_none()
34   - res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service)
35   - else:
  18 + s_type = self.para.get("type")
  19 +
  20 + if s_type in ["地图服务","切片服务"]:
  21 +
  22 + service = Service.query.filter_by(guid=guid).one_or_none()
  23 + if not service:
  24 + raise Exception("服务不存在!")
36 25 res["data"] = {}
37 26
38   - functions = ModelVisitor.objects_to_jsonarray(service.relate_service_functions.all())
39   - res["data"]["service"] = ModelVisitor.object_to_json(service)
40   - res["data"]["service"]["functions"] = functions
  27 + if service.type.__eq__("影像服务"):
  28 + speci_service = service.relate_image_service.one_or_none()
  29 + relate_images = speci_service.images.all()
  30 + res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service)
  31 + res["data"]["speci_service"]["images"] = [{"name":im["name"],"guid":im["guid"]} for im in ModelVisitor.objects_to_jsonarray(relate_images)]
  32 + res["data"]["speci_service"]["images"] = sorted(res["data"]["speci_service"]["images"], key=lambda x: x["name"])
  33 +
  34 + elif service.type.__eq__("切片服务"):
  35 + speci_service = service.relate_tile_service.one_or_none()
  36 + res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service)
  37 + elif service.type.__eq__("地图服务"):
  38 + speci_service = service.relate_map_service.one_or_none()
  39 + res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service)
  40 + else:
  41 + res["data"] = {}
  42 +
  43 + functions = ModelVisitor.objects_to_jsonarray(service.relate_service_functions.all())
  44 + res["data"]["service"] = ModelVisitor.object_to_json(service)
  45 + res["data"]["service"]["functions"] = functions
  46 +
  47 + elif s_type in ["影像服务"]:
  48 + edit_url = "{}/API/Service/Info".format(self.para.get("url"))
  49 + response:requests.Response = requests.post(edit_url,self.para)
  50 + if not response.json().get("result"):
  51 + raise Exception("查询影像服务失败!")
  52 + res = response.json()
  53 + else:
  54 + pass
  55 +
41 56 except Exception as e:
42 57 raise e
43 58 return res
... ... @@ -50,6 +65,15 @@ class Api(ApiTemplate):
50 65 "in": "formData",
51 66 "type": "string",
52 67 "description": "guid"},
  68 + {"name": "type",
  69 + "in": "formData",
  70 + "type": "string",
  71 + "description": "type",
  72 + "enum":["地图服务","切片服务","影像服务"]},
  73 + {"name": "url",
  74 + "in": "formData",
  75 + "type": "string",
  76 + "description": "url"},
53 77 ],
54 78 "responses": {
55 79 200: {
... ...
... ... @@ -6,9 +6,11 @@
6 6
7 7 from app.util.component.ApiTemplate import ApiTemplate
8 8 from app.util.component.ModelVisitor import ModelVisitor
9   -from .models import Service,ServiceFunction,ImageService
  9 +from .models import Service,ServiceFunction,ServiceEngine
10 10 from sqlalchemy import or_
11   -
  11 +import requests
  12 +import re
  13 +from datetime import datetime
12 14
13 15 class Api(ApiTemplate):
14 16 api_name = "服务列表"
... ... @@ -50,17 +52,51 @@ class Api(ApiTemplate):
50 52 services = services.filter(Service.name.like("%" + name + "%"))
51 53
52 54
53   - res["data"] = {}
54   - res["data"]["count"] = services.count()
55   - services = services.limit(page_size).offset(page_index * page_size).all()
56   - res["data"]["list"] = ModelVisitor.objects_to_jsonarray(services)
57   -
58   - for service_json in res["data"]["list"]:
  55 + # 本地服务
  56 + services = services.all()
  57 + services_json = ModelVisitor.objects_to_jsonarray(services)
  58 + for service_json in services_json:
59 59 service_json["functions"] = sorted(ModelVisitor.objects_to_jsonarray(ServiceFunction.query.filter_by(service_guid=service_json["guid"]).all()),
60 60 key=lambda x:x["type"])
61 61
62   - res["result"] = True
  62 + # 影像服务
  63 + image_engines = ServiceEngine.query.filter_by(type="ImageServer").all()
  64 +
  65 + for ie in image_engines:
  66 + url = "{}/API/Service/List".format(ie.url)
  67 + response:requests.Response = requests.post(url,self.para)
  68 + if not response.json().get("result"):
  69 + raise Exception("修改影像服务失败!")
  70 + else:
  71 + raw_json = response.json()["data"]["list"]
  72 + if state:
  73 + raw_json = [ service for service in raw_json if service["state"] == state]
  74 + if type:
  75 + raw_json = [service for service in raw_json if service["type"] == type]
  76 + if catalog_guid:
  77 + raw_json = [service for service in raw_json if service["catalog_guid"] == catalog_guid]
  78 + # 并集
  79 + if title and name:
  80 + raw_json = [service for service in raw_json if re.search(name, service["name"]) or re.search(title, service["title"])]
  81 + else:
  82 + if title:
  83 + raw_json = [service for service in raw_json if re.search(title, service["title"])]
  84 + if name:
  85 + raw_json = [service for service in raw_json if re.search(name, service["name"])]
  86 + services_json.extend(raw_json)
  87 +
  88 + # 筛选服务能力
  89 + if function_type:
  90 + services_json = [s for s in services_json if list(f["type"] for f in s["functions"]).__contains__(function_type)]
63 91
  92 + res["data"] = {}
  93 + res["data"]["count"] = len(services_json)
  94 +
  95 + # update时间倒数
  96 + services_json = sorted(services_json,key=lambda x:x["update_time"],reverse=True)
  97 +
  98 + res["data"]["list"] = services_json[page_index:(page_index+1)*page_size]
  99 + res["result"] = True
64 100
65 101 except Exception as e:
66 102 raise e
... ... @@ -89,6 +125,13 @@ class Api(ApiTemplate):
89 125 "in": "formData",
90 126 "type": "string",
91 127 "description": "服务名"},
  128 +
  129 + {"name": "function_type",
  130 + "in": "formData",
  131 + "type": "string",
  132 + "description": "服务类型",
  133 + "enum":["WMS","WMTS","WFS"]},
  134 +
92 135 {"name": "state",
93 136 "in": "formData",
94 137 "type": "string",
... ... @@ -113,3 +156,5 @@ class Api(ApiTemplate):
113 156 }
114 157 }
115 158 }
  159 +
  160 +
... ...
... ... @@ -6,10 +6,9 @@
6 6
7 7 from app.util.component.ApiTemplate import ApiTemplate
8 8 from app.util.component.ModelVisitor import ModelVisitor
9   -from .models import Service,ServiceFunction,ImageService
10   -from sqlalchemy import or_
  9 +from .models import Service,ServiceFunction,ServiceEngine
11 10 from app.util.component.GeometryAdapter import GeometryAdapter
12   -
  11 +import requests
13 12 import json
14 13
15 14 class Api(ApiTemplate):
... ... @@ -34,9 +33,8 @@ class Api(ApiTemplate):
34 33
35 34 services = services.join(ServiceFunction).filter(ServiceFunction.type=="WMTS")
36 35 services = services.all()
37   -
38   -
39 36 fit_services = []
  37 +
40 38 if bbox:
41 39 g1 = GeometryAdapter.bbox_2_polygon([float(x) for x in bbox.split(",")])
42 40 for ser in services:
... ... @@ -46,25 +44,35 @@ class Api(ApiTemplate):
46 44 g2 = GeometryAdapter.envelop_2_polygon([float(x) for x in layer_exetent.split(",")])
47 45 if g1.Intersect(g2):
48 46 fit_services.append(ser)
49   - if ser.type.__eq__("影像服务"):
50   - image_extent = ser.relate_image_service.one_or_none().extent
51   - g2 = GeometryAdapter.bbox_2_polygon(json.loads(image_extent))
52   - if g1.Intersect(g2):
53   - fit_services.append(ser)
54 47 else:
55 48 fit_services = services
56 49
57   - res["data"] = {}
58   - res["data"]["count"] = len(fit_services)
59   -
60   - res["data"]["list"] = ModelVisitor.objects_to_jsonarray(fit_services[page_index * page_size:(page_index+1) * page_size])
61 50
62   - for service_json in res["data"]["list"]:
  51 + # 本地服务
  52 + fit_services_json = ModelVisitor.objects_to_jsonarray(fit_services)
  53 + for service_json in fit_services_json:
63 54 service_json["functions"] = sorted(ModelVisitor.objects_to_jsonarray(ServiceFunction.query.filter_by(service_guid=service_json["guid"]).all()),
64 55 key=lambda x:x["type"])
65 56
66   - res["result"] = True
  57 + # 影像服务
  58 + image_engines = ServiceEngine.query.filter_by(type="ImageServer").all()
67 59
  60 + for ie in image_engines:
  61 + url = "{}/API/Service/BaseMapList".format(ie.url)
  62 + response:requests.Response = requests.post(url,self.para)
  63 + if not response.json().get("result"):
  64 + raise Exception("修改影像服务失败!")
  65 + else:
  66 + raw_json = response.json()["data"]["list"]
  67 + fit_services_json.extend(raw_json)
  68 +
  69 + res["data"] = {}
  70 + res["data"]["count"] = len(fit_services_json)
  71 +
  72 + fit_services_json = sorted(fit_services_json, key=lambda x: x["update_time"], reverse=True)
  73 +
  74 + res["data"]["list"] = fit_services_json[page_index:(page_index + 1) * page_size]
  75 + res["result"] = True
68 76
69 77 except Exception as e:
70 78 raise e
... ...
... ... @@ -5,6 +5,7 @@
5 5
6 6 from app.util.component.ApiTemplate import ApiTemplate
7 7 from .models import Service
  8 +import requests
8 9 class Api(ApiTemplate):
9 10 api_name = "注册服务"
10 11 def process(self):
... ... @@ -14,17 +15,22 @@ class Api(ApiTemplate):
14 15 service = Service.query.filter_by(name=self.para.get("name")).one_or_none()
15 16 if service:
16 17 raise Exception("服务已存在!")
17   - if self.para.get("type").__eq__("影像服务"):
18   - from app.modules.service.image.image_service_register import Api as RealApi
19   - elif self.para.get("type").__eq__("地图服务"):
  18 +
  19 + if self.para.get("type").__eq__("地图服务"):
20 20 from app.modules.service.map_service.map_service_register import Api as RealApi
  21 +
21 22 elif self.para.get("type").__eq__("切片服务"):
22 23 from app.modules.service.tile_service.tile_service_register import Api as RealApi
  24 +
  25 + elif self.para.get("type").__eq__("影像服务"):
  26 + from app.modules.service.image_service.image_service_register import Api as RealApi
  27 +
23 28 else:
24 29 return res
25 30 api = RealApi()
26 31 api.para = self.para
27 32 res = api.process()
  33 +
28 34 except Exception as e:
29 35 raise e
30 36 return res
... ... @@ -40,10 +46,16 @@ class Api(ApiTemplate):
40 46 "type": "string",
41 47 "required": "true",
42 48 "description": "[地图服务,切片服务,影像服务]"},
  49 +
43 50 {"name": "title",
44 51 "in": "formData",
45 52 "type": "string",
46 53 "description": "[地图服务,切片服务,影像服务]"},
  54 +
  55 + {"name": "url",
  56 + "in": "formData",
  57 + "type": "string"},
  58 +
47 59 {"name": "description",
48 60 "in": "formData",
49 61 "type": "string",
... ... @@ -64,15 +76,12 @@ class Api(ApiTemplate):
64 76 "in": "formData",
65 77 "type": "string",
66 78 "description": "[影像服务]影像guids,以英文逗号相隔"},
67   - {"name": "scheme_guid",
68   - "in": "formData",
69   - "type": "string",
70   - "description": "[切片服务,影像服务]切片方案"},
71 79
72   - {"name": "scheme_guid",
  80 + {"name": "scheme",
73 81 "in": "formData",
74 82 "type": "string",
75   - "description": "[切片服务,影像服务]切片方案"},
  83 + "description": "[影像服务,切片服务]切片方案json"},
  84 +
76 85
77 86 {"name": "functions",
78 87 "in": "formData",
... ... @@ -90,6 +99,7 @@ class Api(ApiTemplate):
90 99 "type": "string",
91 100 "description": "[切片服务]tile_type",
92 101 "enum":["WMTS","TMS"]},
  102 +
93 103 {"name": "vendor",
94 104 "in": "formData",
95 105 "type": "string",
... ...
... ... @@ -24,6 +24,8 @@ class Api(ApiTemplate):
24 24 dir_path, store_file = FileProcess.save(parent)
25 25
26 26
  27 +
  28 +
27 29 except Exception as e:
28 30 raise e
29 31 return res
... ...
... ... @@ -15,12 +15,27 @@ class Api(ApiTemplate):
15 15 try:
16 16 guid = self.para.get("guid")
17 17 state = int(self.para.get("state"))
18   - Service.query.filter_by(guid=guid).update({"state":state})
  18 + s_type = self.para.get("type")
  19 +
  20 +
  21 + #删除本地服务
  22 + if s_type in ["切片服务","地图服务"]:
  23 + service = Service.query.filter_by(guid=guid).one_or_none()
  24 +
  25 + if service:
  26 + service.state = state
  27 + db.session.commit()
  28 + res["result"] = True
  29 + else:
  30 + raise Exception("服务不存在!")
  31 + # 删除影像服务
  32 + else:
  33 + from app.modules.service.image_service.image_service_edit import Api as RealApi
  34 + api = RealApi()
  35 + api.para = self.para
  36 + res = api.process()
19 37
20   - # 清理缓存,拒绝服务
21 38
22   - db.session.commit()
23   - res["result"] = True
24 39 except Exception as e:
25 40 raise e
26 41 return res
... ... @@ -33,6 +48,14 @@ class Api(ApiTemplate):
33 48 "in": "formData",
34 49 "type": "string",
35 50 "description": "guid"},
  51 + {"name": "type",
  52 + "in": "formData",
  53 + "type": "string",
  54 + "description": "type"},
  55 + {"name": "url",
  56 + "in": "formData",
  57 + "type": "string",
  58 + "description": "type"},
36 59 {"name": "state",
37 60 "in": "formData",
38 61 "type": "int",
... ...
... ... @@ -6,11 +6,11 @@
6 6 from app.util.component.ApiTemplate import ApiTemplate
7 7 from app.util.component.ModelVisitor import ModelVisitor
8 8 import uuid
9   -from ..models import TileService,Service,db,ServiceFunction
  9 +from ..models import TileService,Service,db,ServiceFunction,TileScheme
10 10 import datetime
11 11 import requests
12 12 from .util.ProjectFile import ProjectFile
13   -
  13 +import json
14 14 from requests import Response
15 15 import configure
16 16 class Api(ApiTemplate):
... ... @@ -33,6 +33,9 @@ class Api(ApiTemplate):
33 33 "layer_name","layer_alias","layer_title","layer_style","layer_format",
34 34 "layer_extent","layer_description","scheme_guid"]:
35 35 tile_update[key] = self.para.get(key)
  36 + if self.para.get("scheme_guid"):
  37 + tilesche = TileScheme.query.filter_by(guid=self.para.get("scheme_guid")).one_or_none()
  38 + tile_update["scheme"] = json.dumps(ModelVisitor.object_to_json(tilesche))
36 39
37 40 #通知tileserver,更新缓存
38 41 ts = TileService.query.filter_by(service_guid=guid).one_or_none()
... ... @@ -48,8 +51,10 @@ class Api(ApiTemplate):
48 51
49 52 tile_service_edit_url = "{}/dmap/api/manager/RegService".format(configure.wmts_url)
50 53
51   - resp: Response = requests.post(tile_service_edit_url,para).json()
52   - if not resp.json()["status"].__eq__("true"):
  54 + resp: Response = requests.post(tile_service_edit_url,data=json.dumps(para),headers={'Content-Type':'application/json'})
  55 + resp.encoding="utf-8"
  56 + resp_json = resp.json()
  57 + if not resp_json["status"].__eq__("true"):
53 58 raise Exception("调用切片服务的注册服务接口失败!")
54 59
55 60 #修改数据库
... ... @@ -75,8 +80,7 @@ class Api(ApiTemplate):
75 80 res["result"] = True
76 81
77 82 except Exception as e:
78   - raise e
79   -
  83 + raise Exception("数据库错误!")
80 84 return res
81 85
82 86 api_doc = {
... ...
... ... @@ -13,7 +13,7 @@ import datetime
13 13 import configure
14 14 import requests
15 15 from requests import Response
16   -
  16 +import json
17 17 from .util.ProjectFile import ProjectFile
18 18
19 19 class Api(ApiTemplate):
... ... @@ -29,14 +29,16 @@ class Api(ApiTemplate):
29 29 tile_service_guid = uuid.uuid1().__str__()
30 30 service_function_guid = uuid.uuid1().__str__()
31 31 # 调用切片服务的注册服务接口
  32 +
32 33 project_file = ProjectFile.create(self.para)
33 34 para = {"name":self.para.get("name"),"title":self.para.get("title"),
34 35 "type":"tileserver","capabilities":1,"project":project_file}
35 36
36 37 tile_service_register_url = "{}/dmap/api/manager/RegService".format(configure.wmts_url)
37   -
38   - resp: Response = requests.post(tile_service_register_url,para).json()
39   - if not resp.json()["status"].__eq__("true"):
  38 + resp: Response = requests.post(tile_service_register_url,data=json.dumps(para),headers={'Content-Type':'application/json'})
  39 + resp.encoding="utf-8"
  40 + resp_json = resp.json()
  41 + if not resp_json["status"].__eq__("true"):
40 42 raise Exception("调用切片服务的注册服务接口失败!")
41 43
42 44 service = Service(
... ... @@ -60,7 +62,7 @@ class Api(ApiTemplate):
60 62 if tile_service_isexist:
61 63 db.session.delete(tile_service_isexist)
62 64
63   - tile_scheme: TileScheme = TileScheme.query.filter_by(guid=self.para.get("scheme_guid")).one_or_none()
  65 + # tile_scheme: TileScheme = TileScheme.query.filter_by(guid=self.para.get("scheme_guid")).one_or_none()
64 66
65 67 tile_service = TileService(
66 68 guid = tile_service_guid,
... ... @@ -78,8 +80,10 @@ class Api(ApiTemplate):
78 80 layer_format = self.para.get("layer_format"),
79 81 layer_extent = self.para.get("layer_extent"),
80 82 layer_description = self.para.get("layer_description"),
81   - scheme_guid = self.para.get("scheme_guid"),
82   - scheme = ModelVisitor.object_to_json(tile_scheme),
  83 + # scheme_guid = self.para.get("scheme_guid"),
  84 + # scheme = json.dumps(ModelVisitor.object_to_json(tile_scheme)),
  85 +
  86 + scheme=self.para.get("scheme"),
83 87 service_guid = service_guid,
84 88 metadata_url = "{}/DMap/Services/{}/MapServer/WMTSServer".format(configure.wmts_url,self.para.get("name"))
85 89 )
... ... @@ -97,7 +101,7 @@ class Api(ApiTemplate):
97 101 res["result"] = True
98 102 except Exception as e:
99 103 db.session.rollback()
100   - raise e
  104 + raise Exception("数据库错误!")
101 105 return res
102 106
103 107
... ...
... ... @@ -11,6 +11,7 @@ from app.util.component.ModelVisitor import ModelVisitor
11 11
12 12 from .util.ProjectFile import ProjectFile
13 13
  14 +
14 15 class Api(ApiTemplate):
15 16
16 17 api_name = "切片服务reload"
... ... @@ -30,9 +31,11 @@ class Api(ApiTemplate):
30 31 res["data"]["list"].append(para)
31 32 res["result"] = True
32 33 except Exception as e:
33   - raise e
  34 + raise Exception("数据库错误!")
34 35 return res
35 36
  37 +
  38 +
36 39 api_doc = {
37 40 "tags": ["切片服务接口"],
38 41 "parameters": [
... ...
... ... @@ -24,62 +24,66 @@ class ProjectFile:
24 24 raise Exception("切片方案不存在!")
25 25 tile_scheme = ModelVisitor.object_to_json(tile_scheme)
26 26
27   - project_xml_format = '''<?xml version="1.0"?>
28   - <dmap projectname="wmtstest" version="4.0">
29   - <projectCrs>
30   - <spatialrefsys>
31   - <wkt>{wkt}</wkt>
32   - <proj4>{proj4}</proj4>
33   - <srid>{srid}</srid>
34   - <description/>
35   - <projectionacronym/>
36   - </spatialrefsys>
37   - </projectCrs>
38   - <projectlayers>
39   - <maplayer name="{name}" alias="{alias}" type="0">
40   - <extent>
41   - <xmin>{xmin}</xmin>
42   - <ymin>{xmax}</ymin>
43   - <xmax>{xmax}</xmax>
44   - <ymax>{ymax}</ymax>
45   - </extent>
46   - <style>{layer_style}</style>
47   - <format>{layer_format}</format>
48   - <vendor>{vendor}</vendor>
49   - <datasource>{datasource}</datasource>
50   - <tileMatrixSets>
51   - <tileMatrixSet>
52   - <id>default</id>
53   - <crs>{crs}</crs>
54   - <tileCols>{cols}</tileCols>
55   - <tileRows>{rows}</tileRows>
56   - <dpi>{dpi}</dpi>
57   - <tileOrigin>
58   - <X>{x}</X>
59   - <Y>{y}</Y>
60   - </tileOrigin>
61   - <levels>
62   - {levels}
63   - </levels>
64   - </tileMatrixSet>
65   - </tileMatrixSets>
66   - </maplayer>
67   - </projectlayers>
68   - </dmap>
69   - '''
  27 + project_xml_format = '''
  28 +<?xml version="1.0"?>
  29 +<dmap projectname="wmtstest" version="4.0">
  30 + <projectCrs>
  31 + <spatialrefsys>
  32 + <wkt>{wkt}</wkt>
  33 + <proj4>{proj4}</proj4>
  34 + <srid>{srid}</srid>
  35 + <description/>
  36 + <projectionacronym/>
  37 + </spatialrefsys>
  38 + </projectCrs>
  39 + <projectlayers>
  40 + <maplayer name="{name}" alias="{alias}" type="0">
  41 + <extent>
  42 + <xmin>{xmin}</xmin>
  43 + <ymin>{xmax}</ymin>
  44 + <xmax>{ymin}</xmax>
  45 + <ymax>{ymax}</ymax>
  46 + </extent>
  47 + <style>{layer_style}</style>
  48 + <format>{layer_format}</format>
  49 + <vendor>{vendor}</vendor>
  50 + <datasource>{datasource}</datasource>
  51 + <tileMatrixSets>
  52 + <tileMatrixSet>
  53 + <id>default</id>
  54 + <crs>{crs}</crs>
  55 + <tileCols>{cols}</tileCols>
  56 + <tileRows>{rows}</tileRows>
  57 + <dpi>{dpi}</dpi>
  58 + <tileOrigin>
  59 + <X>{x}</X>
  60 + <Y>{y}</Y>
  61 + </tileOrigin>
  62 + <levels>
  63 + {levels}
  64 + </levels>
  65 + </tileMatrixSet>
  66 + </tileMatrixSets>
  67 + </maplayer>
  68 + </projectlayers>
  69 +</dmap>
  70 +'''
70 71
71 72 level_each = '''<level>
72   - <id>{lev}</id>
73   - <scaleDenominator>{scale}</scaleDenominator>
74   - <resolution>{resolution}</resolution>
75   - </level>'''
  73 + <id>{lev}</id>
  74 + <scaleDenominator>{scale}</scaleDenominator>
  75 + <resolution>{resolution}</resolution>
  76 + </level>
  77 + '''
76 78
77   - levels = ""
  79 + levels = ''
78 80 for level in json.loads(tile_scheme.get("levels")):
79 81 levels = "{}{}".format(levels, level_each.format(lev=level["level"],
80 82 scale=level["scale"],
81 83 resolution=level["resolution"],
82 84 ))
  85 + #删除空格
  86 + levels = levels.strip()
83 87
84 88 layer_extent = para.get("layer_extent").split(",")
85 89
... ... @@ -87,7 +91,7 @@ class ProjectFile:
87 91 proj4="",
88 92 srid=para.get("crs").split("::")[-1],
89 93 name=para.get("layer_name"),
90   - alias=para.get("alias"),
  94 + alias=para.get("alias") if para.get("alias") else "",
91 95 xmin=layer_extent[0],
92 96 xmax=layer_extent[1],
93 97 ymin=layer_extent[2],
... ... @@ -106,40 +110,40 @@ class ProjectFile:
106 110 )
107 111 else:
108 112
109   - project_xml_format = '''<?xml version="1.0"?>
110   - <dmap projectname="tmstest" version="4.0">
111   - <projectCrs>
112   - <spatialrefsys>
113   - <wkt>{wkt}</wkt>
114   - <proj4>{proj4}</proj4>
115   - <srid>{srid}</srid>
116   - <description/>
117   - <projectionacronym/>
118   - </spatialrefsys>
119   - </projectCrs>
120   - <projectlayers>
121   - <maplayer name="{name}" alias="{alias}" type="3">
122   - <extent>
123   - <xmin>{xmin}</xmin>
124   - <ymin>{xmax}</ymin>
125   - <xmax>{xmax}</xmax>
126   - <ymax>{ymax}</ymax>
127   - </extent>
128   - <style>{layer_style}</style>
129   - <format>{layer_format}</format>
130   - <vendor>{vendor}</vendor>
131   - <datasource>{datasource}</datasource>
132   - </maplayer>
133   - </projectlayers>
134   - </dmap>
135   -
136   - '''
  113 + project_xml_format = '''
  114 +<?xml version="1.0"?>
  115 +<dmap projectname="tmstest" version="4.0">
  116 + <projectCrs>
  117 + <spatialrefsys>
  118 + <wkt>{wkt}</wkt>
  119 + <proj4>{proj4}</proj4>
  120 + <srid>{srid}</srid>
  121 + <description/>
  122 + <projectionacronym/>
  123 + </spatialrefsys>
  124 + </projectCrs>
  125 + <projectlayers>
  126 + <maplayer name="{name}" alias="{alias}" type="0">
  127 + <extent>
  128 + <xmin>{xmin}</xmin>
  129 + <ymin>{xmax}</ymin>
  130 + <xmax>{xmax}</xmax>
  131 + <ymax>{ymax}</ymax>
  132 + </extent>
  133 + <style>{layer_style}</style>
  134 + <format>{layer_format}</format>
  135 + <vendor>{vendor}</vendor>
  136 + <datasource>{datasource}</datasource>
  137 + </maplayer>
  138 + </projectlayers>
  139 +</dmap>
  140 +'''
137 141 layer_extent = para.get("layer_extent").split(",")
138 142 project_xml = project_xml_format.format(wkt="",
139 143 proj4="",
140 144 srid=para.get("crs").split("::")[-1],
141 145 name=para.get("layer_name"),
142   - alias=para.get("alias"),
  146 + alias=para.get("alias") if para.get("alias") else "",
143 147 xmin=layer_extent[0],
144 148 xmax=layer_extent[1],
145 149 ymin=layer_extent[2],
... ... @@ -149,4 +153,6 @@ class ProjectFile:
149 153 vendor=para.get("vendor"),
150 154 datasource=para.get("datasource"),
151 155 )
  156 +
  157 + project_xml = project_xml.strip()
152 158 return str(base64.b64encode(project_xml.encode('utf-8')), encoding="utf8")
\ No newline at end of file
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/12/15
  4 +#email: nheweijun@sina.com
  5 +
  6 +from app.util.component.ApiTemplate import ApiTemplate
  7 +from app.util.component.ModelVisitor import ModelVisitor
  8 +from ..models import Service,ServiceFunction,ServiceEngine
  9 +from sqlalchemy import or_
  10 +import requests
  11 +
  12 +def get_all_service():
  13 +
  14 + res = []
  15 + services = Service.query.order_by(Service.update_time.desc())
  16 + res.extend(ModelVisitor.objects_to_jsonarray(services))
  17 + engines = ServiceEngine.query.filter_by(type="ImageServer").all()
  18 + for engine in engines:
  19 + service_url = "{}/API/Service/List".format(engine.url)
  20 + response:requests.Response = requests.post(url=service_url,data={"page_index":"0","page_size":"999"})
  21 + res.extend(response.json()["data"]["list"])
  22 + return res
\ No newline at end of file
... ...
... ... @@ -6,7 +6,6 @@
6 6 import datetime
7 7 import uuid
8 8 from app.modules.data.models import Process,Task,Table
9   -from app.modules.service.models import Image
10 9 import configure
11 10 from app.util.component.PGUtil import PGUtil
12 11
... ... @@ -53,11 +52,6 @@ class TaskWriter:
53 52 if commit:
54 53 self.sys_session.commit()
55 54
56   - @check_session
57   - def update_image(self,image_guid,update_info,commit=True):
58   - self.sys_session.query(Image).filter_by(guid=image_guid).update(update_info)
59   - if commit:
60   - self.sys_session.commit()
61 55
62 56 def close(self):
63 57 try:
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/12/20
  4 +#email: nheweijun@sina.com
  5 +
  6 +import math
  7 +import requests
  8 +import numpy
  9 +import cv2
  10 +from osgeo import gdal,osr
  11 +from osgeo.gdal import *
  12 +
  13 +
  14 +# Math functions taken from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames #spellok
  15 +# TMS 经纬度转
  16 +def deg2num( lon_deg,lat_deg, zoom):
  17 + lat_rad = math.radians(lat_deg)
  18 + n = 2.0 ** zoom
  19 + xtile = int((lon_deg + 180.0) / 360.0 * n)
  20 + ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
  21 + return (xtile, ytile)
  22 +
  23 +def num2deg(xtile, ytile, zoom):
  24 + n = 2.0 ** zoom
  25 + lon_deg = xtile / n * 360.0 - 180.0
  26 + lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
  27 + lat_deg = math.degrees(lat_rad)
  28 + return (lat_deg, lon_deg)
  29 +
  30 +def tms_overview(extent,url_format):
  31 +
  32 +
  33 + lev = 0
  34 + r1 = 0
  35 + r2 = 0
  36 + c1 = 0
  37 + c2 = 0
  38 +
  39 + while r1 - r2 < 2:
  40 + lev += 1
  41 + # 左下角所在行列号
  42 + c1, r1 = deg2num( extent[0],extent[2], lev)
  43 + # 右上角所在行列号
  44 + c2, r2 = deg2num( extent[1],extent[3], lev)
  45 + if lev > 20 :
  46 + break
  47 +
  48 + print(lev)
  49 +
  50 + # 左下角瓦片的左上角坐标
  51 + lat1, lon1 = num2deg(c1, r1, lev)
  52 + # 左下角瓦片的右下角坐标
  53 + lat2, lon2 = num2deg(c1 + 1, r1 + 1, lev)
  54 +
  55 + # 右上角瓦片的左上角坐标
  56 + lat3, lon3 = num2deg(c2, r2, lev)
  57 + # 右上角瓦片的右下角坐标
  58 + lat4, lon4 = num2deg(c2 + 1, r2 + 1, lev)
  59 +
  60 + # 瓦片拼接底图
  61 + dat = numpy.zeros(((r1 - r2 + 1) * 256, (c2 - c1 + 1) * 256, 3), dtype=int) + 255
  62 +
  63 + # x偏移量
  64 + offx = (extent[0] - lon1) / ((lon4 - lon1) / ((c2 - c1 + 1) * 256))
  65 + # x方向像素量
  66 + xnum = (extent[1] - extent[0]) / ((lon4 - lon1) / ((c2 - c1 + 1) * 256))
  67 +
  68 + # y偏移量
  69 + offy = (lat3 - extent[3]) / ((lat3 - lat2) / ((r1 - r2 + 1) * 256))
  70 + # y方向像素量
  71 + ynum = (extent[3] - extent[2]) / ((lat3 - lat2) / ((r1 - r2 + 1) * 256))
  72 +
  73 + # 拼接瓦片
  74 + for r in range(r2, r1 + 1):
  75 + for c in range(c1, c2 + 1):
  76 + url = "{}/{}/{}/{}.png".format(url_format,lev, c, r)
  77 + dataset: Dataset = gdal.Open(url, 0)
  78 + for b in range(1, 4):
  79 + band: Band = dataset.GetRasterBand(b)
  80 + dat[(r - r2) * 256:(r - r2 + 1) * 256, (c - c1) * 256: (c - c1 + 1) * 256,
  81 + 2 - (b - 1)] = band.ReadAsArray(0, 0, 256, 256)
  82 +
  83 + #裁剪
  84 + dat2 = dat[int(offy):int(offy + ynum), int(offx):int(offx + xnum), :]
  85 +
  86 + cv2.imwrite("over.jpg", dat2, [cv2.IMWRITE_JPEG_QUALITY, 30])
  87 +
  88 +def get_polygon(parameter,level,row,col):
  89 + level=int(level)
  90 + row = int(row)
  91 + col = int(col)
  92 + detaxy = parameter.get(str(level)).get("resolution")* parameter.get("cols")
  93 +
  94 + lon1 = detaxy * col + int(parameter.get("x"))
  95 + lat2 = -detaxy * row + int(parameter.get("y"))
  96 + lon2 = detaxy + lon1
  97 + lat1 = -detaxy + lat2
  98 +
  99 + return [lon1,lat1,lon2,lat2]
  100 +
  101 +def get_rc(parameter,l,lon,lat):
  102 +
  103 + detaxy = parameter.get(str(l)).get("resolution")* parameter.get("cols")
  104 + c = math.floor((lon - int(parameter.get("x")))/detaxy)
  105 + r = math.floor((int(parameter.get("y"))-lat)/detaxy)
  106 + return int(r),int(c)
  107 +
  108 +def wmts_overview(extent,url_format):
  109 +
  110 + scheme = {"0": {"resolution": 1.4062500000059488, "scale": 590995186.12}, "1": {"resolution": 0.7031250000029744, "scale": 295497593.06}, "2": {"resolution": 0.3515625000014872, "scale": 147748796.53}, "3": {"resolution": 0.1757812500007436, "scale": 73874398.265}, "4": {"resolution": 0.0878906250003718, "scale": 36937199.1325}, "5": {"resolution": 0.0439453125001859, "scale": 18468599.56625}, "6": {"resolution": 0.02197265625009295, "scale": 9234299.783125}, "7": {"resolution": 0.010986328125046475, "scale": 4617149.8915625}, "8": {"resolution": 0.0054931640625232375, "scale": 2308574.94578125}, "9": {"resolution": 0.0027465820312616187, "scale": 1154287.472890625}, "10": {"resolution": 0.0013732910156308094, "scale": 577143.7364453125}, "11": {"resolution": 0.0006866455078154047, "scale": 288571.86822265625}, "12": {"resolution": 0.00034332275390770234, "scale": 144285.93411132813}, "13": {"resolution": 0.00017166137695385117, "scale": 72142.96705566406}, "14": {"resolution": 8.583068847692559e-05, "scale": 36071.48352783203}, "15": {"resolution": 4.291534423846279e-05, "scale": 18035.741763916016}, "16": {"resolution": 2.1457672119231396e-05, "scale": 9017.870881958008}, "17": {"resolution": 1.0728836059615698e-05, "scale": 4508.935440979004}, "18": {"resolution": 5.364418029807849e-06, "scale": 2254.467720489502}, "19": {"resolution": 2.6822090149039246e-06, "scale": 1127.233860244751}, "20": {"resolution": 1.3411045074519623e-06, "scale": 563.6169301223755}, "cols": 256, "rows": 256, "dpi": 96, "wkt": "", "x": -400, "y": 400}
  111 +
  112 + lev = 0
  113 + r1 = 0
  114 + r2 = 0
  115 + c1 = 0
  116 + c2 = 0
  117 + while r1 - r2 <2:
  118 + lev += 1
  119 + # 左下角所在瓦片
  120 + r1,c1 = get_rc(scheme,lev, extent[0],extent[2])
  121 + # 右上角所在瓦片
  122 + r2,c2 = get_rc(scheme,lev, extent[1],extent[3])
  123 + if lev > 20 :
  124 + break
  125 +
  126 + print(lev)
  127 + # 左下角瓦片的范围
  128 + [lon1, lat1, lon2, lat2] = get_polygon(scheme, lev, r1, c1)
  129 + # 右上角角瓦片的范围
  130 + [lon12, lat12, lon22, lat22] = get_polygon(scheme, lev, r2, c2)
  131 +
  132 + # 瓦片拼接底图
  133 + dat = numpy.zeros(((r1 - r2 + 1) * 256, (c2 - c1 + 1) * 256, 3), dtype=int)
  134 +
  135 +
  136 + # x偏移量
  137 + offx = (extent[0] - lon1) / ((lon22 - lon1) / ((c2 - c1 + 1) * 256))
  138 + # x方向像素量
  139 + xnum = (extent[1] - extent[0]) / ((lon22 - lon1) / ((c2 - c1 + 1) * 256))
  140 +
  141 + # y偏移量
  142 + offy = (lat22 - extent[3]) / ((lat22 - lat1) / ((r1 - r2 + 1) * 256))
  143 + # y方向像素量
  144 + ynum = (extent[3] - extent[2]) / ((lat22 - lat1) / ((r1 - r2 + 1) * 256))
  145 + # 拼接瓦片
  146 + for r in range(r2, r1 + 1):
  147 + for c in range(c1, c2 + 1):
  148 +
  149 + url = url_format.format(lev, c, r)
  150 + dataset: Dataset = gdal.Open(url, 0)
  151 +
  152 + if dataset.RasterCount==1:
  153 + continue
  154 +
  155 + for b in range(1, 4):
  156 + band: Band = dataset.GetRasterBand(b)
  157 +
  158 + dat[(r - r2) * 256:(r - r2 + 1) * 256, (c - c1) * 256: (c - c1 + 1) * 256,
  159 + 2 - (b - 1)] = band.ReadAsArray(0, 0, 256, 256)
  160 +
  161 + dat2 = dat[int(offy):int(offy + ynum), int(offx):int(offx + xnum), :]
  162 + #裁剪
  163 + cv2.imwrite("overwmts.jpg", dat2, [cv2.IMWRITE_JPEG_QUALITY, 30])
  164 +
  165 +if __name__ == '__main__':
  166 +
  167 + tms_overview([107.78981494180618, 120.43553603935675, 18.870480519260582, 25.999868757737033],"http://172.26.99.160:6060/DMap/Services/GDMap/TileServer/TMSService"
  168 + )
  169 + wmts_url = "http://172.26.99.160:6060/DMap/Services/tile/TileServer/WMTSService?layer=&style=default&tilematrixset=nativeTileMatrixSet&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix={}&TileCol={}&TileRow={}"
  170 + wmts_overview([107.78981494180618, 120.43553603935675, 18.870480519260582, 25.999868757737033],wmts_url)
\ No newline at end of file
... ...
... ... @@ -4,23 +4,18 @@ import logging
4 4 deploy_ip_host = "172.26.40.105:8840"
5 5 # 系统数据库
6 6
7   -SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.60.100:5432/dmap_manager"
  7 +SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.60.100:5432/dmap_manager_test"
8 8 # SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@localhost:5433/dmap_dms_test"
9 9
10 10 # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中
11 11 #VACUATE_DB_URI = None
12 12 VACUATE_DB_URI = SQLALCHEMY_DATABASE_URI
13 13
14   -# 部署模式cluster,standalone
15   -# deployment_mode = "cluster"
16   -# 部署模式味cluster时有用,master,slave
17   -# application_name = "master"
18   -
19 14 zookeeper = "172.26.99.168:2181"
20 15
21 16 #WMTS服务器
22   -wmts_url = "http://172.26.99.160:6080"
23   -
  17 +wmts_url = "http://172.26.99.160:6060"
  18 +wms_url = ""
24 19
25 20 # 固定配置不需要修改
26 21 swagger_configure = {"title": "DMapManager"}
... ...
... ... @@ -6,5 +6,5 @@ import os
6 6 os.environ['AUTHLIB_INSECURE_TRANSPORT'] = '1'
7 7 app: Flask = create_app()
8 8 if __name__ == '__main__':
9   - app.run(host="0.0.0.0", port="8840", threaded=True, debug=True)
  9 + app.run(host="0.0.0.0", port="8841", threaded=True, debug=True)
10 10 # app.run(host="0.0.0.0", port="8840", threaded=True)
... ...
... ... @@ -20,6 +20,8 @@ import time
20 20 # sql ="SELECT geom FROM {} WHERE geom && 'BOX3D({})'::box3d limit 100000".format(table,bbox)
21 21
22 22 import base64
  23 +
  24 +from kazoo.client import KazooClient
23 25 def query_thread():
24 26 def get_db_session(db_url, autocommit=False) -> Session:
25 27 engine = create_engine(db_url, pool_size=100)
... ... @@ -53,6 +55,27 @@ def query_thread():
53 55 ses.close()
54 56 # query_thread()
55 57 if __name__ == '__main__':
56   - kk="PD94bWwgdmVyc2lvbj0iMS4wIj8+CiAgICAgICAgICAgIDxkbWFwIHByb2plY3RuYW1lPSJ3bXRzdGVzdCIgdmVyc2lvbj0iNC4wIj4KICAgICAgICAgICAgICA8cHJvamVjdENycz4KICAgICAgICAgICAgICAgIDxzcGF0aWFscmVmc3lzPgogICAgICAgICAgICAgICAgICA8d2t0Pjwvd2t0PgogICAgICAgICAgICAgICAgICA8cHJvajQ+PC9wcm9qND4KICAgICAgICAgICAgICAgICAgPHNyaWQ+NDQ5MDwvc3JpZD4KICAgICAgICAgICAgICAgICAgPGRlc2NyaXB0aW9uLz4KICAgICAgICAgICAgICAgICAgPHByb2plY3Rpb25hY3JvbnltLz4KICAgICAgICAgICAgICAgIDwvc3BhdGlhbHJlZnN5cz4KICAgICAgICAgICAgICA8L3Byb2plY3RDcnM+CiAgICAgICAgICAgICAgPHByb2plY3RsYXllcnM+CiAgICAgICAgICAgICAgICA8bWFwbGF5ZXIgbmFtZT0ibGF5ZXIiIGFsaWFzPSJOb25lIiB0eXBlPSIwIj4KICAgICAgICAgICAgICAgICAgPGV4dGVudD4KICAgICAgICAgICAgICAgICAgICA8eG1pbj4xMDcuNzg5ODE0OTQxODA2MTg8L3htaW4+CiAgICAgICAgICAgICAgICAgICAgPHltaW4+MTIwLjQzNTUzNjAzOTM1Njc1PC95bWluPgogICAgICAgICAgICAgICAgICAgIDx4bWF4PjEyMC40MzU1MzYwMzkzNTY3NTwveG1heD4KICAgICAgICAgICAgICAgICAgICA8eW1heD4yNS45OTk4Njg3NTc3MzcwMzM8L3ltYXg+CiAgICAgICAgICAgICAgICAgIDwvZXh0ZW50PgogICAgICAgICAgICAgICAgICA8c3R5bGU+ZGVmYXVsdDwvc3R5bGU+CiAgICAgICAgICAgICAgICAgIDxmb3JtYXQ+aW1hZ2UvcG5nPC9mb3JtYXQ+CiAgICAgICAgICAgICAgICAgIDx2ZW5kb3I+RVNSSV9WMTwvdmVuZG9yPgogICAgICAgICAgICAgICAgICA8ZGF0YXNvdXJjZT4vdXNyL2xvY2FsL2RtYXA0L2dkbWFwL19hbGxsYXllcnM8L2RhdGFzb3VyY2U+CiAgICAgICAgICAgICAgICAgIDx0aWxlTWF0cml4U2V0cz4KICAgICAgICAgICAgICAgICAgICA8dGlsZU1hdHJpeFNldD4KICAgICAgICAgICAgICAgICAgICAgIDxpZD5kZWZhdWx0PC9pZD4KICAgICAgICAgICAgICAgICAgICAgIDxjcnM+RVBTRzo6NDQ5MDwvY3JzPgogICAgICAgICAgICAgICAgICAgICAgPHRpbGVDb2xzPjI1NjwvdGlsZUNvbHM+CiAgICAgICAgICAgICAgICAgICAgICA8dGlsZVJvd3M+MjU2PC90aWxlUm93cz4KICAgICAgICAgICAgICAgICAgICAgIDxkcGk+OTY8L2RwaT4KICAgICAgICAgICAgICAgICAgICAgIDx0aWxlT3JpZ2luPgogICAgICAgICAgICAgICAgICAgICAgICA8WD40MDA8L1g+CiAgICAgICAgICAgICAgICAgICAgICAgIDxZPi00MDA8L1k+CiAgICAgICAgICAgICAgICAgICAgICA8L3RpbGVPcmlnaW4+CiAgICAgICAgICAgICAgICAgICAgICA8bGV2ZWxzPgogICAgICAgICAgICAgICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD4wPC9pZD4KICAgICAgICAgICAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NTkwOTk1MTg2LjEyPC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4xLjQwNjI1MDAwMDAwNTk0ODg8L3Jlc29sdXRpb24+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGV2ZWw+PGxldmVsPgogICAgICAgICAgICAgICAgICAgICAgICA8aWQ+MTwvaWQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjI5NTQ5NzU5My4wNjwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC43MDMxMjUwMDAwMDI5NzQ0PC9yZXNvbHV0aW9uPgogICAgICAgICAgICAgICAgICAgICAgICA8L2xldmVsPjxsZXZlbD4KICAgICAgICAgICAgICAgICAgICAgICAgPGlkPjI8L2lkPgogICAgICAgICAgICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xNDc3NDg3OTYuNTM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMzUxNTYyNTAwMDAxNDg3MjwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbD48bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD4zPC9pZD4KICAgICAgICAgICAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NzM4NzQzOTguMjY1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjE3NTc4MTI1MDAwMDc0MzY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGV2ZWw+PGxldmVsPgogICAgICAgICAgICAgICAgICAgICAgICA8aWQ+NDwvaWQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjM2OTM3MTk5LjEzMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDg3ODkwNjI1MDAwMzcxODwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbD48bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD41PC9pZD4KICAgICAgICAgICAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MTg0Njg1OTkuNTY2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDQzOTQ1MzEyNTAwMTg1OTwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbD48bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD42PC9pZD4KICAgICAgICAgICAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+OTIzNDI5OS43ODMxMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDIxOTcyNjU2MjUwMDkyOTU8L3Jlc29sdXRpb24+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGV2ZWw+PGxldmVsPgogICAgICAgICAgICAgICAgICAgICAgICA8aWQ+NzwvaWQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjQ2MTcxNDkuODkxNTYyNTwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMTA5ODYzMjgxMjUwNDY0NzU8L3Jlc29sdXRpb24+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGV2ZWw+PGxldmVsPgogICAgICAgICAgICAgICAgICAgICAgICA8aWQ+ODwvaWQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjIzMDg1NzQuOTQ1NzgxMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDA1NDkzMTY0MDYyNTIzMjM3NTwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbD48bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD45PC9pZD4KICAgICAgICAgICAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MTE1NDI4Ny40NzI4OTA2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDAyNzQ2NTgyMDMxMjYxNjE4NzwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbD48bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD4xMDwvaWQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjU3NzE0My43MzY0NDUzMTI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjAwMTM3MzI5MTAxNTYzMDgwOTQ8L3Jlc29sdXRpb24+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGV2ZWw+PGxldmVsPgogICAgICAgICAgICAgICAgICAgICAgICA8aWQ+MTE8L2lkPgogICAgICAgICAgICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4yODg1NzEuODY4MjIyNjU2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDAwNjg2NjQ1NTA3ODE1NDA0NzwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbD48bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD4xMjwvaWQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjE0NDI4NS45MzQxMTEzMjgxMzwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDAzNDMzMjI3NTM5MDc3MDIzNDwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbD48bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD4xMzwvaWQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjcyMTQyLjk2NzA1NTY2NDA2PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjAwMDE3MTY2MTM3Njk1Mzg1MTE3PC9yZXNvbHV0aW9uPgogICAgICAgICAgICAgICAgICAgICAgICA8L2xldmVsPjxsZXZlbD4KICAgICAgICAgICAgICAgICAgICAgICAgPGlkPjE0PC9pZD4KICAgICAgICAgICAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MzYwNzEuNDgzNTI3ODMyMDM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjguNTgzMDY4ODQ3NjkyNTU5ZS0wNTwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbD48bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD4xNTwvaWQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjE4MDM1Ljc0MTc2MzkxNjAxNjwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICAgICAgICAgICAgPHJlc29sdXRpb24+NC4yOTE1MzQ0MjM4NDYyNzllLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICAgICAgICAgICAgICA8L2xldmVsPjxsZXZlbD4KICAgICAgICAgICAgICAgICAgICAgICAgPGlkPjE2PC9pZD4KICAgICAgICAgICAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+OTAxNy44NzA4ODE5NTgwMDg8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjIuMTQ1NzY3MjExOTIzMTM5NmUtMDU8L3Jlc29sdXRpb24+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGV2ZWw+PGxldmVsPgogICAgICAgICAgICAgICAgICAgICAgICA8aWQ+MTc8L2lkPgogICAgICAgICAgICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj40NTA4LjkzNTQ0MDk3OTAwNDwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICAgICAgICAgICAgPHJlc29sdXRpb24+MS4wNzI4ODM2MDU5NjE1Njk4ZS0wNTwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbD48bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD4xODwvaWQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjIyNTQuNDY3NzIwNDg5NTAyPC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgICAgICAgICAgICA8cmVzb2x1dGlvbj41LjM2NDQxODAyOTgwNzg0OWUtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvbGV2ZWw+PGxldmVsPgogICAgICAgICAgICAgICAgICAgICAgICA8aWQ+MTk8L2lkPgogICAgICAgICAgICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xMTI3LjIzMzg2MDI0NDc1MTwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICAgICAgICAgICAgPHJlc29sdXRpb24+Mi42ODIyMDkwMTQ5MDM5MjQ2ZS0wNjwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbD48bGV2ZWw+CiAgICAgICAgICAgICAgICAgICAgICAgIDxpZD4yMDwvaWQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjU2My42MTY5MzAxMjIzNzU1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4xLjM0MTEwNDUwNzQ1MTk2MjNlLTA2PC9yZXNvbHV0aW9uPgogICAgICAgICAgICAgICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICAgICAgICAgICAgPC9sZXZlbHM+CiAgICAgICAgICAgICAgICAgICAgPC90aWxlTWF0cml4U2V0PgogICAgICAgICAgICAgICAgICA8L3RpbGVNYXRyaXhTZXRzPgogICAgICAgICAgICAgICAgPC9tYXBsYXllcj4KICAgICAgICAgICAgICA8L3Byb2plY3RsYXllcnM+CiAgICAgICAgICAgIDwvZG1hcD4KICAgICAgICAgICAg"
57   - print('解码:' + str(base64.b64decode(kk), "utf-8"))
58   - daf=0
  58 + # kk="PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxkbWFwIHByb2plY3RuYW1lPSJ3bXRzdGVzdCIgdmVyc2lvbj0iNC4wIj4KICA8cHJvamVjdENycz4KICAgIDxzcGF0aWFscmVmc3lzPgogICAgICA8d2t0Pjwvd2t0PgogICAgICA8cHJvajQ+PC9wcm9qND4KICAgICAgPHNyaWQ+NDQ5MDwvc3JpZD4KICAgICAgPGRlc2NyaXB0aW9uLz4KICAgICAgPHByb2plY3Rpb25hY3JvbnltLz4KICAgIDwvc3BhdGlhbHJlZnN5cz4KICA8L3Byb2plY3RDcnM+CiAgPHByb2plY3RsYXllcnM+CiAgICA8bWFwbGF5ZXIgbmFtZT0ibGF5ZXIiIGFsaWFzPSJOb25lIiB0eXBlPSIwIj4KICAgICAgPGV4dGVudD4KICAgICAgICA8eG1pbj4xMDcuNzg5ODE0OTQxODA2MTg8L3htaW4+CiAgICAgICAgPHltaW4+MTIwLjQzNTUzNjAzOTM1Njc1PC95bWluPgogICAgICAgIDx4bWF4PjEyMC40MzU1MzYwMzkzNTY3NTwveG1heD4KICAgICAgICA8eW1heD4yNS45OTk4Njg3NTc3MzcwMzM8L3ltYXg+CiAgICAgIDwvZXh0ZW50PgogICAgICA8c3R5bGU+ZGVmYXVsdDwvc3R5bGU+CiAgICAgIDxmb3JtYXQ+aW1hZ2UvcG5nPC9mb3JtYXQ+CiAgICAgIDx2ZW5kb3I+RVNSSV9WMTwvdmVuZG9yPgogICAgICA8ZGF0YXNvdXJjZT4vdXNyL2xvY2FsL2RtYXA0L2dkbWFwL19hbGxsYXllcnM8L2RhdGFzb3VyY2U+CiAgICAgIDx0aWxlTWF0cml4U2V0cz4KICAgICAgICA8dGlsZU1hdHJpeFNldD4KICAgICAgICAgIDxpZD5kZWZhdWx0PC9pZD4KICAgICAgICAgIDxjcnM+RVBTRzo6NDQ5MDwvY3JzPgogICAgICAgICAgPHRpbGVDb2xzPjI1NjwvdGlsZUNvbHM+CiAgICAgICAgICA8dGlsZVJvd3M+MjU2PC90aWxlUm93cz4KICAgICAgICAgIDxkcGk+OTY8L2RwaT4KICAgICAgICAgIDx0aWxlT3JpZ2luPgogICAgICAgICAgICA8WD40MDA8L1g+CiAgICAgICAgICAgIDxZPi00MDA8L1k+CiAgICAgICAgICA8L3RpbGVPcmlnaW4+CiAgICAgICAgICA8bGV2ZWxzPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjA8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjU5MDk5NTE4Ni4xMjwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4xLjQwNjI1MDAwMDAwNTk0ODg8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MTwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+Mjk1NDk3NTkzLjA2PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuNzAzMTI1MDAwMDAyOTc0NDwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4yPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xNDc3NDg3OTYuNTM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4zNTE1NjI1MDAwMDE0ODcyPC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjM8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjczODc0Mzk4LjI2NTwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjE3NTc4MTI1MDAwMDc0MzY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MzY5MzcxOTkuMTMyNTwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjA4Nzg5MDYyNTAwMDM3MTg8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NTwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MTg0Njg1OTkuNTY2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wNDM5NDUzMTI1MDAxODU5PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjY8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjkyMzQyOTkuNzgzMTI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDIxOTcyNjU2MjUwMDkyOTU8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NzwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NDYxNzE0OS44OTE1NjI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDEwOTg2MzI4MTI1MDQ2NDc1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjg8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjIzMDg1NzQuOTQ1NzgxMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDU0OTMxNjQwNjI1MjMyMzc1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjk8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjExNTQyODcuNDcyODkwNjI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDAyNzQ2NTgyMDMxMjYxNjE4NzwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xMDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NTc3MTQzLjczNjQ0NTMxMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDEzNzMyOTEwMTU2MzA4MDk0PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjExPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4yODg1NzEuODY4MjIyNjU2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDA2ODY2NDU1MDc4MTU0MDQ3PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjEyPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xNDQyODUuOTM0MTExMzI4MTM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDAzNDMzMjI3NTM5MDc3MDIzNDwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xMzwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NzIxNDIuOTY3MDU1NjY0MDY8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDAxNzE2NjEzNzY5NTM4NTExNzwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xNDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MzYwNzEuNDgzNTI3ODMyMDM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+OC41ODMwNjg4NDc2OTI1NTllLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE1PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xODAzNS43NDE3NjM5MTYwMTY8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+NC4yOTE1MzQ0MjM4NDYyNzllLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE2PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj45MDE3Ljg3MDg4MTk1ODAwODwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4yLjE0NTc2NzIxMTkyMzEzOTZlLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE3PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj40NTA4LjkzNTQ0MDk3OTAwNDwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4xLjA3Mjg4MzYwNTk2MTU2OThlLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE4PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4yMjU0LjQ2NzcyMDQ4OTUwMjwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj41LjM2NDQxODAyOTgwNzg0OWUtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MTk8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjExMjcuMjMzODYwMjQ0NzUxPC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjIuNjgyMjA5MDE0OTAzOTI0NmUtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MjA8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjU2My42MTY5MzAxMjIzNzU1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjEuMzQxMTA0NTA3NDUxOTYyM2UtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICA8L2xldmVscz4KICAgICAgICA8L3RpbGVNYXRyaXhTZXQ+CiAgICAgIDwvdGlsZU1hdHJpeFNldHM+CiAgICA8L21hcGxheWVyPgogIDwvcHJvamVjdGxheWVycz4KPC9kbWFwPg=="
  59 + # kk="PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxkbWFwIHByb2plY3RuYW1lPSJ3bXRzdGVzdCIgdmVyc2lvbj0iNC4wIj4KICA8cHJvamVjdENycz4KICAgIDxzcGF0aWFscmVmc3lzPgogICAgICA8d2t0Pjwvd2t0PgogICAgICA8cHJvajQ+PC9wcm9qND4KICAgICAgPHNyaWQ+NDQ5MDwvc3JpZD4KICAgICAgPGRlc2NyaXB0aW9uLz4KICAgICAgPHByb2plY3Rpb25hY3JvbnltLz4KICAgIDwvc3BhdGlhbHJlZnN5cz4KICA8L3Byb2plY3RDcnM+CiAgPHByb2plY3RsYXllcnM+CiAgICA8bWFwbGF5ZXIgbmFtZT0ibGF5ZXIiIGFsaWFzPSJOb25lIiB0eXBlPSIwIj4KICAgICAgPGV4dGVudD4KICAgICAgICA8eG1pbj4xMDcuNzg5ODE0OTQxODA2MTg8L3htaW4+CiAgICAgICAgPHltaW4+MTIwLjQzNTUzNjAzOTM1Njc1PC95bWluPgogICAgICAgIDx4bWF4PjEyMC40MzU1MzYwMzkzNTY3NTwveG1heD4KICAgICAgICA8eW1heD4yNS45OTk4Njg3NTc3MzcwMzM8L3ltYXg+CiAgICAgIDwvZXh0ZW50PgogICAgICA8c3R5bGU+ZGVmYXVsdDwvc3R5bGU+CiAgICAgIDxmb3JtYXQ+aW1hZ2UvcG5nPC9mb3JtYXQ+CiAgICAgIDx2ZW5kb3I+RVNSSV9WMTwvdmVuZG9yPgogICAgICA8ZGF0YXNvdXJjZT4vdXNyL2xvY2FsL2RtYXA0L2dkbWFwL19hbGxsYXllcnM8L2RhdGFzb3VyY2U+CiAgICAgIDx0aWxlTWF0cml4U2V0cz4KICAgICAgICA8dGlsZU1hdHJpeFNldD4KICAgICAgICAgIDxpZD5kZWZhdWx0PC9pZD4KICAgICAgICAgIDxjcnM+RVBTRzo6NDQ5MDwvY3JzPgogICAgICAgICAgPHRpbGVDb2xzPjI1NjwvdGlsZUNvbHM+CiAgICAgICAgICA8dGlsZVJvd3M+MjU2PC90aWxlUm93cz4KICAgICAgICAgIDxkcGk+OTY8L2RwaT4KICAgICAgICAgIDx0aWxlT3JpZ2luPgogICAgICAgICAgICA8WD40MDA8L1g+CiAgICAgICAgICAgIDxZPi00MDA8L1k+CiAgICAgICAgICA8L3RpbGVPcmlnaW4+CiAgICAgICAgICA8bGV2ZWxzPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjA8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjU5MDk5NTE4Ni4xMjwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4xLjQwNjI1MDAwMDAwNTk0ODg8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MTwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+Mjk1NDk3NTkzLjA2PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuNzAzMTI1MDAwMDAyOTc0NDwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4yPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xNDc3NDg3OTYuNTM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4zNTE1NjI1MDAwMDE0ODcyPC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjM8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjczODc0Mzk4LjI2NTwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjE3NTc4MTI1MDAwMDc0MzY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MzY5MzcxOTkuMTMyNTwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4wLjA4Nzg5MDYyNTAwMDM3MTg8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NTwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MTg0Njg1OTkuNTY2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wNDM5NDUzMTI1MDAxODU5PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjY8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjkyMzQyOTkuNzgzMTI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDIxOTcyNjU2MjUwMDkyOTU8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+NzwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NDYxNzE0OS44OTE1NjI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDEwOTg2MzI4MTI1MDQ2NDc1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjg8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjIzMDg1NzQuOTQ1NzgxMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDU0OTMxNjQwNjI1MjMyMzc1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjk8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjExNTQyODcuNDcyODkwNjI1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjAuMDAyNzQ2NTgyMDMxMjYxNjE4NzwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xMDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NTc3MTQzLjczNjQ0NTMxMjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDEzNzMyOTEwMTU2MzA4MDk0PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjExPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4yODg1NzEuODY4MjIyNjU2MjU8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDA2ODY2NDU1MDc4MTU0MDQ3PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjEyPC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xNDQyODUuOTM0MTExMzI4MTM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDAzNDMzMjI3NTM5MDc3MDIzNDwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xMzwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+NzIxNDIuOTY3MDU1NjY0MDY8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+MC4wMDAxNzE2NjEzNzY5NTM4NTExNzwvcmVzb2x1dGlvbj4KICAgICAgICAgICAgPC9sZXZlbD4KICAgICAgICAgICAgPGxldmVsPgogICAgICAgICAgICAgIDxpZD4xNDwvaWQ+CiAgICAgICAgICAgICAgPHNjYWxlRGVub21pbmF0b3I+MzYwNzEuNDgzNTI3ODMyMDM8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+OC41ODMwNjg4NDc2OTI1NTllLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE1PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4xODAzNS43NDE3NjM5MTYwMTY8L3NjYWxlRGVub21pbmF0b3I+CiAgICAgICAgICAgICAgPHJlc29sdXRpb24+NC4yOTE1MzQ0MjM4NDYyNzllLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE2PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj45MDE3Ljg3MDg4MTk1ODAwODwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4yLjE0NTc2NzIxMTkyMzEzOTZlLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE3PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj40NTA4LjkzNTQ0MDk3OTAwNDwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj4xLjA3Mjg4MzYwNTk2MTU2OThlLTA1PC9yZXNvbHV0aW9uPgogICAgICAgICAgICA8L2xldmVsPgogICAgICAgICAgICA8bGV2ZWw+CiAgICAgICAgICAgICAgPGlkPjE4PC9pZD4KICAgICAgICAgICAgICA8c2NhbGVEZW5vbWluYXRvcj4yMjU0LjQ2NzcyMDQ4OTUwMjwvc2NhbGVEZW5vbWluYXRvcj4KICAgICAgICAgICAgICA8cmVzb2x1dGlvbj41LjM2NDQxODAyOTgwNzg0OWUtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MTk8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjExMjcuMjMzODYwMjQ0NzUxPC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjIuNjgyMjA5MDE0OTAzOTI0NmUtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICAgIDxsZXZlbD4KICAgICAgICAgICAgICA8aWQ+MjA8L2lkPgogICAgICAgICAgICAgIDxzY2FsZURlbm9taW5hdG9yPjU2My42MTY5MzAxMjIzNzU1PC9zY2FsZURlbm9taW5hdG9yPgogICAgICAgICAgICAgIDxyZXNvbHV0aW9uPjEuMzQxMTA0NTA3NDUxOTYyM2UtMDY8L3Jlc29sdXRpb24+CiAgICAgICAgICAgIDwvbGV2ZWw+CiAgICAgICAgICA8L2xldmVscz4KICAgICAgICA8L3RpbGVNYXRyaXhTZXQ+CiAgICAgIDwvdGlsZU1hdHJpeFNldHM+CiAgICA8L21hcGxheWVyPgogIDwvcHJvamVjdGxheWVycz4KPC9kbWFwPg=="
  60 + # kk="PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxkbWFwIHByb2plY3RuYW1lPSJ0bXN0ZXN0IiB2ZXJzaW9uPSI0LjAiPgogIDxwcm9qZWN0Q3JzPgogICAgPHNwYXRpYWxyZWZzeXM+CiAgICAgIDx3a3Q+PC93a3Q+CiAgICAgIDxwcm9qND48L3Byb2o0PgogICAgICA8c3JpZD40NDkwPC9zcmlkPgogICAgICA8ZGVzY3JpcHRpb24vPgogICAgICA8cHJvamVjdGlvbmFjcm9ueW0vPgogICAgPC9zcGF0aWFscmVmc3lzPgogIDwvcHJvamVjdENycz4KICA8cHJvamVjdGxheWVycz4KICAgIDxtYXBsYXllciBuYW1lPSJsYXllciIgYWxpYXM9Ik5vbmUiIHR5cGU9IjMiPgogICAgICA8ZXh0ZW50PgogICAgICAgIDx4bWluPjEwNy43ODk4MTQ5NDE4MDYxODwveG1pbj4KICAgICAgICA8eW1pbj4xMjAuNDM1NTM2MDM5MzU2NzU8L3ltaW4+CiAgICAgICAgPHhtYXg+MTIwLjQzNTUzNjAzOTM1Njc1PC94bWF4PgogICAgICAgIDx5bWF4PjI1Ljk5OTg2ODc1NzczNzAzMzwveW1heD4KICAgICAgPC9leHRlbnQ+CiAgICAgIDxzdHlsZT5kZWZhdWx0PC9zdHlsZT4KICAgICAgPGZvcm1hdD5pbWFnZS9wbmc8L2Zvcm1hdD4KICAgICAgPHZlbmRvcj5RR0lTPC92ZW5kb3I+CiAgICAgIDxkYXRhc291cmNlPi91c3IvbG9jYWwvZG1hcDQvcWdpczwvZGF0YXNvdXJjZT4KICAgIDwvbWFwbGF5ZXI+CiAgPC9wcm9qZWN0bGF5ZXJzPgo8L2RtYXA+"
  61 + # kk="PD94bWwgdmVyc2lvbj0iMS4wIj8+CjxkbWFwIHByb2plY3RuYW1lPSJ0bXN0ZXN0IiB2ZXJzaW9uPSI0LjAiPgogIDxwcm9qZWN0Q3JzPgogICAgPHNwYXRpYWxyZWZzeXM+CiAgICAgIDx3a3Q+PC93a3Q+CiAgICAgIDxwcm9qND48L3Byb2o0PgogICAgICA8c3JpZD40NDkwPC9zcmlkPgogICAgICA8ZGVzY3JpcHRpb24vPgogICAgICA8cHJvamVjdGlvbmFjcm9ueW0vPgogICAgPC9zcGF0aWFscmVmc3lzPgogIDwvcHJvamVjdENycz4KICA8cHJvamVjdGxheWVycz4KICAgIDxtYXBsYXllciBuYW1lPSJsYXllciIgYWxpYXM9IiIgdHlwZT0iMyI+CiAgICAgIDxleHRlbnQ+CiAgICAgICAgPHhtaW4+MTA3Ljc4OTgxNDk0MTgwNjE4PC94bWluPgogICAgICAgIDx5bWluPjEyMC40MzU1MzYwMzkzNTY3NTwveW1pbj4KICAgICAgICA8eG1heD4xMjAuNDM1NTM2MDM5MzU2NzU8L3htYXg+CiAgICAgICAgPHltYXg+MjUuOTk5ODY4NzU3NzM3MDMzPC95bWF4PgogICAgICA8L2V4dGVudD4KICAgICAgPHN0eWxlPmRlZmF1bHQ8L3N0eWxlPgogICAgICA8Zm9ybWF0PmltYWdlL3BuZzwvZm9ybWF0PgogICAgICA8dmVuZG9yPlFHSVM8L3ZlbmRvcj4KICAgICAgPGRhdGFzb3VyY2U+L3Vzci9sb2NhbC9kbWFwNC9xZ2lzPC9kYXRhc291cmNlPgogICAgPC9tYXBsYXllcj4KICA8L3Byb2plY3RsYXllcnM+CjwvZG1hcD4="
  62 + # print(str(base64.b64decode(kk), "utf-8"))
  63 + # daf=0
  64 +
  65 + # zoo: KazooClient = KazooClient(hosts="172.26.99.168:2181", timeout=1)
  66 + # zoo.start()
  67 + # while 1:
  68 + # time.sleep(1)
  69 + # print(zoo.connected)
  70 + # print(zoo.get_children("/rpc"))
  71 +
  72 + if __name__ == '__main__':
  73 + import re
  74 +
  75 + line = "广州市区"
  76 + pattern = r"的区"
  77 + matchObj = re.search(pattern, line)
  78 + if matchObj:
  79 + print("y")
  80 + else:
  81 + print("n")
\ No newline at end of file
... ...
不能预览此文件类型
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/12/20
  4 +#email: nheweijun@sina.com
  5 +
  6 +import math
  7 +import requests
  8 +import numpy
  9 +import cv2
  10 +from osgeo import gdal,osr
  11 +from osgeo.gdal import *
  12 +
  13 +
  14 +# Math functions taken from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames #spellok
  15 +# TMS 经纬度转
  16 +def deg2num( lon_deg,lat_deg, zoom):
  17 + lat_rad = math.radians(lat_deg)
  18 + n = 2.0 ** zoom
  19 + xtile = int((lon_deg + 180.0) / 360.0 * n)
  20 + ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
  21 + return (xtile, ytile)
  22 +
  23 +def num2deg(xtile, ytile, zoom):
  24 + n = 2.0 ** zoom
  25 + lon_deg = xtile / n * 360.0 - 180.0
  26 + lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
  27 + lat_deg = math.degrees(lat_rad)
  28 + return (lat_deg, lon_deg)
  29 +
  30 +def tms_overview(extent,url_format):
  31 +
  32 +
  33 + lev = 0
  34 + r1 = 0
  35 + r2 = 0
  36 + c1 = 0
  37 + c2 = 0
  38 +
  39 + while r1 - r2 < 2:
  40 + lev += 1
  41 + # 左下角所在行列号
  42 + c1, r1 = deg2num( extent[0],extent[2], lev)
  43 + # 右上角所在行列号
  44 + c2, r2 = deg2num( extent[1],extent[3], lev)
  45 + if lev > 20 :
  46 + break
  47 +
  48 + print(lev)
  49 +
  50 + # 左下角瓦片的左上角坐标
  51 + lat1, lon1 = num2deg(c1, r1, lev)
  52 + # 左下角瓦片的右下角坐标
  53 + lat2, lon2 = num2deg(c1 + 1, r1 + 1, lev)
  54 +
  55 + # 右上角瓦片的左上角坐标
  56 + lat3, lon3 = num2deg(c2, r2, lev)
  57 + # 右上角瓦片的右下角坐标
  58 + lat4, lon4 = num2deg(c2 + 1, r2 + 1, lev)
  59 +
  60 + # 瓦片拼接底图
  61 + dat = numpy.zeros(((r1 - r2 + 1) * 256, (c2 - c1 + 1) * 256, 3), dtype=int) + 255
  62 +
  63 + # x偏移量
  64 + offx = (extent[0] - lon1) / ((lon4 - lon1) / ((c2 - c1 + 1) * 256))
  65 + # x方向像素量
  66 + xnum = (extent[1] - extent[0]) / ((lon4 - lon1) / ((c2 - c1 + 1) * 256))
  67 +
  68 + # y偏移量
  69 + offy = (lat3 - extent[3]) / ((lat3 - lat2) / ((r1 - r2 + 1) * 256))
  70 + # y方向像素量
  71 + ynum = (extent[3] - extent[2]) / ((lat3 - lat2) / ((r1 - r2 + 1) * 256))
  72 +
  73 + # 拼接瓦片
  74 + for r in range(r2, r1 + 1):
  75 + for c in range(c1, c2 + 1):
  76 + url = "{}/{}/{}/{}.png".format(url_format,lev, c, r)
  77 + dataset: Dataset = gdal.Open(url, 0)
  78 + for b in range(1, 4):
  79 + band: Band = dataset.GetRasterBand(b)
  80 + dat[(r - r2) * 256:(r - r2 + 1) * 256, (c - c1) * 256: (c - c1 + 1) * 256,
  81 + 2 - (b - 1)] = band.ReadAsArray(0, 0, 256, 256)
  82 +
  83 + #裁剪
  84 + dat2 = dat[int(offy):int(offy + ynum), int(offx):int(offx + xnum), :]
  85 +
  86 + cv2.imwrite("over.jpg", dat2, [cv2.IMWRITE_JPEG_QUALITY, 30])
  87 +
  88 +def get_polygon(parameter,level,row,col):
  89 + level=int(level)
  90 + row = int(row)
  91 + col = int(col)
  92 + detaxy = parameter.get(str(level)).get("resolution")* parameter.get("cols")
  93 +
  94 + lon1 = detaxy * col + int(parameter.get("x"))
  95 + lat2 = -detaxy * row + int(parameter.get("y"))
  96 + lon2 = detaxy + lon1
  97 + lat1 = -detaxy + lat2
  98 +
  99 + return [lon1,lat1,lon2,lat2]
  100 +
  101 +def get_rc(parameter,l,lon,lat):
  102 +
  103 + detaxy = parameter.get(str(l)).get("resolution")* parameter.get("cols")
  104 + c = math.floor((lon - int(parameter.get("x")))/detaxy)
  105 + r = math.floor((int(parameter.get("y"))-lat)/detaxy)
  106 + return int(r),int(c)
  107 +
  108 +def wmts_overview(extent,url_format):
  109 +
  110 + scheme = {"0": {"resolution": 1.4062500000059488, "scale": 590995186.12}, "1": {"resolution": 0.7031250000029744, "scale": 295497593.06}, "2": {"resolution": 0.3515625000014872, "scale": 147748796.53}, "3": {"resolution": 0.1757812500007436, "scale": 73874398.265}, "4": {"resolution": 0.0878906250003718, "scale": 36937199.1325}, "5": {"resolution": 0.0439453125001859, "scale": 18468599.56625}, "6": {"resolution": 0.02197265625009295, "scale": 9234299.783125}, "7": {"resolution": 0.010986328125046475, "scale": 4617149.8915625}, "8": {"resolution": 0.0054931640625232375, "scale": 2308574.94578125}, "9": {"resolution": 0.0027465820312616187, "scale": 1154287.472890625}, "10": {"resolution": 0.0013732910156308094, "scale": 577143.7364453125}, "11": {"resolution": 0.0006866455078154047, "scale": 288571.86822265625}, "12": {"resolution": 0.00034332275390770234, "scale": 144285.93411132813}, "13": {"resolution": 0.00017166137695385117, "scale": 72142.96705566406}, "14": {"resolution": 8.583068847692559e-05, "scale": 36071.48352783203}, "15": {"resolution": 4.291534423846279e-05, "scale": 18035.741763916016}, "16": {"resolution": 2.1457672119231396e-05, "scale": 9017.870881958008}, "17": {"resolution": 1.0728836059615698e-05, "scale": 4508.935440979004}, "18": {"resolution": 5.364418029807849e-06, "scale": 2254.467720489502}, "19": {"resolution": 2.6822090149039246e-06, "scale": 1127.233860244751}, "20": {"resolution": 1.3411045074519623e-06, "scale": 563.6169301223755}, "cols": 256, "rows": 256, "dpi": 96, "wkt": "", "x": -400, "y": 400}
  111 +
  112 + lev = 0
  113 + r1 = 0
  114 + r2 = 0
  115 + c1 = 0
  116 + c2 = 0
  117 + while r1 - r2 <1:
  118 + lev += 1
  119 + # 左下角所在瓦片
  120 + r1,c1 = get_rc(scheme,lev, extent[0],extent[2])
  121 + # 右上角所在瓦片
  122 + r2,c2 = get_rc(scheme,lev, extent[1],extent[3])
  123 + if lev > 20 :
  124 + break
  125 +
  126 + print(lev)
  127 + # 左下角瓦片的范围
  128 + [lon1, lat1, lon2, lat2] = get_polygon(scheme, lev, r1, c1)
  129 + # 右上角角瓦片的范围
  130 + [lon12, lat12, lon22, lat22] = get_polygon(scheme, lev, r2, c2)
  131 +
  132 + # 瓦片拼接底图
  133 + dat = numpy.zeros(((r1 - r2 + 1) * 256, (c2 - c1 + 1) * 256, 3), dtype=int)
  134 +
  135 +
  136 + # x偏移量
  137 + offx = (extent[0] - lon1) / ((lon22 - lon1) / ((c2 - c1 + 1) * 256))
  138 + # x方向像素量
  139 + xnum = (extent[1] - extent[0]) / ((lon22 - lon1) / ((c2 - c1 + 1) * 256))
  140 +
  141 + # y偏移量
  142 + offy = (lat22 - extent[3]) / ((lat22 - lat1) / ((r1 - r2 + 1) * 256))
  143 + # y方向像素量
  144 + ynum = (extent[3] - extent[2]) / ((lat22 - lat1) / ((r1 - r2 + 1) * 256))
  145 + # 拼接瓦片
  146 + for r in range(r2, r1 + 1):
  147 + for c in range(c1, c2 + 1):
  148 +
  149 + url = url_format.format(lev, c, r)
  150 + dataset: Dataset = gdal.Open(url, 0)
  151 +
  152 + if dataset.RasterCount==1:
  153 + continue
  154 +
  155 + for b in range(1, 4):
  156 + band: Band = dataset.GetRasterBand(b)
  157 +
  158 + dat[(r - r2) * 256:(r - r2 + 1) * 256, (c - c1) * 256: (c - c1 + 1) * 256,
  159 + 2 - (b - 1)] = band.ReadAsArray(0, 0, 256, 256)
  160 +
  161 + dat2 = dat[int(offy):int(offy + ynum), int(offx):int(offx + xnum), :]
  162 + #裁剪
  163 + cv2.imwrite("overwmts.jpg", dat2, [cv2.IMWRITE_JPEG_QUALITY, 30])
  164 +
  165 +if __name__ == '__main__':
  166 +
  167 + tms_overview([107.78981494180618, 120.43553603935675, 18.870480519260582, 25.999868757737033],"http://172.26.99.160:6060/DMap/Services/GDMap/TileServer/TMSService"
  168 + )
  169 + wmts_url = "http://172.26.99.160:6060/DMap/Services/tile/TileServer/WMTSService?layer=&style=default&tilematrixset=nativeTileMatrixSet&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix={}&TileCol={}&TileRow={}"
  170 + wmts_overview([107.78981494180618, 120.43553603935675, 18.870480519260582, 25.999868757737033],wmts_url)
\ No newline at end of file
... ...
... ... @@ -8,36 +8,111 @@ from osgeo import gdal
8 8
9 9 from osgeo import gdal, gdalconst
10 10 from osgeo import ogr
  11 +import math
  12 +import requests
  13 +def tms(ytile, zoom):
  14 + n = 2.0 ** zoom
  15 + ytile = n - ytile - 1
  16 + return int(ytile)
  17 +import numpy
  18 +import cv2
  19 +from osgeo import gdal,osr
  20 +from osgeo.gdal import *
11 21
12   -rasterFile = 'F:/**0416.dat' # 原影像
13   -shpFile = 'F:/**小麦.shp' # 裁剪矩形
  22 +# Math functions taken from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames #spellok
  23 +def deg2num(lat_deg, lon_deg, zoom):
  24 + lat_rad = math.radians(lat_deg)
  25 + n = 2.0 ** zoom
  26 + xtile = int((lon_deg + 180.0) / 360.0 * n)
  27 + ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
  28 + return (xtile, ytile)
14 29
15   -dataset = gdal.Open(rasterFile, gdalconst.GA_ReadOnly)
  30 +def num2deg(xtile, ytile, zoom):
  31 + n = 2.0 ** zoom
  32 + lon_deg = xtile / n * 360.0 - 180.0
  33 + lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
  34 + lat_deg = math.degrees(lat_rad)
  35 + return (lat_deg, lon_deg)
16 36
17   -geo_transform = dataset.GetGeoTransform()
18   -cols = dataset.RasterXSize # 列数
19   -rows = dataset.RasterYSize # 行数
  37 +def create_image(cls,image_type, pixel_array, quality):
20 38
21   -x_min = geo_transform[0]
22   -y_min = geo_transform[3]
23   -pixel_width = geo_transform[1]
  39 + if image_type.__eq__("image/jpeg") or image_type.__eq__("image/jpg"):
  40 + r, buf = cv2.imencode(".jpg", pixel_array, [cv2.IMWRITE_JPEG_QUALITY, quality])
  41 + image_out = buf.tobytes()
  42 + else:
  43 + height, width = pixel_array[:, :, 0].shape
  44 + four = numpy.zeros((height,width), dtype=int) + 255
  45 + four[pixel_array[:, :, 0] == 65536] = 0
  46 + r, buf = cv2.imencode(".png", numpy.dstack((pixel_array, four)))
  47 + image_out = buf.tobytes()
  48 + return image_out
24 49
25   -shp = ogr.Open(shpFile, 0)
26   -m_layer = shp.GetLayerByIndex(0)
  50 +if __name__ == '__main__':
27 51
28   -target_ds = gdal.GetDriverByName('MEM').Create("", xsize=cols, ysize=rows, bands=1,
29   - eType=gdal.GDT_Byte)
30   -target_ds.SetGeoTransform(geo_transform)
31   -target_ds.SetProjection(dataset.GetProjection())
32 52
33   -band = target_ds.GetRasterBand(1)
34   -band.SetNoDataValue(0)
35   -band.FlushCache()
36   -gdal.RasterizeLayer(target_ds, [1], m_layer) # 跟shp字段给栅格像元赋值
  53 +
  54 +
  55 + lev = 8
  56 + extent = [107.78981494180618, 120.43553603935675, 18.870480519260582, 25.999868757737033]
  57 + url = "http://172.26.99.160:6060/DMap/Services/GDMap/TileServer/TMSService"
  58 +
  59 +
  60 +
  61 + if extent[3] - extent[2] > extent[1] - extent[0]:
  62 + offset = ((extent[3] - extent[2]) - (extent[1] - extent[0])) / 2.0
  63 + out_extent = [extent[0]- offset, extent[1]+offset , extent[2], extent[3] ]
  64 + else:
  65 + offset = ((extent[1] - extent[0]) - (extent[3] - extent[2])) / 2.0
  66 + out_extent = [extent[0] , extent[1], extent[2] - offset, extent[3] + offset]
  67 +
  68 + c1,r1 = deg2num(18.870480519260582,107.78981494180618,lev)
  69 + c2,r2 = deg2num(25.999868757737033, 120.43553603935675, lev)
  70 +
  71 + print(r1 - r2)
  72 + print(c2 - c1)
  73 +
  74 + lat1, lon1 = num2deg(c1, r1, lev)
  75 + lat2, lon2 = num2deg(c1+1, r1+1, lev)
  76 + print( [lon1, lat2, lon2, lat1])
  77 +
  78 + lat3, lon3 = num2deg(c2, r2, lev)
  79 + lat4, lon4 = num2deg(c2+1, r2+1, lev)
  80 + print( [lon3, lat4, lon4, lat3])
  81 +
  82 + dat = numpy.zeros(((r1 - r2+1)*256, (c2 - c1+1)*256, 3), dtype=int) + 256
  83 +
  84 +
  85 + offx = (extent[0]-lon1)/((lon4-lon1)/((c2 - c1+1)*256))
  86 +
  87 + xnum = (extent[1]-extent[0])/((lon4-lon1)/((c2 - c1+1)*256))
  88 +
  89 + print(offx)
  90 + print(xnum)
  91 +
  92 + offy = (lat3 - extent[3])/((lat3-lat2)/((r1 - r2+1)*256))
  93 + ynum = (extent[3]-extent[2])/((lat3-lat2)/((r1 - r2+1)*256))
  94 + print(offy)
  95 + print(ynum)
  96 +
  97 +
  98 + for r in range(r2,r1+1):
  99 + for c in range(c1,c2+1):
  100 + url = "http://172.26.99.160:6060/DMap/Services/GDMap/TileServer/TMSService/{}/{}/{}.png".format(lev,c,r)
  101 + dataset:Dataset = gdal.Open(url, 0)
  102 + for b in range(1,4):
  103 + band:Band = dataset.GetRasterBand(b)
  104 + zaa = (r - r2)*256
  105 + zbb = (c - c1)*256
  106 + zcc = (r - r2+1)*256
  107 + zdd = (c - c1+1)*256
  108 +
  109 + dat[(r - r2)*256:(r - r2+1)*256,(c - c1)*256 : (c - c1+1)*256, 2-(b-1)] = band.ReadAsArray(0,0,256,256)
  110 +
  111 +
  112 + dat2 = dat[int(offy):int(offy+ynum),int(offx):int(offx+xnum),:]
  113 +
  114 + cv2.imwrite("t.jpg", dat, [cv2.IMWRITE_JPEG_QUALITY, 30])
  115 + cv2.imwrite("t2.jpg", dat2, [cv2.IMWRITE_JPEG_QUALITY, 30])
37 116
38 117
39 118
40   -# gdal.RasterizeLayer(target_ds, [1], m_layer) # 多边形内像元值的全是255
41   -del dataset
42   -del target_ds
43   -shp.Release()
... ...
注册登录 后发表评论