提交 86fa0512be407d0cc4e22c95ea0de8584ddebdb1

作者 nheweijun
1 个父辈 874cc380

2022.01.12 基于新镜像,修复一些bug

正在显示 47 个修改的文件 包含 1099 行增加409 行删除
  1 +From osgeo/gdal:ubuntu-small-3.4.1
1 2
2 3
  4 +WORKDIR /root
  5 +#设置编码
  6 +ENV LANG=en_US.UTF-8
  7 +#设置时区
  8 +ENV TZ=Asia/Shanghai
  9 +
  10 +
  11 +RUN apt-get update
  12 +#安装pip
  13 +RUN apt-get install python3-pip -y
  14 +
  15 +#安装opencv所需依赖库
  16 +RUN apt-get install libgl1-mesa-glx -y
  17 +RUN apt-get install libglib2.0-dev -y
  18 +
  19 +#安装apache2
  20 +RUN apt-get install apache2 -y
  21 +RUN apt-get install apache2-dev -y
  22 +
  23 +
  24 +#安装依赖
  25 +COPY . .
  26 +RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn
  27 +
  28 +
  29 +RUN mod_wsgi-express install-module
  1 +# This is the main Apache server configuration file. It contains the
  2 +# configuration directives that give the server its instructions.
  3 +# See http://httpd.apache.org/docs/2.4/ for detailed information about
  4 +# the directives and /usr/share/doc/apache2/README.Debian about Debian specific
  5 +# hints.
  6 +#
  7 +#
  8 +# Summary of how the Apache 2 configuration works in Debian:
  9 +# The Apache 2 web server configuration in Debian is quite different to
  10 +# upstream's suggested way to configure the web server. This is because Debian's
  11 +# default Apache2 installation attempts to make adding and removing modules,
  12 +# virtual hosts, and extra configuration directives as flexible as possible, in
  13 +# order to make automating the changes and administering the server as easy as
  14 +# possible.
  15 +
  16 +# It is split into several files forming the configuration hierarchy outlined
  17 +# below, all located in the /etc/apache2/ directory:
  18 +#
  19 +# /etc/apache2/
  20 +# |-- apache2.conf
  21 +# | `-- ports.conf
  22 +# |-- mods-enabled
  23 +# | |-- *.load
  24 +# | `-- *.conf
  25 +# |-- conf-enabled
  26 +# | `-- *.conf
  27 +# `-- sites-enabled
  28 +# `-- *.conf
  29 +#
  30 +#
  31 +# * apache2.conf is the main configuration file (this file). It puts the pieces
  32 +# together by including all remaining configuration files when starting up the
  33 +# web server.
  34 +#
  35 +# * ports.conf is always included from the main configuration file. It is
  36 +# supposed to determine listening ports for incoming connections which can be
  37 +# customized anytime.
  38 +#
  39 +# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/
  40 +# directories contain particular configuration snippets which manage modules,
  41 +# global configuration fragments, or virtual host configurations,
  42 +# respectively.
  43 +#
  44 +# They are activated by symlinking available configuration files from their
  45 +# respective *-available/ counterparts. These should be managed by using our
  46 +# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See
  47 +# their respective man pages for detailed information.
  48 +#
  49 +# * The binary is called apache2. Due to the use of environment variables, in
  50 +# the default configuration, apache2 needs to be started/stopped with
  51 +# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
  52 +# work with the default configuration.
  53 +
  54 +
  55 +# Global configuration
  56 +#
  57 +
  58 +#
  59 +# ServerRoot: The top of the directory tree under which the server's
  60 +# configuration, error, and log files are kept.
  61 +#
  62 +# NOTE! If you intend to place this on an NFS (or otherwise network)
  63 +# mounted filesystem then please read the Mutex documentation (available
  64 +# at <URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex>);
  65 +# you will save yourself a lot of trouble.
  66 +#
  67 +# Do NOT add a slash at the end of the directory path.
  68 +#
  69 +#ServerRoot "/etc/apache2"
  70 +
  71 +#
  72 +# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
  73 +#
  74 +#Mutex file:${APACHE_LOCK_DIR} default
  75 +
  76 +#
  77 +# The directory where shm and other runtime files will be stored.
  78 +#
  79 +
  80 +DefaultRuntimeDir ${APACHE_RUN_DIR}
  81 +
  82 +#
  83 +# PidFile: The file in which the server should record its process
  84 +# identification number when it starts.
  85 +# This needs to be set in /etc/apache2/envvars
  86 +#
  87 +PidFile ${APACHE_PID_FILE}
  88 +
  89 +#
  90 +# Timeout: The number of seconds before receives and sends time out.
  91 +#
  92 +Timeout 300
  93 +
  94 +#
  95 +# KeepAlive: Whether or not to allow persistent connections (more than
  96 +# one request per connection). Set to "Off" to deactivate.
  97 +#
  98 +KeepAlive On
  99 +
  100 +#
  101 +# MaxKeepAliveRequests: The maximum number of requests to allow
  102 +# during a persistent connection. Set to 0 to allow an unlimited amount.
  103 +# We recommend you leave this number high, for maximum performance.
  104 +#
  105 +MaxKeepAliveRequests 100
  106 +
  107 +#
  108 +# KeepAliveTimeout: Number of seconds to wait for the next request from the
  109 +# same client on the same connection.
  110 +#
  111 +KeepAliveTimeout 5
  112 +
  113 +
  114 +# These need to be set in /etc/apache2/envvars
  115 +User ${APACHE_RUN_USER}
  116 +Group ${APACHE_RUN_GROUP}
  117 +
  118 +#
  119 +# HostnameLookups: Log the names of clients or just their IP addresses
  120 +# e.g., www.apache.org (on) or 204.62.129.132 (off).
  121 +# The default is off because it'd be overall better for the net if people
  122 +# had to knowingly turn this feature on, since enabling it means that
  123 +# each client request will result in AT LEAST one lookup request to the
  124 +# nameserver.
  125 +#
  126 +HostnameLookups Off
  127 +
  128 +# ErrorLog: The location of the error log file.
  129 +# If you do not specify an ErrorLog directive within a <VirtualHost>
  130 +# container, error messages relating to that virtual host will be
  131 +# logged here. If you *do* define an error logfile for a <VirtualHost>
  132 +# container, that host's errors will be logged there and not here.
  133 +#
  134 +ErrorLog ${APACHE_LOG_DIR}/error.log
  135 +
  136 +#
  137 +# LogLevel: Control the severity of messages logged to the error_log.
  138 +# Available values: trace8, ..., trace1, debug, info, notice, warn,
  139 +# error, crit, alert, emerg.
  140 +# It is also possible to configure the log level for particular modules, e.g.
  141 +# "LogLevel info ssl:warn"
  142 +#
  143 +LogLevel warn
  144 +
  145 +# Include module configuration:
  146 +IncludeOptional mods-enabled/*.load
  147 +IncludeOptional mods-enabled/*.conf
  148 +
  149 +# Include list of ports to listen on
  150 +Include ports.conf
  151 +
  152 +
  153 +# Sets the default security model of the Apache2 HTTPD server. It does
  154 +# not allow access to the root filesystem outside of /usr/share and /var/www.
  155 +# The former is used by web applications packaged in Debian,
  156 +# the latter may be used for local directories served by the web server. If
  157 +# your system is serving content from a sub-directory in /srv you must allow
  158 +# access here, or in any related virtual host.
  159 +<Directory />
  160 + Options FollowSymLinks
  161 + AllowOverride None
  162 + Require all denied
  163 +</Directory>
  164 +
  165 +<Directory /usr/share>
  166 + AllowOverride None
  167 + Require all granted
  168 +</Directory>
  169 +
  170 +<Directory /var/www/>
  171 + Options Indexes FollowSymLinks
  172 + AllowOverride None
  173 + Require all granted
  174 +</Directory>
  175 +
  176 +#<Directory /srv/>
  177 +# Options Indexes FollowSymLinks
  178 +# AllowOverride None
  179 +# Require all granted
  180 +#</Directory>
  181 +
  182 +
  183 +
  184 +
  185 +# AccessFileName: The name of the file to look for in each directory
  186 +# for additional configuration directives. See also the AllowOverride
  187 +# directive.
  188 +#
  189 +AccessFileName .htaccess
  190 +
  191 +#
  192 +# The following lines prevent .htaccess and .htpasswd files from being
  193 +# viewed by Web clients.
  194 +#
  195 +<FilesMatch "^\.ht">
  196 + Require all denied
  197 +</FilesMatch>
  198 +
  199 +
  200 +#
  201 +# The following directives define some format nicknames for use with
  202 +# a CustomLog directive.
  203 +#
  204 +# These deviate from the Common Log Format definitions in that they use %O
  205 +# (the actual bytes sent including headers) instead of %b (the size of the
  206 +# requested file), because the latter makes it impossible to detect partial
  207 +# requests.
  208 +#
  209 +# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
  210 +# Use mod_remoteip instead.
  211 +#
  212 +LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
  213 +LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
  214 +LogFormat "%h %l %u %t \"%r\" %>s %O" common
  215 +LogFormat "%{Referer}i -> %U" referer
  216 +LogFormat "%{User-agent}i" agent
  217 +
  218 +# Include of directories ignores editors' and dpkg's backup files,
  219 +# see README.Debian for details.
  220 +
  221 +# Include generic snippets of statements
  222 +IncludeOptional conf-enabled/*.conf
  223 +
  224 +# Include the virtual host configurations:
  225 +IncludeOptional sites-enabled/*.conf
  226 +
  227 +LoadModule wsgi_module "/usr/lib/apache2/modules/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so"
  228 +WSGIPythonHome "/usr"
@@ -17,6 +17,7 @@ from . import database_edit @@ -17,6 +17,7 @@ from . import database_edit
17 from . import database_alias_check 17 from . import database_alias_check
18 from . import database_connect_test 18 from . import database_connect_test
19 from . import database_info 19 from . import database_info
  20 +from . import database_detail
20 21
21 class DataManager(BlueprintApi): 22 class DataManager(BlueprintApi):
22 23
@@ -88,10 +89,19 @@ class DataManager(BlueprintApi): @@ -88,10 +89,19 @@ class DataManager(BlueprintApi):
88 89
89 90
90 @staticmethod 91 @staticmethod
91 - @bp.route('/Info', methods=['POST']) 92 + @bp.route('/Info', methods=["POST"])
92 @swag_from(database_info.Api.api_doc) 93 @swag_from(database_info.Api.api_doc)
93 def api_database_info(): 94 def api_database_info():
94 """ 95 """
95 数据源信息 96 数据源信息
96 """ 97 """
97 - return database_info.Api().result  
  98 + return database_info.Api().result
  99 +
  100 + @staticmethod
  101 + @bp.route('/Detail', methods=["POST"])
  102 + @swag_from(database_detail.Api.api_doc)
  103 + def api_database_detail():
  104 + """
  105 + 数据源detail
  106 + """
  107 + return database_detail.Api().result
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/3/9
  4 +#email: nheweijun@sina.com
  5 +
  6 +
  7 +from ..models import Database
  8 +from app.util.component.ApiTemplate import ApiTemplate
  9 +from app.util.component.ModelVisitor import ModelVisitor
  10 +
  11 +
  12 +class Api(ApiTemplate):
  13 + api_name = "获取数据库Detial"
  14 + def process(self):
  15 + # 返回结果
  16 + res = {}
  17 + try:
  18 + # 业务逻辑
  19 + database_guid = self.para.get("guid")
  20 + database = Database.query.filter_by(guid=database_guid).one_or_none()
  21 + if not database:
  22 + raise Exception("数据库不存在!")
  23 +
  24 + res["data"] = ModelVisitor.object_to_json(database)
  25 + res["result"] = True
  26 + except Exception as e:
  27 + raise e
  28 + return res
  29 +
  30 + api_doc={
  31 + "tags":["数据库接口"],
  32 + "parameters":[
  33 + {"name": "guid",
  34 + "in": "formData",
  35 + "type": "string", "description": "数据库guid"}
  36 + ],
  37 + "responses":{
  38 + 200:{
  39 + "schema":{
  40 + "properties":{
  41 + }
  42 + }
  43 + }
  44 + }
  45 + }
@@ -93,4 +93,4 @@ class Api(ApiTemplate): @@ -93,4 +93,4 @@ class Api(ApiTemplate):
93 } 93 }
94 } 94 }
95 } 95 }
96 - } 96 + }
@@ -45,11 +45,13 @@ class Api(ApiTemplate): @@ -45,11 +45,13 @@ class Api(ApiTemplate):
45 datab_json = ModelVisitor.database_to_json(datab) 45 datab_json = ModelVisitor.database_to_json(datab)
46 datab_json["table_count"] = table_count 46 datab_json["table_count"] = table_count
47 datab_json["available"] = available 47 datab_json["available"] = available
  48 + del datab_json["connectstr"]
48 res["data"]["list"].append(datab_json) 49 res["data"]["list"].append(datab_json)
49 50
50 # 可用非可用排序 51 # 可用非可用排序
51 sorted_list = [dat for dat in res["data"]["list"] if dat["available"]==1] 52 sorted_list = [dat for dat in res["data"]["list"] if dat["available"]==1]
52 sorted_list.extend([dat for dat in res["data"]["list"] if dat["available"] == -1]) 53 sorted_list.extend([dat for dat in res["data"]["list"] if dat["available"] == -1])
  54 +
53 res["data"]["list"] = sorted_list 55 res["data"]["list"] = sorted_list
54 res["result"]=True 56 res["result"]=True
55 except Exception as e: 57 except Exception as e:
@@ -14,7 +14,7 @@ from . import feature_delete @@ -14,7 +14,7 @@ from . import feature_delete
14 from . import feature_schema 14 from . import feature_schema
15 from . import feature_edit 15 from . import feature_edit
16 16
17 -class DataManager(BlueprintApi): 17 +class DataManager():
18 18
19 bp = Blueprint("FeatureService", __name__, url_prefix="/API/FeatureService") 19 bp = Blueprint("FeatureService", __name__, url_prefix="/API/FeatureService")
20 service_type = [] 20 service_type = []
@@ -115,7 +115,7 @@ class Api(ApiTemplate): @@ -115,7 +115,7 @@ class Api(ApiTemplate):
115 115
116 task:Task = task_writer.session.query(Task).filter_by(guid=task_guid).one_or_none() 116 task:Task = task_writer.session.query(Task).filter_by(guid=task_guid).one_or_none()
117 parameter = json.loads(task.parameter) 117 parameter = json.loads(task.parameter)
118 - task_writer.update_task({"state": 2, "prcess": "入库中"}) 118 + task_writer.update_task({"state": 2, "process": "入库中"})
119 119
120 #处理修改入库信息 120 #处理修改入库信息
121 metas: list = json.loads(parameter.get("meta").__str__()) 121 metas: list = json.loads(parameter.get("meta").__str__())
@@ -132,7 +132,7 @@ class Api(ApiTemplate): @@ -132,7 +132,7 @@ class Api(ApiTemplate):
132 origin_name = layer_name 132 origin_name = layer_name
133 no = 1 133 no = 1
134 134
135 - while (overwrite.__eq__("no") and pg_ds.GetLayerByName(layer_name)) or sys_session.query( 135 + while (overwrite.__eq__("no") and pg_ds.GetLayerByName(layer_name)) or task_writer.session.query(
136 InsertingLayerName).filter_by(name=layer_name).one_or_none(): 136 InsertingLayerName).filter_by(name=layer_name).one_or_none():
137 layer_name = origin_name + "_{}".format(no) 137 layer_name = origin_name + "_{}".format(no)
138 no += 1 138 no += 1
@@ -23,6 +23,7 @@ from . import table_vacuate_info @@ -23,6 +23,7 @@ from . import table_vacuate_info
23 from . import table_vacuate_ref 23 from . import table_vacuate_ref
24 from . import table_vacuate_delete 24 from . import table_vacuate_delete
25 from . import field_value 25 from . import field_value
  26 +from . import table_check
26 class DataManager(BlueprintApi): 27 class DataManager(BlueprintApi):
27 28
28 bp = Blueprint("DataManager", __name__, url_prefix="/API/Manager") 29 bp = Blueprint("DataManager", __name__, url_prefix="/API/Manager")
@@ -93,6 +94,15 @@ class DataManager(BlueprintApi): @@ -93,6 +94,15 @@ class DataManager(BlueprintApi):
93 """ 94 """
94 return table_info.Api().result 95 return table_info.Api().result
95 96
  97 + @staticmethod
  98 + @bp.route('/TableCheck', methods=['POST'])
  99 + @swag_from(table_check.Api.api_doc)
  100 + def table_check():
  101 + """
  102 + 检查表是否存在
  103 + """
  104 + return table_check.Api().result
  105 +
96 106
97 @staticmethod 107 @staticmethod
98 @bp.route('/TableRefresh', methods=['POST']) 108 @bp.route('/TableRefresh', methods=['POST'])
  1 +#author: 4N
  2 +#createtime: 2021/1/27
  3 +#email: nheweijun@sina.com
  4 +
  5 +from ..models import Table,DES,Database
  6 +from app.util.component.ApiTemplate import ApiTemplate
  7 +from app.util.component.PGUtil import PGUtil
  8 +from osgeo.ogr import Layer
  9 +
  10 +class Api(ApiTemplate):
  11 +
  12 + api_name = "检查表是否存在"
  13 +
  14 + def process(self):
  15 + res = {}
  16 + pg_ds = None
  17 + try:
  18 + table_names = self.para.get("table_names")
  19 + database_guid = self.para.get("database_guid")
  20 +
  21 + res["data"] = []
  22 + database = Database.query.filter_by(guid=database_guid).one_or_none()
  23 + if not database:
  24 + raise Exception("数据源不存在!")
  25 + pg_ds = PGUtil.open_pg_data_source(0, DES.decode(database.sqlalchemy_uri))
  26 + if not pg_ds:
  27 + raise Exception("数据源连接失败!")
  28 +
  29 + for table_name in table_names.split(","):
  30 +
  31 + layer:Layer = pg_ds.GetLayerByName(table_name)
  32 + table = Table.query.filter_by(database_guid=database_guid,name=table_name).one_or_none()
  33 +
  34 +
  35 + if table and layer:
  36 + exist = True
  37 + table_guid = table.guid
  38 + else:
  39 + exist = False
  40 + table_guid = None
  41 +
  42 + res["data"].append({"table_name": table_name, "exist": exist,"table_guid":table_guid})
  43 +
  44 +
  45 + res["result"] = True
  46 +
  47 + except Exception as e:
  48 + raise e
  49 + finally:
  50 + if pg_ds:
  51 + try:
  52 + pg_ds.Destroy()
  53 + except:
  54 + pass
  55 + return res
  56 +
  57 + api_doc={
  58 + "tags":["管理接口"],
  59 + "parameters":[
  60 + {"name": "table_names",
  61 + "in": "formData",
  62 + "type": "string",
  63 + "description": "表table_names,多个用,相隔","required":"true"},
  64 + {"name": "database_guid",
  65 + "in": "formData",
  66 + "type": "string",
  67 + "description": "database guid", "required": "true"},
  68 + ],
  69 + "responses":{
  70 + 200:{
  71 + "schema":{
  72 + "properties":{
  73 + }
  74 + }
  75 + }
  76 + }
  77 + }
@@ -58,7 +58,7 @@ class Api(ApiTemplate): @@ -58,7 +58,7 @@ class Api(ApiTemplate):
58 58
59 if Task.query.filter_by(table_guid=table_guid,state=0).one_or_none(): 59 if Task.query.filter_by(table_guid=table_guid,state=0).one_or_none():
60 res["result"] = False 60 res["result"] = False
61 - res["msg"] = "数据精化中!" 61 + res["msg"] = "矢量金字塔构建中!"
62 return res 62 return res
63 if table.table_type==0: 63 if table.table_type==0:
64 res["result"] = False 64 res["result"] = False
@@ -73,7 +73,7 @@ class Api(ApiTemplate): @@ -73,7 +73,7 @@ class Api(ApiTemplate):
73 73
74 74
75 task = Task(guid=task_guid, 75 task = Task(guid=task_guid,
76 - name="{}精化".format(table.name), 76 + name="{}矢量金字塔构建".format(table.name),
77 table_guid=table_guid, 77 table_guid=table_guid,
78 create_time=datetime.datetime.now(), 78 create_time=datetime.datetime.now(),
79 state=0, 79 state=0,
@@ -81,14 +81,14 @@ class Api(ApiTemplate): @@ -81,14 +81,14 @@ class Api(ApiTemplate):
81 creator=self.para.get("creator"), 81 creator=self.para.get("creator"),
82 file_name=None, 82 file_name=None,
83 database_guid=table.database_guid, 83 database_guid=table.database_guid,
84 - process="精化中", 84 + process="构建中",
85 task_pid= vacuate_process.pid 85 task_pid= vacuate_process.pid
86 # parameter=",".join([str(x) for x in ref_grids]) 86 # parameter=",".join([str(x) for x in ref_grids])
87 ) 87 )
88 88
89 db.session.add(task) 89 db.session.add(task)
90 db.session.commit() 90 db.session.commit()
91 - res["msg"] = "图层抽稀已提交!" 91 + res["msg"] = "矢量金字塔构建已提交!"
92 res["data"] = task_guid 92 res["data"] = task_guid
93 res["result"] = True 93 res["result"] = True
94 94
@@ -113,8 +113,8 @@ class Api(ApiTemplate): @@ -113,8 +113,8 @@ class Api(ApiTemplate):
113 task_writer = TaskWriter(task_guid) 113 task_writer = TaskWriter(task_guid)
114 114
115 task_writer.update_table(table.guid,{"is_vacuate": 2, "update_time": datetime.datetime.now()}) 115 task_writer.update_table(table.guid,{"is_vacuate": 2, "update_time": datetime.datetime.now()})
116 - task_writer.update_task({"state":2,"process":"精华中"})  
117 - task_writer.update_process("开始精化...") 116 + task_writer.update_task({"state":2,"process":"构建中"})
  117 + task_writer.update_process("开始构建...")
118 118
119 database = task_writer.session.query(Database).filter_by(guid=table.database_guid).one_or_none() 119 database = task_writer.session.query(Database).filter_by(guid=table.database_guid).one_or_none()
120 database_sqlalchemy_uri = str(database.sqlalchemy_uri) 120 database_sqlalchemy_uri = str(database.sqlalchemy_uri)
@@ -167,13 +167,13 @@ class Api(ApiTemplate): @@ -167,13 +167,13 @@ class Api(ApiTemplate):
167 connectstr=DES.encode(connectstr)) 167 connectstr=DES.encode(connectstr))
168 task_writer.session.add(table_vacuate) 168 task_writer.session.add(table_vacuate)
169 169
170 - task_writer.update_task({"state":1,"update_time":datetime.datetime.now(),"process": "精化完成"}) 170 + task_writer.update_task({"state":1,"update_time":datetime.datetime.now(),"process": "构建完成"})
171 task_writer.update_table(table.guid, {"is_vacuate": 1, "update_time": datetime.datetime.now()}) 171 task_writer.update_table(table.guid, {"is_vacuate": 1, "update_time": datetime.datetime.now()})
172 - task_writer.update_process("精化完成!") 172 + task_writer.update_process("构建完成!")
173 173
174 except Exception as e: 174 except Exception as e:
175 try: 175 try:
176 - task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "精化失败"}) 176 + task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "构建失败"})
177 task_writer.update_table(table.guid, {"is_vacuate": 0, "update_time": datetime.datetime.now()}) 177 task_writer.update_table(table.guid, {"is_vacuate": 0, "update_time": datetime.datetime.now()})
178 task_writer.update_process( e.__str__()) 178 task_writer.update_process( e.__str__())
179 task_writer.update_process("任务中止!") 179 task_writer.update_process("任务中止!")
@@ -58,7 +58,7 @@ class Api(ApiTemplate): @@ -58,7 +58,7 @@ class Api(ApiTemplate):
58 58
59 if Task.query.filter_by(table_guid=table_guid,state=0).one_or_none(): 59 if Task.query.filter_by(table_guid=table_guid,state=0).one_or_none():
60 res["result"] = False 60 res["result"] = False
61 - res["msg"] = "数据精化中!" 61 + res["msg"] = "矢量金字塔构建中!"
62 return res 62 return res
63 if table.table_type==0: 63 if table.table_type==0:
64 res["result"] = False 64 res["result"] = False
@@ -73,7 +73,7 @@ class Api(ApiTemplate): @@ -73,7 +73,7 @@ class Api(ApiTemplate):
73 73
74 74
75 task = Task(guid=task_guid, 75 task = Task(guid=task_guid,
76 - name="{}精化,网格大小:{}".format(table.name,self.para.get("grids")), 76 + name="{}矢量金字塔构建,网格大小:{}".format(table.name,self.para.get("grids")),
77 table_guid=table_guid, 77 table_guid=table_guid,
78 create_time=datetime.datetime.now(), 78 create_time=datetime.datetime.now(),
79 state=0, 79 state=0,
@@ -81,13 +81,13 @@ class Api(ApiTemplate): @@ -81,13 +81,13 @@ class Api(ApiTemplate):
81 creator=self.para.get("creator"), 81 creator=self.para.get("creator"),
82 file_name=None, 82 file_name=None,
83 database_guid=table.database_guid, 83 database_guid=table.database_guid,
84 - process="精化中", 84 + process="构建中",
85 parameter=self.para.get("grids"), 85 parameter=self.para.get("grids"),
86 task_pid=vacuate_process.pid) 86 task_pid=vacuate_process.pid)
87 87
88 db.session.add(task) 88 db.session.add(task)
89 db.session.commit() 89 db.session.commit()
90 - res["msg"] = "图层抽稀已提交!" 90 + res["msg"] = "矢量金字塔构建已提交!"
91 res["data"] = task_guid 91 res["data"] = task_guid
92 res["result"] = True 92 res["result"] = True
93 93
@@ -113,8 +113,8 @@ class Api(ApiTemplate): @@ -113,8 +113,8 @@ class Api(ApiTemplate):
113 task_writer = TaskWriter(task_guid) 113 task_writer = TaskWriter(task_guid)
114 114
115 task_writer.update_table(table.guid,{"is_vacuate": 2, "update_time": datetime.datetime.now()}) 115 task_writer.update_table(table.guid,{"is_vacuate": 2, "update_time": datetime.datetime.now()})
116 - task_writer.update_task({"state":2,"process":"精华中"})  
117 - task_writer.update_process("开始精化...") 116 + task_writer.update_task({"state":2,"process":"构建中"})
  117 + task_writer.update_process("开始构建...")
118 118
119 database = task_writer.session.query(Database).filter_by(guid=table.database_guid).one_or_none() 119 database = task_writer.session.query(Database).filter_by(guid=table.database_guid).one_or_none()
120 database_sqlalchemy_uri = str(database.sqlalchemy_uri) 120 database_sqlalchemy_uri = str(database.sqlalchemy_uri)
@@ -168,13 +168,13 @@ class Api(ApiTemplate): @@ -168,13 +168,13 @@ class Api(ApiTemplate):
168 pixel_distance=vacuate_process.this_gridsize[l], 168 pixel_distance=vacuate_process.this_gridsize[l],
169 connectstr=DES.encode(connectstr)) 169 connectstr=DES.encode(connectstr))
170 task_writer.session.add(table_vacuate) 170 task_writer.session.add(table_vacuate)
171 - task_writer.update_task({"state":1,"update_time":datetime.datetime.now(),"process" : "精化完成"}) 171 + task_writer.update_task({"state":1,"update_time":datetime.datetime.now(),"process" : "构建完成"})
172 task_writer.update_table(table.guid,{"is_vacuate": 1, "update_time": datetime.datetime.now()}) 172 task_writer.update_table(table.guid,{"is_vacuate": 1, "update_time": datetime.datetime.now()})
173 - task_writer.update_process("精化完成!") 173 + task_writer.update_process("构建完成!")
174 174
175 except Exception as e: 175 except Exception as e:
176 try: 176 try:
177 - task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "精化失败"}) 177 + task_writer.update_task({"state": -1,"update_time":datetime.datetime.now(),"process": "构建失败"})
178 task_writer.update_table(table.guid, {"is_vacuate": origin_vacuate, "update_time": datetime.datetime.now()}) 178 task_writer.update_table(table.guid, {"is_vacuate": origin_vacuate, "update_time": datetime.datetime.now()})
179 task_writer.update_process( e.__str__()) 179 task_writer.update_process( e.__str__())
180 task_writer.update_process("任务中止!") 180 task_writer.update_process("任务中止!")
@@ -8,7 +8,7 @@ from ..models import Table,Database,DES @@ -8,7 +8,7 @@ from ..models import Table,Database,DES
8 from sqlalchemy.engine import ResultProxy 8 from sqlalchemy.engine import ResultProxy
9 from app.util.component.ApiTemplate import ApiTemplate 9 from app.util.component.ApiTemplate import ApiTemplate
10 from app.util.component.PGUtil import PGUtil 10 from app.util.component.PGUtil import PGUtil
11 - 11 +import json
12 class Api(ApiTemplate): 12 class Api(ApiTemplate):
13 api_name = "数据浏览" 13 api_name = "数据浏览"
14 def process(self): 14 def process(self):
@@ -35,27 +35,35 @@ class Api(ApiTemplate): @@ -35,27 +35,35 @@ class Api(ApiTemplate):
35 35
36 res["data"]["count"]=PGUtil.get_table_count(table.name,db_session) 36 res["data"]["count"]=PGUtil.get_table_count(table.name,db_session)
37 37
  38 + pkey = PGUtil.get_pkey(table.name,db_session)
  39 +
38 res["data"]["list"]=[] 40 res["data"]["list"]=[]
39 for row_proxy in query_result: 41 for row_proxy in query_result:
  42 + pkey_dict = {}
40 d = {} 43 d = {}
41 for column, value in row_proxy.items(): 44 for column, value in row_proxy.items():
42 #跳过空间列 45 #跳过空间列
43 if geom_col: 46 if geom_col:
44 if column.__eq__(geom_col): 47 if column.__eq__(geom_col):
45 continue 48 continue
  49 + if pkey:
  50 + if column == pkey:
  51 + pkey_dict[column]=value
  52 + continue
46 #格式化时间列 53 #格式化时间列
47 if isinstance(value, datetime.datetime): 54 if isinstance(value, datetime.datetime):
48 d[column] = value.strftime('%Y-%m-%d %H:%M:%S') 55 d[column] = value.strftime('%Y-%m-%d %H:%M:%S')
49 else: 56 else:
50 d[column]=value 57 d[column]=value
51 - res["data"]["list"].append(d) 58 + pkey_dict.update(d)
  59 + res["data"]["list"].append(pkey_dict)
52 res["result"]=True 60 res["result"]=True
53 except Exception as e: 61 except Exception as e:
54 raise Exception("数据库连接失败!") 62 raise Exception("数据库连接失败!")
55 finally: 63 finally:
56 if db_session: 64 if db_session:
57 db_session.close() 65 db_session.close()
58 - return res 66 + return json.dumps(res)
59 67
60 api_doc={ 68 api_doc={
61 "tags":["管理接口"], 69 "tags":["管理接口"],
@@ -73,7 +73,7 @@ class Api(ApiTemplate): @@ -73,7 +73,7 @@ class Api(ApiTemplate):
73 task_process = Process(guid=uuid.uuid1().__str__(), message=message, time=datetime.datetime.now(), 73 task_process = Process(guid=uuid.uuid1().__str__(), message=message, time=datetime.datetime.now(),
74 task_guid=task.guid) 74 task_guid=task.guid)
75 75
76 - db.add(task_process) 76 + db.session.add(task_process)
77 db.session.commit() 77 db.session.commit()
78 return None 78 return None
79 79
@@ -14,6 +14,7 @@ from . import service_delete @@ -14,6 +14,7 @@ from . import service_delete
14 from . import service_state 14 from . import service_state
15 from . import service_info 15 from . import service_info
16 from . import service_edit 16 from . import service_edit
  17 +from . import service_reload
17 import os 18 import os
18 from flask import send_from_directory 19 from flask import send_from_directory
19 20
@@ -88,6 +89,14 @@ class DataManager(BlueprintApi): @@ -88,6 +89,14 @@ class DataManager(BlueprintApi):
88 """ 89 """
89 return service_edit.Api().result 90 return service_edit.Api().result
90 91
  92 + @staticmethod
  93 + @bp.route('/Reload', methods=['POST','GET'])
  94 + @swag_from(service_reload.Api.api_doc)
  95 + def api_service_reload():
  96 + """
  97 + 服务重载
  98 + """
  99 + return service_reload.Api().result
91 100
92 101
93 @staticmethod 102 @staticmethod
@@ -12,7 +12,7 @@ from . import service_engine_delete @@ -12,7 +12,7 @@ from . import service_engine_delete
12 from . import service_engine_edit 12 from . import service_engine_edit
13 from . import service_engine_list 13 from . import service_engine_list
14 from . import service_engine_info 14 from . import service_engine_info
15 - 15 +from . import service_engine_deploy
16 class EngineManager(BlueprintApi): 16 class EngineManager(BlueprintApi):
17 17
18 bp = Blueprint("Engine", __name__, url_prefix="/API/Service/Engine") 18 bp = Blueprint("Engine", __name__, url_prefix="/API/Service/Engine")
@@ -62,3 +62,13 @@ class EngineManager(BlueprintApi): @@ -62,3 +62,13 @@ class EngineManager(BlueprintApi):
62 Engine Delete 62 Engine Delete
63 """ 63 """
64 return service_engine_delete.Api().result 64 return service_engine_delete.Api().result
  65 +
  66 +
  67 + @staticmethod
  68 + @bp.route('/ImageServerDeploy', methods=['GET'])
  69 + @swag_from(service_engine_deploy.Api.api_doc)
  70 + def service_engine_deploy():
  71 + """
  72 + Engine Deploy
  73 + """
  74 + return service_engine_deploy.Api().result
@@ -4,16 +4,21 @@ @@ -4,16 +4,21 @@
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.modules.service.models import ServiceEngine,db 7 +from app.modules.service.models import ServiceEngine,db,Service
8 class Api(ApiTemplate): 8 class Api(ApiTemplate):
9 api_name = "注销服务引擎" 9 api_name = "注销服务引擎"
10 def process(self): 10 def process(self):
11 res = {} 11 res = {}
12 try: 12 try:
13 guid = self.para.get("guid") 13 guid = self.para.get("guid")
14 - service_engine = ServiceEngine.query.filter_by(guid=guid).one_or_none() 14 + service_engine:ServiceEngine = ServiceEngine.query.filter_by(guid=guid).one_or_none()
  15 +
15 if not service_engine: 16 if not service_engine:
16 raise Exception("服务不存在!") 17 raise Exception("服务不存在!")
  18 + if service_engine.type=="AddServer":
  19 + add_service = Service.query.filter_by(url=service_engine.url).one_or_none()
  20 + if add_service:
  21 + db.session.delete(add_service)
17 db.session.delete(service_engine) 22 db.session.delete(service_engine)
18 db.session.commit() 23 db.session.commit()
19 res["result"] = True 24 res["result"] = True
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/9/14
  4 +#email: nheweijun@sina.com
  5 +
  6 +from app.util.component.ApiTemplate import ApiTemplate
  7 +from app.modules.service.models import ServiceEngine
  8 +from app.util.component.StructuredPrint import StructurePrint
  9 +import requests
  10 +import uuid
  11 +
  12 +class Api(ApiTemplate):
  13 +
  14 + api_name = "影像服务引擎Depoly"
  15 +
  16 + def process(self):
  17 + res = {}
  18 + try:
  19 + res["data"] = []
  20 + image_servers = ServiceEngine.query.filter_by(type="ImageServer").all()
  21 + for imgs in image_servers:
  22 + try :
  23 + url = "{}/API/Deploy/Topology".format(imgs.url)
  24 + resp: requests.Response = requests.get(url, timeout=1)
  25 + resp.encoding = "utf-8"
  26 + resp_json = resp.json()
  27 + res["data"].append({"id":uuid.uuid1().__str__(),
  28 + "name":"影像服务器",
  29 + "url":imgs.url,
  30 + "type": 0,
  31 + "children":[{
  32 + "name": "数据服务器",
  33 + "url": ser,
  34 + "type": 1,
  35 + "id":uuid.uuid1().__str__()
  36 + } for ser in resp_json.get("data")]})
  37 + except:
  38 + StructurePrint().print("连接影像服务引擎失败!","error")
  39 + res["result"] = True
  40 + except Exception as e:
  41 + raise e
  42 + return res
  43 +
  44 +
  45 + api_doc = {
  46 + "tags": ["引擎接口"],
  47 + "parameters": [
  48 + ],
  49 + "responses": {
  50 + 200: {
  51 + "schema": {
  52 + "properties": {
  53 + }
  54 + }
  55 + }
  56 + }
  57 + }
@@ -48,7 +48,7 @@ class Api(ApiTemplate): @@ -48,7 +48,7 @@ class Api(ApiTemplate):
48 {"name": "type", 48 {"name": "type",
49 "in": "formData", 49 "in": "formData",
50 "type": "string", 50 "type": "string",
51 - "enum":["ImageServer"]}, 51 + "enum":["ImageServer","AddServer"]},
52 ], 52 ],
53 "responses": { 53 "responses": {
54 200: { 54 200: {
@@ -5,10 +5,10 @@ @@ -5,10 +5,10 @@
5 5
6 from app.util.component.ApiTemplate import ApiTemplate 6 from app.util.component.ApiTemplate import ApiTemplate
7 import requests 7 import requests
8 -from app.modules.service.models import ServiceEngine,db 8 +from app.modules.service.models import ServiceEngine,db,Service
9 import datetime 9 import datetime
10 import uuid 10 import uuid
11 - 11 +import configure
12 class Api(ApiTemplate): 12 class Api(ApiTemplate):
13 api_name = "注册服务引擎" 13 api_name = "注册服务引擎"
14 def process(self): 14 def process(self):
@@ -16,15 +16,41 @@ class Api(ApiTemplate): @@ -16,15 +16,41 @@ class Api(ApiTemplate):
16 try: 16 try:
17 url = self.para.get("url") 17 url = self.para.get("url")
18 name = self.para.get("name") 18 name = self.para.get("name")
19 - response:requests.Response = requests.get(url) 19 +
  20 + if ServiceEngine.query.filter_by(url=url).one_or_none():
  21 + raise Exception("引擎已注册!")
  22 +
  23 + response:requests.Response = requests.get(url,timeout=3)
20 if response.status_code != 200: 24 if response.status_code != 200:
21 raise Exception("服务引擎连接失败!") 25 raise Exception("服务引擎连接失败!")
22 - service_engine = ServiceEngine(guid=uuid.uuid1().__str__(), 26 +
  27 + this_time = datetime.datetime.now()
  28 + engine_guid = uuid.uuid1().__str__()
  29 + service_engine = ServiceEngine(guid=engine_guid,
23 name=name if name else response.json().get("Name"), 30 name=name if name else response.json().get("Name"),
24 url=url, 31 url=url,
25 type=response.json().get("Type"), 32 type=response.json().get("Type"),
26 - create_time=datetime.datetime.now() 33 + create_time=this_time
27 ) 34 )
  35 + #注册地址匹配引擎服务
  36 + if response.json().get("Type") == "AddServer":
  37 + response: requests.Response = requests.get("{}/Info".format(url),timeout=3)
  38 + add_name = response.json().get("name")
  39 + service = Service(
  40 + guid=engine_guid,
  41 + name=add_name,
  42 + title=add_name,
  43 + state=1,
  44 + create_time=this_time,
  45 + update_time=this_time,
  46 + description="地址匹配",
  47 + node=1,
  48 + overview="{}/Thumbnail".format(url),
  49 + type="地址匹配",
  50 + url = url
  51 + )
  52 + db.session.add(service)
  53 +
28 db.session.add(service_engine) 54 db.session.add(service_engine)
29 db.session.commit() 55 db.session.commit()
30 res["result"] = True 56 res["result"] = True
@@ -18,7 +18,7 @@ class Api(ApiTemplate): @@ -18,7 +18,7 @@ class Api(ApiTemplate):
18 url = "{}/API/Service/Register".format(self.para.get("url")) 18 url = "{}/API/Service/Register".format(self.para.get("url"))
19 response:requests.Response = requests.post(url,data=self.para) 19 response:requests.Response = requests.post(url,data=self.para)
20 if not response.json().get("result"): 20 if not response.json().get("result"):
21 - raise Exception("由于{}影像服务注册失败!".format(response.json().get("msg"))) 21 + raise Exception("由于{}影像服务注册失败!".format(response.json().get("msg")))
22 res["result"] = True 22 res["result"] = True
23 except Exception as e: 23 except Exception as e:
24 raise e 24 raise e
@@ -27,15 +27,16 @@ class Api(ApiTemplate): @@ -27,15 +27,16 @@ class Api(ApiTemplate):
27 27
28 28
29 service_update = {"update_time":this_time} 29 service_update = {"update_time":this_time}
30 - map_service_update = {"updatetime":this_time} 30 + map_service_update = {}
  31 +
31 for key in self.para.keys(): 32 for key in self.para.keys():
32 if key in ["name","title","state","description","overview","catalog_guid"]: 33 if key in ["name","title","state","description","overview","catalog_guid"]:
33 service_update[key] = self.para.get(key) 34 service_update[key] = self.para.get(key)
34 - if key in ["name","status","description","username","readonly",  
35 - "sid","stype","ssupply","sctime","company","abstract","thumbnail","layer_style"]: 35 + if key in ["name","tile","project","capabilities"]:
36 map_service_update[key] = self.para.get(key) 36 map_service_update[key] = self.para.get(key)
37 37
38 38
  39 +
39 # 修改功能 40 # 修改功能
40 if functions: 41 if functions:
41 new_types = functions.split(",") 42 new_types = functions.split(",")
@@ -97,48 +98,15 @@ class Api(ApiTemplate): @@ -97,48 +98,15 @@ class Api(ApiTemplate):
97 "type": "string", 98 "type": "string",
98 "description": "[地图服务]服务能力,用逗号相隔"}, 99 "description": "[地图服务]服务能力,用逗号相隔"},
99 100
100 -  
101 - # MapService参数  
102 - {"name": "status",  
103 - "in": "formData",  
104 - "type": "string",  
105 - "description": "[地图服务]status"},  
106 - {"name": "username",  
107 - "in": "formData",  
108 - "type": "string",  
109 - "description": "[地图服务]username"},  
110 - {"name": "readonly",  
111 - "in": "formData",  
112 - "type": "string",  
113 - "description": "[地图服务]readonly"},  
114 - {"name": "sid",  
115 - "in": "formData",  
116 - "type": "string",  
117 - "description": "[地图服务]sid"},  
118 - {"name": "stype",  
119 - "in": "formData",  
120 - "type": "string",  
121 - "description": "[地图服务]stype"},  
122 - {"name": "ssupply",  
123 - "in": "formData",  
124 - "type": "string",  
125 - "description": "[地图服务]ssupply"},  
126 - {"name": "sctime", 101 + #地图服务参数
  102 + {"name": "capabilities",
127 "in": "formData", 103 "in": "formData",
128 - "type": "string",  
129 - "description": "[地图服务]sctime"},  
130 - {"name": "company",  
131 - "in": "formData",  
132 - "type": "string",  
133 - "description": "[地图服务]company"},  
134 - {"name": "abstract",  
135 - "in": "formData",  
136 - "type": "string",  
137 - "description": "[地图服务]abstract"},  
138 - {"name": "thumbnail", 104 + "type": "int",
  105 + "description": "[地图服务]"},
  106 + {"name": "project",
139 "in": "formData", 107 "in": "formData",
140 "type": "string", 108 "type": "string",
141 - "description": "[地图服务]thumbnail"}, 109 + "description": "[地图服务]project"},
142 110
143 ], 111 ],
144 "responses": { 112 "responses": {
@@ -9,6 +9,9 @@ import uuid @@ -9,6 +9,9 @@ import uuid
9 from ..models import Service,db,MapService,ServiceFunction 9 from ..models import Service,db,MapService,ServiceFunction
10 import datetime 10 import datetime
11 import configure 11 import configure
  12 +import requests
  13 +import json
  14 +
12 class Api(ApiTemplate): 15 class Api(ApiTemplate):
13 16
14 api_name = "注册MapService服务" 17 api_name = "注册MapService服务"
@@ -22,23 +25,38 @@ class Api(ApiTemplate): @@ -22,23 +25,38 @@ class Api(ApiTemplate):
22 this_time = datetime.datetime.now() 25 this_time = datetime.datetime.now()
23 service_guid = uuid.uuid1().__str__() 26 service_guid = uuid.uuid1().__str__()
24 map_service_guid = uuid.uuid1().__str__() 27 map_service_guid = uuid.uuid1().__str__()
25 - service_function_guid = uuid.uuid1().__str__()  
26 -  
27 28
28 # 逻辑是,先调用引擎接口,引擎说可以,才做持久化 29 # 逻辑是,先调用引擎接口,引擎说可以,才做持久化
  30 +
  31 + para = {"name":self.para.get("name"),
  32 + "title":self.para.get("title"),
  33 + "type":"mapserver",
  34 + "capabilities":2,
  35 + "project":self.para.get("project")}
  36 +
  37 + map_service_register_url = "{}/dmap/api/manager/regservice".format(configure.vector_engine)
  38 + resp: requests.Response = requests.post(map_service_register_url,data=json.dumps(para),
  39 + headers={'Content-Type':'application/json'},timeout=3
  40 + )
  41 + resp.encoding="utf-8"
  42 + resp_json = resp.json()
  43 + if not resp_json["status"]=="1":
  44 + raise Exception("调用矢量服务的注册服务接口失败!")
  45 +
29 # 并获得服务缩略图 46 # 并获得服务缩略图
30 47
31 service = Service( 48 service = Service(
32 guid = service_guid, 49 guid = service_guid,
33 name = self.para.get("name"), 50 name = self.para.get("name"),
34 title = self.para.get("title"), 51 title = self.para.get("title"),
35 - state = int(self.para.get("state")) if self.para.get("state") else None, 52 + creator=self.para.get("creator"),
  53 + state = 1,
36 create_time = this_time, 54 create_time = this_time,
37 update_time = this_time, 55 update_time = this_time,
38 description = self.para.get("description"), 56 description = self.para.get("description"),
39 #node = Column(Integer), 57 #node = Column(Integer),
40 node = 1 , 58 node = 1 ,
41 - overview = "xxxx", 59 + overview = resp_json["url"],
42 type = self.para.get("type"), 60 type = self.para.get("type"),
43 catalog_guid = self.para.get("catalog_guid") 61 catalog_guid = self.para.get("catalog_guid")
44 ) 62 )
@@ -46,41 +64,22 @@ class Api(ApiTemplate): @@ -46,41 +64,22 @@ class Api(ApiTemplate):
46 map_service = MapService( 64 map_service = MapService(
47 guid = map_service_guid, 65 guid = map_service_guid,
48 name = self.para.get("name"), 66 name = self.para.get("name"),
49 - status = self.para.get("status"),  
50 - description=self.para.get("description"),  
51 - username = self.para.get("username"),  
52 - readonly = self.para.get("readonly"),  
53 - updatetime = this_time,  
54 - sid = int(self.para.get("sid")),  
55 - stype = self.para.get("stype"),  
56 - ssupply = self.para.get("ssupply"),  
57 - sctime = self.para.get("sctime"),  
58 - company = self.para.get("company"),  
59 - abstract = self.para.get("abstract"),  
60 - thumbnail = self.para.get("thumbnail"),  
61 - layer_style = self.para.get("layer_style"), 67 + title = self.para.get("title"),
  68 + type = "mapserver",
  69 + capabilities = int(self.para.get("capabilities",2)),
  70 + project = self.para.get("project"),
62 service_guid = service_guid 71 service_guid = service_guid
63 ) 72 )
64 73
65 - service_function = ServiceFunction(guid=service_function_guid,type="WMS",  
66 - service_guid=service_guid) 74 + service_function_wms = ServiceFunction(guid=uuid.uuid1().__str__(),type="WMS",service_guid=service_guid)
  75 + service_function_wfs = ServiceFunction(guid=uuid.uuid1().__str__(),type="WFS",service_guid=service_guid)
67 76
68 db.session.add(service) 77 db.session.add(service)
69 db.session.add(map_service) 78 db.session.add(map_service)
70 - db.session.add(service_function) 79 + db.session.add(service_function_wms)
  80 + db.session.add(service_function_wfs)
71 db.session.commit() 81 db.session.commit()
72 82
73 - # 调用MapService服务的注册服务接口  
74 - try:  
75 - pass  
76 - #对,逻辑是,先调用引擎接口,引擎说可以,才做持久化  
77 - except Exception as e:  
78 - db.session.delete(service)  
79 - db.session.delete(map_service)  
80 - db.session.delete(service_function)  
81 - db.session.commit()  
82 - raise e  
83 -  
84 res["data"] = service_guid 83 res["data"] = service_guid
85 res["result"] = True 84 res["result"] = True
86 except Exception as e: 85 except Exception as e:
@@ -108,7 +107,7 @@ class Api(ApiTemplate): @@ -108,7 +107,7 @@ class Api(ApiTemplate):
108 {"name": "type", 107 {"name": "type",
109 "in": "formData", 108 "in": "formData",
110 "type": "string", 109 "type": "string",
111 - "enum": ["地图服务", "切片服务", "影像服务"], 110 + "enum": ["地图服务"],
112 "required": "true", 111 "required": "true",
113 "description": "[地图服务,切片服务,影像服务]"}, 112 "description": "[地图服务,切片服务,影像服务]"},
114 {"name": "catalog_guid", 113 {"name": "catalog_guid",
@@ -117,50 +116,16 @@ class Api(ApiTemplate): @@ -117,50 +116,16 @@ class Api(ApiTemplate):
117 "description": "[地图服务,切片服务,影像服务]"}, 116 "description": "[地图服务,切片服务,影像服务]"},
118 117
119 118
120 - {"name": "status",  
121 - "in": "formData",  
122 - "type": "string",  
123 - "description": "[地图服务]status"},  
124 - {"name": "username",  
125 - "in": "formData",  
126 - "type": "string",  
127 - "description": "[地图服务]username"},  
128 - {"name": "readonly",  
129 - "in": "formData",  
130 - "type": "string",  
131 - "description": "[地图服务]readonly"},  
132 - {"name": "sid",  
133 - "in": "formData",  
134 - "type": "string",  
135 - "description": "[地图服务]sid"},  
136 - {"name": "stype",  
137 - "in": "formData",  
138 - "type": "string",  
139 - "description": "[地图服务]stype"},  
140 - {"name": "ssupply", 119 + #地图服务参数
  120 + {"name": "capabilities",
141 "in": "formData", 121 "in": "formData",
142 - "type": "string",  
143 - "description": "[地图服务]ssupply"},  
144 - {"name": "sctime", 122 + "type": "int",
  123 + "description": "[地图服务]"},
  124 + {"name": "project",
145 "in": "formData", 125 "in": "formData",
146 "type": "string", 126 "type": "string",
147 - "description": "[地图服务]sctime"},  
148 - {"name": "company",  
149 - "in": "formData",  
150 - "type": "string",  
151 - "description": "[地图服务]company"},  
152 - {"name": "abstract",  
153 - "in": "formData",  
154 - "type": "string",  
155 - "description": "[地图服务]abstract"},  
156 - {"name": "thumbnail",  
157 - "in": "formData",  
158 - "type": "string",  
159 - "description": "[地图服务]thumbnail"},  
160 - {"name": "layer_style",  
161 - "in": "formData",  
162 - "type": "string",  
163 - "description": "[地图服务,切片服务]layer_style"}, 127 + "description": "[地图服务]project"},
  128 +
164 129
165 ], 130 ],
166 "responses": { 131 "responses": {
  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 +from app.util.component.StructuredPrint import StructurePrint
  10 +import json
  11 +import base64
  12 +
  13 +
  14 +class ProjectFile:
  15 +
  16 + @classmethod
  17 + def create(cls,para):
  18 + if para.get("tile_type").__eq__("WMTS"):
  19 +
  20 + if para.get("scheme"):
  21 + tile_scheme = json.loads(para.get("scheme"))
  22 + else:
  23 + tile_scheme: TileScheme = TileScheme.query.filter_by(guid=para.get("scheme_guid")).one_or_none()
  24 + if not tile_scheme:
  25 + raise Exception("切片方案不存在!")
  26 + tile_scheme = ModelVisitor.object_to_json(tile_scheme)
  27 +
  28 + project_xml_format = '''
  29 +<?xml version="1.0"?>
  30 +<dmap projectname="wmtstest" version="4.0">
  31 + <projectCrs>
  32 + <spatialrefsys>
  33 + <wkt>{wkt}</wkt>
  34 + <proj4>{proj4}</proj4>
  35 + <srid>{srid}</srid>
  36 + <description/>
  37 + <projectionacronym/>
  38 + </spatialrefsys>
  39 + </projectCrs>
  40 + <projectlayers>
  41 + <maplayer name="{name}" alias="{alias}" type="0">
  42 + <extent>
  43 + <xmin>{xmin}</xmin>
  44 + <ymin>{ymin}</ymin>
  45 + <xmax>{xmax}</xmax>
  46 + <ymax>{ymax}</ymax>
  47 + </extent>
  48 + <style>{layer_style}</style>
  49 + <format>{layer_format}</format>
  50 + <vendor>{vendor}</vendor>
  51 + <datasource>{datasource}</datasource>
  52 + <tileMatrixSets>
  53 + <tileMatrixSet>
  54 + <id>default</id>
  55 + <crs>{crs}</crs>
  56 + <tileCols>{cols}</tileCols>
  57 + <tileRows>{rows}</tileRows>
  58 + <dpi>{dpi}</dpi>
  59 + <tileOrigin>
  60 + <X>{x}</X>
  61 + <Y>{y}</Y>
  62 + </tileOrigin>
  63 + <levels>
  64 + {levels}
  65 + </levels>
  66 + </tileMatrixSet>
  67 + </tileMatrixSets>
  68 + </maplayer>
  69 + </projectlayers>
  70 +</dmap>
  71 +'''
  72 +
  73 + level_each = '''<level>
  74 + <id>{lev}</id>
  75 + <scaleDenominator>{scale}</scaleDenominator>
  76 + <resolution>{resolution}</resolution>
  77 + </level>
  78 + '''
  79 +
  80 + levels = ''
  81 + for level in json.loads(tile_scheme.get("levels")):
  82 + levels = "{}{}".format(levels, level_each.format(lev=level["level"],
  83 + scale=level["scale"],
  84 + resolution=level["resolution"],
  85 + ))
  86 + #删除空格
  87 + levels = levels.strip()
  88 +
  89 + layer_extent = para.get("layer_extent").split(",")
  90 +
  91 + project_xml = project_xml_format.format(wkt="",
  92 + proj4="",
  93 + srid=para.get("crs").split("::")[-1],
  94 + name=para.get("layer_name"),
  95 + alias=para.get("alias") if para.get("alias") else "",
  96 + xmin=layer_extent[0],
  97 + xmax=layer_extent[1],
  98 + ymin=layer_extent[2],
  99 + ymax=layer_extent[3],
  100 + layer_style=para.get("layer_style"),
  101 + layer_format=para.get("layer_format"),
  102 + vendor=para.get("vendor"),
  103 + datasource=para.get("datasource"),
  104 + crs=para.get("crs"),
  105 + cols=tile_scheme.get("cols"),
  106 + rows=tile_scheme.get("rows"),
  107 + dpi=tile_scheme.get("dpi"),
  108 + x=tile_scheme.get("top_left").split(",")[0],
  109 + y=tile_scheme.get("top_left").split(",")[1],
  110 + levels=levels
  111 + )
  112 + else:
  113 +
  114 + project_xml_format = '''
  115 +<?xml version="1.0"?>
  116 +<dmap projectname="tmstest" version="4.0">
  117 + <projectCrs>
  118 + <spatialrefsys>
  119 + <wkt>{wkt}</wkt>
  120 + <proj4>{proj4}</proj4>
  121 + <srid>{srid}</srid>
  122 + <description/>
  123 + <projectionacronym/>
  124 + </spatialrefsys>
  125 + </projectCrs>
  126 + <projectlayers>
  127 + <maplayer name="{name}" alias="{alias}" type="0">
  128 + <extent>
  129 + <xmin>{xmin}</xmin>
  130 + <ymin>{ymin}</ymin>
  131 + <xmax>{xmax}</xmax>
  132 + <ymax>{ymax}</ymax>
  133 + </extent>
  134 + <style>{layer_style}</style>
  135 + <format>{layer_format}</format>
  136 + <vendor>{vendor}</vendor>
  137 + <datasource>{datasource}</datasource>
  138 + </maplayer>
  139 + </projectlayers>
  140 +</dmap>
  141 +'''
  142 + layer_extent = para.get("layer_extent").split(",")
  143 + project_xml = project_xml_format.format(wkt="",
  144 + proj4="",
  145 + srid=para.get("crs").split("::")[-1],
  146 + name=para.get("layer_name"),
  147 + alias=para.get("alias") if para.get("alias") else "",
  148 + xmin=layer_extent[0],
  149 + xmax=layer_extent[1],
  150 + ymin=layer_extent[2],
  151 + ymax=layer_extent[3],
  152 + layer_style=para.get("layer_style"),
  153 + layer_format=para.get("layer_format"),
  154 + vendor=para.get("vendor"),
  155 + datasource=para.get("datasource"),
  156 + )
  157 +
  158 + project_xml = project_xml.strip()
  159 + return str(base64.b64encode(project_xml.encode('utf-8')), encoding="utf8")
  1 +# coding=utf-8
  2 +#author: 4N
  3 +#createtime: 2021/12/31
  4 +#email: nheweijun@sina.com
@@ -29,7 +29,8 @@ class Service(db.Model): @@ -29,7 +29,8 @@ class Service(db.Model):
29 type = Column(String(256)) #地图服务,影像服务,切片服务 29 type = Column(String(256)) #地图服务,影像服务,切片服务
30 # 目录外键 30 # 目录外键
31 catalog_guid = Column(String(256), ForeignKey('dmap_service_catalog.guid')) 31 catalog_guid = Column(String(256), ForeignKey('dmap_service_catalog.guid'))
32 - 32 + # 创建者
  33 + creator = Column(String(256))
33 url = Column(String(256)) 34 url = Column(String(256))
34 35
35 relate_service_functions = relationship('ServiceFunction', backref='relate_service', lazy='dynamic') 36 relate_service_functions = relationship('ServiceFunction', backref='relate_service', lazy='dynamic')
@@ -76,6 +77,9 @@ class TileScheme(db.Model): @@ -76,6 +77,9 @@ class TileScheme(db.Model):
76 extent = Column(Text) 77 extent = Column(Text)
77 top_left = Column(String(256)) 78 top_left = Column(String(256))
78 79
  80 + # 创建者
  81 + creator = Column(String(256))
  82 +
79 levels = Column(Text) 83 levels = Column(Text)
80 dpi = Column(Integer) 84 dpi = Column(Integer)
81 rows = Column(Integer) 85 rows = Column(Integer)
@@ -141,23 +145,11 @@ class MapService(db.Model): @@ -141,23 +145,11 @@ class MapService(db.Model):
141 guid = Column(String(256), primary_key=True) 145 guid = Column(String(256), primary_key=True)
142 name = Column(String, unique=True) 146 name = Column(String, unique=True)
143 147
144 - #基本信息  
145 - status = Column(String)  
146 - description = Column(String)  
147 - #厂家  
148 - username = Column(String(256))  
149 -  
150 - readonly = Column(String)  
151 - updatetime = Column(DateTime)  
152 - sid = Column(Integer)  
153 - stype = Column(String)  
154 - ssupply = Column(String)  
155 - sctime = Column(String)  
156 - company = Column(String)  
157 - abstract = Column(String)  
158 - title = Column(String)  
159 - thumbnail = Column(String)  
160 - layer_style = Column(Text) 148 + title = Column(String(256))
  149 + type = Column(String(256))
  150 + capabilities = Column(Integer)
  151 + project = Column(Text)
  152 +
161 service_guid = Column(String,ForeignKey('dmap_service.guid')) 153 service_guid = Column(String,ForeignKey('dmap_service.guid'))
162 154
163 class ServiceEngine(db.Model): 155 class ServiceEngine(db.Model):
@@ -45,6 +45,7 @@ class Api(ApiTemplate): @@ -45,6 +45,7 @@ class Api(ApiTemplate):
45 crs_wkt = data.get("crs_wkt"), 45 crs_wkt = data.get("crs_wkt"),
46 extent = data.get("extent"), 46 extent = data.get("extent"),
47 top_left = data.get("top_left"), 47 top_left = data.get("top_left"),
  48 + creator= data.get("creator"),
48 # ymin = extent[1], 49 # ymin = extent[1],
49 # xmax = extent[2], 50 # xmax = extent[2],
50 # ymax = extent[3], 51 # ymax = extent[3],
@@ -77,6 +78,9 @@ class Api(ApiTemplate): @@ -77,6 +78,9 @@ class Api(ApiTemplate):
77 {"name": "alias", 78 {"name": "alias",
78 "in": "formData", 79 "in": "formData",
79 "type": "string"}, 80 "type": "string"},
  81 + {"name": "creator",
  82 + "in": "formData",
  83 + "type": "string"},
80 {"name": "description", 84 {"name": "description",
81 "in": "formData", 85 "in": "formData",
82 "type": "string"}, 86 "type": "string"},
@@ -27,18 +27,22 @@ class Api(ApiTemplate): @@ -27,18 +27,22 @@ class Api(ApiTemplate):
27 service = Service.query.filter_by(guid=guid).one_or_none() 27 service = Service.query.filter_by(guid=guid).one_or_none()
28 28
29 if service: 29 if service:
30 - if service.type.__eq__("切片服务"):  
31 - #调用接口  
32 - #172.26.99.160:6060/dmap/api/manager/deleteService?servername=tileserver&servicename=GDMap  
33 - tile_service = TileService.query.filter_by(service_guid=guid).one_or_none()  
34 - db.session.delete(tile_service)  
35 30
36 - if service.type.__eq__("地图服务"):  
37 - map_service = MapService.query.filter_by(service_guid=guid).one_or_none()  
38 - db.session.delete(map_service)  
39 - service_functions = service.relate_service_functions.all()  
40 - for function in service_functions:  
41 - db.session.delete(function) 31 + try:
  32 + if service.type.__eq__("切片服务"):
  33 + #调用接口
  34 + tile_service = TileService.query.filter_by(service_guid=guid).one_or_none()
  35 + db.session.delete(tile_service)
  36 +
  37 + if service.type.__eq__("地图服务"):
  38 + map_service = MapService.query.filter_by(service_guid=guid).one_or_none()
  39 + db.session.delete(map_service)
  40 + service_functions = service.relate_service_functions.all()
  41 + for function in service_functions:
  42 + db.session.delete(function)
  43 + except:
  44 + pass
  45 +
42 db.session.delete(service) 46 db.session.delete(service)
43 47
44 else: 48 else:
@@ -149,47 +149,15 @@ class Api(ApiTemplate): @@ -149,47 +149,15 @@ class Api(ApiTemplate):
149 "type": "string", 149 "type": "string",
150 "description": "[切片服务]图层描述"}, 150 "description": "[切片服务]图层描述"},
151 151
152 - # WMS参数  
153 - {"name": "status", 152 + #地图服务参数
  153 + {"name": "capabilities",
154 "in": "formData", 154 "in": "formData",
155 - "type": "string",  
156 - "description": "[地图服务]status"},  
157 - {"name": "username",  
158 - "in": "formData",  
159 - "type": "string",  
160 - "description": "[地图服务]username"},  
161 - {"name": "readonly",  
162 - "in": "formData",  
163 - "type": "string",  
164 - "description": "[地图服务]readonly"},  
165 - {"name": "sid",  
166 - "in": "formData",  
167 - "type": "string",  
168 - "description": "[地图服务]sid"},  
169 - {"name": "stype",  
170 - "in": "formData",  
171 - "type": "string",  
172 - "description": "[地图服务]stype"},  
173 - {"name": "ssupply",  
174 - "in": "formData",  
175 - "type": "string",  
176 - "description": "[地图服务]ssupply"},  
177 - {"name": "sctime",  
178 - "in": "formData",  
179 - "type": "string",  
180 - "description": "[地图服务]sctime"},  
181 - {"name": "company",  
182 - "in": "formData",  
183 - "type": "string",  
184 - "description": "[地图服务]company"},  
185 - {"name": "abstract",  
186 - "in": "formData",  
187 - "type": "string",  
188 - "description": "[地图服务]abstract"},  
189 - {"name": "thumbnail", 155 + "type": "int",
  156 + "description": "[地图服务]"},
  157 + {"name": "project",
190 "in": "formData", 158 "in": "formData",
191 "type": "string", 159 "type": "string",
192 - "description": "[地图服务]thumbnail"}, 160 + "description": "[地图服务]project"},
193 ], 161 ],
194 "responses": { 162 "responses": {
195 200: { 163 200: {
@@ -64,7 +64,7 @@ class Api(ApiTemplate): @@ -64,7 +64,7 @@ class Api(ApiTemplate):
64 64
65 for ie in image_engines: 65 for ie in image_engines:
66 url = "{}/API/Service/List".format(ie.url) 66 url = "{}/API/Service/List".format(ie.url)
67 - response:requests.Response = requests.post(url,self.para) 67 + response:requests.Response = requests.post(url,{"page_size":"9999","page_index":"0"})
68 if not response.json().get("result"): 68 if not response.json().get("result"):
69 raise Exception("修改影像服务失败!") 69 raise Exception("修改影像服务失败!")
70 else: 70 else:
@@ -95,7 +95,7 @@ class Api(ApiTemplate): @@ -95,7 +95,7 @@ class Api(ApiTemplate):
95 # update时间倒数 95 # update时间倒数
96 services_json = sorted(services_json,key=lambda x:x["update_time"],reverse=True) 96 services_json = sorted(services_json,key=lambda x:x["update_time"],reverse=True)
97 97
98 - res["data"]["list"] = services_json[page_index:(page_index+1)*page_size] 98 + res["data"]["list"] = services_json[page_index*page_size:(page_index+1)*page_size]
99 res["result"] = True 99 res["result"] = True
100 100
101 except Exception as e: 101 except Exception as e:
@@ -59,7 +59,8 @@ class Api(ApiTemplate): @@ -59,7 +59,8 @@ class Api(ApiTemplate):
59 59
60 for ie in image_engines: 60 for ie in image_engines:
61 url = "{}/API/Service/BaseMapList".format(ie.url) 61 url = "{}/API/Service/BaseMapList".format(ie.url)
62 - response:requests.Response = requests.post(url,self.para) 62 + response:requests.Response = requests.post(url,{"page_size":"9999","page_index":"0",
  63 + "bbox":bbox,"state":state})
63 if not response.json().get("result"): 64 if not response.json().get("result"):
64 raise Exception("修改影像服务失败!") 65 raise Exception("修改影像服务失败!")
65 else: 66 else:
@@ -71,7 +72,7 @@ class Api(ApiTemplate): @@ -71,7 +72,7 @@ class Api(ApiTemplate):
71 72
72 fit_services_json = sorted(fit_services_json, key=lambda x: x["update_time"], reverse=True) 73 fit_services_json = sorted(fit_services_json, key=lambda x: x["update_time"], reverse=True)
73 74
74 - res["data"]["list"] = fit_services_json[page_index:(page_index + 1) * page_size] 75 + res["data"]["list"] = fit_services_json[page_index*page_size:(page_index+1)*page_size]
75 res["result"] = True 76 res["result"] = True
76 77
77 except Exception as e: 78 except Exception as e:
@@ -52,6 +52,10 @@ class Api(ApiTemplate): @@ -52,6 +52,10 @@ class Api(ApiTemplate):
52 "type": "string", 52 "type": "string",
53 "description": "[地图服务,切片服务,影像服务]"}, 53 "description": "[地图服务,切片服务,影像服务]"},
54 54
  55 + {"name": "creator",
  56 + "in": "formData",
  57 + "type": "string"},
  58 +
55 {"name": "url", 59 {"name": "url",
56 "in": "formData", 60 "in": "formData",
57 "type": "string"}, 61 "type": "string"},
@@ -142,46 +146,14 @@ class Api(ApiTemplate): @@ -142,46 +146,14 @@ class Api(ApiTemplate):
142 "description": "[切片服务]图层描述"}, 146 "description": "[切片服务]图层描述"},
143 147
144 #地图服务参数 148 #地图服务参数
145 - {"name": "status",  
146 - "in": "formData",  
147 - "type": "string",  
148 - "description": "[地图服务]status"},  
149 - {"name": "username",  
150 - "in": "formData",  
151 - "type": "string",  
152 - "description": "[地图服务]username"},  
153 - {"name": "readonly",  
154 - "in": "formData",  
155 - "type": "string",  
156 - "description": "[地图服务]readonly"},  
157 - {"name": "sid",  
158 - "in": "formData",  
159 - "type": "string",  
160 - "description": "[地图服务]sid"},  
161 - {"name": "stype",  
162 - "in": "formData",  
163 - "type": "string",  
164 - "description": "[地图服务]stype"},  
165 - {"name": "ssupply",  
166 - "in": "formData",  
167 - "type": "string",  
168 - "description": "[地图服务]ssupply"},  
169 - {"name": "sctime", 149 + {"name": "capabilities",
170 "in": "formData", 150 "in": "formData",
171 - "type": "string",  
172 - "description": "[地图服务]sctime"},  
173 - {"name": "company",  
174 - "in": "formData",  
175 - "type": "string",  
176 - "description": "[地图服务]company"},  
177 - {"name": "abstract",  
178 - "in": "formData",  
179 - "type": "string",  
180 - "description": "[地图服务]abstract"},  
181 - {"name": "thumbnail", 151 + "type": "int",
  152 + "description": "[地图服务]"},
  153 + {"name": "project",
182 "in": "formData", 154 "in": "formData",
183 "type": "string", 155 "type": "string",
184 - "description": "[地图服务]thumbnail"}, 156 + "description": "[地图服务]project"},
185 157
186 ], 158 ],
187 "responses": { 159 "responses": {
  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,MapService
  9 +import configure
  10 +from app.util.component.ModelVisitor import ModelVisitor
  11 +
  12 +from .tile_service.util.ProjectFile import ProjectFile
  13 +
  14 +
  15 +class Api(ApiTemplate):
  16 +
  17 + api_name = "服务reload"
  18 +
  19 + def process(self):
  20 + res = {}
  21 + try:
  22 +
  23 + res["data"] = {}
  24 +
  25 + res["data"]["list"] = []
  26 +
  27 + #切片服务
  28 + tile_services = TileService.query.join(Service).filter(Service.type == "切片服务").all()
  29 + for ts in tile_services:
  30 + project_file = ProjectFile.create(ModelVisitor.object_to_json(ts))
  31 + service:Service = Service.query.filter_by(guid=ts.service_guid).one_or_none()
  32 + para = {"name":service.name,"title":service.title,
  33 + "type":"tileserver","capabilities":1 if ts.tile_type=="WMTS" else 16,"project":project_file}
  34 + res["data"]["list"].append(para)
  35 +
  36 + #地图服务
  37 + map_services = MapService.query.all()
  38 + for ms in map_services:
  39 + res["data"]["list"].append(ModelVisitor.object_to_json(ms))
  40 +
  41 + res["data"]["count"] = len(tile_services)+len(map_services)
  42 + res["result"] = True
  43 + except Exception as e:
  44 + raise Exception("数据库错误!")
  45 + return res
  46 +
  47 +
  48 +
  49 + api_doc = {
  50 + "tags": ["服务接口"],
  51 + "parameters": [
  52 + ],
  53 + "responses": {
  54 + 200: {
  55 + "schema": {
  56 + "properties": {
  57 + }
  58 + }
  59 + }
  60 + }
  61 + }
@@ -19,7 +19,7 @@ class Api(ApiTemplate): @@ -19,7 +19,7 @@ class Api(ApiTemplate):
19 19
20 20
21 #删除本地服务 21 #删除本地服务
22 - if s_type in ["切片服务","地图服务"]: 22 + if s_type in ["切片服务","地图服务","地址匹配"]:
23 service = Service.query.filter_by(guid=guid).one_or_none() 23 service = Service.query.filter_by(guid=guid).one_or_none()
24 24
25 if service: 25 if service:
@@ -35,7 +35,6 @@ class Api(ApiTemplate): @@ -35,7 +35,6 @@ class Api(ApiTemplate):
35 api.para = self.para 35 api.para = self.para
36 res = api.process() 36 res = api.process()
37 37
38 -  
39 except Exception as e: 38 except Exception as e:
40 raise e 39 raise e
41 return res 40 return res
@@ -55,7 +54,7 @@ class Api(ApiTemplate): @@ -55,7 +54,7 @@ class Api(ApiTemplate):
55 {"name": "url", 54 {"name": "url",
56 "in": "formData", 55 "in": "formData",
57 "type": "string", 56 "type": "string",
58 - "description": "type"}, 57 + "description": "url"},
59 {"name": "state", 58 {"name": "state",
60 "in": "formData", 59 "in": "formData",
61 "type": "int", 60 "type": "int",
@@ -46,7 +46,7 @@ class DataManager(BlueprintApi): @@ -46,7 +46,7 @@ class DataManager(BlueprintApi):
46 return tile_service_edit.Api().result 46 return tile_service_edit.Api().result
47 47
48 @staticmethod 48 @staticmethod
49 - @bp.route('/Reload', methods=['GET']) 49 + @bp.route('/Reload', methods=['POST','GET'])
50 @swag_from(tile_service_reload.Api.api_doc) 50 @swag_from(tile_service_reload.Api.api_doc)
51 def api_tile_service_reload(): 51 def api_tile_service_reload():
52 """ 52 """
@@ -54,3 +54,5 @@ class DataManager(BlueprintApi): @@ -54,3 +54,5 @@ class DataManager(BlueprintApi):
54 """ 54 """
55 return tile_service_reload.Api().result 55 return tile_service_reload.Api().result
56 56
  57 +
  58 +
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
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.StructuredPrint import StructurePrint
7 from app.util.component.ModelVisitor import ModelVisitor 8 from app.util.component.ModelVisitor import ModelVisitor
8 import uuid 9 import uuid
9 from ..models import TileService,Service,db,ServiceFunction,TileScheme 10 from ..models import TileService,Service,db,ServiceFunction,TileScheme
@@ -38,25 +39,29 @@ class Api(ApiTemplate): @@ -38,25 +39,29 @@ class Api(ApiTemplate):
38 tile_update["scheme"] = json.dumps(ModelVisitor.object_to_json(tilesche)) 39 tile_update["scheme"] = json.dumps(ModelVisitor.object_to_json(tilesche))
39 40
40 #通知tileserver,更新缓存 41 #通知tileserver,更新缓存
41 - ts = TileService.query.filter_by(service_guid=guid).one_or_none() 42 + ts:TileService = TileService.query.filter_by(service_guid=guid).one_or_none()
42 se = service.one_or_none() 43 se = service.one_or_none()
  44 + tile_type = self.para.get("tile_type") if self.para.get("tile_type") else ts.tile_type
43 45
44 ts_json = ModelVisitor.object_to_json(ts) 46 ts_json = ModelVisitor.object_to_json(ts)
45 ts_json.update(tile_update) 47 ts_json.update(tile_update)
  48 +
46 project_file = ProjectFile.create(ts_json) 49 project_file = ProjectFile.create(ts_json)
47 50
48 para = {"name":self.para.get("name") if self.para.get("name") else se.name, 51 para = {"name":self.para.get("name") if self.para.get("name") else se.name,
49 "title":self.para.get("title") if self.para.get("title") else se.title, 52 "title":self.para.get("title") if self.para.get("title") else se.title,
50 - "type":"tileserver","capabilities":1,"project":project_file} 53 + "type":"tileserver","capabilities":1 if tile_type == "WMTS" else 16,"project":project_file}
  54 +
51 55
52 - tile_service_edit_url = "{}/dmap/api/manager/RegService".format(configure.wmts_url) 56 + tile_service_edit_url = "{}/dmap/api/manager/RegService".format(configure.tile_engine)
53 57
54 - resp: Response = requests.post(tile_service_edit_url,data=json.dumps(para),headers={'Content-Type':'application/json'}) 58 + resp: Response = requests.post(tile_service_edit_url,data=json.dumps(para),headers={'Content-Type':'application/json'},timeout=3)
55 resp.encoding="utf-8" 59 resp.encoding="utf-8"
56 resp_json = resp.json() 60 resp_json = resp.json()
57 - if not resp_json["status"].__eq__("true"): 61 + if not resp_json["status"].__eq__("1"):
58 raise Exception("调用切片服务的注册服务接口失败!") 62 raise Exception("调用切片服务的注册服务接口失败!")
59 63
  64 + service_update["overview"] = resp_json["url"]
60 #修改数据库 65 #修改数据库
61 tile_service = TileService.query.filter_by(service_guid=guid) 66 tile_service = TileService.query.filter_by(service_guid=guid)
62 tile_type = self.para.get("tile_type") 67 tile_type = self.para.get("tile_type")
@@ -31,28 +31,32 @@ class Api(ApiTemplate): @@ -31,28 +31,32 @@ class Api(ApiTemplate):
31 # 调用切片服务的注册服务接口 31 # 调用切片服务的注册服务接口
32 32
33 project_file = ProjectFile.create(self.para) 33 project_file = ProjectFile.create(self.para)
34 - para = {"name":self.para.get("name"),"title":self.para.get("title"),  
35 - "type":"tileserver","capabilities":1,"project":project_file}  
36 -  
37 - tile_service_register_url = "{}/dmap/api/manager/RegService".format(configure.wmts_url)  
38 - resp: Response = requests.post(tile_service_register_url,data=json.dumps(para),headers={'Content-Type':'application/json'}) 34 + para = {"name":self.para.get("name"),
  35 + "title":self.para.get("title"),
  36 + "type":"tileserver",
  37 + "capabilities":1 if self.para.get("tile_type") == "WMTS" else 16,
  38 + "project":project_file}
  39 +
  40 + tile_service_register_url = "{}/dmap/api/manager/RegService".format(configure.tile_engine)
  41 + resp: Response = requests.post(tile_service_register_url,data=json.dumps(para),
  42 + headers={'Content-Type':'application/json'},timeout=3
  43 + )
39 resp.encoding="utf-8" 44 resp.encoding="utf-8"
40 resp_json = resp.json() 45 resp_json = resp.json()
41 - if not resp_json["status"].__eq__("true"): 46 + if not resp_json["status"]=="1":
42 raise Exception("调用切片服务的注册服务接口失败!") 47 raise Exception("调用切片服务的注册服务接口失败!")
43 48
44 service = Service( 49 service = Service(
45 guid = service_guid, 50 guid = service_guid,
46 name = self.para.get("name"), 51 name = self.para.get("name"),
47 title = self.para.get("title"), 52 title = self.para.get("title"),
  53 + creator= self.para.get("creator"),
48 state = 1, 54 state = 1,
49 create_time = this_time, 55 create_time = this_time,
50 update_time = this_time, 56 update_time = this_time,
51 description = self.para.get("description"), 57 description = self.para.get("description"),
52 node = 1, 58 node = 1,
53 - overview = "http://{}/API/Service/Overview/{}".format(  
54 - configure.deploy_ip_host,  
55 - self.para.get("overview") if self.para.get("overview") else "wmts_tb.png"), 59 + overview= resp_json["url"],
56 type = self.para.get("type"), 60 type = self.para.get("type"),
57 catalog_guid = self.para.get("catalog_guid") 61 catalog_guid = self.para.get("catalog_guid")
58 ) 62 )
@@ -85,7 +89,7 @@ class Api(ApiTemplate): @@ -85,7 +89,7 @@ class Api(ApiTemplate):
85 89
86 scheme=self.para.get("scheme"), 90 scheme=self.para.get("scheme"),
87 service_guid = service_guid, 91 service_guid = service_guid,
88 - metadata_url = "{}/DMap/Services/{}/MapServer/WMTSServer".format(configure.wmts_url,self.para.get("name")) 92 + metadata_url = "{}/DMap/Services/{}/MapServer/WMTSServer".format(configure.tile_engine,self.para.get("name"))
89 ) 93 )
90 94
91 service_function = ServiceFunction(guid=service_function_guid, 95 service_function = ServiceFunction(guid=service_function_guid,
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 5
6 6
7 from app.util.component.ApiTemplate import ApiTemplate 7 from app.util.component.ApiTemplate import ApiTemplate
8 -from ..models import TileService,db,Service 8 +from ..models import TileService,db,Service,MapService
9 import configure 9 import configure
10 from app.util.component.ModelVisitor import ModelVisitor 10 from app.util.component.ModelVisitor import ModelVisitor
11 11
@@ -19,16 +19,21 @@ class Api(ApiTemplate): @@ -19,16 +19,21 @@ class Api(ApiTemplate):
19 def process(self): 19 def process(self):
20 res = {} 20 res = {}
21 try: 21 try:
22 - tile_services = TileService.query.join(Service).filter(Service.type=="切片服务").all() 22 +
23 res["data"] = {} 23 res["data"] = {}
24 - res["data"]["count"] = len(tile_services) 24 +
25 res["data"]["list"] = [] 25 res["data"]["list"] = []
  26 +
  27 + #切片服务
  28 + tile_services = TileService.query.join(Service).filter(Service.type == "切片服务").all()
26 for ts in tile_services: 29 for ts in tile_services:
27 project_file = ProjectFile.create(ModelVisitor.object_to_json(ts)) 30 project_file = ProjectFile.create(ModelVisitor.object_to_json(ts))
28 service:Service = Service.query.filter_by(guid=ts.service_guid).one_or_none() 31 service:Service = Service.query.filter_by(guid=ts.service_guid).one_or_none()
29 para = {"name":service.name,"title":service.title, 32 para = {"name":service.name,"title":service.title,
30 - "type":"tileserver","capabilities":1,"project":project_file} 33 + "type":"tileserver","capabilities":1 if ts.tile_type=="WMTS" else 16,"project":project_file}
31 res["data"]["list"].append(para) 34 res["data"]["list"].append(para)
  35 +
  36 + res["data"]["count"] = len(tile_services)
32 res["result"] = True 37 res["result"] = True
33 except Exception as e: 38 except Exception as e:
34 raise Exception("数据库错误!") 39 raise Exception("数据库错误!")
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 6
7 from app.modules.service.models import TileScheme 7 from app.modules.service.models import TileScheme
8 from app.util.component.ModelVisitor import ModelVisitor 8 from app.util.component.ModelVisitor import ModelVisitor
  9 +from app.util.component.StructuredPrint import StructurePrint
9 import json 10 import json
10 import base64 11 import base64
11 12
@@ -40,8 +41,8 @@ class ProjectFile: @@ -40,8 +41,8 @@ class ProjectFile:
40 <maplayer name="{name}" alias="{alias}" type="0"> 41 <maplayer name="{name}" alias="{alias}" type="0">
41 <extent> 42 <extent>
42 <xmin>{xmin}</xmin> 43 <xmin>{xmin}</xmin>
43 - <ymin>{xmax}</ymin>  
44 - <xmax>{ymin}</xmax> 44 + <ymin>{ymin}</ymin>
  45 + <xmax>{xmax}</xmax>
45 <ymax>{ymax}</ymax> 46 <ymax>{ymax}</ymax>
46 </extent> 47 </extent>
47 <style>{layer_style}</style> 48 <style>{layer_style}</style>
@@ -126,7 +127,7 @@ class ProjectFile: @@ -126,7 +127,7 @@ class ProjectFile:
126 <maplayer name="{name}" alias="{alias}" type="0"> 127 <maplayer name="{name}" alias="{alias}" type="0">
127 <extent> 128 <extent>
128 <xmin>{xmin}</xmin> 129 <xmin>{xmin}</xmin>
129 - <ymin>{xmax}</ymin> 130 + <ymin>{ymin}</ymin>
130 <xmax>{xmax}</xmax> 131 <xmax>{xmax}</xmax>
131 <ymax>{ymax}</ymax> 132 <ymax>{ymax}</ymax>
132 </extent> 133 </extent>
@@ -71,6 +71,26 @@ class PGUtil: @@ -71,6 +71,26 @@ class PGUtil:
71 return geom_col 71 return geom_col
72 72
73 @classmethod 73 @classmethod
  74 + def get_pkey(cls,table_name,db_session):
  75 + # 判断空间列
  76 + pkey_sql = '''
  77 + select pg_attribute.attname as colname from
  78 + pg_constraint inner join pg_class
  79 + on pg_constraint.conrelid = pg_class.oid
  80 + inner join pg_attribute on pg_attribute.attrelid = pg_class.oid
  81 + and pg_attribute.attnum = pg_constraint.conkey[1]
  82 + inner join pg_type on pg_type.oid = pg_attribute.atttypid
  83 + where pg_class.relname = '{}'
  84 + and pg_constraint.contype='p'
  85 + '''.format(table_name)
  86 + pkey = None
  87 + pkey_result = db_session.execute(pkey_sql)
  88 + for row_proxy in pkey_result:
  89 + pkey = row_proxy[0]
  90 + return pkey
  91 +
  92 +
  93 + @classmethod
74 def get_table_count(cls,table_name,db_session): 94 def get_table_count(cls,table_name,db_session):
75 count_result = db_session.execute('''SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public."{}"'::regclass'''.format( 95 count_result = db_session.execute('''SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public."{}"'::regclass'''.format(
76 table_name)).fetchone() 96 table_name)).fetchone()
@@ -107,7 +107,28 @@ def get_rc(parameter,l,lon,lat): @@ -107,7 +107,28 @@ def get_rc(parameter,l,lon,lat):
107 107
108 def wmts_overview(extent,url_format): 108 def wmts_overview(extent,url_format):
109 109
110 - scheme = {"0": {"resolution": 1.4062500000059488, "scale": 590995186.12}, "1": {"resolution": 0.7031250000029744, "scale": 295497593.06}, "2": {"resolution": 0.3515625000014872, "scale": 147748796.53}, "3": {"resolution": 0.1757812500007436, "scale": 73874398.265}, "4": {"resolution": 0.0878906250003718, "scale": 36937199.1325}, "5": {"resolution": 0.0439453125001859, "scale": 18468599.56625}, "6": {"resolution": 0.02197265625009295, "scale": 9234299.783125}, "7": {"resolution": 0.010986328125046475, "scale": 4617149.8915625}, "8": {"resolution": 0.0054931640625232375, "scale": 2308574.94578125}, "9": {"resolution": 0.0027465820312616187, "scale": 1154287.472890625}, "10": {"resolution": 0.0013732910156308094, "scale": 577143.7364453125}, "11": {"resolution": 0.0006866455078154047, "scale": 288571.86822265625}, "12": {"resolution": 0.00034332275390770234, "scale": 144285.93411132813}, "13": {"resolution": 0.00017166137695385117, "scale": 72142.96705566406}, "14": {"resolution": 8.583068847692559e-05, "scale": 36071.48352783203}, "15": {"resolution": 4.291534423846279e-05, "scale": 18035.741763916016}, "16": {"resolution": 2.1457672119231396e-05, "scale": 9017.870881958008}, "17": {"resolution": 1.0728836059615698e-05, "scale": 4508.935440979004}, "18": {"resolution": 5.364418029807849e-06, "scale": 2254.467720489502}, "19": {"resolution": 2.6822090149039246e-06, "scale": 1127.233860244751}, "20": {"resolution": 1.3411045074519623e-06, "scale": 563.6169301223755}, "cols": 256, "rows": 256, "dpi": 96, "wkt": "", "x": -400, "y": 400} 110 + scheme = {"0": {"resolution": 1.4062500000059488, "scale": 590995186.12},
  111 + "1": {"resolution": 0.7031250000029744, "scale": 295497593.06},
  112 + "2": {"resolution": 0.3515625000014872, "scale": 147748796.53},
  113 + "3": {"resolution": 0.1757812500007436, "scale": 73874398.265},
  114 + "4": {"resolution": 0.0878906250003718, "scale": 36937199.1325},
  115 + "5": {"resolution": 0.0439453125001859, "scale": 18468599.56625},
  116 + "6": {"resolution": 0.02197265625009295, "scale": 9234299.783125},
  117 + "7": {"resolution": 0.010986328125046475, "scale": 4617149.8915625},
  118 + "8": {"resolution": 0.0054931640625232375, "scale": 2308574.94578125},
  119 + "9": {"resolution": 0.0027465820312616187, "scale": 1154287.472890625},
  120 + "10": {"resolution": 0.0013732910156308094, "scale": 577143.7364453125},
  121 + "11": {"resolution": 0.0006866455078154047, "scale": 288571.86822265625},
  122 + "12": {"resolution": 0.00034332275390770234, "scale": 144285.93411132813},
  123 + "13": {"resolution": 0.00017166137695385117, "scale": 72142.96705566406},
  124 + "14": {"resolution": 8.583068847692559e-05, "scale": 36071.48352783203},
  125 + "15": {"resolution": 4.291534423846279e-05, "scale": 18035.741763916016},
  126 + "16": {"resolution": 2.1457672119231396e-05, "scale": 9017.870881958008},
  127 + "17": {"resolution": 1.0728836059615698e-05, "scale": 4508.935440979004},
  128 + "18": {"resolution": 5.364418029807849e-06, "scale": 2254.467720489502},
  129 + "19": {"resolution": 2.6822090149039246e-06, "scale": 1127.233860244751},
  130 + "20": {"resolution": 1.3411045074519623e-06, "scale": 563.6169301223755},
  131 + "cols": 256, "rows": 256, "dpi": 96, "wkt": "", "x": -400, "y": 400}
111 132
112 lev = 0 133 lev = 0
113 r1 = 0 134 r1 = 0
@@ -4,8 +4,7 @@ import logging @@ -4,8 +4,7 @@ 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"
9 8
10 # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中 9 # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中
11 #VACUATE_DB_URI = None 10 #VACUATE_DB_URI = None
@@ -13,9 +12,10 @@ VACUATE_DB_URI = SQLALCHEMY_DATABASE_URI @@ -13,9 +12,10 @@ VACUATE_DB_URI = SQLALCHEMY_DATABASE_URI
13 12
14 zookeeper = "172.26.99.168:2181" 13 zookeeper = "172.26.99.168:2181"
15 14
16 -#WMTS服务器  
17 -wmts_url = "http://172.26.99.160:6060"  
18 -wms_url = "" 15 +#切片引擎
  16 +tile_engine = "http://172.26.99.160:6060"
  17 +#矢量引擎
  18 +vector_engine = "http://172.26.99.160:6060"
19 19
20 # 固定配置不需要修改 20 # 固定配置不需要修改
21 swagger_configure = {"title": "DMapManager"} 21 swagger_configure = {"title": "DMapManager"}
  1 +<VirtualHost *:80>
  2 + ServerName 172.26.60.101
  3 + WSGIDaemonProcess yourapplication processes=4 threads=16
  4 + WSGIScriptAlias / /usr/src/app/run.wsgi
  5 + WSGIPassAuthorization On
  6 +
  7 + <Directory /usr/src/app/>
  8 + WSGIProcessGroup yourapplication
  9 + WSGIApplicationGroup %{GLOBAL}
  10 + WSGIScriptReloading On
  11 + Require all granted
  12 + </Directory>
  13 +</VirtualHost>
  14 +
  15 +Listen 81
  16 +
  17 +<VirtualHost *:81>
  18 + ServerName 172.26.60.101
  19 + WSGIDaemonProcess monitormanager processes=1 threads=8
  20 + WSGIScriptAlias / /usr/src/app/monitor.wsgi
  21 + WSGIPassAuthorization On
  22 + <Directory /usr/src/app/>
  23 + WSGIProcessGroup monitormanager
  24 + WSGIApplicationGroup %{GLOBAL}
  25 + WSGIScriptReloading On
  26 + Require all granted
  27 + </Directory>
  28 +</VirtualHost>
1 -flask==1.1.2  
2 -SQLAlchemy==1.3.17  
3 -Flask-SQLAlchemy==2.4.3  
4 -gevent==20.9.0  
5 -gunicorn==20.0.4  
6 -flask_cors==3.0.8  
7 -flasgger==0.9.5  
8 -GDAL==3.2.1  
9 -psycopg2==2.8.5  
10 -pyDes==2.0.1  
11 -gevent-websocket==0.10.1  
12 -Pillow==8.1.2  
13 -#Rtree==0.9.7  
14 -opencv-python==4.5.1.48  
15 -psutil==5.8.0  
16 -# mod_wsgi==4.8.0  
17 -thrift==0.13.0  
18 -Authlib==0.13  
19 -kazoo==2.8.0  
20 -paramiko==2.8.0  
21 -requests==2.26.0  
22 -schedule==1.1.0  
23 - 1 +flask==1.1.2
  2 +SQLAlchemy==1.3.17
  3 +Flask-SQLAlchemy==2.4.3
  4 +gevent==20.9.0
  5 +gunicorn==20.0.4
  6 +flask_cors==3.0.8
  7 +flasgger==0.9.5
  8 +#GDAL==3.2.1
  9 +psycopg2-binary==2.8.5
  10 +pyDes==2.0.1
  11 +gevent-websocket==0.10.1
  12 +opencv-python==4.5.1.48
  13 +mod_wsgi==4.8.0
  14 +thrift==0.13.0
  15 +Authlib==0.13
  16 +kazoo==2.8.0
  17 +paramiko==2.8.0
  18 +requests==2.26.0
  19 +schedule==1.1.0
  1 +#! /bin/sh
  2 +container_name="dmapmanager"
  3 +#停止容器
  4 +echo "正在关闭容器..."
  5 +docker stop $container_name
  6 +docker rm $container_name
  7 +
  8 +curPath=$(readlink -f $(dirname $0))
  9 +
  10 +
  11 +#设置日志权限
  12 +chmod -R 777 $curPath
  13 +
  14 +#设置端口
  15 +port=""
  16 +if [ ! -n "$1" ] ;then
  17 +port="8840"
  18 +echo "未设置端口,使用默认8840端口..."
  19 +else
  20 +port=$1
  21 +echo "端口设置为$1 ..."
  22 +fi
  23 +
  24 +port2=""
  25 +if [ ! -n "$2" ] ;then
  26 +port="8841"
  27 +echo "未设置端口2,使用默认8840端口..."
  28 +else
  29 +port2=$2
  30 +echo "端口2设置为$2 ..."
  31 +fi
  32 +
  33 +
  34 +#启动容器和apache
  35 +echo "正在启动容器..."
  36 +set="--privileged=true -e TZ="Asia/Shanghai" --restart=always -e ALLOW_IP_RANGE=0.0.0.0/0"
  37 +docker run -it -d --name $container_name $set -p ${port}:80 -p ${port2}:81 -v ${curPath}:/usr/src/app -v ${curPath}/apache2.conf:/etc/apache2/apache2.conf -v ${curPath}/dmapmanager.conf:/etc/apache2/sites-enabled/dmapmanager.conf dci/dmapserver:base
  38 +docker exec -d $container_name service apache2 start
  39 +sleep 5
  40 +curl localhost:$port/release
  41 +curl localhost:$port2
@@ -3,116 +3,72 @@ @@ -3,116 +3,72 @@
3 #createtime: 2021/7/15 3 #createtime: 2021/7/15
4 #email: nheweijun@sina.com 4 #email: nheweijun@sina.com
5 5
6 -from osgeo import gdal  
7 -  
8 -  
9 -from osgeo import gdal, gdalconst  
10 -from osgeo import ogr  
11 -import math  
12 -import requests  
13 -def tms(ytile, zoom):  
14 - n = 2.0 ** zoom  
15 - ytile = n - ytile - 1  
16 - return int(ytile)  
17 -import numpy  
18 -import cv2  
19 -from osgeo import gdal,osr 6 +from osgeo import gdal,osr,ogr
20 from osgeo.gdal import * 7 from osgeo.gdal import *
  8 +from osgeo.ogr import *
21 9
22 -# Math functions taken from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames #spellok  
23 -def deg2num(lat_deg, lon_deg, zoom):  
24 - lat_rad = math.radians(lat_deg)  
25 - n = 2.0 ** zoom  
26 - xtile = int((lon_deg + 180.0) / 360.0 * n)  
27 - ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)  
28 - return (xtile, ytile)  
29 -  
30 -def num2deg(xtile, ytile, zoom):  
31 - n = 2.0 ** zoom  
32 - lon_deg = xtile / n * 360.0 - 180.0  
33 - lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))  
34 - lat_deg = math.degrees(lat_rad)  
35 - return (lat_deg, lon_deg)  
36 -  
37 -def create_image(cls,image_type, pixel_array, quality):  
38 -  
39 - if image_type.__eq__("image/jpeg") or image_type.__eq__("image/jpg"):  
40 - r, buf = cv2.imencode(".jpg", pixel_array, [cv2.IMWRITE_JPEG_QUALITY, quality])  
41 - image_out = buf.tobytes()  
42 - else:  
43 - height, width = pixel_array[:, :, 0].shape  
44 - four = numpy.zeros((height,width), dtype=int) + 255  
45 - four[pixel_array[:, :, 0] == 65536] = 0  
46 - r, buf = cv2.imencode(".png", numpy.dstack((pixel_array, four)))  
47 - image_out = buf.tobytes()  
48 - return image_out  
49 10
50 -if __name__ == '__main__':  
51 -  
52 -  
53 -  
54 -  
55 - lev = 8  
56 - extent = [107.78981494180618, 120.43553603935675, 18.870480519260582, 25.999868757737033]  
57 - url = "http://172.26.99.160:6060/DMap/Services/GDMap/TileServer/TMSService" 11 +import json
58 12
59 13
  14 +def getInfo( path):
  15 + # driver: Driver = ogr.GetDriverByName("OpenFileGDB")
  16 + # ds: DataSource = driver.Open(path, 0)
  17 + #
  18 + #
  19 + # layer:Layer = ds.GetLayerByName("LM51130251998341HAJ00_B2")
  20 + #
  21 + # count = layer.GetFeatureCount()
  22 + #
  23 + # dd:Feature = layer.GetNextFeature()
  24 + # dd.
  25 + #
  26 + # for i in range(dd.GetFieldCount()):
  27 + # print(dd.GetField(i))
  28 + # ff = dd.GetField(1)
  29 + image: Dataset = gdal.Open(path)
60 30
61 - if extent[3] - extent[2] > extent[1] - extent[0]:  
62 - offset = ((extent[3] - extent[2]) - (extent[1] - extent[0])) / 2.0  
63 - out_extent = [extent[0]- offset, extent[1]+offset , extent[2], extent[3] ]  
64 - else:  
65 - offset = ((extent[1] - extent[0]) - (extent[3] - extent[2])) / 2.0  
66 - out_extent = [extent[0] , extent[1], extent[2] - offset, extent[3] + offset]  
67 -  
68 - c1,r1 = deg2num(18.870480519260582,107.78981494180618,lev)  
69 - c2,r2 = deg2num(25.999868757737033, 120.43553603935675, lev) 31 + geo = image.GetGeoTransform()
70 32
71 - print(r1 - r2)  
72 - print(c2 - c1) 33 + # print(image.GetSpatialRef())
73 34
74 - lat1, lon1 = num2deg(c1, r1, lev)  
75 - lat2, lon2 = num2deg(c1+1, r1+1, lev)  
76 - print( [lon1, lat2, lon2, lat1]) 35 + origin: osr.SpatialReference = osr.SpatialReference()
  36 + origin.ImportFromWkt(image.GetProjection())
77 37
78 - lat3, lon3 = num2deg(c2, r2, lev)  
79 - lat4, lon4 = num2deg(c2+1, r2+1, lev)  
80 - print( [lon3, lat4, lon4, lat3]) 38 + authority_code = origin.GetAuthorityCode(None)
81 39
82 - dat = numpy.zeros(((r1 - r2+1)*256, (c2 - c1+1)*256, 3), dtype=int) + 256 40 + band_count = image.RasterCount
  41 + band: Band = image.GetRasterBand(1)
83 42
  43 + count = band.GetOverviewCount()
  44 + nodatavalue = band.GetNoDataValue()
84 45
85 - offx = (extent[0]-lon1)/((lon4-lon1)/((c2 - c1+1)*256)) 46 + left_top = (geo[0], geo[3])
  47 + right_buttom = (geo[0] + geo[1] * image.RasterXSize, geo[3] + geo[5] * image.RasterYSize)
86 48
87 - xnum = (extent[1]-extent[0])/((lon4-lon1)/((c2 - c1+1)*256)) 49 + origin_extent = [left_top[0], right_buttom[1], right_buttom[0], left_top[1]]
88 50
89 - print(offx)  
90 - print(xnum) 51 + info = {"band_count": band_count,
  52 + "overview_count": count,
  53 + "xy_size": [image.RasterXSize, image.RasterYSize],
  54 + "origin_extent": origin_extent,
  55 + "null_value": nodatavalue,
  56 + "crs_wkt": image.GetProjection(),
  57 + "crs": authority_code,
  58 + "crs_proj4": origin.ExportToProj4(),
  59 + "size": os.path.getsize(path),
  60 + "path": path,
  61 + "cell_x_size": geo[1],
  62 + "cell_y_size": geo[5]}
91 63
92 - offy = (lat3 - extent[3])/((lat3-lat2)/((r1 - r2+1)*256))  
93 - ynum = (extent[3]-extent[2])/((lat3-lat2)/((r1 - r2+1)*256))  
94 - print(offy)  
95 - print(ynum)  
96 -  
97 -  
98 - for r in range(r2,r1+1):  
99 - for c in range(c1,c2+1):  
100 - url = "http://172.26.99.160:6060/DMap/Services/GDMap/TileServer/TMSService/{}/{}/{}.png".format(lev,c,r)  
101 - dataset:Dataset = gdal.Open(url, 0)  
102 - for b in range(1,4):  
103 - band:Band = dataset.GetRasterBand(b)  
104 - zaa = (r - r2)*256  
105 - zbb = (c - c1)*256  
106 - zcc = (r - r2+1)*256  
107 - zdd = (c - c1+1)*256  
108 -  
109 - dat[(r - r2)*256:(r - r2+1)*256,(c - c1)*256 : (c - c1+1)*256, 2-(b-1)] = band.ReadAsArray(0,0,256,256) 64 + del image
  65 + return json.dumps(info)
110 66
  67 +if __name__ == '__main__':
111 68
112 - dat2 = dat[int(offy):int(offy+ynum),int(offx):int(offx+xnum),:] 69 + path = r"E:\Data\zh.gdb"
  70 + print(getInfo(path))
113 71
114 - cv2.imwrite("t.jpg", dat, [cv2.IMWRITE_JPEG_QUALITY, 30])  
115 - cv2.imwrite("t2.jpg", dat2, [cv2.IMWRITE_JPEG_QUALITY, 30])  
116 72
117 73
118 74
1 -#增加table_vacuate connectstr 1 +#
注册登录 后发表评论