正在显示
16 个修改的文件
包含
296 行增加
和
38 行删除
| @@ -94,6 +94,11 @@ def create_app(): | @@ -94,6 +94,11 @@ def create_app(): | ||
| 94 | # 不检测https | 94 | # 不检测https |
| 95 | os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' | 95 | os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' |
| 96 | 96 | ||
| 97 | + | ||
| 98 | + @app.before_first_request | ||
| 99 | + def init_data(): | ||
| 100 | + pass | ||
| 101 | + | ||
| 97 | # start_schedule() | 102 | # start_schedule() |
| 98 | return app | 103 | return app |
| 99 | 104 |
| @@ -23,7 +23,6 @@ class Api(ApiTemplate): | @@ -23,7 +23,6 @@ class Api(ApiTemplate): | ||
| 23 | res["result"] = False | 23 | res["result"] = False |
| 24 | try: | 24 | try: |
| 25 | # 业务逻辑 | 25 | # 业务逻辑 |
| 26 | - | ||
| 27 | if not Database.query.filter_by(guid=self.para.get("database_guid")).one_or_none(): | 26 | if not Database.query.filter_by(guid=self.para.get("database_guid")).one_or_none(): |
| 28 | res["msg"]="数据库不存在!" | 27 | res["msg"]="数据库不存在!" |
| 29 | return res | 28 | return res |
| @@ -86,7 +86,7 @@ class Api(ApiTemplate): | @@ -86,7 +86,7 @@ class Api(ApiTemplate): | ||
| 86 | task_writer = TaskWriter(task_guid) | 86 | task_writer = TaskWriter(task_guid) |
| 87 | 87 | ||
| 88 | #进入创建金字塔的状态 | 88 | #进入创建金字塔的状态 |
| 89 | - task_guid.sys_session.query(Image).filter_by(guid=image_guid).update({"has_pyramid": -1}) | 89 | + task_writer.session.query(Image).filter_by(guid=image_guid).update({"has_pyramid": -1}) |
| 90 | task_writer.update_task({"state": 2}) | 90 | task_writer.update_task({"state": 2}) |
| 91 | 91 | ||
| 92 | #所有数据节点的影像都要建金字塔 | 92 | #所有数据节点的影像都要建金字塔 |
| @@ -155,6 +155,7 @@ class ImageWMTSServer(ImageServer): | @@ -155,6 +155,7 @@ class ImageWMTSServer(ImageServer): | ||
| 155 | if not tile_scheme: | 155 | if not tile_scheme: |
| 156 | raise Exception("切片方案不存在!") | 156 | raise Exception("切片方案不存在!") |
| 157 | tile_scheme = ModelVisitor.object_to_json(tile_scheme) | 157 | tile_scheme = ModelVisitor.object_to_json(tile_scheme) |
| 158 | + | ||
| 158 | xml = '''<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0"> | 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"> |
| 159 | <!-- Service Identification --> | 160 | <!-- Service Identification --> |
| 160 | <ows:ServiceIdentification> | 161 | <ows:ServiceIdentification> |
| @@ -137,7 +137,11 @@ class ImageService(db.Model): | @@ -137,7 +137,11 @@ class ImageService(db.Model): | ||
| 137 | __tablename__ = 'dmap_image_service' | 137 | __tablename__ = 'dmap_image_service' |
| 138 | guid = Column(String(256), primary_key=True) | 138 | guid = Column(String(256), primary_key=True) |
| 139 | name = Column(String,unique = True) | 139 | name = Column(String,unique = True) |
| 140 | + #切片方案 | ||
| 141 | + scheme = Column(Text) | ||
| 142 | + | ||
| 140 | scheme_guid = Column(String) | 143 | scheme_guid = Column(String) |
| 144 | + | ||
| 141 | extent = Column(String(256)) | 145 | extent = Column(String(256)) |
| 142 | # node = Column(Integer) | 146 | # node = Column(Integer) |
| 143 | #可视范围geojson | 147 | #可视范围geojson |
| @@ -173,9 +177,7 @@ class ImageTag(db.Model): | @@ -173,9 +177,7 @@ class ImageTag(db.Model): | ||
| 173 | images = db.relationship('Image', | 177 | images = db.relationship('Image', |
| 174 | secondary=dmap_image_tag_rel, | 178 | secondary=dmap_image_tag_rel, |
| 175 | backref='image_tags', | 179 | backref='image_tags', |
| 176 | - lazy='dynamic' | ||
| 177 | - ) | ||
| 178 | - | 180 | + lazy='dynamic') |
| 179 | 181 | ||
| 180 | class TileService(db.Model): | 182 | class TileService(db.Model): |
| 181 | ''' | 183 | ''' |
| @@ -217,6 +219,9 @@ class TileService(db.Model): | @@ -217,6 +219,9 @@ class TileService(db.Model): | ||
| 217 | #图层描述 | 219 | #图层描述 |
| 218 | layer_description = Column(String) | 220 | layer_description = Column(String) |
| 219 | 221 | ||
| 222 | + #切片方案 | ||
| 223 | + scheme = Column(Text) | ||
| 224 | + | ||
| 220 | scheme_guid = Column(String,ForeignKey('dmap_tile_scheme.guid')) | 225 | scheme_guid = Column(String,ForeignKey('dmap_tile_scheme.guid')) |
| 221 | service_guid = Column(String,ForeignKey('dmap_service.guid')) | 226 | service_guid = Column(String,ForeignKey('dmap_service.guid')) |
| 222 | 227 |
| @@ -68,6 +68,12 @@ class Api(ApiTemplate): | @@ -68,6 +68,12 @@ class Api(ApiTemplate): | ||
| 68 | "in": "formData", | 68 | "in": "formData", |
| 69 | "type": "string", | 69 | "type": "string", |
| 70 | "description": "[切片服务,影像服务]切片方案"}, | 70 | "description": "[切片服务,影像服务]切片方案"}, |
| 71 | + | ||
| 72 | + {"name": "scheme_guid", | ||
| 73 | + "in": "formData", | ||
| 74 | + "type": "string", | ||
| 75 | + "description": "[切片服务,影像服务]切片方案"}, | ||
| 76 | + | ||
| 71 | {"name": "functions", | 77 | {"name": "functions", |
| 72 | "in": "formData", | 78 | "in": "formData", |
| 73 | "type": "string", | 79 | "type": "string", |
| @@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
| 7 | from flasgger import swag_from | 7 | from flasgger import swag_from |
| 8 | from flask import Blueprint | 8 | from flask import Blueprint |
| 9 | from app.util import BlueprintApi | 9 | from app.util import BlueprintApi |
| 10 | -from . import upload_oview,tile_service_register,tile_service_edit | 10 | +from . import upload_oview,tile_service_register,tile_service_edit,tile_service_reload |
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | 13 | ||
| @@ -45,3 +45,12 @@ class DataManager(BlueprintApi): | @@ -45,3 +45,12 @@ class DataManager(BlueprintApi): | ||
| 45 | """ | 45 | """ |
| 46 | return tile_service_edit.Api().result | 46 | return tile_service_edit.Api().result |
| 47 | 47 | ||
| 48 | + @staticmethod | ||
| 49 | + @bp.route('/Reload', methods=['GET']) | ||
| 50 | + @swag_from(tile_service_reload.Api.api_doc) | ||
| 51 | + def api_tile_service_reload(): | ||
| 52 | + """ | ||
| 53 | + TileService Reload | ||
| 54 | + """ | ||
| 55 | + return tile_service_reload.Api().result | ||
| 56 | + |
| @@ -4,11 +4,15 @@ | @@ -4,11 +4,15 @@ | ||
| 4 | #email: nheweijun@sina.com | 4 | #email: nheweijun@sina.com |
| 5 | 5 | ||
| 6 | from app.util.component.ApiTemplate import ApiTemplate | 6 | from app.util.component.ApiTemplate import ApiTemplate |
| 7 | +from app.util.component.ModelVisitor import ModelVisitor | ||
| 7 | import uuid | 8 | import uuid |
| 8 | from ..models import TileService,Service,db,ServiceFunction | 9 | from ..models import TileService,Service,db,ServiceFunction |
| 10 | +import datetime | ||
| 11 | +import requests | ||
| 12 | +from .util.ProjectFile import ProjectFile | ||
| 9 | 13 | ||
| 14 | +from requests import Response | ||
| 10 | 15 | ||
| 11 | -import datetime | ||
| 12 | class Api(ApiTemplate): | 16 | class Api(ApiTemplate): |
| 13 | 17 | ||
| 14 | api_name = "修改切片服务" | 18 | api_name = "修改切片服务" |
| @@ -25,7 +29,6 @@ class Api(ApiTemplate): | @@ -25,7 +29,6 @@ class Api(ApiTemplate): | ||
| 25 | service = Service.query.filter_by(guid=guid) | 29 | service = Service.query.filter_by(guid=guid) |
| 26 | this_time = datetime.datetime.now() | 30 | this_time = datetime.datetime.now() |
| 27 | 31 | ||
| 28 | - | ||
| 29 | service_update = {"update_time":this_time} | 32 | service_update = {"update_time":this_time} |
| 30 | tile_update = {} | 33 | tile_update = {} |
| 31 | for key in self.para.keys(): | 34 | for key in self.para.keys(): |
| @@ -36,10 +39,27 @@ class Api(ApiTemplate): | @@ -36,10 +39,27 @@ class Api(ApiTemplate): | ||
| 36 | "layer_extent","layer_description","scheme_guid"]: | 39 | "layer_extent","layer_description","scheme_guid"]: |
| 37 | tile_update[key] = self.para.get(key) | 40 | tile_update[key] = self.para.get(key) |
| 38 | 41 | ||
| 39 | - tile_service = TileService.query.filter_by(service_guid=guid) | 42 | + #通知tileserver,更新缓存 |
| 43 | + ts = TileService.query.filter_by(service_guid=guid).one_or_none() | ||
| 44 | + se = service.one_or_none() | ||
| 40 | 45 | ||
| 41 | - tile_type = self.para.get("tile_type") | 46 | + ts_json = ModelVisitor.object_to_json(ts) |
| 47 | + ts_json.update(tile_update) | ||
| 48 | + project_file = ProjectFile.create(ts_json) | ||
| 49 | + | ||
| 50 | + para = {"name":self.para.get("name") if self.para.get("name") else se.name, | ||
| 51 | + "title":self.para.get("title") if self.para.get("title") else se.title, | ||
| 52 | + "type":"tileserver","capabilities":1,"project":project_file} | ||
| 53 | + | ||
| 54 | + tile_service_edit_url = "" | ||
| 42 | 55 | ||
| 56 | + resp: Response = requests.post(tile_service_edit_url,para).json() | ||
| 57 | + if not resp.json()["status"].__eq__("true"): | ||
| 58 | + raise Exception("调用切片服务的注册服务接口失败!") | ||
| 59 | + | ||
| 60 | + #修改数据库 | ||
| 61 | + tile_service = TileService.query.filter_by(service_guid=guid) | ||
| 62 | + tile_type = self.para.get("tile_type") | ||
| 43 | # 修改功能 | 63 | # 修改功能 |
| 44 | if tile_type: | 64 | if tile_type: |
| 45 | old_functions = ServiceFunction.query.filter_by(service_guid=guid).all() | 65 | old_functions = ServiceFunction.query.filter_by(service_guid=guid).all() |
| @@ -57,8 +77,8 @@ class Api(ApiTemplate): | @@ -57,8 +77,8 @@ class Api(ApiTemplate): | ||
| 57 | tile_service.update(tile_update) | 77 | tile_service.update(tile_update) |
| 58 | 78 | ||
| 59 | db.session.commit() | 79 | db.session.commit() |
| 60 | - | ||
| 61 | res["result"] = True | 80 | res["result"] = True |
| 81 | + | ||
| 62 | except Exception as e: | 82 | except Exception as e: |
| 63 | raise e | 83 | raise e |
| 64 | 84 | ||
| @@ -67,11 +87,14 @@ class Api(ApiTemplate): | @@ -67,11 +87,14 @@ class Api(ApiTemplate): | ||
| 67 | api_doc = { | 87 | api_doc = { |
| 68 | "tags": ["切片服务接口"], | 88 | "tags": ["切片服务接口"], |
| 69 | "parameters": [ | 89 | "parameters": [ |
| 90 | + {"name": "guid", | ||
| 91 | + "in": "formData", | ||
| 92 | + "type": "string", | ||
| 93 | + "description": "service guid"}, | ||
| 70 | 94 | ||
| 71 | {"name": "name", | 95 | {"name": "name", |
| 72 | "in": "formData", | 96 | "in": "formData", |
| 73 | "type": "string", | 97 | "type": "string", |
| 74 | - "required": "true", | ||
| 75 | "description": "[地图服务,切片服务,影像服务]"}, | 98 | "description": "[地图服务,切片服务,影像服务]"}, |
| 76 | {"name": "title", | 99 | {"name": "title", |
| 77 | "in": "formData", | 100 | "in": "formData", |
| @@ -5,14 +5,17 @@ | @@ -5,14 +5,17 @@ | ||
| 5 | 5 | ||
| 6 | 6 | ||
| 7 | from app.util.component.ApiTemplate import ApiTemplate | 7 | from app.util.component.ApiTemplate import ApiTemplate |
| 8 | +from app.util.component.ModelVisitor import ModelVisitor | ||
| 8 | import uuid | 9 | import uuid |
| 9 | -from ..models import TileService,Service,db,ServiceFunction | 10 | +from ..models import TileService,Service,db,ServiceFunction,TileScheme |
| 10 | 11 | ||
| 11 | import datetime | 12 | import datetime |
| 12 | import configure | 13 | import configure |
| 13 | import requests | 14 | import requests |
| 14 | from requests import Response | 15 | from requests import Response |
| 15 | -import json | 16 | + |
| 17 | +from .util.ProjectFile import ProjectFile | ||
| 18 | + | ||
| 16 | class Api(ApiTemplate): | 19 | class Api(ApiTemplate): |
| 17 | 20 | ||
| 18 | api_name = "注册切片服务" | 21 | api_name = "注册切片服务" |
| @@ -20,16 +23,20 @@ class Api(ApiTemplate): | @@ -20,16 +23,20 @@ class Api(ApiTemplate): | ||
| 20 | def process(self): | 23 | def process(self): |
| 21 | # 返回结果 | 24 | # 返回结果 |
| 22 | res = {} | 25 | res = {} |
| 23 | - | ||
| 24 | try: | 26 | try: |
| 25 | - | ||
| 26 | this_time = datetime.datetime.now() | 27 | this_time = datetime.datetime.now() |
| 27 | service_guid = uuid.uuid1().__str__() | 28 | service_guid = uuid.uuid1().__str__() |
| 28 | tile_service_guid = uuid.uuid1().__str__() | 29 | tile_service_guid = uuid.uuid1().__str__() |
| 29 | service_function_guid = uuid.uuid1().__str__() | 30 | service_function_guid = uuid.uuid1().__str__() |
| 30 | - | ||
| 31 | # 调用切片服务的注册服务接口 | 31 | # 调用切片服务的注册服务接口 |
| 32 | - # 先调用切片服务接口,成功后才持久化 | 32 | + project_file = ProjectFile.create(self.para) |
| 33 | + para = {"name":self.para.get("name"),"title":self.para.get("title"), | ||
| 34 | + "type":"tileserver","capabilities":1,"project":project_file} | ||
| 35 | + tile_service_register_url = "" | ||
| 36 | + | ||
| 37 | + resp: Response = requests.post(tile_service_register_url,para).json() | ||
| 38 | + if not resp.json()["status"].__eq__("true"): | ||
| 39 | + raise Exception("调用切片服务的注册服务接口失败!") | ||
| 33 | 40 | ||
| 34 | service = Service( | 41 | service = Service( |
| 35 | guid = service_guid, | 42 | guid = service_guid, |
| @@ -52,6 +59,8 @@ class Api(ApiTemplate): | @@ -52,6 +59,8 @@ class Api(ApiTemplate): | ||
| 52 | if tile_service_isexist: | 59 | if tile_service_isexist: |
| 53 | db.session.delete(tile_service_isexist) | 60 | db.session.delete(tile_service_isexist) |
| 54 | 61 | ||
| 62 | + tile_scheme: TileScheme = TileScheme.query.filter_by(guid=self.para.get("scheme_guid")).one_or_none() | ||
| 63 | + | ||
| 55 | tile_service = TileService( | 64 | tile_service = TileService( |
| 56 | guid = tile_service_guid, | 65 | guid = tile_service_guid, |
| 57 | name = self.para.get("name"), | 66 | name = self.para.get("name"), |
| @@ -69,8 +78,9 @@ class Api(ApiTemplate): | @@ -69,8 +78,9 @@ class Api(ApiTemplate): | ||
| 69 | layer_extent = self.para.get("layer_extent"), | 78 | layer_extent = self.para.get("layer_extent"), |
| 70 | layer_description = self.para.get("layer_description"), | 79 | layer_description = self.para.get("layer_description"), |
| 71 | scheme_guid = self.para.get("scheme_guid"), | 80 | scheme_guid = self.para.get("scheme_guid"), |
| 81 | + scheme = ModelVisitor.object_to_json(tile_scheme), | ||
| 72 | service_guid = service_guid, | 82 | service_guid = service_guid, |
| 73 | - metadata_url="{}/DMap/Services/{}/MapServer/WMTSServer".format(configure.wmts_url,self.para.get("name")) | 83 | + metadata_url = "{}/DMap/Services/{}/MapServer/WMTSServer".format(configure.wmts_url,self.para.get("name")) |
| 74 | ) | 84 | ) |
| 75 | 85 | ||
| 76 | service_function = ServiceFunction(guid=service_function_guid, | 86 | service_function = ServiceFunction(guid=service_function_guid, |
| @@ -82,18 +92,6 @@ class Api(ApiTemplate): | @@ -82,18 +92,6 @@ class Api(ApiTemplate): | ||
| 82 | db.session.add(service_function) | 92 | db.session.add(service_function) |
| 83 | db.session.commit() | 93 | db.session.commit() |
| 84 | 94 | ||
| 85 | - # 调用切片服务的注册服务接口 | ||
| 86 | - try: | ||
| 87 | - url = "{}/dmap/api/manager/updatecache?servicename={}".format(configure.wmts_url,service.name) | ||
| 88 | - resp:Response = requests.get(url) | ||
| 89 | - if not resp.json()["status"].__eq__("true"): | ||
| 90 | - raise Exception("调用切片服务的注册服务接口失败!") | ||
| 91 | - except Exception as e: | ||
| 92 | - db.session.delete(service) | ||
| 93 | - db.session.delete(tile_service) | ||
| 94 | - db.session.delete(service_function) | ||
| 95 | - db.session.commit() | ||
| 96 | - raise e | ||
| 97 | res["data"] = service_guid | 95 | res["data"] = service_guid |
| 98 | res["result"] = True | 96 | res["result"] = True |
| 99 | except Exception as e: | 97 | except Exception as e: |
| @@ -101,6 +99,7 @@ class Api(ApiTemplate): | @@ -101,6 +99,7 @@ class Api(ApiTemplate): | ||
| 101 | raise e | 99 | raise e |
| 102 | return res | 100 | return res |
| 103 | 101 | ||
| 102 | + | ||
| 104 | api_doc = { | 103 | api_doc = { |
| 105 | "tags": ["切片服务接口"], | 104 | "tags": ["切片服务接口"], |
| 106 | "parameters": [ | 105 | "parameters": [ |
| 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 TileService,db,Service | ||
| 9 | +import configure | ||
| 10 | +from app.util.component.ModelVisitor import ModelVisitor | ||
| 11 | + | ||
| 12 | +from .util.ProjectFile import ProjectFile | ||
| 13 | + | ||
| 14 | +class Api(ApiTemplate): | ||
| 15 | + | ||
| 16 | + api_name = "切片服务reload" | ||
| 17 | + | ||
| 18 | + def process(self): | ||
| 19 | + res = {} | ||
| 20 | + try: | ||
| 21 | + tile_services = TileService.query.join(Service).filter(Service.type=="切片服务").all() | ||
| 22 | + res["data"] = {} | ||
| 23 | + res["data"]["count"] = len(tile_services) | ||
| 24 | + res["data"]["list"] = [] | ||
| 25 | + for ts in tile_services: | ||
| 26 | + project_file = ProjectFile.create(ModelVisitor.object_to_json(ts)) | ||
| 27 | + service:Service = Service.query.filter_by(guid=ts.service_guid).one_or_none() | ||
| 28 | + para = {"name":service.name,"title":service.title, | ||
| 29 | + "type":"tileserver","capabilities":1,"project":project_file} | ||
| 30 | + res["data"]["list"].append(para) | ||
| 31 | + res["result"] = True | ||
| 32 | + except Exception as e: | ||
| 33 | + raise e | ||
| 34 | + return res | ||
| 35 | + | ||
| 36 | + api_doc = { | ||
| 37 | + "tags": ["切片服务接口"], | ||
| 38 | + "parameters": [ | ||
| 39 | + ], | ||
| 40 | + "responses": { | ||
| 41 | + 200: { | ||
| 42 | + "schema": { | ||
| 43 | + "properties": { | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | + } |
| 1 | +# coding=utf-8 | ||
| 2 | +#author: 4N | ||
| 3 | +#createtime: 2021/12/6 | ||
| 4 | +#email: nheweijun@sina.com | ||
| 5 | + | ||
| 6 | + | ||
| 7 | +from app.modules.service.models import TileScheme | ||
| 8 | +from app.util.component.ModelVisitor import ModelVisitor | ||
| 9 | +import json | ||
| 10 | +import base64 | ||
| 11 | + | ||
| 12 | + | ||
| 13 | +class ProjectFile: | ||
| 14 | + | ||
| 15 | + @classmethod | ||
| 16 | + def create(cls,para): | ||
| 17 | + if para.get("tile_type").__eq__("WMTS"): | ||
| 18 | + | ||
| 19 | + if para.get("scheme"): | ||
| 20 | + tile_scheme = json.loads(para.get("scheme")) | ||
| 21 | + else: | ||
| 22 | + tile_scheme: TileScheme = TileScheme.query.filter_by(guid=para.get("scheme_guid")).one_or_none() | ||
| 23 | + if not tile_scheme: | ||
| 24 | + raise Exception("切片方案不存在!") | ||
| 25 | + tile_scheme = ModelVisitor.object_to_json(tile_scheme) | ||
| 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 | + ''' | ||
| 70 | + | ||
| 71 | + level_each = '''<level> | ||
| 72 | + <id>{lev}</id> | ||
| 73 | + <scaleDenominator>{scale}</scaleDenominator> | ||
| 74 | + <resolution>{resolution}</resolution> | ||
| 75 | + </level>''' | ||
| 76 | + | ||
| 77 | + levels = "" | ||
| 78 | + for level in json.loads(tile_scheme.get("levels")): | ||
| 79 | + levels = "{}{}".format(levels, level_each.format(lev=level["level"], | ||
| 80 | + scale=level["scale"], | ||
| 81 | + resolution=level["resolution"], | ||
| 82 | + )) | ||
| 83 | + | ||
| 84 | + layer_extent = para.get("layer_extent").split(",") | ||
| 85 | + | ||
| 86 | + project_xml = project_xml_format.format(wkt="", | ||
| 87 | + proj4="", | ||
| 88 | + srid=para.get("crs").split("::")[-1], | ||
| 89 | + name=para.get("layer_name"), | ||
| 90 | + alias=para.get("alias"), | ||
| 91 | + xmin=layer_extent[0], | ||
| 92 | + xmax=layer_extent[1], | ||
| 93 | + ymin=layer_extent[2], | ||
| 94 | + ymax=layer_extent[3], | ||
| 95 | + layer_style=para.get("layer_style"), | ||
| 96 | + layer_format=para.get("layer_format"), | ||
| 97 | + vendor=para.get("vendor"), | ||
| 98 | + datasource=para.get("datasource"), | ||
| 99 | + crs=para.get("crs"), | ||
| 100 | + cols=tile_scheme.get("cols"), | ||
| 101 | + rows=tile_scheme.get("rows"), | ||
| 102 | + dpi=tile_scheme.get("dpi"), | ||
| 103 | + x=tile_scheme.get("top_left").split(",")[0], | ||
| 104 | + y=tile_scheme.get("top_left").split(",")[1], | ||
| 105 | + levels=levels | ||
| 106 | + ) | ||
| 107 | + else: | ||
| 108 | + | ||
| 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 | + ''' | ||
| 137 | + layer_extent = para.get("layer_extent").split(",") | ||
| 138 | + project_xml = project_xml_format.format(wkt="", | ||
| 139 | + proj4="", | ||
| 140 | + srid=para.get("crs").split("::")[-1], | ||
| 141 | + name=para.get("layer_name"), | ||
| 142 | + alias=para.get("alias"), | ||
| 143 | + xmin=layer_extent[0], | ||
| 144 | + xmax=layer_extent[1], | ||
| 145 | + ymin=layer_extent[2], | ||
| 146 | + ymax=layer_extent[3], | ||
| 147 | + layer_style=para.get("layer_style"), | ||
| 148 | + layer_format=para.get("layer_format"), | ||
| 149 | + vendor=para.get("vendor"), | ||
| 150 | + datasource=para.get("datasource"), | ||
| 151 | + ) | ||
| 152 | + return str(base64.b64encode(project_xml.encode('utf-8')), encoding="utf8") |
| @@ -107,4 +107,10 @@ class PGUtil: | @@ -107,4 +107,10 @@ class PGUtil: | ||
| 107 | 107 | ||
| 108 | @classmethod | 108 | @classmethod |
| 109 | def check_database_privilege(cls,table_name,pri_type,user,session): | 109 | def check_database_privilege(cls,table_name,pri_type,user,session): |
| 110 | - pass | ||
| 110 | + pass | ||
| 111 | + | ||
| 112 | +if __name__ == '__main__': | ||
| 113 | + session:Session = PGUtil.get_db_session("postgresql://postgres:chinadci@172.26.60.100:5432/template1") | ||
| 114 | + result = session.execute("SELECT datname FROM pg_database;") | ||
| 115 | + for re in result: | ||
| 116 | + print(re) |
| @@ -4,8 +4,8 @@ import logging | @@ -4,8 +4,8 @@ import logging | ||
| 4 | deploy_ip_host = "172.26.40.105:8840" | 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_test" | ||
| 8 | -SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@localhost:5433/dmap_dms_test" | 7 | +SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.60.100:5432/dmap_manager" |
| 8 | +# SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@localhost:5433/dmap_dms_test" | ||
| 9 | 9 | ||
| 10 | # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中 | 10 | # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中 |
| 11 | #VACUATE_DB_URI = None | 11 | #VACUATE_DB_URI = None |
| @@ -356,12 +356,14 @@ LoadModule wsgi_module "/usr/lib64/httpd/modules/mod_wsgi-py37.cpython-37m-x86_6 | @@ -356,12 +356,14 @@ LoadModule wsgi_module "/usr/lib64/httpd/modules/mod_wsgi-py37.cpython-37m-x86_6 | ||
| 356 | "/var/gdal" | 356 | "/var/gdal" |
| 357 | 357 | ||
| 358 | dmapmanager processes=4 threads=16 display-name=%{GROUP} | 358 | dmapmanager processes=4 threads=16 display-name=%{GROUP} |
| 359 | + | ||
| 359 | dmapmanager | 360 | dmapmanager |
| 360 | #Authorization请求头顺利转发 | 361 | #Authorization请求头顺利转发 |
| 361 | On | 362 | On |
| 362 | %{GLOBAL} | 363 | %{GLOBAL} |
| 363 | 364 | ||
| 364 | / /usr/src/app/run.wsgi | 365 | / /usr/src/app/run.wsgi |
| 366 | + | ||
| 365 | <Directory /usr/> | 367 | <Directory /usr/> |
| 366 | Require all granted | 368 | Require all granted |
| 367 | </Directory> | 369 | </Directory> |
| @@ -19,7 +19,7 @@ import time | @@ -19,7 +19,7 @@ import time | ||
| 19 | # table="fs900w_1" | 19 | # table="fs900w_1" |
| 20 | # sql ="SELECT geom FROM {} WHERE geom && 'BOX3D({})'::box3d limit 100000".format(table,bbox) | 20 | # sql ="SELECT geom FROM {} WHERE geom && 'BOX3D({})'::box3d limit 100000".format(table,bbox) |
| 21 | 21 | ||
| 22 | - | 22 | +import base64 |
| 23 | def query_thread(): | 23 | def query_thread(): |
| 24 | def get_db_session(db_url, autocommit=False) -> Session: | 24 | def get_db_session(db_url, autocommit=False) -> Session: |
| 25 | engine = create_engine(db_url, pool_size=100) | 25 | engine = create_engine(db_url, pool_size=100) |
| @@ -53,6 +53,5 @@ def query_thread(): | @@ -53,6 +53,5 @@ def query_thread(): | ||
| 53 | ses.close() | 53 | ses.close() |
| 54 | # query_thread() | 54 | # query_thread() |
| 55 | if __name__ == '__main__': | 55 | if __name__ == '__main__': |
| 56 | - kk = [1,2,3,4,5,6,7,8,9,10,11] | ||
| 57 | - print(len(kk)) | ||
| 58 | - print(kk[10:20]) | ||
| 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")) |
请
注册
或
登录
后发表评论