提交 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
\ No newline at end of file
... ...
  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"
\ No newline at end of file
... ...
... ... @@ -17,6 +17,7 @@ from . import database_edit
17 17 from . import database_alias_check
18 18 from . import database_connect_test
19 19 from . import database_info
  20 +from . import database_detail
20 21
21 22 class DataManager(BlueprintApi):
22 23
... ... @@ -88,10 +89,19 @@ class DataManager(BlueprintApi):
88 89
89 90
90 91 @staticmethod
91   - @bp.route('/Info', methods=['POST'])
  92 + @bp.route('/Info', methods=["POST"])
92 93 @swag_from(database_info.Api.api_doc)
93 94 def api_database_info():
94 95 """
95 96 数据源信息
96 97 """
97   - return database_info.Api().result
\ No newline at end of file
  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
\ No newline at end of file
... ...
  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 93 }
94 94 }
95 95 }
96   - }
  96 + }
\ No newline at end of file
... ...
... ... @@ -45,11 +45,13 @@ class Api(ApiTemplate):
45 45 datab_json = ModelVisitor.database_to_json(datab)
46 46 datab_json["table_count"] = table_count
47 47 datab_json["available"] = available
  48 + del datab_json["connectstr"]
48 49 res["data"]["list"].append(datab_json)
49 50
50 51 # 可用非可用排序
51 52 sorted_list = [dat for dat in res["data"]["list"] if dat["available"]==1]
52 53 sorted_list.extend([dat for dat in res["data"]["list"] if dat["available"] == -1])
  54 +
53 55 res["data"]["list"] = sorted_list
54 56 res["result"]=True
55 57 except Exception as e:
... ...
... ... @@ -14,7 +14,7 @@ from . import feature_delete
14 14 from . import feature_schema
15 15 from . import feature_edit
16 16
17   -class DataManager(BlueprintApi):
  17 +class DataManager():
18 18
19 19 bp = Blueprint("FeatureService", __name__, url_prefix="/API/FeatureService")
20 20 service_type = []
... ...
... ... @@ -115,7 +115,7 @@ class Api(ApiTemplate):
115 115
116 116 task:Task = task_writer.session.query(Task).filter_by(guid=task_guid).one_or_none()
117 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 121 metas: list = json.loads(parameter.get("meta").__str__())
... ... @@ -132,7 +132,7 @@ class Api(ApiTemplate):
132 132 origin_name = layer_name
133 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 136 InsertingLayerName).filter_by(name=layer_name).one_or_none():
137 137 layer_name = origin_name + "_{}".format(no)
138 138 no += 1
... ...
... ... @@ -23,6 +23,7 @@ from . import table_vacuate_info
23 23 from . import table_vacuate_ref
24 24 from . import table_vacuate_delete
25 25 from . import field_value
  26 +from . import table_check
26 27 class DataManager(BlueprintApi):
27 28
28 29 bp = Blueprint("DataManager", __name__, url_prefix="/API/Manager")
... ... @@ -93,6 +94,15 @@ class DataManager(BlueprintApi):
93 94 """
94 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 107 @staticmethod
98 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 + }
\ No newline at end of file
... ...
... ... @@ -58,7 +58,7 @@ class Api(ApiTemplate):
58 58
59 59 if Task.query.filter_by(table_guid=table_guid,state=0).one_or_none():
60 60 res["result"] = False
61   - res["msg"] = "数据精化中!"
  61 + res["msg"] = "矢量金字塔构建中!"
62 62 return res
63 63 if table.table_type==0:
64 64 res["result"] = False
... ... @@ -73,7 +73,7 @@ class Api(ApiTemplate):
73 73
74 74
75 75 task = Task(guid=task_guid,
76   - name="{}精化".format(table.name),
  76 + name="{}矢量金字塔构建".format(table.name),
77 77 table_guid=table_guid,
78 78 create_time=datetime.datetime.now(),
79 79 state=0,
... ... @@ -81,14 +81,14 @@ class Api(ApiTemplate):
81 81 creator=self.para.get("creator"),
82 82 file_name=None,
83 83 database_guid=table.database_guid,
84   - process="精化中",
  84 + process="构建中",
85 85 task_pid= vacuate_process.pid
86 86 # parameter=",".join([str(x) for x in ref_grids])
87 87 )
88 88
89 89 db.session.add(task)
90 90 db.session.commit()
91   - res["msg"] = "图层抽稀已提交!"
  91 + res["msg"] = "矢量金字塔构建已提交!"
92 92 res["data"] = task_guid
93 93 res["result"] = True
94 94
... ... @@ -113,8 +113,8 @@ class Api(ApiTemplate):
113 113 task_writer = TaskWriter(task_guid)
114 114
115 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 119 database = task_writer.session.query(Database).filter_by(guid=table.database_guid).one_or_none()
120 120 database_sqlalchemy_uri = str(database.sqlalchemy_uri)
... ... @@ -167,13 +167,13 @@ class Api(ApiTemplate):
167 167 connectstr=DES.encode(connectstr))
168 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 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 174 except Exception as e:
175 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 177 task_writer.update_table(table.guid, {"is_vacuate": 0, "update_time": datetime.datetime.now()})
178 178 task_writer.update_process( e.__str__())
179 179 task_writer.update_process("任务中止!")
... ...
... ... @@ -58,7 +58,7 @@ class Api(ApiTemplate):
58 58
59 59 if Task.query.filter_by(table_guid=table_guid,state=0).one_or_none():
60 60 res["result"] = False
61   - res["msg"] = "数据精化中!"
  61 + res["msg"] = "矢量金字塔构建中!"
62 62 return res
63 63 if table.table_type==0:
64 64 res["result"] = False
... ... @@ -73,7 +73,7 @@ class Api(ApiTemplate):
73 73
74 74
75 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 77 table_guid=table_guid,
78 78 create_time=datetime.datetime.now(),
79 79 state=0,
... ... @@ -81,13 +81,13 @@ class Api(ApiTemplate):
81 81 creator=self.para.get("creator"),
82 82 file_name=None,
83 83 database_guid=table.database_guid,
84   - process="精化中",
  84 + process="构建中",
85 85 parameter=self.para.get("grids"),
86 86 task_pid=vacuate_process.pid)
87 87
88 88 db.session.add(task)
89 89 db.session.commit()
90   - res["msg"] = "图层抽稀已提交!"
  90 + res["msg"] = "矢量金字塔构建已提交!"
91 91 res["data"] = task_guid
92 92 res["result"] = True
93 93
... ... @@ -113,8 +113,8 @@ class Api(ApiTemplate):
113 113 task_writer = TaskWriter(task_guid)
114 114
115 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 119 database = task_writer.session.query(Database).filter_by(guid=table.database_guid).one_or_none()
120 120 database_sqlalchemy_uri = str(database.sqlalchemy_uri)
... ... @@ -168,13 +168,13 @@ class Api(ApiTemplate):
168 168 pixel_distance=vacuate_process.this_gridsize[l],
169 169 connectstr=DES.encode(connectstr))
170 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 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 175 except Exception as e:
176 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 178 task_writer.update_table(table.guid, {"is_vacuate": origin_vacuate, "update_time": datetime.datetime.now()})
179 179 task_writer.update_process( e.__str__())
180 180 task_writer.update_process("任务中止!")
... ...
... ... @@ -8,7 +8,7 @@ from ..models import Table,Database,DES
8 8 from sqlalchemy.engine import ResultProxy
9 9 from app.util.component.ApiTemplate import ApiTemplate
10 10 from app.util.component.PGUtil import PGUtil
11   -
  11 +import json
12 12 class Api(ApiTemplate):
13 13 api_name = "数据浏览"
14 14 def process(self):
... ... @@ -35,27 +35,35 @@ class Api(ApiTemplate):
35 35
36 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 40 res["data"]["list"]=[]
39 41 for row_proxy in query_result:
  42 + pkey_dict = {}
40 43 d = {}
41 44 for column, value in row_proxy.items():
42 45 #跳过空间列
43 46 if geom_col:
44 47 if column.__eq__(geom_col):
45 48 continue
  49 + if pkey:
  50 + if column == pkey:
  51 + pkey_dict[column]=value
  52 + continue
46 53 #格式化时间列
47 54 if isinstance(value, datetime.datetime):
48 55 d[column] = value.strftime('%Y-%m-%d %H:%M:%S')
49 56 else:
50 57 d[column]=value
51   - res["data"]["list"].append(d)
  58 + pkey_dict.update(d)
  59 + res["data"]["list"].append(pkey_dict)
52 60 res["result"]=True
53 61 except Exception as e:
54 62 raise Exception("数据库连接失败!")
55 63 finally:
56 64 if db_session:
57 65 db_session.close()
58   - return res
  66 + return json.dumps(res)
59 67
60 68 api_doc={
61 69 "tags":["管理接口"],
... ...
... ... @@ -73,7 +73,7 @@ class Api(ApiTemplate):
73 73 task_process = Process(guid=uuid.uuid1().__str__(), message=message, time=datetime.datetime.now(),
74 74 task_guid=task.guid)
75 75
76   - db.add(task_process)
  76 + db.session.add(task_process)
77 77 db.session.commit()
78 78 return None
79 79
... ...
... ... @@ -14,6 +14,7 @@ from . import service_delete
14 14 from . import service_state
15 15 from . import service_info
16 16 from . import service_edit
  17 +from . import service_reload
17 18 import os
18 19 from flask import send_from_directory
19 20
... ... @@ -88,6 +89,14 @@ class DataManager(BlueprintApi):
88 89 """
89 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 102 @staticmethod
... ...
... ... @@ -12,7 +12,7 @@ from . import service_engine_delete
12 12 from . import service_engine_edit
13 13 from . import service_engine_list
14 14 from . import service_engine_info
15   -
  15 +from . import service_engine_deploy
16 16 class EngineManager(BlueprintApi):
17 17
18 18 bp = Blueprint("Engine", __name__, url_prefix="/API/Service/Engine")
... ... @@ -62,3 +62,13 @@ class EngineManager(BlueprintApi):
62 62 Engine Delete
63 63 """
64 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
\ No newline at end of file
... ...
... ... @@ -4,16 +4,21 @@
4 4 #email: nheweijun@sina.com
5 5
6 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 8 class Api(ApiTemplate):
9 9 api_name = "注销服务引擎"
10 10 def process(self):
11 11 res = {}
12 12 try:
13 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 16 if not service_engine:
16 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 22 db.session.delete(service_engine)
18 23 db.session.commit()
19 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 + }
\ No newline at end of file
... ...
... ... @@ -48,7 +48,7 @@ class Api(ApiTemplate):
48 48 {"name": "type",
49 49 "in": "formData",
50 50 "type": "string",
51   - "enum":["ImageServer"]},
  51 + "enum":["ImageServer","AddServer"]},
52 52 ],
53 53 "responses": {
54 54 200: {
... ...
... ... @@ -5,10 +5,10 @@
5 5
6 6 from app.util.component.ApiTemplate import ApiTemplate
7 7 import requests
8   -from app.modules.service.models import ServiceEngine,db
  8 +from app.modules.service.models import ServiceEngine,db,Service
9 9 import datetime
10 10 import uuid
11   -
  11 +import configure
12 12 class Api(ApiTemplate):
13 13 api_name = "注册服务引擎"
14 14 def process(self):
... ... @@ -16,15 +16,41 @@ class Api(ApiTemplate):
16 16 try:
17 17 url = self.para.get("url")
18 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 24 if response.status_code != 200:
21 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 30 name=name if name else response.json().get("Name"),
24 31 url=url,
25 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 54 db.session.add(service_engine)
29 55 db.session.commit()
30 56 res["result"] = True
... ...
... ... @@ -18,7 +18,7 @@ class Api(ApiTemplate):
18 18 url = "{}/API/Service/Register".format(self.para.get("url"))
19 19 response:requests.Response = requests.post(url,data=self.para)
20 20 if not response.json().get("result"):
21   - raise Exception("由于{}影像服务注册失败!".format(response.json().get("msg")))
  21 + raise Exception("由于{}影像服务注册失败!".format(response.json().get("msg")))
22 22 res["result"] = True
23 23 except Exception as e:
24 24 raise e
... ...
... ... @@ -27,15 +27,16 @@ class Api(ApiTemplate):
27 27
28 28
29 29 service_update = {"update_time":this_time}
30   - map_service_update = {"updatetime":this_time}
  30 + map_service_update = {}
  31 +
31 32 for key in self.para.keys():
32 33 if key in ["name","title","state","description","overview","catalog_guid"]:
33 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 36 map_service_update[key] = self.para.get(key)
37 37
38 38
  39 +
39 40 # 修改功能
40 41 if functions:
41 42 new_types = functions.split(",")
... ... @@ -97,48 +98,15 @@ class Api(ApiTemplate):
97 98 "type": "string",
98 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 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 107 "in": "formData",
140 108 "type": "string",
141   - "description": "[地图服务]thumbnail"},
  109 + "description": "[地图服务]project"},
142 110
143 111 ],
144 112 "responses": {
... ...
... ... @@ -9,6 +9,9 @@ import uuid
9 9 from ..models import Service,db,MapService,ServiceFunction
10 10 import datetime
11 11 import configure
  12 +import requests
  13 +import json
  14 +
12 15 class Api(ApiTemplate):
13 16
14 17 api_name = "注册MapService服务"
... ... @@ -22,23 +25,38 @@ class Api(ApiTemplate):
22 25 this_time = datetime.datetime.now()
23 26 service_guid = uuid.uuid1().__str__()
24 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 48 service = Service(
32 49 guid = service_guid,
33 50 name = self.para.get("name"),
34 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 54 create_time = this_time,
37 55 update_time = this_time,
38 56 description = self.para.get("description"),
39 57 #node = Column(Integer),
40 58 node = 1 ,
41   - overview = "xxxx",
  59 + overview = resp_json["url"],
42 60 type = self.para.get("type"),
43 61 catalog_guid = self.para.get("catalog_guid")
44 62 )
... ... @@ -46,41 +64,22 @@ class Api(ApiTemplate):
46 64 map_service = MapService(
47 65 guid = map_service_guid,
48 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 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 77 db.session.add(service)
69 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 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 83 res["data"] = service_guid
85 84 res["result"] = True
86 85 except Exception as e:
... ... @@ -108,7 +107,7 @@ class Api(ApiTemplate):
108 107 {"name": "type",
109 108 "in": "formData",
110 109 "type": "string",
111   - "enum": ["地图服务", "切片服务", "影像服务"],
  110 + "enum": ["地图服务"],
112 111 "required": "true",
113 112 "description": "[地图服务,切片服务,影像服务]"},
114 113 {"name": "catalog_guid",
... ... @@ -117,50 +116,16 @@ class Api(ApiTemplate):
117 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 121 "in": "formData",
142   - "type": "string",
143   - "description": "[地图服务]ssupply"},
144   - {"name": "sctime",
  122 + "type": "int",
  123 + "description": "[地图服务]"},
  124 + {"name": "project",
145 125 "in": "formData",
146 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 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")
\ No newline at end of file
... ...
  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 29 type = Column(String(256)) #地图服务,影像服务,切片服务
30 30 # 目录外键
31 31 catalog_guid = Column(String(256), ForeignKey('dmap_service_catalog.guid'))
32   -
  32 + # 创建者
  33 + creator = Column(String(256))
33 34 url = Column(String(256))
34 35
35 36 relate_service_functions = relationship('ServiceFunction', backref='relate_service', lazy='dynamic')
... ... @@ -76,6 +77,9 @@ class TileScheme(db.Model):
76 77 extent = Column(Text)
77 78 top_left = Column(String(256))
78 79
  80 + # 创建者
  81 + creator = Column(String(256))
  82 +
79 83 levels = Column(Text)
80 84 dpi = Column(Integer)
81 85 rows = Column(Integer)
... ... @@ -141,23 +145,11 @@ class MapService(db.Model):
141 145 guid = Column(String(256), primary_key=True)
142 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 153 service_guid = Column(String,ForeignKey('dmap_service.guid'))
162 154
163 155 class ServiceEngine(db.Model):
... ...
... ... @@ -45,6 +45,7 @@ class Api(ApiTemplate):
45 45 crs_wkt = data.get("crs_wkt"),
46 46 extent = data.get("extent"),
47 47 top_left = data.get("top_left"),
  48 + creator= data.get("creator"),
48 49 # ymin = extent[1],
49 50 # xmax = extent[2],
50 51 # ymax = extent[3],
... ... @@ -77,6 +78,9 @@ class Api(ApiTemplate):
77 78 {"name": "alias",
78 79 "in": "formData",
79 80 "type": "string"},
  81 + {"name": "creator",
  82 + "in": "formData",
  83 + "type": "string"},
80 84 {"name": "description",
81 85 "in": "formData",
82 86 "type": "string"},
... ...
... ... @@ -27,18 +27,22 @@ class Api(ApiTemplate):
27 27 service = Service.query.filter_by(guid=guid).one_or_none()
28 28
29 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 46 db.session.delete(service)
43 47
44 48 else:
... ...
... ... @@ -149,47 +149,15 @@ class Api(ApiTemplate):
149 149 "type": "string",
150 150 "description": "[切片服务]图层描述"},
151 151
152   - # WMS参数
153   - {"name": "status",
  152 + #地图服务参数
  153 + {"name": "capabilities",
154 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 158 "in": "formData",
191 159 "type": "string",
192   - "description": "[地图服务]thumbnail"},
  160 + "description": "[地图服务]project"},
193 161 ],
194 162 "responses": {
195 163 200: {
... ...
... ... @@ -64,7 +64,7 @@ class Api(ApiTemplate):
64 64
65 65 for ie in image_engines:
66 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 68 if not response.json().get("result"):
69 69 raise Exception("修改影像服务失败!")
70 70 else:
... ... @@ -95,7 +95,7 @@ class Api(ApiTemplate):
95 95 # update时间倒数
96 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 99 res["result"] = True
100 100
101 101 except Exception as e:
... ...
... ... @@ -59,7 +59,8 @@ class Api(ApiTemplate):
59 59
60 60 for ie in image_engines:
61 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 64 if not response.json().get("result"):
64 65 raise Exception("修改影像服务失败!")
65 66 else:
... ... @@ -71,7 +72,7 @@ class Api(ApiTemplate):
71 72
72 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 76 res["result"] = True
76 77
77 78 except Exception as e:
... ...
... ... @@ -52,6 +52,10 @@ class Api(ApiTemplate):
52 52 "type": "string",
53 53 "description": "[地图服务,切片服务,影像服务]"},
54 54
  55 + {"name": "creator",
  56 + "in": "formData",
  57 + "type": "string"},
  58 +
55 59 {"name": "url",
56 60 "in": "formData",
57 61 "type": "string"},
... ... @@ -142,46 +146,14 @@ class Api(ApiTemplate):
142 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 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 154 "in": "formData",
183 155 "type": "string",
184   - "description": "[地图服务]thumbnail"},
  156 + "description": "[地图服务]project"},
185 157
186 158 ],
187 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 + }
\ No newline at end of file
... ...
... ... @@ -19,7 +19,7 @@ class Api(ApiTemplate):
19 19
20 20
21 21 #删除本地服务
22   - if s_type in ["切片服务","地图服务"]:
  22 + if s_type in ["切片服务","地图服务","地址匹配"]:
23 23 service = Service.query.filter_by(guid=guid).one_or_none()
24 24
25 25 if service:
... ... @@ -35,7 +35,6 @@ class Api(ApiTemplate):
35 35 api.para = self.para
36 36 res = api.process()
37 37
38   -
39 38 except Exception as e:
40 39 raise e
41 40 return res
... ... @@ -55,7 +54,7 @@ class Api(ApiTemplate):
55 54 {"name": "url",
56 55 "in": "formData",
57 56 "type": "string",
58   - "description": "type"},
  57 + "description": "url"},
59 58 {"name": "state",
60 59 "in": "formData",
61 60 "type": "int",
... ...
... ... @@ -46,7 +46,7 @@ class DataManager(BlueprintApi):
46 46 return tile_service_edit.Api().result
47 47
48 48 @staticmethod
49   - @bp.route('/Reload', methods=['GET'])
  49 + @bp.route('/Reload', methods=['POST','GET'])
50 50 @swag_from(tile_service_reload.Api.api_doc)
51 51 def api_tile_service_reload():
52 52 """
... ... @@ -54,3 +54,5 @@ class DataManager(BlueprintApi):
54 54 """
55 55 return tile_service_reload.Api().result
56 56
  57 +
  58 +
... ...
... ... @@ -4,6 +4,7 @@
4 4 #email: nheweijun@sina.com
5 5
6 6 from app.util.component.ApiTemplate import ApiTemplate
  7 +from app.util.component.StructuredPrint import StructurePrint
7 8 from app.util.component.ModelVisitor import ModelVisitor
8 9 import uuid
9 10 from ..models import TileService,Service,db,ServiceFunction,TileScheme
... ... @@ -38,25 +39,29 @@ class Api(ApiTemplate):
38 39 tile_update["scheme"] = json.dumps(ModelVisitor.object_to_json(tilesche))
39 40
40 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 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 46 ts_json = ModelVisitor.object_to_json(ts)
45 47 ts_json.update(tile_update)
  48 +
46 49 project_file = ProjectFile.create(ts_json)
47 50
48 51 para = {"name":self.para.get("name") if self.para.get("name") else se.name,
49 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 59 resp.encoding="utf-8"
56 60 resp_json = resp.json()
57   - if not resp_json["status"].__eq__("true"):
  61 + if not resp_json["status"].__eq__("1"):
58 62 raise Exception("调用切片服务的注册服务接口失败!")
59 63
  64 + service_update["overview"] = resp_json["url"]
60 65 #修改数据库
61 66 tile_service = TileService.query.filter_by(service_guid=guid)
62 67 tile_type = self.para.get("tile_type")
... ...
... ... @@ -31,28 +31,32 @@ class Api(ApiTemplate):
31 31 # 调用切片服务的注册服务接口
32 32
33 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 44 resp.encoding="utf-8"
40 45 resp_json = resp.json()
41   - if not resp_json["status"].__eq__("true"):
  46 + if not resp_json["status"]=="1":
42 47 raise Exception("调用切片服务的注册服务接口失败!")
43 48
44 49 service = Service(
45 50 guid = service_guid,
46 51 name = self.para.get("name"),
47 52 title = self.para.get("title"),
  53 + creator= self.para.get("creator"),
48 54 state = 1,
49 55 create_time = this_time,
50 56 update_time = this_time,
51 57 description = self.para.get("description"),
52 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 60 type = self.para.get("type"),
57 61 catalog_guid = self.para.get("catalog_guid")
58 62 )
... ... @@ -85,7 +89,7 @@ class Api(ApiTemplate):
85 89
86 90 scheme=self.para.get("scheme"),
87 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 95 service_function = ServiceFunction(guid=service_function_guid,
... ...
... ... @@ -5,7 +5,7 @@
5 5
6 6
7 7 from app.util.component.ApiTemplate import ApiTemplate
8   -from ..models import TileService,db,Service
  8 +from ..models import TileService,db,Service,MapService
9 9 import configure
10 10 from app.util.component.ModelVisitor import ModelVisitor
11 11
... ... @@ -19,16 +19,21 @@ class Api(ApiTemplate):
19 19 def process(self):
20 20 res = {}
21 21 try:
22   - tile_services = TileService.query.join(Service).filter(Service.type=="切片服务").all()
  22 +
23 23 res["data"] = {}
24   - res["data"]["count"] = len(tile_services)
  24 +
25 25 res["data"]["list"] = []
  26 +
  27 + #切片服务
  28 + tile_services = TileService.query.join(Service).filter(Service.type == "切片服务").all()
26 29 for ts in tile_services:
27 30 project_file = ProjectFile.create(ModelVisitor.object_to_json(ts))
28 31 service:Service = Service.query.filter_by(guid=ts.service_guid).one_or_none()
29 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 34 res["data"]["list"].append(para)
  35 +
  36 + res["data"]["count"] = len(tile_services)
32 37 res["result"] = True
33 38 except Exception as e:
34 39 raise Exception("数据库错误!")
... ...
... ... @@ -6,6 +6,7 @@
6 6
7 7 from app.modules.service.models import TileScheme
8 8 from app.util.component.ModelVisitor import ModelVisitor
  9 +from app.util.component.StructuredPrint import StructurePrint
9 10 import json
10 11 import base64
11 12
... ... @@ -40,8 +41,8 @@ class ProjectFile:
40 41 <maplayer name="{name}" alias="{alias}" type="0">
41 42 <extent>
42 43 <xmin>{xmin}</xmin>
43   - <ymin>{xmax}</ymin>
44   - <xmax>{ymin}</xmax>
  44 + <ymin>{ymin}</ymin>
  45 + <xmax>{xmax}</xmax>
45 46 <ymax>{ymax}</ymax>
46 47 </extent>
47 48 <style>{layer_style}</style>
... ... @@ -126,7 +127,7 @@ class ProjectFile:
126 127 <maplayer name="{name}" alias="{alias}" type="0">
127 128 <extent>
128 129 <xmin>{xmin}</xmin>
129   - <ymin>{xmax}</ymin>
  130 + <ymin>{ymin}</ymin>
130 131 <xmax>{xmax}</xmax>
131 132 <ymax>{ymax}</ymax>
132 133 </extent>
... ...
... ... @@ -71,6 +71,26 @@ class PGUtil:
71 71 return geom_col
72 72
73 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 94 def get_table_count(cls,table_name,db_session):
75 95 count_result = db_session.execute('''SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public."{}"'::regclass'''.format(
76 96 table_name)).fetchone()
... ...
... ... @@ -107,7 +107,28 @@ def get_rc(parameter,l,lon,lat):
107 107
108 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 133 lev = 0
113 134 r1 = 0
... ...
... ... @@ -4,8 +4,7 @@ import logging
4 4 deploy_ip_host = "172.26.40.105:8840"
5 5 # 系统数据库
6 6
7   -SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.60.100:5432/dmap_manager_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 9 # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中
11 10 #VACUATE_DB_URI = None
... ... @@ -13,9 +12,10 @@ VACUATE_DB_URI = SQLALCHEMY_DATABASE_URI
13 12
14 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 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>
\ No newline at end of file
... ...
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 3 #createtime: 2021/7/15
4 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 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 +#
... ...
注册登录 后发表评论