feature_query.py
4.0 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# coding=utf-8
# author: 4N
# createtime: 2021/8/4
# email: nheweijun@sina.com
import datetime
from app.modules.data.models import Table,Database
from app.util.component.ApiTemplate import ApiTemplate
from app.util.component.GeometryAdapter import GeometryAdapter
from app.util.component.LayerUtil import LayerUtil
from app.util.component.PGUtil import PGUtil
from osgeo.ogr import Geometry,Layer,DataSource,Feature
from app.models import DES
import json
import gzip
from flask import make_response
class Api(ApiTemplate):
api_name = "空间查询"
def para_check(self):
pass
def process(self):
res = {}
pg_ds:DataSource = None
try:
table:Table = Table.query.filter_by(guid=self.para.get("guid")).one_or_none()
if not table:
raise Exception("数据不存在!")
if table.table_type == 0:
raise Exception("非空间数据!")
database:Database = table.relate_database
pg_ds:DataSource = PGUtil.open_pg_data_source(0,DES.decode(database.sqlalchemy_uri))
layer:Layer = pg_ds.GetLayerByName(table.name)
#空间查询
if self.para.get("bbox"):
bbox:Geometry = GeometryAdapter.envelop_2_polygon([float(x) for x in self.para.get("bbox").split(",")])
layer.SetSpatialFilter(bbox)
#属性查询
if self.para.get("filter"):
conditions = json.loads(self.para.get("filter"))
filter_conds = []
for cond in conditions:
if cond["type"].__eq__("range"):
filter_conds.append("{}>{} AND {}<{}".format(cond["name"],cond["lower"],
cond["name"], cond["higher"]))
if cond["type"].__eq__("value"):
try:
val = float(cond["value"])
filter_conds.append("{}={}".format(cond["name"], val))
except:
filter_conds.append("{} like '%{}%'".format(cond["name"], cond["value"]))
if cond["type"].__eq__("time"):
filter_conds.append("{} > timestamp '{}' AND {} < timestamp '{}'".format(cond["name"],
cond["lower"],
cond["name"],
cond["higher"]))
layer.SetAttributeFilter(" AND ".join(filter_conds))
feature_collection = LayerUtil.layer_to_feature_collection(layer,limit=1000)
res["data"] = feature_collection
res["result"] = True
except Exception as e:
raise e
finally:
if pg_ds:
pg_ds.Destroy()
# 使用gzip 压缩传输
content = gzip.compress(bytes('{}'.format(json.dumps(res,ensure_ascii=False)), 'utf-8'), 2)
response = make_response(content)
response.headers['Content-length'] = len(content)
response.headers['Content-Encoding'] = 'gzip'
return response
api_doc={
"tags":["要素接口"],
"parameters":[
{"name": "guid",
"in": "formData",
"type": "string",
"description": "guid"},
{"name": "bbox",
"in": "formData",
"type": "string",
"description": "bbox"},
{"name": "filter",
"in": "formData",
"type": "string",
"description": "filter"}
],
"responses":{
200:{
"schema":{
"properties":{
}
}
}
}
}