提交 838afebfcb42828c7b9e3077230c32dca0aeab5e

作者 nheweijun
1 个父辈 c39bdbc1

修改服务整合ER结构前

正在显示 43 个修改的文件 包含 1346 行增加186 行删除
... ... @@ -12,7 +12,7 @@ from . import data_download,data_download_task
12 12 from . import get_meta
13 13 from . import data_entry_by_meta
14 14 from . import get_data_list
15   -
  15 +from . import data_entry_simple
16 16
17 17 class DataManager(BlueprintApi):
18 18
... ... @@ -99,4 +99,13 @@ class DataManager(BlueprintApi):
99 99 """
100 100 数据入库ByMeta
101 101 """
102   - return data_entry_by_meta.Api().result
\ No newline at end of file
  102 + return data_entry_by_meta.Api().result
  103 +
  104 + @staticmethod
  105 + @bp.route('/DataEntrySimple', methods=['POST'])
  106 + @swag_from(data_entry_simple.Api.api_doc)
  107 + def data_entry_simple():
  108 + """
  109 + 数据入库Simple
  110 + """
  111 + return data_entry_simple.Api().result
\ No newline at end of file
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/1/27
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo.ogr import *
  7 +import uuid
  8 +
  9 +import time
  10 +from app.models import *
  11 +import json
  12 +import re
  13 +from app.util.component.ApiTemplate import ApiTemplate
  14 +from app.util.component.PGUtil import PGUtil
  15 +from .get_meta import Api as MetaApi
  16 +from threading import Thread
  17 +from app.util.component.EntryDataVacuate import EntryDataVacuate
  18 +
  19 +class Api(ApiTemplate):
  20 +
  21 + api_name = "Simple入库"
  22 +
  23 + def process(self):
  24 +
  25 +
  26 + data_path = self.para.get("data_path")
  27 + database_guid = self.para.get("database_guid")
  28 + is_task = self.para.get("is_task")
  29 +
  30 + self.para["overwrite"] = "yes"
  31 + self.para["task_guid"] = uuid.uuid1().__str__()
  32 + self.para["task_time"] = time.time()
  33 + self.para["task_name"] = "入库测试接口"
  34 + self.para["creator"] = "4N"
  35 +
  36 +
  37 + #返回结果
  38 + res={}
  39 + try:
  40 + meta_api = MetaApi()
  41 + meta_api.para["data_path"] = data_path
  42 + meta_list = json.loads(meta_api.process())["data"]
  43 +
  44 + if is_task:
  45 + task = Task(guid=self.para.get("task_guid"),
  46 + name=self.para.get("task_name"),
  47 + create_time=datetime.datetime.now(),
  48 + state=0,
  49 + task_type=1,
  50 + creator=self.para.get("creator"),
  51 + file_name=meta_list[0].get("filename"),
  52 + database_guid=self.para.get("database_guid"),
  53 + catalog_guid=self.para.get("catalog_guid"),
  54 + process="等待入库",
  55 + parameter=json.dumps(self.para))
  56 + db.session.add(task)
  57 + db.session.commit()
  58 +
  59 + res["result"] = True
  60 + res["msg"] = "数据录入提交成功!"
  61 + res["data"] = self.para["task_guid"]
  62 + else:
  63 + start = time.time()
  64 +
  65 + self.para["meta"] = meta_list
  66 +
  67 + task = Task(guid=self.para.get("task_guid"),
  68 + name=self.para.get("task_name"),
  69 + create_time=datetime.datetime.now(),
  70 + state=0,
  71 + task_type=-1,
  72 + creator=self.para.get("creator"),
  73 + file_name=meta_list[0].get("filename"),
  74 + database_guid=self.para.get("database_guid"),
  75 + catalog_guid=self.para.get("catalog_guid"),
  76 + process="等待入库",
  77 + parameter=json.dumps(self.para))
  78 + db.session.add(task)
  79 + db.session.commit()
  80 +
  81 + entry_data_thread = Thread(
  82 + target=EntryDataVacuate().entry, args=(self.para,))
  83 + entry_data_thread.start()
  84 + entry_data_thread.join()
  85 + res["result"] = True
  86 + res["msg"] = "数据入库成功!"
  87 + res["data"] = "耗时{}秒".format(time.time()-start)
  88 +
  89 + except Exception as e:
  90 + raise e
  91 + return res
  92 +
  93 +
  94 + api_doc={
  95 + "tags":["IO接口"],
  96 + "parameters":[
  97 + {"name": "data_path",
  98 + "in": "formData",
  99 + "type": "string",
  100 + "description": "服务器数据路径"},
  101 + {"name": "database_guid",
  102 + "in": "formData",
  103 + "type": "string",
  104 + "description": "数据库guid"},
  105 + {"name": "is_task",
  106 + "in": "formData",
  107 + "type": "boolean",
  108 + "description": "是否形成任务"}
  109 + ],
  110 + "responses":{
  111 + 200:{
  112 + "schema":{
  113 + "properties":{
  114 + }
  115 + }
  116 + }
  117 + }
  118 + }
\ No newline at end of file
... ...
... ... @@ -23,7 +23,7 @@ class Api(ApiTemplate):
23 23 res = {}
24 24
25 25 try:
26   - project_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
  26 + project_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))))
27 27 base_path = os.path.join(project_path,"tmp")
28 28 if self.para.get("data_path"):
29 29 base_path = os.path.normpath(self.para.get("data_path"))
... ...
... ... @@ -14,12 +14,14 @@ from . import capabilities
14 14 from . import image_tile,image_wms
15 15 from . import image_service_list
16 16 from . import image_tile_mask
  17 +from . import image_wmts
17 18
18 19 from . import image_delete
19 20 from . import image_cancle
20 21 from . import image_register,image_list,image_info,image_edit,image_overview
21 22 from . import image_tag_create,image_tag_delete,image_tag_list
22   -
  23 +from . import image_wms_temporary
  24 +from . import image_wms_kv
23 25
24 26 class DataManager(BlueprintApi):
25 27
... ... @@ -169,7 +171,7 @@ class DataManager(BlueprintApi):
169 171
170 172 @staticmethod
171 173 @bp.route('/Tile/<guid>/<l>/<y>/<z>', methods=['GET'])
172   - @swag_from(image_tile.Api.api_doc)
  174 + # @swag_from(image_tile.Api.api_doc)
173 175 def api_image_tile(guid,l,y,z):
174 176 """
175 177 切片服务
... ... @@ -178,18 +180,11 @@ class DataManager(BlueprintApi):
178 180
179 181
180 182
181   - # @staticmethod
182   - # @bp.route('/<service_name>/WMTS', methods=['GET'])
183   - # @swag_from(image_tile.Api.api_doc)
184   - # def api_image_tile(service_name):
185   - # """
186   - # 切片服务
187   - # """
188   - # return image_tile.Api(service_name).result
  183 +
189 184
190 185 @staticmethod
191 186 @bp.route('/Tile', methods=['GET','POST'])
192   - @swag_from(image_tile.Api.api_doc)
  187 + # @swag_from(image_tile.Api.api_doc)
193 188 def api_image_tile_kv():
194 189 """
195 190 切片服务
... ... @@ -217,10 +212,40 @@ class DataManager(BlueprintApi):
217 212
218 213
219 214 @staticmethod
220   - @bp.route('/WMS', methods=['GET','POST'])
  215 + @bp.route('/<service_name>/WMS', methods=['GET','POST'])
221 216 @swag_from(image_wms.Api.api_doc)
222   - def image_wms():
  217 + def image_wms(service_name):
  218 + """
  219 + WMS服务
  220 + """
  221 + return image_wms.Api(service_name).result
  222 +
  223 + @staticmethod
  224 + @bp.route('/<service_name>/WMTS', methods=['GET','POST'])
  225 + @swag_from(image_wmts.Api.api_doc)
  226 + def api_image_wmts(service_name):
  227 + """
  228 + 切片服务
  229 + """
  230 + return image_wmts.Api(service_name).result
  231 +
  232 +
  233 +
  234 + @staticmethod
  235 + @bp.route('/WMS', methods=['GET','POST'])
  236 + # @swag_from(image_wms_kv.Api.api_doc)
  237 + def image_wms_kv():
223 238 """
224 239 WMS服务
225 240 """
226   - return image_wms.Api().result
\ No newline at end of file
  241 + return image_wms_kv.Api().result
  242 +
  243 +
  244 + @staticmethod
  245 + @bp.route('/WMSTem', methods=['GET','POST'])
  246 + @swag_from(image_wms_temporary.Api.api_doc)
  247 + def image_wms_temporary():
  248 + """
  249 + WMS服务预览
  250 + """
  251 + return image_wms_temporary.Api().result
\ No newline at end of file
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/10/18
  4 +#email: nheweijun@sina.com
... ...
... ... @@ -48,7 +48,7 @@ class Api(ApiTemplate):
48 48
49 49 file_info = {"name": f, "path": file_path, "size": file_size, "create_time": fctime,"real_size": real_size}
50 50
51   - if file_path.lower().endswith("tiff") or file_path.lower().endswith("tif") or file_path.lower().endswith("img"):
  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 52
53 53 exist_image: Image = Image.query.filter_by(path=os.path.normpath(file_info.get("path")),
54 54 size=file_info.get("real_size")).one_or_none()
... ... @@ -57,19 +57,33 @@ class Api(ApiTemplate):
57 57 if exist_image.server.__contains__(data_server):
58 58 file_info["exist"] = True
59 59
  60 + file_info["type"] = ImageType.get_type(file_path)
  61 + data_list.append(file_info)
60 62
61   - file_info["type"] = ImageType.get_type(file_path)
62   - data_list.append(file_info)
63 63
  64 + info_dir = []
  65 + info_img = []
  66 + for dat in data_list:
64 67
65   - data_list_sorted = sorted(data_list, key=lambda x: x["name"])
66   - res["data"] = data_list_sorted
  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
67 78
68 79 else:
69 80 thrift_connect = ThriftConnect(data_server)
70 81 info= json.loads(thrift_connect.client.getImageList(path))
71 82 thrift_connect.close()
72 83
  84 +
  85 + info_dir = []
  86 + info_img = []
73 87 for inf in info:
74 88 if inf["path"].lower().endswith("tiff") or inf["path"].lower().endswith("tif") or inf["path"].lower().endswith("img"):
75 89
... ... @@ -80,7 +94,16 @@ class Api(ApiTemplate):
80 94 if exist_image.server.__contains__(data_server):
81 95 inf["exist"] = True
82 96
83   - res["data"] = info
  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
84 107
85 108 res["result"] = True
86 109
... ...
... ... @@ -4,18 +4,12 @@
4 4 #email: nheweijun@sina.com
5 5
6 6
7   -from osgeo import gdal,ogr,osr
8   -from osgeo.gdal import Dataset,Band
9 7 from app.util.component.ApiTemplate import ApiTemplate
10   -from app.modules.service.image.util.ThriftConnect import ThriftConnect
11 8 import json
12 9 from .models import Image
13 10 import datetime
14 11 from app.models import db
15   -import uuid
16   -import os
17   -from .models import ImageTag
18   -import math
  12 +
19 13
20 14 class Api(ApiTemplate):
21 15
... ...
... ... @@ -6,14 +6,12 @@
6 6
7 7
8 8 from app.util.component.ApiTemplate import ApiTemplate
9   -from app.util.component.ModelVisitor import ModelVisitor
10   -
11 9 from app.modules.service.image.models import Image,db,ImageTag
12   -from sqlalchemy import or_,and_
13 10 import datetime
  11 +
14 12 class Api(ApiTemplate):
15 13
16   - api_name = "影像数据List"
  14 + api_name = "修改影像数据"
17 15
18 16 def process(self):
19 17
... ... @@ -28,7 +26,8 @@ class Api(ApiTemplate):
28 26 this_time = datetime.datetime.now()
29 27
30 28 del para["guid"]
31   - del para["tag_guids"]
  29 + if para.get("tag_guids"):
  30 + del para["tag_guids"]
32 31
33 32 if para or tag_guids:
34 33 para["update_time"] = this_time
... ... @@ -58,7 +57,7 @@ class Api(ApiTemplate):
58 57 {"name": "alias",
59 58 "in": "formData",
60 59 "type": "string"},
61   - {"name": "ym",
  60 + {"name": "collect_time",
62 61 "in": "formData",
63 62 "type": "string","description":"成像时间字符串"},
64 63 {"name": "region",
... ... @@ -67,9 +66,12 @@ class Api(ApiTemplate):
67 66 {"name": "satellite",
68 67 "in": "formData",
69 68 "type": "string", "description": "卫星类型"},
70   - {"name": "epsg",
  69 + {"name": "crs",
71 70 "in": "formData",
72 71 "type": "string", "description": "空间参考"},
  72 + {"name": "band_view",
  73 + "in": "formData",
  74 + "type": "string", "description": "波段设计[1,1,1]"},
73 75 {"name": "tag_guids",
74 76 "in": "formData",
75 77 "type": "string", "description": "tags"},
... ...
... ... @@ -8,8 +8,8 @@ from app.util.component.ApiTemplate import ApiTemplate
8 8 from app.util.component.ModelVisitor import ModelVisitor
9 9
10 10 from app.modules.service.image.models import Image,ImageTag
11   -from sqlalchemy import or_,and_
12 11 from app.util.component.FileProcess import FileProcess
  12 +
13 13 class Api(ApiTemplate):
14 14
15 15 api_name = "影像数据Info"
... ...
... ... @@ -8,7 +8,9 @@ from app.util.component.ApiTemplate import ApiTemplate
8 8 from app.util.component.ModelVisitor import ModelVisitor
9 9 from app.util.component.FileProcess import FileProcess
10 10 from app.modules.service.image.models import Image,ImageTag
11   -from sqlalchemy import or_,and_
  11 +from sqlalchemy import or_
  12 +import datetime
  13 +
12 14 class Api(ApiTemplate):
13 15
14 16 api_name = "影像数据List"
... ... @@ -26,6 +28,7 @@ class Api(ApiTemplate):
26 28 band = self.para.get("band")
27 29 region = self.para.get("region")
28 30 tag_guid = self.para.get("tag_guid")
  31 + collect_time = self.para.get("collect_time")
29 32
30 33 type = self.para.get("type")
31 34
... ... @@ -48,12 +51,20 @@ class Api(ApiTemplate):
48 51 if region:
49 52 images = images.filter(Image.region.in_(region.split(",")))
50 53
  54 + if collect_time:
  55 + begin,end = collect_time.split(",")
  56 + begin = datetime.datetime.strptime(begin,"%Y-%m-%d %H:%M:%S")
  57 + end = datetime.datetime.strptime(end, "%Y-%m-%d %H:%M:%S")
  58 + images.filter(Image.collect_time>=begin).filter(Image.collect_time<=end)
  59 +
51 60 if tag_guid:
52 61 tag:ImageTag = ImageTag.query.filter_by(guid=tag_guid).one_or_none()
53 62 images_guid = [img.guid for img in tag.images.all()]
54 63 images = images.filter(Image.guid.in_(images_guid))
55 64
56 65
  66 +
  67 +
57 68 res["data"] = {}
58 69 res["data"]["count"] = images.count()
59 70 imgs = images.limit(page_size).offset(page_index * page_size).all()
... ... @@ -89,7 +100,7 @@ class Api(ApiTemplate):
89 100 {"name": "name",
90 101 "in": "formData",
91 102 "type": "string"},
92   - {"name": "ym",
  103 + {"name": "collect_time",
93 104 "in": "formData",
94 105 "type": "string"},
95 106 {"name": "region",
... ...
... ... @@ -64,7 +64,7 @@ class Api(ApiTemplate):
64 64
65 65 bands = json.loads(image.band_view)
66 66
67   - # bands = [1,2,3] if image.band_count>=3 else [1,1,1]
  67 +
68 68
69 69 #计算查询范围,保持正常比例
70 70 query_extent = json.loads(image.extent)
... ... @@ -83,20 +83,17 @@ class Api(ApiTemplate):
83 83 pixel_array = numpy.zeros((height, width, 3), dtype=int)
84 84
85 85 for ii in [0, 1, 2]:
86   - # opencv 颜色排序为GBR
  86 + # opencv 颜色排序为BGR
87 87 pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii]
88 88
89 89 # 将图片生成在内存中,然后直接返回response
90 90 im_data = Opencv.create_image(format, pixel_array, 30)
91 91
92   - return Response(im_data, mimetype=format)
93   -
94 92 except Exception as e:
95 93 StructurePrint().print(traceback.format_exc())
96   - res["state"] = -1
97   - res["message"] = e.__str__()
98   - return res
  94 + raise e
99 95
  96 + return Response(im_data, mimetype=format)
100 97
101 98 api_doc = {
102 99 "tags": ["影像接口"],
... ...
... ... @@ -4,7 +4,7 @@
4 4 #email: nheweijun@sina.com
5 5
6 6
7   -from osgeo import gdal,ogr,osr
  7 +from osgeo import gdal,osr
8 8 from osgeo.gdal import Dataset,Band
9 9 from app.util.component.ApiTemplate import ApiTemplate
10 10 from app.modules.service.image.util.ThriftConnect import ThriftConnect
... ... @@ -15,7 +15,6 @@ from app.models import db
15 15 import uuid
16 16 import os
17 17 from .models import ImageTag
18   -import math
19 18 from .util.ImageType import ImageType
20 19
21 20 class Api(ApiTemplate):
... ... @@ -60,8 +59,9 @@ class Api(ApiTemplate):
60 59 left_top = (geo[0], geo[3])
61 60
62 61 right_buttom = (geo[0] + geo[1] * image.RasterXSize, geo[3] + geo[5] * image.RasterYSize)
63   - origin_extent = [left_top[0], right_buttom[0], right_buttom[1], left_top[1]]
64 62
  63 +
  64 + origin_extent = [left_top[0], right_buttom[1], right_buttom[0], left_top[1]]
65 65 # target = origin.CloneGeogCS()
66 66 # tran = osr.CoordinateTransformation(origin, target)
67 67 #
... ... @@ -134,9 +134,9 @@ class Api(ApiTemplate):
134 134 server=data_server,
135 135 path = os.path.normpath(info.get("path")),
136 136 size=info.get("size"),
137   - epsg= info.get("epsg"),
138   - sr_wkt = info.get("sr_wkt"),
139   - sr_proj4= info.get("sr_proj4"),
  137 + crs = str(info.get("crs")),
  138 + crs_wkt = info.get("crs_wkt"),
  139 + crs_proj4= info.get("crs_proj4"),
140 140 band_count=info.get("band_count"),
141 141 band_view = "[1,2,3]" if info.get("band_count")>=3 else "[1,1,1]",
142 142 create_time=this_time,
... ...
... ... @@ -32,7 +32,7 @@ class Api(ApiTemplate):
32 32 service_update = {}
33 33 image_update = {}
34 34 for key in self.para.keys():
35   - if key in ["name","title","state","description","catalog_guid"]:
  35 + if key in ["name","title","state","description","catalog_guid","type"]:
36 36 service_update[key] = self.para.get(key)
37 37 if key in ["name","scheme_guid"]:
38 38 image_update[key] = self.para.get(key)
... ... @@ -98,6 +98,11 @@ class Api(ApiTemplate):
98 98 "type": "string",
99 99 "description": "[WMS,WMTS,影像WMS,影像WMTS]"},
100 100
  101 + {"name": "type",
  102 + "in": "formData",
  103 + "type": "string",
  104 + "description": "修改服务类型"},
  105 +
101 106 {"name": "title",
102 107 "in": "formData",
103 108 "type": "string",
... ...
... ... @@ -3,11 +3,10 @@
3 3 #createtime: 2021/7/19
4 4 #email: nheweijun@sina.com
5 5
6   -from app.modules.service.image.models import ImageService,Image
  6 +from app.modules.service.image.models import ImageService
7 7
8 8 from app.util.component.ApiTemplate import ApiTemplate
9 9 from app.util.component.ModelVisitor import ModelVisitor
10   -from app.models import Service
11 10 from sqlalchemy import or_
12 11 class Api(ApiTemplate):
13 12
... ...
... ... @@ -7,8 +7,7 @@ from .models import ImageService,Image
7 7 from app.models import db,Service
8 8 from app.util.component.ApiTemplate import ApiTemplate
9 9 import uuid
10   -from app.util.component.SliceScheme import SliceScheme
11   -from app.util.component.FileProcess import FileProcess
  10 +
12 11 import os
13 12 import json
14 13 import datetime
... ... @@ -93,7 +92,7 @@ class Api(ApiTemplate):
93 92
94 93 def get_overview(self,service,image_service):
95 94
96   - api = RealApi()
  95 + api = RealApi("")
97 96
98 97
99 98 query_extent = json.loads(image_service.extent)
... ... @@ -106,7 +105,7 @@ class Api(ApiTemplate):
106 105
107 106 bbox = ",".join([str(x) for x in query_extent])
108 107
109   - api.para = {"guid":image_service.guid,"bbox":bbox,"overview":1,"width":512,"height":512}
  108 + api.para = {"service_name":service.name,"bbox":bbox,"overview":1,"width":512,"height":512}
110 109 res = api.process()
111 110 dir_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "overview")
112 111 gid = uuid.uuid1().__str__()
... ...
... ... @@ -5,9 +5,6 @@
5 5
6 6
7 7 from app.util.component.ApiTemplate import ApiTemplate
8   -from app.util.component.ModelVisitor import ModelVisitor
9   -from kazoo.client import KazooClient
10   -import configure
11 8 from .models import ImageTag
12 9 import uuid
13 10 from app.models import db
... ...
... ... @@ -6,8 +6,6 @@
6 6
7 7 from app.util.component.ApiTemplate import ApiTemplate
8 8 from app.util.component.ModelVisitor import ModelVisitor
9   -from kazoo.client import KazooClient
10   -import configure
11 9 from .models import ImageTag
12 10 class Api(ApiTemplate):
13 11
... ...
... ... @@ -3,27 +3,15 @@
3 3 #createtime: 2021/3/24
4 4 #email: nheweijun@sina.com
5 5
6   -from app.util import *
7 6 import traceback
8   -from osgeo import gdal
9   -from osgeo.gdal import *
10   -from numpy import ndarray
11 7 import numpy
12 8 from flask import Response
13 9 from .util.ImageData import ImageData
14 10
15   -import time
16   -import cv2
17   -from app.modules.service.image.models import ImageService,Image
18   -from app.models import db,TileScheme
19 11 from app.util.component.ApiTemplate import ApiTemplate
20 12 from app.util.component.SliceScheme import SliceScheme
21 13 from app.util.component.ParameterUtil import ParameterUtil
22 14 import json
23   -from kazoo.client import KazooClient
24   -from threading import Thread
25   -from app.modules.service.image.util.ThriftConnect import ThriftConnect,ThriftPool
26   -import gzip
27 15 import random
28 16 import copy
29 17 from .util.Opencv import Opencv
... ...
... ... @@ -10,22 +10,19 @@ from osgeo.gdal import *
10 10 from numpy import ndarray
11 11 import numpy
12 12 from flask import Response
13   -import io
14   -import os
15   -from PIL import Image
16 13
17 14 import time
18 15 import cv2
19 16 from app.modules.service.image.models import ImageService,Image
20 17 from app.models import db,TileScheme
21 18 from app.util.component.ApiTemplate import ApiTemplate
22   -import uuid
  19 +
23 20 from app.util.component.SliceScheme import SliceScheme
24   -from app.util.component.FileProcess import FileProcess
  21 +
25 22 from app.util.component.ParameterUtil import ParameterUtil
26 23 from app.util.component.GeometryAdapter import GeometryAdapter
27 24 from app.util.component.Geometry2Raster import Geometry2Raster
28   -import os
  25 +
29 26 import json
30 27 from kazoo.client import KazooClient
31 28
... ... @@ -61,6 +58,7 @@ class Api(ApiTemplate):
61 58
62 59 #缓存服务信息
63 60 image_service_info = GLOBAL_DIC.get(self.guid)
  61 +
64 62 if image_service_info is None:
65 63 image_service:ImageService = ImageService.query.filter_by(guid = self.guid).one_or_none()
66 64 images = image_service.images.all()
... ...
... ... @@ -21,6 +21,11 @@ class Api(ApiTemplate):
21 21
22 22 api_name = "WMS"
23 23
  24 +
  25 + def __init__(self,service_name):
  26 + super().__init__()
  27 + self.service_name = service_name
  28 +
24 29 def process(self):
25 30
26 31
... ... @@ -30,21 +35,21 @@ class Api(ApiTemplate):
30 35 try:
31 36
32 37 parameter = ParameterUtil.to_lower(parameter)
33   - self.guid = parameter.get("guid")
34   - bbox = parameter.get("bbox")
35   - width = int(parameter.get("width")) if parameter.get("width") else 256
36   - height = int(parameter.get("height")) if parameter.get("height") else 256
37   - image_type = parameter.get("format") if parameter.get("format") else "image/png"
38   - quality = int(parameter.get("quality")) if parameter.get("quality") else 30
  38 + if parameter.get("service_name"):
  39 + self.service_name = parameter.get("service_name")
39 40
40   - image_service_info, zoo, servers = Cache.cache_data(self.guid)
  41 + #获取缓存信息
  42 + image_service_info, zoo, servers = Cache.cache_data(self.service_name, type="name")
41 43
42 44 re = parameter.get("request")
43 45 if re and re.__eq__("GetCapabilities"):
44 46 return self.get_capabilities(image_service_info["service"])
45 47
46   -
47   - # bands = [1, 2, 3]
  48 + bbox = parameter.get("bbox")
  49 + width = int(parameter.get("width")) if parameter.get("width") else 256
  50 + height = int(parameter.get("height")) if parameter.get("height") else 256
  51 + image_type = parameter.get("format") if parameter.get("format") else "image/png"
  52 + quality = int(parameter.get("quality")) if parameter.get("quality") else 30
48 53
49 54 extent = [float(x) for x in bbox.split(",")]
50 55
... ... @@ -267,6 +272,10 @@ class Api(ApiTemplate):
267 272 {"name": "guid",
268 273 "in": "query",
269 274 "type": "string"},
  275 + {"name": "request",
  276 + "in": "query",
  277 + "type": "string",
  278 + "enum":["GetMap","GetCapabilities"]},
270 279 {"name": "bbox",
271 280 "in": "query",
272 281 "type": "string"},
... ...
  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 +import numpy
  9 +from flask import Response
  10 +import random
  11 +from app.modules.service.image.models import ImageService
  12 +from app.util.component.ApiTemplate import ApiTemplate
  13 +from app.util.component.ParameterUtil import ParameterUtil
  14 +import json
  15 +from threading import Thread
  16 +from .util.ImageData import ImageData
  17 +from .util.Cache import Cache
  18 +from .util.Opencv import Opencv
  19 +
  20 +class Api(ApiTemplate):
  21 +
  22 + api_name = "WMS"
  23 +
  24 + def process(self):
  25 +
  26 +
  27 + result = {}
  28 + parameter: dict = self.para
  29 +
  30 + try:
  31 +
  32 + parameter = ParameterUtil.to_lower(parameter)
  33 + if parameter.get("guid"):
  34 + self.guid = parameter.get("guid")
  35 +
  36 + #获取缓存信息
  37 + if parameter.get("guid"):
  38 +
  39 + image_service_info, zoo, servers = Cache.cache_data(self.guid, type="guid")
  40 + else:
  41 + image_service_info, zoo, servers = Cache.cache_data(parameter.get("service_name"), type="name")
  42 +
  43 + re = parameter.get("request")
  44 + if re and re.__eq__("GetCapabilities"):
  45 + return self.get_capabilities(image_service_info["service"])
  46 +
  47 + bbox = parameter.get("bbox")
  48 + width = int(parameter.get("width")) if parameter.get("width") else 256
  49 + height = int(parameter.get("height")) if parameter.get("height") else 256
  50 + image_type = parameter.get("format") if parameter.get("format") else "image/png"
  51 + quality = int(parameter.get("quality")) if parameter.get("quality") else 30
  52 +
  53 +
  54 +
  55 + extent = [float(x) for x in bbox.split(",")]
  56 +
  57 + intersect_image = [im for im in image_service_info["images"] if self.determin_intersect(json.loads(im.extent),extent)]
  58 +
  59 + if len(intersect_image)>1:
  60 +
  61 + # 结果矩阵
  62 + empty_list = [numpy.zeros((height,width), dtype=int) + 65536,
  63 + numpy.zeros((height,width), dtype=int) + 65536,
  64 + numpy.zeros((height,width), dtype=int) + 65536]
  65 +
  66 + pixel_array = numpy.zeros((height,width,3), dtype=int)
  67 + thread_list = []
  68 +
  69 + for image in intersect_image:
  70 + #该影像的服务器,随机选取一个
  71 + image_servers = image.server.split(",")
  72 + image_servers = [ser for ser in image_servers if ser in servers]
  73 + if len(image_servers)>0:
  74 + indx = int(random.random() * len(image_servers))
  75 + image_server = image_servers[indx]
  76 + else:
  77 + image_server = "None"
  78 + bands = json.loads(image.band_view)
  79 +
  80 + image_data = ImageData(image_server, image)
  81 +
  82 + thread: MyThread = MyThread(image_data.get_data, args=(extent,bands,height,width))
  83 + thread.start()
  84 + thread_list.append(thread)
  85 +
  86 +
  87 + for thread in thread_list:
  88 + thread.join()
  89 + data = thread.get_result()
  90 +
  91 + # 掩膜在中央接口生成,合图
  92 + mask = numpy.zeros((height,width), dtype=int)
  93 + mask2 = numpy.zeros((height,width), dtype=int)
  94 + jizhun = data[:, :, 0]
  95 + mask[jizhun == 65536] = 1
  96 + mask[jizhun != 65536] = 0
  97 + mask2[jizhun == 65536] = 0
  98 + mask2[jizhun != 65536] = 1
  99 + # 掩膜计算
  100 + for i, d in enumerate(empty_list):
  101 + empty_list[i] = empty_list[i] * mask + data[:, :, i] * mask2
  102 +
  103 + for ii in [0, 1, 2]:
  104 + # opencv 颜色排序为GBR
  105 + pixel_array[:, :, 2 - ii] = empty_list[ii]
  106 +
  107 +
  108 + elif len(intersect_image)==1:
  109 + # 该影像的服务器,随机选取一个
  110 + image = intersect_image[0]
  111 + image_servers = image.server.split(",")
  112 + image_servers = [ser for ser in image_servers if ser in servers]
  113 + if len(image_servers) > 0:
  114 + indx = int(random.random() * len(image_servers))
  115 + image_server = image_servers[indx]
  116 + else:
  117 + image_server = "None"
  118 +
  119 + bands = json.loads(image.band_view)
  120 +
  121 + image_data = ImageData(image_server, image)
  122 +
  123 + pixel_array_t = image_data.get_data(extent,bands,height,width)
  124 +
  125 + pixel_array = numpy.zeros((height, width, 3), dtype=int)
  126 + for ii in [0, 1, 2]:
  127 + # opencv 颜色排序为GBR
  128 + pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii]
  129 + else:
  130 + # 结果矩阵
  131 + pixel_array = numpy.zeros((height, width, 3), dtype=int)+65536
  132 +
  133 + # 将图片生成在内存中,然后直接返回response
  134 + im_data = Opencv.create_image(image_type, pixel_array, quality)
  135 +
  136 + if self.para.get("overview"):
  137 + return pixel_array
  138 + return Response(im_data, mimetype=image_type.lower())
  139 +
  140 + except Exception as e:
  141 + print(traceback.format_exc())
  142 + result["state"] = -1
  143 + result["message"] = e.__str__()
  144 + return result
  145 +
  146 +
  147 +
  148 + def determin_intersect(self, extent1, extent2):
  149 + if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[
  150 + 3] or extent2[3] < extent1[1]:
  151 + return False
  152 + else:
  153 + return True
  154 +
  155 + def get_capabilities(self,image_service:ImageService):
  156 +
  157 + xml = '''<?xml version="1.0" encoding="utf-8" ?>
  158 + <WMS_Capabilities version="1.2.0">
  159 + <Service>
  160 + <Name>WMS</Name>
  161 + <Title>{service_title}</Title>
  162 + <Abstract>{abstract}</Abstract>
  163 + <Keywords>GIMS</Keywords>
  164 + <OnlineResource/>
  165 + <Fees>none</Fees>
  166 + <AccessConstraints>none</AccessConstraints>
  167 + </Service>
  168 + <Capability>
  169 + <Request>
  170 + <GetCapabilities>
  171 + <Format>text/xml</Format>
  172 + <DCPType>
  173 + <HTTP>
  174 + <Get>
  175 + <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
  176 + </Get>
  177 + </HTTP>
  178 + </DCPType>
  179 + </GetCapabilities>
  180 + <GetMap>
  181 + <Format>png</Format>
  182 + <Format>jpeg</Format>
  183 + <Format>gif</Format>
  184 + <Format>image/png</Format>
  185 + <Format>image/jpeg</Format>
  186 + <Format>image/gif</Format>
  187 + <DCPType>
  188 + <HTTP>
  189 + <Get>
  190 + <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
  191 + </Get>
  192 + </HTTP>
  193 + </DCPType>
  194 + </GetMap>
  195 + <Map>
  196 + <Format>
  197 + <PNG/>
  198 + <GIF/>
  199 + <JPG/>
  200 + </Format>
  201 + <DCPType>
  202 + <HTTP>
  203 + <Get onlineResource="{url}"/>
  204 + </HTTP>
  205 + </DCPType>
  206 + </Map>
  207 + <Capabilities>
  208 + <Format>
  209 + <WMS_XML/>
  210 + </Format>
  211 + <DCPType>
  212 + <HTTP>
  213 + <Get onlineResource="{url}"/>
  214 + </HTTP>
  215 + </DCPType>
  216 + </Capabilities>
  217 + <FeatureInfo>
  218 + <Format>
  219 + <XML/>
  220 + <MIME/>
  221 + </Format>
  222 + <DCPType>
  223 + <HTTP>
  224 + <Get onlineResource="{url}"/>
  225 + </HTTP>
  226 + </DCPType>
  227 + </FeatureInfo>
  228 + </Request>
  229 + <Exception>
  230 + <Format>
  231 + <WMS_XML/>
  232 + <INIMAGE/>
  233 + <BLANK/>
  234 + </Format>
  235 + </Exception>
  236 + <Layer>
  237 + <Name>{service_name}</Name>
  238 + <Title>{service_title}</Title>
  239 + <CRS>{crs}</CRS>
  240 + <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/>
  241 +
  242 + <Layer queryable="1">
  243 + <CRS>{crs}</CRS>
  244 + <Name>{layer_name}</Name>
  245 + <Title>{layer_title}</Title>
  246 + <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/>
  247 + </Layer>
  248 + </Layer>
  249 + </Capability>
  250 + </WMS_Capabilities>'''
  251 +
  252 + extent = json.loads(image_service.extent)
  253 + xml = xml.format(service_title=image_service.name,
  254 + service_name=image_service.name,
  255 + abstract= "None" ,
  256 + crs="ESPG:4326",
  257 + layer_name=image_service.name,
  258 + layer_title=image_service.name,
  259 + maxx=extent[2],
  260 + maxy = extent[3],
  261 + minx = extent[0],
  262 + miny = extent[1],
  263 + url="http://{}/API/Service/Image/WMS?guid={}".format(configure.deploy_ip_host,image_service.guid))
  264 +
  265 +
  266 + r = Response(response=xml, status=200, mimetype="application/xml")
  267 + r.headers["Content-Type"] = "text/xml; charset=utf-8"
  268 + return r
  269 +
  270 + api_doc = {
  271 + "tags": ["影像接口"],
  272 + "parameters": [
  273 + {"name": "guid",
  274 + "in": "query",
  275 + "type": "string"},
  276 + {"name": "bbox",
  277 + "in": "query",
  278 + "type": "string"},
  279 + {"name": "width",
  280 + "in": "query",
  281 + "type": "string"},
  282 + {"name": "height",
  283 + "in": "query",
  284 + "type": "string"},
  285 + {"name": "format",
  286 + "in": "query",
  287 + "type": "string"},
  288 + {"name": "quality",
  289 + "in": "query",
  290 + "type": "string"}
  291 + ],
  292 + "responses": {
  293 + 200: {
  294 + "schema": {
  295 + "properties": {
  296 + }
  297 + }
  298 + }
  299 + }
  300 + }
  301 +
  302 +class MyThread(Thread):
  303 + def __init__(self,func,args=()):
  304 + super(MyThread,self).__init__()
  305 + self.func = func
  306 + self.args = args
  307 + def run(self):
  308 + self.result = self.func(*self.args)
  309 + def get_result(self):
  310 + try:
  311 + return self.result
  312 + except Exception:
  313 + return None
  314 +
  315 +
  316 +
... ...
... ... @@ -9,7 +9,7 @@ import numpy
9 9 from flask import Response
10 10 import random
11 11
12   -from app.modules.service.image.models import ImageService,Image
  12 +from app.modules.service.image.models import Image
13 13 from app.util.component.ApiTemplate import ApiTemplate
14 14
15 15 from app.util.component.ParameterUtil import ParameterUtil
... ... @@ -36,6 +36,25 @@ class Api(ApiTemplate):
36 36 parameter = ParameterUtil.to_lower(parameter)
37 37
38 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 + tmp_extent = []
  43 + for g in image_guids.split(","):
  44 + image = Image.query.filter_by(guid=g).one_or_none()
  45 + if image:
  46 + image_extent = json.loads(image.extent)
  47 + if not tmp_extent:
  48 + tmp_extent = image_extent
  49 + else:
  50 + tmp_extent[0] = min(image_extent[0], tmp_extent[0])
  51 + tmp_extent[2] = max(image_extent[2], tmp_extent[2])
  52 + tmp_extent[1] = min(image_extent[1], tmp_extent[1])
  53 + tmp_extent[3] = max(image_extent[3], tmp_extent[3])
  54 +
  55 + result["result"] = True
  56 + result["data"] = tmp_extent
  57 + return result
39 58
40 59 bbox = parameter.get("bbox")
41 60 width = int(parameter.get("width")) if parameter.get("width") else 256
... ... @@ -147,9 +166,13 @@ class Api(ApiTemplate):
147 166 api_doc = {
148 167 "tags": ["影像接口"],
149 168 "parameters": [
150   - {"name": "guid",
  169 + {"name": "image_guids",
151 170 "in": "query",
152 171 "type": "string"},
  172 + {"name": "get_extent",
  173 + "in": "query",
  174 + "type": "boolean",
  175 + "enum":[True,False]},
153 176 {"name": "bbox",
154 177 "in": "query",
155 178 "type": "string"},
... ...
  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 +import numpy
  9 +from flask import Response
  10 +from .util.ImageData import ImageData
  11 +
  12 +from app.modules.service.image.models import ImageService
  13 +from app.models import TileScheme,Service
  14 +from app.util.component.ApiTemplate import ApiTemplate
  15 +from app.util.component.SliceScheme import SliceScheme
  16 +from app.util.component.ParameterUtil import ParameterUtil
  17 +import json
  18 +import random
  19 +import copy
  20 +from .util.Opencv import Opencv
  21 +from .util.Cache import Cache
  22 +from .util.MyThread import MyThread
  23 +
  24 +class Api(ApiTemplate):
  25 +
  26 + api_name = "切片"
  27 +
  28 + def __init__(self,service_name):
  29 + super().__init__()
  30 + self.service_name = service_name
  31 +
  32 + def process(self):
  33 +
  34 + result = {}
  35 + parameter: dict = self.para
  36 +
  37 + try:
  38 + if parameter.get("service_name"):
  39 + self.service_name = parameter.get("service_name")
  40 +
  41 + #获取缓存数据
  42 + image_service_info, zoo, servers = Cache.cache_data(self.service_name,type="name")
  43 +
  44 + # 转换参数
  45 + parameter = ParameterUtil.to_lower(parameter)
  46 +
  47 + re = parameter.get("request")
  48 + if re and re.__eq__("GetCapabilities"):
  49 + service = Service.query.filter_by(guid=image_service_info["service"].service_guid).one_or_none()
  50 + return self.get_capabilities(image_service_info["service"],service)
  51 +
  52 + if parameter.get("tilematrix"):
  53 + if parameter.get("tilematrix").__contains__(":"):
  54 + self.level = int(parameter.get("tilematrix").split(":")[-1])
  55 + else:
  56 + self.level = int(parameter.get("tilematrix"))
  57 + if parameter.get("tilerow"):
  58 + self.row = int(parameter.get("tilerow"))
  59 + if parameter.get("tilecol"):
  60 + self.col = int(parameter.get("tilecol"))
  61 +
  62 + image_type = parameter.get("format") if parameter.get("format") else "image/png"
  63 + quality = int(parameter.get("quality")) if parameter.get("quality") else 30
  64 + slice_para = image_service_info["scheme"]
  65 + extent = SliceScheme.get_polygon(slice_para, self.level, self.row, self.col)
  66 +
  67 + height, width = 256,256
  68 +
  69 + # 多线程获取分布式数据
  70 +
  71 + intersect_image = [im for im in image_service_info["images"] if self.determin_intersect(json.loads(im.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.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.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.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.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 +
  149 +
  150 +
  151 + # 将图片生成在内存中,然后直接返回response
  152 + im_data = Opencv.create_image(image_type, pixel_array, quality)
  153 + return Response(im_data, mimetype=image_type.lower())
  154 +
  155 +
  156 + except Exception as e:
  157 + print(traceback.format_exc())
  158 + result["state"] = -1
  159 + result["message"] = e.__str__()
  160 + return result
  161 +
  162 + def get_capabilities(self, image_service: ImageService, service: Service):
  163 + tile_scheme: TileScheme = TileScheme.query.filter_by(guid=image_service.scheme_guid).one_or_none()
  164 + if not tile_scheme:
  165 + raise Exception("切片方案不存在!")
  166 +
  167 + 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">
  168 + <!-- Service Identification -->
  169 + <ows:ServiceIdentification>
  170 + <ows:Title>{title}</ows:Title>
  171 + <ows:ServiceType>OGC WMTS</ows:ServiceType>
  172 + <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>
  173 + </ows:ServiceIdentification>
  174 +
  175 + <!-- Operations Metadata -->
  176 + <ows:OperationsMetadata>
  177 + <ows:Operation name="GetCapabilities">
  178 + <ows:DCP>
  179 + <ows:HTTP>
  180 + <ows:Get xlink:href="{capabilities_url}">
  181 + <ows:Constraint name="GetEncoding">
  182 + <ows:AllowedValues>
  183 + <ows:Value>RESTful</ows:Value>
  184 + </ows:AllowedValues>
  185 + </ows:Constraint>
  186 + </ows:Get>
  187 +
  188 + <!-- add KVP binding in 10.1 -->
  189 + <ows:Get xlink:href="{tile_url}?">
  190 + <ows:Constraint name="GetEncoding">
  191 + <ows:AllowedValues>
  192 + <ows:Value>KVP</ows:Value>
  193 + </ows:AllowedValues>
  194 + </ows:Constraint>
  195 + </ows:Get>
  196 + </ows:HTTP>
  197 + </ows:DCP>
  198 + </ows:Operation>
  199 + <ows:Operation name="GetTile">
  200 + <ows:DCP>
  201 + <ows:HTTP>
  202 + <ows:Get xlink:href="{tile_url}">
  203 + <ows:Constraint name="GetEncoding">
  204 + <ows:AllowedValues>
  205 + <ows:Value>RESTful</ows:Value>
  206 + </ows:AllowedValues>
  207 + </ows:Constraint>
  208 + </ows:Get>
  209 + <ows:Get xlink:href="{tile_url}?">
  210 + <ows:Constraint name="GetEncoding">
  211 + <ows:AllowedValues>
  212 + <ows:Value>KVP</ows:Value>
  213 + </ows:AllowedValues>
  214 + </ows:Constraint>
  215 + </ows:Get>
  216 + </ows:HTTP>
  217 + </ows:DCP>
  218 + </ows:Operation>
  219 + </ows:OperationsMetadata>
  220 +
  221 + <Contents>
  222 +
  223 + <!-- Layer -->
  224 +
  225 +
  226 + <Layer>
  227 + <ows:Title>{title}</ows:Title>
  228 + <ows:Identifier>{title}</ows:Identifier>
  229 + <ows:BoundingBox crs="{crs}">
  230 + <ows:LowerCorner>{xmin} {ymin}</ows:LowerCorner>
  231 + <ows:UpperCorner>{xmax} {ymax}</ows:UpperCorner>
  232 + </ows:BoundingBox>
  233 +
  234 + <Style isDefault="true">
  235 + <ows:Title>Default Style</ows:Title>
  236 + <ows:Identifier>default</ows:Identifier>
  237 + </Style>
  238 + <Format>image/png</Format>
  239 + <TileMatrixSetLink>
  240 + <TileMatrixSet>{tile_name}</TileMatrixSet>
  241 + </TileMatrixSetLink>
  242 +
  243 + <ResourceURL format="image/png" resourceType="tile" template="{tile_url}"/>
  244 +
  245 + </Layer>
  246 +
  247 + <!-- TileMatrixSet -->
  248 +
  249 +
  250 + <TileMatrixSet>
  251 +
  252 + <TileMatrix>
  253 + <ows:Title>{tile_title}</ows:Title>
  254 + <ows:Abstract>{tile_description}</ows:Abstract>
  255 + <ows:Identifier>{tile_name}</ows:Identifier>
  256 + <ows:SupportedCRS>{crs}</ows:SupportedCRS>
  257 +
  258 + {tile_matrix}
  259 +
  260 + </TileMatrix>
  261 +
  262 + </TileMatrixSet>
  263 +
  264 +
  265 + </Contents>
  266 + <ServiceMetadataURL xlink:href="{capabilities_url}"/>
  267 + </Capabilities>'''
  268 +
  269 + tile_matrix_each = '''
  270 + <TileMatrix>
  271 + <ows:Identifier>{lev}</ows:Identifier>
  272 + <ScaleDenominator>{scale}</ScaleDenominator>
  273 + <TopLeftCorner>{top_left}</TopLeftCorner>
  274 + <TileWidth>{cols}</TileWidth>
  275 + <TileHeight>{rows}</TileHeight>
  276 + </TileMatrix>
  277 + '''
  278 +
  279 + tile_matrix = ""
  280 + top_left = tile_scheme.top_left
  281 + for level in json.loads(tile_scheme.levels):
  282 + tile_matrix = "{}{}".format(tile_matrix, tile_matrix_each.format(lev=level["level"],
  283 + scale=level["scale"],
  284 + top_left=top_left,
  285 + cols=tile_scheme.cols,
  286 + rows=tile_scheme.rows))
  287 +
  288 + extent = json.loads(image_service.extent)
  289 +
  290 + xml = xml.format(
  291 + capabilities_url="http://{}/API/Service/Image/Capabilities?guid={}".format(configure.deploy_ip_host,
  292 + image_service.guid),
  293 + tile_url="http://{}/API/Service/Image/Tile?guid={}".format(configure.deploy_ip_host, image_service.guid),
  294 + crs=tile_scheme.crs,
  295 + xmin=extent[0],
  296 + ymin=extent[1],
  297 + xmax=extent[2],
  298 + ymax=extent[3],
  299 + # TileMatrix = "{TileMatrix}",
  300 + # TileRow = "{TileRow}",
  301 + # TileCol = "{TileCol}",
  302 + guid=image_service.guid,
  303 + title=service.title,
  304 + tile_title=tile_scheme.name,
  305 + tile_name=tile_scheme.name,
  306 + tile_description=tile_scheme.description,
  307 + tile_matrix=tile_matrix
  308 + )
  309 +
  310 + r = Response(response=xml, status=200, mimetype="application/xml")
  311 + r.headers["Content-Type"] = "text/xml; charset=utf-8"
  312 +
  313 + return r
  314 +
  315 +
  316 +
  317 + def determin_intersect(self, extent1, extent2):
  318 + if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[
  319 + 3] or extent2[3] < extent1[1]:
  320 + return False
  321 + else:
  322 + return True
  323 +
  324 +
  325 + api_doc = {
  326 + "tags": ["影像接口"],
  327 + "parameters": [
  328 + {"name": "guid",
  329 + "in": "formData",
  330 + "type": "string"},
  331 + {"name": "request",
  332 + "in": "formData",
  333 + "type": "string",
  334 + "enum": ["GetTile", "GetCapabilities"]},
  335 + {"name": "tilematrix",
  336 + "in": "formData",
  337 + "type": "string"},
  338 + {"name": "tilerow",
  339 + "in": "formData",
  340 + "type": "string"},
  341 + {"name": "tilecol",
  342 + "in": "formData",
  343 + "type": "string"},
  344 + {"name": "format",
  345 + "in": "formData",
  346 + "type": "string"},
  347 + {"name": "quality",
  348 + "in": "formData",
  349 + "type": "string"}
  350 +
  351 + ],
  352 + "responses": {
  353 + 200: {
  354 + "schema": {
  355 + "properties": {
  356 + }
  357 + }
  358 + }
  359 + }
  360 + }
  361 +
  362 +
  363 +
... ...
... ... @@ -31,16 +31,16 @@ class Image(db.Model):
31 31
32 32 size = Column(Float)
33 33 #坐标wkt
34   - sr_wkt = Column(Text) #坐标wkt
35   - sr_proj4 = Column(Text)#坐标proj
36   - epsg = Column(Integer)#坐标epsg
  34 + crs_wkt = Column(Text) #坐标wkt
  35 + crs_proj4 = Column(Text)#坐标proj
  36 + crs = Column(String)#坐标
37 37 create_time = Column(DateTime)
38 38 update_time = Column(DateTime)
39 39 cell_x_size = Column(Float)#像元x大小
40 40 cell_y_size = Column(Float)#像元y大小
41 41 region = Column(Text)
42 42
43   - ym = Column(String(256))#时间年份
  43 + collect_time = Column(DateTime) #成像时间年份
44 44
45 45 satellite = Column(String)#卫星类型
46 46 type = Column(String(128))
... ...
... ... @@ -7,13 +7,14 @@
7 7 from kazoo.client import KazooClient
8 8 import configure
9 9 import time
10   -from app.modules.service.image.models import ImageService,Image
11   -from app.models import TileScheme
  10 +from app.modules.service.image.models import ImageService
  11 +from app.models import TileScheme,Service
12 12 import json
  13 +
13 14 class Cache:
14 15
15 16 @classmethod
16   - def cache_data(cls,guid):
  17 + def cache_data(cls,guid_or_name,type="guid"):
17 18
18 19 from app import GLOBAL_DIC
19 20
... ... @@ -38,7 +39,7 @@ class Cache:
38 39 servers = GLOBAL_DIC.get("servers")
39 40
40 41 # 更新缓存
41   - if time.time() - GLOBAL_DIC["servers_updatetime"] > 10:
  42 + if time.time() - GLOBAL_DIC["servers_updatetime"] > 30:
42 43 servers = zoo.get_children("/rpc")
43 44 servers.append("本地服务器")
44 45 GLOBAL_DIC["servers"] = servers
... ... @@ -46,25 +47,31 @@ class Cache:
46 47
47 48
48 49 # 缓存服务信息
49   - if guid:
50   - image_service_info = GLOBAL_DIC.get(guid)
51   - if image_service_info is None or time.time() - GLOBAL_DIC.get("service_updatetime") > 20:
52   - image_service: ImageService = ImageService.query.filter_by(guid=guid).one_or_none()
  50 + if guid_or_name:
  51 + image_service_info = GLOBAL_DIC.get(guid_or_name)
  52 + if image_service_info is None or time.time() - GLOBAL_DIC.get("service_updatetime") > 30:
  53 + if type.__eq__("guid"):
  54 + image_service: ImageService = ImageService.query.filter_by(guid=guid_or_name).one_or_none()
  55 + else:
  56 + service = Service.query.filter_by(name=guid_or_name).one_or_none()
  57 + image_service: ImageService = ImageService.query.filter_by(guid=service.service_guid).one_or_none()
53 58 images = image_service.images.all()
54 59
55 60 if image_service.scheme_guid:
56 61 scheme: TileScheme = TileScheme.query.filter_by(guid=image_service.scheme_guid).one_or_none()
57   - GLOBAL_DIC[guid] = {"service": image_service, "images": images,
  62 + GLOBAL_DIC[guid_or_name] = {"service": image_service, "images": images,
58 63 "scheme": json.loads(scheme.parameter)}
59 64 else:
60 65
61   - GLOBAL_DIC[guid] = {"service": image_service, "images": images}
  66 + GLOBAL_DIC[guid_or_name] = {"service": image_service, "images": images}
62 67 GLOBAL_DIC["service_updatetime"] = time.time()
63   - image_service_info = GLOBAL_DIC[guid]
  68 + image_service_info = GLOBAL_DIC[guid_or_name]
64 69
65 70 else:
66   - image_service_info = GLOBAL_DIC[guid]
  71 + image_service_info = GLOBAL_DIC[guid_or_name]
67 72 else:
68 73 image_service_info = None
69 74
70   - return image_service_info,zoo,servers
\ No newline at end of file
  75 + return image_service_info,zoo,servers
  76 +
  77 +
... ...
... ... @@ -82,77 +82,120 @@ class ImageData:
82 82 :param bands:
83 83 :return:
84 84 '''
85   -
  85 + pixel_array = numpy.zeros((height, width, 3), dtype=int)
  86 + ceng = 0
86 87 img: Dataset = gdal.Open(self.image.path, 0)
87 88
88   - origin_extent = json.loads(self.image.extent)
  89 + for band in bands:
89 90
90   - # 超出空间范围
91   - if extent[2] < origin_extent[0] or extent[0] > origin_extent[2] or extent[1] > origin_extent[3] or extent[
92   - 3] < origin_extent[1]:
93   - empty = numpy.zeros((height, width, 3), dtype=int) + 65536
94   - # 空间范围相交
95   - else:
  91 + # 自决定金字塔等级
  92 + xysize = [img.RasterXSize, img.RasterYSize]
96 93
97   - ox = img.RasterXSize
98   - oy = img.RasterYSize
  94 + origin_extent = json.loads(self.image.extent)
  95 + band_data: Band = img.GetRasterBand(band)
99 96
100   - # 网格大小
101   - grid_x = (origin_extent[2] - origin_extent[0]) / (ox * 1.0)
102   - grid_y = (origin_extent[3] - origin_extent[1]) / (oy * 1.0)
  97 + max_level = band_data.GetOverviewCount()
103 98
104   - # 完全在影像范围内
105   - if extent[0] > origin_extent[0] and extent[1] > origin_extent[1] and extent[2] < \
106   - origin_extent[2] and extent[3] < origin_extent[3]:
  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)
107 106
108   - # 网格偏移量
109   - off_x = math.floor((extent[0] - origin_extent[0]) / grid_x)
110   - off_y = math.floor((origin_extent[3] - extent[3]) / grid_y)
  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
111 116
112   - # 截取后网格个数
113   - x_g = math.ceil((extent[2] - extent[0]) / grid_x)
  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)
114 120
115   - y_g = math.ceil((extent[3] - extent[1]) / grid_y)
  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)
116 135
117   - empty = img.ReadRaster(off_x, off_y, x_g, y_g, 256, 256, band_list = bands)
118   - img.ReadAsArray()
119   - # 部分相交
120   - else:
121 136
122   - inter_extent = [0, 0, 0, 0]
123   - inter_extent[0] = origin_extent[0] if origin_extent[0] > extent[0] else extent[0]
124   - inter_extent[1] = origin_extent[1] if origin_extent[1] > extent[1] else extent[1]
125   - inter_extent[2] = origin_extent[2] if origin_extent[2] < extent[2] else extent[2]
126   - inter_extent[3] = origin_extent[3] if origin_extent[3] < extent[3] else extent[3]
  137 + # 部分相交
  138 + else:
127 139
128   - # 网格偏移量
129   - off_x = math.floor((inter_extent[0] - origin_extent[0]) / grid_x)
130   - off_y = math.floor((origin_extent[3] - inter_extent[3]) / grid_y)
  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]
131 145
132   - # 截取后网格个数
133   - x_g = math.floor((inter_extent[2] - inter_extent[0]) / grid_x)
134   - y_g = math.floor((inter_extent[3] - inter_extent[1]) / grid_y)
  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)
135 149
136   - # 相对于出图的偏移量
  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)
137 153
138   - # 出图的网格大小
139   - out_grid_x = (extent[2] - extent[0]) / (width * 1.0)
140   - out_grid_y = (extent[3] - extent[1]) / (height * 1.0)
  154 + # 相对于出图的偏移量
141 155
142   - out_off_x = int(math.ceil((inter_extent[0] - extent[0]) / out_grid_x))
143   - out_off_y = int(math.ceil((extent[3] - inter_extent[3]) / out_grid_y))
  156 + # 出图的网格大小
  157 + out_grid_x = (extent[2] - extent[0]) / (width * 1.0)
  158 + out_grid_y = (extent[3] - extent[1]) / (height * 1.0)
144 159
145   - out_x_g = int(math.floor((inter_extent[2] - inter_extent[0]) / out_grid_x))
146   - out_y_g = int(math.floor((inter_extent[3] - inter_extent[1]) / out_grid_y))
  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))
147 162
148   - # 相交部分在出图的哪个位置
  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))
149 165
150   - overview_raster: ndarray = img.ReadAsArray(off_x, off_y, x_g, y_g, out_x_g,
151   - out_y_g)
  166 + # 相交部分在出图的哪个位置
152 167
153   - dat = numpy.zeros((height, width, 3), dtype=int) + 65536
154   - dat[out_off_y:out_off_y + out_y_g, out_off_x:out_off_x + out_x_g] = overview_raster
155   - empty = dat
  168 + overview_raster: ndarray = overview.ReadAsArray(off_x, off_y, x_g, y_g, out_x_g,
  169 + out_y_g)
156 170
157   - return empty
  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
158 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
... ...
... ... @@ -27,9 +27,9 @@ class Api(ApiTemplate):
27 27 parameter = {}
28 28 for l_dict in json.loads(data.get("levels")):
29 29 parameter[str(l_dict["level"])] = {"resolution":l_dict["resolution"],"scale":l_dict["scale"]}
30   - parameter["cols"] = int(data.get("cols"))
31   - parameter["rows"] = int(data.get("rows"))
32   - parameter["dpi"] = int(data.get("dpi"))
  30 + parameter["cols"] = int(data.get("cols",256))
  31 + parameter["rows"] = int(data.get("rows",256))
  32 + parameter["dpi"] = int(data.get("dpi",96))
33 33 parameter["wkt"] = data.get("crs_wkt")
34 34 parameter["x"] = eval(data.get("top_left").split(",")[0])
35 35 parameter["y"] = eval(data.get("top_left").split(",")[1])
... ... @@ -51,9 +51,9 @@ class Api(ApiTemplate):
51 51 # origin_x = top_left[0],
52 52 # origin_y = top_left[1],
53 53 levels = json.dumps(json.loads(data.get("levels"))),
54   - dpi = int(data.get("dpi")),
55   - rows = int(data.get("rows")),
56   - cols = int(data.get("cols")),
  54 + dpi = int(data.get("dpi",96)),
  55 + rows = int(data.get("rows",256)),
  56 + cols = int(data.get("cols",256)),
57 57 update_time = datetime.datetime.now(),
58 58 parameter=json.dumps(parameter)
59 59 )
... ...
... ... @@ -19,6 +19,18 @@ class Api(ApiTemplate):
19 19 try:
20 20 guid = self.para.get("guid")
21 21 service = Service.query.filter_by(guid=guid).one_or_none()
  22 + if service.type in ["ImageWMTS","ImageWMS"]:
  23 + from app.modules.service.image.models import ImageService
  24 + image_service = ImageService.query.filter_by(guid=service.service_guid).one_or_none()
  25 + db.session.delete(image_service)
  26 + if service.type in ["WMTS","TMS"]:
  27 + from app.modules.service.wmts.models import WMTS
  28 + wmts = WMTS.query.filter_by(guid=service.service_guid).one_or_none()
  29 + db.session.delete(wmts)
  30 + if service.type in ["WMTS", "TMS"]:
  31 + from app.modules.service.wms.models import WMS
  32 + wms = WMS.query.filter_by(guid=service.service_guid).one_or_none()
  33 + db.session.delete(wms)
22 34 db.session.delete(service)
23 35 db.session.commit()
24 36 res["result"] = True
... ...
... ... @@ -44,12 +44,11 @@ class Api(ApiTemplate):
44 44 "type": "string",
45 45 "description": "[WMS,WMTS,影像WMS,影像WMTS,guid]"},
46 46
47   - # {"name": "type",
48   - # "in": "formData",
49   - # "type": "string",
50   - # "enum": ["WMS/WFS", "WMTS", "TMS", "ImageWMS", "ImageWMTS"],
51   - # "required": "true",
52   - # "description": "[WMS,WMTS,影像WMS,影像WMTS]"},
  47 + {"name": "type",
  48 + "in": "formData",
  49 + "type": "string",
  50 + "enum": ["WMS/WFS", "WMTS", "TMS", "ImageWMS", "ImageWMTS"],
  51 + "description": "[WMS,WMTS,影像WMS,影像WMTS]"},
53 52
54 53 {"name": "name",
55 54 "in": "formData",
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/9/22
  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.models import Service
  11 +import os
  12 +
  13 +class Api(ApiTemplate):
  14 + '''
  15 + 解析md文件
  16 + '''
  17 + api_name = "服务resolve"
  18 +
  19 + def process(self):
  20 + res = {}
  21 + try:
  22 +
  23 + parent = os.path.dirname(os.path.realpath(__file__))
  24 + dir_path, store_file = FileProcess.save(parent)
  25 +
  26 +
  27 + except Exception as e:
  28 + raise e
  29 + return res
  30 +
  31 +
  32 + api_doc = {
  33 + "tags": ["服务接口"],
  34 + "parameters": [
  35 + {"name": "guid",
  36 + "in": "formData",
  37 + "type": "string",
  38 + "description": "guid"},
  39 + ],
  40 + "responses": {
  41 + 200: {
  42 + "schema": {
  43 + "properties": {
  44 + }
  45 + }
  46 + }
  47 + }
  48 + }
\ No newline at end of file
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/9/22
  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.models import Service
  10 +
  11 +class Api(ApiTemplate):
  12 + '''
  13 + 保存服务到dmd文件
  14 + '''
  15 + api_name = "服务Save"
  16 + def process(self):
  17 + res = {}
  18 + try:
  19 + guid = self.para.get("guid")
  20 + service = Service.query.filter_by(guid=guid).one_or_none()
  21 + if not service:
  22 + raise Exception("服务不存在!")
  23 + res["data"] = {}
  24 +
  25 + if service.type in ["ImageWMS","ImageWMTS"]:
  26 + from app.modules.service.image.models import ImageService
  27 + speci_service = ImageService.query.filter_by(guid=service.service_guid).one_or_none()
  28 + relate_images = speci_service.images.all()
  29 + res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service)
  30 +
  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__("WMTS") or service.type.__eq__("TMS"):
  35 + from app.modules.service.wmts.models import WMTS
  36 + speci_service = WMTS.query.filter_by(guid=service.service_guid).one_or_none()
  37 +
  38 + res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service)
  39 +
  40 + elif service.type.__eq__("WMS/WFS"):
  41 + from app.modules.service.wms.models import WMS
  42 + speci_service = WMS.query.filter_by(guid=service.service_guid).one_or_none()
  43 + res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service)
  44 + else:
  45 + res["data"] = {}
  46 +
  47 + res["data"]["service"] = ModelVisitor.object_to_json(service)
  48 +
  49 + except Exception as e:
  50 + raise e
  51 + return res
  52 +
  53 +
  54 + api_doc = {
  55 + "tags": ["服务接口"],
  56 + "parameters": [
  57 + {"name": "guid",
  58 + "in": "formData",
  59 + "type": "string",
  60 + "description": "guid"},
  61 + ],
  62 + "responses": {
  63 + 200: {
  64 + "schema": {
  65 + "properties": {
  66 + }
  67 + }
  68 + }
  69 + }
  70 + }
\ No newline at end of file
... ...
... ... @@ -17,6 +17,8 @@ class Api(ApiTemplate):
17 17 state = int(self.para.get("state"))
18 18 Service.query.filter_by(guid=guid).update({"state":state})
19 19
  20 + # 清理缓存,拒绝服务
  21 +
20 22 db.session.commit()
21 23 res["result"] = True
22 24 except Exception as e:
... ...
... ... @@ -8,8 +8,10 @@ from flask import current_app
8 8 import os
9 9
10 10 from app.util.component.ApiTemplate import ApiTemplate
  11 +from app.util.component.ModelVisitor import ModelVisitor
11 12 from app.util.component.StructuredPrint import StructurePrint
12   -
  13 +from app.models import Service,db
  14 +from sqlalchemy.orm import load_only
13 15 from flask import current_app
14 16 class Api(ApiTemplate):
15 17
... ... @@ -24,7 +26,9 @@ class Api(ApiTemplate):
24 26
25 27 result=dict()
26 28 result.update(self.para)
  29 + services = Service.query.options(load_only('guid')).all()
27 30 result["root_path"] = os.path.dirname(current_app.instance_path)
  31 + result["services"] = ModelVisitor.objects_to_jsonarray(services)
28 32 return result
29 33
30 34
... ...
... ... @@ -307,13 +307,6 @@ class ThisTask:
307 307 :return: 表名
308 308 '''
309 309
310   - # 在覆盖模式下,删除原有记录
311   - if overwrite.__eq__("yes"):
312   - old_table = self.sys_session.query(Table).filter_by(name=new_layer_name).one_or_none()
313   - if old_table:
314   - self.sys_session.delete(old_table)
315   -
316   -
317 310 this_time = datetime.datetime.now()
318 311
319 312 ext = layer.GetExtent()
... ... @@ -336,7 +329,7 @@ class ThisTask:
336 329 is_vacuate=is_vacuate
337 330 )
338 331 # 删除遗留业务数据
339   - history_table = self.sys_session.query(Table).filter_by(name=new_layer_name).all()
  332 + history_table = self.sys_session.query(Table).filter_by(name=new_layer_name,database_guid=self.database.guid).all()
340 333 if history_table:
341 334 for ht in history_table:
342 335 self.sys_session.delete(ht)
... ...
... ... @@ -52,8 +52,8 @@ class SliceScheme:
52 52 col = int(col)
53 53 detaxy = parameter.get(str(level)).get("resolution")* parameter.get("cols")
54 54
55   - minx = detaxy * col + parameter.get("x")
56   - maxy = -detaxy * row + parameter.get("y")
  55 + minx = detaxy * col + int(parameter.get("x"))
  56 + maxy = -detaxy * row + int(parameter.get("y"))
57 57 maxx = detaxy + minx
58 58 miny = -detaxy + maxy
59 59
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/10/21
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo import ogr
  7 +from osgeo import gdal
  8 +
  9 +def function():
  10 + gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8")
  11 +
  12 + fn = "PG: user=postgres password=chinadci host=172.26.60.101 port=5432 dbname=parcel"
  13 + driver = ogr.GetDriverByName("PostgreSQL")
  14 + ds:ogr.DataSource = driver.Open(fn, 1)
  15 +
  16 + layer:ogr.Layer = ds.GetLayerByName("ZDCLHX2000V14")
  17 +
  18 + output = r"E:\D2\桌面\工作\2021.10省厅测评\10w.shp"
  19 +
  20 + shp_driver = ogr.GetDriverByName("FileGDB")
  21 + output_ds: ogr.DataSource = shp_driver.CreateDataSource(output)
  22 +
  23 + out_layer:ogr.Layer = output_ds.CreateLayer(layer.GetName(),layer.GetSpatialRef(),layer.GetGeomType())
  24 +
  25 + field_names = ["id","预编号","土地使用者","所有权性质","土地证号","地址","镇区","测量日期","二维码信息","shape_area"]
  26 + field_names_yinwen = ["id", "precode", "user", "xingzhi", "tudi", "address", "region", "date", "code", "shape_area"]
  27 + scheme = [field for field in layer.schema if field.GetName() in field_names]
  28 +
  29 + out_layer.CreateFields(scheme)
  30 + count = 100000
  31 +
  32 + i=0
  33 + featureDefn = out_layer.GetLayerDefn()
  34 +
  35 + for f in layer:
  36 + ff :ogr.Feature = f
  37 + new_f = ogr.Feature(featureDefn)
  38 + new_f.SetGeometry(ff.geometry())
  39 + for field in field_names:
  40 + dd = ff.GetFieldIndex(field)
  41 + kkk = ff.GetField(dd)
  42 + new_f.SetField(field,kkk)
  43 + out_layer.CreateFeature(new_f)
  44 + i += 1
  45 + if i==count:
  46 + break
  47 +
  48 + output_ds.Destroy()
  49 +if __name__ == '__main__':
  50 +
  51 + function()
\ No newline at end of file
... ...
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/10/21
  4 +#email: nheweijun@sina.com
  5 +
  6 +from osgeo import ogr
  7 +from osgeo import gdal
  8 +
  9 +def function():
  10 + gdal.SetConfigOption("SHAPE_ENCODING", "GBK")
  11 +
  12 + fn = "PG: user=postgres password=chinadci host=172.26.60.101 port=5432 dbname=parcel"
  13 + driver = ogr.GetDriverByName("PostgreSQL")
  14 + ds:ogr.DataSource = driver.Open(fn, 1)
  15 +
  16 + layer:ogr.Layer = ds.GetLayerByName("ZDCLHX2000V14")
  17 + output = r"E:\D2\桌面\工作\2021.10省厅测评\100w.shp"
  18 + shp_driver = ogr.GetDriverByName("ESRI Shapefile")
  19 + output_ds: ogr.DataSource = shp_driver.CreateDataSource(output)
  20 +
  21 + out_layer:ogr.Layer = output_ds.CreateLayer(layer.GetName(),layer.GetSpatialRef(),layer.GetGeomType())
  22 +
  23 + field_names = ["id","预编号","土地使用者","所有权性质","土地证号","地址","镇区","测量日期","二维码信息","shape_area"]
  24 + scheme = [field for field in layer.schema if field.GetName() in field_names]
  25 +
  26 + out_layer.CreateFields(scheme)
  27 + count = 1000000
  28 +
  29 + i=0
  30 + featureDefn = out_layer.GetLayerDefn()
  31 +
  32 + for f in layer:
  33 + ff :ogr.Feature = f
  34 + new_f = ogr.Feature(featureDefn)
  35 + new_f.SetGeometry(ff.geometry())
  36 + for field in field_names:
  37 + dd = ff.GetFieldIndex(field)
  38 + kkk = ff.GetField(dd)
  39 + new_f.SetField(field,kkk)
  40 + out_layer.CreateFeature(new_f)
  41 + i += 1
  42 + if i==count:
  43 + break
  44 +
  45 + output_ds.Destroy()
  46 +if __name__ == '__main__':
  47 +
  48 + function()
\ No newline at end of file
... ...
... ... @@ -3,3 +3,8 @@
3 3 #createtime: 2021/10/15
4 4 #email: nheweijun@sina.com
5 5
  6 +
  7 +
  8 +kk = {"dpi":"11","cols":"112"}
  9 +
  10 +print(int(kk.get("rows",256)))
\ No newline at end of file
... ...
注册登录 后发表评论