正在显示
115 个修改的文件
包含
2119 行增加
和
1800 行删除
... | ... | @@ -8,7 +8,7 @@ from sqlalchemy.sql.expression import true |
8 | 8 | import configure |
9 | 9 | from app.util import BlueprintApi |
10 | 10 | from app.util import find_class |
11 | -from app.models import db, Table, InsertingLayerName, Database, DES, Task | |
11 | +from app.models import db | |
12 | 12 | from app.modules.auth.oauth2 import config_oauth, myCodeIDToken |
13 | 13 | from flasgger import Swagger |
14 | 14 | import logging | ... | ... |
1 | 1 | # coding=utf-8 |
2 | -import base64 | |
3 | -import os | |
4 | -from flask_sqlalchemy import SQLAlchemy,Model | |
5 | -import importlib | |
6 | -from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Time,Float,Binary | |
7 | -from sqlalchemy.orm import relationship | |
8 | -import base64 | |
9 | -from pyDes import * | |
10 | -import datetime | |
11 | 2 | |
12 | -from app.util.component.PGUtil import PGUtil | |
3 | +import os | |
4 | +from flask_sqlalchemy import SQLAlchemy | |
13 | 5 | import glob |
14 | 6 | import traceback |
7 | +from pyDes import des,PAD_PKCS5,ECB | |
8 | + | |
9 | +import base64 | |
15 | 10 | class DES(): |
16 | 11 | ''' |
17 | 12 | DES密码加解密 |
... | ... | @@ -33,232 +28,6 @@ class DES(): |
33 | 28 | |
34 | 29 | db = SQLAlchemy() |
35 | 30 | |
36 | - | |
37 | -class Table(db.Model): | |
38 | - ''' | |
39 | - 数据表元数据 | |
40 | - ''' | |
41 | - __tablename__ = 'dmap_table' | |
42 | - guid = Column(String(256), primary_key=True) | |
43 | - # 数据源外键 | |
44 | - database_guid = Column(String(256), ForeignKey('dmap_database.guid')) | |
45 | - | |
46 | - # 点线面123 | |
47 | - table_type = Column(Integer) | |
48 | - | |
49 | - name = Column(String(256)) | |
50 | - alias = Column(Text) | |
51 | - create_time = Column(DateTime) | |
52 | - update_time = Column(DateTime) | |
53 | - | |
54 | - feature_count = Column(Integer) | |
55 | - | |
56 | - description = Column(Text) | |
57 | - extent = Column(Text) | |
58 | - | |
59 | - #用户 | |
60 | - creator = Column(Text) | |
61 | - #是否已抽稀 | |
62 | - is_vacuate=Column(Integer,default=0) | |
63 | - | |
64 | - # 目录外键 | |
65 | - catalog_guid = Column(String(256), ForeignKey('dmap_catalog.guid')) | |
66 | - | |
67 | - relate_columns = relationship('Columns', backref='relate_table', lazy='dynamic') | |
68 | - relate_table_vacuates = relationship('TableVacuate', backref='relate_table', lazy='dynamic') | |
69 | - | |
70 | - | |
71 | -class TableVacuate(db.Model): | |
72 | - ''' | |
73 | - sub数据表元数据 | |
74 | - ''' | |
75 | - __tablename__ = 'dmap_table_vacuate' | |
76 | - guid = Column(String(256), primary_key=True) | |
77 | - name = Column(String(256)) | |
78 | - level = Column(Integer) | |
79 | - pixel_distance = Column(Float) | |
80 | - table_guid = Column(String(256), ForeignKey('dmap_table.guid')) | |
81 | - | |
82 | - #所在的库 | |
83 | - connectstr= Column(Text) | |
84 | - | |
85 | -class Columns(db.Model): | |
86 | - ''' | |
87 | - 数据表的列 | |
88 | - ''' | |
89 | - __tablename__ = 'dmap_column' | |
90 | - guid = Column(String(256), primary_key=True) | |
91 | - # 表外键 | |
92 | - table_guid= Column(String(256), ForeignKey('dmap_table.guid')) | |
93 | - name=Column(String(256)) | |
94 | - alias = Column(String(256)) | |
95 | - create_time = Column(DateTime) | |
96 | - update_time = Column(DateTime) | |
97 | - | |
98 | -class Task(db.Model): | |
99 | - ''' | |
100 | - 任务表 | |
101 | - ''' | |
102 | - __tablename__ = 'dmap_task' | |
103 | - guid = Column(String(256), primary_key=True) | |
104 | - name = Column(Text) | |
105 | - process = Column(Text) | |
106 | - create_time = Column(DateTime) | |
107 | - update_time = Column(DateTime) | |
108 | - state = Column(Integer) | |
109 | - #数据源外键 | |
110 | - database_guid = Column(String(256), ForeignKey('dmap_database.guid')) | |
111 | - #目录外键 | |
112 | - catalog_guid = Column(String(256), ForeignKey('dmap_catalog.guid')) | |
113 | - #抽稀任务指定表的guid | |
114 | - table_guid = Column(String(256)) | |
115 | - #任务类型 | |
116 | - #1:入库任务 | |
117 | - #2:抽稀任务 | |
118 | - #3:数据库刷新任务 | |
119 | - #4:影像金字塔任务 | |
120 | - #5:数据下载任务 | |
121 | - task_type=Column(Integer) | |
122 | - creator = Column(Text) | |
123 | - file_name = Column(Text) | |
124 | - relate_processes = relationship('Process', backref='relate_task', lazy='dynamic') | |
125 | - # 入库参数 | |
126 | - parameter= Column(Text) | |
127 | - | |
128 | - | |
129 | - | |
130 | -class Process(db.Model): | |
131 | - ''' | |
132 | - 过程信息表 | |
133 | - ''' | |
134 | - __tablename__ = 'dmap_process' | |
135 | - guid = Column(String(256), primary_key=True) | |
136 | - # 任务外键 | |
137 | - task_guid = Column(String(256), ForeignKey('dmap_task.guid')) | |
138 | - time = Column(DateTime) | |
139 | - message = Column(Text) | |
140 | - | |
141 | - | |
142 | -class Catalog(db.Model): | |
143 | - ''' | |
144 | - 目录表 | |
145 | - ''' | |
146 | - __tablename__ = 'dmap_catalog' | |
147 | - guid = Column(String(256), primary_key=True) | |
148 | - database_guid = Column(String(256), ForeignKey('dmap_database.guid')) | |
149 | - pguid = Column(String(256)) | |
150 | - path = Column(Text) | |
151 | - name = Column(String(256)) | |
152 | - sort = Column(Integer) | |
153 | - description = Column(Text) | |
154 | - relate_tables = relationship('Table', backref='relate_catalog', lazy='dynamic') | |
155 | - relate_tasks = relationship('Task', backref='relate_catalog', lazy='dynamic') | |
156 | - | |
157 | - | |
158 | -class Database(db.Model): | |
159 | - ''' | |
160 | - 数据源表 | |
161 | - ''' | |
162 | - __tablename__ = 'dmap_database' | |
163 | - guid = Column(String(256), primary_key=True) | |
164 | - name = Column(String(256)) | |
165 | - alias = Column(String(256)) | |
166 | - sqlalchemy_uri = Column(String(256)) | |
167 | - description = Column(Text) | |
168 | - # 唯一性约束,不能注册相同连接的库 | |
169 | - connectstr= Column(Text,unique=True) | |
170 | - creator = Column(String(256)) | |
171 | - create_time = Column(DateTime) | |
172 | - update_time = Column(DateTime) | |
173 | - relate_catalogs = relationship('Catalog', backref='relate_database', lazy='dynamic') | |
174 | - relate_tables = relationship('Table', backref='relate_database', lazy='dynamic') | |
175 | - relate_tasks = relationship('Task', backref='relate_database', lazy='dynamic') | |
176 | - | |
177 | - | |
178 | - | |
179 | -class InsertingLayerName(db.Model): | |
180 | - ''' | |
181 | - 正在入库的数据 | |
182 | - ''' | |
183 | - __tablename__ = 'dmap_iln' | |
184 | - guid = Column(String(256), primary_key=True) | |
185 | - task_guid = Column(String(256)) | |
186 | - name = Column(String(256)) | |
187 | - | |
188 | - | |
189 | -class Service(db.Model): | |
190 | - ''' | |
191 | - ''' | |
192 | - __tablename__ = 'dmap_service' | |
193 | - guid = Column(String(256), primary_key=True) | |
194 | - name = Column(String(256)) | |
195 | - # alias = Column(String(256)) | |
196 | - | |
197 | - title = Column(String(256)) | |
198 | - | |
199 | - #服务状态 | |
200 | - state= Column(Integer) | |
201 | - create_time = Column(DateTime) | |
202 | - update_time = Column(DateTime) | |
203 | - #服务描述 | |
204 | - description = Column(Text) | |
205 | - #服务节点 | |
206 | - node = Column(Integer) | |
207 | - #服务缩略图 | |
208 | - overview = Column(Text) | |
209 | - #服务类型 | |
210 | - type = Column(String(256)) | |
211 | - #具体服务id | |
212 | - service_guid = Column(String(256)) | |
213 | - # 目录外键 | |
214 | - catalog_guid = Column(String(256), ForeignKey('dmap_service_catalog.guid')) | |
215 | - | |
216 | - | |
217 | -class ServiceCatalog(db.Model): | |
218 | - ''' | |
219 | - 目录表 | |
220 | - ''' | |
221 | - __tablename__ = 'dmap_service_catalog' | |
222 | - guid = Column(String(256), primary_key=True) | |
223 | - pguid = Column(String(256)) | |
224 | - path = Column(Text) | |
225 | - name = Column(String(256)) | |
226 | - sort = Column(Integer) | |
227 | - description = Column(Text) | |
228 | - relate_services = relationship('Service', backref='relate_catalog', lazy='dynamic') | |
229 | - | |
230 | - | |
231 | - | |
232 | -class TileScheme(db.Model): | |
233 | - ''' | |
234 | - 切片方案表 | |
235 | - ''' | |
236 | - __tablename__ = 'dmap_tile_scheme' | |
237 | - guid = Column(String(256), primary_key=True) | |
238 | - name = Column(String(256)) | |
239 | - alias = Column(String(256)) | |
240 | - description = Column(Text) | |
241 | - crs = Column(String(256)) | |
242 | - crs_wkt = Column(Text) | |
243 | - | |
244 | - extent = Column(Text) | |
245 | - top_left = Column(String(256)) | |
246 | - | |
247 | - # xmin = Column(Float) | |
248 | - # ymin = Column(Float) | |
249 | - # xmax = Column(Float) | |
250 | - # ymax = Column(Float) | |
251 | - # origin_x = Column(Float) | |
252 | - # origin_y = Column(Float) | |
253 | - | |
254 | - levels = Column(Text) | |
255 | - dpi = Column(Integer) | |
256 | - rows = Column(Integer) | |
257 | - cols = Column(Integer) | |
258 | - update_time = Column(DateTime) | |
259 | - | |
260 | - parameter = Column(Text) | |
261 | - | |
262 | 31 | # 动态加载Model |
263 | 32 | current_dir = os.path.abspath(os.path.dirname(__file__)) |
264 | 33 | pkgs = list(glob.glob('%s/modules/*/models' % (current_dir))) | ... | ... |
... | ... | @@ -3,12 +3,11 @@ |
3 | 3 | #createtime: 2021/3/9 |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | -from app.models import Database,db | |
6 | +from ..models import Database,db,DES | |
7 | 7 | from contextlib import closing |
8 | 8 | |
9 | 9 | from sqlalchemy import create_engine |
10 | 10 | |
11 | -from app.models import DES | |
12 | 11 | import datetime |
13 | 12 | from . import database_alias_check |
14 | 13 | ... | ... |
... | ... | @@ -2,11 +2,9 @@ |
2 | 2 | #author: 4N |
3 | 3 | #createtime: 2021/3/9 |
4 | 4 | #email: nheweijun@sina.com |
5 | -from app.models import Database,DES | |
6 | -from contextlib import closing | |
7 | -from sqlalchemy import create_engine,or_ | |
8 | 5 | |
9 | -from app.models import Database,Catalog,Table | |
6 | + | |
7 | +from ..models import Database,Catalog,Table | |
10 | 8 | |
11 | 9 | |
12 | 10 | from app.util.component.ApiTemplate import ApiTemplate | ... | ... |
... | ... | @@ -2,11 +2,11 @@ |
2 | 2 | #author: 4N |
3 | 3 | #createtime: 2021/3/9 |
4 | 4 | #email: nheweijun@sina.com |
5 | -from app.models import Database,DES | |
5 | + | |
6 | 6 | from contextlib import closing |
7 | 7 | from sqlalchemy import create_engine |
8 | 8 | |
9 | -from app.models import Database | |
9 | +from ..models import Database,DES | |
10 | 10 | |
11 | 11 | |
12 | 12 | from app.util.component.ApiTemplate import ApiTemplate | ... | ... |
... | ... | @@ -3,11 +3,10 @@ |
3 | 3 | #createtime: 2021/3/9 |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | import datetime |
6 | -from app.models import Database,db,DES,Table,Columns,TableVacuate | |
7 | -# from app.util import get_db_session,get_info_from_sqlachemy_uri | |
6 | +from ..models import Database,db,Table,Columns,TableVacuate,DES | |
7 | + | |
8 | 8 | import uuid |
9 | 9 | from . import database_test |
10 | -# from app.util import open_pg_data_source | |
11 | 10 | from osgeo.ogr import DataSource,Layer,FeatureDefn,FieldDefn |
12 | 11 | from sqlalchemy.orm import Session |
13 | 12 | from sqlalchemy import create_engine | ... | ... |
... | ... | @@ -6,7 +6,8 @@ from contextlib import closing |
6 | 6 | |
7 | 7 | from sqlalchemy import create_engine |
8 | 8 | |
9 | -from app.models import DES,Database,db | |
9 | +from ..models import Database,db,DES | |
10 | + | |
10 | 11 | |
11 | 12 | from sqlalchemy.orm import sessionmaker |
12 | 13 | from app.util.component.ApiTemplate import ApiTemplate | ... | ... |
... | ... | @@ -6,7 +6,7 @@ import datetime |
6 | 6 | |
7 | 7 | |
8 | 8 | |
9 | -from app.models import Table,Database | |
9 | +from app.modules.data.models import Table,Database | |
10 | 10 | from app.util.component.ApiTemplate import ApiTemplate |
11 | 11 | from app.util.component.GeometryAdapter import GeometryAdapter |
12 | 12 | from app.util.component.LayerUtil import LayerUtil |
... | ... | @@ -14,6 +14,7 @@ from app.util.component.PGUtil import PGUtil |
14 | 14 | from osgeo.ogr import Geometry,Layer,DataSource,Feature |
15 | 15 | from app.models import DES |
16 | 16 | from osgeo import ogr |
17 | +import json | |
17 | 18 | import gzip |
18 | 19 | from flask import make_response |
19 | 20 | class Api(ApiTemplate): | ... | ... |
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | # author: 4N |
3 | 3 | # createtime: 2021/8/4 |
4 | 4 | # email: nheweijun@sina.com |
5 | -from app.models import Table,Database | |
5 | +from app.modules.data.models import Table,Database | |
6 | 6 | from app.util.component.ApiTemplate import ApiTemplate |
7 | 7 | from app.util.component.GeometryAdapter import GeometryAdapter |
8 | 8 | from app.util.component.LayerUtil import LayerUtil | ... | ... |
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | # email: nheweijun@sina.com |
5 | 5 | |
6 | 6 | |
7 | -from app.models import Table,Database | |
7 | +from app.modules.data.models import Table,Database | |
8 | 8 | from app.util.component.ApiTemplate import ApiTemplate |
9 | 9 | from app.util.component.GeometryAdapter import GeometryAdapter |
10 | 10 | from app.util.component.LayerUtil import LayerUtil | ... | ... |
... | ... | @@ -6,7 +6,7 @@ import datetime |
6 | 6 | |
7 | 7 | |
8 | 8 | |
9 | -from app.models import Table,Database | |
9 | +from app.modules.data.models import Table,Database | |
10 | 10 | from app.util.component.ApiTemplate import ApiTemplate |
11 | 11 | from app.util.component.GeometryAdapter import GeometryAdapter |
12 | 12 | from app.util.component.LayerUtil import LayerUtil | ... | ... |
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | # email: nheweijun@sina.com |
5 | 5 | |
6 | 6 | |
7 | -from app.models import Table,Database | |
7 | +from app.modules.data.models import Table,Database | |
8 | 8 | from app.util.component.ApiTemplate import ApiTemplate |
9 | 9 | from app.util.component.GeometryAdapter import GeometryAdapter |
10 | 10 | from app.util.component.LayerUtil import LayerUtil | ... | ... |
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | 6 | |
7 | -from app.models import * | |
7 | +from ..models import * | |
8 | 8 | |
9 | 9 | import traceback |
10 | 10 | |
... | ... | @@ -17,6 +17,7 @@ from app.util.component.ApiTemplate import ApiTemplate |
17 | 17 | from app.util.component.PGUtil import PGUtil |
18 | 18 | from app.util.component.ZipUtil import ZipUtil |
19 | 19 | import multiprocessing |
20 | +import datetime | |
20 | 21 | |
21 | 22 | class Api(ApiTemplate): |
22 | 23 | ... | ... |
... | ... | @@ -7,12 +7,13 @@ from osgeo.ogr import * |
7 | 7 | import uuid |
8 | 8 | |
9 | 9 | import time |
10 | -from app.models import * | |
10 | +from ..models import * | |
11 | + | |
11 | 12 | import json |
12 | 13 | import re |
13 | 14 | from app.util.component.ApiTemplate import ApiTemplate |
14 | 15 | from app.util.component.PGUtil import PGUtil |
15 | - | |
16 | +import datetime | |
16 | 17 | |
17 | 18 | |
18 | 19 | class Api(ApiTemplate): | ... | ... |
... | ... | @@ -4,7 +4,8 @@ |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | 6 | import configure |
7 | -from app.models import InsertingLayerName, Database, DES, Task | |
7 | +from ..models import InsertingLayerName, Database, Task,DES | |
8 | + | |
8 | 9 | from sqlalchemy.orm import Session |
9 | 10 | import multiprocessing |
10 | 11 | from app.util.component.EntryDataVacuate import EntryDataVacuate | ... | ... |
... | ... | @@ -7,11 +7,10 @@ from osgeo.ogr import * |
7 | 7 | import uuid |
8 | 8 | |
9 | 9 | import time |
10 | -from app.models import * | |
10 | +from ..models import * | |
11 | +import datetime | |
11 | 12 | import json |
12 | -import re | |
13 | 13 | from app.util.component.ApiTemplate import ApiTemplate |
14 | -from app.util.component.PGUtil import PGUtil | |
15 | 14 | from .get_meta import Api as MetaApi |
16 | 15 | from threading import Thread |
17 | 16 | from app.util.component.EntryDataVacuate import EntryDataVacuate | ... | ... |
... | ... | @@ -3,20 +3,12 @@ |
3 | 3 | # createtime: 2020/9/4 |
4 | 4 | # email: nheweijun@sina.com |
5 | 5 | |
6 | -import traceback | |
7 | -from osgeo.ogr import * | |
8 | -from osgeo import ogr | |
9 | 6 | |
10 | -from flask import request | |
11 | 7 | import os |
12 | -import uuid | |
13 | - | |
14 | -import json | |
15 | 8 | from app.util.component.ApiTemplate import ApiTemplate |
16 | -from app.util.component.ZipUtil import ZipUtil | |
17 | 9 | from app.util.component.FileProcess import FileProcess |
18 | 10 | import datetime |
19 | -import time | |
11 | + | |
20 | 12 | class Api(ApiTemplate): |
21 | 13 | api_name = "本地数据list" |
22 | 14 | def process(self): | ... | ... |
... | ... | @@ -2,7 +2,8 @@ |
2 | 2 | #createtime: 2021/1/27 |
3 | 3 | #email: nheweijun@sina.com |
4 | 4 | |
5 | -from app.models import Table,Columns,DES | |
5 | +from ..models import Table,Columns,DES | |
6 | + | |
6 | 7 | |
7 | 8 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 9 | from app.util.component.ModelVisitor import ModelVisitor | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | |
6 | 6 | import datetime |
7 | 7 | import traceback |
8 | -from app.models import Table, Database, DES,Task,db,TableVacuate,Process | |
8 | +from ..models import Table, Database, Task,db,TableVacuate,Process,DES | |
9 | 9 | |
10 | 10 | from sqlalchemy.engine import ResultProxy |
11 | 11 | from app.util.component.ApiTemplate import ApiTemplate | ... | ... |
... | ... | @@ -3,21 +3,11 @@ |
3 | 3 | # email: nheweijun@sina.com |
4 | 4 | |
5 | 5 | |
6 | -import datetime | |
7 | -import traceback | |
8 | -from app.models import Table, Database, DES,Task,db,TableVacuate | |
9 | - | |
10 | -from sqlalchemy.engine import ResultProxy | |
6 | +from ..models import Table,DES,db,TableVacuate | |
11 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
12 | 8 | from app.util.component.PGUtil import PGUtil |
13 | -from app.util.component.EntryDataVacuate import Process | |
14 | -from app.util.component.GeometryAdapter import GeometryAdapter | |
15 | -from app.util.component.StructuredPrint import StructurePrint | |
16 | -import multiprocessing | |
17 | -import uuid | |
18 | 9 | import configure |
19 | -from osgeo.ogr import DataSource,Layer,Geometry | |
20 | -from osgeo import ogr | |
10 | +from osgeo.ogr import DataSource | |
21 | 11 | from flask import current_app |
22 | 12 | |
23 | 13 | class Api(ApiTemplate): | ... | ... |
... | ... | @@ -3,11 +3,10 @@ |
3 | 3 | # email: nheweijun@sina.com |
4 | 4 | |
5 | 5 | |
6 | -from app.models import Table,TableVacuate,Task | |
6 | +from ..models import Table,TableVacuate,Task | |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | from app.util.component.VacuateConf import VacuateConf |
9 | -import collections | |
10 | -import json | |
9 | + | |
11 | 10 | |
12 | 11 | import copy |
13 | 12 | class Api(ApiTemplate): | ... | ... |
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | |
6 | 6 | import datetime |
7 | 7 | import traceback |
8 | -from app.models import Table, Database, DES,Task,db,TableVacuate | |
8 | +from ..models import Table, Database, DES,Task,db,TableVacuate | |
9 | 9 | from app.util.component.ApiTemplate import ApiTemplate |
10 | 10 | from app.util.component.PGUtil import PGUtil |
11 | 11 | from app.util.component.EntryDataVacuate import Process |
... | ... | @@ -14,7 +14,7 @@ import uuid |
14 | 14 | import configure |
15 | 15 | from osgeo.ogr import DataSource,Layer,Geometry |
16 | 16 | from osgeo import ogr |
17 | -from app.util.component.StructuredPrint import StructurePrint | |
17 | + | |
18 | 18 | from app.util.component.VacuateConf import VacuateConf |
19 | 19 | |
20 | 20 | class Api(ApiTemplate): | ... | ... |
... | ... | @@ -3,21 +3,17 @@ |
3 | 3 | # email: nheweijun@sina.com |
4 | 4 | |
5 | 5 | |
6 | -import datetime | |
7 | -import traceback | |
8 | -from app.models import Table, Database, DES,Task,db,TableVacuate | |
6 | +from ..models import Table, DES | |
7 | + | |
9 | 8 | |
10 | -from sqlalchemy.engine import ResultProxy | |
11 | 9 | from app.util.component.ApiTemplate import ApiTemplate |
12 | 10 | from app.util.component.PGUtil import PGUtil |
13 | -from app.util.component.EntryDataVacuate import Process | |
11 | + | |
14 | 12 | from app.util.component.GeometryAdapter import GeometryAdapter |
15 | 13 | from app.util.component.StructuredPrint import StructurePrint |
16 | -import multiprocessing | |
17 | -import uuid | |
18 | -import configure | |
19 | -from osgeo.ogr import DataSource,Layer,Geometry | |
20 | -from osgeo import ogr | |
14 | + | |
15 | +from osgeo.ogr import DataSource | |
16 | + | |
21 | 17 | from app.util.component.VacuateConf import VacuateConf |
22 | 18 | import copy |
23 | 19 | class Api(ApiTemplate): | ... | ... |
... | ... | @@ -4,9 +4,7 @@ |
4 | 4 | |
5 | 5 | |
6 | 6 | import datetime |
7 | -import traceback | |
8 | -from app.models import Table,Database,DES | |
9 | - | |
7 | +from ..models import Table,Database,DES | |
10 | 8 | from sqlalchemy.engine import ResultProxy |
11 | 9 | from app.util.component.ApiTemplate import ApiTemplate |
12 | 10 | from app.util.component.PGUtil import PGUtil | ... | ... |
app/modules/data/models/__init__.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +#author: 4N | |
3 | +#createtime: 2021/10/26 | |
4 | +#email: nheweijun@sina.com | |
5 | + | |
6 | +from app.models import db | |
7 | +from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Time,Float,Binary | |
8 | +from sqlalchemy.orm import relationship | |
9 | +import base64 | |
10 | +from pyDes import * | |
11 | + | |
12 | + | |
13 | +class DES(): | |
14 | + ''' | |
15 | + DES密码加解密 | |
16 | + ''' | |
17 | + Des: des = des("Chinadci", ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) | |
18 | + | |
19 | + @classmethod | |
20 | + def encode(cls, data): | |
21 | + return str(base64.b64encode(cls.Des.encrypt(data)), encoding="utf8") | |
22 | + | |
23 | + | |
24 | + @classmethod | |
25 | + def decode(cls, data): | |
26 | + if data: | |
27 | + return str(cls.Des.decrypt(base64.b64decode(data.encode("utf-8"))), encoding="utf8") | |
28 | + | |
29 | + else: | |
30 | + return data | |
31 | + | |
32 | +class Table(db.Model): | |
33 | + ''' | |
34 | + 数据表元数据 | |
35 | + ''' | |
36 | + __tablename__ = 'dmap_table' | |
37 | + guid = Column(String(256), primary_key=True) | |
38 | + # 数据源外键 | |
39 | + database_guid = Column(String(256), ForeignKey('dmap_database.guid')) | |
40 | + | |
41 | + # 点线面123 | |
42 | + table_type = Column(Integer) | |
43 | + | |
44 | + name = Column(String(256)) | |
45 | + alias = Column(Text) | |
46 | + create_time = Column(DateTime) | |
47 | + update_time = Column(DateTime) | |
48 | + | |
49 | + feature_count = Column(Integer) | |
50 | + | |
51 | + description = Column(Text) | |
52 | + extent = Column(Text) | |
53 | + | |
54 | + #用户 | |
55 | + creator = Column(Text) | |
56 | + #是否已抽稀 | |
57 | + is_vacuate=Column(Integer,default=0) | |
58 | + | |
59 | + # 目录外键 | |
60 | + catalog_guid = Column(String(256), ForeignKey('dmap_catalog.guid')) | |
61 | + | |
62 | + relate_columns = relationship('Columns', backref='relate_table', lazy='dynamic') | |
63 | + relate_table_vacuates = relationship('TableVacuate', backref='relate_table', lazy='dynamic') | |
64 | + | |
65 | + | |
66 | +class TableVacuate(db.Model): | |
67 | + ''' | |
68 | + sub数据表元数据 | |
69 | + ''' | |
70 | + __tablename__ = 'dmap_table_vacuate' | |
71 | + guid = Column(String(256), primary_key=True) | |
72 | + name = Column(String(256)) | |
73 | + level = Column(Integer) | |
74 | + pixel_distance = Column(Float) | |
75 | + table_guid = Column(String(256), ForeignKey('dmap_table.guid')) | |
76 | + | |
77 | + #所在的库 | |
78 | + connectstr= Column(Text) | |
79 | + | |
80 | +class Columns(db.Model): | |
81 | + ''' | |
82 | + 数据表的列 | |
83 | + ''' | |
84 | + __tablename__ = 'dmap_column' | |
85 | + guid = Column(String(256), primary_key=True) | |
86 | + # 表外键 | |
87 | + table_guid= Column(String(256), ForeignKey('dmap_table.guid')) | |
88 | + name=Column(String(256)) | |
89 | + alias = Column(String(256)) | |
90 | + create_time = Column(DateTime) | |
91 | + update_time = Column(DateTime) | |
92 | + | |
93 | +class Task(db.Model): | |
94 | + ''' | |
95 | + 任务表 | |
96 | + ''' | |
97 | + __tablename__ = 'dmap_task' | |
98 | + guid = Column(String(256), primary_key=True) | |
99 | + name = Column(Text) | |
100 | + process = Column(Text) | |
101 | + create_time = Column(DateTime) | |
102 | + update_time = Column(DateTime) | |
103 | + state = Column(Integer) | |
104 | + #数据源外键 | |
105 | + database_guid = Column(String(256), ForeignKey('dmap_database.guid')) | |
106 | + #目录外键 | |
107 | + catalog_guid = Column(String(256), ForeignKey('dmap_catalog.guid')) | |
108 | + #抽稀任务指定表的guid | |
109 | + table_guid = Column(String(256)) | |
110 | + #任务类型 | |
111 | + #1:入库任务 | |
112 | + #2:抽稀任务 | |
113 | + #3:数据库刷新任务 | |
114 | + #4:影像金字塔任务 | |
115 | + #5:数据下载任务 | |
116 | + task_type=Column(Integer) | |
117 | + creator = Column(Text) | |
118 | + file_name = Column(Text) | |
119 | + relate_processes = relationship('Process', backref='relate_task', lazy='dynamic') | |
120 | + # 入库参数 | |
121 | + parameter= Column(Text) | |
122 | + | |
123 | + | |
124 | + | |
125 | +class Process(db.Model): | |
126 | + ''' | |
127 | + 过程信息表 | |
128 | + ''' | |
129 | + __tablename__ = 'dmap_process' | |
130 | + guid = Column(String(256), primary_key=True) | |
131 | + # 任务外键 | |
132 | + task_guid = Column(String(256), ForeignKey('dmap_task.guid')) | |
133 | + time = Column(DateTime) | |
134 | + message = Column(Text) | |
135 | + | |
136 | + | |
137 | +class Catalog(db.Model): | |
138 | + ''' | |
139 | + 目录表 | |
140 | + ''' | |
141 | + __tablename__ = 'dmap_catalog' | |
142 | + guid = Column(String(256), primary_key=True) | |
143 | + database_guid = Column(String(256), ForeignKey('dmap_database.guid')) | |
144 | + pguid = Column(String(256)) | |
145 | + path = Column(Text) | |
146 | + name = Column(String(256)) | |
147 | + sort = Column(Integer) | |
148 | + description = Column(Text) | |
149 | + relate_tables = relationship('Table', backref='relate_catalog', lazy='dynamic') | |
150 | + relate_tasks = relationship('Task', backref='relate_catalog', lazy='dynamic') | |
151 | + | |
152 | + | |
153 | +class Database(db.Model): | |
154 | + ''' | |
155 | + 数据源表 | |
156 | + ''' | |
157 | + __tablename__ = 'dmap_database' | |
158 | + guid = Column(String(256), primary_key=True) | |
159 | + name = Column(String(256)) | |
160 | + alias = Column(String(256)) | |
161 | + sqlalchemy_uri = Column(String(256)) | |
162 | + description = Column(Text) | |
163 | + # 唯一性约束,不能注册相同连接的库 | |
164 | + connectstr= Column(Text,unique=True) | |
165 | + creator = Column(String(256)) | |
166 | + create_time = Column(DateTime) | |
167 | + update_time = Column(DateTime) | |
168 | + relate_catalogs = relationship('Catalog', backref='relate_database', lazy='dynamic') | |
169 | + relate_tables = relationship('Table', backref='relate_database', lazy='dynamic') | |
170 | + relate_tasks = relationship('Task', backref='relate_database', lazy='dynamic') | |
171 | + | |
172 | + | |
173 | + | |
174 | +class InsertingLayerName(db.Model): | |
175 | + ''' | |
176 | + 正在入库的数据 | |
177 | + ''' | |
178 | + __tablename__ = 'dmap_iln' | |
179 | + guid = Column(String(256), primary_key=True) | |
180 | + task_guid = Column(String(256)) | |
181 | + name = Column(String(256)) | |
182 | + | |
183 | + | |
184 | + | |
185 | + | ... | ... |
... | ... | @@ -3,65 +3,41 @@ |
3 | 3 | #createtime: 2021/10/11 |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | -from app.models import Task | |
7 | -import configure | |
8 | -from app.models import InsertingLayerName, Database, DES, Task,Columns | |
6 | + | |
7 | +from ..models import InsertingLayerName,Columns | |
9 | 8 | from sqlalchemy.orm import Session |
10 | -import multiprocessing | |
9 | + | |
11 | 10 | from app.util.component.EntryDataVacuate import EntryDataVacuate |
12 | 11 | import json |
13 | 12 | from sqlalchemy import distinct |
14 | -import uuid | |
15 | -from osgeo.ogr import DataSource | |
16 | -from app.util.component.StructuredPrint import StructurePrint | |
17 | -from app.util.component.PGUtil import PGUtil | |
13 | + | |
18 | 14 | import time |
19 | -import datetime | |
20 | -import traceback | |
21 | -from app.models import Table, Database, DES,Task,db,TableVacuate | |
22 | -from app.util.component.ApiTemplate import ApiTemplate | |
23 | -from app.util.component.PGUtil import PGUtil | |
24 | -from app.util.component.EntryDataVacuate import Process | |
15 | + | |
25 | 16 | from app.util.component.SQLUtil import SQLUtil |
26 | -import multiprocessing | |
27 | -import uuid | |
28 | -import configure | |
29 | -from osgeo.ogr import DataSource,Layer,Geometry,FieldDefn,FeatureDefn | |
30 | -from osgeo import ogr | |
31 | -from app.util.component.StructuredPrint import StructurePrint | |
32 | -from app.util.component.VacuateConf import VacuateConf | |
17 | + | |
33 | 18 | import datetime |
34 | -import traceback | |
35 | -from app.models import Table, Database, DES,Task,db,TableVacuate,Process | |
36 | 19 | |
37 | -from sqlalchemy.engine import ResultProxy | |
38 | -from app.util.component.ApiTemplate import ApiTemplate | |
20 | +from ..models import Table, Database, DES,Task,db,TableVacuate,Process | |
39 | 21 | |
40 | 22 | from app.util.component.StructuredPrint import StructurePrint |
41 | -from app.util.component.PGUtil import PGUtil | |
42 | -import multiprocessing | |
43 | -import uuid | |
44 | -import configure | |
23 | + | |
45 | 24 | from osgeo.ogr import DataSource,Layer,Geometry |
46 | -from osgeo import ogr | |
25 | + | |
47 | 26 | from app.util.component.VacuateConf import VacuateConf |
48 | 27 | from app.util.component.GeometryAdapter import GeometryAdapter |
49 | -from app.models import * | |
50 | 28 | |
51 | 29 | import traceback |
52 | - | |
53 | 30 | from osgeo.ogr import DataSource,Layer,FeatureDefn,FieldDefn,Feature |
54 | 31 | from osgeo import gdal,ogr |
55 | 32 | import os |
56 | 33 | import uuid |
57 | 34 | import configure |
58 | -from app.util.component.ApiTemplate import ApiTemplate | |
35 | + | |
59 | 36 | from app.util.component.PGUtil import PGUtil |
60 | 37 | from app.util.component.ZipUtil import ZipUtil |
61 | 38 | import multiprocessing |
62 | 39 | |
63 | 40 | |
64 | - | |
65 | 41 | def task_consumer(): |
66 | 42 | |
67 | 43 | running_dict = {} | ... | ... |
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | #createtime: 2020/9/4 |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | -from app.models import db,Task,Process | |
6 | +from ..models import db,Task,Process | |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | from app.util.component.ModelVisitor import ModelVisitor |
9 | 9 | class Api(ApiTemplate): | ... | ... |
app/modules/data/util/EntryDataVacuate.py
0 → 100644
1 | + | |
2 | +from osgeo.ogr import * | |
3 | +from osgeo import ogr | |
4 | +from osgeo import gdal | |
5 | +import os | |
6 | +import uuid | |
7 | +import shutil | |
8 | +import time | |
9 | +from app.modules.data.models import * | |
10 | +from app.util.component.PGUtil import PGUtil | |
11 | +from app.util.component.StructuredPrint import StructurePrint | |
12 | +from sqlalchemy.orm import Session | |
13 | +import configure | |
14 | +import math | |
15 | +from functools import lru_cache | |
16 | +import traceback | |
17 | +import copy | |
18 | +from app.util.component.GeometryAdapter import GeometryAdapter | |
19 | +from app.util.component.VacuateConf import VacuateConf | |
20 | +import datetime | |
21 | +class EntryDataVacuate: | |
22 | + | |
23 | + def entry(self,parameter): | |
24 | + # meta:dict = parameter.get("meta") | |
25 | + | |
26 | + # 初始化任务 | |
27 | + this_task = ThisTask(parameter) | |
28 | + this_task.write_process("入库任务初始化...") | |
29 | + | |
30 | + # 数据路径,用作删除 | |
31 | + _data_path=None | |
32 | + try: | |
33 | + metas: list = parameter.get("meta") | |
34 | + # 总的入库是否成功 | |
35 | + is_success=True | |
36 | + | |
37 | + this_task.update({"process": "入库中"}) | |
38 | + | |
39 | + # 开始入库事务 | |
40 | + this_task.start() | |
41 | + | |
42 | + # 多个文件依次入库 | |
43 | + for meta in metas: | |
44 | + #设置编码 | |
45 | + encoding = parameter.get("encoding") | |
46 | + if encoding: | |
47 | + gdal.SetConfigOption("SHAPE_ENCODING",encoding) | |
48 | + else: | |
49 | + gdal.SetConfigOption("SHAPE_ENCODING", "GBK") | |
50 | + | |
51 | + #如果包含cpg文件,优先使用cpg文件中声明的编码 | |
52 | + encoding_cpg = meta.get("encoding") | |
53 | + if encoding_cpg: | |
54 | + gdal.SetConfigOption("SHAPE_ENCODING", encoding_cpg) | |
55 | + | |
56 | + data_path = meta.get("data_path") | |
57 | + | |
58 | + #设定删除路径 | |
59 | + if not _data_path: | |
60 | + _data_path=data_path | |
61 | + | |
62 | + | |
63 | + if not data_path: | |
64 | + raise Exception("数据错误!") | |
65 | + # 分为shp和gdb 2种录入形式 | |
66 | + | |
67 | + if data_path.endswith("shp"): | |
68 | + is_success_one,new_layer_name = self.entry_shp(data_path,this_task,meta) | |
69 | + else: | |
70 | + is_success_one,new_layer_names = self.entry_gdb(data_path,this_task,meta) | |
71 | + | |
72 | + #如果其中一个失败,总的入库就失败 | |
73 | + if not is_success_one: | |
74 | + is_success=False | |
75 | + | |
76 | + this_task.write_process("数据入库结束。") | |
77 | + | |
78 | + if is_success: | |
79 | + # 更新任务为成功任务 | |
80 | + this_task.update({"state": 1,"process":"入库完成","update_time": datetime.datetime.now()}) | |
81 | + this_task.commit() | |
82 | + else: | |
83 | + # 更新任务为失败任务 | |
84 | + this_task.update({"state": -1, "process": "入库失败", "update_time": datetime.datetime.now()}) | |
85 | + # rollback | |
86 | + this_task.rollback() | |
87 | + | |
88 | + except Exception as e: | |
89 | + this_task.write_process("{} 任务结束!".format(e.__str__())) | |
90 | + this_task.update({"state": -1, "process": "入库失败", "update_time": datetime.datetime.now()}) | |
91 | + StructurePrint().print(e.__str__(),"ERROR") | |
92 | + # rollback | |
93 | + this_task.rollback() | |
94 | + finally: | |
95 | + this_task.end() | |
96 | + try: | |
97 | + file_tmp_path = os.path.join(_data_path.split("file_tmp")[0],"file_tmp") | |
98 | + dir_path = os.path.dirname(_data_path) | |
99 | + i=0 | |
100 | + while not os.path.dirname(dir_path).__eq__(file_tmp_path) and i<30: | |
101 | + dir_path = os.path.dirname(dir_path) | |
102 | + i+=1 | |
103 | + if i<30: | |
104 | + shutil.rmtree(dir_path,True) | |
105 | + StructurePrint().print("删除文件成功!") | |
106 | + else: | |
107 | + raise Exception("找不到文件!") | |
108 | + | |
109 | + except Exception as e: | |
110 | + StructurePrint().print(e.__str__(), "ERROR") | |
111 | + StructurePrint().print("删除文件失败!","ERROR") | |
112 | + | |
113 | + | |
114 | + def entry_shp(self,data_path,this_task,meta): | |
115 | + ''' | |
116 | + 录入shp | |
117 | + :param data_path: | |
118 | + :return: | |
119 | + ''' | |
120 | + | |
121 | + driver: Driver = ogr.GetDriverByName("ESRI Shapefile") | |
122 | + ds: DataSource = driver.Open(data_path, 1) | |
123 | + if not ds: | |
124 | + raise Exception("打开数据失败!") | |
125 | + layer: Layer = ds.GetLayer(0) | |
126 | + | |
127 | + is_success_one, new_layer_name =self.entry_one_layer(layer, this_task,meta) | |
128 | + ds.Destroy() | |
129 | + return is_success_one, new_layer_name | |
130 | + | |
131 | + def entry_gdb(self,data_path,this_task,meta): | |
132 | + ''' | |
133 | + 录入gdb | |
134 | + :param data_path: | |
135 | + :return: | |
136 | + ''' | |
137 | + | |
138 | + is_successes = [] | |
139 | + new_layer_names=[] | |
140 | + driver: Driver = ogr.GetDriverByName("OpenFileGDB") | |
141 | + ds: DataSource = driver.Open(data_path, 0) | |
142 | + if not ds: | |
143 | + raise Exception("打开数据失败!") | |
144 | + | |
145 | + | |
146 | + for i in range(ds.GetLayerCount()): | |
147 | + layer: Layer = ds.GetLayer(i) | |
148 | + is_success, new_layer_name = self.entry_one_layer(layer,this_task,meta) | |
149 | + new_layer_names.append(new_layer_name) | |
150 | + is_successes.append(is_success) | |
151 | + ds.Destroy() | |
152 | + if is_successes.__contains__(False): | |
153 | + return False,new_layer_names | |
154 | + else: | |
155 | + return True,new_layer_names | |
156 | + | |
157 | + def entry_one_layer(self,layer: Layer,this_task,meta): | |
158 | + | |
159 | + # this_task.pg_ds.StartTransaction() | |
160 | + new_layer_name = None | |
161 | + # vacuate_process= None | |
162 | + success = True | |
163 | + table_guid = uuid.uuid1().__str__() | |
164 | + try: | |
165 | + # 图层设置 | |
166 | + parameter = this_task.parameter | |
167 | + | |
168 | + overwrite = parameter.get("overwrite") if parameter.get("overwrite") is not None and parameter.get("overwrite")=="yes" else "no" | |
169 | + geom_name = parameter.get("geom_name") if parameter.get("geom_name") is not None else "geom" | |
170 | + fid = parameter.get("fid") if parameter.get("fid") is not None else "fid" | |
171 | + options = ["OVERWRITE={}".format(overwrite), "FID={}".format(fid), "GEOMETRY_NAME={}".format(geom_name),"PRECISION=NO"] | |
172 | + | |
173 | + | |
174 | + # 将线/面转多线多面 | |
175 | + geom_type = GeometryAdapter.change_geom_type(layer.GetGeomType()) | |
176 | + | |
177 | + # 更改图层名 | |
178 | + change_name = False | |
179 | + origin_name = layer.GetName().lower() | |
180 | + | |
181 | + # 新图层名 | |
182 | + new_layer_name: str = meta.get("layer").get(origin_name) | |
183 | + origin_name = new_layer_name | |
184 | + no = 1 | |
185 | + while overwrite.__eq__("no") and this_task.pg_ds.GetLayerByName(new_layer_name) : | |
186 | + change_name=True | |
187 | + new_layer_name = origin_name+"_{}".format(no) | |
188 | + no+=1 | |
189 | + | |
190 | + if change_name: | |
191 | + this_task.write_process("{}图层已存在,更名为{}入库".format(origin_name, new_layer_name)) | |
192 | + | |
193 | + | |
194 | + this_task.write_process("{}图层正在入库...".format(new_layer_name)) | |
195 | + | |
196 | + pg_layer: Layer = this_task.pg_ds.CreateLayer(new_layer_name, layer.GetSpatialRef(), geom_type, options) | |
197 | + | |
198 | + # 复制原图层的属性 | |
199 | + # 去掉fid的属性 | |
200 | + schema = [sche for sche in layer.schema if not sche.name.__eq__(fid)] | |
201 | + pg_layer.CreateFields(schema) | |
202 | + | |
203 | + #创建抽稀过程 | |
204 | + # vacuate_process = VacuateProcess(layer,table_guid,options) | |
205 | + | |
206 | + | |
207 | + | |
208 | + count =0 | |
209 | + | |
210 | + for feature in layer: | |
211 | + count+=1 | |
212 | + if count%10000==0: | |
213 | + StructurePrint().print("{}图层已入库{}个对象".format(new_layer_name,count)) | |
214 | + # print(time.time()-this_time) | |
215 | + #this_time=time.time() | |
216 | + geo :Geometry = feature.GetGeometryRef() | |
217 | + # 如果是空对象不录入 | |
218 | + if geo is not None: | |
219 | + if geo.IsEmpty(): | |
220 | + this_task.write_process("FID:{}要素的空间字段为空,跳过该要素!".format(feature.GetFID())) | |
221 | + StructurePrint().print("FID:{}要素的空间字段为空,跳过该要素!".format(feature.GetFID()),"WARN") | |
222 | + continue | |
223 | + | |
224 | + out_feature: Feature = copy.copy(feature) | |
225 | + out_geom = None | |
226 | + if geo is not None: | |
227 | + out_geom:Geometry = GeometryAdapter.change_geom(geo, geom_type) | |
228 | + out_feature.SetGeometry(out_geom) | |
229 | + # 出现fid为0经常有问题 | |
230 | + out_feature.SetFID(out_feature.GetFID() + 1) | |
231 | + pg_layer.CreateFeature(out_feature) | |
232 | + | |
233 | + #插入抽稀图层 | |
234 | + # if out_geom is not None: | |
235 | + # vacuate_process.vacuate(out_geom) | |
236 | + | |
237 | + # 注册图层信息 | |
238 | + # 是否抽吸过 | |
239 | + # is_vacuate = 1 if vacuate_process.max_level>0 else 0 | |
240 | + is_vacuate = 0 | |
241 | + | |
242 | + this_task.register_table(pg_layer,new_layer_name,overwrite,parameter.get("creator"),is_vacuate,table_guid) | |
243 | + | |
244 | + # 注册抽稀表 | |
245 | + # this_task.register_table_vacuate(table_guid,vacuate_process.vacuate_layers) | |
246 | + | |
247 | + this_task.write_process("{}图层入库成功。".format(new_layer_name)) | |
248 | + | |
249 | + except Exception as e: | |
250 | + | |
251 | + this_task.write_process("{}入库失败,数据回滚!原因:{}".format(new_layer_name,e.__str__())) | |
252 | + StructurePrint().print("{}入库失败,数据回滚!原因:{}".format(new_layer_name,e.__str__()), "error") | |
253 | + print(traceback.format_exc()) | |
254 | + # 抽稀回滚 | |
255 | + # vacuate_process.rollback() | |
256 | + success =False | |
257 | + | |
258 | + finally: | |
259 | + # vacuate_process.end() | |
260 | + pass | |
261 | + return success,new_layer_name | |
262 | + | |
263 | + | |
264 | + | |
265 | +class ThisTask: | |
266 | + | |
267 | + def __init__(self, parameter): | |
268 | + try: | |
269 | + # 该任务事务的连接 | |
270 | + self.sys_session: Session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI) | |
271 | + # 专门的写过程的连接 | |
272 | + self.process_session: Session = PGUtil.get_db_session(configure.SQLALCHEMY_DATABASE_URI) | |
273 | + | |
274 | + except Exception as e: | |
275 | + raise Exception("打开数据库失败!") | |
276 | + self.parameter = parameter | |
277 | + | |
278 | + self.task = self.process_session.query(Task).filter_by(guid=parameter.get("task_guid")) | |
279 | + | |
280 | + self.database = self.sys_session.query(Database).filter_by( | |
281 | + guid=parameter.get("database_guid")).one_or_none() | |
282 | + | |
283 | + self.catalog_guid = parameter.get("catalog_guid") | |
284 | + | |
285 | + self.pg_ds: DataSource = PGUtil.open_pg_data_source(1, DES.decode(self.database.sqlalchemy_uri)) | |
286 | + | |
287 | + | |
288 | + def start(self): | |
289 | + self.pg_ds.StartTransaction() | |
290 | + | |
291 | + def update(self, update_dict): | |
292 | + self.task.update(update_dict) | |
293 | + self.process_session.commit() | |
294 | + | |
295 | + def write_process(self, message): | |
296 | + message = "{} {}".format(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), message) | |
297 | + task_process_guid = uuid.uuid1().__str__() | |
298 | + task_process = Process(guid=task_process_guid, message=message, time=datetime.datetime.now(), | |
299 | + task_guid=self.parameter.get("task_guid")) | |
300 | + self.process_session.add(task_process) | |
301 | + self.process_session.commit() | |
302 | + | |
303 | + def register_table(self, layer: Layer, new_layer_name, overwrite, creator,is_vacuate,table_guid): | |
304 | + ''' | |
305 | + 注册表 | |
306 | + :param layer: 图层 | |
307 | + :param new_layer_name: 图层名 | |
308 | + :return: 表名 | |
309 | + ''' | |
310 | + | |
311 | + this_time = datetime.datetime.now() | |
312 | + | |
313 | + ext = layer.GetExtent() | |
314 | + if ext[0] < 360: | |
315 | + ext = [round(e, 6) for e in ext] | |
316 | + else: | |
317 | + ext = [round(e, 2) for e in ext] | |
318 | + | |
319 | + geom_type = GeometryAdapter.get_geometry_type(layer) | |
320 | + | |
321 | + extent = "{},{},{},{}".format(ext[0], ext[1], ext[2], ext[3]) | |
322 | + | |
323 | + table = Table(guid=table_guid, | |
324 | + database_guid=self.database.guid, | |
325 | + creator=creator, | |
326 | + name=new_layer_name, create_time=this_time, update_time=this_time, | |
327 | + catalog_guid=self.catalog_guid, table_type=GeometryAdapter.get_table_type(geom_type), | |
328 | + extent=extent, | |
329 | + feature_count=layer.GetFeatureCount(), | |
330 | + is_vacuate=is_vacuate | |
331 | + ) | |
332 | + # 删除遗留业务数据 | |
333 | + history_table = self.sys_session.query(Table).filter_by(name=new_layer_name,database_guid=self.database.guid).all() | |
334 | + if history_table: | |
335 | + for ht in history_table: | |
336 | + self.sys_session.delete(ht) | |
337 | + self.sys_session.add(table) | |
338 | + | |
339 | + feature_defn: FeatureDefn = layer.GetLayerDefn() | |
340 | + | |
341 | + for i in range(feature_defn.GetFieldCount()): | |
342 | + field_defn: FieldDefn = feature_defn.GetFieldDefn(i) | |
343 | + field_name = field_defn.GetName().lower() | |
344 | + field_alias = field_name if field_defn.GetAlternativeName() is None or field_defn.GetAlternativeName().__eq__( | |
345 | + "") else field_defn.GetAlternativeName() | |
346 | + column = Columns(guid=uuid.uuid1().__str__(), table_guid=table_guid, | |
347 | + name=field_name, alias=field_alias, create_time=this_time, update_time=this_time) | |
348 | + self.sys_session.add(column) | |
349 | + return table_guid | |
350 | + | |
351 | + | |
352 | + def register_table_vacuate(self,table_guid,vacuate_layers:dict): | |
353 | + | |
354 | + # 抽稀表有固定的命名规则 | |
355 | + for level,layer in vacuate_layers.items(): | |
356 | + pixel_distance_str:str=layer.GetName().split("_")[-1] | |
357 | + lev = layer.GetName().split("_")[-2] | |
358 | + | |
359 | + if pixel_distance_str.startswith("0"): | |
360 | + pixel_distance_str="0.{}".format(pixel_distance_str) | |
361 | + | |
362 | + pixel_distance = float(pixel_distance_str) | |
363 | + | |
364 | + table_vacuate = TableVacuate(guid=uuid.uuid1().__str__(), | |
365 | + table_guid=table_guid, | |
366 | + level=int(lev), | |
367 | + name=layer.GetName(), | |
368 | + pixel_distance=pixel_distance) | |
369 | + self.sys_session.add(table_vacuate) | |
370 | + | |
371 | + | |
372 | + def commit(self): | |
373 | + if self.sys_session: | |
374 | + self.sys_session.commit() | |
375 | + if self.pg_ds: | |
376 | + self.pg_ds.CommitTransaction() | |
377 | + if self.process_session: | |
378 | + self.process_session.commit() | |
379 | + | |
380 | + | |
381 | + def end(self): | |
382 | + if self.sys_session: | |
383 | + self.sys_session.close() | |
384 | + if self.pg_ds: | |
385 | + self.pg_ds.Destroy() | |
386 | + if self.process_session: | |
387 | + self.process_session.close() | |
388 | + | |
389 | + def rollback(self): | |
390 | + if self.sys_session: | |
391 | + self.sys_session.rollback() | |
392 | + if self.pg_ds: | |
393 | + self.pg_ds.RollbackTransaction() | |
394 | + | |
395 | + | |
396 | + | |
397 | +class VacuateProcess: | |
398 | + | |
399 | + max_level=0 | |
400 | + fill_dict={} | |
401 | + vacuate_layers={} | |
402 | + vacuate_layers_gridsize={} | |
403 | + pg_ds_dict = {} | |
404 | + # 图层要素大于5W才抽稀 | |
405 | + least_vacuate_count = VacuateConf.least_vacuate_count | |
406 | + | |
407 | + extent=[] | |
408 | + is_spatial=False | |
409 | + | |
410 | + lonlat_gridsize = VacuateConf.lonlat_gridsize | |
411 | + project_gridsize = VacuateConf.project_gridsize | |
412 | + | |
413 | + # 该抽稀过程使用的grid_size | |
414 | + t_grid_size = [] | |
415 | + | |
416 | + # 该抽稀过程的抽稀网格 | |
417 | + this_gridsize=[] | |
418 | + | |
419 | + | |
420 | + def __init__(self,layer:Layer,table_guid, options,sqlalchemy_uri): | |
421 | + | |
422 | + #是空间图层才初始化 | |
423 | + if layer.GetExtent()[0] > 0 or layer.GetExtent()[0] < 0: | |
424 | + | |
425 | + self.is_spatial=True | |
426 | + | |
427 | + # 判断需要抽稀多少级 | |
428 | + | |
429 | + lc = layer.GetFeatureCount() | |
430 | + extent = layer.GetExtent() | |
431 | + self.extent=extent | |
432 | + | |
433 | + #判断疏密程度 | |
434 | + p_x = (extent[1]-extent[0])/10.0 | |
435 | + p_y = (extent[3] - extent[2]) / 10.0 | |
436 | + fill_precent=0 | |
437 | + StructurePrint().print("判断疏密") | |
438 | + for ix in range(10): | |
439 | + for iy in range(10): | |
440 | + grid_extent = [extent[0]+ix*p_x,extent[0]+ix*p_x+p_x,extent[2]+iy*p_y,extent[2]+iy*p_y+p_y] | |
441 | + poly = GeometryAdapter.envelop_2_polygon(grid_extent) | |
442 | + | |
443 | + layer.SetSpatialFilter(None) | |
444 | + layer.SetSpatialFilter(poly) | |
445 | + layer.ResetReading() | |
446 | + if layer.GetNextFeature(): | |
447 | + fill_precent += 1 | |
448 | + | |
449 | + print(fill_precent) | |
450 | + StructurePrint().print("判断疏密结束") | |
451 | + | |
452 | + layer.SetSpatialFilter(None) | |
453 | + layer.ResetReading() | |
454 | + # 固有疏密程度 | |
455 | + original_density=8 | |
456 | + | |
457 | + | |
458 | + # 额外一层 | |
459 | + # self.this_gridsize.append(0.000075) | |
460 | + # self.max_level += 1 | |
461 | + ###### | |
462 | + | |
463 | + if extent[0]>180: | |
464 | + self.t_grid_size=self.project_gridsize | |
465 | + else: | |
466 | + self.t_grid_size = self.lonlat_gridsize | |
467 | + | |
468 | + for grid_size in self.t_grid_size: | |
469 | + # 最少抽稀个数 | |
470 | + if lc > self.least_vacuate_count: | |
471 | + # 网格数至少大于 | |
472 | + if ((extent[1] - extent[0]) * (extent[3] - extent[2])) / (grid_size**2)>self.least_vacuate_count: | |
473 | + # 要素数量大于网格数量 | |
474 | + # 要考虑图层的疏密程度,original_density*(100.0/fill_precent) 为疏密指数 | |
475 | + if lc * original_density * (100.0/fill_precent)>((extent[1] - extent[0])*(extent[3] - extent[2]))/(grid_size**2) : | |
476 | + print(grid_size) | |
477 | + self.this_gridsize.append(grid_size) | |
478 | + self.max_level += 1 | |
479 | + | |
480 | + | |
481 | + | |
482 | + # 创建抽稀ds | |
483 | + for l in range(self.max_level): | |
484 | + # pg_ds_l: DataSource = PGUtil.open_pg_data_source(1, DES.decode(sqlalchemy_uri)) | |
485 | + if configure.VACUATE_DB_URI: | |
486 | + pg_ds_l: DataSource = PGUtil.open_pg_data_source(1, configure.VACUATE_DB_URI) | |
487 | + else: | |
488 | + pg_ds_l: DataSource = PGUtil.open_pg_data_source(1, DES.decode(sqlalchemy_uri)) | |
489 | + pg_ds_l.StartTransaction() | |
490 | + self.pg_ds_dict[l] = pg_ds_l | |
491 | + | |
492 | + # 生成抽稀图层 | |
493 | + options = options[1:] | |
494 | + options.append("OVERWRITE=yes") | |
495 | + options.append("LAUNDER=no") | |
496 | + | |
497 | + schema = layer.schema | |
498 | + # 增加统计字段 | |
499 | + schema.append(ogr.FieldDefn("_dcigrid_count_", ogr.OFTInteger)) | |
500 | + schema.append(ogr.FieldDefn("_dcigrid_name_", ogr.OFTString)) | |
501 | + | |
502 | + for l in range(self.max_level): | |
503 | + this_grid_len = self.this_gridsize[l] | |
504 | + | |
505 | + self.vacuate_layers_gridsize[l] = this_grid_len | |
506 | + | |
507 | + pg = self.pg_ds_dict[l] | |
508 | + | |
509 | + grid_name = str(this_grid_len) | |
510 | + if this_grid_len<1: | |
511 | + grid_name = str(this_grid_len).split(".")[-1] | |
512 | + if this_grid_len.__eq__(0.00008): | |
513 | + grid_name = "00008" | |
514 | + | |
515 | + # 抽稀图层是点面混合的 | |
516 | + # 抽稀表有固定的命名规则 | |
517 | + # 抽稀表一定要覆盖 | |
518 | + | |
519 | + | |
520 | + print("{}:{}".format(self.t_grid_size.index(this_grid_len),this_grid_len)) | |
521 | + | |
522 | + | |
523 | + v_ln = "z{}_vacuate_{}_{}".format(table_guid, self.t_grid_size.index(this_grid_len), grid_name) | |
524 | + vl = pg.CreateLayer(v_ln, layer.GetSpatialRef(),ogr.wkbUnknown, options) | |
525 | + # 抽稀表需要属性 | |
526 | + vl.CreateFields(schema) | |
527 | + self.vacuate_layers[l] = vl | |
528 | + | |
529 | + else: | |
530 | + pass | |
531 | + | |
532 | + | |
533 | + def vacuate(self,g,feature): | |
534 | + | |
535 | + if self.is_spatial: | |
536 | + | |
537 | + # 插入到所有抽稀图层中 | |
538 | + for level in range(self.max_level): | |
539 | + | |
540 | + center: Geometry = g.Centroid() | |
541 | + | |
542 | + extent = g.GetEnvelope() | |
543 | + long_extent= extent[1]-extent[0] | |
544 | + lat_extent = extent[3]-extent[2] | |
545 | + | |
546 | + this_grid_len =self.vacuate_layers_gridsize[level] | |
547 | + #超大的直接加入 | |
548 | + # if long_extent > 10*this_grid_len or lat_extent >10*this_grid_len: | |
549 | + # vacuate_layer: Layer = self.vacuate_layers.get(level) | |
550 | + # feat = ogr.Feature(vacuate_layer.GetLayerDefn()) | |
551 | + # feat.SetGeometry(g) | |
552 | + # vacuate_layer.CreateFeature(feat) | |
553 | + # else: | |
554 | + | |
555 | + row = int((center.GetY() - self.extent[2]) / this_grid_len) | |
556 | + col = int((center.GetX() - self.extent[0]) / this_grid_len) | |
557 | + key = "{}.{}.{}".format(level, row, col) | |
558 | + | |
559 | + if not self.fill_dict.get(key): | |
560 | + self.fill_dict[key] = 0 | |
561 | + if self.fill_dict[key] == 0: | |
562 | + | |
563 | + vacuate_layer: Layer = self.vacuate_layers.get(level) | |
564 | + feat = ogr.Feature(vacuate_layer.GetLayerDefn()) | |
565 | + # 如果图形比网格小,直接存储其中心点 | |
566 | + if this_grid_len>long_extent and this_grid_len>lat_extent: | |
567 | + feat.SetGeometry(center) | |
568 | + else: | |
569 | + feat.SetGeometry(g) | |
570 | + | |
571 | + # 复制旧feature属性 | |
572 | + field_dict = feature.items() | |
573 | + for field_name in field_dict: | |
574 | + feat.SetField(field_name, field_dict[field_name]) | |
575 | + feat.SetField("_dcigrid_name_",".".join(key.split(".")[1:])) | |
576 | + | |
577 | + vacuate_layer.CreateFeature(feat) | |
578 | + self.fill_dict[key] += 1 | |
579 | + #超大的还有机会 | |
580 | + elif (long_extent > 10*this_grid_len or lat_extent >10*this_grid_len) and self.fill_dict[key]<5: | |
581 | + vacuate_layer: Layer = self.vacuate_layers.get(level) | |
582 | + feat = ogr.Feature(vacuate_layer.GetLayerDefn()) | |
583 | + feat.SetGeometry(g) | |
584 | + | |
585 | + # 复制旧feature属性 | |
586 | + field_dict = feature.items() | |
587 | + for field_name in field_dict: | |
588 | + feat.SetField(field_name, field_dict[field_name]) | |
589 | + feat.SetField("_dcigrid_name_",".".join(key.split(".")[1:])) | |
590 | + | |
591 | + vacuate_layer.CreateFeature(feat) | |
592 | + self.fill_dict[key] += 1 | |
593 | + else: | |
594 | + self.fill_dict[key] += 1 | |
595 | + | |
596 | + def set_vacuate_count(self): | |
597 | + if self.is_spatial: | |
598 | + # 插入到所有抽稀图层中 | |
599 | + for level in range(self.max_level): | |
600 | + vacuate_layer: Layer = self.vacuate_layers.get(level) | |
601 | + for feat in vacuate_layer: | |
602 | + key = "{}.{}".format(level,feat.GetField("_dcigrid_name_")) | |
603 | + feat.SetField("_dcigrid_count_",self.fill_dict.get(key)) | |
604 | + vacuate_layer.SetFeature(feat) | |
605 | + | |
606 | + def end(self): | |
607 | + for pg in self.pg_ds_dict.values(): | |
608 | + pg.Destroy() | |
609 | + | |
610 | + def rollback(self): | |
611 | + for pg in self.pg_ds_dict.values(): | |
612 | + pg.RollbackTransaction() | ... | ... |
app/modules/data/util/__init__.py
0 → 100644
... | ... | @@ -7,7 +7,7 @@ from flask import current_app as app |
7 | 7 | import socket |
8 | 8 | |
9 | 9 | from app.util.component.ApiTemplate import ApiTemplate |
10 | -from app.models import Task,InsertingLayerName,db | |
10 | +from app.modules.data.models import Task,InsertingLayerName,db | |
11 | 11 | import datetime |
12 | 12 | import traceback |
13 | 13 | from sqlalchemy import or_ | ... | ... |
... | ... | @@ -12,10 +12,8 @@ from . import image_server_list |
12 | 12 | from . import data_list |
13 | 13 | from . import capabilities |
14 | 14 | from . import image_tile,image_wms |
15 | -from . import image_service_list | |
16 | 15 | from . import image_tile_mask |
17 | 16 | from . import image_wmts |
18 | - | |
19 | 17 | from . import image_delete |
20 | 18 | from . import image_cancle |
21 | 19 | from . import image_register,image_list,image_info,image_edit,image_overview |
... | ... | @@ -23,10 +21,14 @@ from . import image_tag_create,image_tag_delete,image_tag_list |
23 | 21 | from . import image_wms_temporary |
24 | 22 | from . import image_wms_kv |
25 | 23 | |
26 | -class DataManager(BlueprintApi): | |
27 | 24 | |
28 | - bp = Blueprint("Image", __name__, url_prefix="/API/Service/Image") | |
29 | - service_type = ["ImageWMS","ImageWMTS"] | |
25 | +class ImageServerInstance: | |
26 | + pass | |
27 | + | |
28 | +class ImageManager(BlueprintApi): | |
29 | + | |
30 | + bp = Blueprint("ImageService", __name__, url_prefix="/API/Service/Image") | |
31 | + service_type = ["影像服务"] | |
30 | 32 | |
31 | 33 | @staticmethod |
32 | 34 | @bp.route('/Register', methods=['POST']) |
... | ... | @@ -122,14 +124,7 @@ class DataManager(BlueprintApi): |
122 | 124 | """ |
123 | 125 | return image_service_register.Api().result |
124 | 126 | |
125 | - @staticmethod | |
126 | - @bp.route('/ServiceList', methods=['GET']) | |
127 | - @swag_from(image_service_list.Api.api_doc) | |
128 | - def api_image_service_list(): | |
129 | - """ | |
130 | - 服务列表 | |
131 | - """ | |
132 | - return image_service_list.Api().result | |
127 | + | |
133 | 128 | |
134 | 129 | @staticmethod |
135 | 130 | @bp.route('/ServerList', methods=['GET']) | ... | ... |
... | ... | @@ -6,8 +6,8 @@ |
6 | 6 | |
7 | 7 | from flask import Response |
8 | 8 | from app.util.component.ApiTemplate import ApiTemplate |
9 | -from .models import ImageService | |
10 | -from app.models import Service,TileScheme | |
9 | +from ..models import ImageService | |
10 | +from ..models import Service,TileScheme | |
11 | 11 | import json |
12 | 12 | import configure |
13 | 13 | ... | ... |
... | ... | @@ -12,7 +12,7 @@ import datetime |
12 | 12 | from app.modules.service.image.util.ThriftConnect import ThriftConnect |
13 | 13 | import os |
14 | 14 | from app.models import db |
15 | -from app.modules.service.image.models import Image | |
15 | +from app.modules.service.models import Image | |
16 | 16 | from .util.ImageType import ImageType |
17 | 17 | |
18 | 18 | class Api(ApiTemplate): | ... | ... |
... | ... | @@ -7,7 +7,7 @@ |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | from app.util.component.ModelVisitor import ModelVisitor |
9 | 9 | |
10 | -from app.modules.service.image.models import Image,ImageTag | |
10 | +from app.modules.service.models import Image,ImageTag | |
11 | 11 | from app.util.component.FileProcess import FileProcess |
12 | 12 | |
13 | 13 | class Api(ApiTemplate): | ... | ... |
... | ... | @@ -7,7 +7,7 @@ |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | from app.util.component.ModelVisitor import ModelVisitor |
9 | 9 | from app.util.component.FileProcess import FileProcess |
10 | -from app.modules.service.image.models import Image,ImageTag | |
10 | +from app.modules.service.models import Image,ImageTag | |
11 | 11 | from sqlalchemy import or_ |
12 | 12 | import datetime |
13 | 13 | |
... | ... | @@ -27,7 +27,7 @@ class Api(ApiTemplate): |
27 | 27 | name = self.para.get("name") |
28 | 28 | band = self.para.get("band") |
29 | 29 | region = self.para.get("region") |
30 | - tag_guid = self.para.get("tag_guid") | |
30 | + tag_guids = self.para.get("tag_guids") | |
31 | 31 | collect_time = self.para.get("collect_time") |
32 | 32 | |
33 | 33 | type = self.para.get("type") |
... | ... | @@ -53,13 +53,17 @@ class Api(ApiTemplate): |
53 | 53 | |
54 | 54 | if collect_time: |
55 | 55 | begin,end = collect_time.split(",") |
56 | - begin = datetime.datetime.strptime(begin,"%Y-%m-%d %H:%M:%S") | |
57 | - end = datetime.datetime.strptime(end, "%Y-%m-%d %H:%M:%S") | |
58 | - images.filter(Image.collect_time>=begin).filter(Image.collect_time<=end) | |
56 | + begin:datetime.datetime= datetime.datetime.strptime(begin,"%Y-%m-%d") | |
59 | 57 | |
60 | - if tag_guid: | |
61 | - tag:ImageTag = ImageTag.query.filter_by(guid=tag_guid).one_or_none() | |
62 | - images_guid = [img.guid for img in tag.images.all()] | |
58 | + end = datetime.datetime.strptime(end, "%Y-%m-%d") | |
59 | + images = images.filter(Image.collect_time.__ge__(begin)).filter(Image.collect_time.__le__(end)) | |
60 | + | |
61 | + if tag_guids: | |
62 | + tag_guids = tag_guids.split(",") | |
63 | + tags = ImageTag.query.filter(ImageTag.guid.in_(tag_guids)).all() | |
64 | + images_guid = [] | |
65 | + for tag in tags: | |
66 | + images_guid.extend([img.guid for img in tag.images.all()]) | |
63 | 67 | images = images.filter(Image.guid.in_(images_guid)) |
64 | 68 | |
65 | 69 | |
... | ... | @@ -112,7 +116,7 @@ class Api(ApiTemplate): |
112 | 116 | {"name": "band", |
113 | 117 | "in": "formData", |
114 | 118 | "type": "string"}, |
115 | - {"name": "tag_guid", | |
119 | + {"name": "tag_guids", | |
116 | 120 | "in": "formData", |
117 | 121 | "type": "string"}, |
118 | 122 | ], | ... | ... |
... | ... | @@ -9,12 +9,12 @@ from osgeo.gdal import Dataset,Band |
9 | 9 | from app.util.component.ApiTemplate import ApiTemplate |
10 | 10 | from app.modules.service.image.util.ThriftConnect import ThriftConnect |
11 | 11 | import json |
12 | -from .models import Image | |
12 | +from ..models import Image | |
13 | 13 | import datetime |
14 | 14 | from app.models import db |
15 | 15 | import uuid |
16 | 16 | import os |
17 | -from .models import ImageTag | |
17 | +from ..models import ImageTag | |
18 | 18 | from .util.ImageType import ImageType |
19 | 19 | |
20 | 20 | class Api(ApiTemplate): | ... | ... |
... | ... | @@ -3,15 +3,15 @@ |
3 | 3 | #createtime: 2021/7/19 |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | -from app.modules.service.image.models import ImageService,Image | |
7 | -from app.models import db | |
6 | + | |
7 | + | |
8 | 8 | from app.util.component.ApiTemplate import ApiTemplate |
9 | -from app.models import Service | |
9 | +from ..models import Service,ImageService,Image,db,ServiceFunction | |
10 | 10 | import datetime |
11 | 11 | import json |
12 | 12 | from .image_service_register import Api as RegisterApi |
13 | 13 | import configure |
14 | - | |
14 | +import uuid | |
15 | 15 | |
16 | 16 | class Api(ApiTemplate): |
17 | 17 | |
... | ... | @@ -28,19 +28,30 @@ class Api(ApiTemplate): |
28 | 28 | service = Service.query.filter_by(guid=guid) |
29 | 29 | this_time = datetime.datetime.now() |
30 | 30 | image_guids = self.para.get("image_guids") |
31 | + function_types = self.para.get("function_types") | |
31 | 32 | |
32 | 33 | service_update = {} |
33 | 34 | image_update = {} |
35 | + | |
34 | 36 | for key in self.para.keys(): |
35 | - if key in ["name","title","state","description","catalog_guid","type"]: | |
37 | + if key in ["name","title","state","description","catalog_guid"]: | |
36 | 38 | service_update[key] = self.para.get(key) |
37 | 39 | if key in ["name","scheme_guid"]: |
38 | 40 | image_update[key] = self.para.get(key) |
39 | 41 | |
42 | + image_service = ImageService.query.filter_by(service_guid=guid) | |
40 | 43 | |
41 | - | |
42 | - image_service = ImageService.query.filter_by(guid=Service.query.filter_by(guid=guid).one_or_none().service_guid) | |
43 | - | |
44 | + # 修改功能 | |
45 | + if function_types: | |
46 | + new_types = function_types.split(",") | |
47 | + old_functions = ServiceFunction.query.filter_by(service_guid=guid).all() | |
48 | + for function in old_functions: | |
49 | + if function.type not in new_types: | |
50 | + db.session.delete(function) | |
51 | + for new_type in new_types: | |
52 | + if new_type not in [fun.type for fun in old_functions]: | |
53 | + service_function = ServiceFunction(guid=uuid.uuid1().__str__()) | |
54 | + db.session.add(service_function) | |
44 | 55 | |
45 | 56 | #修改影像 |
46 | 57 | if image_guids: |
... | ... | @@ -63,7 +74,7 @@ class Api(ApiTemplate): |
63 | 74 | |
64 | 75 | image_update["extent"] = json.dumps(image_service_exetent) |
65 | 76 | |
66 | - if service_update or image_update: | |
77 | + if service_update or image_update or function_types: | |
67 | 78 | service_update["update_time"] = this_time |
68 | 79 | if image_guids: |
69 | 80 | register_api = RegisterApi() |
... | ... | @@ -71,6 +82,7 @@ class Api(ApiTemplate): |
71 | 82 | service_update["overview"] = "http://{}/API/Service/Overview/{}".format(configure.deploy_ip_host, overview_file) |
72 | 83 | |
73 | 84 | service.update(service_update) |
85 | + | |
74 | 86 | if image_update: |
75 | 87 | image_service.update(image_update) |
76 | 88 | |
... | ... | @@ -91,31 +103,32 @@ class Api(ApiTemplate): |
91 | 103 | {"name": "guid", |
92 | 104 | "in": "formData", |
93 | 105 | "type": "string", |
94 | - "description": "[WMS,WMTS,影像WMS,影像WMTS,guid]"}, | |
106 | + "description": "[地图服务,切片服务,影像服务]guid"}, | |
95 | 107 | |
96 | 108 | {"name": "name", |
97 | 109 | "in": "formData", |
98 | 110 | "type": "string", |
99 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
111 | + "description": "[地图服务,切片服务,影像服务]"}, | |
100 | 112 | |
101 | - {"name": "type", | |
102 | - "in": "formData", | |
103 | - "type": "string", | |
104 | - "description": "修改服务类型"}, | |
105 | 113 | |
106 | 114 | {"name": "title", |
107 | 115 | "in": "formData", |
108 | 116 | "type": "string", |
109 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
117 | + "description": "[地图服务,切片服务,影像服务]"}, | |
110 | 118 | {"name": "description", |
111 | 119 | "in": "formData", |
112 | 120 | "type": "string", |
113 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
121 | + "description": "[地图服务,切片服务,影像服务]"}, | |
114 | 122 | |
115 | 123 | {"name": "catalog_guid", |
116 | 124 | "in": "formData", |
117 | 125 | "type": "string", |
118 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
126 | + "description": "[地图服务,切片服务,影像服务]"}, | |
127 | + | |
128 | + {"name": "function_types", | |
129 | + "in": "formData", | |
130 | + "type": "string", | |
131 | + "description": "[地图服务,切片服务,影像服务]以逗号相隔,可选WMTS,WMS"}, | |
119 | 132 | |
120 | 133 | |
121 | 134 | {"name": "image_guids", | ... | ... |
1 | -# coding=utf-8 | |
2 | -#author: 4N | |
3 | -#createtime: 2021/7/19 | |
4 | -#email: nheweijun@sina.com | |
5 | - | |
6 | -from app.modules.service.image.models import ImageService | |
7 | - | |
8 | -from app.util.component.ApiTemplate import ApiTemplate | |
9 | -from app.util.component.ModelVisitor import ModelVisitor | |
10 | -from sqlalchemy import or_ | |
11 | -class Api(ApiTemplate): | |
12 | - | |
13 | - api_name = "影像服务List" | |
14 | - | |
15 | - def process(self): | |
16 | - | |
17 | - # 返回结果 | |
18 | - res = {} | |
19 | - | |
20 | - try: | |
21 | - page_index = int(self.para.get("page_index", "0")) | |
22 | - page_size = int(self.para.get("page_size", "10")) | |
23 | - | |
24 | - alias = self.para.get("alias") | |
25 | - name = self.para.get("name") | |
26 | - type = self.para.get("type") | |
27 | - | |
28 | - services = ImageService.query | |
29 | - if type: | |
30 | - services = services.filter_by(type=type) | |
31 | - # 并集 | |
32 | - if alias and name: | |
33 | - services = services.filter( | |
34 | - or_(ImageService.alias.like("%" + alias + "%"), ImageService.name.like("%" + name + "%"))) | |
35 | - else: | |
36 | - if alias: | |
37 | - services = services.filter(ImageService.alias.like("%" + alias + "%")) | |
38 | - if name: | |
39 | - services = services.filter(ImageService.name.like("%" + name + "%")) | |
40 | - | |
41 | - | |
42 | - res["data"] = {} | |
43 | - res["data"]["count"] = services.count() | |
44 | - services = services.limit(page_size).offset(page_index * page_size).all() | |
45 | - res["data"]["list"] = ModelVisitor.objects_to_jsonarray(services) | |
46 | - res["result"] = True | |
47 | - | |
48 | - except Exception as e: | |
49 | - raise e | |
50 | - | |
51 | - return res | |
52 | - | |
53 | - api_doc = { | |
54 | - "tags": ["影像接口"], | |
55 | - "parameters": [ | |
56 | - {"name": "page_index", | |
57 | - "in": "formData", | |
58 | - "type": "int", | |
59 | - "description": "页"}, | |
60 | - {"name": "page_size", | |
61 | - "in": "formData", | |
62 | - "type": "int", | |
63 | - "description": "页大小"}, | |
64 | - {"name": "alias", | |
65 | - "in": "formData", | |
66 | - "type": "string", | |
67 | - "description": "服务别名"}, | |
68 | - {"name": "name", | |
69 | - "in": "formData", | |
70 | - "type": "string", | |
71 | - "description": "服务名"}, | |
72 | - ], | |
73 | - "responses": { | |
74 | - 200: { | |
75 | - "schema": { | |
76 | - "properties": { | |
77 | - } | |
78 | - } | |
79 | - } | |
80 | - } | |
81 | - } | |
\ No newline at end of file |
... | ... | @@ -3,8 +3,8 @@ |
3 | 3 | #createtime: 2021/7/19 |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | -from .models import ImageService,Image | |
7 | -from app.models import db,Service | |
6 | + | |
7 | +from ..models import db,Service,ImageService,Image,ServiceFunction | |
8 | 8 | from app.util.component.ApiTemplate import ApiTemplate |
9 | 9 | import uuid |
10 | 10 | |
... | ... | @@ -19,9 +19,14 @@ class Api(ApiTemplate): |
19 | 19 | |
20 | 20 | api_name = "注册影像服务" |
21 | 21 | |
22 | - def process(self): | |
22 | + def para_check(self): | |
23 | + if not self.para.get("function_types"): | |
24 | + raise Exception("缺乏影像服务类型!") | |
25 | + if self.para.get("function_types").__contains__("WMTS") and (not self.para.get("scheme_guid")): | |
26 | + raise Exception("选择WMTS功能,但是缺乏切片方案!") | |
23 | 27 | |
24 | 28 | |
29 | + def process(self): | |
25 | 30 | |
26 | 31 | # 返回结果 |
27 | 32 | res = {} |
... | ... | @@ -29,11 +34,15 @@ class Api(ApiTemplate): |
29 | 34 | try: |
30 | 35 | guids = self.para.get("guids").split(",") |
31 | 36 | name = self.para.get("name") |
37 | + function_types = self.para.get("function_types") | |
38 | + | |
32 | 39 | |
33 | 40 | image_service_guid = uuid.uuid1().__str__() |
41 | + service_guid = uuid.uuid1().__str__() | |
42 | + service_function_guid = uuid.uuid1().__str__() | |
43 | + | |
34 | 44 | |
35 | 45 | this_time = datetime.datetime.now() |
36 | - service_guid = uuid.uuid1().__str__() | |
37 | 46 | image_service = ImageService(guid=image_service_guid, |
38 | 47 | name=name, |
39 | 48 | create_time=this_time, |
... | ... | @@ -60,7 +69,7 @@ class Api(ApiTemplate): |
60 | 69 | |
61 | 70 | service = Service( |
62 | 71 | guid = service_guid, |
63 | - name = self.para.get("name"), | |
72 | + name = name, | |
64 | 73 | title = self.para.get("title"), |
65 | 74 | state = 1, |
66 | 75 | create_time = this_time, |
... | ... | @@ -68,10 +77,17 @@ class Api(ApiTemplate): |
68 | 77 | description = self.para.get("description"), |
69 | 78 | #node = Column(Integer), |
70 | 79 | type = self.para.get("type"), |
71 | - service_guid = image_service_guid, | |
72 | 80 | catalog_guid = self.para.get("catalog_guid") |
73 | 81 | ) |
74 | 82 | |
83 | + | |
84 | + | |
85 | + for type in function_types.split(","): | |
86 | + service_function = ServiceFunction(guid=service_function_guid, | |
87 | + service_guid=service_guid, | |
88 | + type=type) | |
89 | + db.session.add(service_function) | |
90 | + | |
75 | 91 | db.session.add(service) |
76 | 92 | db.session.add(image_service) |
77 | 93 | |
... | ... | @@ -80,8 +96,8 @@ class Api(ApiTemplate): |
80 | 96 | overview_file = self.get_overview(service,image_service) |
81 | 97 | service.overview="http://{}/API/Service/Overview/{}".format( |
82 | 98 | configure.deploy_ip_host,overview_file) |
83 | - db.session.commit() | |
84 | 99 | |
100 | + db.session.commit() | |
85 | 101 | res["data"] = image_service_guid |
86 | 102 | res["result"] = True |
87 | 103 | except Exception as e: |
... | ... | @@ -126,35 +142,39 @@ class Api(ApiTemplate): |
126 | 142 | "in": "formData", |
127 | 143 | "type": "string", |
128 | 144 | "required": "true", |
129 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
145 | + "description": "[地图服务,切片服务,影像服务]"}, | |
130 | 146 | {"name": "title", |
131 | 147 | "in": "formData", |
132 | 148 | "type": "string", |
133 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
149 | + "description": "[地图服务,切片服务,影像服务]"}, | |
134 | 150 | {"name": "description", |
135 | 151 | "in": "formData", |
136 | 152 | "type": "string", |
137 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
153 | + "description": "[地图服务,切片服务,影像服务]"}, | |
138 | 154 | {"name": "type", |
139 | 155 | "in": "formData", |
140 | 156 | "type": "string", |
141 | - "enum": ["WMS/WFS","WMTS","TMS","ImageWMS","ImageWMTS"], | |
157 | + "enum": ["地图服务","切片服务","影像服务"], | |
142 | 158 | "required": "true", |
143 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
159 | + "description": "[地图服务,切片服务,影像服务]"}, | |
144 | 160 | {"name": "catalog_guid", |
145 | 161 | "in": "formData", |
146 | 162 | "type": "string", |
147 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
163 | + "description": "[地图服务,切片服务,影像服务]"}, | |
148 | 164 | |
149 | 165 | # 影像参数 |
150 | 166 | {"name": "guids", |
151 | 167 | "in": "formData", |
152 | 168 | "type": "string", |
153 | - "description": "[影像WMS,影像WMTS]影像guids,以英文逗号相隔"}, | |
169 | + "description": "[影像服务]影像guids,以英文逗号相隔"}, | |
154 | 170 | {"name": "scheme_guid", |
155 | 171 | "in": "formData", |
156 | 172 | "type": "string", |
157 | - "description": "[WMTS,影像WMTS]切片方案"}, | |
173 | + "description": "[影像服务]切片方案"}, | |
174 | + {"name": "function_types", | |
175 | + "in": "formData", | |
176 | + "type": "string", | |
177 | + "description": "[影像服务]功能类型,以逗号相隔,可选WMTS,WMS"}, | |
158 | 178 | |
159 | 179 | ], |
160 | 180 | "responses": { |
... | ... | @@ -166,6 +186,3 @@ class Api(ApiTemplate): |
166 | 186 | } |
167 | 187 | } |
168 | 188 | } |
169 | - | |
170 | -if __name__ == '__main__': | |
171 | - pass | |
\ No newline at end of file | ... | ... |
... | ... | @@ -13,8 +13,8 @@ from flask import Response |
13 | 13 | |
14 | 14 | import time |
15 | 15 | import cv2 |
16 | -from app.modules.service.image.models import ImageService,Image | |
17 | -from app.models import db,TileScheme | |
16 | +from app.modules.service.models import ImageService,Image | |
17 | +from ..models import db,TileScheme | |
18 | 18 | from app.util.component.ApiTemplate import ApiTemplate |
19 | 19 | |
20 | 20 | from app.util.component.SliceScheme import SliceScheme |
... | ... | @@ -211,7 +211,7 @@ class Api(ApiTemplate): |
211 | 211 | |
212 | 212 | except Exception as e: |
213 | 213 | print(traceback.format_exc()) |
214 | - result["state"] = -1 | |
214 | + result["result"] = False | |
215 | 215 | result["message"] = e.__str__() |
216 | 216 | return result |
217 | 217 | ... | ... |
... | ... | @@ -3,19 +3,11 @@ |
3 | 3 | #createtime: 2021/3/24 |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | -from app.util import * | |
7 | -import traceback | |
8 | -import numpy | |
9 | -from flask import Response | |
10 | -import random | |
11 | -from app.modules.service.image.models import ImageService | |
6 | + | |
12 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
13 | -from app.util.component.ParameterUtil import ParameterUtil | |
14 | -import json | |
8 | + | |
15 | 9 | from threading import Thread |
16 | -from .util.ImageData import ImageData | |
17 | -from .util.Cache import Cache | |
18 | -from .util.Opencv import Opencv | |
10 | +from .util.ImageWMSServer import ImageWMSServer | |
19 | 11 | |
20 | 12 | class Api(ApiTemplate): |
21 | 13 | |
... | ... | @@ -27,251 +19,19 @@ class Api(ApiTemplate): |
27 | 19 | self.service_name = service_name |
28 | 20 | |
29 | 21 | def process(self): |
30 | - | |
31 | - | |
32 | - result = {} | |
33 | - parameter: dict = self.para | |
34 | - | |
35 | 22 | try: |
36 | - | |
37 | - parameter = ParameterUtil.to_lower(parameter) | |
38 | - if parameter.get("service_name"): | |
39 | - self.service_name = parameter.get("service_name") | |
40 | - | |
41 | - #获取缓存信息 | |
42 | - image_service_info, zoo, servers = Cache.cache_data(self.service_name, type="name") | |
43 | - | |
44 | - re = parameter.get("request") | |
45 | - if re and re.__eq__("GetCapabilities"): | |
46 | - return self.get_capabilities(image_service_info["service"]) | |
47 | - | |
48 | - bbox = parameter.get("bbox") | |
49 | - width = int(parameter.get("width")) if parameter.get("width") else 256 | |
50 | - height = int(parameter.get("height")) if parameter.get("height") else 256 | |
51 | - image_type = parameter.get("format") if parameter.get("format") else "image/png" | |
52 | - quality = int(parameter.get("quality")) if parameter.get("quality") else 30 | |
53 | - | |
54 | - extent = [float(x) for x in bbox.split(",")] | |
55 | - | |
56 | - intersect_image = [im for im in image_service_info["images"] if self.determin_intersect(json.loads(im.extent),extent)] | |
57 | - | |
58 | - if len(intersect_image)>1: | |
59 | - | |
60 | - # 结果矩阵 | |
61 | - empty_list = [numpy.zeros((height,width), dtype=int) + 65536, | |
62 | - numpy.zeros((height,width), dtype=int) + 65536, | |
63 | - numpy.zeros((height,width), dtype=int) + 65536] | |
64 | - | |
65 | - pixel_array = numpy.zeros((height,width,3), dtype=int) | |
66 | - thread_list = [] | |
67 | - | |
68 | - for image in intersect_image: | |
69 | - #该影像的服务器,随机选取一个 | |
70 | - image_servers = image.server.split(",") | |
71 | - image_servers = [ser for ser in image_servers if ser in servers] | |
72 | - if len(image_servers)>0: | |
73 | - indx = int(random.random() * len(image_servers)) | |
74 | - image_server = image_servers[indx] | |
75 | - else: | |
76 | - image_server = "None" | |
77 | - bands = json.loads(image.band_view) | |
78 | - | |
79 | - image_data = ImageData(image_server, image) | |
80 | - | |
81 | - thread: MyThread = MyThread(image_data.get_data, args=(extent,bands,height,width)) | |
82 | - thread.start() | |
83 | - thread_list.append(thread) | |
84 | - | |
85 | - | |
86 | - for thread in thread_list: | |
87 | - thread.join() | |
88 | - data = thread.get_result() | |
89 | - | |
90 | - # 掩膜在中央接口生成,合图 | |
91 | - mask = numpy.zeros((height,width), dtype=int) | |
92 | - mask2 = numpy.zeros((height,width), dtype=int) | |
93 | - jizhun = data[:, :, 0] | |
94 | - mask[jizhun == 65536] = 1 | |
95 | - mask[jizhun != 65536] = 0 | |
96 | - mask2[jizhun == 65536] = 0 | |
97 | - mask2[jizhun != 65536] = 1 | |
98 | - # 掩膜计算 | |
99 | - for i, d in enumerate(empty_list): | |
100 | - empty_list[i] = empty_list[i] * mask + data[:, :, i] * mask2 | |
101 | - | |
102 | - for ii in [0, 1, 2]: | |
103 | - # opencv 颜色排序为GBR | |
104 | - pixel_array[:, :, 2 - ii] = empty_list[ii] | |
105 | - | |
106 | - | |
107 | - elif len(intersect_image)==1: | |
108 | - # 该影像的服务器,随机选取一个 | |
109 | - image = intersect_image[0] | |
110 | - image_servers = image.server.split(",") | |
111 | - image_servers = [ser for ser in image_servers if ser in servers] | |
112 | - if len(image_servers) > 0: | |
113 | - indx = int(random.random() * len(image_servers)) | |
114 | - image_server = image_servers[indx] | |
115 | - else: | |
116 | - image_server = "None" | |
117 | - | |
118 | - bands = json.loads(image.band_view) | |
119 | - | |
120 | - image_data = ImageData(image_server, image) | |
121 | - | |
122 | - pixel_array_t = image_data.get_data(extent,bands,height,width) | |
123 | - | |
124 | - pixel_array = numpy.zeros((height, width, 3), dtype=int) | |
125 | - for ii in [0, 1, 2]: | |
126 | - # opencv 颜色排序为GBR | |
127 | - pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii] | |
128 | - else: | |
129 | - # 结果矩阵 | |
130 | - pixel_array = numpy.zeros((height, width, 3), dtype=int)+65536 | |
131 | - | |
132 | - # 将图片生成在内存中,然后直接返回response | |
133 | - im_data = Opencv.create_image(image_type, pixel_array, quality) | |
134 | - | |
135 | - if self.para.get("overview"): | |
136 | - return pixel_array | |
137 | - return Response(im_data, mimetype=image_type.lower()) | |
23 | + instance = ImageWMSServer() | |
24 | + response = instance.wms(self.service_name,self.para) | |
138 | 25 | |
139 | 26 | except Exception as e: |
140 | - print(traceback.format_exc()) | |
141 | - result["state"] = -1 | |
142 | - result["message"] = e.__str__() | |
143 | - return result | |
144 | - | |
145 | - | |
146 | - | |
147 | - def determin_intersect(self, extent1, extent2): | |
148 | - if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[ | |
149 | - 3] or extent2[3] < extent1[1]: | |
150 | - return False | |
151 | - else: | |
152 | - return True | |
153 | - | |
154 | - def get_capabilities(self,image_service:ImageService): | |
27 | + raise e | |
28 | + return response | |
155 | 29 | |
156 | - xml = '''<?xml version="1.0" encoding="utf-8" ?> | |
157 | - <WMS_Capabilities version="1.2.0"> | |
158 | - <Service> | |
159 | - <Name>WMS</Name> | |
160 | - <Title>{service_title}</Title> | |
161 | - <Abstract>{abstract}</Abstract> | |
162 | - <Keywords>GIMS</Keywords> | |
163 | - <OnlineResource/> | |
164 | - <Fees>none</Fees> | |
165 | - <AccessConstraints>none</AccessConstraints> | |
166 | - </Service> | |
167 | - <Capability> | |
168 | - <Request> | |
169 | - <GetCapabilities> | |
170 | - <Format>text/xml</Format> | |
171 | - <DCPType> | |
172 | - <HTTP> | |
173 | - <Get> | |
174 | - <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/> | |
175 | - </Get> | |
176 | - </HTTP> | |
177 | - </DCPType> | |
178 | - </GetCapabilities> | |
179 | - <GetMap> | |
180 | - <Format>png</Format> | |
181 | - <Format>jpeg</Format> | |
182 | - <Format>gif</Format> | |
183 | - <Format>image/png</Format> | |
184 | - <Format>image/jpeg</Format> | |
185 | - <Format>image/gif</Format> | |
186 | - <DCPType> | |
187 | - <HTTP> | |
188 | - <Get> | |
189 | - <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/> | |
190 | - </Get> | |
191 | - </HTTP> | |
192 | - </DCPType> | |
193 | - </GetMap> | |
194 | - <Map> | |
195 | - <Format> | |
196 | - <PNG/> | |
197 | - <GIF/> | |
198 | - <JPG/> | |
199 | - </Format> | |
200 | - <DCPType> | |
201 | - <HTTP> | |
202 | - <Get onlineResource="{url}"/> | |
203 | - </HTTP> | |
204 | - </DCPType> | |
205 | - </Map> | |
206 | - <Capabilities> | |
207 | - <Format> | |
208 | - <WMS_XML/> | |
209 | - </Format> | |
210 | - <DCPType> | |
211 | - <HTTP> | |
212 | - <Get onlineResource="{url}"/> | |
213 | - </HTTP> | |
214 | - </DCPType> | |
215 | - </Capabilities> | |
216 | - <FeatureInfo> | |
217 | - <Format> | |
218 | - <XML/> | |
219 | - <MIME/> | |
220 | - </Format> | |
221 | - <DCPType> | |
222 | - <HTTP> | |
223 | - <Get onlineResource="{url}"/> | |
224 | - </HTTP> | |
225 | - </DCPType> | |
226 | - </FeatureInfo> | |
227 | - </Request> | |
228 | - <Exception> | |
229 | - <Format> | |
230 | - <WMS_XML/> | |
231 | - <INIMAGE/> | |
232 | - <BLANK/> | |
233 | - </Format> | |
234 | - </Exception> | |
235 | - <Layer> | |
236 | - <Name>{service_name}</Name> | |
237 | - <Title>{service_title}</Title> | |
238 | - <CRS>{crs}</CRS> | |
239 | - <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/> | |
240 | - | |
241 | - <Layer queryable="1"> | |
242 | - <CRS>{crs}</CRS> | |
243 | - <Name>{layer_name}</Name> | |
244 | - <Title>{layer_title}</Title> | |
245 | - <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/> | |
246 | - </Layer> | |
247 | - </Layer> | |
248 | - </Capability> | |
249 | - </WMS_Capabilities>''' | |
250 | 30 | |
251 | - extent = json.loads(image_service.extent) | |
252 | - xml = xml.format(service_title=image_service.name, | |
253 | - service_name=image_service.name, | |
254 | - abstract= "None" , | |
255 | - crs="ESPG:4326", | |
256 | - layer_name=image_service.name, | |
257 | - layer_title=image_service.name, | |
258 | - maxx=extent[2], | |
259 | - maxy = extent[3], | |
260 | - minx = extent[0], | |
261 | - miny = extent[1], | |
262 | - url="http://{}/API/Service/Image/WMS?guid={}".format(configure.deploy_ip_host,image_service.guid)) | |
263 | - | |
264 | - | |
265 | - r = Response(response=xml, status=200, mimetype="application/xml") | |
266 | - r.headers["Content-Type"] = "text/xml; charset=utf-8" | |
267 | - return r | |
268 | 31 | |
269 | 32 | api_doc = { |
270 | 33 | "tags": ["影像接口"], |
271 | 34 | "parameters": [ |
272 | - {"name": "guid", | |
273 | - "in": "query", | |
274 | - "type": "string"}, | |
275 | 35 | {"name": "request", |
276 | 36 | "in": "query", |
277 | 37 | "type": "string", | ... | ... |
... | ... | @@ -3,269 +3,24 @@ |
3 | 3 | #createtime: 2021/3/24 |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | -from app.util import * | |
7 | -import traceback | |
8 | -import numpy | |
9 | -from flask import Response | |
10 | -import random | |
11 | -from app.modules.service.image.models import ImageService | |
12 | 6 | from app.util.component.ApiTemplate import ApiTemplate |
13 | -from app.util.component.ParameterUtil import ParameterUtil | |
14 | -import json | |
15 | 7 | from threading import Thread |
16 | -from .util.ImageData import ImageData | |
17 | -from .util.Cache import Cache | |
18 | -from .util.Opencv import Opencv | |
19 | 8 | |
9 | +from .util.ImageWMSServer import ImageWMSServer | |
20 | 10 | class Api(ApiTemplate): |
21 | 11 | |
22 | 12 | api_name = "WMS" |
23 | 13 | |
24 | 14 | def process(self): |
25 | - | |
26 | - | |
27 | - result = {} | |
28 | - parameter: dict = self.para | |
29 | - | |
30 | 15 | try: |
31 | - | |
32 | - parameter = ParameterUtil.to_lower(parameter) | |
33 | - if parameter.get("guid"): | |
34 | - self.guid = parameter.get("guid") | |
35 | - | |
36 | - #获取缓存信息 | |
37 | - if parameter.get("guid"): | |
38 | - | |
39 | - image_service_info, zoo, servers = Cache.cache_data(self.guid, type="guid") | |
40 | - else: | |
41 | - image_service_info, zoo, servers = Cache.cache_data(parameter.get("service_name"), type="name") | |
42 | - | |
43 | - re = parameter.get("request") | |
44 | - if re and re.__eq__("GetCapabilities"): | |
45 | - return self.get_capabilities(image_service_info["service"]) | |
46 | - | |
47 | - bbox = parameter.get("bbox") | |
48 | - width = int(parameter.get("width")) if parameter.get("width") else 256 | |
49 | - height = int(parameter.get("height")) if parameter.get("height") else 256 | |
50 | - image_type = parameter.get("format") if parameter.get("format") else "image/png" | |
51 | - quality = int(parameter.get("quality")) if parameter.get("quality") else 30 | |
52 | - | |
53 | - | |
54 | - | |
55 | - extent = [float(x) for x in bbox.split(",")] | |
56 | - | |
57 | - intersect_image = [im for im in image_service_info["images"] if self.determin_intersect(json.loads(im.extent),extent)] | |
58 | - | |
59 | - if len(intersect_image)>1: | |
60 | - | |
61 | - # 结果矩阵 | |
62 | - empty_list = [numpy.zeros((height,width), dtype=int) + 65536, | |
63 | - numpy.zeros((height,width), dtype=int) + 65536, | |
64 | - numpy.zeros((height,width), dtype=int) + 65536] | |
65 | - | |
66 | - pixel_array = numpy.zeros((height,width,3), dtype=int) | |
67 | - thread_list = [] | |
68 | - | |
69 | - for image in intersect_image: | |
70 | - #该影像的服务器,随机选取一个 | |
71 | - image_servers = image.server.split(",") | |
72 | - image_servers = [ser for ser in image_servers if ser in servers] | |
73 | - if len(image_servers)>0: | |
74 | - indx = int(random.random() * len(image_servers)) | |
75 | - image_server = image_servers[indx] | |
76 | - else: | |
77 | - image_server = "None" | |
78 | - bands = json.loads(image.band_view) | |
79 | - | |
80 | - image_data = ImageData(image_server, image) | |
81 | - | |
82 | - thread: MyThread = MyThread(image_data.get_data, args=(extent,bands,height,width)) | |
83 | - thread.start() | |
84 | - thread_list.append(thread) | |
85 | - | |
86 | - | |
87 | - for thread in thread_list: | |
88 | - thread.join() | |
89 | - data = thread.get_result() | |
90 | - | |
91 | - # 掩膜在中央接口生成,合图 | |
92 | - mask = numpy.zeros((height,width), dtype=int) | |
93 | - mask2 = numpy.zeros((height,width), dtype=int) | |
94 | - jizhun = data[:, :, 0] | |
95 | - mask[jizhun == 65536] = 1 | |
96 | - mask[jizhun != 65536] = 0 | |
97 | - mask2[jizhun == 65536] = 0 | |
98 | - mask2[jizhun != 65536] = 1 | |
99 | - # 掩膜计算 | |
100 | - for i, d in enumerate(empty_list): | |
101 | - empty_list[i] = empty_list[i] * mask + data[:, :, i] * mask2 | |
102 | - | |
103 | - for ii in [0, 1, 2]: | |
104 | - # opencv 颜色排序为GBR | |
105 | - pixel_array[:, :, 2 - ii] = empty_list[ii] | |
106 | - | |
107 | - | |
108 | - elif len(intersect_image)==1: | |
109 | - # 该影像的服务器,随机选取一个 | |
110 | - image = intersect_image[0] | |
111 | - image_servers = image.server.split(",") | |
112 | - image_servers = [ser for ser in image_servers if ser in servers] | |
113 | - if len(image_servers) > 0: | |
114 | - indx = int(random.random() * len(image_servers)) | |
115 | - image_server = image_servers[indx] | |
116 | - else: | |
117 | - image_server = "None" | |
118 | - | |
119 | - bands = json.loads(image.band_view) | |
120 | - | |
121 | - image_data = ImageData(image_server, image) | |
122 | - | |
123 | - pixel_array_t = image_data.get_data(extent,bands,height,width) | |
124 | - | |
125 | - pixel_array = numpy.zeros((height, width, 3), dtype=int) | |
126 | - for ii in [0, 1, 2]: | |
127 | - # opencv 颜色排序为GBR | |
128 | - pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii] | |
16 | + instance = ImageWMSServer() | |
17 | + if self.para.get("guid"): | |
18 | + response = instance.wms(self.para.get("service_name"),self.para) | |
129 | 19 | else: |
130 | - # 结果矩阵 | |
131 | - pixel_array = numpy.zeros((height, width, 3), dtype=int)+65536 | |
132 | - | |
133 | - # 将图片生成在内存中,然后直接返回response | |
134 | - im_data = Opencv.create_image(image_type, pixel_array, quality) | |
135 | - | |
136 | - if self.para.get("overview"): | |
137 | - return pixel_array | |
138 | - return Response(im_data, mimetype=image_type.lower()) | |
139 | - | |
20 | + response = instance.wms(self.para.get("guid"), self.para,type="guid") | |
140 | 21 | except Exception as e: |
141 | - print(traceback.format_exc()) | |
142 | - result["state"] = -1 | |
143 | - result["message"] = e.__str__() | |
144 | - return result | |
145 | - | |
146 | - | |
147 | - | |
148 | - def determin_intersect(self, extent1, extent2): | |
149 | - if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[ | |
150 | - 3] or extent2[3] < extent1[1]: | |
151 | - return False | |
152 | - else: | |
153 | - return True | |
154 | - | |
155 | - def get_capabilities(self,image_service:ImageService): | |
156 | - | |
157 | - xml = '''<?xml version="1.0" encoding="utf-8" ?> | |
158 | - <WMS_Capabilities version="1.2.0"> | |
159 | - <Service> | |
160 | - <Name>WMS</Name> | |
161 | - <Title>{service_title}</Title> | |
162 | - <Abstract>{abstract}</Abstract> | |
163 | - <Keywords>GIMS</Keywords> | |
164 | - <OnlineResource/> | |
165 | - <Fees>none</Fees> | |
166 | - <AccessConstraints>none</AccessConstraints> | |
167 | - </Service> | |
168 | - <Capability> | |
169 | - <Request> | |
170 | - <GetCapabilities> | |
171 | - <Format>text/xml</Format> | |
172 | - <DCPType> | |
173 | - <HTTP> | |
174 | - <Get> | |
175 | - <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/> | |
176 | - </Get> | |
177 | - </HTTP> | |
178 | - </DCPType> | |
179 | - </GetCapabilities> | |
180 | - <GetMap> | |
181 | - <Format>png</Format> | |
182 | - <Format>jpeg</Format> | |
183 | - <Format>gif</Format> | |
184 | - <Format>image/png</Format> | |
185 | - <Format>image/jpeg</Format> | |
186 | - <Format>image/gif</Format> | |
187 | - <DCPType> | |
188 | - <HTTP> | |
189 | - <Get> | |
190 | - <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/> | |
191 | - </Get> | |
192 | - </HTTP> | |
193 | - </DCPType> | |
194 | - </GetMap> | |
195 | - <Map> | |
196 | - <Format> | |
197 | - <PNG/> | |
198 | - <GIF/> | |
199 | - <JPG/> | |
200 | - </Format> | |
201 | - <DCPType> | |
202 | - <HTTP> | |
203 | - <Get onlineResource="{url}"/> | |
204 | - </HTTP> | |
205 | - </DCPType> | |
206 | - </Map> | |
207 | - <Capabilities> | |
208 | - <Format> | |
209 | - <WMS_XML/> | |
210 | - </Format> | |
211 | - <DCPType> | |
212 | - <HTTP> | |
213 | - <Get onlineResource="{url}"/> | |
214 | - </HTTP> | |
215 | - </DCPType> | |
216 | - </Capabilities> | |
217 | - <FeatureInfo> | |
218 | - <Format> | |
219 | - <XML/> | |
220 | - <MIME/> | |
221 | - </Format> | |
222 | - <DCPType> | |
223 | - <HTTP> | |
224 | - <Get onlineResource="{url}"/> | |
225 | - </HTTP> | |
226 | - </DCPType> | |
227 | - </FeatureInfo> | |
228 | - </Request> | |
229 | - <Exception> | |
230 | - <Format> | |
231 | - <WMS_XML/> | |
232 | - <INIMAGE/> | |
233 | - <BLANK/> | |
234 | - </Format> | |
235 | - </Exception> | |
236 | - <Layer> | |
237 | - <Name>{service_name}</Name> | |
238 | - <Title>{service_title}</Title> | |
239 | - <CRS>{crs}</CRS> | |
240 | - <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/> | |
241 | - | |
242 | - <Layer queryable="1"> | |
243 | - <CRS>{crs}</CRS> | |
244 | - <Name>{layer_name}</Name> | |
245 | - <Title>{layer_title}</Title> | |
246 | - <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/> | |
247 | - </Layer> | |
248 | - </Layer> | |
249 | - </Capability> | |
250 | - </WMS_Capabilities>''' | |
251 | - | |
252 | - extent = json.loads(image_service.extent) | |
253 | - xml = xml.format(service_title=image_service.name, | |
254 | - service_name=image_service.name, | |
255 | - abstract= "None" , | |
256 | - crs="ESPG:4326", | |
257 | - layer_name=image_service.name, | |
258 | - layer_title=image_service.name, | |
259 | - maxx=extent[2], | |
260 | - maxy = extent[3], | |
261 | - minx = extent[0], | |
262 | - miny = extent[1], | |
263 | - url="http://{}/API/Service/Image/WMS?guid={}".format(configure.deploy_ip_host,image_service.guid)) | |
264 | - | |
265 | - | |
266 | - r = Response(response=xml, status=200, mimetype="application/xml") | |
267 | - r.headers["Content-Type"] = "text/xml; charset=utf-8" | |
268 | - return r | |
22 | + raise e | |
23 | + return response | |
269 | 24 | |
270 | 25 | api_doc = { |
271 | 26 | "tags": ["影像接口"], |
... | ... | @@ -273,6 +28,9 @@ class Api(ApiTemplate): |
273 | 28 | {"name": "guid", |
274 | 29 | "in": "query", |
275 | 30 | "type": "string"}, |
31 | + {"name": "service_name", | |
32 | + "in": "query", | |
33 | + "type": "string"}, | |
276 | 34 | {"name": "bbox", |
277 | 35 | "in": "query", |
278 | 36 | "type": "string"}, | ... | ... |
... | ... | @@ -9,7 +9,7 @@ import numpy |
9 | 9 | from flask import Response |
10 | 10 | import random |
11 | 11 | |
12 | -from app.modules.service.image.models import Image | |
12 | +from app.modules.service.models import Image | |
13 | 13 | from app.util.component.ApiTemplate import ApiTemplate |
14 | 14 | |
15 | 15 | from app.util.component.ParameterUtil import ParameterUtil |
... | ... | @@ -152,7 +152,7 @@ class Api(ApiTemplate): |
152 | 152 | |
153 | 153 | except Exception as e: |
154 | 154 | print(traceback.format_exc()) |
155 | - result["state"] = -1 | |
155 | + result["result"] = False | |
156 | 156 | result["message"] = e.__str__() |
157 | 157 | return result |
158 | 158 | ... | ... |
... | ... | @@ -3,331 +3,29 @@ |
3 | 3 | #createtime: 2021/3/24 |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | -from app.util import * | |
7 | 6 | import traceback |
8 | -import numpy | |
9 | -from flask import Response | |
10 | -from .util.ImageData import ImageData | |
11 | - | |
12 | -from app.modules.service.image.models import ImageService | |
13 | -from app.models import TileScheme,Service | |
14 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
15 | -from app.util.component.SliceScheme import SliceScheme | |
16 | -from app.util.component.ParameterUtil import ParameterUtil | |
17 | -import json | |
18 | -import random | |
19 | -import copy | |
20 | -from .util.Opencv import Opencv | |
21 | -from .util.Cache import Cache | |
22 | -from .util.MyThread import MyThread | |
23 | 8 | |
9 | +from .util.ImageWMTSServer import ImageWMTSServer | |
24 | 10 | class Api(ApiTemplate): |
25 | - | |
26 | 11 | api_name = "切片" |
27 | - | |
28 | 12 | def __init__(self,service_name): |
29 | 13 | super().__init__() |
30 | 14 | self.service_name = service_name |
31 | 15 | |
32 | 16 | def process(self): |
33 | - | |
34 | - result = {} | |
35 | - parameter: dict = self.para | |
36 | - | |
37 | 17 | try: |
38 | - if parameter.get("service_name"): | |
39 | - self.service_name = parameter.get("service_name") | |
40 | - | |
41 | - #获取缓存数据 | |
42 | - image_service_info, zoo, servers = Cache.cache_data(self.service_name,type="name") | |
43 | - | |
44 | - # 转换参数 | |
45 | - parameter = ParameterUtil.to_lower(parameter) | |
46 | - | |
47 | - re = parameter.get("request") | |
48 | - if re and re.__eq__("GetCapabilities"): | |
49 | - service = Service.query.filter_by(guid=image_service_info["service"].service_guid).one_or_none() | |
50 | - return self.get_capabilities(image_service_info["service"],service) | |
51 | - | |
52 | - if parameter.get("tilematrix"): | |
53 | - if parameter.get("tilematrix").__contains__(":"): | |
54 | - self.level = int(parameter.get("tilematrix").split(":")[-1]) | |
55 | - else: | |
56 | - self.level = int(parameter.get("tilematrix")) | |
57 | - if parameter.get("tilerow"): | |
58 | - self.row = int(parameter.get("tilerow")) | |
59 | - if parameter.get("tilecol"): | |
60 | - self.col = int(parameter.get("tilecol")) | |
61 | - | |
62 | - image_type = parameter.get("format") if parameter.get("format") else "image/png" | |
63 | - quality = int(parameter.get("quality")) if parameter.get("quality") else 30 | |
64 | - slice_para = image_service_info["scheme"] | |
65 | - extent = SliceScheme.get_polygon(slice_para, self.level, self.row, self.col) | |
66 | - | |
67 | - height, width = 256,256 | |
68 | - | |
69 | - # 多线程获取分布式数据 | |
70 | - | |
71 | - intersect_image = [im for im in image_service_info["images"] if self.determin_intersect(json.loads(im.extent),extent)] | |
72 | - | |
73 | - if len(intersect_image) > 1: | |
74 | - | |
75 | - # 结果矩阵 | |
76 | - pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536 | |
77 | - | |
78 | - thread_list = [] | |
79 | - | |
80 | - for image in intersect_image: | |
81 | - | |
82 | - # 该影像的服务器,随机选取一个 | |
83 | - image_servers = image.server.split(",") | |
84 | - image_servers = [ser for ser in image_servers if ser in servers] | |
85 | - if len(image_servers)>0: | |
86 | - indx = int(random.random() * len(image_servers)) | |
87 | - image_server = image_servers[indx] | |
88 | - else: | |
89 | - image_server = "None" | |
90 | - | |
91 | - bands = json.loads(image.band_view) | |
92 | - | |
93 | - image_data = ImageData(image_server,image) | |
94 | - | |
95 | - thread: MyThread = MyThread(image_data.get_data,args=(extent, bands, height, width)) | |
96 | - | |
97 | - thread.start() | |
98 | - thread_list.append(thread) | |
99 | - | |
100 | - for thread in thread_list: | |
101 | - thread.join() | |
102 | - data = thread.get_result() | |
103 | - | |
104 | - # 掩膜在中央接口生成,合图 | |
105 | - mask = numpy.zeros((height, width, 3), dtype=int) | |
106 | - mask_data = numpy.zeros((height, width, 3), dtype=int) | |
107 | - | |
108 | - mask[data == 65536] = 1 | |
109 | - mask[data != 65536] = 0 | |
110 | - mask_data[data == 65536] = 0 | |
111 | - mask_data[data != 65536] = 1 | |
112 | - | |
113 | - # # 掩膜计算 | |
114 | - pixel_array = pixel_array * mask + data * mask_data | |
115 | - | |
116 | - # opencv 颜色排序为GBR | |
117 | - d1 = copy.copy(pixel_array[:,:,0]) | |
118 | - pixel_array[:, :, 0] = pixel_array[:,:,2] | |
119 | - pixel_array[:, :, 2] = d1 | |
120 | - | |
121 | - | |
122 | - elif len(intersect_image) == 1: | |
123 | - # 该影像的服务器,随机选取一个 | |
124 | - image = intersect_image[0] | |
125 | - image_servers = image.server.split(",") | |
126 | - #判断可用服务器 | |
127 | - image_servers = [ser for ser in image_servers if ser in servers] | |
128 | - if len(image_servers) > 0: | |
129 | - indx = int(random.random() * len(image_servers)) | |
130 | - image_server = image_servers[indx] | |
131 | - else: | |
132 | - image_server = "None" | |
133 | - # image_server = image_servers[0] | |
134 | - bands = json.loads(image.band_view) | |
135 | - | |
136 | - image_data = ImageData(image_server, image) | |
137 | - pixel_array_t: numpy.ndarray = image_data.get_data(extent, bands, height, width) | |
138 | - pixel_array = numpy.zeros((height, width, 3), dtype=int) | |
139 | - | |
140 | - for ii in [0, 1, 2]: | |
141 | - # opencv 颜色排序为GBR | |
142 | - pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii] | |
143 | - | |
144 | - else: | |
145 | - # 结果矩阵 | |
146 | - pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536 | |
147 | - | |
148 | - | |
149 | - | |
150 | - | |
151 | - # 将图片生成在内存中,然后直接返回response | |
152 | - im_data = Opencv.create_image(image_type, pixel_array, quality) | |
153 | - return Response(im_data, mimetype=image_type.lower()) | |
154 | - | |
155 | - | |
18 | + instance = ImageWMTSServer() | |
19 | + response = instance.wmts(self.service_name,self.para) | |
156 | 20 | except Exception as e: |
157 | 21 | print(traceback.format_exc()) |
158 | - result["state"] = -1 | |
159 | - result["message"] = e.__str__() | |
160 | - return result | |
161 | - | |
162 | - def get_capabilities(self, image_service: ImageService, service: Service): | |
163 | - tile_scheme: TileScheme = TileScheme.query.filter_by(guid=image_service.scheme_guid).one_or_none() | |
164 | - if not tile_scheme: | |
165 | - raise Exception("切片方案不存在!") | |
166 | - | |
167 | - xml = '''<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0"> | |
168 | - <!-- Service Identification --> | |
169 | - <ows:ServiceIdentification> | |
170 | - <ows:Title>{title}</ows:Title> | |
171 | - <ows:ServiceType>OGC WMTS</ows:ServiceType> | |
172 | - <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion> | |
173 | - </ows:ServiceIdentification> | |
174 | - | |
175 | - <!-- Operations Metadata --> | |
176 | - <ows:OperationsMetadata> | |
177 | - <ows:Operation name="GetCapabilities"> | |
178 | - <ows:DCP> | |
179 | - <ows:HTTP> | |
180 | - <ows:Get xlink:href="{capabilities_url}"> | |
181 | - <ows:Constraint name="GetEncoding"> | |
182 | - <ows:AllowedValues> | |
183 | - <ows:Value>RESTful</ows:Value> | |
184 | - </ows:AllowedValues> | |
185 | - </ows:Constraint> | |
186 | - </ows:Get> | |
187 | - | |
188 | - <!-- add KVP binding in 10.1 --> | |
189 | - <ows:Get xlink:href="{tile_url}?"> | |
190 | - <ows:Constraint name="GetEncoding"> | |
191 | - <ows:AllowedValues> | |
192 | - <ows:Value>KVP</ows:Value> | |
193 | - </ows:AllowedValues> | |
194 | - </ows:Constraint> | |
195 | - </ows:Get> | |
196 | - </ows:HTTP> | |
197 | - </ows:DCP> | |
198 | - </ows:Operation> | |
199 | - <ows:Operation name="GetTile"> | |
200 | - <ows:DCP> | |
201 | - <ows:HTTP> | |
202 | - <ows:Get xlink:href="{tile_url}"> | |
203 | - <ows:Constraint name="GetEncoding"> | |
204 | - <ows:AllowedValues> | |
205 | - <ows:Value>RESTful</ows:Value> | |
206 | - </ows:AllowedValues> | |
207 | - </ows:Constraint> | |
208 | - </ows:Get> | |
209 | - <ows:Get xlink:href="{tile_url}?"> | |
210 | - <ows:Constraint name="GetEncoding"> | |
211 | - <ows:AllowedValues> | |
212 | - <ows:Value>KVP</ows:Value> | |
213 | - </ows:AllowedValues> | |
214 | - </ows:Constraint> | |
215 | - </ows:Get> | |
216 | - </ows:HTTP> | |
217 | - </ows:DCP> | |
218 | - </ows:Operation> | |
219 | - </ows:OperationsMetadata> | |
220 | - | |
221 | - <Contents> | |
222 | - | |
223 | - <!-- Layer --> | |
224 | - | |
225 | - | |
226 | - <Layer> | |
227 | - <ows:Title>{title}</ows:Title> | |
228 | - <ows:Identifier>{title}</ows:Identifier> | |
229 | - <ows:BoundingBox crs="{crs}"> | |
230 | - <ows:LowerCorner>{xmin} {ymin}</ows:LowerCorner> | |
231 | - <ows:UpperCorner>{xmax} {ymax}</ows:UpperCorner> | |
232 | - </ows:BoundingBox> | |
233 | - | |
234 | - <Style isDefault="true"> | |
235 | - <ows:Title>Default Style</ows:Title> | |
236 | - <ows:Identifier>default</ows:Identifier> | |
237 | - </Style> | |
238 | - <Format>image/png</Format> | |
239 | - <TileMatrixSetLink> | |
240 | - <TileMatrixSet>{tile_name}</TileMatrixSet> | |
241 | - </TileMatrixSetLink> | |
242 | - | |
243 | - <ResourceURL format="image/png" resourceType="tile" template="{tile_url}"/> | |
244 | - | |
245 | - </Layer> | |
246 | - | |
247 | - <!-- TileMatrixSet --> | |
248 | - | |
249 | - | |
250 | - <TileMatrixSet> | |
251 | - | |
252 | - <TileMatrix> | |
253 | - <ows:Title>{tile_title}</ows:Title> | |
254 | - <ows:Abstract>{tile_description}</ows:Abstract> | |
255 | - <ows:Identifier>{tile_name}</ows:Identifier> | |
256 | - <ows:SupportedCRS>{crs}</ows:SupportedCRS> | |
257 | - | |
258 | - {tile_matrix} | |
259 | - | |
260 | - </TileMatrix> | |
261 | - | |
262 | - </TileMatrixSet> | |
263 | - | |
264 | - | |
265 | - </Contents> | |
266 | - <ServiceMetadataURL xlink:href="{capabilities_url}"/> | |
267 | - </Capabilities>''' | |
268 | - | |
269 | - tile_matrix_each = ''' | |
270 | - <TileMatrix> | |
271 | - <ows:Identifier>{lev}</ows:Identifier> | |
272 | - <ScaleDenominator>{scale}</ScaleDenominator> | |
273 | - <TopLeftCorner>{top_left}</TopLeftCorner> | |
274 | - <TileWidth>{cols}</TileWidth> | |
275 | - <TileHeight>{rows}</TileHeight> | |
276 | - </TileMatrix> | |
277 | - ''' | |
278 | - | |
279 | - tile_matrix = "" | |
280 | - top_left = tile_scheme.top_left | |
281 | - for level in json.loads(tile_scheme.levels): | |
282 | - tile_matrix = "{}{}".format(tile_matrix, tile_matrix_each.format(lev=level["level"], | |
283 | - scale=level["scale"], | |
284 | - top_left=top_left, | |
285 | - cols=tile_scheme.cols, | |
286 | - rows=tile_scheme.rows)) | |
287 | - | |
288 | - extent = json.loads(image_service.extent) | |
289 | - | |
290 | - xml = xml.format( | |
291 | - capabilities_url="http://{}/API/Service/Image/Capabilities?guid={}".format(configure.deploy_ip_host, | |
292 | - image_service.guid), | |
293 | - tile_url="http://{}/API/Service/Image/Tile?guid={}".format(configure.deploy_ip_host, image_service.guid), | |
294 | - crs=tile_scheme.crs, | |
295 | - xmin=extent[0], | |
296 | - ymin=extent[1], | |
297 | - xmax=extent[2], | |
298 | - ymax=extent[3], | |
299 | - # TileMatrix = "{TileMatrix}", | |
300 | - # TileRow = "{TileRow}", | |
301 | - # TileCol = "{TileCol}", | |
302 | - guid=image_service.guid, | |
303 | - title=service.title, | |
304 | - tile_title=tile_scheme.name, | |
305 | - tile_name=tile_scheme.name, | |
306 | - tile_description=tile_scheme.description, | |
307 | - tile_matrix=tile_matrix | |
308 | - ) | |
309 | - | |
310 | - r = Response(response=xml, status=200, mimetype="application/xml") | |
311 | - r.headers["Content-Type"] = "text/xml; charset=utf-8" | |
312 | - | |
313 | - return r | |
314 | - | |
315 | - | |
316 | - | |
317 | - def determin_intersect(self, extent1, extent2): | |
318 | - if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[ | |
319 | - 3] or extent2[3] < extent1[1]: | |
320 | - return False | |
321 | - else: | |
322 | - return True | |
22 | + raise e | |
23 | + return response | |
323 | 24 | |
324 | 25 | |
325 | 26 | api_doc = { |
326 | 27 | "tags": ["影像接口"], |
327 | 28 | "parameters": [ |
328 | - {"name": "guid", | |
329 | - "in": "formData", | |
330 | - "type": "string"}, | |
331 | 29 | {"name": "request", |
332 | 30 | "in": "formData", |
333 | 31 | "type": "string", | ... | ... |
1 | -# coding=utf-8 | |
2 | -#author: 4N | |
3 | -#createtime: 2021/6/11 | |
4 | -#email: nheweijun@sina.com | |
5 | - | |
6 | - | |
7 | -from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Time,Binary,Float | |
8 | -from app.models import db | |
9 | - | |
10 | - | |
11 | - | |
12 | -class Image(db.Model): | |
13 | - ''' | |
14 | - 影像元数据 | |
15 | - ''' | |
16 | - __tablename__ = 'dmap_image' | |
17 | - guid = Column(String(256), primary_key=True) | |
18 | - name = Column(String) | |
19 | - alias = Column(String) | |
20 | - raster_y_size = Column(Integer)#图像y 分辨率 | |
21 | - raster_x_size = Column(Integer)#图像x 分辨率 | |
22 | - overview_count = Column(Integer)#金字塔等级 | |
23 | - extent = Column(String)#范围 | |
24 | - # geo_origin_extent = Column(String) | |
25 | - null_value = Column(Integer)#空值 | |
26 | - available = Column(Integer)#影像是否可用,不可用可能在创建金字塔中 | |
27 | - band_count = Column(Integer)#波段数 | |
28 | - band_view = Column(String)#波段设置 | |
29 | - path = Column(String) | |
30 | - server = Column(String) | |
31 | - | |
32 | - size = Column(Float) | |
33 | - #坐标wkt | |
34 | - crs_wkt = Column(Text) #坐标wkt | |
35 | - crs_proj4 = Column(Text)#坐标proj | |
36 | - crs = Column(String)#坐标 | |
37 | - create_time = Column(DateTime) | |
38 | - update_time = Column(DateTime) | |
39 | - cell_x_size = Column(Float)#像元x大小 | |
40 | - cell_y_size = Column(Float)#像元y大小 | |
41 | - region = Column(Text) | |
42 | - | |
43 | - collect_time = Column(DateTime) #成像时间年份 | |
44 | - | |
45 | - satellite = Column(String)#卫星类型 | |
46 | - type = Column(String(128)) | |
47 | - | |
48 | - | |
49 | -dmap_image_rel = db.Table('dmap_image_rel', | |
50 | - Column('image_guid',String, ForeignKey('dmap_image.guid')), | |
51 | - Column('service_guid', String, ForeignKey('dmap_image_service.guid')) | |
52 | - ) | |
53 | - | |
54 | - | |
55 | - | |
56 | -class ImageService(db.Model): | |
57 | - ''' | |
58 | - 影像服务 | |
59 | - ''' | |
60 | - __tablename__ = 'dmap_image_service' | |
61 | - guid = Column(String(256), primary_key=True) | |
62 | - name = Column(String) | |
63 | - scheme_guid = Column(String) | |
64 | - extent = Column(String(256)) | |
65 | - # node = Column(Integer) | |
66 | - #可视范围geojson | |
67 | - visual_region = Column(Text) | |
68 | - crs = Column(String(256)) | |
69 | - create_time = Column(DateTime) | |
70 | - # service_guid = Column(String, ForeignKey('dmap_service.guid')) | |
71 | - | |
72 | - service_guid = Column(String) | |
73 | - | |
74 | - images = db.relationship('Image', | |
75 | - secondary=dmap_image_rel, | |
76 | - backref='image_services', | |
77 | - lazy='dynamic' | |
78 | - ) | |
79 | - | |
80 | - | |
81 | -dmap_image_tag_rel = db.Table('dmap_image_tag_rel', | |
82 | - Column('image_guid',String, ForeignKey('dmap_image.guid')), | |
83 | - Column('tag_guid', String, ForeignKey('dmap_image_tag.guid')) | |
84 | - ) | |
85 | - | |
86 | -class ImageTag(db.Model): | |
87 | - ''' | |
88 | - 影像标签 | |
89 | - ''' | |
90 | - __tablename__ = 'dmap_image_tag' | |
91 | - guid = Column(String(256), primary_key=True) | |
92 | - name=Column(String(256)) | |
93 | - alias = Column(String(256)) | |
94 | - images = db.relationship('Image', | |
95 | - secondary=dmap_image_tag_rel, | |
96 | - backref='image_tags', | |
97 | - lazy='dynamic' | |
98 | - ) |
... | ... | @@ -7,8 +7,8 @@ |
7 | 7 | from kazoo.client import KazooClient |
8 | 8 | import configure |
9 | 9 | import time |
10 | -from app.modules.service.image.models import ImageService | |
11 | -from app.models import TileScheme,Service | |
10 | +from app.modules.service.models import ImageService | |
11 | +from app.modules.service.models import TileScheme,Service | |
12 | 12 | import json |
13 | 13 | |
14 | 14 | class Cache: | ... | ... |
1 | +# coding=utf-8 | |
2 | +#author: 4N | |
3 | +#createtime: 2021/10/26 | |
4 | +#email: nheweijun@sina.com | |
5 | + | |
6 | + | |
7 | +import numpy | |
8 | +from app.util.component.ParameterUtil import ParameterUtil | |
9 | +from .Cache import Cache | |
10 | +from app.modules.service.models import ImageService | |
11 | +from flask import Response | |
12 | +from .ImageData import ImageData | |
13 | +from .MyThread import MyThread | |
14 | +from .Opencv import Opencv | |
15 | +import json | |
16 | +import random | |
17 | +import configure | |
18 | +import threading | |
19 | +from .ImageServer import ImageServer | |
20 | + | |
21 | + | |
22 | +class ImageWMSServer(ImageServer): | |
23 | + | |
24 | + _instance_lock = threading.Lock() | |
25 | + singleton = None | |
26 | + | |
27 | + def __init__(self): | |
28 | + pass | |
29 | + | |
30 | + def __new__(cls, *args, **kwargs): | |
31 | + if not cls.singleton: | |
32 | + with ImageWMSServer._instance_lock: | |
33 | + cls.singleton = super().__new__(cls) | |
34 | + return cls.singleton | |
35 | + | |
36 | + def wms(self,service_name,parameter,type="name"): | |
37 | + | |
38 | + # 获取缓存信息 | |
39 | + image_service_info, zoo, servers = Cache.cache_data(service_name, type=type) | |
40 | + # 转换参数 | |
41 | + parameter = ParameterUtil.to_lower(parameter) | |
42 | + re = parameter.get("request") | |
43 | + if re and re.__eq__("GetCapabilities"): | |
44 | + return self.get_wms_capabilities(image_service_info["service"]) | |
45 | + | |
46 | + bbox = parameter.get("bbox") | |
47 | + width = int(parameter.get("width")) if parameter.get("width") else 256 | |
48 | + height = int(parameter.get("height")) if parameter.get("height") else 256 | |
49 | + image_type = parameter.get("format") if parameter.get("format") else "image/png" | |
50 | + quality = int(parameter.get("quality")) if parameter.get("quality") else 30 | |
51 | + | |
52 | + extent = [float(x) for x in bbox.split(",")] | |
53 | + | |
54 | + intersect_image = [im for im in image_service_info["images"] if | |
55 | + self.determin_intersect(json.loads(im.extent), extent)] | |
56 | + | |
57 | + if len(intersect_image) > 1: | |
58 | + | |
59 | + # 结果矩阵 | |
60 | + empty_list = [numpy.zeros((height, width), dtype=int) + 65536, | |
61 | + numpy.zeros((height, width), dtype=int) + 65536, | |
62 | + numpy.zeros((height, width), dtype=int) + 65536] | |
63 | + | |
64 | + pixel_array = numpy.zeros((height, width, 3), dtype=int) | |
65 | + thread_list = [] | |
66 | + | |
67 | + for image in intersect_image: | |
68 | + # 该影像的服务器,随机选取一个 | |
69 | + image_servers = image.server.split(",") | |
70 | + image_servers = [ser for ser in image_servers if ser in servers] | |
71 | + if len(image_servers) > 0: | |
72 | + indx = int(random.random() * len(image_servers)) | |
73 | + image_server = image_servers[indx] | |
74 | + else: | |
75 | + image_server = "None" | |
76 | + bands = json.loads(image.band_view) | |
77 | + | |
78 | + image_data = ImageData(image_server, image) | |
79 | + | |
80 | + thread: MyThread = MyThread(image_data.get_data, args=(extent, bands, height, width)) | |
81 | + thread.start() | |
82 | + thread_list.append(thread) | |
83 | + | |
84 | + for thread in thread_list: | |
85 | + thread.join() | |
86 | + data = thread.get_result() | |
87 | + | |
88 | + # 掩膜在中央接口生成,合图 | |
89 | + mask = numpy.zeros((height, width), dtype=int) | |
90 | + mask2 = numpy.zeros((height, width), dtype=int) | |
91 | + jizhun = data[:, :, 0] | |
92 | + mask[jizhun == 65536] = 1 | |
93 | + mask[jizhun != 65536] = 0 | |
94 | + mask2[jizhun == 65536] = 0 | |
95 | + mask2[jizhun != 65536] = 1 | |
96 | + # 掩膜计算 | |
97 | + for i, d in enumerate(empty_list): | |
98 | + empty_list[i] = empty_list[i] * mask + data[:, :, i] * mask2 | |
99 | + | |
100 | + for ii in [0, 1, 2]: | |
101 | + # opencv 颜色排序为GBR | |
102 | + pixel_array[:, :, 2 - ii] = empty_list[ii] | |
103 | + | |
104 | + | |
105 | + elif len(intersect_image) == 1: | |
106 | + # 该影像的服务器,随机选取一个 | |
107 | + image = intersect_image[0] | |
108 | + image_servers = image.server.split(",") | |
109 | + image_servers = [ser for ser in image_servers if ser in servers] | |
110 | + if len(image_servers) > 0: | |
111 | + indx = int(random.random() * len(image_servers)) | |
112 | + image_server = image_servers[indx] | |
113 | + else: | |
114 | + image_server = "None" | |
115 | + | |
116 | + bands = json.loads(image.band_view) | |
117 | + | |
118 | + image_data = ImageData(image_server, image) | |
119 | + | |
120 | + pixel_array_t = image_data.get_data(extent, bands, height, width) | |
121 | + | |
122 | + pixel_array = numpy.zeros((height, width, 3), dtype=int) | |
123 | + for ii in [0, 1, 2]: | |
124 | + # opencv 颜色排序为GBR | |
125 | + pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii] | |
126 | + else: | |
127 | + # 结果矩阵 | |
128 | + pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536 | |
129 | + | |
130 | + # 将图片生成在内存中,然后直接返回response | |
131 | + im_data = Opencv.create_image(image_type, pixel_array, quality) | |
132 | + | |
133 | + if parameter.get("overview"): | |
134 | + return pixel_array | |
135 | + return Response(im_data, mimetype=image_type.lower()) | |
136 | + | |
137 | + | |
138 | + def get_wms_capabilities(self, image_service: ImageService): | |
139 | + | |
140 | + xml = '''<?xml version="1.0" encoding="utf-8" ?> | |
141 | + <WMS_Capabilities version="1.2.0"> | |
142 | + <Service> | |
143 | + <Name>WMS</Name> | |
144 | + <Title>{service_title}</Title> | |
145 | + <Abstract>{abstract}</Abstract> | |
146 | + <Keywords>GIMS</Keywords> | |
147 | + <OnlineResource/> | |
148 | + <Fees>none</Fees> | |
149 | + <AccessConstraints>none</AccessConstraints> | |
150 | + </Service> | |
151 | + <Capability> | |
152 | + <Request> | |
153 | + <GetCapabilities> | |
154 | + <Format>text/xml</Format> | |
155 | + <DCPType> | |
156 | + <HTTP> | |
157 | + <Get> | |
158 | + <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/> | |
159 | + </Get> | |
160 | + </HTTP> | |
161 | + </DCPType> | |
162 | + </GetCapabilities> | |
163 | + <GetMap> | |
164 | + <Format>png</Format> | |
165 | + <Format>jpeg</Format> | |
166 | + <Format>gif</Format> | |
167 | + <Format>image/png</Format> | |
168 | + <Format>image/jpeg</Format> | |
169 | + <Format>image/gif</Format> | |
170 | + <DCPType> | |
171 | + <HTTP> | |
172 | + <Get> | |
173 | + <OnlineResource xlink:href="{url}" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/> | |
174 | + </Get> | |
175 | + </HTTP> | |
176 | + </DCPType> | |
177 | + </GetMap> | |
178 | + <Map> | |
179 | + <Format> | |
180 | + <PNG/> | |
181 | + <GIF/> | |
182 | + <JPG/> | |
183 | + </Format> | |
184 | + <DCPType> | |
185 | + <HTTP> | |
186 | + <Get onlineResource="{url}"/> | |
187 | + </HTTP> | |
188 | + </DCPType> | |
189 | + </Map> | |
190 | + <Capabilities> | |
191 | + <Format> | |
192 | + <WMS_XML/> | |
193 | + </Format> | |
194 | + <DCPType> | |
195 | + <HTTP> | |
196 | + <Get onlineResource="{url}"/> | |
197 | + </HTTP> | |
198 | + </DCPType> | |
199 | + </Capabilities> | |
200 | + <FeatureInfo> | |
201 | + <Format> | |
202 | + <XML/> | |
203 | + <MIME/> | |
204 | + </Format> | |
205 | + <DCPType> | |
206 | + <HTTP> | |
207 | + <Get onlineResource="{url}"/> | |
208 | + </HTTP> | |
209 | + </DCPType> | |
210 | + </FeatureInfo> | |
211 | + </Request> | |
212 | + <Exception> | |
213 | + <Format> | |
214 | + <WMS_XML/> | |
215 | + <INIMAGE/> | |
216 | + <BLANK/> | |
217 | + </Format> | |
218 | + </Exception> | |
219 | + <Layer> | |
220 | + <Name>{service_name}</Name> | |
221 | + <Title>{service_title}</Title> | |
222 | + <CRS>{crs}</CRS> | |
223 | + <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/> | |
224 | + | |
225 | + <Layer queryable="1"> | |
226 | + <CRS>{crs}</CRS> | |
227 | + <Name>{layer_name}</Name> | |
228 | + <Title>{layer_title}</Title> | |
229 | + <BoundingBox CRS="{crs}" maxx="{maxx}" maxy="{maxy}" minx="{minx}" miny="{miny}"/> | |
230 | + </Layer> | |
231 | + </Layer> | |
232 | + </Capability> | |
233 | + </WMS_Capabilities>''' | |
234 | + | |
235 | + extent = json.loads(image_service.extent) | |
236 | + xml = xml.format(service_title=image_service.name, | |
237 | + service_name=image_service.name, | |
238 | + abstract="None", | |
239 | + crs="ESPG:4326", | |
240 | + layer_name=image_service.name, | |
241 | + layer_title=image_service.name, | |
242 | + maxx=extent[2], | |
243 | + maxy=extent[3], | |
244 | + minx=extent[0], | |
245 | + miny=extent[1], | |
246 | + url="http://{}/API/Service/Image/WMS?guid={}".format(configure.deploy_ip_host, | |
247 | + image_service.guid)) | |
248 | + | |
249 | + r = Response(response=xml, status=200, mimetype="application/xml") | |
250 | + r.headers["Content-Type"] = "text/xml; charset=utf-8" | |
251 | + return r | |
252 | + | |
253 | + def determin_intersect(self, extent1, extent2): | |
254 | + if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[ | |
255 | + 3] or extent2[3] < extent1[1]: | |
256 | + return False | |
257 | + else: | |
258 | + return True | |
\ No newline at end of file | ... | ... |
1 | +# coding=utf-8 | |
2 | +#author: 4N | |
3 | +#createtime: 2021/10/26 | |
4 | +#email: nheweijun@sina.com | |
5 | + | |
6 | + | |
7 | +import numpy | |
8 | +from app.util.component.ParameterUtil import ParameterUtil | |
9 | +from .Cache import Cache | |
10 | +from app.modules.service.models import ImageService | |
11 | +from flask import Response | |
12 | +from .ImageData import ImageData | |
13 | +from .MyThread import MyThread | |
14 | +from .Opencv import Opencv | |
15 | +from app.modules.service.models import Service,TileScheme | |
16 | +import json | |
17 | +import random | |
18 | +import copy | |
19 | +import configure | |
20 | +from app.util.component.SliceScheme import SliceScheme | |
21 | +import threading | |
22 | +from .ImageServer import ImageServer | |
23 | + | |
24 | +class ImageWMTSServer(ImageServer): | |
25 | + _instance_lock = threading.Lock() | |
26 | + singleton = None | |
27 | + | |
28 | + def __init__(self): | |
29 | + pass | |
30 | + | |
31 | + def __new__(cls, *args, **kwargs): | |
32 | + if not cls.singleton: | |
33 | + with ImageWMTSServer._instance_lock: | |
34 | + cls.singleton = super().__new__(cls) | |
35 | + return cls.singleton | |
36 | + | |
37 | + | |
38 | + def wmts(self,service_name,parameter,type="name"): | |
39 | + | |
40 | + image_service_info, zoo, servers = Cache.cache_data(service_name, type=type) | |
41 | + | |
42 | + # 转换参数 | |
43 | + parameter = ParameterUtil.to_lower(parameter) | |
44 | + | |
45 | + re = parameter.get("request") | |
46 | + if re and re.__eq__("GetCapabilities"): | |
47 | + service = Service.query.filter_by(guid=image_service_info["service"].service_guid).one_or_none() | |
48 | + return self.get_wmts_capabilities(image_service_info["service"], service) | |
49 | + | |
50 | + if parameter.get("tilematrix"): | |
51 | + if parameter.get("tilematrix").__contains__(":"): | |
52 | + self.level = int(parameter.get("tilematrix").split(":")[-1]) | |
53 | + else: | |
54 | + self.level = int(parameter.get("tilematrix")) | |
55 | + if parameter.get("tilerow"): | |
56 | + self.row = int(parameter.get("tilerow")) | |
57 | + if parameter.get("tilecol"): | |
58 | + self.col = int(parameter.get("tilecol")) | |
59 | + | |
60 | + image_type = parameter.get("format") if parameter.get("format") else "image/png" | |
61 | + quality = int(parameter.get("quality")) if parameter.get("quality") else 30 | |
62 | + slice_para = image_service_info["scheme"] | |
63 | + extent = SliceScheme.get_polygon(slice_para, self.level, self.row, self.col) | |
64 | + | |
65 | + height, width = 256, 256 | |
66 | + | |
67 | + # 多线程获取分布式数据 | |
68 | + | |
69 | + intersect_image = [im for im in image_service_info["images"] if | |
70 | + self.determin_intersect(json.loads(im.extent), extent)] | |
71 | + | |
72 | + if len(intersect_image) > 1: | |
73 | + | |
74 | + # 结果矩阵 | |
75 | + pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536 | |
76 | + | |
77 | + thread_list = [] | |
78 | + | |
79 | + for image in intersect_image: | |
80 | + | |
81 | + # 该影像的服务器,随机选取一个 | |
82 | + image_servers = image.server.split(",") | |
83 | + image_servers = [ser for ser in image_servers if ser in servers] | |
84 | + if len(image_servers) > 0: | |
85 | + indx = int(random.random() * len(image_servers)) | |
86 | + image_server = image_servers[indx] | |
87 | + else: | |
88 | + image_server = "None" | |
89 | + | |
90 | + bands = json.loads(image.band_view) | |
91 | + | |
92 | + image_data = ImageData(image_server, image) | |
93 | + | |
94 | + thread: MyThread = MyThread(image_data.get_data, args=(extent, bands, height, width)) | |
95 | + | |
96 | + thread.start() | |
97 | + thread_list.append(thread) | |
98 | + | |
99 | + for thread in thread_list: | |
100 | + thread.join() | |
101 | + data = thread.get_result() | |
102 | + | |
103 | + # 掩膜在中央接口生成,合图 | |
104 | + mask = numpy.zeros((height, width, 3), dtype=int) | |
105 | + mask_data = numpy.zeros((height, width, 3), dtype=int) | |
106 | + | |
107 | + mask[data == 65536] = 1 | |
108 | + mask[data != 65536] = 0 | |
109 | + mask_data[data == 65536] = 0 | |
110 | + mask_data[data != 65536] = 1 | |
111 | + | |
112 | + # # 掩膜计算 | |
113 | + pixel_array = pixel_array * mask + data * mask_data | |
114 | + | |
115 | + # opencv 颜色排序为GBR | |
116 | + d1 = copy.copy(pixel_array[:, :, 0]) | |
117 | + pixel_array[:, :, 0] = pixel_array[:, :, 2] | |
118 | + pixel_array[:, :, 2] = d1 | |
119 | + | |
120 | + | |
121 | + elif len(intersect_image) == 1: | |
122 | + # 该影像的服务器,随机选取一个 | |
123 | + image = intersect_image[0] | |
124 | + image_servers = image.server.split(",") | |
125 | + # 判断可用服务器 | |
126 | + image_servers = [ser for ser in image_servers if ser in servers] | |
127 | + if len(image_servers) > 0: | |
128 | + indx = int(random.random() * len(image_servers)) | |
129 | + image_server = image_servers[indx] | |
130 | + else: | |
131 | + image_server = "None" | |
132 | + # image_server = image_servers[0] | |
133 | + bands = json.loads(image.band_view) | |
134 | + | |
135 | + image_data = ImageData(image_server, image) | |
136 | + pixel_array_t: numpy.ndarray = image_data.get_data(extent, bands, height, width) | |
137 | + pixel_array = numpy.zeros((height, width, 3), dtype=int) | |
138 | + | |
139 | + for ii in [0, 1, 2]: | |
140 | + # opencv 颜色排序为GBR | |
141 | + pixel_array[:, :, 2 - ii] = pixel_array_t[:, :, ii] | |
142 | + | |
143 | + else: | |
144 | + # 结果矩阵 | |
145 | + pixel_array = numpy.zeros((height, width, 3), dtype=int) + 65536 | |
146 | + | |
147 | + # 将图片生成在内存中,然后直接返回response | |
148 | + im_data = Opencv.create_image(image_type, pixel_array, quality) | |
149 | + return Response(im_data, mimetype=image_type.lower()) | |
150 | + | |
151 | + | |
152 | + def get_wmts_capabilities(self, image_service: ImageService, service: Service): | |
153 | + tile_scheme: TileScheme = TileScheme.query.filter_by(guid=image_service.scheme_guid).one_or_none() | |
154 | + if not tile_scheme: | |
155 | + raise Exception("切片方案不存在!") | |
156 | + | |
157 | + xml = '''<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0"> | |
158 | + <!-- Service Identification --> | |
159 | + <ows:ServiceIdentification> | |
160 | + <ows:Title>{title}</ows:Title> | |
161 | + <ows:ServiceType>OGC WMTS</ows:ServiceType> | |
162 | + <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion> | |
163 | + </ows:ServiceIdentification> | |
164 | + | |
165 | + <!-- Operations Metadata --> | |
166 | + <ows:OperationsMetadata> | |
167 | + <ows:Operation name="GetCapabilities"> | |
168 | + <ows:DCP> | |
169 | + <ows:HTTP> | |
170 | + <ows:Get xlink:href="{capabilities_url}"> | |
171 | + <ows:Constraint name="GetEncoding"> | |
172 | + <ows:AllowedValues> | |
173 | + <ows:Value>RESTful</ows:Value> | |
174 | + </ows:AllowedValues> | |
175 | + </ows:Constraint> | |
176 | + </ows:Get> | |
177 | + | |
178 | + <!-- add KVP binding in 10.1 --> | |
179 | + <ows:Get xlink:href="{tile_url}?"> | |
180 | + <ows:Constraint name="GetEncoding"> | |
181 | + <ows:AllowedValues> | |
182 | + <ows:Value>KVP</ows:Value> | |
183 | + </ows:AllowedValues> | |
184 | + </ows:Constraint> | |
185 | + </ows:Get> | |
186 | + </ows:HTTP> | |
187 | + </ows:DCP> | |
188 | + </ows:Operation> | |
189 | + <ows:Operation name="GetTile"> | |
190 | + <ows:DCP> | |
191 | + <ows:HTTP> | |
192 | + <ows:Get xlink:href="{tile_url}"> | |
193 | + <ows:Constraint name="GetEncoding"> | |
194 | + <ows:AllowedValues> | |
195 | + <ows:Value>RESTful</ows:Value> | |
196 | + </ows:AllowedValues> | |
197 | + </ows:Constraint> | |
198 | + </ows:Get> | |
199 | + <ows:Get xlink:href="{tile_url}?"> | |
200 | + <ows:Constraint name="GetEncoding"> | |
201 | + <ows:AllowedValues> | |
202 | + <ows:Value>KVP</ows:Value> | |
203 | + </ows:AllowedValues> | |
204 | + </ows:Constraint> | |
205 | + </ows:Get> | |
206 | + </ows:HTTP> | |
207 | + </ows:DCP> | |
208 | + </ows:Operation> | |
209 | + </ows:OperationsMetadata> | |
210 | + | |
211 | + <Contents> | |
212 | + | |
213 | + <!-- Layer --> | |
214 | + | |
215 | + | |
216 | + <Layer> | |
217 | + <ows:Title>{title}</ows:Title> | |
218 | + <ows:Identifier>{title}</ows:Identifier> | |
219 | + <ows:BoundingBox crs="{crs}"> | |
220 | + <ows:LowerCorner>{xmin} {ymin}</ows:LowerCorner> | |
221 | + <ows:UpperCorner>{xmax} {ymax}</ows:UpperCorner> | |
222 | + </ows:BoundingBox> | |
223 | + | |
224 | + <Style isDefault="true"> | |
225 | + <ows:Title>Default Style</ows:Title> | |
226 | + <ows:Identifier>default</ows:Identifier> | |
227 | + </Style> | |
228 | + <Format>image/png</Format> | |
229 | + <TileMatrixSetLink> | |
230 | + <TileMatrixSet>{tile_name}</TileMatrixSet> | |
231 | + </TileMatrixSetLink> | |
232 | + | |
233 | + <ResourceURL format="image/png" resourceType="tile" template="{tile_url}"/> | |
234 | + | |
235 | + </Layer> | |
236 | + | |
237 | + <!-- TileMatrixSet --> | |
238 | + | |
239 | + | |
240 | + <TileMatrixSet> | |
241 | + | |
242 | + <TileMatrix> | |
243 | + <ows:Title>{tile_title}</ows:Title> | |
244 | + <ows:Abstract>{tile_description}</ows:Abstract> | |
245 | + <ows:Identifier>{tile_name}</ows:Identifier> | |
246 | + <ows:SupportedCRS>{crs}</ows:SupportedCRS> | |
247 | + | |
248 | + {tile_matrix} | |
249 | + | |
250 | + </TileMatrix> | |
251 | + | |
252 | + </TileMatrixSet> | |
253 | + | |
254 | + | |
255 | + </Contents> | |
256 | + <ServiceMetadataURL xlink:href="{capabilities_url}"/> | |
257 | + </Capabilities>''' | |
258 | + | |
259 | + tile_matrix_each = ''' | |
260 | + <TileMatrix> | |
261 | + <ows:Identifier>{lev}</ows:Identifier> | |
262 | + <ScaleDenominator>{scale}</ScaleDenominator> | |
263 | + <TopLeftCorner>{top_left}</TopLeftCorner> | |
264 | + <TileWidth>{cols}</TileWidth> | |
265 | + <TileHeight>{rows}</TileHeight> | |
266 | + </TileMatrix> | |
267 | + ''' | |
268 | + | |
269 | + tile_matrix = "" | |
270 | + top_left = tile_scheme.top_left | |
271 | + for level in json.loads(tile_scheme.levels): | |
272 | + tile_matrix = "{}{}".format(tile_matrix, tile_matrix_each.format(lev=level["level"], | |
273 | + scale=level["scale"], | |
274 | + top_left=top_left, | |
275 | + cols=tile_scheme.cols, | |
276 | + rows=tile_scheme.rows)) | |
277 | + | |
278 | + extent = json.loads(image_service.extent) | |
279 | + | |
280 | + xml = xml.format( | |
281 | + capabilities_url="http://{}/API/Service/Image/Capabilities?guid={}".format(configure.deploy_ip_host, | |
282 | + image_service.guid), | |
283 | + tile_url="http://{}/API/Service/Image/Tile?guid={}".format(configure.deploy_ip_host, image_service.guid), | |
284 | + crs=tile_scheme.crs, | |
285 | + xmin=extent[0], | |
286 | + ymin=extent[1], | |
287 | + xmax=extent[2], | |
288 | + ymax=extent[3], | |
289 | + # TileMatrix = "{TileMatrix}", | |
290 | + # TileRow = "{TileRow}", | |
291 | + # TileCol = "{TileCol}", | |
292 | + guid=image_service.guid, | |
293 | + title=service.title, | |
294 | + tile_title=tile_scheme.name, | |
295 | + tile_name=tile_scheme.name, | |
296 | + tile_description=tile_scheme.description, | |
297 | + tile_matrix=tile_matrix | |
298 | + ) | |
299 | + | |
300 | + r = Response(response=xml, status=200, mimetype="application/xml") | |
301 | + r.headers["Content-Type"] = "text/xml; charset=utf-8" | |
302 | + | |
303 | + return r | |
304 | + | |
305 | + | |
306 | + | |
307 | + def determin_intersect(self, extent1, extent2): | |
308 | + if extent2[2] < extent1[0] or extent2[0] > extent1[2] or extent2[1] > extent1[ | |
309 | + 3] or extent2[3] < extent1[1]: | |
310 | + return False | |
311 | + else: | |
312 | + return True | |
\ No newline at end of file | ... | ... |
... | ... | @@ -6,28 +6,28 @@ |
6 | 6 | from flasgger import swag_from |
7 | 7 | from flask import Blueprint |
8 | 8 | from app.util import BlueprintApi |
9 | -from . import wms_register,wms_edit | |
9 | +from . import map_service_register,map_service_edit | |
10 | 10 | |
11 | 11 | class DataManager(BlueprintApi): |
12 | 12 | |
13 | - bp = Blueprint("WMS", __name__, url_prefix="/API/Service/WMS") | |
14 | - service_type = ["WMS/WFS"] | |
13 | + bp = Blueprint("MapService", __name__, url_prefix="/API/Service/MapService") | |
14 | + service_type = ["地图服务"] | |
15 | 15 | |
16 | 16 | @staticmethod |
17 | 17 | @bp.route('/Register', methods=['POST']) |
18 | - @swag_from(wms_register.Api.api_doc) | |
18 | + @swag_from(map_service_register.Api.api_doc) | |
19 | 19 | def api_wms_register(): |
20 | 20 | """ |
21 | - 注册WMS | |
21 | + 注册MapService | |
22 | 22 | """ |
23 | - return wms_register.Api().result | |
23 | + return map_service_register.Api().result | |
24 | 24 | |
25 | 25 | |
26 | 26 | @staticmethod |
27 | 27 | @bp.route('/Edit', methods=['POST']) |
28 | - @swag_from(wms_edit.Api.api_doc) | |
28 | + @swag_from(map_service_edit.Api.api_doc) | |
29 | 29 | def api_wms_edit(): |
30 | 30 | """ |
31 | - 修改WMS | |
31 | + 修改MapService | |
32 | 32 | """ |
33 | - return wms_edit.Api().result | |
\ No newline at end of file | ||
33 | + return map_service_edit.Api().result | |
\ No newline at end of file | ... | ... |
... | ... | @@ -6,18 +6,16 @@ |
6 | 6 | |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | import uuid |
9 | -from .models import WMS | |
10 | -from app.models import Service,db | |
9 | +from ..models import Service,MapService,db | |
10 | + | |
11 | 11 | |
12 | 12 | import datetime |
13 | 13 | class Api(ApiTemplate): |
14 | 14 | |
15 | - api_name = "修改WMTS服务" | |
15 | + api_name = "修改MapService服务" | |
16 | 16 | |
17 | 17 | def process(self): |
18 | 18 | |
19 | - | |
20 | - | |
21 | 19 | # 返回结果 |
22 | 20 | res = {} |
23 | 21 | |
... | ... | @@ -28,24 +26,21 @@ class Api(ApiTemplate): |
28 | 26 | |
29 | 27 | |
30 | 28 | service_update = {"update_time":this_time} |
31 | - wms_update = {"updatetime":this_time} | |
29 | + map_service_update = {"updatetime":this_time} | |
32 | 30 | for key in self.para.keys(): |
33 | 31 | if key in ["name","title","state","description","overview","catalog_guid"]: |
34 | 32 | service_update[key] = self.para.get(key) |
35 | - if key in ["status","description","username","readonly", | |
33 | + if key in ["name","status","description","username","readonly", | |
36 | 34 | "sid","stype","ssupply","sctime","company","abstract","thumbnail","layer_style"]: |
37 | - wms_update[key] = self.para.get(key) | |
38 | - if key.__eq__("name"): | |
39 | - wms_update["service"] = self.para.get(key) | |
35 | + map_service_update[key] = self.para.get(key) | |
40 | 36 | |
41 | 37 | |
42 | - | |
43 | - wms = WMS.query.filter_by(guid=Service.query.filter_by(guid=guid).one_or_none().service_guid) | |
38 | + map_service = MapService.query.filter_by(service_guid=guid) | |
44 | 39 | |
45 | 40 | if service_update: |
46 | 41 | service.update(service_update) |
47 | - if wms_update: | |
48 | - wms.update(wms_update) | |
42 | + if map_service_update: | |
43 | + map_service.update(map_service_update) | |
49 | 44 | |
50 | 45 | db.session.commit() |
51 | 46 | |
... | ... | @@ -56,75 +51,80 @@ class Api(ApiTemplate): |
56 | 51 | return res |
57 | 52 | |
58 | 53 | api_doc = { |
59 | - "tags": ["WMS接口"], | |
54 | + "tags": ["地图服务接口"], | |
60 | 55 | "parameters": [ |
61 | 56 | |
62 | 57 | {"name": "name", |
63 | 58 | "in": "formData", |
64 | 59 | "type": "string", |
65 | 60 | "required": "true", |
66 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
61 | + "description": "[地图服务,切片服务,影像服务]"}, | |
67 | 62 | {"name": "title", |
68 | 63 | "in": "formData", |
69 | 64 | "type": "string", |
70 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
65 | + "description": "[地图服务,切片服务,影像服务]"}, | |
71 | 66 | {"name": "description", |
72 | 67 | "in": "formData", |
73 | 68 | "type": "string", |
74 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
69 | + "description": "[地图服务,切片服务,影像服务]"}, | |
75 | 70 | {"name": "catalog_guid", |
76 | 71 | "in": "formData", |
77 | 72 | "type": "string", |
78 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
79 | - | |
73 | + "description": "[地图服务,切片服务,影像服务]"}, | |
80 | 74 | |
81 | 75 | |
82 | 76 | {"name": "layer_style", |
83 | 77 | "in": "formData", |
84 | 78 | "type": "string", |
85 | - "description": "[WMTS,WMS]图层样式"}, | |
79 | + "description": "[地图服务,切片服务]图层样式"}, | |
80 | + | |
81 | + {"name": "functions", | |
82 | + "in": "formData", | |
83 | + "type": "string", | |
84 | + "description": "[地图服务]服务能力,用逗号相隔"}, | |
85 | + | |
86 | 86 | |
87 | - # WMS参数 | |
87 | + # MapService参数 | |
88 | 88 | {"name": "status", |
89 | 89 | "in": "formData", |
90 | 90 | "type": "string", |
91 | - "description": "[WMS]status"}, | |
91 | + "description": "[地图服务]status"}, | |
92 | 92 | {"name": "username", |
93 | 93 | "in": "formData", |
94 | 94 | "type": "string", |
95 | - "description": "[WMS]username"}, | |
95 | + "description": "[地图服务]username"}, | |
96 | 96 | {"name": "readonly", |
97 | 97 | "in": "formData", |
98 | 98 | "type": "string", |
99 | - "description": "[WMS]readonly"}, | |
99 | + "description": "[地图服务]readonly"}, | |
100 | 100 | {"name": "sid", |
101 | 101 | "in": "formData", |
102 | 102 | "type": "string", |
103 | - "description": "[WMS]sid"}, | |
103 | + "description": "[地图服务]sid"}, | |
104 | 104 | {"name": "stype", |
105 | 105 | "in": "formData", |
106 | 106 | "type": "string", |
107 | - "description": "[WMS]stype"}, | |
107 | + "description": "[地图服务]stype"}, | |
108 | 108 | {"name": "ssupply", |
109 | 109 | "in": "formData", |
110 | 110 | "type": "string", |
111 | - "description": "[WMS]ssupply"}, | |
111 | + "description": "[地图服务]ssupply"}, | |
112 | 112 | {"name": "sctime", |
113 | 113 | "in": "formData", |
114 | 114 | "type": "string", |
115 | - "description": "[WMS]sctime"}, | |
115 | + "description": "[地图服务]sctime"}, | |
116 | 116 | {"name": "company", |
117 | 117 | "in": "formData", |
118 | 118 | "type": "string", |
119 | - "description": "[WMS]company"}, | |
119 | + "description": "[地图服务]company"}, | |
120 | 120 | {"name": "abstract", |
121 | 121 | "in": "formData", |
122 | 122 | "type": "string", |
123 | - "description": "[WMS]abstract"}, | |
123 | + "description": "[地图服务]abstract"}, | |
124 | 124 | {"name": "thumbnail", |
125 | 125 | "in": "formData", |
126 | 126 | "type": "string", |
127 | - "description": "[WMS]thumbnail"}, | |
127 | + "description": "[地图服务]thumbnail"}, | |
128 | 128 | |
129 | 129 | ], |
130 | 130 | "responses": { | ... | ... |
... | ... | @@ -6,13 +6,12 @@ |
6 | 6 | |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | import uuid |
9 | -from .models import WMS | |
10 | -from app.models import Service,db | |
9 | +from ..models import Service,db,MapService,ServiceFunction | |
11 | 10 | import datetime |
12 | 11 | import configure |
13 | 12 | class Api(ApiTemplate): |
14 | 13 | |
15 | - api_name = "注册WMS服务" | |
14 | + api_name = "注册MapService服务" | |
16 | 15 | |
17 | 16 | def process(self): |
18 | 17 | # 返回结果 |
... | ... | @@ -22,10 +21,10 @@ class Api(ApiTemplate): |
22 | 21 | |
23 | 22 | this_time = datetime.datetime.now() |
24 | 23 | service_guid = uuid.uuid1().__str__() |
25 | - wms_service_guid = uuid.uuid1().__str__() | |
24 | + map_service_guid = uuid.uuid1().__str__() | |
25 | + service_function_guid = uuid.uuid1().__str__() | |
26 | 26 | |
27 | - | |
28 | - #调用wms服务发布接口 | |
27 | + #调用MapService服务发布接口 | |
29 | 28 | |
30 | 29 | service = Service( |
31 | 30 | guid = service_guid, |
... | ... | @@ -39,13 +38,12 @@ class Api(ApiTemplate): |
39 | 38 | node = 1 , |
40 | 39 | overview = "xxxx", |
41 | 40 | type = self.para.get("type"), |
42 | - service_guid = wms_service_guid, | |
43 | 41 | catalog_guid = self.para.get("catalog_guid") |
44 | 42 | ) |
45 | 43 | |
46 | - wms = WMS( | |
47 | - guid = wms_service_guid, | |
48 | - service = self.para.get("name"), | |
44 | + map_service = MapService( | |
45 | + guid = map_service_guid, | |
46 | + name = self.para.get("name"), | |
49 | 47 | status = self.para.get("status"), |
50 | 48 | description=self.para.get("description"), |
51 | 49 | username = self.para.get("username"), |
... | ... | @@ -62,10 +60,24 @@ class Api(ApiTemplate): |
62 | 60 | service_guid = service_guid |
63 | 61 | ) |
64 | 62 | |
63 | + service_function = ServiceFunction(guid=service_function_guid,type="WMS", | |
64 | + service_guid=service_guid) | |
65 | 65 | |
66 | 66 | db.session.add(service) |
67 | - db.session.add(wms) | |
67 | + db.session.add(map_service) | |
68 | + db.session.add(service_function) | |
68 | 69 | db.session.commit() |
70 | + | |
71 | + # 调用MapService服务的注册服务接口 | |
72 | + try: | |
73 | + pass | |
74 | + except Exception as e: | |
75 | + db.session.delete(service) | |
76 | + db.session.delete(map_service) | |
77 | + db.session.delete(service_function) | |
78 | + db.session.commit() | |
79 | + raise e | |
80 | + | |
69 | 81 | res["data"] = service_guid |
70 | 82 | res["result"] = True |
71 | 83 | except Exception as e: |
... | ... | @@ -74,82 +86,78 @@ class Api(ApiTemplate): |
74 | 86 | return res |
75 | 87 | |
76 | 88 | api_doc = { |
77 | - "tags": ["WMS接口"], | |
89 | + "tags": ["地图服务接口"], | |
78 | 90 | "parameters": [ |
79 | 91 | |
80 | 92 | {"name": "name", |
81 | 93 | "in": "formData", |
82 | 94 | "type": "string", |
83 | 95 | "required": "true", |
84 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
96 | + "description": "[地图服务,切片服务,影像服务]"}, | |
85 | 97 | {"name": "title", |
86 | 98 | "in": "formData", |
87 | 99 | "type": "string", |
88 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
100 | + "description": "[地图服务,切片服务,影像服务]"}, | |
89 | 101 | {"name": "description", |
90 | 102 | "in": "formData", |
91 | 103 | "type": "string", |
92 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
104 | + "description": "[地图服务,切片服务,影像服务]"}, | |
93 | 105 | {"name": "type", |
94 | 106 | "in": "formData", |
95 | 107 | "type": "string", |
96 | - "enum": ["WMS", "WMTS", "影像WMS", "影像WMTS"], | |
108 | + "enum": ["地图服务", "切片服务", "影像服务"], | |
97 | 109 | "required": "true", |
98 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
110 | + "description": "[地图服务,切片服务,影像服务]"}, | |
99 | 111 | {"name": "catalog_guid", |
100 | 112 | "in": "formData", |
101 | 113 | "type": "string", |
102 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
114 | + "description": "[地图服务,切片服务,影像服务]"}, | |
103 | 115 | |
104 | - {"name": "catalog_guid", | |
105 | - "in": "formData", | |
106 | - "type": "string", | |
107 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
108 | 116 | |
109 | 117 | {"name": "status", |
110 | 118 | "in": "formData", |
111 | 119 | "type": "string", |
112 | - "description": "[WMS]status"}, | |
120 | + "description": "[地图服务]status"}, | |
113 | 121 | {"name": "username", |
114 | 122 | "in": "formData", |
115 | 123 | "type": "string", |
116 | - "description": "[WMS]username"}, | |
124 | + "description": "[地图服务]username"}, | |
117 | 125 | {"name": "readonly", |
118 | 126 | "in": "formData", |
119 | 127 | "type": "string", |
120 | - "description": "[WMS]readonly"}, | |
128 | + "description": "[地图服务]readonly"}, | |
121 | 129 | {"name": "sid", |
122 | 130 | "in": "formData", |
123 | 131 | "type": "string", |
124 | - "description": "[WMS]sid"}, | |
132 | + "description": "[地图服务]sid"}, | |
125 | 133 | {"name": "stype", |
126 | 134 | "in": "formData", |
127 | 135 | "type": "string", |
128 | - "description": "[WMS]stype"}, | |
136 | + "description": "[地图服务]stype"}, | |
129 | 137 | {"name": "ssupply", |
130 | 138 | "in": "formData", |
131 | 139 | "type": "string", |
132 | - "description": "[WMS]ssupply"}, | |
140 | + "description": "[地图服务]ssupply"}, | |
133 | 141 | {"name": "sctime", |
134 | 142 | "in": "formData", |
135 | 143 | "type": "string", |
136 | - "description": "[WMS]sctime"}, | |
144 | + "description": "[地图服务]sctime"}, | |
137 | 145 | {"name": "company", |
138 | 146 | "in": "formData", |
139 | 147 | "type": "string", |
140 | - "description": "[WMS]company"}, | |
148 | + "description": "[地图服务]company"}, | |
141 | 149 | {"name": "abstract", |
142 | 150 | "in": "formData", |
143 | 151 | "type": "string", |
144 | - "description": "[WMS]abstract"}, | |
152 | + "description": "[地图服务]abstract"}, | |
145 | 153 | {"name": "thumbnail", |
146 | 154 | "in": "formData", |
147 | 155 | "type": "string", |
148 | - "description": "[WMS]thumbnail"}, | |
156 | + "description": "[地图服务]thumbnail"}, | |
149 | 157 | {"name": "layer_style", |
150 | 158 | "in": "formData", |
151 | 159 | "type": "string", |
152 | - "description": "[WMS,WMTS]layer_style"}, | |
160 | + "description": "[地图服务,切片服务]layer_style"}, | |
153 | 161 | |
154 | 162 | ], |
155 | 163 | "responses": { | ... | ... |
app/modules/service/models/__init__.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +#author: 4N | |
3 | +#createtime: 2021/10/26 | |
4 | +#email: nheweijun@sina.com | |
5 | + | |
6 | +from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Time,Float,Binary | |
7 | +from sqlalchemy.orm import relationship | |
8 | +from app.models import db | |
9 | + | |
10 | + | |
11 | +class Service(db.Model): | |
12 | + ''' | |
13 | + ''' | |
14 | + __tablename__ = 'dmap_service' | |
15 | + guid = Column(String(256), primary_key=True) | |
16 | + name = Column(String(256),unique = True) | |
17 | + title = Column(String(256)) | |
18 | + #服务状态 | |
19 | + state= Column(Integer) | |
20 | + create_time = Column(DateTime) | |
21 | + update_time = Column(DateTime) | |
22 | + #服务描述 | |
23 | + description = Column(Text) | |
24 | + #服务节点 | |
25 | + node = Column(Integer) | |
26 | + #服务缩略图 | |
27 | + overview = Column(Text) | |
28 | + #服务类型 | |
29 | + type = Column(String(256)) #地图服务,影像服务,切片服务 | |
30 | + # 目录外键 | |
31 | + catalog_guid = Column(String(256), ForeignKey('dmap_service_catalog.guid')) | |
32 | + | |
33 | + relate_service_functions = relationship('ServiceFunction', backref='relate_service', lazy='dynamic') | |
34 | + relate_tile_service = relationship('TileService', backref='relate_service', lazy='dynamic') | |
35 | + relate_image_service = relationship('ImageService', backref='relate_service', lazy='dynamic') | |
36 | + relate_map_service = relationship('MapService', backref='relate_service', lazy='dynamic') | |
37 | + | |
38 | +class ServiceFunction(db.Model): | |
39 | + ''' | |
40 | + 细分功能 | |
41 | + ''' | |
42 | + __tablename__ = 'dmap_service_function' | |
43 | + guid = Column(String(256), primary_key=True) | |
44 | + type = Column(String(256)) # 功能类别,WMTS,WMS,WFS,等等等 | |
45 | + url = Column(String(1024)) | |
46 | + service_guid = Column(String(256), ForeignKey('dmap_service.guid')) | |
47 | + | |
48 | +class ServiceCatalog(db.Model): | |
49 | + ''' | |
50 | + 目录表 | |
51 | + ''' | |
52 | + __tablename__ = 'dmap_service_catalog' | |
53 | + guid = Column(String(256), primary_key=True) | |
54 | + pguid = Column(String(256)) | |
55 | + path = Column(Text) | |
56 | + name = Column(String(256)) | |
57 | + sort = Column(Integer) | |
58 | + description = Column(Text) | |
59 | + relate_services = relationship('Service', backref='relate_catalog', lazy='dynamic') | |
60 | + | |
61 | + | |
62 | + | |
63 | +class TileScheme(db.Model): | |
64 | + ''' | |
65 | + 切片方案表 | |
66 | + ''' | |
67 | + __tablename__ = 'dmap_tile_scheme' | |
68 | + guid = Column(String(256), primary_key=True) | |
69 | + name = Column(String(256)) | |
70 | + alias = Column(String(256)) | |
71 | + description = Column(Text) | |
72 | + crs = Column(String(256)) | |
73 | + crs_wkt = Column(Text) | |
74 | + | |
75 | + extent = Column(Text) | |
76 | + top_left = Column(String(256)) | |
77 | + | |
78 | + levels = Column(Text) | |
79 | + dpi = Column(Integer) | |
80 | + rows = Column(Integer) | |
81 | + cols = Column(Integer) | |
82 | + update_time = Column(DateTime) | |
83 | + | |
84 | + parameter = Column(Text) | |
85 | + | |
86 | + | |
87 | +class Image(db.Model): | |
88 | + ''' | |
89 | + 影像元数据 | |
90 | + ''' | |
91 | + __tablename__ = 'dmap_image' | |
92 | + guid = Column(String(256), primary_key=True) | |
93 | + name = Column(String) | |
94 | + alias = Column(String) | |
95 | + raster_y_size = Column(Integer)#图像y 分辨率 | |
96 | + raster_x_size = Column(Integer)#图像x 分辨率 | |
97 | + overview_count = Column(Integer)#金字塔等级 | |
98 | + extent = Column(String)#范围 | |
99 | + # geo_origin_extent = Column(String) | |
100 | + null_value = Column(Integer)#空值 | |
101 | + available = Column(Integer)#影像是否可用,不可用可能在创建金字塔中 | |
102 | + band_count = Column(Integer)#波段数 | |
103 | + band_view = Column(String)#波段设置 | |
104 | + path = Column(String) | |
105 | + server = Column(String) | |
106 | + | |
107 | + size = Column(Float) | |
108 | + #坐标wkt | |
109 | + crs_wkt = Column(Text) #坐标wkt | |
110 | + crs_proj4 = Column(Text)#坐标proj | |
111 | + crs = Column(String)#坐标 | |
112 | + create_time = Column(DateTime) | |
113 | + update_time = Column(DateTime) | |
114 | + cell_x_size = Column(Float)#像元x大小 | |
115 | + cell_y_size = Column(Float)#像元y大小 | |
116 | + region = Column(Text) | |
117 | + | |
118 | + collect_time = Column(DateTime) #成像时间年份 | |
119 | + | |
120 | + satellite = Column(String)#卫星类型 | |
121 | + type = Column(String(128)) | |
122 | + | |
123 | + | |
124 | +dmap_image_rel = db.Table('dmap_image_rel', | |
125 | + Column('image_guid',String, ForeignKey('dmap_image.guid')), | |
126 | + Column('service_guid', String, ForeignKey('dmap_image_service.guid')) | |
127 | + ) | |
128 | + | |
129 | + | |
130 | + | |
131 | +class ImageService(db.Model): | |
132 | + ''' | |
133 | + 影像服务 | |
134 | + ''' | |
135 | + __tablename__ = 'dmap_image_service' | |
136 | + guid = Column(String(256), primary_key=True) | |
137 | + name = Column(String,unique = True) | |
138 | + scheme_guid = Column(String) | |
139 | + extent = Column(String(256)) | |
140 | + # node = Column(Integer) | |
141 | + #可视范围geojson | |
142 | + visual_region = Column(Text) | |
143 | + crs = Column(String(256)) | |
144 | + create_time = Column(DateTime) | |
145 | + service_guid = Column(String, ForeignKey('dmap_service.guid')) | |
146 | + | |
147 | + images = db.relationship('Image', | |
148 | + secondary=dmap_image_rel, | |
149 | + backref='image_services', | |
150 | + lazy='dynamic' | |
151 | + ) | |
152 | + | |
153 | + | |
154 | +dmap_image_tag_rel = db.Table('dmap_image_tag_rel', | |
155 | + Column('image_guid',String, ForeignKey('dmap_image.guid')), | |
156 | + Column('tag_guid', String, ForeignKey('dmap_image_tag.guid')) | |
157 | + ) | |
158 | + | |
159 | +class ImageTag(db.Model): | |
160 | + ''' | |
161 | + 影像标签 | |
162 | + ''' | |
163 | + __tablename__ = 'dmap_image_tag' | |
164 | + guid = Column(String(256), primary_key=True) | |
165 | + name=Column(String(256)) | |
166 | + alias = Column(String(256)) | |
167 | + images = db.relationship('Image', | |
168 | + secondary=dmap_image_tag_rel, | |
169 | + backref='image_tags', | |
170 | + lazy='dynamic' | |
171 | + ) | |
172 | + | |
173 | + | |
174 | +class TileService(db.Model): | |
175 | + ''' | |
176 | + 切片元数据 | |
177 | + ''' | |
178 | + __tablename__ = 'dmap_tile_service' | |
179 | + | |
180 | + guid = Column(String(256), primary_key=True) | |
181 | + | |
182 | + #基本信息 | |
183 | + name = Column(String,unique = True) | |
184 | + | |
185 | + #厂家 | |
186 | + vendor = Column(String(256)) | |
187 | + create_time = Column(DateTime) | |
188 | + #坐标系 | |
189 | + crs = Column(String(256)) | |
190 | + #切片路径 | |
191 | + datasource = Column(String) | |
192 | + #调用地址 | |
193 | + metadata_url = Column(String) | |
194 | + #描述 | |
195 | + description = Column(String) | |
196 | + | |
197 | + #图层信息 | |
198 | + #图层名 | |
199 | + layer_name = Column(String(256)) | |
200 | + #图层别名 | |
201 | + layer_alias = Column(String(256)) | |
202 | + #图层title | |
203 | + layer_title = Column(String(256)) | |
204 | + #图层样式 | |
205 | + layer_style = Column(String(256)) | |
206 | + #图片格式 | |
207 | + layer_format = Column(String(256)) | |
208 | + #图层范围 | |
209 | + layer_extent = Column(String) | |
210 | + #图层描述 | |
211 | + layer_description = Column(String) | |
212 | + | |
213 | + scheme_guid = Column(String,ForeignKey('dmap_tile_scheme.guid')) | |
214 | + service_guid = Column(String,ForeignKey('dmap_service.guid')) | |
215 | + | |
216 | + | |
217 | +class MapService(db.Model): | |
218 | + ''' | |
219 | + MapService元数据 | |
220 | + ''' | |
221 | + __tablename__ = 'dmdms_map_service' | |
222 | + | |
223 | + guid = Column(String(256), primary_key=True) | |
224 | + name = Column(String, unique=True) | |
225 | + | |
226 | + #基本信息 | |
227 | + status = Column(String) | |
228 | + description = Column(String) | |
229 | + #厂家 | |
230 | + username = Column(String(256)) | |
231 | + | |
232 | + readonly = Column(String) | |
233 | + updatetime = Column(DateTime) | |
234 | + sid = Column(Integer) | |
235 | + stype = Column(String) | |
236 | + ssupply = Column(String) | |
237 | + sctime = Column(String) | |
238 | + company = Column(String) | |
239 | + abstract = Column(String) | |
240 | + title = Column(String) | |
241 | + thumbnail = Column(String) | |
242 | + layer_style = Column(Text) | |
243 | + service_guid = Column(String,ForeignKey('dmap_service.guid')) | ... | ... |
... | ... | @@ -5,11 +5,11 @@ |
5 | 5 | |
6 | 6 | |
7 | 7 | import uuid |
8 | -from app.models import TileScheme,db | |
8 | +from ..models import TileScheme,db | |
9 | 9 | from app.util.component.ApiTemplate import ApiTemplate |
10 | 10 | from app.util.component.ModelVisitor import ModelVisitor |
11 | 11 | from sqlalchemy import or_ |
12 | -import datetime | |
12 | + | |
13 | 13 | |
14 | 14 | class Api(ApiTemplate): |
15 | 15 | api_name = "查询切片方案" | ... | ... |
... | ... | @@ -10,7 +10,7 @@ from app.util.component.FileProcess import FileProcess |
10 | 10 | from app.util.component.SliceScheme import SliceScheme |
11 | 11 | import shutil |
12 | 12 | from app.util.component.StructuredPrint import StructurePrint |
13 | -import json | |
13 | + | |
14 | 14 | class Api(ApiTemplate): |
15 | 15 | api_name = "解析方案" |
16 | 16 | ... | ... |
... | ... | @@ -4,12 +4,14 @@ |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | from app.util.component.ApiTemplate import ApiTemplate |
6 | 6 | |
7 | -from app.util import find_class,BlueprintApi | |
8 | -from app.models import Service,db | |
9 | - | |
10 | - | |
7 | +from app.models import db | |
8 | +from app.modules.service.models import Service | |
9 | +from app.modules.service.models import ImageService | |
10 | +from app.modules.service.models import TileService | |
11 | +from app.modules.service.models import MapService | |
11 | 12 | class Api(ApiTemplate): |
12 | - api_name = "服务类型" | |
13 | + | |
14 | + api_name = "服务删除" | |
13 | 15 | |
14 | 16 | def process(self): |
15 | 17 | |
... | ... | @@ -18,19 +20,21 @@ class Api(ApiTemplate): |
18 | 20 | |
19 | 21 | try: |
20 | 22 | guid = self.para.get("guid") |
23 | + | |
21 | 24 | service = Service.query.filter_by(guid=guid).one_or_none() |
22 | - if service.type in ["ImageWMTS","ImageWMS"]: | |
23 | - from app.modules.service.image.models import ImageService | |
24 | - image_service = ImageService.query.filter_by(guid=service.service_guid).one_or_none() | |
25 | + if service.type.__eq__("影像服务"): | |
26 | + image_service = ImageService.query.filter_by(service_guid=guid).one_or_none() | |
25 | 27 | db.session.delete(image_service) |
26 | - if service.type in ["WMTS","TMS"]: | |
27 | - from app.modules.service.wmts.models import WMTS | |
28 | - wmts = WMTS.query.filter_by(guid=service.service_guid).one_or_none() | |
29 | - db.session.delete(wmts) | |
30 | - if service.type in ["WMTS", "TMS"]: | |
31 | - from app.modules.service.wms.models import WMS | |
32 | - wms = WMS.query.filter_by(guid=service.service_guid).one_or_none() | |
33 | - db.session.delete(wms) | |
28 | + if service.type.__eq__("切片服务"): | |
29 | + tile_service = TileService.query.filter_by(service_guid=guid).one_or_none() | |
30 | + db.session.delete(tile_service) | |
31 | + if service.type.__eq__("地图服务"): | |
32 | + map_service = MapService.query.filter_by(service_guid=guid).one_or_none() | |
33 | + db.session.delete(map_service) | |
34 | + | |
35 | + service_functions = service.relate_service_functions.all() | |
36 | + for function in service_functions: | |
37 | + db.session.delete(function) | |
34 | 38 | db.session.delete(service) |
35 | 39 | db.session.commit() |
36 | 40 | res["result"] = True | ... | ... |
... | ... | @@ -7,7 +7,11 @@ |
7 | 7 | |
8 | 8 | |
9 | 9 | from app.util.component.ApiTemplate import ApiTemplate |
10 | -from app.models import Service | |
10 | +from app.models import db | |
11 | +from app.modules.service.models import Service | |
12 | +from app.modules.service.models import ImageService | |
13 | +from app.modules.service.models import TileService | |
14 | +from app.modules.service.models import MapService | |
11 | 15 | |
12 | 16 | class Api(ApiTemplate): |
13 | 17 | api_name = "修改服务" |
... | ... | @@ -18,12 +22,12 @@ class Api(ApiTemplate): |
18 | 22 | if not service: |
19 | 23 | raise Exception("服务不存在!") |
20 | 24 | |
21 | - if service.type in ["ImageWMTS","ImageWMS"]: | |
25 | + if service.type.__eq__("影像服务"): | |
22 | 26 | from app.modules.service.image.image_service_edit import Api as RealApi |
23 | - elif service.type in ["WMS/WFS"]: | |
24 | - from app.modules.service.wms.wms_edit import Api as RealApi | |
25 | - elif service.type in ["WMTS","TMS"]: | |
26 | - from app.modules.service.wmts.wmts_edit import Api as RealApi | |
27 | + elif service.type.__eq__("地图服务"): | |
28 | + from app.modules.service.map_service.map_service_edit import Api as RealApi | |
29 | + elif service.type.__eq__("切片服务"): | |
30 | + from app.modules.service.tile_service.tile_service_edit import Api as RealApi | |
27 | 31 | else: |
28 | 32 | return res |
29 | 33 | api = RealApi() | ... | ... |
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | from app.util.component.ModelVisitor import ModelVisitor |
9 | -from app.models import Service | |
9 | +from .models import Service | |
10 | 10 | |
11 | 11 | class Api(ApiTemplate): |
12 | 12 | api_name = "服务Info" |
... | ... | @@ -19,8 +19,8 @@ class Api(ApiTemplate): |
19 | 19 | raise Exception("服务不存在!") |
20 | 20 | res["data"] = {} |
21 | 21 | |
22 | - if service.type in ["ImageWMS","ImageWMTS"]: | |
23 | - from app.modules.service.image.models import ImageService | |
22 | + if service.type.__eq__("影像服务"): | |
23 | + from app.modules.service.models import ImageService | |
24 | 24 | speci_service = ImageService.query.filter_by(guid=service.service_guid).one_or_none() |
25 | 25 | relate_images = speci_service.images.all() |
26 | 26 | res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service) |
... | ... | @@ -28,15 +28,15 @@ class Api(ApiTemplate): |
28 | 28 | res["data"]["speci_service"]["images"] = [{"name":im["name"],"guid":im["guid"]} for im in ModelVisitor.objects_to_jsonarray(relate_images)] |
29 | 29 | res["data"]["speci_service"]["images"] = sorted(res["data"]["speci_service"]["images"], key=lambda x: x["name"]) |
30 | 30 | |
31 | - elif service.type.__eq__("WMTS") or service.type.__eq__("TMS"): | |
32 | - from app.modules.service.wmts.models import WMTS | |
33 | - speci_service = WMTS.query.filter_by(guid=service.service_guid).one_or_none() | |
31 | + elif service.type.__eq__("切片服务"): | |
32 | + from app.modules.service.models import MapService | |
33 | + speci_service = MapService.query.filter_by(guid=service.service_guid).one_or_none() | |
34 | 34 | |
35 | 35 | res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service) |
36 | 36 | |
37 | - elif service.type.__eq__("WMS/WFS"): | |
38 | - from app.modules.service.wms.models import WMS | |
39 | - speci_service = WMS.query.filter_by(guid=service.service_guid).one_or_none() | |
37 | + elif service.type.__eq__("地图服务"): | |
38 | + from app.modules.service.models import TileService | |
39 | + speci_service = TileService.query.filter_by(guid=service.service_guid).one_or_none() | |
40 | 40 | res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service) |
41 | 41 | else: |
42 | 42 | res["data"] = {} | ... | ... |
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | from app.util.component.ModelVisitor import ModelVisitor |
9 | -from app.models import Service | |
9 | +from .models import Service | |
10 | 10 | from sqlalchemy import or_ |
11 | 11 | |
12 | 12 | |
... | ... | @@ -25,6 +25,7 @@ class Api(ApiTemplate): |
25 | 25 | title = self.para.get("title") |
26 | 26 | name = self.para.get("name") |
27 | 27 | type = self.para.get("type") |
28 | + function_type = self.para.get("function_type") | |
28 | 29 | |
29 | 30 | catalog_guid = self.para.get("catalog_guid") |
30 | 31 | |
... | ... | @@ -78,7 +79,7 @@ class Api(ApiTemplate): |
78 | 79 | "in": "formData", |
79 | 80 | "type": "string", |
80 | 81 | "description": "服务类型", |
81 | - "enum":["WMTS","TMS","WMS/WFS","ImageWMTS","ImageWMS"]}, | |
82 | + "enum":["影像服务","切片服务","地图服务"]}, | |
82 | 83 | {"name": "catalog_guid", |
83 | 84 | "in": "formData", |
84 | 85 | "type": "string", | ... | ... |
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | 6 | from app.util.component.ApiTemplate import ApiTemplate |
7 | -from app.models import Service | |
7 | +from .models import Service | |
8 | 8 | class Api(ApiTemplate): |
9 | 9 | api_name = "注册服务" |
10 | 10 | def process(self): |
... | ... | @@ -14,12 +14,12 @@ class Api(ApiTemplate): |
14 | 14 | service = Service.query.filter_by(name=self.para.get("name")).one_or_none() |
15 | 15 | if service: |
16 | 16 | raise Exception("服务已存在!") |
17 | - if self.para.get("type").__eq__("ImageWMS") or self.para.get("type").__eq__("ImageWMTS"): | |
17 | + if self.para.get("type").__eq__("影像服务"): | |
18 | 18 | from app.modules.service.image.image_service_register import Api as RealApi |
19 | - elif self.para.get("type").__eq__("WMS"): | |
20 | - from app.modules.service.wms.wms_register import Api as RealApi | |
21 | - elif self.para.get("type").__eq__("WMTS") or self.para.get("type").__eq__("TMS"): | |
22 | - from app.modules.service.wmts.wmts_register import Api as RealApi | |
19 | + elif self.para.get("type").__eq__("地图服务"): | |
20 | + from app.modules.service.map_service.map_service_register import Api as RealApi | |
21 | + elif self.para.get("type").__eq__("切片服务"): | |
22 | + from app.modules.service.tile_service.tile_service_register import Api as RealApi | |
23 | 23 | else: |
24 | 24 | return res |
25 | 25 | api = RealApi() |
... | ... | @@ -39,127 +39,133 @@ class Api(ApiTemplate): |
39 | 39 | "in": "formData", |
40 | 40 | "type": "string", |
41 | 41 | "required": "true", |
42 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
42 | + "description": "[地图服务,切片服务,影像服务]"}, | |
43 | 43 | {"name": "title", |
44 | 44 | "in": "formData", |
45 | 45 | "type": "string", |
46 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
46 | + "description": "[地图服务,切片服务,影像服务]"}, | |
47 | 47 | {"name": "description", |
48 | 48 | "in": "formData", |
49 | 49 | "type": "string", |
50 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
50 | + "description": "[地图服务,切片服务,影像服务]"}, | |
51 | 51 | {"name": "type", |
52 | 52 | "in": "formData", |
53 | 53 | "type": "string", |
54 | - "enum":["WMS/WFS","WMTS","TMS","ImageWMS","ImageWMTS"], | |
54 | + "enum":["地图服务","切片服务","影像服务"], | |
55 | 55 | "required": "true", |
56 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
56 | + "description": "[地图服务,切片服务,影像服务]"}, | |
57 | 57 | {"name": "catalog_guid", |
58 | 58 | "in": "formData", |
59 | 59 | "type": "string", |
60 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
60 | + "description": "[地图服务,切片服务,影像服务]"}, | |
61 | 61 | |
62 | 62 | #影像参数 |
63 | 63 | {"name": "guids", |
64 | 64 | "in": "formData", |
65 | 65 | "type": "string", |
66 | - "description": "[影像WMS,影像WMTS]影像guids,以英文逗号相隔"}, | |
66 | + "description": "[影像服务]影像guids,以英文逗号相隔"}, | |
67 | 67 | {"name": "scheme_guid", |
68 | 68 | "in": "formData", |
69 | 69 | "type": "string", |
70 | - "description": "[WMTS,影像WMTS]切片方案"}, | |
70 | + "description": "[切片服务,影像服务]切片方案"}, | |
71 | + {"name": "function_types", | |
72 | + "in": "formData", | |
73 | + "type": "string", | |
74 | + "description": "[影像服务]function_types", | |
75 | + "enum": ["WMS","WMTS"]}, | |
71 | 76 | |
72 | - # WMTS参数 | |
77 | + # 切片参数 | |
73 | 78 | {"name": "overview", |
74 | 79 | "in": "formData", |
75 | 80 | "type": "string", |
76 | - "description": "[WMTS]缩略图"}, | |
77 | - {"name": "wmts_type", | |
81 | + "description": "[切片服务]缩略图"}, | |
82 | + {"name": "tile_type", | |
78 | 83 | "in": "formData", |
79 | 84 | "type": "string", |
80 | - "description": "[WMTS]wmts_type"}, | |
85 | + "description": "[切片服务]tile_type", | |
86 | + "enum":["WMTS","TMS"]}, | |
81 | 87 | {"name": "vendor", |
82 | 88 | "in": "formData", |
83 | 89 | "type": "string", |
84 | - "description": "[WMTS]厂商"}, | |
90 | + "description": "[切片服务]厂商"}, | |
85 | 91 | {"name": "crs", |
86 | 92 | "in": "formData", |
87 | 93 | "type": "string", |
88 | - "description": "[WMTS]坐标系"}, | |
94 | + "description": "[切片服务]坐标系"}, | |
89 | 95 | {"name": "datasource", |
90 | 96 | "in": "formData", |
91 | 97 | "type": "string", |
92 | - "description": "[WMTS]数据路径"}, | |
98 | + "description": "[切片服务]数据路径"}, | |
93 | 99 | {"name": "layer_name", |
94 | 100 | "in": "formData", |
95 | 101 | "type": "string", |
96 | - "description": "[WMTS]图层名"}, | |
102 | + "description": "[切片服务]图层名"}, | |
97 | 103 | {"name": "layer_alias", |
98 | 104 | "in": "formData", |
99 | 105 | "type": "string", |
100 | - "description": "[WMTS]图层别名"}, | |
106 | + "description": "[切片服务]图层别名"}, | |
101 | 107 | {"name": "layer_title", |
102 | 108 | "in": "formData", |
103 | 109 | "type": "string", |
104 | - "description": "[WMTS]图层标题"}, | |
110 | + "description": "[切片服务]图层标题"}, | |
105 | 111 | {"name": "layer_style", |
106 | 112 | "in": "formData", |
107 | 113 | "type": "string", |
108 | - "description": "[WMTS,WMS]图层样式"}, | |
114 | + "description": "[切片服务,地图服务]图层样式"}, | |
109 | 115 | {"name": "layer_format", |
110 | 116 | "in": "formData", |
111 | 117 | "type": "string", |
112 | - "description": "[WMTS]图层format"}, | |
118 | + "description": "[切片服务]图层format"}, | |
113 | 119 | {"name": "layer_extent", |
114 | 120 | "in": "formData", |
115 | 121 | "type": "string", |
116 | - "description": "[WMTS]图层范围"}, | |
122 | + "description": "[切片服务]图层范围"}, | |
117 | 123 | {"name": "layer_description", |
118 | 124 | "in": "formData", |
119 | 125 | "type": "string", |
120 | - "description": "[WMTS]图层描述"}, | |
126 | + "description": "[切片服务]图层描述"}, | |
121 | 127 | |
122 | - #WMS参数 | |
128 | + #地图服务参数 | |
123 | 129 | {"name": "status", |
124 | 130 | "in": "formData", |
125 | 131 | "type": "string", |
126 | - "description": "[WMS]status"}, | |
132 | + "description": "[地图服务]status"}, | |
127 | 133 | {"name": "username", |
128 | 134 | "in": "formData", |
129 | 135 | "type": "string", |
130 | - "description": "[WMS]username"}, | |
136 | + "description": "[地图服务]username"}, | |
131 | 137 | {"name": "readonly", |
132 | 138 | "in": "formData", |
133 | 139 | "type": "string", |
134 | - "description": "[WMS]readonly"}, | |
140 | + "description": "[地图服务]readonly"}, | |
135 | 141 | {"name": "sid", |
136 | 142 | "in": "formData", |
137 | 143 | "type": "string", |
138 | - "description": "[WMS]sid"}, | |
144 | + "description": "[地图服务]sid"}, | |
139 | 145 | {"name": "stype", |
140 | 146 | "in": "formData", |
141 | 147 | "type": "string", |
142 | - "description": "[WMS]stype"}, | |
148 | + "description": "[地图服务]stype"}, | |
143 | 149 | {"name": "ssupply", |
144 | 150 | "in": "formData", |
145 | 151 | "type": "string", |
146 | - "description": "[WMS]ssupply"}, | |
152 | + "description": "[地图服务]ssupply"}, | |
147 | 153 | {"name": "sctime", |
148 | 154 | "in": "formData", |
149 | 155 | "type": "string", |
150 | - "description": "[WMS]sctime"}, | |
156 | + "description": "[地图服务]sctime"}, | |
151 | 157 | {"name": "company", |
152 | 158 | "in": "formData", |
153 | 159 | "type": "string", |
154 | - "description": "[WMS]company"}, | |
160 | + "description": "[地图服务]company"}, | |
155 | 161 | {"name": "abstract", |
156 | 162 | "in": "formData", |
157 | 163 | "type": "string", |
158 | - "description": "[WMS]abstract"}, | |
164 | + "description": "[地图服务]abstract"}, | |
159 | 165 | {"name": "thumbnail", |
160 | 166 | "in": "formData", |
161 | 167 | "type": "string", |
162 | - "description": "[WMS]thumbnail"}, | |
168 | + "description": "[地图服务]thumbnail"}, | |
163 | 169 | |
164 | 170 | ], |
165 | 171 | "responses": { | ... | ... |
... | ... | @@ -7,7 +7,7 @@ |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | from app.util.component.ModelVisitor import ModelVisitor |
9 | 9 | from app.util.component.FileProcess import FileProcess |
10 | -from app.models import Service | |
10 | +from .models import Service | |
11 | 11 | import os |
12 | 12 | |
13 | 13 | class Api(ApiTemplate): | ... | ... |
... | ... | @@ -6,46 +6,17 @@ |
6 | 6 | |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | from app.util.component.ModelVisitor import ModelVisitor |
9 | -from app.models import Service | |
9 | +from .models import Service | |
10 | 10 | |
11 | 11 | class Api(ApiTemplate): |
12 | 12 | ''' |
13 | 13 | 保存服务到dmd文件 |
14 | 14 | ''' |
15 | - api_name = "服务Save" | |
15 | + api_name = "服务save" | |
16 | 16 | def process(self): |
17 | 17 | res = {} |
18 | 18 | try: |
19 | - guid = self.para.get("guid") | |
20 | - service = Service.query.filter_by(guid=guid).one_or_none() | |
21 | - if not service: | |
22 | - raise Exception("服务不存在!") | |
23 | - res["data"] = {} | |
24 | - | |
25 | - if service.type in ["ImageWMS","ImageWMTS"]: | |
26 | - from app.modules.service.image.models import ImageService | |
27 | - speci_service = ImageService.query.filter_by(guid=service.service_guid).one_or_none() | |
28 | - relate_images = speci_service.images.all() | |
29 | - res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service) | |
30 | - | |
31 | - res["data"]["speci_service"]["images"] = [{"name":im["name"],"guid":im["guid"]} for im in ModelVisitor.objects_to_jsonarray(relate_images)] | |
32 | - res["data"]["speci_service"]["images"] = sorted(res["data"]["speci_service"]["images"], key=lambda x: x["name"]) | |
33 | - | |
34 | - elif service.type.__eq__("WMTS") or service.type.__eq__("TMS"): | |
35 | - from app.modules.service.wmts.models import WMTS | |
36 | - speci_service = WMTS.query.filter_by(guid=service.service_guid).one_or_none() | |
37 | - | |
38 | - res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service) | |
39 | - | |
40 | - elif service.type.__eq__("WMS/WFS"): | |
41 | - from app.modules.service.wms.models import WMS | |
42 | - speci_service = WMS.query.filter_by(guid=service.service_guid).one_or_none() | |
43 | - res["data"]["speci_service"] = ModelVisitor.object_to_json(speci_service) | |
44 | - else: | |
45 | - res["data"] = {} | |
46 | - | |
47 | - res["data"]["service"] = ModelVisitor.object_to_json(service) | |
48 | - | |
19 | + pass | |
49 | 20 | except Exception as e: |
50 | 21 | raise e |
51 | 22 | return res | ... | ... |
... | ... | @@ -7,15 +7,15 @@ |
7 | 7 | from flasgger import swag_from |
8 | 8 | from flask import Blueprint |
9 | 9 | from app.util import BlueprintApi |
10 | -from . import upload_oview,wmts_register,wmts_edit | |
10 | +from . import upload_oview,tile_service_register,tile_service_edit | |
11 | 11 | |
12 | 12 | |
13 | 13 | |
14 | 14 | class DataManager(BlueprintApi): |
15 | 15 | |
16 | - bp = Blueprint("WMTS", __name__, url_prefix="/API/Service/WMTS") | |
16 | + bp = Blueprint("TileService", __name__, url_prefix="/API/Service/TileService") | |
17 | 17 | |
18 | - service_type = ["WMTS","TMS"] | |
18 | + service_type = ["切片服务"] | |
19 | 19 | |
20 | 20 | @staticmethod |
21 | 21 | @bp.route('/UploadOverview', methods=['POST']) |
... | ... | @@ -29,19 +29,19 @@ class DataManager(BlueprintApi): |
29 | 29 | |
30 | 30 | @staticmethod |
31 | 31 | @bp.route('/Register', methods=['POST']) |
32 | - @swag_from(wmts_register.Api.api_doc) | |
32 | + @swag_from(tile_service_register.Api.api_doc) | |
33 | 33 | def api_wmts_register(): |
34 | 34 | """ |
35 | - 注册WMTS | |
35 | + 注册TileService | |
36 | 36 | """ |
37 | - return wmts_register.Api().result | |
37 | + return tile_service_register.Api().result | |
38 | 38 | |
39 | 39 | @staticmethod |
40 | 40 | @bp.route('/Edit', methods=['POST']) |
41 | - @swag_from(wmts_edit.Api.api_doc) | |
41 | + @swag_from(tile_service_edit.Api.api_doc) | |
42 | 42 | def api_wmts_edit(): |
43 | 43 | """ |
44 | - 修改WMTS | |
44 | + 修改TileService | |
45 | 45 | """ |
46 | - return wmts_edit.Api().result | |
46 | + return tile_service_edit.Api().result | |
47 | 47 | ... | ... |
... | ... | @@ -5,13 +5,13 @@ |
5 | 5 | |
6 | 6 | from app.util.component.ApiTemplate import ApiTemplate |
7 | 7 | import uuid |
8 | -from .models import WMTS | |
9 | -from app.models import Service,db | |
8 | +from ..models import TileService,Service,db | |
9 | + | |
10 | 10 | |
11 | 11 | import datetime |
12 | 12 | class Api(ApiTemplate): |
13 | 13 | |
14 | - api_name = "修改WMTS服务" | |
14 | + api_name = "修改切片服务" | |
15 | 15 | |
16 | 16 | def process(self): |
17 | 17 | |
... | ... | @@ -27,21 +27,20 @@ class Api(ApiTemplate): |
27 | 27 | |
28 | 28 | |
29 | 29 | service_update = {"update_time":this_time} |
30 | - wmts_update = {} | |
30 | + tile_update = {} | |
31 | 31 | for key in self.para.keys(): |
32 | 32 | if key in ["name","title","state","description","overview","catalog_guid"]: |
33 | 33 | service_update[key] = self.para.get(key) |
34 | - if key in ["name","wmts_type","vendor","crs","datasource","description", | |
34 | + if key in ["name","tile_type","vendor","crs","datasource","description", | |
35 | 35 | "layer_name","layer_alias","layer_title","layer_style","layer_format", |
36 | 36 | "layer_extent","layer_description","scheme_guid"]: |
37 | - wmts_update[key] = self.para.get(key) | |
38 | - | |
37 | + tile_update[key] = self.para.get(key) | |
39 | 38 | |
40 | - wmts = WMTS.query.filter_by(guid=Service.query.filter_by(guid=guid).one_or_none().service_guid) | |
39 | + tile_service = TileService.query.filter_by(service_guid=guid) | |
41 | 40 | if service_update: |
42 | 41 | service.update(service_update) |
43 | - if wmts_update: | |
44 | - wmts.update(wmts_update) | |
42 | + if tile_update: | |
43 | + tile_service.update(tile_update) | |
45 | 44 | |
46 | 45 | db.session.commit() |
47 | 46 | |
... | ... | @@ -52,82 +51,83 @@ class Api(ApiTemplate): |
52 | 51 | return res |
53 | 52 | |
54 | 53 | api_doc = { |
55 | - "tags": ["WMTS接口"], | |
54 | + "tags": ["切片服务接口"], | |
56 | 55 | "parameters": [ |
57 | 56 | |
58 | 57 | {"name": "name", |
59 | 58 | "in": "formData", |
60 | 59 | "type": "string", |
61 | 60 | "required": "true", |
62 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
61 | + "description": "[地图服务,切片服务,影像服务]"}, | |
63 | 62 | {"name": "title", |
64 | 63 | "in": "formData", |
65 | 64 | "type": "string", |
66 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
65 | + "description": "[地图服务,切片服务,影像服务]"}, | |
67 | 66 | {"name": "description", |
68 | 67 | "in": "formData", |
69 | 68 | "type": "string", |
70 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
69 | + "description": "[地图服务,切片服务,影像服务]"}, | |
71 | 70 | |
72 | 71 | {"name": "catalog_guid", |
73 | 72 | "in": "formData", |
74 | 73 | "type": "string", |
75 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
74 | + "description": "[地图服务,切片服务,影像服务]"}, | |
76 | 75 | |
77 | 76 | {"name": "scheme_guid", |
78 | 77 | "in": "formData", |
79 | 78 | "type": "string", |
80 | - "description": "[WMTS,影像WMTS]切片方案"}, | |
79 | + "description": "[切片服务,影像服务]切片方案"}, | |
81 | 80 | |
82 | - # WMTS参数 | |
81 | + # 切片服务参数 | |
83 | 82 | {"name": "overview", |
84 | 83 | "in": "formData", |
85 | 84 | "type": "string", |
86 | - "description": "[WMTS]缩略图"}, | |
87 | - {"name": "wmts_type", | |
85 | + "description": "[切片服务]缩略图"}, | |
86 | + {"name": "tile_type", | |
88 | 87 | "in": "formData", |
89 | 88 | "type": "string", |
90 | - "description": "[WMTS]wmts_type"}, | |
89 | + "description": "[切片服务]tile_type", | |
90 | + "enum":["WMTS","TMS"]}, | |
91 | 91 | {"name": "vendor", |
92 | 92 | "in": "formData", |
93 | 93 | "type": "string", |
94 | - "description": "[WMTS]厂商"}, | |
94 | + "description": "[切片服务]厂商"}, | |
95 | 95 | {"name": "crs", |
96 | 96 | "in": "formData", |
97 | 97 | "type": "string", |
98 | - "description": "[WMTS]坐标系"}, | |
98 | + "description": "[切片服务]坐标系"}, | |
99 | 99 | {"name": "datasource", |
100 | 100 | "in": "formData", |
101 | 101 | "type": "string", |
102 | - "description": "[WMTS]数据路径"}, | |
102 | + "description": "[切片服务]数据路径"}, | |
103 | 103 | {"name": "layer_name", |
104 | 104 | "in": "formData", |
105 | 105 | "type": "string", |
106 | - "description": "[WMTS]图层名"}, | |
106 | + "description": "[切片服务]图层名"}, | |
107 | 107 | {"name": "layer_alias", |
108 | 108 | "in": "formData", |
109 | 109 | "type": "string", |
110 | - "description": "[WMTS]图层别名"}, | |
110 | + "description": "[切片服务]图层别名"}, | |
111 | 111 | {"name": "layer_title", |
112 | 112 | "in": "formData", |
113 | 113 | "type": "string", |
114 | - "description": "[WMTS]图层标题"}, | |
114 | + "description": "[切片服务]图层标题"}, | |
115 | 115 | {"name": "layer_style", |
116 | 116 | "in": "formData", |
117 | 117 | "type": "string", |
118 | - "description": "[WMTS,WMS]图层样式"}, | |
118 | + "description": "[切片服务,地图服务]图层样式"}, | |
119 | 119 | {"name": "layer_format", |
120 | 120 | "in": "formData", |
121 | 121 | "type": "string", |
122 | - "description": "[WMTS]图层format"}, | |
122 | + "description": "[切片服务]图层format"}, | |
123 | 123 | {"name": "layer_extent", |
124 | 124 | "in": "formData", |
125 | 125 | "type": "string", |
126 | - "description": "[WMTS]图层范围"}, | |
126 | + "description": "[切片服务]图层范围"}, | |
127 | 127 | {"name": "layer_description", |
128 | 128 | "in": "formData", |
129 | 129 | "type": "string", |
130 | - "description": "[WMTS]图层描述"}, | |
130 | + "description": "[切片服务]图层描述"}, | |
131 | 131 | |
132 | 132 | |
133 | 133 | ], | ... | ... |
... | ... | @@ -6,8 +6,8 @@ |
6 | 6 | |
7 | 7 | from app.util.component.ApiTemplate import ApiTemplate |
8 | 8 | import uuid |
9 | -from .models import WMTS | |
10 | -from app.models import Service,db | |
9 | +from ..models import TileService,Service,db,ServiceFunction | |
10 | + | |
11 | 11 | import datetime |
12 | 12 | import configure |
13 | 13 | import requests |
... | ... | @@ -15,7 +15,7 @@ from requests import Response |
15 | 15 | import json |
16 | 16 | class Api(ApiTemplate): |
17 | 17 | |
18 | - api_name = "注册WMTS服务" | |
18 | + api_name = "注册切片服务" | |
19 | 19 | |
20 | 20 | def process(self): |
21 | 21 | # 返回结果 |
... | ... | @@ -25,7 +25,9 @@ class Api(ApiTemplate): |
25 | 25 | |
26 | 26 | this_time = datetime.datetime.now() |
27 | 27 | service_guid = uuid.uuid1().__str__() |
28 | - wmts_service_guid = uuid.uuid1().__str__() | |
28 | + tile_service_guid = uuid.uuid1().__str__() | |
29 | + service_function_guid = uuid.uuid1().__str__() | |
30 | + | |
29 | 31 | |
30 | 32 | service = Service( |
31 | 33 | guid = service_guid, |
... | ... | @@ -40,19 +42,18 @@ class Api(ApiTemplate): |
40 | 42 | configure.deploy_ip_host, |
41 | 43 | self.para.get("overview") if self.para.get("overview") else "wmts_tb.png"), |
42 | 44 | type = self.para.get("type"), |
43 | - service_guid = wmts_service_guid, | |
44 | 45 | catalog_guid = self.para.get("catalog_guid") |
45 | 46 | ) |
46 | 47 | |
47 | 48 | #已存在就删除 |
48 | - wmts_isexist = WMTS.query.filter_by(name=self.para.get("name")).one_or_none() | |
49 | - if wmts_isexist: | |
50 | - db.session.delete(wmts_isexist) | |
49 | + tile_service_isexist = TileService.query.filter_by(name=self.para.get("name")).one_or_none() | |
50 | + if tile_service_isexist: | |
51 | + db.session.delete(tile_service_isexist) | |
51 | 52 | |
52 | - wmts = WMTS( | |
53 | - guid = wmts_service_guid, | |
53 | + tile_service = TileService( | |
54 | + guid = tile_service_guid, | |
54 | 55 | name = self.para.get("name"), |
55 | - wmts_type = self.para.get("wmts_type"), | |
56 | + tile_type = self.para.get("tile_type"), | |
56 | 57 | vendor = self.para.get("vendor"), |
57 | 58 | create_time = this_time, |
58 | 59 | crs = self.para.get("crs"), |
... | ... | @@ -70,19 +71,25 @@ class Api(ApiTemplate): |
70 | 71 | metadata_url="{}/DMap/Services/{}/MapServer/WMTSServer".format(configure.wmts_url,self.para.get("name")) |
71 | 72 | ) |
72 | 73 | |
74 | + service_function = ServiceFunction(guid=service_function_guid, | |
75 | + service_guid=service_guid, | |
76 | + type=self.para.get("tile_type")) | |
77 | + | |
73 | 78 | db.session.add(service) |
74 | - db.session.add(wmts) | |
79 | + db.session.add(tile_service) | |
80 | + db.session.add(service_function) | |
75 | 81 | db.session.commit() |
76 | 82 | |
77 | - # 调用WMTS的注册服务接口 | |
83 | + # 调用切片服务的注册服务接口 | |
78 | 84 | try: |
79 | 85 | url = "{}/dmap/api/manager/updatecache?servicename={}".format(configure.wmts_url,service.name) |
80 | 86 | resp:Response = requests.get(url) |
81 | 87 | if not resp.json()["status"].__eq__("true"): |
82 | - raise Exception("调用WMTS的注册服务接口失败!") | |
88 | + raise Exception("调用切片服务的注册服务接口失败!") | |
83 | 89 | except Exception as e: |
84 | 90 | db.session.delete(service) |
85 | - db.session.delete(wmts) | |
91 | + db.session.delete(tile_service) | |
92 | + db.session.delete(service_function) | |
86 | 93 | db.session.commit() |
87 | 94 | raise e |
88 | 95 | res["data"] = service_guid |
... | ... | @@ -93,80 +100,82 @@ class Api(ApiTemplate): |
93 | 100 | return res |
94 | 101 | |
95 | 102 | api_doc = { |
96 | - "tags": ["WMTS接口"], | |
103 | + "tags": ["切片服务接口"], | |
97 | 104 | "parameters": [ |
98 | 105 | {"name": "name", |
99 | 106 | "in": "formData", |
100 | 107 | "type": "string", |
101 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
108 | + "description": "[地图服务,切片服务,影像服务]"}, | |
102 | 109 | {"name": "title", |
103 | 110 | "in": "formData", |
104 | 111 | "type": "string", |
105 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
112 | + "description": "[地图服务,切片服务,影像服务]"}, | |
106 | 113 | {"name": "description", |
107 | 114 | "in": "formData", |
108 | 115 | "type": "string", |
109 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
116 | + "description": "[地图服务,切片服务,影像服务]"}, | |
110 | 117 | {"name": "type", |
111 | 118 | "in": "formData", |
112 | 119 | "type": "string", |
113 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
120 | + "description": "[地图服务,切片服务,影像服务", | |
121 | + "enum":["地图服务","切片服务","影像服务"]}, | |
114 | 122 | {"name": "catalog_guid", |
115 | 123 | "in": "formData", |
116 | 124 | "type": "string", |
117 | - "description": "[WMS,WMTS,影像WMS,影像WMTS]"}, | |
125 | + "description": "[地图服务,切片服务,影像服务]"}, | |
118 | 126 | {"name": "scheme_guid", |
119 | 127 | "in": "formData", |
120 | 128 | "type": "string", |
121 | - "description": "[WMTS,影像WMTS]切片方案"}, | |
129 | + "description": "[切片服务,影像服务]切片方案"}, | |
122 | 130 | {"name": "overview", |
123 | 131 | "in": "formData", |
124 | 132 | "type": "string", |
125 | - "description": "[WMTS]缩略图"}, | |
126 | - {"name": "wmts_type", | |
133 | + "description": "[切片服务]缩略图"}, | |
134 | + {"name": "tile_type", | |
127 | 135 | "in": "formData", |
128 | 136 | "type": "string", |
129 | - "description": "[WMTS]wmts_type"}, | |
137 | + "description": "[切片服务]tile_type", | |
138 | + "enum":["WMTS","TMS"]}, | |
130 | 139 | {"name": "vendor", |
131 | 140 | "in": "formData", |
132 | 141 | "type": "string", |
133 | - "description": "[WMTS]厂商"}, | |
142 | + "description": "[切片服务]厂商"}, | |
134 | 143 | {"name": "crs", |
135 | 144 | "in": "formData", |
136 | 145 | "type": "string", |
137 | - "description": "[WMTS]坐标系"}, | |
146 | + "description": "[切片服务]坐标系"}, | |
138 | 147 | {"name": "datasource", |
139 | 148 | "in": "formData", |
140 | 149 | "type": "string", |
141 | - "description": "[WMTS]数据路径"}, | |
150 | + "description": "[切片服务]数据路径"}, | |
142 | 151 | {"name": "layer_name", |
143 | 152 | "in": "formData", |
144 | 153 | "type": "string", |
145 | - "description": "[WMTS]图层名"}, | |
154 | + "description": "[切片服务]图层名"}, | |
146 | 155 | {"name": "layer_alias", |
147 | 156 | "in": "formData", |
148 | 157 | "type": "string", |
149 | - "description": "[WMTS]图层别名"}, | |
158 | + "description": "[切片服务]图层别名"}, | |
150 | 159 | {"name": "layer_title", |
151 | 160 | "in": "formData", |
152 | 161 | "type": "string", |
153 | - "description": "[WMTS]图层标题"}, | |
162 | + "description": "[切片服务]图层标题"}, | |
154 | 163 | {"name": "layer_style", |
155 | 164 | "in": "formData", |
156 | 165 | "type": "string", |
157 | - "description": "[WMTS]图层样式"}, | |
166 | + "description": "[切片服务]图层样式"}, | |
158 | 167 | {"name": "layer_format", |
159 | 168 | "in": "formData", |
160 | 169 | "type": "string", |
161 | - "description": "[WMTS]图层format"}, | |
170 | + "description": "[切片服务]图层format"}, | |
162 | 171 | {"name": "layer_extent", |
163 | 172 | "in": "formData", |
164 | 173 | "type": "string", |
165 | - "description": "[WMTS]图层范围"}, | |
174 | + "description": "[切片服务]图层范围"}, | |
166 | 175 | {"name": "layer_description", |
167 | 176 | "in": "formData", |
168 | 177 | "type": "string", |
169 | - "description": "[WMTS]图层描述"}, | |
178 | + "description": "[切片服务]图层描述"}, | |
170 | 179 | ], |
171 | 180 | "responses": { |
172 | 181 | 200: { | ... | ... |
1 | -# coding=utf-8 | |
2 | -#author: 4N | |
3 | -#createtime: 2021/6/11 | |
4 | -#email: nheweijun@sina.com | |
5 | - | |
6 | - | |
7 | -from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Time,Binary,Float | |
8 | -from app.models import db | |
9 | - | |
10 | - | |
11 | - | |
12 | -class WMS(db.Model): | |
13 | - ''' | |
14 | - WMTS元数据 | |
15 | - ''' | |
16 | - __tablename__ = 'dmdms_wms' | |
17 | - | |
18 | - guid = Column(String(256), primary_key=True) | |
19 | - service = Column(String) | |
20 | - #基本信息 | |
21 | - status = Column(String) | |
22 | - description = Column(String) | |
23 | - #厂家 | |
24 | - username = Column(String(256)) | |
25 | - | |
26 | - readonly = Column(String) | |
27 | - updatetime = Column(DateTime) | |
28 | - sid = Column(Integer) | |
29 | - stype = Column(String) | |
30 | - ssupply = Column(String) | |
31 | - sctime = Column(String) | |
32 | - company = Column(String) | |
33 | - abstract = Column(String) | |
34 | - title = Column(String) | |
35 | - thumbnail = Column(String) | |
36 | - | |
37 | - layer_style = Column(Text) | |
38 | - | |
39 | - # service_guid = Column(String,ForeignKey('dmdms_service.guid')) | |
40 | - service_guid = Column(String) | |
\ No newline at end of file |
1 | -# coding=utf-8 | |
2 | -#author: 4N | |
3 | -#createtime: 2021/6/11 | |
4 | -#email: nheweijun@sina.com | |
5 | - | |
6 | - | |
7 | -from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Time,Binary,Float | |
8 | -from app.models import db | |
9 | - | |
10 | - | |
11 | - | |
12 | -class WMTS(db.Model): | |
13 | - ''' | |
14 | - WMTS元数据 | |
15 | - ''' | |
16 | - __tablename__ = 'dmap_wmts' | |
17 | - | |
18 | - guid = Column(String(256), primary_key=True) | |
19 | - | |
20 | - #基本信息 | |
21 | - name = Column(String) | |
22 | - wmts_type = Column(String(256)) | |
23 | - #厂家 | |
24 | - vendor = Column(String(256)) | |
25 | - create_time = Column(DateTime) | |
26 | - #坐标系 | |
27 | - crs = Column(String(256)) | |
28 | - #切片路径 | |
29 | - datasource = Column(String) | |
30 | - #调用地址 | |
31 | - metadata_url = Column(String) | |
32 | - #描述 | |
33 | - description = Column(String) | |
34 | - | |
35 | - #图层信息 | |
36 | - #图层名 | |
37 | - layer_name = Column(String(256)) | |
38 | - #图层别名 | |
39 | - layer_alias = Column(String(256)) | |
40 | - #图层title | |
41 | - layer_title = Column(String(256)) | |
42 | - #图层样式 | |
43 | - layer_style = Column(String(256)) | |
44 | - #图片格式 | |
45 | - layer_format = Column(String(256)) | |
46 | - #图层范围 | |
47 | - layer_extent = Column(String) | |
48 | - #图层描述 | |
49 | - layer_description = Column(String) | |
50 | - | |
51 | - # scheme_guid = Column(String,ForeignKey('dmap_tile_scheme.guid')) | |
52 | - # | |
53 | - # service_guid = Column(String,ForeignKey('dmap_service.guid')) | |
54 | - | |
55 | - scheme_guid = Column(String) | |
56 | - service_guid = Column(String) | |
\ No newline at end of file |
... | ... | @@ -4,14 +4,11 @@ |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | 6 | |
7 | -from flask import current_app | |
7 | + | |
8 | 8 | import os |
9 | 9 | |
10 | 10 | from app.util.component.ApiTemplate import ApiTemplate |
11 | -from app.util.component.ModelVisitor import ModelVisitor | |
12 | -from app.util.component.StructuredPrint import StructurePrint | |
13 | -from app.models import Service,db | |
14 | -from sqlalchemy.orm import load_only | |
11 | + | |
15 | 12 | from flask import current_app |
16 | 13 | class Api(ApiTemplate): |
17 | 14 | |
... | ... | @@ -26,9 +23,9 @@ class Api(ApiTemplate): |
26 | 23 | |
27 | 24 | result=dict() |
28 | 25 | result.update(self.para) |
29 | - services = Service.query.options(load_only('guid')).all() | |
26 | + | |
30 | 27 | result["root_path"] = os.path.dirname(current_app.instance_path) |
31 | - result["services"] = ModelVisitor.objects_to_jsonarray(services) | |
28 | + | |
32 | 29 | return result |
33 | 30 | |
34 | 31 | ... | ... |
... | ... | @@ -6,12 +6,13 @@ import os |
6 | 6 | import uuid |
7 | 7 | import shutil |
8 | 8 | import time |
9 | -from app.models import * | |
9 | +from app.modules.data.models import * | |
10 | 10 | from app.util.component.PGUtil import PGUtil |
11 | 11 | from app.util.component.StructuredPrint import StructurePrint |
12 | 12 | from sqlalchemy.orm import Session |
13 | 13 | import configure |
14 | 14 | import copy |
15 | +import datetime | |
15 | 16 | class EntryData: |
16 | 17 | |
17 | 18 | def entry(self,parameter): | ... | ... |
... | ... | @@ -6,7 +6,7 @@ import os |
6 | 6 | import uuid |
7 | 7 | import shutil |
8 | 8 | import time |
9 | -from app.models import * | |
9 | +from app.modules.data.models import * | |
10 | 10 | from app.util.component.PGUtil import PGUtil |
11 | 11 | from app.util.component.StructuredPrint import StructurePrint |
12 | 12 | from sqlalchemy.orm import Session |
... | ... | @@ -17,6 +17,7 @@ import traceback |
17 | 17 | import copy |
18 | 18 | from app.util.component.GeometryAdapter import GeometryAdapter |
19 | 19 | from app.util.component.VacuateConf import VacuateConf |
20 | +import datetime | |
20 | 21 | class EntryDataVacuate: |
21 | 22 | |
22 | 23 | def entry(self,parameter): | ... | ... |
... | ... | @@ -4,7 +4,7 @@ |
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" | |
7 | +SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.60.100:5432/dmap_manager" | |
8 | 8 | |
9 | 9 | # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中 |
10 | 10 | #VACUATE_DB_URI = None | ... | ... |
请
注册
或
登录
后发表评论