提交 9c2719526ef1069a2634995ce6365062fe8f6bff
1 个父辈
031121d5
ÐÞ¸´»ñȡͼ²ãÒªËØÊýÁ¿bugºÍ²»ÄÜʶ±ðͼ²ãÀàÐÍbug
正在显示
25 个修改的文件
包含
1028 行增加
和
153 行删除
... | ... | @@ -119,20 +119,22 @@ class Task(db.Model): |
119 | 119 | create_time = Column(DateTime) |
120 | 120 | update_time = Column(DateTime) |
121 | 121 | state = Column(Integer) |
122 | - # 数据源外键 | |
122 | + #数据源外键 | |
123 | 123 | database_guid = Column(String(256), ForeignKey('dmdms_database.guid')) |
124 | - # 目录外键 | |
124 | + #目录外键 | |
125 | 125 | catalog_guid = Column(String(256), ForeignKey('dmdms_catalog.guid')) |
126 | - | |
126 | + #抽稀任务指定表的guid | |
127 | 127 | table_guid = Column(String(256)) |
128 | 128 | #任务类型 |
129 | + #1:入库任务 | |
130 | + #2:抽稀任务 | |
131 | + #3:数据库刷新任务 | |
132 | + #4:影像金字塔任务 | |
133 | + #5:数据下载任务 | |
129 | 134 | task_type=Column(Integer) |
130 | - | |
131 | 135 | creator = Column(Text) |
132 | 136 | file_name = Column(Text) |
133 | - | |
134 | 137 | relate_processes = relationship('Process', backref='relate_task', lazy='dynamic') |
135 | - | |
136 | 138 | # 入库参数 |
137 | 139 | parameter= Column(Text) |
138 | 140 | |
... | ... | @@ -177,12 +179,9 @@ class Database(db.Model): |
177 | 179 | description = Column(Text) |
178 | 180 | # 唯一性约束,不能注册相同连接的库 |
179 | 181 | connectstr= Column(Text,unique=True) |
180 | - | |
181 | 182 | creator = Column(String(256)) |
182 | - | |
183 | 183 | create_time = Column(DateTime) |
184 | 184 | update_time = Column(DateTime) |
185 | - | |
186 | 185 | relate_catalogs = relationship('Catalog', backref='relate_database', lazy='dynamic') |
187 | 186 | relate_tables = relationship('Table', backref='relate_database', lazy='dynamic') |
188 | 187 | relate_tasks = relationship('Task', backref='relate_database', lazy='dynamic') | ... | ... |
... | ... | @@ -118,7 +118,7 @@ class Api(ApiTemplate): |
118 | 118 | |
119 | 119 | # 范围统计和数量统计以100w为界限 |
120 | 120 | query_count_layer: Layer = pg_ds.ExecuteSQL( |
121 | - "SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public.{}'::regclass".format(l_name)) | |
121 | + '''SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public."{}"'::regclass'''.format(l_name)) | |
122 | 122 | feature_count = query_count_layer.GetFeature(0).GetField("ec") |
123 | 123 | # 要素少于100w可以精确统计 |
124 | 124 | if feature_count < 1000000: |
... | ... | @@ -141,7 +141,7 @@ class Api(ApiTemplate): |
141 | 141 | database_guid=database.guid, |
142 | 142 | # alias=layer.GetName(), |
143 | 143 | name=layer.GetName(), create_time=this_time, update_time=this_time, |
144 | - table_type=GeometryAdapter.get_table_type(layer.GetGeomType()), | |
144 | + table_type=GeometryAdapter.get_table_type(GeometryAdapter.get_geometry_type(layer)), | |
145 | 145 | extent=extent, |
146 | 146 | feature_count=feature_count |
147 | 147 | ) | ... | ... |
app/modules/featureservice/__init__.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +#author: 4N | |
3 | +#createtime: 2021/8/11 | |
4 | +#email: nheweijun@sina.com | |
5 | + | |
6 | +from flasgger import swag_from | |
7 | +from flask import Blueprint | |
8 | +from app.util import BlueprintApi | |
9 | +from . import feature_query | |
10 | +from . import feature_add | |
11 | +from . import feature_buffer_query | |
12 | +from . import feature_info | |
13 | +from . import feature_delete | |
14 | +from . import feature_schema | |
15 | +from . import feature_edit | |
16 | + | |
17 | +class DataManager(BlueprintApi): | |
18 | + | |
19 | + bp = Blueprint("FeatureService", __name__, url_prefix="/API/FeatureService") | |
20 | + | |
21 | + @staticmethod | |
22 | + @bp.route('/Query', methods=['POST']) | |
23 | + @swag_from(feature_query.Api.api_doc) | |
24 | + def feature_query(): | |
25 | + """ | |
26 | + 要素查询 | |
27 | + """ | |
28 | + return feature_query.Api().result | |
29 | + | |
30 | + @staticmethod | |
31 | + @bp.route('/BufferQuery', methods=['POST']) | |
32 | + @swag_from(feature_buffer_query.Api.api_doc) | |
33 | + def feature_buffer_query(): | |
34 | + """ | |
35 | + 缓冲区查询 | |
36 | + """ | |
37 | + return feature_buffer_query.Api().result | |
38 | + | |
39 | + @staticmethod | |
40 | + @bp.route('/Info', methods=['POST']) | |
41 | + @swag_from(feature_info.Api.api_doc) | |
42 | + def feature_info(): | |
43 | + """ | |
44 | + 要素info | |
45 | + """ | |
46 | + return feature_info.Api().result | |
47 | + | |
48 | + | |
49 | + @staticmethod | |
50 | + @bp.route('/Delete', methods=['POST']) | |
51 | + @swag_from(feature_delete.Api.api_doc) | |
52 | + def feature_delete(): | |
53 | + """ | |
54 | + 要素删除 | |
55 | + """ | |
56 | + return feature_delete.Api().result | |
57 | + | |
58 | + @staticmethod | |
59 | + @bp.route('/Add', methods=['POST']) | |
60 | + @swag_from(feature_add.Api.api_doc) | |
61 | + def feature_add(): | |
62 | + """ | |
63 | + 要素增加 | |
64 | + """ | |
65 | + return feature_add.Api().result | |
66 | + | |
67 | + @staticmethod | |
68 | + @bp.route('/Edit', methods=['POST']) | |
69 | + @swag_from(feature_edit.Api.api_doc) | |
70 | + def feature_edit(): | |
71 | + """ | |
72 | + 要素修改 | |
73 | + """ | |
74 | + return feature_edit.Api().result | |
75 | + | |
76 | + @staticmethod | |
77 | + @bp.route('/Schema', methods=['POST']) | |
78 | + @swag_from(feature_schema.Api.api_doc) | |
79 | + def feature_schema(): | |
80 | + """ | |
81 | + 要素schema | |
82 | + """ | |
83 | + return feature_schema.Api().result | |
\ No newline at end of file | ... | ... |
app/modules/featureservice/feature_add.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +# author: 4N | |
3 | +# createtime: 2021/8/4 | |
4 | +# email: nheweijun@sina.com | |
5 | +import datetime | |
6 | + | |
7 | + | |
8 | + | |
9 | +from app.models import Task | |
10 | +from app.util.component.ApiTemplate import ApiTemplate | |
11 | +from app.util.component.ModelVisitor import ModelVisitor | |
12 | +class Api(ApiTemplate): | |
13 | + api_name = "要素增加" | |
14 | + def para_check(self): | |
15 | + pass | |
16 | + | |
17 | + def process(self): | |
18 | + | |
19 | + res = {} | |
20 | + res["data"] = {} | |
21 | + try: | |
22 | + pass | |
23 | + except Exception as e: | |
24 | + raise e | |
25 | + return res | |
26 | + | |
27 | + | |
28 | + | |
29 | + api_doc={ | |
30 | + "tags":["要素接口"], | |
31 | + "parameters":[ | |
32 | + | |
33 | + ], | |
34 | + "responses":{ | |
35 | + 200:{ | |
36 | + "schema":{ | |
37 | + "properties":{ | |
38 | + } | |
39 | + } | |
40 | + } | |
41 | + } | |
42 | + } | |
\ No newline at end of file | ... | ... |
1 | +# coding=utf-8 | |
2 | +# author: 4N | |
3 | +# createtime: 2021/8/4 | |
4 | +# email: nheweijun@sina.com | |
5 | +import datetime | |
6 | + | |
7 | + | |
8 | + | |
9 | +from app.models import Table,Database | |
10 | +from app.util.component.ApiTemplate import ApiTemplate | |
11 | +from app.util.component.GeometryAdapter import GeometryAdapter | |
12 | +from app.util.component.LayerUtil import LayerUtil | |
13 | +from app.util.component.PGUtil import PGUtil | |
14 | +from osgeo.ogr import Geometry,Layer,DataSource,Feature | |
15 | +from app.models import DES | |
16 | +from osgeo import ogr | |
17 | +import gzip | |
18 | +from flask import make_response | |
19 | +class Api(ApiTemplate): | |
20 | + api_name = "缓冲区查询" | |
21 | + def para_check(self): | |
22 | + pass | |
23 | + | |
24 | + def process(self): | |
25 | + | |
26 | + res = {} | |
27 | + pg_ds:DataSource = None | |
28 | + try: | |
29 | + table:Table = Table.query.filter_by(guid=self.para.get("guid")).one_or_none() | |
30 | + if not table: | |
31 | + raise Exception("数据不存在!") | |
32 | + if table.table_type == 0: | |
33 | + raise Exception("非空间数据!") | |
34 | + | |
35 | + database:Database = table.relate_database | |
36 | + pg_ds:DataSource = PGUtil.open_pg_data_source(0,DES.decode(database.sqlalchemy_uri)) | |
37 | + layer:Layer = pg_ds.GetLayerByName(table.name) | |
38 | + | |
39 | + #缓冲区查询 | |
40 | + point = GeometryAdapter.tuple_2_point([float(x) for x in self.para.get("point").split(",")]) | |
41 | + layer.SetSpatialFilter(point.Buffer(float(self.para.get("buffer")))) | |
42 | + | |
43 | + feature_collection = LayerUtil.layer_to_feature_collection(layer,limit=1000) | |
44 | + res["data"] = feature_collection | |
45 | + res["result"] = True | |
46 | + | |
47 | + except Exception as e: | |
48 | + raise e | |
49 | + finally: | |
50 | + if pg_ds: | |
51 | + pg_ds.Destroy() | |
52 | + | |
53 | + # 使用gzip 压缩传输 | |
54 | + content = gzip.compress(bytes('{}'.format(json.dumps(res,ensure_ascii=False)), 'utf-8'), 2) | |
55 | + response = make_response(content) | |
56 | + response.headers['Content-length'] = len(content) | |
57 | + response.headers['Content-Encoding'] = 'gzip' | |
58 | + return response | |
59 | + | |
60 | + api_doc={ | |
61 | + "tags":["要素接口"], | |
62 | + "parameters":[ | |
63 | + {"name": "guid", | |
64 | + "in": "formData", | |
65 | + "type": "string", | |
66 | + "description": "guid"}, | |
67 | + {"name": "point", | |
68 | + "in": "formData", | |
69 | + "type": "string", | |
70 | + "description": "point"}, | |
71 | + {"name": "buffer", | |
72 | + "in": "formData", | |
73 | + "type": "float", | |
74 | + "description": "buffer"} | |
75 | + ], | |
76 | + "responses":{ | |
77 | + 200:{ | |
78 | + "schema":{ | |
79 | + "properties":{ | |
80 | + } | |
81 | + } | |
82 | + } | |
83 | + } | |
84 | + } | |
\ No newline at end of file | ... | ... |
app/modules/featureservice/feature_delete.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +# author: 4N | |
3 | +# createtime: 2021/8/4 | |
4 | +# email: nheweijun@sina.com | |
5 | +from app.models import Table,Database | |
6 | +from app.util.component.ApiTemplate import ApiTemplate | |
7 | +from app.util.component.GeometryAdapter import GeometryAdapter | |
8 | +from app.util.component.LayerUtil import LayerUtil | |
9 | +from app.util.component.PGUtil import PGUtil | |
10 | +from osgeo.ogr import Geometry,Layer,DataSource,Feature | |
11 | +from app.models import DES | |
12 | +import json | |
13 | +class Api(ApiTemplate): | |
14 | + api_name = "要素删除" | |
15 | + def para_check(self): | |
16 | + pass | |
17 | + | |
18 | + def process(self): | |
19 | + | |
20 | + res = {} | |
21 | + pg_ds:DataSource = None | |
22 | + try: | |
23 | + table:Table = Table.query.filter_by(guid=self.para.get("guid")).one_or_none() | |
24 | + if not table: | |
25 | + raise Exception("数据不存在!") | |
26 | + if table.table_type == 0: | |
27 | + raise Exception("非空间数据!") | |
28 | + | |
29 | + database:Database = table.relate_database | |
30 | + pg_ds:DataSource = PGUtil.open_pg_data_source(1,DES.decode(database.sqlalchemy_uri)) | |
31 | + layer:Layer = pg_ds.GetLayerByName(table.name) | |
32 | + | |
33 | + fid = int(self.para.get("fid")) | |
34 | + is_success = layer.DeleteFeature(fid) | |
35 | + if is_success == 0: | |
36 | + res["msg"] = "删除成功!" | |
37 | + res["result"] = True | |
38 | + else : | |
39 | + res["msg"] = "要素不存在,删除失败!" | |
40 | + res["result"] = False | |
41 | + | |
42 | + except Exception as e: | |
43 | + raise e | |
44 | + finally: | |
45 | + if pg_ds: | |
46 | + pg_ds.Destroy() | |
47 | + return res | |
48 | + | |
49 | + | |
50 | + | |
51 | + | |
52 | + api_doc={ | |
53 | + "tags":["要素接口"], | |
54 | + "parameters":[ | |
55 | + {"name": "guid", | |
56 | + "in": "formData", | |
57 | + "type": "string", | |
58 | + "description": "guid"}, | |
59 | + {"name": "fid", | |
60 | + "in": "formData", | |
61 | + "type": "string", | |
62 | + "description": "fid"} | |
63 | + ], | |
64 | + "responses":{ | |
65 | + 200:{ | |
66 | + "schema":{ | |
67 | + "properties":{ | |
68 | + } | |
69 | + } | |
70 | + } | |
71 | + } | |
72 | + } | |
\ No newline at end of file | ... | ... |
app/modules/featureservice/feature_edit.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +# author: 4N | |
3 | +# createtime: 2021/8/4 | |
4 | +# email: nheweijun@sina.com | |
5 | +import datetime | |
6 | + | |
7 | + | |
8 | + | |
9 | +from app.models import Task | |
10 | +from app.util.component.ApiTemplate import ApiTemplate | |
11 | +from app.util.component.ModelVisitor import ModelVisitor | |
12 | +class Api(ApiTemplate): | |
13 | + api_name = "要素编辑" | |
14 | + def para_check(self): | |
15 | + pass | |
16 | + | |
17 | + def process(self): | |
18 | + | |
19 | + res = {} | |
20 | + res["data"] = {} | |
21 | + try: | |
22 | + pass | |
23 | + except Exception as e: | |
24 | + raise e | |
25 | + return res | |
26 | + | |
27 | + | |
28 | + | |
29 | + api_doc={ | |
30 | + "tags":["要素接口"], | |
31 | + "parameters":[ | |
32 | + | |
33 | + ], | |
34 | + "responses":{ | |
35 | + 200:{ | |
36 | + "schema":{ | |
37 | + "properties":{ | |
38 | + } | |
39 | + } | |
40 | + } | |
41 | + } | |
42 | + } | |
\ No newline at end of file | ... | ... |
app/modules/featureservice/feature_info.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +# author: 4N | |
3 | +# createtime: 2021/8/4 | |
4 | +# email: nheweijun@sina.com | |
5 | + | |
6 | + | |
7 | +from app.models import Table,Database | |
8 | +from app.util.component.ApiTemplate import ApiTemplate | |
9 | +from app.util.component.GeometryAdapter import GeometryAdapter | |
10 | +from app.util.component.LayerUtil import LayerUtil | |
11 | +from app.util.component.PGUtil import PGUtil | |
12 | +from osgeo.ogr import Geometry,Layer,DataSource,Feature | |
13 | +from app.models import DES | |
14 | +import json | |
15 | +import gzip | |
16 | +from flask import make_response | |
17 | +class Api(ApiTemplate): | |
18 | + api_name = "要素info" | |
19 | + def para_check(self): | |
20 | + pass | |
21 | + | |
22 | + def process(self): | |
23 | + | |
24 | + res = {} | |
25 | + pg_ds:DataSource = None | |
26 | + try: | |
27 | + table:Table = Table.query.filter_by(guid=self.para.get("guid")).one_or_none() | |
28 | + if not table: | |
29 | + raise Exception("数据不存在!") | |
30 | + if table.table_type == 0: | |
31 | + raise Exception("非空间数据!") | |
32 | + | |
33 | + database:Database = table.relate_database | |
34 | + pg_ds:DataSource = PGUtil.open_pg_data_source(0,DES.decode(database.sqlalchemy_uri)) | |
35 | + layer:Layer = pg_ds.GetLayerByName(table.name) | |
36 | + | |
37 | + #info查询 | |
38 | + point = GeometryAdapter.tuple_2_point([float(x) for x in self.para.get("point").split(",")]) | |
39 | + layer.SetSpatialFilter(point) | |
40 | + intersect_feats = [] | |
41 | + for feature in layer: | |
42 | + if feature.geometry().Intersect(point): | |
43 | + intersect_feats.append(feature) | |
44 | + feature_collection = LayerUtil.layer_to_feature_collection(intersect_feats,limit=1000) | |
45 | + res["data"] = feature_collection | |
46 | + res["result"] = True | |
47 | + | |
48 | + except Exception as e: | |
49 | + raise e | |
50 | + finally: | |
51 | + if pg_ds: | |
52 | + pg_ds.Destroy() | |
53 | + | |
54 | + # 使用gzip 压缩传输 | |
55 | + content = gzip.compress(bytes("{}".format(json.dumps(res,ensure_ascii=False)), "utf-8"), 2) | |
56 | + response = make_response(content) | |
57 | + response.headers['Content-length'] = len(content) | |
58 | + response.headers['Content-Encoding'] = "gzip" | |
59 | + return response | |
60 | + | |
61 | + | |
62 | + api_doc={ | |
63 | + "tags":["要素接口"], | |
64 | + "parameters":[ | |
65 | + {"name": "guid", | |
66 | + "in": "formData", | |
67 | + "type": "string", | |
68 | + "description": "guid"}, | |
69 | + {"name": "point", | |
70 | + "in": "formData", | |
71 | + "type": "string", | |
72 | + "description": "point"} | |
73 | + ], | |
74 | + "responses":{ | |
75 | + 200:{ | |
76 | + "schema":{ | |
77 | + "properties":{ | |
78 | + } | |
79 | + } | |
80 | + } | |
81 | + } | |
82 | + } | |
\ No newline at end of file | ... | ... |
app/modules/featureservice/feature_query.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +# author: 4N | |
3 | +# createtime: 2021/8/4 | |
4 | +# email: nheweijun@sina.com | |
5 | +import datetime | |
6 | + | |
7 | + | |
8 | + | |
9 | +from app.models import Table,Database | |
10 | +from app.util.component.ApiTemplate import ApiTemplate | |
11 | +from app.util.component.GeometryAdapter import GeometryAdapter | |
12 | +from app.util.component.LayerUtil import LayerUtil | |
13 | +from app.util.component.PGUtil import PGUtil | |
14 | +from osgeo.ogr import Geometry,Layer,DataSource,Feature | |
15 | +from app.models import DES | |
16 | +import json | |
17 | +import gzip | |
18 | +from flask import make_response | |
19 | +class Api(ApiTemplate): | |
20 | + api_name = "空间查询" | |
21 | + def para_check(self): | |
22 | + pass | |
23 | + | |
24 | + def process(self): | |
25 | + | |
26 | + res = {} | |
27 | + pg_ds:DataSource = None | |
28 | + try: | |
29 | + table:Table = Table.query.filter_by(guid=self.para.get("guid")).one_or_none() | |
30 | + if not table: | |
31 | + raise Exception("数据不存在!") | |
32 | + if table.table_type == 0: | |
33 | + raise Exception("非空间数据!") | |
34 | + | |
35 | + database:Database = table.relate_database | |
36 | + pg_ds:DataSource = PGUtil.open_pg_data_source(0,DES.decode(database.sqlalchemy_uri)) | |
37 | + layer:Layer = pg_ds.GetLayerByName(table.name) | |
38 | + | |
39 | + #空间查询 | |
40 | + if self.para.get("bbox"): | |
41 | + bbox:Geometry = GeometryAdapter.envelop_2_polygon([float(x) for x in self.para.get("bbox").split(",")]) | |
42 | + layer.SetSpatialFilter(bbox) | |
43 | + #属性查询 | |
44 | + if self.para.get("filter"): | |
45 | + conditions = json.loads(self.para.get("filter")) | |
46 | + filter_conds = [] | |
47 | + for cond in conditions: | |
48 | + if cond["type"].__eq__("range"): | |
49 | + filter_conds.append("{}>{} AND {}<{}".format(cond["name"],cond["lower"], | |
50 | + cond["name"], cond["higher"])) | |
51 | + if cond["type"].__eq__("value"): | |
52 | + try: | |
53 | + val = float(cond["value"]) | |
54 | + filter_conds.append("{}={}".format(cond["name"], val)) | |
55 | + except: | |
56 | + filter_conds.append("{} like '%{}%'".format(cond["name"], cond["value"])) | |
57 | + if cond["type"].__eq__("time"): | |
58 | + filter_conds.append("{} > timestamp '{}' AND {} < timestamp '{}'".format(cond["name"], | |
59 | + cond["lower"], | |
60 | + cond["name"], | |
61 | + cond["higher"])) | |
62 | + layer.SetAttributeFilter(" AND ".join(filter_conds)) | |
63 | + | |
64 | + | |
65 | + feature_collection = LayerUtil.layer_to_feature_collection(layer,limit=1000) | |
66 | + res["data"] = feature_collection | |
67 | + res["result"] = True | |
68 | + | |
69 | + except Exception as e: | |
70 | + raise e | |
71 | + finally: | |
72 | + if pg_ds: | |
73 | + pg_ds.Destroy() | |
74 | + | |
75 | + # 使用gzip 压缩传输 | |
76 | + content = gzip.compress(bytes('{}'.format(json.dumps(res,ensure_ascii=False)), 'utf-8'), 2) | |
77 | + response = make_response(content) | |
78 | + response.headers['Content-length'] = len(content) | |
79 | + response.headers['Content-Encoding'] = 'gzip' | |
80 | + return response | |
81 | + | |
82 | + api_doc={ | |
83 | + "tags":["要素接口"], | |
84 | + "parameters":[ | |
85 | + {"name": "guid", | |
86 | + "in": "formData", | |
87 | + "type": "string", | |
88 | + "description": "guid"}, | |
89 | + {"name": "bbox", | |
90 | + "in": "formData", | |
91 | + "type": "string", | |
92 | + "description": "bbox"}, | |
93 | + {"name": "filter", | |
94 | + "in": "formData", | |
95 | + "type": "string", | |
96 | + "description": "filter"} | |
97 | + ], | |
98 | + "responses":{ | |
99 | + 200:{ | |
100 | + "schema":{ | |
101 | + "properties":{ | |
102 | + } | |
103 | + } | |
104 | + } | |
105 | + } | |
106 | + } | |
\ No newline at end of file | ... | ... |
app/modules/featureservice/feature_schema.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +# author: 4N | |
3 | +# createtime: 2021/8/4 | |
4 | +# email: nheweijun@sina.com | |
5 | + | |
6 | + | |
7 | +from app.models import Table,Database | |
8 | +from app.util.component.ApiTemplate import ApiTemplate | |
9 | +from app.util.component.GeometryAdapter import GeometryAdapter | |
10 | +from app.util.component.LayerUtil import LayerUtil | |
11 | +from app.util.component.PGUtil import PGUtil | |
12 | +from osgeo.ogr import Geometry,Layer,DataSource,Feature,FieldDefn | |
13 | +from app.models import DES | |
14 | +import json | |
15 | +class Api(ApiTemplate): | |
16 | + api_name = "要素info" | |
17 | + def para_check(self): | |
18 | + pass | |
19 | + | |
20 | + def process(self): | |
21 | + | |
22 | + res = {} | |
23 | + pg_ds:DataSource = None | |
24 | + try: | |
25 | + table:Table = Table.query.filter_by(guid=self.para.get("guid")).one_or_none() | |
26 | + if not table: | |
27 | + raise Exception("数据不存在!") | |
28 | + if table.table_type == 0: | |
29 | + raise Exception("非空间数据!") | |
30 | + | |
31 | + database:Database = table.relate_database | |
32 | + pg_ds:DataSource = PGUtil.open_pg_data_source(0,DES.decode(database.sqlalchemy_uri)) | |
33 | + layer:Layer = pg_ds.GetLayerByName(table.name) | |
34 | + | |
35 | + res["data"] = [] | |
36 | + | |
37 | + schema = layer.schema | |
38 | + for s in schema: | |
39 | + field :FieldDefn = s | |
40 | + d1 = field.GetName() | |
41 | + d2 = field.GetTypeName() | |
42 | + res["data"].append({"name":field.GetName(),"type":field.GetTypeName(),"pricision":field.GetWidth()}) | |
43 | + res["result"] = True | |
44 | + | |
45 | + except Exception as e: | |
46 | + raise e | |
47 | + finally: | |
48 | + if pg_ds: | |
49 | + pg_ds.Destroy() | |
50 | + return res | |
51 | + | |
52 | + | |
53 | + | |
54 | + | |
55 | + api_doc={ | |
56 | + "tags":["要素接口"], | |
57 | + "parameters":[ | |
58 | + {"name": "guid", | |
59 | + "in": "formData", | |
60 | + "type": "string", | |
61 | + "description": "guid"} | |
62 | + ], | |
63 | + "responses":{ | |
64 | + 200:{ | |
65 | + "schema":{ | |
66 | + "properties":{ | |
67 | + } | |
68 | + } | |
69 | + } | |
70 | + } | |
71 | + } | |
\ No newline at end of file | ... | ... |
... | ... | @@ -85,18 +85,12 @@ class Api(ApiTemplate): |
85 | 85 | if parameter.get("tilecol"): |
86 | 86 | self.col = int(parameter.get("tilecol")) |
87 | 87 | |
88 | - | |
89 | - | |
90 | 88 | image_type = parameter.get("format") if parameter.get("format") else "image/png" |
91 | - | |
92 | 89 | quality = int(parameter.get("quality")) if parameter.get("quality") else 30 |
93 | - | |
94 | 90 | slice_para = json.loads(image_service.slice_scheme) |
95 | - | |
96 | 91 | extent = SliceScheme.get_polygon(slice_para, self.level, self.row, self.col) |
97 | 92 | |
98 | 93 | # 结果矩阵 |
99 | - | |
100 | 94 | empty_list = [numpy.zeros((256, 256), dtype=int) + 65536, |
101 | 95 | numpy.zeros((256, 256), dtype=int) + 65536, |
102 | 96 | numpy.zeros((256, 256), dtype=int) + 65536] |
... | ... | @@ -108,134 +102,23 @@ class Api(ApiTemplate): |
108 | 102 | pixel_array = numpy.zeros((256, 256,3), dtype=int) |
109 | 103 | |
110 | 104 | for image in intersect_image: |
111 | - | |
112 | 105 | if image.host.__eq__("本地服务器"): |
113 | - | |
114 | - pixel_array = numpy.zeros((256, 256, 3), dtype=int) | |
115 | - ceng = 0 | |
116 | - img: Dataset = gdal.Open(image.path, 0) | |
117 | - t1 = time.time() | |
118 | - for band in bands: | |
119 | - | |
120 | - # 自决定金字塔等级 | |
121 | - xysize = [img.RasterXSize, img.RasterYSize] | |
122 | - origin_extent = image.extent | |
123 | - band_data: Band = img.GetRasterBand(band) | |
124 | - max_level = band_data.GetOverviewCount() | |
125 | - | |
126 | - # 超出空间范围 | |
127 | - if extent[2] < origin_extent[0] or extent[0] > origin_extent[2] or extent[1] > origin_extent[ | |
128 | - 3] or extent[3] < origin_extent[1]: | |
129 | - empty = numpy.zeros((256, 256), dtype=int) + 65536 | |
130 | - # 空间范围相交 | |
131 | - else: | |
132 | - image_level = self.determine_level(xysize, origin_extent, extent, max_level) | |
133 | - | |
134 | - if image_level == -1: | |
135 | - overview = band_data | |
136 | - else: | |
137 | - try: | |
138 | - overview: Band = band_data.GetOverview(image_level) | |
139 | - except: | |
140 | - raise Exception("该影像不存在该级别的金字塔数据!") | |
141 | - ox = overview.XSize | |
142 | - oy = overview.YSize | |
143 | - | |
144 | - # 网格大小 | |
145 | - grid_x = (origin_extent[2] - origin_extent[0]) / (ox * 1.0) | |
146 | - grid_y = (origin_extent[3] - origin_extent[1]) / (oy * 1.0) | |
147 | - | |
148 | - # 完全在影像范围内 | |
149 | - if extent[0] > origin_extent[0] and extent[1] > origin_extent[1] and extent[2] < \ | |
150 | - origin_extent[2] and extent[3] < origin_extent[3]: | |
151 | - | |
152 | - # 网格偏移量 | |
153 | - off_x = math.floor((extent[0] - origin_extent[0]) / grid_x) | |
154 | - off_y = math.floor((origin_extent[3] - extent[3]) / grid_y) | |
155 | - | |
156 | - # 截取后网格个数 | |
157 | - x_g = math.ceil((extent[2] - extent[0]) / grid_x) | |
158 | - | |
159 | - y_g = math.ceil((extent[3] - extent[1]) / grid_y) | |
160 | - | |
161 | - empty = overview.ReadAsArray(off_x, off_y, x_g, y_g, 256, 256) | |
162 | - | |
163 | - | |
164 | - # 部分相交 | |
165 | - else: | |
166 | - | |
167 | - inter_extent = [0, 0, 0, 0] | |
168 | - inter_extent[0] = origin_extent[0] if origin_extent[0] > extent[0] else extent[0] | |
169 | - inter_extent[1] = origin_extent[1] if origin_extent[1] > extent[1] else extent[1] | |
170 | - inter_extent[2] = origin_extent[2] if origin_extent[2] < extent[2] else extent[2] | |
171 | - inter_extent[3] = origin_extent[3] if origin_extent[3] < extent[3] else extent[3] | |
172 | - | |
173 | - # 网格偏移量 | |
174 | - off_x = math.floor((inter_extent[0] - origin_extent[0]) / grid_x) | |
175 | - off_y = math.floor((origin_extent[3] - inter_extent[3]) / grid_y) | |
176 | - | |
177 | - # 截取后网格个数 | |
178 | - x_g = math.floor((inter_extent[2] - inter_extent[0]) / grid_x) | |
179 | - y_g = math.floor((inter_extent[3] - inter_extent[1]) / grid_y) | |
180 | - | |
181 | - # 相对于出图的偏移量 | |
182 | - | |
183 | - # 出图的网格大小 | |
184 | - out_grid_x = (extent[2] - extent[0]) / (256 * 1.0) | |
185 | - out_grid_y = (extent[3] - extent[1]) / (256 * 1.0) | |
186 | - | |
187 | - out_off_x = int(math.ceil((inter_extent[0] - extent[0]) / out_grid_x)) | |
188 | - out_off_y = int(math.ceil((extent[3] - inter_extent[3]) / out_grid_y)) | |
189 | - | |
190 | - out_x_g = int(math.floor((inter_extent[2] - inter_extent[0]) / out_grid_x)) | |
191 | - out_y_g = int(math.floor((inter_extent[3] - inter_extent[1]) / out_grid_y)) | |
192 | - | |
193 | - # 相交部分在出图的哪个位置 | |
194 | - | |
195 | - overview_raster: ndarray = overview.ReadAsArray(off_x, off_y, x_g, y_g, out_x_g, | |
196 | - out_y_g) | |
197 | - | |
198 | - dat = numpy.zeros((256, 256), dtype=int) + 65536 | |
199 | - dat[out_off_y:out_off_y + out_y_g, out_off_x:out_off_x + out_x_g] = overview_raster | |
200 | - | |
201 | - empty = dat | |
202 | - | |
203 | - pixel_array[:, :, ceng] = empty | |
204 | - ceng += 1 | |
205 | - | |
206 | - data = pixel_array | |
207 | - | |
106 | + data = self.get_local_data(image,extent,bands) | |
208 | 107 | else: |
209 | 108 | ser = "{}:{}".format(image.host,image.port) |
210 | 109 | if zoo.exists("/rpc/{}".format(ser)): |
211 | - | |
212 | - transport = TSocket.TSocket(image.host, image.port) | |
213 | - transport = TTransport.TBufferedTransport(transport) | |
214 | - protocol = TBinaryProtocol.TBinaryProtocol(transport) | |
215 | - client = ImageDataService.Client(protocol) | |
216 | - transport.open() | |
217 | - t1 = time.time() | |
218 | - data = client.getData(image.path, extent, json.loads(image.extent), bands) | |
219 | - transport.close() | |
220 | - current_app.logger.info("time {}".format(time.time()-t1)) | |
221 | - | |
222 | - data = gzip.decompress(data) | |
223 | - data = numpy.frombuffer(data, dtype=int) | |
224 | - data= data.reshape((256, 256, 3)) | |
110 | + data= self.get_remote_data(image,extent,bands) | |
225 | 111 | else: |
226 | 112 | data = numpy.zeros((256, 256, 3), dtype=int) + 65536 |
227 | 113 | |
228 | - | |
229 | 114 | # 掩膜在中央接口生成 |
230 | 115 | mask = numpy.zeros((256, 256), dtype=int) |
231 | 116 | mask2 = numpy.zeros((256, 256), dtype=int) |
232 | 117 | jizhun = data[:, :, 0] |
233 | - | |
234 | 118 | mask[jizhun == 65536] = 1 |
235 | 119 | mask[jizhun != 65536] = 0 |
236 | 120 | mask2[jizhun == 65536] = 0 |
237 | 121 | mask2[jizhun != 65536] = 1 |
238 | - | |
239 | 122 | # 掩膜计算 |
240 | 123 | for i, d in enumerate(empty_list): |
241 | 124 | empty_list[i] = empty_list[i] * mask + data[:, :, i] * mask2 |
... | ... | @@ -290,7 +173,7 @@ class Api(ApiTemplate): |
290 | 173 | image_out = buf.tobytes() |
291 | 174 | return image_out |
292 | 175 | |
293 | - def get_data(self,image,extent,bands): | |
176 | + def get_remote_data(self,image,extent,bands): | |
294 | 177 | ''' |
295 | 178 | 通过RPC获取远程数据 |
296 | 179 | :param image: |
... | ... | @@ -298,16 +181,123 @@ class Api(ApiTemplate): |
298 | 181 | :param bands: |
299 | 182 | :return: |
300 | 183 | ''' |
184 | + | |
301 | 185 | transport = TSocket.TSocket(image.host, image.port) |
302 | 186 | transport = TTransport.TBufferedTransport(transport) |
303 | 187 | protocol = TBinaryProtocol.TBinaryProtocol(transport) |
304 | 188 | client = ImageDataService.Client(protocol) |
305 | - | |
306 | 189 | transport.open() |
307 | - data = client.getData(image.path,extent,json.loads(image.extent), bands) | |
190 | + t1 = time.time() | |
191 | + data = client.getData(image.path, extent, json.loads(image.extent), bands) | |
308 | 192 | transport.close() |
193 | + current_app.logger.info("time {}".format(time.time() - t1)) | |
194 | + | |
195 | + data = gzip.decompress(data) | |
196 | + data = numpy.frombuffer(data, dtype=int) | |
197 | + data = data.reshape((256, 256, 3)) | |
198 | + | |
199 | + return data | |
200 | + | |
201 | + def get_local_data(self,image,extent,bands): | |
202 | + ''' | |
203 | + 获取本地数据 | |
204 | + :param image: | |
205 | + :param extent: | |
206 | + :param bands: | |
207 | + :return: | |
208 | + ''' | |
209 | + pixel_array = numpy.zeros((256, 256, 3), dtype=int) | |
210 | + ceng = 0 | |
211 | + img: Dataset = gdal.Open(image.path, 0) | |
212 | + t1 = time.time() | |
213 | + for band in bands: | |
214 | + | |
215 | + # 自决定金字塔等级 | |
216 | + xysize = [img.RasterXSize, img.RasterYSize] | |
217 | + origin_extent = image.extent | |
218 | + band_data: Band = img.GetRasterBand(band) | |
219 | + max_level = band_data.GetOverviewCount() | |
220 | + | |
221 | + # 超出空间范围 | |
222 | + if extent[2] < origin_extent[0] or extent[0] > origin_extent[2] or extent[1] > origin_extent[ | |
223 | + 3] or extent[3] < origin_extent[1]: | |
224 | + empty = numpy.zeros((256, 256), dtype=int) + 65536 | |
225 | + # 空间范围相交 | |
226 | + else: | |
227 | + image_level = self.determine_level(xysize, origin_extent, extent, max_level) | |
228 | + | |
229 | + if image_level == -1: | |
230 | + overview = band_data | |
231 | + else: | |
232 | + try: | |
233 | + overview: Band = band_data.GetOverview(image_level) | |
234 | + except: | |
235 | + raise Exception("该影像不存在该级别的金字塔数据!") | |
236 | + ox = overview.XSize | |
237 | + oy = overview.YSize | |
238 | + | |
239 | + # 网格大小 | |
240 | + grid_x = (origin_extent[2] - origin_extent[0]) / (ox * 1.0) | |
241 | + grid_y = (origin_extent[3] - origin_extent[1]) / (oy * 1.0) | |
242 | + | |
243 | + # 完全在影像范围内 | |
244 | + if extent[0] > origin_extent[0] and extent[1] > origin_extent[1] and extent[2] < \ | |
245 | + origin_extent[2] and extent[3] < origin_extent[3]: | |
246 | + | |
247 | + # 网格偏移量 | |
248 | + off_x = math.floor((extent[0] - origin_extent[0]) / grid_x) | |
249 | + off_y = math.floor((origin_extent[3] - extent[3]) / grid_y) | |
250 | + | |
251 | + # 截取后网格个数 | |
252 | + x_g = math.ceil((extent[2] - extent[0]) / grid_x) | |
253 | + | |
254 | + y_g = math.ceil((extent[3] - extent[1]) / grid_y) | |
255 | + | |
256 | + empty = overview.ReadAsArray(off_x, off_y, x_g, y_g, 256, 256) | |
257 | + | |
258 | + | |
259 | + # 部分相交 | |
260 | + else: | |
261 | + | |
262 | + inter_extent = [0, 0, 0, 0] | |
263 | + inter_extent[0] = origin_extent[0] if origin_extent[0] > extent[0] else extent[0] | |
264 | + inter_extent[1] = origin_extent[1] if origin_extent[1] > extent[1] else extent[1] | |
265 | + inter_extent[2] = origin_extent[2] if origin_extent[2] < extent[2] else extent[2] | |
266 | + inter_extent[3] = origin_extent[3] if origin_extent[3] < extent[3] else extent[3] | |
267 | + | |
268 | + # 网格偏移量 | |
269 | + off_x = math.floor((inter_extent[0] - origin_extent[0]) / grid_x) | |
270 | + off_y = math.floor((origin_extent[3] - inter_extent[3]) / grid_y) | |
271 | + | |
272 | + # 截取后网格个数 | |
273 | + x_g = math.floor((inter_extent[2] - inter_extent[0]) / grid_x) | |
274 | + y_g = math.floor((inter_extent[3] - inter_extent[1]) / grid_y) | |
275 | + | |
276 | + # 相对于出图的偏移量 | |
277 | + | |
278 | + # 出图的网格大小 | |
279 | + out_grid_x = (extent[2] - extent[0]) / (256 * 1.0) | |
280 | + out_grid_y = (extent[3] - extent[1]) / (256 * 1.0) | |
281 | + | |
282 | + out_off_x = int(math.ceil((inter_extent[0] - extent[0]) / out_grid_x)) | |
283 | + out_off_y = int(math.ceil((extent[3] - inter_extent[3]) / out_grid_y)) | |
284 | + | |
285 | + out_x_g = int(math.floor((inter_extent[2] - inter_extent[0]) / out_grid_x)) | |
286 | + out_y_g = int(math.floor((inter_extent[3] - inter_extent[1]) / out_grid_y)) | |
287 | + | |
288 | + # 相交部分在出图的哪个位置 | |
289 | + | |
290 | + overview_raster: ndarray = overview.ReadAsArray(off_x, off_y, x_g, y_g, out_x_g, | |
291 | + out_y_g) | |
292 | + | |
293 | + dat = numpy.zeros((256, 256), dtype=int) + 65536 | |
294 | + dat[out_off_y:out_off_y + out_y_g, out_off_x:out_off_x + out_x_g] = overview_raster | |
295 | + | |
296 | + empty = dat | |
309 | 297 | |
310 | - return numpy.array(json.loads(data)) | |
298 | + pixel_array[:, :, ceng] = empty | |
299 | + ceng += 1 | |
300 | + return pixel_array | |
311 | 301 | |
312 | 302 | def determin_intersect(self,extent1,extent2): |
313 | 303 | g1 = GeometryAdapter.envelop_2_polygon(extent1) | ... | ... |
... | ... | @@ -4,11 +4,11 @@ |
4 | 4 | #email: nheweijun@sina.com |
5 | 5 | |
6 | 6 | |
7 | -from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Time | |
7 | +from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Time,Binary | |
8 | 8 | from app.models import db |
9 | -from sqlalchemy.ext.declarative import declarative_base | |
10 | 9 | |
11 | -Base = declarative_base() | |
10 | + | |
11 | + | |
12 | 12 | class Image(db.Model): |
13 | 13 | ''' |
14 | 14 | 影像元数据 |
... | ... | @@ -27,7 +27,10 @@ class Image(db.Model): |
27 | 27 | path=Column(String) |
28 | 28 | host=Column(String) |
29 | 29 | port=Column(Integer) |
30 | - | |
30 | + #坐标wkt | |
31 | + projection = Column(Text) | |
32 | + #年份 | |
33 | + ym= Column(String(256)) | |
31 | 34 | |
32 | 35 | dmdms_image_rel = db.Table('dmdms_image_rel', |
33 | 36 | Column('image_guid',String, ForeignKey('dmdms_image.guid')), |
... | ... | @@ -50,6 +53,10 @@ class ImageService(db.Model): |
50 | 53 | description = Column(Text) |
51 | 54 | slice_scheme = Column(Text) |
52 | 55 | extent = Column(String(256)) |
56 | + #可视范围geojson | |
57 | + visual_range = Column(Text) | |
58 | + #影像服务缩略图 | |
59 | + overview = Column(Binary) | |
53 | 60 | images = db.relationship('Image', |
54 | 61 | secondary=dmdms_image_rel, |
55 | 62 | backref='image_services', | ... | ... |
... | ... | @@ -37,7 +37,7 @@ class Api(ApiTemplate): |
37 | 37 | |
38 | 38 | sort = int(self.para.get("sort","1")) |
39 | 39 | if sort.__eq__(1): |
40 | - tables = Table.query.order_by(Table.update_time.desc()) | |
40 | + tables = Table.query.order_by(Table.update_time.desc(),Table.name) | |
41 | 41 | else: |
42 | 42 | tables = Table.query.order_by(Table.name) |
43 | 43 | ... | ... |
... | ... | @@ -198,7 +198,7 @@ class Api(ApiTemplate): |
198 | 198 | |
199 | 199 | # 范围统计和数量统计以100w为界限 |
200 | 200 | query_count_layer: Layer = pg_ds.ExecuteSQL( |
201 | - "SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public.{}'::regclass".format( | |
201 | + '''SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public."{}"'::regclass'''.format( | |
202 | 202 | l_name)) |
203 | 203 | feature_count = query_count_layer.GetFeature(0).GetField("ec") |
204 | 204 | # 要素少于100w可以精确统计 |
... | ... | @@ -223,7 +223,7 @@ class Api(ApiTemplate): |
223 | 223 | database_guid=database.guid, |
224 | 224 | # alias=layer.GetName(), |
225 | 225 | name=layer.GetName(), create_time=this_time, update_time=this_time, |
226 | - table_type=GeometryAdapter.get_table_type(layer.GetGeomType()), | |
226 | + table_type=GeometryAdapter.get_table_type(GeometryAdapter.get_geometry_type(layer)), | |
227 | 227 | extent=extent, |
228 | 228 | feature_count=feature_count |
229 | 229 | ) |
... | ... | @@ -331,7 +331,7 @@ class Api(ApiTemplate): |
331 | 331 | |
332 | 332 | # 范围统计和数量统计以100w为界限 |
333 | 333 | query_count_layer: Layer = pg_ds.ExecuteSQL( |
334 | - "SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public.{}'::regclass".format( | |
334 | + '''SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public."{}"'::regclass'''.format( | |
335 | 335 | l_name)) |
336 | 336 | feature_count = query_count_layer.GetFeature(0).GetField("ec") |
337 | 337 | # 要素少于100w可以精确统计 | ... | ... |
app/util/component/CopyData.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +#author: 4N | |
3 | +#createtime: 2021/6/11 | |
4 | +#email: nheweijun@sina.com | |
5 | +import copy | |
6 | +from osgeo.ogr import * | |
7 | +from osgeo import gdal,ogr | |
8 | +import uuid | |
9 | +import time | |
10 | +import os | |
11 | + | |
12 | +def get_info_from_sqlachemy_uri(uri): | |
13 | + parts = uri.split(":") | |
14 | + user = parts[1][2:] | |
15 | + | |
16 | + password_list = parts[2].split("@") | |
17 | + if password_list.__len__() > 2: | |
18 | + password = "@".join(password_list[:-1]) | |
19 | + else: | |
20 | + password = parts[2].split("@")[0] | |
21 | + host = parts[2].split("@")[-1] | |
22 | + port = parts[3].split("/")[0] | |
23 | + database = parts[3].split("/")[1] | |
24 | + | |
25 | + return user, password, host, port, database | |
26 | + | |
27 | +def open_pg_data_source(iswrite, uri): | |
28 | + """ | |
29 | + # 获取PostGIS数据源 | |
30 | + :return: | |
31 | + """ | |
32 | + db_conn_tuple = get_info_from_sqlachemy_uri(uri) | |
33 | + fn = "PG: user=%s password=%s host=%s port=%s dbname=%s " % db_conn_tuple | |
34 | + driver = ogr.GetDriverByName("PostgreSQL") | |
35 | + if driver is None: | |
36 | + raise Exception("打开PostgreSQL驱动失败,可能是当前GDAL未支持PostgreSQL驱动!") | |
37 | + ds = driver.Open(fn, iswrite) | |
38 | + if ds is None: | |
39 | + raise Exception("打开数据源失败!") | |
40 | + return ds | |
41 | + | |
42 | +def move(geo:Geometry,offx,offy): | |
43 | + | |
44 | + g = geo.GetGeometryRef(0) | |
45 | + num = g.GetPointCount() | |
46 | + | |
47 | + coor = [] | |
48 | + try: | |
49 | + for j in range(num): | |
50 | + point = g.GetPoint(j) | |
51 | + x = point[0] | |
52 | + y = point[1] | |
53 | + x += offx | |
54 | + y += offy | |
55 | + coor.append([x, y]) | |
56 | + if num==1: | |
57 | + point = ogr.Geometry(ogr.wkbPoint) | |
58 | + point.AddPoint(coor[0][0], coor[0][1]) | |
59 | + return point | |
60 | + elif coor[0].__eq__(coor[-1]): | |
61 | + ring = ogr.Geometry(ogr.wkbLinearRing) | |
62 | + for co in coor: | |
63 | + ring.AddPoint(co[0], co[1]) | |
64 | + poly = ogr.Geometry(ogr.wkbPolygon) | |
65 | + poly.AddGeometry(ring) | |
66 | + return poly | |
67 | + else : | |
68 | + line = ogr.Geometry(ogr.wkbLineString) | |
69 | + for co in coor: | |
70 | + line.AddPoint(co[0], co[1]) | |
71 | + return line | |
72 | + except: | |
73 | + return None | |
74 | + | |
75 | + | |
76 | +def copydata(): | |
77 | + | |
78 | + | |
79 | + bound = "" | |
80 | + | |
81 | + work_dir =r"E:\D2\桌面\FSSD_RES_PY_FWM" | |
82 | + | |
83 | + data_path=r"E:\D2\桌面\FSSD_RES_PY_FWM\fs4326.shp" | |
84 | + | |
85 | + base_name="fs900w" | |
86 | + | |
87 | + driver: Driver = ogr.GetDriverByName("ESRI Shapefile") | |
88 | + ds: DataSource = driver.Open(data_path, 1) | |
89 | + | |
90 | + bound_ds : DataSource = driver.Open(bound, 1) | |
91 | + bound_layer :Layer = bound_ds.GetLayer(0) | |
92 | + bound_geom = bound_layer.GetNextFeature().GetGeometryRef() | |
93 | + | |
94 | + | |
95 | + if not ds: | |
96 | + raise Exception("打开数据失败!") | |
97 | + | |
98 | + layer: Layer = ds.GetLayer(0) | |
99 | + | |
100 | + | |
101 | + | |
102 | + schema = layer.schema | |
103 | + schema = [s for s in schema if not s.GetName().lower().__eq__("objectid")] | |
104 | + for s in schema : | |
105 | + if s.GetName().lower().__eq__("objectid") and not s.GetTypeName().__eq__("Interger"): | |
106 | + s.SetType(ogr.OFTInteger) | |
107 | + | |
108 | + | |
109 | + | |
110 | + gdb_driver:Driver = ogr.GetDriverByName("FileGDB") | |
111 | + gdb_ds: DataSource = gdb_driver.CreateDataSource(os.path.join(work_dir,"{}.gdb".format(base_name))) | |
112 | + gdb_layer:Layer = gdb_ds.CreateLayer(base_name, layer.GetSpatialRef(),layer.GetGeomType()) | |
113 | + | |
114 | + # gdb_layer.CreateFields(schema) | |
115 | + | |
116 | + print(gdb_layer.GetFIDColumn()) | |
117 | + | |
118 | + extent = layer.GetExtent() | |
119 | + xxrange=extent[1]-extent[0] | |
120 | + yrange = extent[3]-extent[2] | |
121 | + feature_defn: FeatureDefn = layer.GetLayerDefn() | |
122 | + | |
123 | + begin = time.time() | |
124 | + count=0 | |
125 | + work_dir =os.path.dirname(os.path.abspath(__file__)) | |
126 | + | |
127 | + for f in layer: | |
128 | + | |
129 | + if count%10000==0: | |
130 | + print(count) | |
131 | + with open(os.path.join(work_dir, "copy.txt"), "w") as fi: | |
132 | + fi.write("已完成{}".format(count)) | |
133 | + g:Geometry=f.GetGeometryRef() | |
134 | + new_f:Feature = copy.copy(f) | |
135 | + for xt in range(3): | |
136 | + for yt in range(3): | |
137 | + out_g = move(g,xxrange*xt,yrange*yt) | |
138 | + new_f.SetGeometry(out_g) | |
139 | + new_f.SetFID(count) | |
140 | + dd:FieldDefn=new_f.GetField("OBJECTID") | |
141 | + # new_f.UnsetField("OBJECTID") | |
142 | + gdb_layer.CreateFeature(new_f) | |
143 | + count += 1 | |
144 | + | |
145 | + print(time.time()-begin) | |
146 | + | |
147 | + gdb_ds.Destroy() | |
148 | + | |
149 | + | |
150 | + | |
151 | +if __name__ == '__main__': | |
152 | + copydata() | |
153 | + | |
154 | + | |
155 | + | |
156 | + | |
157 | + | |
158 | + | |
159 | + | |
160 | + | |
161 | + | |
162 | + | |
163 | + | ... | ... |
... | ... | @@ -323,7 +323,7 @@ class ThisTask: |
323 | 323 | database_guid=self.database.guid, |
324 | 324 | creator=creator, |
325 | 325 | name=new_layer_name, create_time=this_time, update_time=this_time, |
326 | - catalog_guid=self.catalog_guid, table_type=GeometryAdapter.get_table_type(layer.GetGeomType()), | |
326 | + catalog_guid=self.catalog_guid, table_type=GeometryAdapter.get_table_type(GeometryAdapter.get_geometry_type(layer)), | |
327 | 327 | extent=extent, |
328 | 328 | feature_count=layer.GetFeatureCount(), |
329 | 329 | is_vacuate=is_vacuate | ... | ... |
... | ... | @@ -152,4 +152,21 @@ class GeometryAdapter: |
152 | 152 | # Create polygon |
153 | 153 | poly = ogr.Geometry(ogr.wkbPolygon) |
154 | 154 | poly.AddGeometry(ring) |
155 | - return poly | |
\ No newline at end of file | ||
155 | + return poly | |
156 | + | |
157 | + @classmethod | |
158 | + def tuple_2_point(cls,tup): | |
159 | + point = ogr.Geometry(ogr.wkbPoint) | |
160 | + point.AddPoint(tup[0], tup[1]) | |
161 | + return point | |
162 | + | |
163 | + @classmethod | |
164 | + def get_geometry_type(cls,layer): | |
165 | + geom_type = layer.GetGeomType() | |
166 | + if geom_type.__eq__(0): | |
167 | + fea = layer.GetNextFeature() | |
168 | + if fea: | |
169 | + g: Geometry = fea.geometry() | |
170 | + geom_type = g.GetGeometryType() | |
171 | + layer.ResetReading() | |
172 | + return geom_type | |
\ No newline at end of file | ... | ... |
app/util/component/GzipUtil.py
0 → 100644
app/util/component/LayerUtil.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +#author: 4N | |
3 | +#createtime: 2021/8/12 | |
4 | +#email: nheweijun@sina.com | |
5 | +from osgeo.ogr import Layer,Feature | |
6 | +import json | |
7 | + | |
8 | + | |
9 | +class LayerUtil: | |
10 | + | |
11 | + @classmethod | |
12 | + def layer_to_feature_collection(cls,layer,limit=None): | |
13 | + ''' | |
14 | + 图层转feature collection | |
15 | + :param layer: | |
16 | + :param limit: 读取限制数 | |
17 | + :return: | |
18 | + ''' | |
19 | + feature_collection = dict() | |
20 | + feature_collection["type"]="FeatureCollection" | |
21 | + feature_collection["features"] = [] | |
22 | + count = 0 | |
23 | + for feature in layer : | |
24 | + feature:Feature = feature | |
25 | + feature_collection["features"].append(json.loads(feature.ExportToJson())) | |
26 | + #超过限制不再读取 | |
27 | + if limit: | |
28 | + if count>limit: | |
29 | + break | |
30 | + return feature_collection | ... | ... |
... | ... | @@ -27,6 +27,11 @@ class PGUtil: |
27 | 27 | |
28 | 28 | @classmethod |
29 | 29 | def get_info_from_sqlachemy_uri(cls,uri): |
30 | + ''' | |
31 | + 解析sqlachemy_uri | |
32 | + :param uri: | |
33 | + :return: | |
34 | + ''' | |
30 | 35 | parts = uri.split(":") |
31 | 36 | user = parts[1][2:] |
32 | 37 | |
... | ... | @@ -51,7 +56,12 @@ class PGUtil: |
51 | 56 | |
52 | 57 | @classmethod |
53 | 58 | def get_geo_column(cls,table_name,db_session): |
59 | + ''' | |
54 | 60 | # 判断空间列 |
61 | + :param table_name: | |
62 | + :param db_session: | |
63 | + :return: | |
64 | + ''' | |
55 | 65 | geom_col_sql = ''' |
56 | 66 | SELECT a.attname AS field,t.typname AS type |
57 | 67 | FROM |
... | ... | @@ -74,7 +84,13 @@ class PGUtil: |
74 | 84 | |
75 | 85 | @classmethod |
76 | 86 | def get_table_count(cls,table_name,db_session): |
77 | - count_result = db_session.execute("SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public.{}'::regclass".format( | |
87 | + ''' | |
88 | + 获取图层数量 | |
89 | + :param table_name: | |
90 | + :param db_session: | |
91 | + :return: | |
92 | + ''' | |
93 | + count_result = db_session.execute('''SELECT reltuples::bigint AS ec FROM pg_class WHERE oid = 'public."{}"'::regclass'''.format( | |
78 | 94 | table_name)).fetchone() |
79 | 95 | count = count_result[0] |
80 | 96 | if count< 1000000: |
... | ... | @@ -84,6 +100,11 @@ class PGUtil: |
84 | 100 | |
85 | 101 | @classmethod |
86 | 102 | def check_space(cls, sqlachemy_uri): |
103 | + ''' | |
104 | + 判断数据库是否为空间库 | |
105 | + :param sqlachemy_uri: | |
106 | + :return: | |
107 | + ''' | |
87 | 108 | system_session = None |
88 | 109 | check = True |
89 | 110 | try: | ... | ... |
app/util/component/WMSTest.py
0 → 100644
1 | +# coding=utf-8 | |
2 | +#author: 4N | |
3 | +#createtime: 2021/8/18 | |
4 | +#email: nheweijun@sina.com | |
5 | +import random | |
6 | + | |
7 | +def create(extent,example:dict,path,num): | |
8 | + with open(path, 'w') as f: | |
9 | + each_num = int(num/len(example.keys())) | |
10 | + for i in range(each_num): | |
11 | + for ext in example.values(): | |
12 | + x_leng = ext[2] - ext[0] | |
13 | + y_leng = ext[3] - ext[1] | |
14 | + randomx = random.random() * (extent[2] - extent[0]) + extent[0] | |
15 | + randomy = random.random() * (extent[3] - extent[1]) + extent[1] | |
16 | + | |
17 | + wms = [randomx, randomy, randomx + x_leng, randomy + y_leng] | |
18 | + wms = [str(x) for x in wms] | |
19 | + f.write(",".join(wms)) | |
20 | + f.write("\n") | |
21 | + | |
22 | + | |
23 | + | |
24 | +if __name__ == '__main__': | |
25 | + extent=[113.060008,22.765613,115.062014,24.470024] | |
26 | + | |
27 | + example={"10km":[114.2578125, 23.37890625, 114.43359375, 23.5546875], | |
28 | + "5km": [113.73046875, 23.466796875, 113.818359375, 23.5546875], | |
29 | + "3km": [114.1259765625, 23.466796875, 114.169921875, 23.5107421875], | |
30 | + "1km": [113.97216796875, 23.48876953125, 113.994140625, 23.5107421875], | |
31 | + "500m": [113.97216796875, 23.499755859375, 113.983154296875, 23.5107421875], | |
32 | + "300m": [113.9886474609375,23.5107421875,113.994140625,23.5162353515625], | |
33 | + "200m":[113.9776611328125,23.51348876953125,113.98040771484375,23.5162353515625], | |
34 | + "100m":[113.98590087890625,23.52447509765625,113.98727416992188,23.525848388671875], | |
35 | + "50":[113.983154296875,23.530654907226562,113.98384094238281,23.531341552734375]} | |
36 | + path = "wms.bat" | |
37 | + num = 100000 | |
38 | + create(extent,example,path,num) | |
\ No newline at end of file | ... | ... |
app/util/component/WMTSTest.py
0 → 100644
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | deploy_ip_host = "172.26.99.160:8840" |
5 | 5 | # 系统数据库 |
6 | 6 | |
7 | -SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@172.26.40.254:5433/dmap_dms_test" | |
8 | -# SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.99.160:5432/dmap_dms_test" | |
7 | +# SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@172.26.40.254:5433/dmap_dms_test" | |
8 | +SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.99.160:5432/dmap_dms_test" | |
9 | 9 | |
10 | 10 | |
11 | 11 | # 部署模式cluster,standalone | ... | ... |
... | ... | @@ -33,7 +33,7 @@ IncludeOptional conf.d/*.conf |
33 | 33 | LoadModule wsgi_module "/usr/lib/apache2/modules/mod_wsgi-py39.cpython-39-x86_64-linux-gnu.so" |
34 | 34 | WSGIPythonHome "/usr" |
35 | 35 | |
36 | -WSGIScriptAlias / /usr/DMapManager/run.wsgi | |
36 | +WSGIScriptAlias /DMapManager /usr/DMapManager/run.wsgi | |
37 | 37 | <Directory /usr/> |
38 | 38 | Require all granted |
39 | 39 | </Directory> |
\ No newline at end of file | ... | ... |
... | ... | @@ -9,12 +9,25 @@ import numpy |
9 | 9 | import gzip |
10 | 10 | import sys |
11 | 11 | import json |
12 | -pixel_array = numpy.empty((256,256,3),dtype=int)+3 | |
12 | +# pixel_array = numpy.empty((256,256,3),dtype=int)+3 | |
13 | +# | |
14 | +# | |
15 | +# | |
16 | +# # 使用gzip 压缩传输 | |
17 | +# content = gzip.compress(pixel_array, 2) | |
18 | +# | |
19 | +# print(sys.getsizeof(json.dumps(pixel_array.tolist()))) | |
20 | +# print(sys.getsizeof((content))) | |
13 | 21 | |
22 | +def c(dd): | |
23 | + return 1 | |
14 | 24 | |
25 | +dd = numpy.zeros((2000, 2000), dtype=int) + 2 | |
15 | 26 | |
16 | -# 使用gzip 压缩传输 | |
17 | -content = gzip.compress(pixel_array, 2) | |
18 | 27 | |
19 | -print(sys.getsizeof(json.dumps(pixel_array.tolist()))) | |
20 | -print(sys.getsizeof((content))) | |
\ No newline at end of file | ||
28 | +dd[range(0, 5), 1]=1 | |
29 | + | |
30 | + | |
31 | + | |
32 | + | |
33 | +print(dd) | |
\ No newline at end of file | ... | ... |
请
注册
或
登录
后发表评论