提交 380261be7c46485db374f03801854c0d7bcaba17
Merge branch 'master' of http://gitlab.ctune.cn/DMapServer/DMapServer4.1
正在显示
62 个修改的文件
包含
4955 行增加
和
523 行删除
... | ... | @@ -11,21 +11,22 @@ |
11 | 11 | #include "dmpvectorlayerrenderer.h" |
12 | 12 | #include "dmpproviderregistry.h" |
13 | 13 | #include "libpq-fe.h" |
14 | +#include "clsUtil.h" | |
15 | +#include <boost/algorithm/string/predicate.hpp> | |
14 | 16 | |
15 | 17 | DmpVectorLayer::DmpVectorLayer(const std::string &path, |
16 | - const std::string &baseName, | |
17 | - const std::string &providerKey, | |
18 | - const DmpVectorLayer::LayerOptions &options) | |
19 | - : DmpMapLayer(DmpMapLayerType::VectorLayer, baseName, path) | |
20 | - , readExtentFromXml_(options.readExtentFromXml) | |
18 | + const std::string &baseName, | |
19 | + const std::string &providerKey, | |
20 | + const DmpVectorLayer::LayerOptions &options) | |
21 | + : DmpMapLayer(DmpMapLayerType::VectorLayer, baseName, path), readExtentFromXml_(options.readExtentFromXml) | |
21 | 22 | { |
22 | - wkbType_ = options.fallbackWkbType; | |
23 | - setProviderType(providerKey); | |
23 | + wkbType_ = options.fallbackWkbType; | |
24 | + setProviderType(providerKey); | |
24 | 25 | |
25 | - if (!path.empty() && !providerKey.empty()) | |
26 | - { | |
27 | - setDataSource(path, baseName, providerKey, options.loadDefaultStyle ); | |
28 | - } | |
26 | + if (!path.empty() && !providerKey.empty()) | |
27 | + { | |
28 | + setDataSource(path, baseName, providerKey, options.loadDefaultStyle); | |
29 | + } | |
29 | 30 | } |
30 | 31 | |
31 | 32 | DmpVectorLayer::~DmpVectorLayer() |
... | ... | @@ -34,147 +35,254 @@ DmpVectorLayer::~DmpVectorLayer() |
34 | 35 | |
35 | 36 | DmpMapLayerRenderer *DmpVectorLayer::createMapRenderer(DmpRenderContext &rendererContext) |
36 | 37 | { |
37 | - return new DmpVectorLayerRenderer(this, rendererContext); | |
38 | + return new DmpVectorLayerRenderer(this, rendererContext); | |
38 | 39 | } |
39 | 40 | |
40 | 41 | bool DmpVectorLayer::readXml(const boost::property_tree::ptree &layerNode) |
41 | 42 | { |
42 | - //id="gzxxd_aabe200b_5b63_4b82_8546_af1fc99e4ec6" name="gzxxd" alias="中学" type="1" | |
43 | - // geometry="Point" alwaysShow="true" maxScale="0" maxScale="50000" | |
44 | - id_ = layerNode.get<std::string>("<xmlattr>.id"); | |
45 | - name_ = layerNode.get<std::string>("<xmlattr>.name"); | |
46 | - title_ = layerNode.get<std::string>("<xmlattr>.alias"); | |
47 | - boost::property_tree::ptree pExtent = layerNode.get_child("extent"); | |
48 | - extent_ = DmpXmlUtils::readRectangle(pExtent); | |
49 | - dataSource_ = layerNode.get<std::string>("datasource"); | |
50 | - | |
51 | - setDataProvider("postgres"); | |
52 | - | |
53 | - // boost::property_tree::ptree pResourceMetadata = layerNode.get_child("resourcemetadata"); | |
54 | - // schema_ = layerNode.get<std::string>("schema"); | |
55 | - // geom_ = layerNode.get<std::string>("geom"); | |
56 | - // featurecount_ = layerNode.get<unsigned int>("featurecount"); | |
57 | - | |
58 | - boost::property_tree::ptree ptRenderer = layerNode.get_child("renderer"); | |
59 | - auto pIter = ptRenderer.begin(); | |
60 | - if(pIter == ptRenderer.end())return false; | |
61 | - DmapCore_30::Renderer* renderer_30 = nullptr; | |
62 | - DmapCore_30::clsXML::XMLParse(pIter->first, pIter->second, &renderer_30); | |
63 | - renderer_30_ = shared_ptr<DmapCore_30::Renderer>(renderer_30); | |
64 | - | |
65 | - // geom_ = "geom"; | |
66 | - // schema_ = "public"; | |
67 | - // wkbType_ = DmpWkbTypes::MultiLineString; | |
68 | - | |
69 | - return true; | |
43 | + //id="gzxxd_aabe200b_5b63_4b82_8546_af1fc99e4ec6" name="gzxxd" alias="中学" type="1" | |
44 | + // geometry="Point" alwaysShow="true" maxScale="0" maxScale="50000" | |
45 | + id_ = layerNode.get<std::string>("<xmlattr>.id"); | |
46 | + name_ = layerNode.get<std::string>("<xmlattr>.name"); | |
47 | + title_ = layerNode.get<std::string>("<xmlattr>.alias"); | |
48 | + boost::property_tree::ptree pExtent = layerNode.get_child("extent"); | |
49 | + extent_ = DmpXmlUtils::readRectangle(pExtent); | |
50 | + dataSource_ = layerNode.get<std::string>("datasource"); | |
51 | + | |
52 | + if (!setDataProvider(dataSource_)) | |
53 | + { | |
54 | + schema_ = layerNode.get<std::string>("<xmlattr>.schema"); | |
55 | + geom_ = layerNode.get<std::string>("<xmlattr>.geomfield"); | |
56 | + wkbTypeString_ = layerNode.get<std::string>("<xmlattr>.geometry"); | |
57 | + featurecount_ = layerNode.get<unsigned int>("<xmlattr>.featurecount"); | |
58 | + srid_ = layerNode.get<std::string>("<xmlattr>.srid"); | |
59 | + } | |
60 | + | |
61 | + if (boost::iequals(wkbTypeString_, "POINT")) | |
62 | + wkbType_ = DmpWkbTypes::Point; | |
63 | + else if (boost::iequals(wkbTypeString_, "MULTIPOINT")) | |
64 | + wkbType_ = DmpWkbTypes::MultiPoint; | |
65 | + else if (boost::iequals(wkbTypeString_, "LINESTRING")) | |
66 | + wkbType_ = DmpWkbTypes::LineString; | |
67 | + else if (boost::iequals(wkbTypeString_, "MULTILINESTRING")) | |
68 | + wkbType_ = DmpWkbTypes::MultiLineString; | |
69 | + else if (boost::iequals(wkbTypeString_, "POLYGON")) | |
70 | + wkbType_ = DmpWkbTypes::Polygon; | |
71 | + else if (boost::iequals(wkbTypeString_, "MULTIPOLYGON")) | |
72 | + wkbType_ = DmpWkbTypes::MultiPolygon; | |
73 | + else if (boost::iequals(wkbTypeString_, "GEOMETRY")) | |
74 | + wkbType_ = DmpWkbTypes::Unknown; | |
75 | + | |
76 | + boost::property_tree::ptree ptRenderer = layerNode.get_child("renderer"); | |
77 | + auto pIter = ptRenderer.begin(); | |
78 | + if (pIter == ptRenderer.end()) | |
79 | + return false; | |
80 | + DmapCore_30::Renderer *renderer_30 = nullptr; | |
81 | + DmapCore_30::clsXML::XMLParse(pIter->first, pIter->second, &renderer_30); | |
82 | + renderer_30_ = shared_ptr<DmapCore_30::Renderer>(renderer_30); | |
83 | + | |
84 | + // geom_ = "geom"; | |
85 | + // schema_ = "public"; | |
86 | + // wkbType_ = DmpWkbTypes::MultiLineString; | |
87 | + | |
88 | + return true; | |
70 | 89 | } |
71 | 90 | |
72 | 91 | bool DmpVectorLayer::writeXml(boost::property_tree::ptree &layerNode) |
73 | 92 | { |
74 | - layerNode.add("<xmlattr>.id", id_); | |
75 | - layerNode.add("<xmlattr>.name", name_); | |
76 | - layerNode.add("<xmlattr>.alias", title_); | |
77 | - | |
78 | - | |
79 | - boost::property_tree::ptree ptExtent; | |
80 | - ptExtent.add("xmin", extent_.xmin()); | |
81 | - ptExtent.add("ymin", extent_.ymin()); | |
82 | - ptExtent.add("xmax", extent_.xmax()); | |
83 | - ptExtent.add("ymax", extent_.ymax()); | |
84 | - layerNode.add_child("extent", ptExtent); | |
85 | - | |
86 | - layerNode.add("datasource", dataSource_); | |
87 | - boost::property_tree::ptree ptRenderer; | |
88 | - if(this->renderer_30_) | |
89 | - { | |
90 | - this->renderer_30_->ParsePtree(ptRenderer); | |
91 | - } | |
92 | - layerNode.add_child("renderer",ptRenderer); | |
93 | - | |
94 | - return true; | |
93 | + layerNode.add("<xmlattr>.id", id_); | |
94 | + layerNode.add("<xmlattr>.name", name_); | |
95 | + layerNode.add("<xmlattr>.alias", title_); | |
96 | + | |
97 | + boost::property_tree::ptree ptExtent; | |
98 | + ptExtent.add("xmin", extent_.xmin()); | |
99 | + ptExtent.add("ymin", extent_.ymin()); | |
100 | + ptExtent.add("xmax", extent_.xmax()); | |
101 | + ptExtent.add("ymax", extent_.ymax()); | |
102 | + layerNode.add_child("extent", ptExtent); | |
103 | + | |
104 | + layerNode.add("datasource", dataSource_); | |
105 | + boost::property_tree::ptree ptRenderer; | |
106 | + if (this->renderer_30_) | |
107 | + { | |
108 | + this->renderer_30_->ParsePtree(ptRenderer); | |
109 | + } | |
110 | + layerNode.add_child("renderer", ptRenderer); | |
111 | + | |
112 | + return true; | |
95 | 113 | } |
96 | 114 | |
97 | -void DmpVectorLayer::setRenderer(DmpFeatureRenderer *renderer) | |
115 | +bool DmpVectorLayer::writejson(std::string &json) | |
98 | 116 | { |
117 | + string shapeTypeString = "UNKNOWORD"; | |
118 | + | |
119 | + switch (wkbType_) | |
120 | + { | |
121 | + case DmpWkbTypes::Point: | |
122 | + shapeTypeString = "POINT"; | |
123 | + break; | |
124 | + case DmpWkbTypes::MultiPoint: | |
125 | + shapeTypeString = "MULTIPOINT"; | |
126 | + break; | |
127 | + case DmpWkbTypes::LineString: | |
128 | + shapeTypeString = "LINESTRING"; | |
129 | + break; | |
130 | + case DmpWkbTypes::MultiLineString: | |
131 | + shapeTypeString = "MULTILINESTRING"; | |
132 | + break; | |
133 | + case DmpWkbTypes::Polygon: | |
134 | + shapeTypeString = "POLYGON"; | |
135 | + break; | |
136 | + case DmpWkbTypes::MultiPolygon: | |
137 | + shapeTypeString = "MULTIPOLYGON"; | |
138 | + break; | |
139 | + default: | |
140 | + shapeTypeString = "UNKNOWORD"; | |
141 | + break; | |
142 | + } | |
143 | + | |
144 | + bool alwaysShow = this->minScale() == 0 && this->maxScale() > 10000000000; | |
145 | + char buff_maxscale[100]; | |
146 | + char buff_minscale[100]; | |
147 | + if (this->maxScale() > 100000000) | |
148 | + { | |
149 | + sprintf(buff_maxscale, "%e", this->maxScale()); | |
150 | + } | |
151 | + else | |
152 | + { | |
153 | + sprintf(buff_maxscale, "%.0f", this->maxScale()); | |
154 | + } | |
155 | + | |
156 | + if (this->minScale() > 100000000) | |
157 | + { | |
158 | + sprintf(buff_minscale, "%e", this->minScale()); | |
159 | + } | |
160 | + else | |
161 | + { | |
162 | + sprintf(buff_minscale, "%.0f", this->minScale()); | |
163 | + } | |
164 | + //Display scale setting type="1" geometry="Point" alwaysShow="true" maxScale="0" maxScale="50000"> | |
165 | + char resultbuff[1000]; | |
166 | + string json_source = this->source(); | |
167 | + DmapCore_30::clsUtil::ToJSONString(json_source); | |
168 | + sprintf(resultbuff, | |
169 | + R"({"workspace":"","type":"1","dbsource":"%s","data":"","schema":"%s","alias":"%s","name":"%s","id":"%s","filter":"%s","visible":"%s","tag":"","minScale":"%s","maxScale":"%s","geometry":"%s","alwaysShow":"%s")", | |
170 | + json_source.c_str(), | |
171 | + this->schema().c_str(), | |
172 | + this->title().c_str(), | |
173 | + this->name().c_str(), | |
174 | + this->id().c_str(), | |
175 | + this->wherestr_.c_str(), | |
176 | + "true", | |
177 | + buff_minscale, buff_maxscale, | |
178 | + shapeTypeString.c_str(), | |
179 | + alwaysShow ? "true" : "false"); | |
180 | + | |
181 | + json.append(resultbuff); | |
182 | + if (this->renderer_30_ != nullptr) | |
183 | + { | |
184 | + | |
185 | + json.append(","); | |
186 | + DmapCore_30::AppendBuffer ab; | |
187 | + this->renderer_30_->ToJson(&ab); | |
188 | + json.append(ab.GetString()); | |
189 | + } | |
190 | + json.append("}"); | |
191 | + return true; | |
192 | +} | |
99 | 193 | |
194 | +void DmpVectorLayer::setRenderer(DmpFeatureRenderer *renderer) | |
195 | +{ | |
100 | 196 | } |
101 | 197 | |
102 | 198 | void DmpVectorLayer::setDataSource(const std::string &dataSource, const std::string &baseName, const std::string &provider, bool loadDefaultStyleFlag) |
103 | 199 | { |
104 | - DmpWkbTypes::GeometryType geomType = GeometryType(); | |
200 | + DmpWkbTypes::GeometryType geomType = GeometryType(); | |
105 | 201 | } |
106 | 202 | |
107 | 203 | DmpWkbTypes::GeometryType DmpVectorLayer::GeometryType() const |
108 | 204 | { |
109 | - return DmpWkbTypes::GeometryType(wkbType_); | |
205 | + return DmpWkbTypes::GeometryType(wkbType_); | |
110 | 206 | } |
111 | 207 | |
112 | -bool DmpVectorLayer::setDataProvider(std::string const &provider) | |
208 | +bool DmpVectorLayer::setDataProvider(const std::string &provider) | |
113 | 209 | { |
114 | - //临时测试使用 | |
115 | - PGconn* pPGconn = PQconnectdb(dataSource_.c_str()); | |
210 | + if (provider.size() < 50) | |
211 | + return false; | |
212 | + isinit_ = true; | |
213 | + //临时测试使用 | |
214 | + PGconn *pPGconn = PQconnectdb(provider.c_str()); | |
116 | 215 | ConnStatusType t = PQstatus(pPGconn); |
117 | 216 | if (t != CONNECTION_OK) |
118 | - return false; | |
217 | + return false; | |
119 | 218 | int re = PQsetClientEncoding(pPGconn, "UTF-8"); |
120 | 219 | |
121 | - std::string sql = "select t.f_geometry_column, t.type ,f_table_schema,t.srid from public.geometry_columns t where lower( t.f_table_name) = lower('" + name_ + "');"; | |
122 | - PGresult* pPGresult= PQexec(pPGconn, sql.c_str()); | |
220 | + std::string sql = "select t.f_geometry_column, t.type ,f_table_schema,t.srid from public.geometry_columns t where lower( t.f_table_name) = lower('" + name_ + "');"; | |
221 | + PGresult *pPGresult = PQexec(pPGconn, sql.c_str()); | |
123 | 222 | char *sz = PQerrorMessage(pPGconn); |
124 | - if(sz != nullptr && strcmp(sz,"") !=0) | |
125 | - { | |
126 | - PQfinish(pPGconn); return false; | |
127 | - } | |
128 | - | |
129 | - int rowCount = PQntuples(pPGresult); | |
130 | - if(rowCount<1) | |
131 | - { | |
132 | - PQfinish(pPGconn); return false; | |
133 | - } | |
134 | - | |
135 | - geom_ = PQgetvalue(pPGresult, 0, 0); | |
136 | - const char* geomtype = PQgetvalue(pPGresult, 0, 1); | |
137 | - schema_ = PQgetvalue(pPGresult, 0, 2); | |
138 | - //std::string srid = PQgetvalue(pPGresult, 0, 3); | |
139 | - | |
223 | + if (sz != nullptr && strcmp(sz, "") != 0) | |
224 | + { | |
225 | + PQfinish(pPGconn); | |
226 | + return false; | |
227 | + } | |
228 | + | |
229 | + int rowCount = PQntuples(pPGresult); | |
230 | + if (rowCount < 1) | |
231 | + { | |
232 | + PQfinish(pPGconn); | |
233 | + return false; | |
234 | + } | |
235 | + | |
236 | + geom_ = PQgetvalue(pPGresult, 0, 0); | |
237 | + const char *geomtype = PQgetvalue(pPGresult, 0, 1); | |
238 | + schema_ = PQgetvalue(pPGresult, 0, 2); | |
239 | + std::string srid = PQgetvalue(pPGresult, 0, 3); | |
240 | + wkbTypeString_ = geomtype; | |
241 | + srid_ = srid; | |
140 | 242 | if (!geomtype) |
141 | 243 | return false; |
142 | - if (!strcmp(geomtype, "POINT")) wkbType_ = DmpWkbTypes::Point; | |
143 | - else if (!strcmp(geomtype, "MULTIPOINT")) wkbType_ = DmpWkbTypes::MultiPoint; | |
144 | - else if (!strcmp(geomtype, "LINESTRING")) wkbType_ = DmpWkbTypes::LineString; | |
145 | - else if (!strcmp(geomtype, "MULTILINESTRING"))wkbType_ = DmpWkbTypes::MultiLineString; | |
146 | - else if (!strcmp(geomtype, "POLYGON")) wkbType_ = DmpWkbTypes::Polygon; | |
147 | - else if (!strcmp(geomtype, "MULTIPOLYGON")) wkbType_ = DmpWkbTypes::MultiPolygon; | |
148 | - else if (!strcmp(geomtype, "GEOMETRY")) wkbType_ = DmpWkbTypes::Unknown; | |
149 | - PQclear(pPGresult); pPGresult = NULL; | |
244 | + if (!strcmp(geomtype, "POINT")) | |
245 | + wkbType_ = DmpWkbTypes::Point; | |
246 | + else if (!strcmp(geomtype, "MULTIPOINT")) | |
247 | + wkbType_ = DmpWkbTypes::MultiPoint; | |
248 | + else if (!strcmp(geomtype, "LINESTRING")) | |
249 | + wkbType_ = DmpWkbTypes::LineString; | |
250 | + else if (!strcmp(geomtype, "MULTILINESTRING")) | |
251 | + wkbType_ = DmpWkbTypes::MultiLineString; | |
252 | + else if (!strcmp(geomtype, "POLYGON")) | |
253 | + wkbType_ = DmpWkbTypes::Polygon; | |
254 | + else if (!strcmp(geomtype, "MULTIPOLYGON")) | |
255 | + wkbType_ = DmpWkbTypes::MultiPolygon; | |
256 | + else if (!strcmp(geomtype, "GEOMETRY")) | |
257 | + wkbType_ = DmpWkbTypes::Unknown; | |
258 | + PQclear(pPGresult); | |
259 | + pPGresult = NULL; | |
150 | 260 | PQfinish(pPGconn); |
151 | - | |
152 | - return true; | |
153 | - | |
154 | - | |
155 | - providerKey_ = provider; | |
156 | - delete dataProvider_; | |
157 | - | |
158 | - dataProvider_ = dynamic_cast<DmpVectorDataProvider *>(DmpProviderRegistry::Instance(provider)->CreateProvider(provider, dataSource_)); | |
159 | - if (!dataProvider_) | |
160 | - { | |
161 | - isValid_ = false; | |
162 | - return false; | |
163 | - } | |
164 | - isValid_ = dataProvider_->IsValid() | |
165 | - ; | |
166 | - if (!isValid_) | |
167 | - { | |
168 | - return false; | |
169 | - } | |
170 | - wkbType_ = dataProvider_->WkbType(); | |
171 | - return true; | |
172 | -} | |
173 | 261 | |
174 | - shared_ptr<DmpVectorThinLayer> DmpVectorLayer::GetCurrentScaleTable(double dx) | |
262 | + return true; | |
263 | + | |
264 | + providerKey_ = provider; | |
265 | + delete dataProvider_; | |
266 | + | |
267 | + dataProvider_ = dynamic_cast<DmpVectorDataProvider *>(DmpProviderRegistry::Instance(provider)->CreateProvider(provider, dataSource_)); | |
268 | + if (!dataProvider_) | |
269 | + { | |
270 | + isValid_ = false; | |
271 | + return false; | |
272 | + } | |
273 | + isValid_ = dataProvider_->IsValid(); | |
274 | + if (!isValid_) | |
175 | 275 | { |
176 | - | |
177 | -/* | |
276 | + return false; | |
277 | + } | |
278 | + wkbType_ = dataProvider_->WkbType(); | |
279 | + return true; | |
280 | +} | |
281 | + | |
282 | +shared_ptr<DmpVectorThinLayer> DmpVectorLayer::GetCurrentScaleTable(double dx) | |
283 | +{ | |
284 | + | |
285 | + /* | |
178 | 286 | int outTime = 600; |
179 | 287 | if(this->dataCount >500000 && this->m_pDataset->m_MapLayerThinning.size() ==0) |
180 | 288 | { |
... | ... | @@ -197,14 +305,14 @@ bool DmpVectorLayer::setDataProvider(std::string const &provider) |
197 | 305 | } |
198 | 306 | */ |
199 | 307 | |
200 | - for(int i =0; i< this->thinLayers_.size(); i++) | |
201 | - { | |
202 | - shared_ptr<DmpVectorThinLayer> mapLayerThinning = this->thinLayers_[i]; | |
308 | + for (int i = 0; i < this->thinLayers_.size(); i++) | |
309 | + { | |
310 | + shared_ptr<DmpVectorThinLayer> mapLayerThinning = this->thinLayers_[i]; | |
203 | 311 | |
204 | - if(mapLayerThinning->IsCurrentLayer(dx)) | |
205 | - { | |
206 | - return mapLayerThinning; | |
207 | - } | |
312 | + if (mapLayerThinning->IsCurrentLayer(dx)) | |
313 | + { | |
314 | + return mapLayerThinning; | |
208 | 315 | } |
209 | - return nullptr; | |
210 | - } | |
\ No newline at end of file | ||
316 | + } | |
317 | + return nullptr; | |
318 | +} | |
\ No newline at end of file | ... | ... |
... | ... | @@ -44,6 +44,7 @@ class CORE_EXPORT DmpVectorLayer : public DmpMapLayer |
44 | 44 | DmpMapLayerRenderer *createMapRenderer(DmpRenderContext &rendererContext); |
45 | 45 | bool readXml(const boost::property_tree::ptree &layerNode); |
46 | 46 | bool writeXml(boost::property_tree::ptree &layerNode); |
47 | + bool writejson(std::string& json); | |
47 | 48 | |
48 | 49 | DmpFeatureRenderer *renderer() { return renderer_; } |
49 | 50 | void setRenderer(DmpFeatureRenderer *renderer); |
... | ... | @@ -59,7 +60,10 @@ class CORE_EXPORT DmpVectorLayer : public DmpMapLayer |
59 | 60 | std::string schema() { return schema_;} |
60 | 61 | std::string geom() { return geom_;} |
61 | 62 | std::string wherestr() { return wherestr_;} |
63 | + std::string GeomTypeString(){return wkbTypeString_;} | |
64 | + std::string srid(){return srid_;} | |
62 | 65 | size_t featurecount(){return featurecount_;} |
66 | + bool IsInit(){return isinit_;} | |
63 | 67 | private: |
64 | 68 | bool readExtentFromXml_; |
65 | 69 | DmpWkbTypes::Type wkbType_ = DmpWkbTypes::Unknown; |
... | ... | @@ -69,10 +73,15 @@ class CORE_EXPORT DmpVectorLayer : public DmpMapLayer |
69 | 73 | std::string schema_; |
70 | 74 | std::string geom_; |
71 | 75 | size_t featurecount_; |
76 | + std::string wkbTypeString_; | |
77 | + std::string srid_; | |
72 | 78 | |
73 | 79 | std::string wherestr_; |
80 | + bool isinit_ = false; | |
74 | 81 | shared_ptr<DmapCore_30::Renderer> renderer_30_ = nullptr; |
75 | 82 | vector<shared_ptr<DmpVectorThinLayer>> thinLayers_; |
83 | + | |
84 | + | |
76 | 85 | |
77 | 86 | }; |
78 | 87 | #endif //__dmpvectorlayer_h__ | ... | ... |
... | ... | @@ -53,22 +53,34 @@ namespace DmapCore_30 |
53 | 53 | for (auto ptchild = pt.begin(); ptchild != pt.end(); ++ptchild) |
54 | 54 | { |
55 | 55 | string sz = ptchild->first; |
56 | + | |
56 | 57 | if (boost::iequals(sz, "OTHER")) |
57 | 58 | { |
58 | - //rapidxml::xml_node<char>* node2 = node1->first_node(); | |
59 | - clsXML::XMLParse(ptchild->first,ptchild->second, &m_pDefaultSymbol); | |
59 | + for(auto ptchild2 = ptchild->second.begin(); ptchild2 != ptchild->second.end(); ptchild2++) | |
60 | + { | |
61 | + if(ptchild2->first != "<xmlattr>") | |
62 | + { | |
63 | + clsXML::XMLParse(ptchild2->first,ptchild2->second, &m_pDefaultSymbol); | |
64 | + break; | |
65 | + } | |
66 | + } | |
67 | + | |
60 | 68 | } |
61 | 69 | else if (boost::iequals(sz, "EXACT")) |
62 | 70 | { |
63 | 71 | string sValue = clsXML::XMLGetPropByString(ptchild->second, "value"); |
64 | - | |
65 | - //rapidxml::xml_node<char>* node2 = node1->first_node();//exact 只有一个子节点 ,存着简单样 | |
66 | - Renderer* pSymbol = NULL; | |
67 | - clsXML::XMLParse(ptchild->first, ptchild->second, &pSymbol); | |
68 | - | |
69 | - ValueMapRendererComponent* vmrc = new ValueMapRendererComponent(pSymbol, sValue); | |
70 | - | |
71 | - m_vComponents.push_back(vmrc);//引用只需要一份, 无需AddRef | |
72 | + //auto ptchild2 = ptchild->second.begin(); | |
73 | + for(auto ptchild2 = ptchild->second.begin(); ptchild2 != ptchild->second.end(); ptchild2++) | |
74 | + { | |
75 | + if (ptchild2->first != "<xmlattr>") | |
76 | + { | |
77 | + Renderer *pSymbol = NULL; | |
78 | + clsXML::XMLParse(ptchild2->first, ptchild2->second, &pSymbol); | |
79 | + ValueMapRendererComponent *vmrc = new ValueMapRendererComponent(pSymbol, sValue); | |
80 | + m_vComponents.push_back(vmrc); //引用只需要一份, 无需AddRef | |
81 | + break; | |
82 | + } | |
83 | + } | |
72 | 84 | } |
73 | 85 | else{ ; } |
74 | 86 | } | ... | ... |
... | ... | @@ -587,6 +587,104 @@ namespace DmapCore_30 |
587 | 587 | *bValue = false; |
588 | 588 | } |
589 | 589 | |
590 | + | |
591 | + void clsUtil::ToXMLString(std::string &s) | |
592 | + { | |
593 | + const char *str1 = s.c_str(); | |
594 | + if (strstr(str1, "&")) | |
595 | + { | |
596 | + s = clsUtil::CharReplace(s, "&", "&"); | |
597 | + str1 = s.c_str(); | |
598 | + } | |
599 | + if (strstr(str1, "<")) | |
600 | + { | |
601 | + s = clsUtil::CharReplace(s, "<", "<"); | |
602 | + str1 = s.c_str(); | |
603 | + } | |
604 | + if (strstr(str1, ">")) | |
605 | + { | |
606 | + s = clsUtil::CharReplace(s, ">", ">"); | |
607 | + str1 = s.c_str(); | |
608 | + } | |
609 | + if (strstr(str1, "\"")) | |
610 | + { | |
611 | + s = clsUtil::CharReplace(s, "\"", """); | |
612 | + str1 = s.c_str(); | |
613 | + } | |
614 | + if (strstr(str1, "\r")) | |
615 | + { | |
616 | + s = clsUtil::CharReplace(s, "\r", ""); | |
617 | + str1 = s.c_str(); | |
618 | + } | |
619 | + if (strstr(str1, "\n")) | |
620 | + { | |
621 | + s = clsUtil::CharReplace(s, "\n", ""); | |
622 | + str1 = s.c_str(); | |
623 | + } | |
624 | + if (strstr(str1, "'")) | |
625 | + { | |
626 | + s = clsUtil::CharReplace(s, "'", "'"); | |
627 | + //str1=s.c_str(); | |
628 | + } | |
629 | + return; | |
630 | + } | |
631 | + | |
632 | + void clsUtil::ToJSONString(std::string &s) | |
633 | + { | |
634 | + const char *str1 = s.c_str(); | |
635 | + if (strstr(str1, "\\")) | |
636 | + { | |
637 | + s = clsUtil::CharReplace(s, "\\", "\\\\"); | |
638 | + str1 = s.c_str(); | |
639 | + } | |
640 | + if (strstr(str1, "/")) | |
641 | + { | |
642 | + s = clsUtil::CharReplace(s, "/", "\\/"); | |
643 | + str1 = s.c_str(); | |
644 | + } | |
645 | + if (strstr(str1, "\"")) | |
646 | + { | |
647 | + s = clsUtil::CharReplace(s, "\"", "\\\""); | |
648 | + str1 = s.c_str(); | |
649 | + } | |
650 | + if (strstr(str1, "\\r")) | |
651 | + { | |
652 | + s = clsUtil::CharReplace(s, "\\r", ""); | |
653 | + str1 = s.c_str(); | |
654 | + } | |
655 | + if (strstr(str1, "\\n")) | |
656 | + { | |
657 | + s = clsUtil::CharReplace(s, "\\n", ""); | |
658 | + str1 = s.c_str(); | |
659 | + } | |
660 | + if (strstr(str1, "\r")) | |
661 | + { | |
662 | + s = clsUtil::CharReplace(s, "\r", ""); | |
663 | + str1 = s.c_str(); | |
664 | + } | |
665 | + if (strstr(str1, "\n")) | |
666 | + { | |
667 | + s = clsUtil::CharReplace(s, "\n", ""); | |
668 | + str1 = s.c_str(); | |
669 | + } | |
670 | + if (strstr(str1, "\t")) | |
671 | + { | |
672 | + s = clsUtil::CharReplace(s, "'", "\\t"); | |
673 | + //str1=s.c_str(); | |
674 | + } | |
675 | + return; | |
676 | + } | |
677 | + | |
678 | + string clsUtil::CharReplace(string strsrc, string strfind, string strrep) | |
679 | + { | |
680 | + for(string::size_type pos(0); pos!=string::npos; pos+=strrep.length()) { | |
681 | + if( (pos=strsrc.find(strfind,pos))!=string::npos ) | |
682 | + strsrc.replace(pos,strfind.length(),strrep); | |
683 | + else break; | |
684 | + } | |
685 | + return strsrc; | |
686 | + } | |
687 | + | |
590 | 688 | std::string clsUtil::fmt(char* fmt, ...) |
591 | 689 | { |
592 | 690 | va_list argptr; | ... | ... |
... | ... | @@ -73,7 +73,11 @@ else { to[index]->Release(); to[index] = from; }\ |
73 | 73 | |
74 | 74 | static void GetFiles(string path, string exd, vector<string> & files); |
75 | 75 | static int ParseStringTok(char * sz, char toK, char ** szPtr, int maxPtr); |
76 | - | |
76 | + | |
77 | + static void ToJSONString(std::string &s); | |
78 | + static void ToXMLString(std::string &s); | |
79 | + static string CharReplace(string strsrc, string strfind, string strrep); | |
80 | + | |
77 | 81 | static std::string fmt(char *, ...); |
78 | 82 | static std::string fmt(const char*, ...); |
79 | 83 | static void ValueString(string * s, bool* bValue); | ... | ... |
... | ... | @@ -32,6 +32,7 @@ SET (DMAP_SERVER_SRCS |
32 | 32 | dmpserverparameters.cpp |
33 | 33 | dmpserverplugins.cpp |
34 | 34 | dmpserverutils.cpp |
35 | + dmpserverdes.cpp | |
35 | 36 | dmpserverloader.cpp |
36 | 37 | dmpserverproject.cpp |
37 | 38 | dmpserverregistry.cpp |
... | ... | @@ -39,7 +40,6 @@ SET (DMAP_SERVER_SRCS |
39 | 40 | python/dmpserverwrapper.cpp |
40 | 41 | dmphttpbase.cpp |
41 | 42 | dmphttputils.cpp |
42 | - | |
43 | 43 | ) |
44 | 44 | |
45 | 45 | SET (DMAP_SERVER_HDRS |
... | ... | @@ -63,6 +63,7 @@ SET (DMAP_SERVER_HDRS |
63 | 63 | dmpserverparameters.h |
64 | 64 | dmpserverplugins.h |
65 | 65 | dmpserverutils.h |
66 | + dmpserverdes.h | |
66 | 67 | dmpservice.h |
67 | 68 | dmpservermodule.h |
68 | 69 | dmpserverloader.h |
... | ... | @@ -71,7 +72,6 @@ SET (DMAP_SERVER_HDRS |
71 | 72 | python/dmppythonutils.h |
72 | 73 | dmphttpbase.h |
73 | 74 | dmphttputils.h |
74 | - | |
75 | 75 | ) |
76 | 76 | |
77 | 77 | ############################################################# | ... | ... |
... | ... | @@ -54,25 +54,25 @@ if (temp_data.find(http_) == 0) { |
54 | 54 | int DmpHttp::DmpHttpBase::buildPostRequest(const std::string& server, const std::string& path, |
55 | 55 | std::ostream& out_request) { |
56 | 56 | // 分割path中的json数据 |
57 | - // std::string temp_path(path), temp_json; | |
58 | - // int json_pos_begin = temp_path.find(HTTP_JSON_BEGIN) + 1; | |
59 | - // int json_pos_end = temp_path.find(HTTP_JSON_END); | |
60 | - // if (json_pos_begin != std::string::npos) { | |
61 | - // // 计算json的长度 | |
62 | - // int temp_json_lenth = std::string::npos; | |
63 | - // if (json_pos_end != temp_json_lenth) { | |
64 | - // temp_json_lenth = (json_pos_end - json_pos_begin); | |
65 | - // } | |
66 | - // temp_json = temp_path.substr(json_pos_begin, temp_json_lenth); | |
67 | - // temp_path = temp_path.substr(0, (json_pos_begin - 1)); | |
68 | - // } | |
69 | - // out_request << "POST " << temp_path.c_str() << " HTTP/1.0\r\n"; | |
70 | - // out_request << "Host: " << server.c_str() << "\r\n"; | |
71 | - // out_request << "Content-Length: " << temp_json.length() << "\r\n"; | |
72 | - // out_request << "Content-Type: application/x-www-form-urlencoded\r\n"; | |
73 | - // out_request << "Accept: */*\r\n"; | |
74 | - // out_request << "Connection: close\r\n\r\n"; | |
75 | - // out_request << temp_json.c_str(); | |
57 | + std::string temp_path(path), temp_json; | |
58 | + int json_pos_begin = temp_path.find(HTTP_JSON_BEGIN) + 1; | |
59 | + int json_pos_end = temp_path.find(HTTP_JSON_END); | |
60 | + if (json_pos_begin != std::string::npos) { | |
61 | + // 计算json的长度 | |
62 | + int temp_json_lenth = std::string::npos; | |
63 | + if (json_pos_end != temp_json_lenth) { | |
64 | + temp_json_lenth = (json_pos_end - json_pos_begin); | |
65 | + } | |
66 | + temp_json = temp_path.substr(json_pos_begin, temp_json_lenth); | |
67 | + temp_path = temp_path.substr(0, (json_pos_begin - 1)); | |
68 | + } | |
69 | + out_request << "POST " << temp_path.c_str() << " HTTP/1.0\r\n"; | |
70 | + out_request << "Host: " << server.c_str() << "\r\n"; | |
71 | + out_request << "Content-Length: " << temp_json.length() << "\r\n"; | |
72 | + out_request << "Content-Type: application/x-www-form-urlencoded\r\n"; | |
73 | + out_request << "Accept: */*\r\n"; | |
74 | + out_request << "Connection: close\r\n\r\n"; | |
75 | + out_request << temp_json.c_str(); | |
76 | 76 | return HTTP_SUCCESS; |
77 | 77 | } |
78 | 78 | ... | ... |
... | ... | @@ -11,8 +11,8 @@ |
11 | 11 | #include <iostream> |
12 | 12 | #include <boost/asio.hpp> |
13 | 13 | namespace DmpHttp |
14 | -{ | |
15 | - #define HTTP_SUCCESS (0) // 操作成功 | |
14 | +{ | |
15 | + #define HTTP_SUCCESS (0) // 操作成功 | |
16 | 16 | #define HTTP_ERROR_UNKNOWN (-1) // 未知的错误 |
17 | 17 | #define HTTP_ERROR_NETWORK (-2) // 网络连接失败 |
18 | 18 | #define HTTP_ERROR_HTTP_HEAD (-3) // 未找到协议头 http || https |
... | ... | @@ -35,6 +35,7 @@ namespace DmpHttp |
35 | 35 | virtual ~DmpHttpBase(); |
36 | 36 | // Post请求 |
37 | 37 | virtual int post(const std::string& url) = 0; |
38 | + virtual int post(const std::string& url, std::string& postData)= 0; | |
38 | 39 | // get请求 |
39 | 40 | virtual int get(const std::string& url) = 0; |
40 | 41 | virtual std::string getResponse(void) = 0; | ... | ... |
... | ... | @@ -18,6 +18,11 @@ int DmpHttp::DmpHttpUtils::post(const std::string& url) |
18 | 18 | handleRequestResolve(url, DmpHttpBase::buildPostRequest); |
19 | 19 | return HTTP_SUCCESS; |
20 | 20 | } |
21 | +int DmpHttp::DmpHttpUtils::post(const std::string& url, std::string& postData) | |
22 | +{ | |
23 | + handleRequestResolve(url,postData, DmpHttpBase::buildPostRequest); | |
24 | + return HTTP_SUCCESS; | |
25 | +} | |
21 | 26 | int DmpHttp::DmpHttpUtils::get(const std::string& url) |
22 | 27 | { |
23 | 28 | handleRequestResolve(url, DmpHttpBase::buildGetRequest); |
... | ... | @@ -47,6 +52,32 @@ void DmpHttp::DmpHttpUtils::handleRequestResolve(const std::string& url, pBuildR |
47 | 52 | } |
48 | 53 | return; |
49 | 54 | } |
55 | +void DmpHttp::DmpHttpUtils::handleRequestResolve(const std::string& url, std::string& postData, pBuildRequest func) | |
56 | +{ | |
57 | + try { | |
58 | + responseData_.clear(); | |
59 | + // 解析URL | |
60 | + std::string server, port,path; | |
61 | + parseUrl(url, server, port, path); | |
62 | + path=postData; | |
63 | + | |
64 | + std::ostream request_stream(&request_); | |
65 | + // 合成请求 | |
66 | + func(server, path, request_stream); | |
67 | + | |
68 | + // 解析服务地址\端口 | |
69 | + boost::asio::ip::tcp::resolver::query query(server, port); | |
70 | + resolver_.async_resolve(query, | |
71 | + boost::bind(&DmpHttpUtils::handleResolve, this, | |
72 | + boost::asio::placeholders::error, | |
73 | + boost::asio::placeholders::iterator)); | |
74 | + } | |
75 | + catch (std::exception& e) { | |
76 | + socket_.close(); | |
77 | + std::cout << "Exception: " << e.what() << "\n"; | |
78 | + } | |
79 | + return; | |
80 | +} | |
50 | 81 | void DmpHttp::DmpHttpUtils::handleResolve(const boost::system::error_code& err, |
51 | 82 | boost::asio::ip::tcp::resolver::iterator endpoint_iterator) { |
52 | 83 | if (err) { |
... | ... | @@ -173,7 +204,14 @@ std::string DmpHttp::post(const std::string &url) { |
173 | 204 | io.run(); |
174 | 205 | return c.getResponse(); |
175 | 206 | } |
176 | - | |
207 | +std::string DmpHttp::post(const std::string& url, std::string& postData) | |
208 | +{ | |
209 | + boost::asio::io_service io; | |
210 | + DmpHttp::DmpHttpUtils c(io); | |
211 | + c.post(url,postData); | |
212 | + io.run(); | |
213 | + return c.getResponse(); | |
214 | +} | |
177 | 215 | std::string DmpHttp::get(const std::string &url) { |
178 | 216 | boost::asio::io_service io; |
179 | 217 | DmpHttp::DmpHttpUtils c(io); | ... | ... |
... | ... | @@ -20,12 +20,14 @@ namespace DmpHttp |
20 | 20 | DmpHttpUtils(boost::asio::io_service& io_service); |
21 | 21 | virtual ~DmpHttpUtils(); |
22 | 22 | virtual int post(const std::string& url); |
23 | + virtual int post(const std::string& url, std::string& postData); | |
23 | 24 | virtual int get(const std::string& url); |
24 | 25 | |
25 | 26 | virtual std::string getResponse(void) {return responseData_;} |
26 | 27 | private: |
27 | 28 | // 建立请求 |
28 | 29 | void handleRequestResolve(const std::string& url, pBuildRequest func); |
30 | + void handleRequestResolve(const std::string& url, std::string& path, pBuildRequest func); | |
29 | 31 | // 解析后 |
30 | 32 | void handleResolve(const boost::system::error_code& err, |
31 | 33 | boost::asio::ip::tcp::resolver::iterator endpoint_iterator); |
... | ... | @@ -52,6 +54,7 @@ namespace DmpHttp |
52 | 54 | std::string responseData_; |
53 | 55 | }; |
54 | 56 | std::string post(const std::string &url); |
57 | + std::string post(const std::string& url, std::string& postData); | |
55 | 58 | std::string get(const std::string &url); |
56 | 59 | } |
57 | 60 | ... | ... |
... | ... | @@ -10,7 +10,7 @@ |
10 | 10 | #include <iostream> |
11 | 11 | #include "dmpserverconfig.h" |
12 | 12 | #include "dmpapplication.h" |
13 | - | |
13 | +#include "dmphttputils.h" | |
14 | 14 | DmpServerConfig::DmpServerConfig() |
15 | 15 | { |
16 | 16 | std::string iniFile = DmpApplication::Instance()->libexecPath() + iniFileName_; |
... | ... | @@ -82,4 +82,14 @@ std::string DmpServerConfig::getValue(const std::string §ion,const std::stri |
82 | 82 | std::cerr << "Exception: " << e.what() << "\n"; |
83 | 83 | } |
84 | 84 | return value; |
85 | +} | |
86 | + | |
87 | +std::string DmpServerConfig::HttpPost(const std::string& url, std::string& postData) | |
88 | +{ | |
89 | + return DmpHttp::post(url, postData); | |
90 | +} | |
91 | + | |
92 | +std::string DmpServerConfig::HttpGet(const std::string& url) | |
93 | +{ | |
94 | + return DmpHttp::get(url); | |
85 | 95 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -22,6 +22,9 @@ public: |
22 | 22 | std::string getPqsqlConnect(); |
23 | 23 | std::string getMetaUrl(); |
24 | 24 | std::string getValue(const std::string §ion,const std::string &key); |
25 | + | |
26 | + std::string HttpPost(const std::string& url, std::string& postData); | |
27 | + std::string HttpGet(const std::string& url); | |
25 | 28 | private: |
26 | 29 | DmpServerConfig(); |
27 | 30 | boost::property_tree::ptree ptIni_; | ... | ... |
src/server/dmpserverdes.cpp
0 → 100644
1 | +/************************************************************************** | |
2 | +* file: dmpserverdes.cpp | |
3 | + | |
4 | +* Author: qingxiongf | |
5 | +* Date: 2022-01-13 19:20:30 | |
6 | +* Email: qingxiongf@chinadci.com | |
7 | +* copyright: 广州城市信息研究所有限公司 | |
8 | +***************************************************************************/ | |
9 | +#include "dmpserverdes.h" | |
10 | +#include "dmpserverutils.h" | |
11 | + | |
12 | +//std::string RsaBase64Encrypt(const std::string &source, const char* key) | |
13 | +//{ | |
14 | +//} | |
15 | + | |
16 | +std::string DmpServerDes::DesBase64Decrypt(const std::string &source, const char* key) | |
17 | +{ | |
18 | + // char key[] = "Chinadci"; | |
19 | + char decry[1000] = {0}; | |
20 | + std::string decbase64_source; | |
21 | + if(!DmpServerUtils::Base64Decode(source, &decbase64_source)) | |
22 | + { | |
23 | + return ""; | |
24 | + } | |
25 | + int size = decbase64_source.size(); | |
26 | + for(; size>0; size--) | |
27 | + { | |
28 | + if(decbase64_source[size-1] != 0)break; | |
29 | + } | |
30 | + DmpServerDes rsa2048; | |
31 | + rsa2048.Decrypt((unsigned char *)decbase64_source.c_str(), size, (unsigned char *)key, (unsigned char *)decry); | |
32 | + for (size_t i = 0; i < strlen(decry) && i < 1000; i++) | |
33 | + { | |
34 | + if (decry[i] == '\b') | |
35 | + { | |
36 | + decry[i] = '\0'; | |
37 | + break; | |
38 | + } | |
39 | + } | |
40 | + return decry; | |
41 | +} | |
42 | + | |
43 | + | |
44 | +void DmpServerDes::generate_key(unsigned char *key) | |
45 | +{ | |
46 | + int i; | |
47 | + for (i = 0; i < 8; i++) | |
48 | + { | |
49 | + key[i] = rand() % 255; | |
50 | + } | |
51 | +} | |
52 | + | |
53 | +void DmpServerDes::generate_sub_keys(unsigned char *main_key, key_set *key_sets) | |
54 | +{ | |
55 | + int initial_key_permutaion[] = {57, 49, 41, 33, 25, 17, 9, | |
56 | + 1, 58, 50, 42, 34, 26, 18, | |
57 | + 10, 2, 59, 51, 43, 35, 27, | |
58 | + 19, 11, 3, 60, 52, 44, 36, | |
59 | + 63, 55, 47, 39, 31, 23, 15, | |
60 | + 7, 62, 54, 46, 38, 30, 22, | |
61 | + 14, 6, 61, 53, 45, 37, 29, | |
62 | + 21, 13, 5, 28, 20, 12, 4}; | |
63 | + | |
64 | + int key_shift_sizes[] = {-1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; | |
65 | + | |
66 | + int sub_key_permutation[] = {14, 17, 11, 24, 1, 5, | |
67 | + 3, 28, 15, 6, 21, 10, | |
68 | + 23, 19, 12, 4, 26, 8, | |
69 | + 16, 7, 27, 20, 13, 2, | |
70 | + 41, 52, 31, 37, 47, 55, | |
71 | + 30, 40, 51, 45, 33, 48, | |
72 | + 44, 49, 39, 56, 34, 53, | |
73 | + 46, 42, 50, 36, 29, 32}; | |
74 | + | |
75 | + int i, j; | |
76 | + int shift_size; | |
77 | + unsigned char shift_byte, first_shift_bits, second_shift_bits, third_shift_bits, fourth_shift_bits; | |
78 | + | |
79 | + memset(key_sets, 0, sizeof(key_set) * 17); | |
80 | + for (i = 0; i < 8; i++) | |
81 | + { | |
82 | + key_sets[0].k[i] = 0; | |
83 | + } | |
84 | + | |
85 | + for (i = 0; i < 56; i++) | |
86 | + { | |
87 | + shift_size = initial_key_permutaion[i]; | |
88 | + shift_byte = 0x80 >> ((shift_size - 1) % 8); | |
89 | + shift_byte &= main_key[(shift_size - 1) / 8]; | |
90 | + shift_byte <<= ((shift_size - 1) % 8); | |
91 | + | |
92 | + key_sets[0].k[i / 8] |= (shift_byte >> i % 8); | |
93 | + } | |
94 | + | |
95 | + for (i = 0; i < 3; i++) | |
96 | + { | |
97 | + key_sets[0].c[i] = key_sets[0].k[i]; | |
98 | + } | |
99 | + | |
100 | + key_sets[0].c[3] = key_sets[0].k[3] & 0xF0; | |
101 | + | |
102 | + for (i = 0; i < 3; i++) | |
103 | + { | |
104 | + key_sets[0].d[i] = (key_sets[0].k[i + 3] & 0x0F) << 4; | |
105 | + key_sets[0].d[i] |= (key_sets[0].k[i + 4] & 0xF0) >> 4; | |
106 | + } | |
107 | + | |
108 | + key_sets[0].d[3] = (key_sets[0].k[6] & 0x0F) << 4; | |
109 | + | |
110 | + for (i = 1; i < 17; i++) | |
111 | + { | |
112 | + for (j = 0; j < 4; j++) | |
113 | + { | |
114 | + key_sets[i].c[j] = key_sets[i - 1].c[j]; | |
115 | + key_sets[i].d[j] = key_sets[i - 1].d[j]; | |
116 | + } | |
117 | + | |
118 | + shift_size = key_shift_sizes[i]; | |
119 | + if (shift_size == 1) | |
120 | + { | |
121 | + shift_byte = 0x80; | |
122 | + } | |
123 | + else | |
124 | + { | |
125 | + shift_byte = 0xC0; | |
126 | + } | |
127 | + | |
128 | + // Process C | |
129 | + first_shift_bits = shift_byte & key_sets[i].c[0]; | |
130 | + second_shift_bits = shift_byte & key_sets[i].c[1]; | |
131 | + third_shift_bits = shift_byte & key_sets[i].c[2]; | |
132 | + fourth_shift_bits = shift_byte & key_sets[i].c[3]; | |
133 | + | |
134 | + key_sets[i].c[0] <<= shift_size; | |
135 | + key_sets[i].c[0] |= (second_shift_bits >> (8 - shift_size)); | |
136 | + | |
137 | + key_sets[i].c[1] <<= shift_size; | |
138 | + key_sets[i].c[1] |= (third_shift_bits >> (8 - shift_size)); | |
139 | + | |
140 | + key_sets[i].c[2] <<= shift_size; | |
141 | + key_sets[i].c[2] |= (fourth_shift_bits >> (8 - shift_size)); | |
142 | + | |
143 | + key_sets[i].c[3] <<= shift_size; | |
144 | + key_sets[i].c[3] |= (first_shift_bits >> (4 - shift_size)); | |
145 | + | |
146 | + // Process D | |
147 | + first_shift_bits = shift_byte & key_sets[i].d[0]; | |
148 | + second_shift_bits = shift_byte & key_sets[i].d[1]; | |
149 | + third_shift_bits = shift_byte & key_sets[i].d[2]; | |
150 | + fourth_shift_bits = shift_byte & key_sets[i].d[3]; | |
151 | + | |
152 | + key_sets[i].d[0] <<= shift_size; | |
153 | + key_sets[i].d[0] |= (second_shift_bits >> (8 - shift_size)); | |
154 | + | |
155 | + key_sets[i].d[1] <<= shift_size; | |
156 | + key_sets[i].d[1] |= (third_shift_bits >> (8 - shift_size)); | |
157 | + | |
158 | + key_sets[i].d[2] <<= shift_size; | |
159 | + key_sets[i].d[2] |= (fourth_shift_bits >> (8 - shift_size)); | |
160 | + | |
161 | + key_sets[i].d[3] <<= shift_size; | |
162 | + key_sets[i].d[3] |= (first_shift_bits >> (4 - shift_size)); | |
163 | + | |
164 | + for (j = 0; j < 48; j++) | |
165 | + { | |
166 | + shift_size = sub_key_permutation[j]; | |
167 | + if (shift_size <= 28) | |
168 | + { | |
169 | + shift_byte = 0x80 >> ((shift_size - 1) % 8); | |
170 | + shift_byte &= key_sets[i].c[(shift_size - 1) / 8]; | |
171 | + shift_byte <<= ((shift_size - 1) % 8); | |
172 | + } | |
173 | + else | |
174 | + { | |
175 | + shift_byte = 0x80 >> ((shift_size - 29) % 8); | |
176 | + shift_byte &= key_sets[i].d[(shift_size - 29) / 8]; | |
177 | + shift_byte <<= ((shift_size - 29) % 8); | |
178 | + } | |
179 | + | |
180 | + key_sets[i].k[j / 8] |= (shift_byte >> j % 8); | |
181 | + } | |
182 | + } | |
183 | +} | |
184 | + | |
185 | +void DmpServerDes::process_message(unsigned char *message_piece, unsigned char *processed_piece, key_set *key_sets, int mode) | |
186 | +{ | |
187 | + | |
188 | + int initial_message_permutation[] = {58, 50, 42, 34, 26, 18, 10, 2, | |
189 | + 60, 52, 44, 36, 28, 20, 12, 4, | |
190 | + 62, 54, 46, 38, 30, 22, 14, 6, | |
191 | + 64, 56, 48, 40, 32, 24, 16, 8, | |
192 | + 57, 49, 41, 33, 25, 17, 9, 1, | |
193 | + 59, 51, 43, 35, 27, 19, 11, 3, | |
194 | + 61, 53, 45, 37, 29, 21, 13, 5, | |
195 | + 63, 55, 47, 39, 31, 23, 15, 7}; | |
196 | + | |
197 | + int message_expansion[] = {32, 1, 2, 3, 4, 5, | |
198 | + 4, 5, 6, 7, 8, 9, | |
199 | + 8, 9, 10, 11, 12, 13, | |
200 | + 12, 13, 14, 15, 16, 17, | |
201 | + 16, 17, 18, 19, 20, 21, | |
202 | + 20, 21, 22, 23, 24, 25, | |
203 | + 24, 25, 26, 27, 28, 29, | |
204 | + 28, 29, 30, 31, 32, 1}; | |
205 | + int S1[] = {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, | |
206 | + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, | |
207 | + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, | |
208 | + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}; | |
209 | + | |
210 | + int S2[] = {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, | |
211 | + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, | |
212 | + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, | |
213 | + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}; | |
214 | + | |
215 | + int S3[] = {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, | |
216 | + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, | |
217 | + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, | |
218 | + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}; | |
219 | + | |
220 | + int S4[] = {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, | |
221 | + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, | |
222 | + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, | |
223 | + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}; | |
224 | + | |
225 | + int S5[] = {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, | |
226 | + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, | |
227 | + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, | |
228 | + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}; | |
229 | + | |
230 | + int S6[] = {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, | |
231 | + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, | |
232 | + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, | |
233 | + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}; | |
234 | + | |
235 | + int S7[] = {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, | |
236 | + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, | |
237 | + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, | |
238 | + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}; | |
239 | + | |
240 | + int S8[] = {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, | |
241 | + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, | |
242 | + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, | |
243 | + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}; | |
244 | + | |
245 | + int right_sub_message_permutation[] = {16, 7, 20, 21, | |
246 | + 29, 12, 28, 17, | |
247 | + 1, 15, 23, 26, | |
248 | + 5, 18, 31, 10, | |
249 | + 2, 8, 24, 14, | |
250 | + 32, 27, 3, 9, | |
251 | + 19, 13, 30, 6, | |
252 | + 22, 11, 4, 25}; | |
253 | + int final_message_permutation[] = {40, 8, 48, 16, 56, 24, 64, 32, | |
254 | + 39, 7, 47, 15, 55, 23, 63, 31, | |
255 | + 38, 6, 46, 14, 54, 22, 62, 30, | |
256 | + 37, 5, 45, 13, 53, 21, 61, 29, | |
257 | + 36, 4, 44, 12, 52, 20, 60, 28, | |
258 | + 35, 3, 43, 11, 51, 19, 59, 27, | |
259 | + 34, 2, 42, 10, 50, 18, 58, 26, | |
260 | + 33, 1, 41, 9, 49, 17, 57, 25}; | |
261 | + int i, k; | |
262 | + int shift_size; | |
263 | + unsigned char shift_byte; | |
264 | + | |
265 | + unsigned char initial_permutation[8]; | |
266 | + memset(initial_permutation, 0, 8); | |
267 | + memset(processed_piece, 0, 8); | |
268 | + | |
269 | + for (i = 0; i < 64; i++) | |
270 | + { | |
271 | + shift_size = initial_message_permutation[i]; | |
272 | + shift_byte = 0x80 >> ((shift_size - 1) % 8); | |
273 | + shift_byte &= message_piece[(shift_size - 1) / 8]; | |
274 | + shift_byte <<= ((shift_size - 1) % 8); | |
275 | + | |
276 | + initial_permutation[i / 8] |= (shift_byte >> i % 8); | |
277 | + } | |
278 | + | |
279 | + unsigned char l[4], r[4]; | |
280 | + for (i = 0; i < 4; i++) | |
281 | + { | |
282 | + l[i] = initial_permutation[i]; | |
283 | + r[i] = initial_permutation[i + 4]; | |
284 | + } | |
285 | + | |
286 | + unsigned char ln[4], rn[4], er[6], ser[4]; | |
287 | + | |
288 | + int key_index; | |
289 | + for (k = 1; k <= 16; k++) | |
290 | + { | |
291 | + memcpy(ln, r, 4); | |
292 | + | |
293 | + memset(er, 0, 6); | |
294 | + | |
295 | + for (i = 0; i < 48; i++) | |
296 | + { | |
297 | + shift_size = message_expansion[i]; | |
298 | + shift_byte = 0x80 >> ((shift_size - 1) % 8); | |
299 | + shift_byte &= r[(shift_size - 1) / 8]; | |
300 | + shift_byte <<= ((shift_size - 1) % 8); | |
301 | + | |
302 | + er[i / 8] |= (shift_byte >> i % 8); | |
303 | + } | |
304 | + | |
305 | + if (mode == DECRYPTION_MODE) | |
306 | + { | |
307 | + key_index = 17 - k; | |
308 | + } | |
309 | + else | |
310 | + { | |
311 | + key_index = k; | |
312 | + } | |
313 | + | |
314 | + for (i = 0; i < 6; i++) | |
315 | + { | |
316 | + er[i] ^= key_sets[key_index].k[i]; | |
317 | + } | |
318 | + | |
319 | + unsigned char row, column; | |
320 | + | |
321 | + for (i = 0; i < 4; i++) | |
322 | + { | |
323 | + ser[i] = 0; | |
324 | + } | |
325 | + | |
326 | + // 0000 0000 0000 0000 0000 0000 | |
327 | + // rccc crrc cccr rccc crrc cccr | |
328 | + | |
329 | + // Byte 1 | |
330 | + row = 0; | |
331 | + row |= ((er[0] & 0x80) >> 6); | |
332 | + row |= ((er[0] & 0x04) >> 2); | |
333 | + | |
334 | + column = 0; | |
335 | + column |= ((er[0] & 0x78) >> 3); | |
336 | + | |
337 | + ser[0] |= ((unsigned char)S1[row * 16 + column] << 4); | |
338 | + | |
339 | + row = 0; | |
340 | + row |= (er[0] & 0x02); | |
341 | + row |= ((er[1] & 0x10) >> 4); | |
342 | + | |
343 | + column = 0; | |
344 | + column |= ((er[0] & 0x01) << 3); | |
345 | + column |= ((er[1] & 0xE0) >> 5); | |
346 | + | |
347 | + ser[0] |= (unsigned char)S2[row * 16 + column]; | |
348 | + | |
349 | + // Byte 2 | |
350 | + row = 0; | |
351 | + row |= ((er[1] & 0x08) >> 2); | |
352 | + row |= ((er[2] & 0x40) >> 6); | |
353 | + | |
354 | + column = 0; | |
355 | + column |= ((er[1] & 0x07) << 1); | |
356 | + column |= ((er[2] & 0x80) >> 7); | |
357 | + | |
358 | + ser[1] |= ((unsigned char)S3[row * 16 + column] << 4); | |
359 | + | |
360 | + row = 0; | |
361 | + row |= ((er[2] & 0x20) >> 4); | |
362 | + row |= (er[2] & 0x01); | |
363 | + | |
364 | + column = 0; | |
365 | + column |= ((er[2] & 0x1E) >> 1); | |
366 | + | |
367 | + ser[1] |= (unsigned char)S4[row * 16 + column]; | |
368 | + | |
369 | + // Byte 3 | |
370 | + row = 0; | |
371 | + row |= ((er[3] & 0x80) >> 6); | |
372 | + row |= ((er[3] & 0x04) >> 2); | |
373 | + | |
374 | + column = 0; | |
375 | + column |= ((er[3] & 0x78) >> 3); | |
376 | + | |
377 | + ser[2] |= ((unsigned char)S5[row * 16 + column] << 4); | |
378 | + | |
379 | + row = 0; | |
380 | + row |= (er[3] & 0x02); | |
381 | + row |= ((er[4] & 0x10) >> 4); | |
382 | + | |
383 | + column = 0; | |
384 | + column |= ((er[3] & 0x01) << 3); | |
385 | + column |= ((er[4] & 0xE0) >> 5); | |
386 | + | |
387 | + ser[2] |= (unsigned char)S6[row * 16 + column]; | |
388 | + | |
389 | + // Byte 4 | |
390 | + row = 0; | |
391 | + row |= ((er[4] & 0x08) >> 2); | |
392 | + row |= ((er[5] & 0x40) >> 6); | |
393 | + | |
394 | + column = 0; | |
395 | + column |= ((er[4] & 0x07) << 1); | |
396 | + column |= ((er[5] & 0x80) >> 7); | |
397 | + | |
398 | + ser[3] |= ((unsigned char)S7[row * 16 + column] << 4); | |
399 | + | |
400 | + row = 0; | |
401 | + row |= ((er[5] & 0x20) >> 4); | |
402 | + row |= (er[5] & 0x01); | |
403 | + | |
404 | + column = 0; | |
405 | + column |= ((er[5] & 0x1E) >> 1); | |
406 | + | |
407 | + ser[3] |= (unsigned char)S8[row * 16 + column]; | |
408 | + | |
409 | + for (i = 0; i < 4; i++) | |
410 | + { | |
411 | + rn[i] = 0; | |
412 | + } | |
413 | + | |
414 | + for (i = 0; i < 32; i++) | |
415 | + { | |
416 | + shift_size = right_sub_message_permutation[i]; | |
417 | + shift_byte = 0x80 >> ((shift_size - 1) % 8); | |
418 | + shift_byte &= ser[(shift_size - 1) / 8]; | |
419 | + shift_byte <<= ((shift_size - 1) % 8); | |
420 | + | |
421 | + rn[i / 8] |= (shift_byte >> i % 8); | |
422 | + } | |
423 | + | |
424 | + for (i = 0; i < 4; i++) | |
425 | + { | |
426 | + rn[i] ^= l[i]; | |
427 | + } | |
428 | + | |
429 | + for (i = 0; i < 4; i++) | |
430 | + { | |
431 | + l[i] = ln[i]; | |
432 | + r[i] = rn[i]; | |
433 | + } | |
434 | + } | |
435 | + | |
436 | + unsigned char pre_end_permutation[8]; | |
437 | + for (i = 0; i < 4; i++) | |
438 | + { | |
439 | + pre_end_permutation[i] = r[i]; | |
440 | + pre_end_permutation[4 + i] = l[i]; | |
441 | + } | |
442 | + | |
443 | + for (i = 0; i < 64; i++) | |
444 | + { | |
445 | + shift_size = final_message_permutation[i]; | |
446 | + shift_byte = 0x80 >> ((shift_size - 1) % 8); | |
447 | + shift_byte &= pre_end_permutation[(shift_size - 1) / 8]; | |
448 | + shift_byte <<= ((shift_size - 1) % 8); | |
449 | + | |
450 | + processed_piece[i / 8] |= (shift_byte >> i % 8); | |
451 | + } | |
452 | +} | |
453 | + | |
454 | +void DmpServerDes::copyUChar(unsigned char *data_block, unsigned char *source, int loc, int num) | |
455 | +{ | |
456 | + int i; | |
457 | + for (i = 0; i < num; i++) | |
458 | + { | |
459 | + data_block[i] = source[loc + i]; | |
460 | + } | |
461 | +} | |
462 | + | |
463 | +bool DmpServerDes::Encrypt(unsigned char *source, unsigned char *des_key, unsigned char *destination) | |
464 | +{ | |
465 | + | |
466 | + // Generate DES key set******************************************* | |
467 | + int padding; | |
468 | + int block_count = 0, number_of_blocks; | |
469 | + | |
470 | + unsigned char data_block[8]; | |
471 | + unsigned char processed_block[8]; | |
472 | + key_set *key_sets = (key_set *)malloc(17 * sizeof(key_set)); | |
473 | + | |
474 | + generate_sub_keys(des_key, key_sets); | |
475 | + // Generate DES key set******************************************* | |
476 | + | |
477 | + int length = strlen((const char *)source); | |
478 | + number_of_blocks = length / 8 + ((length % 8) ? 1 : 0); | |
479 | + | |
480 | + // Start read source word, encrypt to destination | |
481 | + for (int i = 0; i < length; i += 8) | |
482 | + { | |
483 | + | |
484 | + block_count++; | |
485 | + | |
486 | + if (block_count == number_of_blocks) | |
487 | + { | |
488 | + padding = 8 - length % 8; | |
489 | + | |
490 | + copyUChar(data_block, source, i, 8 - padding); | |
491 | + if (padding < 8) | |
492 | + { // Fill empty data block bytes with padding | |
493 | + memset((data_block + 8 - padding), (unsigned char)padding, padding); | |
494 | + } | |
495 | + else if (padding == 8) | |
496 | + { // Write an extra block for padding | |
497 | + copyUChar(data_block, source, i, 8); | |
498 | + } | |
499 | + } | |
500 | + else | |
501 | + { | |
502 | + copyUChar(data_block, source, i, 8); | |
503 | + } | |
504 | + | |
505 | + process_message(data_block, processed_block, key_sets, ENCRYPTION_MODE); | |
506 | + memcpy(destination + i, &processed_block, 8 * sizeof(char)); | |
507 | + | |
508 | + memset(data_block, 0, 8); | |
509 | + } | |
510 | + | |
511 | + // Free up memory | |
512 | + free(key_sets); | |
513 | + | |
514 | + return true; | |
515 | +} | |
516 | + | |
517 | +bool DmpServerDes::Decrypt(unsigned char *source, int length, unsigned char *key, unsigned char *destination) | |
518 | +{ | |
519 | + | |
520 | + // Generate DES key set******************************************* | |
521 | + int padding; | |
522 | + int block_count = 0, number_of_blocks; | |
523 | + | |
524 | + unsigned char data_block[8]; | |
525 | + unsigned char processed_block[8]; | |
526 | + key_set *key_sets = (key_set *)malloc(17 * sizeof(key_set)); | |
527 | + | |
528 | + generate_sub_keys(key, key_sets); | |
529 | + // Generate DES key set******************************************* | |
530 | + | |
531 | + //int length = strlen((const char*)source); | |
532 | + number_of_blocks = length / 8 + ((length % 8) ? 1 : 0); | |
533 | + | |
534 | + // Start read source word | |
535 | + for (int i = 0; i < length; i += 8) | |
536 | + { | |
537 | + | |
538 | + block_count++; | |
539 | + | |
540 | + if (block_count == number_of_blocks) | |
541 | + { | |
542 | + copyUChar(data_block, source, i, 8); | |
543 | + process_message(data_block, processed_block, key_sets, DECRYPTION_MODE); | |
544 | + padding = processed_block[7]; | |
545 | + | |
546 | + if (padding < 8) | |
547 | + { | |
548 | + memcpy(destination + i, &processed_block, (8 - padding) * sizeof(char)); | |
549 | + } | |
550 | + else | |
551 | + { | |
552 | + memcpy(destination + i, &processed_block, 8 * sizeof(char)); | |
553 | + } | |
554 | + } | |
555 | + else | |
556 | + { | |
557 | + copyUChar(data_block, source, i, 8); | |
558 | + process_message(data_block, processed_block, key_sets, DECRYPTION_MODE); | |
559 | + memcpy(destination + i, &processed_block, 8 * sizeof(char)); | |
560 | + } | |
561 | + | |
562 | + memset(data_block, 0, 8); | |
563 | + } | |
564 | + | |
565 | + // Free up memory | |
566 | + free(key_sets); | |
567 | + | |
568 | + return true; | |
569 | +} | ... | ... |
src/server/dmpserverdes.h
0 → 100644
1 | +/************************************************************************** | |
2 | +* file: dmpserverdes.h | |
3 | + | |
4 | +* Author: qingxiongf | |
5 | +* Date: 2022-01-13 19:20:26 | |
6 | +* Email: qingxiongf@chinadci.com | |
7 | +* copyright: 广州城市信息研究所有限公司 | |
8 | +***************************************************************************/ | |
9 | + | |
10 | +#ifndef __dmpserverdes_h__ | |
11 | +#define __dmpserverdes_h__ | |
12 | +#include "dmap_server.h" | |
13 | +#include <boost/filesystem.hpp> | |
14 | +#include <unordered_map> | |
15 | + | |
16 | +#define ENCRYPTION_MODE 1 | |
17 | +#define DECRYPTION_MODE 0 | |
18 | + | |
19 | +class SERVER_EXPORT DmpServerDes | |
20 | +{ | |
21 | +public: | |
22 | + typedef struct | |
23 | + { | |
24 | + unsigned char k[8]; | |
25 | + unsigned char c[4]; | |
26 | + unsigned char d[4]; | |
27 | + } key_set; | |
28 | + | |
29 | + bool Encrypt(unsigned char *source, unsigned char *des_key, unsigned char *destination); | |
30 | + bool Decrypt(unsigned char *source, int length, unsigned char *key, unsigned char *destination); | |
31 | + | |
32 | + // static std::string RsaBase64Encrypt(const std::string &source, const char* key); | |
33 | + static std::string DesBase64Decrypt(const std::string &source, const char* key); | |
34 | + | |
35 | +private: | |
36 | + void generate_key(unsigned char *key); | |
37 | + void generate_sub_keys(unsigned char *main_key, key_set *key_sets); | |
38 | + void process_message(unsigned char *message_piece, unsigned char *processed_piece, key_set *key_sets, int mode); | |
39 | + void copyUChar(unsigned char *data_block, unsigned char *source, int loc, int num); | |
40 | +}; | |
41 | + | |
42 | +#endif // __dmpserverdes_h__ | ... | ... |
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | #include "dmpservermanager.h" |
10 | 10 | #include "dmpserver.h" |
11 | 11 | #include "dmphttputils.h" |
12 | -#include "dmpserverConfig.h" | |
12 | +#include "dmpserverconfig.h" | |
13 | 13 | #include <memory> |
14 | 14 | #include <boost/property_tree/ptree.hpp> |
15 | 15 | #include <boost/property_tree/json_parser.hpp> | ... | ... |
... | ... | @@ -39,19 +39,21 @@ DmpSpServerRequest::DmpSpServerRequest(SP_HttpRequest* request) |
39 | 39 | } |
40 | 40 | |
41 | 41 | //获取querystring |
42 | - std::string url(request->getURL()); | |
43 | - //std::string deurl=Percent::decode( url); | |
44 | - std::string::size_type pos = url.find("?"); | |
42 | + std::string url(request->getURL()); | |
43 | + std::string deurl; | |
44 | + this->UrlDecode(url,deurl); | |
45 | + | |
46 | + std::string::size_type pos = deurl.find("?"); | |
45 | 47 | if (pos != std::string::npos) { |
46 | - std::string path = url.substr(0, pos); | |
48 | + std::string path = deurl.substr(0, pos); | |
47 | 49 | setPath(path); |
48 | 50 | std::string queryString; |
49 | - queryString = url.substr(pos+1,url.length()); | |
51 | + queryString = deurl.substr(pos+1,deurl.length()); | |
50 | 52 | setQuery(queryString); |
51 | 53 | } |
52 | 54 | else { |
53 | 55 | isRestful_ = true; |
54 | - setPath(url); | |
56 | + setPath(deurl); | |
55 | 57 | } |
56 | 58 | |
57 | 59 | // for(int i=0; i< request->getParamCount(); i++) { |
... | ... | @@ -71,4 +73,50 @@ const void * DmpSpServerRequest::GetData() const |
71 | 73 | int DmpSpServerRequest::GetDataLength() const |
72 | 74 | { |
73 | 75 | return dataLen_; |
76 | +} | |
77 | +bool DmpSpServerRequest::UrlDecode(const std::string& src, std::string& dst) | |
78 | +{ | |
79 | + if(src.size() == 0) | |
80 | + return false; | |
81 | + int hex = 0; | |
82 | + for (size_t i = 0; i < src.length(); ++i) | |
83 | + { | |
84 | + switch (src[i]) | |
85 | + { | |
86 | + case '+': | |
87 | + dst += ' '; | |
88 | + break; | |
89 | + case '%': | |
90 | + { | |
91 | + if (isxdigit(src[i + 1]) && isxdigit(src[i + 2])) | |
92 | + { | |
93 | + std::string hexStr = src.substr(i + 1, 2); | |
94 | + hex = strtol(hexStr.c_str(), 0, 16); | |
95 | + //字母和数字[0-9a-zA-Z]、一些特殊符号[$-_.+!*'(),] 、以及某些保留字[$&+,/:;=?@] | |
96 | + //可以不经过编码直接用于URL | |
97 | + if (!((hex >= 48 && hex <= 57) || //0-9 | |
98 | + (hex >=97 && hex <= 122) || //a-z | |
99 | + (hex >=65 && hex <= 90) || //A-Z | |
100 | + //一些特殊符号及保留字[$-_.+!*'(),] [$&+,/:;=?@] | |
101 | + hex == 0x21 || hex == 0x24 || hex == 0x26 || hex == 0x27 || hex == 0x28 || hex == 0x29 | |
102 | + || hex == 0x2a || hex == 0x2b|| hex == 0x2c || hex == 0x2d || hex == 0x2e || hex == 0x2f | |
103 | + || hex == 0x3A || hex == 0x3B|| hex == 0x3D || hex == 0x3f || hex == 0x40 || hex == 0x5f | |
104 | + )) | |
105 | + { | |
106 | + dst += char(hex); | |
107 | + i += 2; | |
108 | + } | |
109 | + else | |
110 | + dst += '%'; | |
111 | + } | |
112 | + else | |
113 | + dst += '%'; | |
114 | + } | |
115 | + break; | |
116 | + default: | |
117 | + dst += src[i]; | |
118 | + break; | |
119 | + } | |
120 | + } | |
121 | + return true; | |
74 | 122 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -23,6 +23,7 @@ public: |
23 | 23 | DmpSpServerRequest(SP_HttpRequest* request); |
24 | 24 | const void * GetData() const override; |
25 | 25 | int GetDataLength() const override; |
26 | + bool UrlDecode(const std::string& src, std::string& dst); | |
26 | 27 | private: |
27 | 28 | const void* data_; |
28 | 29 | int dataLen_; | ... | ... |
... | ... | @@ -130,16 +130,16 @@ void DmpManagerApiHandler::regService(const DmpServerApiContext &context) const |
130 | 130 | break; |
131 | 131 | } |
132 | 132 | |
133 | - default: | |
133 | + default: | |
134 | 134 | break; |
135 | 135 | } |
136 | 136 | |
137 | - context.response()->write("{\"status\":\""+std::to_string(flag)+"\",\"url\":\""+url+"\",\"message\":\"Pulish service successful!\"}"); | |
138 | 137 | // std::string projData; |
139 | 138 | // DmpServerUtils::Base64Decode(project, &projData); |
140 | - // context.response()->removeHeader("Content-Type"); | |
141 | - // context.response()->setHeader("Content-Type", "text/xml;charset=utf-8"); | |
142 | - // context.response()->write(projData); | |
139 | + context.response()->removeHeader("Content-Type"); | |
140 | + context.response()->setHeader("Content-Type", "text/xml;charset=utf-8"); | |
141 | + // context.response()->write(projData); | |
142 | + context.response()->write("{\"status\":\""+std::to_string(flag)+"\",\"url\":\""+url+"\",\"message\":\"Pulish service successful!\"}"); | |
143 | 143 | } |
144 | 144 | else |
145 | 145 | { |
... | ... | @@ -312,6 +312,12 @@ void DmpManagerApiHandler::GetTileServiceInfo(const DmpServerApiContext &context |
312 | 312 | path= pt.get<std::string>("projectlayers.maplayer.datasource"); |
313 | 313 | confcdipath=path+"/conf.cdi"; |
314 | 314 | confxmlpath=path+"/conf.xml"; |
315 | + std::ifstream fread(confxmlpath, std::ifstream::binary); | |
316 | + if(!fread) | |
317 | + { | |
318 | + context.response()->write("{\"status\":\"false\",\"message\":\"获取切片配置信息失败\"}"); | |
319 | + return; | |
320 | + } | |
315 | 321 | //读取切片配置文件conf.cdi |
316 | 322 | boost::property_tree::ptree pt_confcdi; |
317 | 323 | boost::property_tree::read_xml(confcdipath,pt_confcdi); |
... | ... | @@ -334,6 +340,8 @@ void DmpManagerApiHandler::GetTileServiceInfo(const DmpServerApiContext &context |
334 | 340 | std::string tileCols=pt_confxml.get<std::string>("CacheInfo.TileCacheInfo.TileCols"); |
335 | 341 | std::string tileRows=pt_confxml.get<std::string>("CacheInfo.TileCacheInfo.TileRows"); |
336 | 342 | std::string dpi=pt_confxml.get<std::string>("CacheInfo.TileCacheInfo.DPI"); |
343 | + std::string storageFormat=pt_confxml.get<std::string>("CacheInfo.CacheStorageInfo.StorageFormat"); | |
344 | + pt.put("vendor",storageFormat); | |
337 | 345 | pt.put("projectCrs.spatialrefsys.wkt",strWKT); |
338 | 346 | pt.put("projectCrs.spatialrefsys.srid",wkid); |
339 | 347 | ... | ... |
... | ... | @@ -9,18 +9,23 @@ SET (MAPSERVER_SRCS |
9 | 9 | dmppgsqlpool.cpp |
10 | 10 | dmppgsqlsourcepools.cpp |
11 | 11 | wfs/dmpwfs.cpp |
12 | + wfs/dmpwfsfilter.cpp | |
13 | + wfs/dmpgmlfilter.cpp | |
12 | 14 | wfs/dmpwfsgetcapabilities.cpp |
13 | 15 | wfs/dmpwfsgetfeature.cpp |
14 | 16 | wfs/dmpwfsparameters.cpp |
17 | + wfs/dmpsqlfactory.cpp | |
15 | 18 | wms/dmpwmsrenderer.cpp |
16 | 19 | wms/dmpwms.cpp |
17 | 20 | wms/dmpwmsparameters.cpp |
18 | 21 | wms/dmpwmsgetcapabilities.cpp |
19 | 22 | wms/dmpwmsgetmap.cpp |
23 | + wms/dmpwmsserviceinfo.cpp | |
20 | 24 | wms/dmpwmsgetfeatureinfo.cpp |
21 | 25 | mapping/dmpmapping.cpp |
22 | 26 | mapping/dmpeditservice.cpp |
23 | 27 | mapping/dmpmappingparameters.cpp |
28 | + mapping/dmpimageinfo.cpp | |
24 | 29 | ) |
25 | 30 | |
26 | 31 | SET (MAPSERVER_HDRS |
... | ... | @@ -30,18 +35,23 @@ SET (MAPSERVER_HDRS |
30 | 35 | dmppgsqlpool.h |
31 | 36 | dmppgsqlsourcepools.h |
32 | 37 | wfs/dmpwfs.h |
38 | + wfs/dmpwfsfilter.h | |
39 | + wfs/dmpgmlfilter.h | |
33 | 40 | wfs/dmpwfsgetcapabilities.h |
34 | 41 | wfs/dmpwfsgetfeature.h |
35 | 42 | wfs/dmpwfsparameters.h |
43 | + wfs/dmpsqlfactory.h | |
36 | 44 | wms/dmpwmsrenderer.h |
37 | 45 | wms/dmpwms.h |
38 | 46 | wms/dmpwmsparameters.h |
39 | 47 | wms/dmpwmsgetcapabilities.h |
40 | 48 | wms/dmpwmsgetmap.h |
49 | + wms/dmpwmsserviceinfo.h | |
41 | 50 | wms/dmpwmsgetfeatureinfo.h |
42 | 51 | mapping/dmpmapping.h |
43 | 52 | mapping/dmpeditservice.h |
44 | 53 | mapping/dmpmappingparameters.h |
54 | + mapping/dmpimageinfo.h | |
45 | 55 | ) |
46 | 56 | |
47 | 57 | ######################################################## | ... | ... |
... | ... | @@ -34,7 +34,8 @@ public: |
34 | 34 | ~DmpMapServer(); |
35 | 35 | std::string name() const override { return std::string("MapServer");} |
36 | 36 | std::string alias() const override { return std::string("矢量地图服务");} |
37 | - std::string path() const override { return std::string("^/DMap/Services/?([\\w./]*)/MapServer/([\\w]+)"); } | |
37 | + //std::string path() const override { return std::string("^/DMap/Services/?([\\w./]*)/MapServer/([\\w]+)"); } | |
38 | + std::string path() const override { return std::string("^/DMap/Services/?([\\w\\W./]*)/MapServer/([\\w]+)"); } | |
38 | 39 | std::string capability() const override; |
39 | 40 | void executeRequest(DmpServerRequest &request, DmpServerResponse &response) override; |
40 | 41 | bool publish(const std::string &serviceName, const std::string &title, unsigned int capability, const DmpProject &project) override; | ... | ... |
... | ... | @@ -7,11 +7,109 @@ |
7 | 7 | * copyright: 广州城市信息研究所有限公司 |
8 | 8 | ***************************************************************************/ |
9 | 9 | #include "dmpmapserverutil.h" |
10 | -#include <string.h> | |
10 | +#include <iostream> | |
11 | +#include <istream> | |
12 | +#include <ostream> | |
13 | +#include <string> | |
14 | +#include <boost/asio.hpp> | |
15 | + | |
16 | + | |
17 | +using boost::asio::ip::tcp; | |
11 | 18 | |
12 | 19 | namespace mapserver |
13 | 20 | { |
14 | 21 | |
22 | +void DmpMapServerUtil::responseGml(shared_ptr<DmpPgsql> pPgsqlConn, std::string &responseData,const string& layerName,const std::string &srid) | |
23 | +{ | |
24 | + | |
25 | +// rs->PrepareFieldhead(); //获得了结果集的字段类型 | |
26 | + int shapeType = -1; | |
27 | + | |
28 | + double xg1, yg1, xg2, yg2; | |
29 | + int havegSet = 0; | |
30 | + int count = 0; | |
31 | + int pointCountTemp = 0; | |
32 | + char buff[5000] = {0}; | |
33 | + | |
34 | + responseData.append("<?xml version=\"1.0\" encoding=\"utf-8\" ?><wfs:FeatureCollection "); | |
35 | + responseData.append("xmlns:gims=\"http://www.esri.com/esri\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:ogc=\"http://www.opengis.net/ogc\">"); | |
36 | + | |
37 | + | |
38 | + //bool paff = parseString.affine; | |
39 | + try | |
40 | + { | |
41 | + int fieldsCount = pPgsqlConn->GetFieldCount(); | |
42 | + for (; pPgsqlConn->next();) | |
43 | + { | |
44 | + // css++; | |
45 | + //if(css!=24)continue; | |
46 | + //break; | |
47 | + //string geometry = ""; | |
48 | + //string properties = ""; | |
49 | + responseData.append("<gims:featureMember>"); | |
50 | + sprintf(buff, "<gims:%s fid=\"%s.%d\">", layerName.c_str(), layerName.c_str(), count + 1); | |
51 | + responseData.append(buff); | |
52 | + //responseData.append("\r\n"); | |
53 | + | |
54 | + //columns[md[ i ].getString(MetaData::ATTR_NAME)] = i; | |
55 | + for (int i = 0; i < fieldsCount; i++) | |
56 | + { | |
57 | + const char *sfieldName = pPgsqlConn->GetFieldName(i); //pPgsqlConn->field_name[i].c_str(); | |
58 | + if (sfieldName == 0) | |
59 | + { | |
60 | + break; | |
61 | + } | |
62 | + if (strncmp(sfieldName, "RN_RN", 5) == 0) | |
63 | + continue; | |
64 | + std::string strFieldName = sfieldName; | |
65 | + //DmapDll::StringHelp::ToXMLString(strFieldName); | |
66 | + | |
67 | + if (strFieldName == "geometry_as_gml") | |
68 | + { | |
69 | + const char* value = pPgsqlConn->getString(i); | |
70 | + if(value) | |
71 | + responseData.append(value); | |
72 | + continue; | |
73 | + } | |
74 | + else | |
75 | + { | |
76 | + const char *v = pPgsqlConn->getString(i); | |
77 | + sprintf(buff, "<gims:%s>%s</gims:%s>", strFieldName.c_str(), v, strFieldName.c_str()); | |
78 | + //properties += buff; | |
79 | + responseData.append(buff); | |
80 | + } | |
81 | + | |
82 | + } | |
83 | + //tickAA=GetTickCount(); | |
84 | + | |
85 | + sprintf(buff, "</gims:%s>\r",layerName.c_str()); | |
86 | + responseData.append(buff); | |
87 | + responseData.append("</gims:featureMember>"); | |
88 | + | |
89 | + count++; | |
90 | + //if(pointCount>25)break; | |
91 | + | |
92 | + if (pointCountTemp > 2000) | |
93 | + break; | |
94 | + //Sleep(5000); | |
95 | + // break; | |
96 | + } | |
97 | + } | |
98 | + catch (...) | |
99 | + { | |
100 | + | |
101 | + } | |
102 | + | |
103 | + //sprintf(buff, "numberMatched=\"%ld\" numberReturned=\"%ld\" ", count, count); | |
104 | + //responseData.append(insertBuf, sql, strlen(sql)); | |
105 | + | |
106 | + | |
107 | + | |
108 | + responseData.append("</wfs:FeatureCollection>"); | |
109 | + | |
110 | + return; | |
111 | +} | |
112 | + | |
15 | 113 | //以GeoJson的形式返回 |
16 | 114 | void DmpMapServerUtil::responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::string &responseData,const string& layerName,const string& srid) |
17 | 115 | { |
... | ... | @@ -28,10 +126,10 @@ void DmpMapServerUtil::responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::str |
28 | 126 | int fieldsCount = pPgsqlConn->GetFieldCount(); |
29 | 127 | for (int featureIndex = 0; pPgsqlConn->next(); featureIndex++) |
30 | 128 | { |
31 | - | |
32 | 129 | if (featureIndex > 0) |
33 | 130 | responseData.append(","); |
34 | - //ab->AppendString(R"({"type":"Feature")"); | |
131 | + | |
132 | + responseData.append(R"({"type":"Feature")"); | |
35 | 133 | |
36 | 134 | string geometry = ""; |
37 | 135 | string properties = ""; |
... | ... | @@ -43,6 +141,7 @@ void DmpMapServerUtil::responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::str |
43 | 141 | { |
44 | 142 | break; |
45 | 143 | } |
144 | + | |
46 | 145 | |
47 | 146 | if (strncmp(sfieldName, "RN_RN", 5) == 0) |
48 | 147 | continue; |
... | ... | @@ -148,4 +247,184 @@ void DmpMapServerUtil::responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::str |
148 | 247 | } |
149 | 248 | return strsrc; |
150 | 249 | } |
250 | + | |
251 | + | |
252 | + | |
253 | + std::vector<std::string> DmpMapServerUtil::stringSplit(const std::string &str, const std::string &pattern) | |
254 | + { | |
255 | + vector<std::string> stringList; | |
256 | + std::string subStr; | |
257 | + std::string tPattern; | |
258 | + size_t patternLen = pattern.length(); | |
259 | + for (size_t i = 0; i < str.length(); i++) | |
260 | + { | |
261 | + if(pattern[0] == str[i]) | |
262 | + { | |
263 | + tPattern = str.substr(i, patternLen); | |
264 | + if(tPattern == pattern) | |
265 | + { | |
266 | + i += patternLen -1; | |
267 | + if(!subStr.empty()) | |
268 | + { | |
269 | + stringList.push_back(subStr); | |
270 | + subStr.clear(); | |
271 | + } | |
272 | + } | |
273 | + else | |
274 | + { | |
275 | + subStr.push_back(str[i]); | |
276 | + } | |
277 | + } | |
278 | + else | |
279 | + { | |
280 | + subStr.push_back(str[i]); | |
281 | + } | |
282 | + } | |
283 | + | |
284 | + if(!subStr.empty()) | |
285 | + { | |
286 | + stringList.push_back(subStr); | |
287 | + } | |
288 | + return stringList; | |
289 | + | |
290 | + } | |
291 | + | |
292 | + | |
293 | + int DmpMapServerUtil::HttpPost(const std::string& url, std::string& postData, std::string &reponse_data) | |
294 | + { | |
295 | + string host, port,path; | |
296 | + const std::string &http_ = "http://"; | |
297 | + const std::string &https_ = "https://"; | |
298 | + std::string temp_data = url; | |
299 | + if (temp_data.find(http_) == 0) | |
300 | + { | |
301 | + temp_data = temp_data.substr(http_.length()); | |
302 | + } | |
303 | + else if (temp_data.find(https_) == 0) | |
304 | + { | |
305 | + temp_data = temp_data.substr(https_.length()); | |
306 | + } | |
307 | + else | |
308 | + { | |
309 | + return 500; | |
310 | + } | |
311 | + // 解析域名 | |
312 | + std::size_t idx = temp_data.find('/'); | |
313 | + // 解析 域名后的page | |
314 | + if (std::string::npos == idx) | |
315 | + { | |
316 | + path = "/"; | |
317 | + idx = temp_data.size(); | |
318 | + } | |
319 | + else | |
320 | + { | |
321 | + path = temp_data.substr(idx); | |
322 | + } | |
323 | + // 解析域名 | |
324 | + host = temp_data.substr(0, idx); | |
325 | + // 解析端口 | |
326 | + idx = host.find(':'); | |
327 | + if (std::string::npos == idx) | |
328 | + { | |
329 | + port = "80"; | |
330 | + } | |
331 | + else | |
332 | + { | |
333 | + port = host.substr(idx + 1); | |
334 | + host = host.substr(0, idx); | |
335 | + } | |
336 | + | |
337 | + | |
338 | + try | |
339 | + { | |
340 | + boost::asio::io_service io_service; | |
341 | + //如果io_service存在复用的情况 | |
342 | + if (io_service.stopped()) | |
343 | + io_service.reset(); | |
344 | + | |
345 | + // 从dns取得域名下的所有ip | |
346 | + tcp::resolver resolver(io_service); | |
347 | + tcp::resolver::query query(host, port); | |
348 | + tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); | |
349 | + | |
350 | + // 尝试连接到其中的某个ip直到成功 | |
351 | + tcp::socket socket(io_service); | |
352 | + boost::asio::connect(socket, endpoint_iterator); | |
353 | + | |
354 | + // Form the request. We specify the "Connection: close" header so that the | |
355 | + // server will close the socket after transmitting the response. This will | |
356 | + // allow us to treat all data up until the EOF as the content. | |
357 | + boost::asio::streambuf request; | |
358 | + std::ostream request_stream(&request); | |
359 | + request_stream << "POST " << path.c_str() << " HTTP/1.0\r\n"; | |
360 | + request_stream << "Host: " << host << ":" << port << "\r\n"; | |
361 | + request_stream << "Accept: */*\r\n"; | |
362 | + request_stream << "Content-Length: " << postData.length() << "\r\n"; | |
363 | + request_stream << "Content-Type: application/x-www-form-urlencoded\r\n"; | |
364 | + request_stream << "Connection: close\r\n\r\n"; | |
365 | + request_stream << postData.c_str(); | |
366 | + | |
367 | + // Send the request. | |
368 | + boost::asio::write(socket, request); | |
369 | + | |
370 | + // Read the response status line. The response streambuf will automatically | |
371 | + // grow to accommodate the entire line. The growth may be limited by passing | |
372 | + // a maximum size to the streambuf constructor. | |
373 | + boost::asio::streambuf response; | |
374 | + boost::asio::read_until(socket, response, "\r\n"); | |
375 | + | |
376 | + // Check that response is OK. | |
377 | + std::istream response_stream(&response); | |
378 | + std::string http_version; | |
379 | + response_stream >> http_version; | |
380 | + unsigned int status_code; | |
381 | + response_stream >> status_code; | |
382 | + std::string status_message; | |
383 | + std::getline(response_stream, status_message); | |
384 | + if (!response_stream || http_version.substr(0, 5) != "HTTP/") | |
385 | + { | |
386 | + reponse_data = "Invalid response"; | |
387 | + return -2; | |
388 | + } | |
389 | + // 如果服务器返回非200都认为有错,不支持301/302等跳转 | |
390 | + if (status_code != 200) | |
391 | + { | |
392 | + reponse_data = "Response returned with status code != 200 "; | |
393 | + return status_code; | |
394 | + } | |
395 | + | |
396 | + // 传说中的包头可以读下来了 | |
397 | + std::string header; | |
398 | + std::vector<string> headers; | |
399 | + while (std::getline(response_stream, header) && header != "\r") | |
400 | + headers.push_back(header); | |
401 | + | |
402 | + // 读取所有剩下的数据作为包体 | |
403 | + boost::system::error_code error; | |
404 | + while (boost::asio::read(socket, response, | |
405 | + boost::asio::transfer_at_least(1), error)) | |
406 | + { | |
407 | + } | |
408 | + | |
409 | + //响应有数据 | |
410 | + if (response.size()) | |
411 | + { | |
412 | + std::istream response_stream(&response); | |
413 | + std::istreambuf_iterator<char> eos; | |
414 | + reponse_data = string(std::istreambuf_iterator<char>(response_stream), eos); | |
415 | + } | |
416 | + | |
417 | + if (error != boost::asio::error::eof) | |
418 | + { | |
419 | + reponse_data = error.message(); | |
420 | + return -3; | |
421 | + } | |
422 | + } | |
423 | + catch (std::exception &e) | |
424 | + { | |
425 | + reponse_data = e.what(); | |
426 | + return -4; | |
427 | + } | |
428 | + return 0; | |
429 | + } | |
151 | 430 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -14,14 +14,20 @@ |
14 | 14 | #include <memory> |
15 | 15 | #include "dmppgsqlsourcepools.h" |
16 | 16 | |
17 | + | |
17 | 18 | namespace mapserver |
18 | 19 | { |
19 | 20 | class DmpMapServerUtil |
20 | 21 | { |
21 | 22 | public: |
22 | 23 | static void responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::string &responseData,const string& layerName,const std::string &srid); |
24 | + static void responseGml(shared_ptr<DmpPgsql> pPgsqlConn, std::string &responseData,const string& layerName,const std::string &srid); | |
23 | 25 | static void toJsonString(std::string &s); |
24 | 26 | static std::string replace(std::string strsrc, std::string strfind, std::string strrep); |
27 | + | |
28 | + static std::vector<std::string> stringSplit(const std::string &str, const std::string &pattern); | |
29 | + | |
30 | + static int HttpPost(const std::string& url, std::string& postData, std::string& responseData ); | |
25 | 31 | }; |
26 | 32 | } |
27 | 33 | ... | ... |
... | ... | @@ -13,8 +13,11 @@ |
13 | 13 | #define MAX_SIZE 40 |
14 | 14 | namespace mapserver |
15 | 15 | { |
16 | - DmpPgsqlPool::DmpPgsqlPool() | |
16 | + DmpPgsqlPool::DmpPgsqlPool(const std::string& guid,const std::string& name, const std::string& alias) | |
17 | 17 | { |
18 | + guid_ = guid; | |
19 | + name_ = name; | |
20 | + alias_ = alias; | |
18 | 21 | waitConnectSize_ = MAX_SIZE; |
19 | 22 | connectionTimeout_ = 15000; |
20 | 23 | } | ... | ... |
... | ... | @@ -19,42 +19,42 @@ |
19 | 19 | namespace mapserver |
20 | 20 | { |
21 | 21 | class DmpPgsqlPool |
22 | - { | |
23 | -public: | |
24 | - DmpPgsqlPool(); | |
22 | + { | |
23 | + public: | |
24 | + DmpPgsqlPool(const std::string& guid,const std::string& name, const std::string& alias); | |
25 | 25 | ~DmpPgsqlPool(); |
26 | - void ScannerConnectionTask(); | |
26 | + void ScannerConnectionTask(); | |
27 | 27 | std::shared_ptr<DmpPgsql> TestDmpPgsql(void); |
28 | - std::shared_ptr<DmpPgsql> GetPgsqlConn(void); | |
29 | - void ReleaseHandle(DmpPgsql*); | |
28 | + std::shared_ptr<DmpPgsql> GetPgsqlConn(void); | |
29 | + void ReleaseHandle(DmpPgsql *); | |
30 | 30 | |
31 | 31 | void Close(void); |
32 | - bool Connect(const char * s); | |
33 | - DmpPgsql* GetConnect(); | |
34 | - std::string guid()const { return guid_;} | |
35 | - std::string name()const { return name_;} | |
36 | - std::string alias()const{ return alias_;} | |
37 | - | |
38 | -private: | |
39 | - std::string conninfo_; | |
32 | + bool Connect(const char *s); | |
33 | + DmpPgsql *GetConnect(); | |
34 | + std::string guid() const { return guid_; } | |
35 | + std::string name() const { return name_; } | |
36 | + std::string alias() const { return alias_; } | |
37 | + | |
38 | + | |
39 | + | |
40 | + private: | |
41 | + std::string conninfo_; | |
40 | 42 | // 存储连接的队列 |
41 | - queue<DmpPgsql*> connectionQue_; | |
43 | + queue<DmpPgsql *> connectionQue_; | |
42 | 44 | int waitConnectSize_; |
43 | 45 | int connectSize_ = 0; |
44 | 46 | mutex mutex_; |
45 | 47 | //连接超时时间 |
46 | - int connectionTimeout_; | |
47 | - | |
48 | - // 设置条件变量,用于连接生产线程和连接消费线程的通信 | |
49 | - condition_variable cv_; | |
50 | - bool isClose_ = false; | |
51 | - std::string guid_; | |
52 | - std::string name_; | |
53 | - std::string alias_; | |
48 | + int connectionTimeout_; | |
49 | + | |
50 | + // 设置条件变量,用于连接生产线程和连接消费线程的通信 | |
51 | + condition_variable cv_; | |
52 | + bool isClose_ = false; | |
53 | + std::string guid_; | |
54 | + std::string name_; | |
55 | + std::string alias_; | |
54 | 56 | }; |
55 | - | |
56 | -} | |
57 | 57 | |
58 | +} | |
58 | 59 | |
59 | 60 | #endif //__dmppgsqlpool_h__ |
60 | - | ... | ... |
... | ... | @@ -9,6 +9,15 @@ |
9 | 9 | |
10 | 10 | #include "dmppgsqlsourcepools.h" |
11 | 11 | #include <iostream> |
12 | +#include "dmphttpbase.h" | |
13 | +#include "dmphttputils.h" | |
14 | +#include "dmpmapserverutil.h" | |
15 | +#include "dmpserverutils.h" | |
16 | +#include "dmpserverdes.h" | |
17 | +#include <boost/property_tree/ptree.hpp> | |
18 | +#include <boost/property_tree/json_parser.hpp> | |
19 | +#include <boost/typeof/typeof.hpp> | |
20 | + | |
12 | 21 | //#include "DES.h" |
13 | 22 | //#include "StringHelp.h" |
14 | 23 | |
... | ... | @@ -79,9 +88,9 @@ namespace mapserver |
79 | 88 | } |
80 | 89 | |
81 | 90 | |
82 | - AddDatabasePool("postgis", name, name,name, name); | |
91 | + AddDatabasePool(name); | |
83 | 92 | |
84 | - map<string, shared_ptr<DmpPgsqlPool>>::iterator poolIter2 = this->pgsqlPool_.find(name); | |
93 | + map<string, shared_ptr<DmpPgsqlPool>>::iterator poolIter2 = this->pgsqlPool_.find(name); | |
85 | 94 | if (poolIter2 != this->pgsqlPool_.end()) |
86 | 95 | { |
87 | 96 | shared_ptr<DmpPgsqlPool> pool = poolIter2->second; |
... | ... | @@ -166,6 +175,9 @@ namespace mapserver |
166 | 175 | return ""; |
167 | 176 | } |
168 | 177 | |
178 | + | |
179 | + | |
180 | + | |
169 | 181 | bool DmpPgsqlSourcePools::UpdateDatabasePool() |
170 | 182 | { |
171 | 183 | printf("InitDatabasePool\r\n"); |
... | ... | @@ -319,13 +331,6 @@ namespace mapserver |
319 | 331 | string alias = pPgsqlConn->getString(2); |
320 | 332 | string uri = pPgsqlConn->getString(3); |
321 | 333 | string connectstr = pPgsqlConn->getString(4); |
322 | - /* if(guid == "74c73a18-00c9-11ec-aced-0242ac110002") | |
323 | - { | |
324 | - continue; | |
325 | - }*/ | |
326 | - | |
327 | - | |
328 | - | |
329 | 334 | string pgConnect= ""; |
330 | 335 | if(connectstr != "") |
331 | 336 | { |
... | ... | @@ -440,13 +445,95 @@ namespace mapserver |
440 | 445 | |
441 | 446 | bool DmpPgsqlSourcePools::CreateDefaultDatabasePool(string dataType, string connStr) |
442 | 447 | { |
443 | - shared_ptr<DmpPgsqlPool> newPool(new DmpPgsqlPool()); | |
448 | + shared_ptr<DmpPgsqlPool> newPool(new DmpPgsqlPool("","","")); | |
444 | 449 | defaultPool_ = newPool; |
445 | 450 | bool result = defaultPool_->Connect(connStr.c_str()); |
446 | - | |
451 | + | |
447 | 452 | return true; |
448 | 453 | } |
449 | 454 | |
455 | + bool DmpPgsqlSourcePools::AddDatabasePool(string guid) | |
456 | + { | |
457 | + if (guid.find(" ") != string::npos && guid.size() > 50) | |
458 | + { | |
459 | + std::string connStr = guid; | |
460 | + shared_ptr<DmpPgsqlPool> newPool(new DmpPgsqlPool(guid,guid,guid)); | |
461 | + newPool->Connect(connStr.c_str()); | |
462 | + //newPool->Connect("PostgreSQLConn=hostaddr=172.26.99.173 port=5433 dbname='postgres' user='postgres' password='chinadci'"); | |
463 | + pgsqlPool_[guid] = newPool; | |
464 | + return true; | |
465 | + } | |
466 | + else | |
467 | + { | |
468 | + string requestUrl = DmpServerConfig::Instance()->getMetaUrl(); | |
469 | + if (requestUrl.size() > 0 && requestUrl[requestUrl.size() - 1] != '/') | |
470 | + { | |
471 | + requestUrl += "/"; | |
472 | + } | |
473 | + requestUrl.append("API/Database/Detail?guid="); | |
474 | + requestUrl.append(guid); | |
475 | + std::string reponse_data = DmpServerConfig::Instance()->HttpGet(requestUrl); | |
476 | + if (!reponse_data.empty()) | |
477 | + { | |
478 | + try | |
479 | + { | |
480 | + std::stringstream stream(reponse_data); | |
481 | + boost::property_tree::ptree pt; | |
482 | + boost::property_tree::read_json(stream, pt); | |
483 | + std::string name = pt.get<std::string>("data.name"); | |
484 | + std::string alias = pt.get<std::string>("data.alias"); | |
485 | + std::string sqlalchemy_uri_base64 = pt.get<std::string>("data.connectstr"); | |
486 | + std::string sqlalchemy_uri = DmpServerDes::DesBase64Decrypt(sqlalchemy_uri_base64, "Chinadci"); | |
487 | + | |
488 | + shared_ptr<DmpPgsqlPool> newPool(new DmpPgsqlPool(guid,name,alias)); | |
489 | + if (newPool->Connect(sqlalchemy_uri.c_str())) | |
490 | + { | |
491 | + pgsqlPool_[guid] = newPool; | |
492 | + return true; | |
493 | + } | |
494 | + | |
495 | + } | |
496 | + catch (...) | |
497 | + { | |
498 | + return false; | |
499 | + } | |
500 | + } | |
501 | + } | |
502 | + return false; | |
503 | + } | |
504 | + | |
505 | + string DmpPgsqlSourcePools::GetDbsource(const string& serviceid) | |
506 | + { | |
507 | + string requestUrl = DmpServerConfig::Instance()->getMetaUrl(); | |
508 | + if (requestUrl.size() > 0 && requestUrl[requestUrl.size() - 1] != '/') | |
509 | + { | |
510 | + requestUrl += "/"; | |
511 | + } | |
512 | + requestUrl.append("API/Database/Detail?guid="); | |
513 | + requestUrl.append(serviceid); | |
514 | + std::string reponse_data = DmpServerConfig::Instance()->HttpGet(requestUrl); | |
515 | + if (!reponse_data.empty()) | |
516 | + { | |
517 | + try | |
518 | + { | |
519 | + std::stringstream stream(reponse_data); | |
520 | + boost::property_tree::ptree pt; | |
521 | + boost::property_tree::read_json(stream, pt); | |
522 | + std::string name = pt.get<std::string>("data.name"); | |
523 | + std::string alias = pt.get<std::string>("data.alias"); | |
524 | + std::string sqlalchemy_uri_base64 = pt.get<std::string>("data.connectstr"); | |
525 | + std::string sqlalchemy_uri = DmpServerDes::DesBase64Decrypt(sqlalchemy_uri_base64, "Chinadci"); | |
526 | + | |
527 | + return sqlalchemy_uri; | |
528 | + } | |
529 | + catch (...) | |
530 | + { | |
531 | + return ""; | |
532 | + } | |
533 | + } | |
534 | + return ""; | |
535 | + } | |
536 | + | |
450 | 537 | bool DmpPgsqlSourcePools::AddDatabasePool(string dataType, |
451 | 538 | string guid, |
452 | 539 | string databaseName, |
... | ... | @@ -454,7 +541,7 @@ namespace mapserver |
454 | 541 | string connStr) |
455 | 542 | { |
456 | 543 | |
457 | - shared_ptr<DmpPgsqlPool> newPool(new DmpPgsqlPool()); | |
544 | + shared_ptr<DmpPgsqlPool> newPool(new DmpPgsqlPool(guid,databaseName,alias)); | |
458 | 545 | // newPool->guid() = guid; |
459 | 546 | // newPool->m_name = databaseName; |
460 | 547 | // newPool->m_alias = alias; |
... | ... | @@ -468,7 +555,7 @@ namespace mapserver |
468 | 555 | { |
469 | 556 | if(pgsqlPool_.find(guid) == pgsqlPool_.end()) |
470 | 557 | { |
471 | - shared_ptr<DmpPgsqlPool> newPool(new DmpPgsqlPool()); | |
558 | + shared_ptr<DmpPgsqlPool> newPool(new DmpPgsqlPool(guid,databaseName,alias)); | |
472 | 559 | // newPool->guid() = guid; |
473 | 560 | // newPool->m_name = databaseName; |
474 | 561 | // newPool->m_alias = alias; | ... | ... |
... | ... | @@ -7,58 +7,61 @@ |
7 | 7 | * copyright: 广州城市信息研究所有限公司 |
8 | 8 | ***************************************************************************/ |
9 | 9 | |
10 | - | |
11 | 10 | #ifndef __dmppgsqlsourcepools_h__ |
12 | 11 | #define __dmppgsqlsourcepools_h__ |
13 | 12 | |
14 | 13 | #include <map> |
15 | 14 | #include "dmppgsqlpool.h" |
16 | 15 | #include <mutex> |
16 | +#include "dmpserverconfig.h" | |
17 | + | |
17 | 18 | #define DMAP_DMDMS_DATABASE "dmdms_database" |
18 | 19 | #define DMAP_SCHEMA "public" |
19 | 20 | #define MAXCOUNT 200000 |
20 | 21 | |
21 | 22 | namespace mapserver |
22 | 23 | { |
23 | - class DmpPgsqlPool; | |
24 | - class DmpPgsqlSourcePools | |
25 | - { | |
26 | - public: | |
27 | - | |
28 | - DmpPgsqlSourcePools(); | |
29 | - ~DmpPgsqlSourcePools(); | |
30 | - static DmpPgsqlSourcePools* get_instance(); | |
31 | - | |
32 | - //获取默认数据库连接 | |
33 | - shared_ptr<DmpPgsql> GetDefaultPgsqlConn(); | |
34 | - | |
35 | - //获取数据库连接 | |
36 | - shared_ptr<DmpPgsql> GetPgsqlConn(const string& name); | |
37 | - | |
38 | - // shared_ptr<DmpPgsql> GetPgsqlConn(char* name); | |
39 | - | |
40 | - string GetDbSourceID(string name); | |
41 | - | |
42 | - bool InitDatabasePool(); | |
43 | - | |
44 | - bool UpdateDatabasePool(); | |
45 | - //创建默认数据库连接池 | |
46 | - bool CreateDefaultDatabasePool(string dataType, string connStr); | |
47 | - // 添加数据库连接池 | |
48 | - bool AddDatabasePool(string dataType, string guid, string databaseName, string alias, string connStr); | |
49 | - // Update 数据库连接池 | |
50 | - bool UpdDatabasePool(string dataType, string guid, string databaseName, string alias, string connStr); | |
51 | - private: | |
52 | - shared_ptr<DmpPgsqlPool> defaultPool_; | |
53 | - map<string, shared_ptr<DmpPgsqlPool>> pgsqlPool_; | |
54 | - bool updateLock_ = false; | |
55 | - | |
56 | - private: | |
57 | - mutex mutex_; | |
58 | - static DmpPgsqlSourcePools* instance_ptr; | |
59 | - }; | |
60 | -} | |
24 | + class DmpPgsqlPool; | |
25 | + class DmpPgsqlSourcePools | |
26 | + { | |
27 | + public: | |
28 | + DmpPgsqlSourcePools(); | |
29 | + ~DmpPgsqlSourcePools(); | |
30 | + static DmpPgsqlSourcePools *get_instance(); | |
61 | 31 | |
32 | + //获取默认数据库连接 | |
33 | + shared_ptr<DmpPgsql> GetDefaultPgsqlConn(); | |
62 | 34 | |
63 | -#endif //__dmppgsqlsourcepools_h__ | |
35 | + //获取数据库连接 | |
36 | + shared_ptr<DmpPgsql> GetPgsqlConn(const string &name); | |
37 | + | |
38 | + // shared_ptr<DmpPgsql> GetPgsqlConn(char* name); | |
39 | + | |
40 | + string GetDbSourceID(string name); | |
41 | + | |
42 | + string GetDbsource(const string& serviceid); | |
64 | 43 | |
44 | + bool InitDatabasePool(); | |
45 | + | |
46 | + bool UpdateDatabasePool(); | |
47 | + //创建默认数据库连接池 | |
48 | + bool CreateDefaultDatabasePool(string dataType, string connStr); | |
49 | + // 添加数据库连接池 | |
50 | + bool AddDatabasePool(string dataType, string guid, string databaseName, string alias, string connStr); | |
51 | + // Update 数据库连接池 | |
52 | + bool UpdDatabasePool(string dataType, string guid, string databaseName, string alias, string connStr); | |
53 | + | |
54 | + bool AddDatabasePool(string guid); | |
55 | + | |
56 | + private: | |
57 | + shared_ptr<DmpPgsqlPool> defaultPool_; | |
58 | + map<string, shared_ptr<DmpPgsqlPool>> pgsqlPool_; | |
59 | + bool updateLock_ = false; | |
60 | + | |
61 | + private: | |
62 | + mutex mutex_; | |
63 | + static DmpPgsqlSourcePools *instance_ptr; | |
64 | + }; | |
65 | +} | |
66 | + | |
67 | +#endif //__dmppgsqlsourcepools_h__ | ... | ... |
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | #include "dmpserverresponse.h" |
12 | 12 | #include "dmpserverrequest.h" |
13 | 13 | #include "dmpproject.h" |
14 | +#include "dmpvectorlayer.h" | |
14 | 15 | #include "dmpserverproject.h" |
15 | 16 | #include <boost/property_tree/ptree.hpp> |
16 | 17 | #include <boost/property_tree/json_parser.hpp> |
... | ... | @@ -21,7 +22,9 @@ namespace DmpMapping |
21 | 22 | bool loadService(const DmpServerContext &context, ProjectMap& vectorMappingProjects) |
22 | 23 | { |
23 | 24 | const char *data = (char *)(context.request()->GetData()); |
24 | - if(data== nullptr || *data == '\0') | |
25 | + | |
26 | + | |
27 | + if(data== nullptr || *data == '\0' || context.request()->method() != DmpServerRequest::Method::POST_METHOD ) | |
25 | 28 | { |
26 | 29 | LOGGER_ERROR("post 参数错误"); |
27 | 30 | context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}"); |
... | ... | @@ -31,12 +34,14 @@ namespace DmpMapping |
31 | 34 | if(!context.serverProject()) |
32 | 35 | { |
33 | 36 | LOGGER_ERROR("加载服务信息失败,服务名称是否错误"); |
34 | - context.response()->writeJson("{\"status\":\"false\",\"message\":\"加载服务信息失败,服务名称是否错误!\"}"); | |
37 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"加载服务信息失败,服务名称错误!\"}"); | |
35 | 38 | return false; |
36 | 39 | } |
37 | 40 | |
38 | 41 | try |
39 | 42 | { |
43 | + std::string name = context.serverProject()->name(); | |
44 | + std::string title = context.serverProject()->title(); | |
40 | 45 | std::stringstream stream(data); |
41 | 46 | boost::property_tree::ptree pt; |
42 | 47 | boost::property_tree::read_json(stream, pt); |
... | ... | @@ -54,9 +59,55 @@ namespace DmpMapping |
54 | 59 | return false; |
55 | 60 | } |
56 | 61 | vectorMappingProjects[guid] = project; |
57 | - context.response()->removeHeader("Content-Type"); | |
58 | - context.response()->setHeader("Content-Type", "text/xml;charset=utf-8"); | |
59 | - context.response()->write(projectData); | |
62 | + | |
63 | + int i = 0; | |
64 | + double minx, miny, maxx, maxy; | |
65 | + std::map<std::string, DmpMapLayer *> mapLayers = project->mapLayers(); | |
66 | + for (std::map<std::string, DmpMapLayer *>::iterator iter = mapLayers.begin(); iter != mapLayers.end(); iter++) | |
67 | + { | |
68 | + DmpMapLayer *layer = iter->second; | |
69 | + if (i == 0) | |
70 | + { | |
71 | + minx = layer->extent().xmin(); | |
72 | + miny = layer->extent().ymin(); | |
73 | + maxx = layer->extent().xmax(); | |
74 | + maxy = layer->extent().ymax(); | |
75 | + } | |
76 | + else | |
77 | + { | |
78 | + if (minx > layer->extent().xmin()) | |
79 | + minx = layer->extent().xmin(); | |
80 | + if (miny > layer->extent().ymin()) | |
81 | + miny = layer->extent().ymin(); | |
82 | + if (maxx < layer->extent().xmax()) | |
83 | + maxx = layer->extent().xmax(); | |
84 | + if (maxy < layer->extent().ymax()) | |
85 | + maxy = layer->extent().ymax(); | |
86 | + } | |
87 | + } | |
88 | + | |
89 | + char buff[250]; | |
90 | + sprintf(buff, "{\"name\":\"%s\",\"title\":\"%s\",\"boundingBox\":{\"minx\":%f, \"miny\":%f,\"maxx\":%f, \"maxy\":%f }", | |
91 | + name.c_str(), title.c_str(),minx, miny, maxx, maxy); | |
92 | + | |
93 | + std::string json = buff; | |
94 | + json.append(",\"maplayer\":["); | |
95 | + | |
96 | + i = 0; | |
97 | + for (std::map<std::string, DmpMapLayer *>::iterator iter = mapLayers.begin(); iter != mapLayers.end(); iter++) | |
98 | + { | |
99 | + DmpVectorLayer *layer = (DmpVectorLayer*) iter->second; | |
100 | + if(i>0) | |
101 | + { | |
102 | + json.append(","); | |
103 | + } | |
104 | + layer->writejson(json); | |
105 | + i++; | |
106 | + } | |
107 | + | |
108 | + json.append("]}"); | |
109 | + | |
110 | + context.response()->writeJson( json); | |
60 | 111 | return true; |
61 | 112 | } |
62 | 113 | else |
... | ... | @@ -82,7 +133,7 @@ namespace DmpMapping |
82 | 133 | return false; |
83 | 134 | } |
84 | 135 | |
85 | - bool editService(const DmpServerContext &context,ProjectMap& vectorMappingProjects) | |
136 | + bool loadProjectService(const DmpServerContext &context,ProjectMap& vectorMappingProjects) | |
86 | 137 | { |
87 | 138 | const char *data = (char *)(context.request()->GetData()); |
88 | 139 | if(data== nullptr || *data == '\0') |
... | ... | @@ -91,11 +142,112 @@ namespace DmpMapping |
91 | 142 | context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}"); |
92 | 143 | return false; |
93 | 144 | } |
145 | + | |
146 | + try | |
147 | + { | |
148 | + std::stringstream stream(data); | |
149 | + boost::property_tree::ptree pt; | |
150 | + boost::property_tree::read_json(stream, pt); | |
94 | 151 | |
95 | - if(!context.serverProject()) | |
152 | + std::string guid = pt.get<std::string>("guid"); | |
153 | + std::string project = pt.get<std::string>("project"); | |
154 | + if(!guid.empty() && !project.empty()) | |
155 | + { | |
156 | + std::string projData; | |
157 | + if (!DmpServerUtils::Base64Decode(project, &projData)) | |
158 | + { | |
159 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"base64转码错误\"}"); | |
160 | + return false; | |
161 | + } | |
162 | + shared_ptr<DmpProject> project(new DmpProject()); | |
163 | + if (!project->Read(projData)) | |
164 | + { | |
165 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"DMD文档错误\"}"); | |
166 | + return false; | |
167 | + } | |
168 | + vectorMappingProjects[guid] = project; | |
169 | + | |
170 | + int i = 0; | |
171 | + double minx, miny, maxx, maxy; | |
172 | + std::map<std::string, DmpMapLayer *> mapLayers = project->mapLayers(); | |
173 | + for (std::map<std::string, DmpMapLayer *>::iterator iter = mapLayers.begin(); iter != mapLayers.end(); iter++) | |
174 | + { | |
175 | + DmpMapLayer *layer = iter->second; | |
176 | + if (i == 0) | |
177 | + { | |
178 | + minx = layer->extent().xmin(); | |
179 | + miny = layer->extent().ymin(); | |
180 | + maxx = layer->extent().xmax(); | |
181 | + maxy = layer->extent().ymax(); | |
182 | + } | |
183 | + else | |
184 | + { | |
185 | + if (minx > layer->extent().xmin()) | |
186 | + minx = layer->extent().xmin(); | |
187 | + if (miny > layer->extent().ymin()) | |
188 | + miny = layer->extent().ymin(); | |
189 | + if (maxx < layer->extent().xmax()) | |
190 | + maxx = layer->extent().xmax(); | |
191 | + if (maxy < layer->extent().ymax()) | |
192 | + maxy = layer->extent().ymax(); | |
193 | + } | |
194 | + } | |
195 | + | |
196 | + char buff[250]; | |
197 | + sprintf(buff, "{\"name\":\"%s\",\"title\":\"%s\",\"boundingBox\":{\"minx\":%f, \"miny\":%f,\"maxx\":%f, \"maxy\":%f }", | |
198 | + guid.c_str(), "",minx, miny, maxx, maxy); | |
199 | + | |
200 | + std::string json = buff; | |
201 | + json.append(",\"maplayer\":["); | |
202 | + | |
203 | + i = 0; | |
204 | + for (std::map<std::string, DmpMapLayer *>::iterator iter = mapLayers.begin(); iter != mapLayers.end(); iter++) | |
205 | + { | |
206 | + DmpVectorLayer *layer = (DmpVectorLayer*) iter->second; | |
207 | + if(i>0) | |
208 | + { | |
209 | + json.append(","); | |
210 | + } | |
211 | + layer->writejson(json); | |
212 | + i++; | |
213 | + } | |
214 | + | |
215 | + json.append("]}"); | |
216 | + | |
217 | + context.response()->writeJson( json); | |
218 | + return true; | |
219 | + } | |
220 | + else | |
221 | + { | |
222 | + LOGGER_ERROR("post 参数错误"); | |
223 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}"); | |
224 | + return false; | |
225 | + } | |
226 | + } | |
227 | + catch (boost::property_tree::ptree_bad_path &e) | |
96 | 228 | { |
97 | - LOGGER_ERROR("加载服务信息失败,服务名称是否错误"); | |
98 | - context.response()->writeJson("{\"status\":\"false\",\"message\":\"加载服务信息失败,服务名称是否错误!\"}"); | |
229 | + LOGGER_ERROR(e.what()); | |
230 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误\"}"); | |
231 | + return false; | |
232 | + } | |
233 | + catch (boost::property_tree::ptree_bad_data &e) | |
234 | + { | |
235 | + LOGGER_ERROR(e.what()); | |
236 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误\"}"); | |
237 | + return false; | |
238 | + } | |
239 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"未知错误\"}"); | |
240 | + return false; | |
241 | + } | |
242 | + | |
243 | + | |
244 | + bool editService(const DmpServerContext &context,ProjectMap& vectorMappingProjects) | |
245 | + { | |
246 | + const char *data = (char *)(context.request()->GetData()); | |
247 | + if(data== nullptr || *data == '\0') | |
248 | + { | |
249 | + LOGGER_ERROR("post 参数错误"); | |
250 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}"); | |
99 | 251 | return false; |
100 | 252 | } |
101 | 253 | |
... | ... | @@ -112,15 +264,18 @@ namespace DmpMapping |
112 | 264 | std::string projData; |
113 | 265 | if (!DmpServerUtils::Base64Decode(project, &projData)) |
114 | 266 | { |
267 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"base64转码错误\"}"); | |
115 | 268 | return false; |
116 | 269 | } |
117 | 270 | shared_ptr<DmpProject> project(new DmpProject()); |
118 | 271 | if (!project->Read(projData)) |
119 | 272 | { |
273 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"DMD文档错误\"}"); | |
120 | 274 | return false; |
121 | 275 | } |
122 | 276 | vectorMappingProjects[guid] = project; |
123 | 277 | context.response()->writeJson("{\"status\":\"true\",\"message\":\"创建编辑服务工作空间成功!\"}"); |
278 | + return true; | |
124 | 279 | } |
125 | 280 | else |
126 | 281 | { |
... | ... | @@ -128,7 +283,6 @@ namespace DmpMapping |
128 | 283 | context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}"); |
129 | 284 | return false; |
130 | 285 | } |
131 | - | |
132 | 286 | } |
133 | 287 | catch (boost::property_tree::ptree_bad_path &e) |
134 | 288 | { |
... | ... | @@ -142,7 +296,8 @@ namespace DmpMapping |
142 | 296 | context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误\"}"); |
143 | 297 | return false; |
144 | 298 | } |
145 | - return false; | |
299 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"未知错误\"}"); | |
300 | + return false; | |
146 | 301 | } |
147 | 302 | |
148 | 303 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -22,7 +22,7 @@ namespace DmpMapping |
22 | 22 | |
23 | 23 | bool loadService(const DmpServerContext &context,ProjectMap& vectorMappingProjects); |
24 | 24 | |
25 | - | |
25 | + bool loadProjectService(const DmpServerContext &context,ProjectMap& vectorMappingProjects); | |
26 | 26 | bool editService(const DmpServerContext &context,ProjectMap& vectorMappingProjects); |
27 | 27 | |
28 | 28 | } | ... | ... |
1 | +/************************************************************************** | |
2 | +* file: dmpimageinfo.cpp | |
3 | + | |
4 | +* Author: qingxiongf | |
5 | +* Date: 2022-01-04 10:50:35 | |
6 | +* Email: qingxiongf@chinadci.com | |
7 | +* copyright: 广州城市信息研究所有限公司 | |
8 | +***************************************************************************/ | |
9 | +#include <unistd.h> | |
10 | +#include <dirent.h> | |
11 | +#include <stdlib.h> | |
12 | +#include <sys/stat.h> | |
13 | +#include <map> | |
14 | +#include <set> | |
15 | +#include <fontconfig/fontconfig.h> | |
16 | + | |
17 | +#include <boost/foreach.hpp> | |
18 | +#include <boost/lexical_cast.hpp> | |
19 | +#include <boost/algorithm/string.hpp> | |
20 | +#include <boost/date_time.hpp> | |
21 | +#include <boost/property_tree/ptree.hpp> | |
22 | +#include <boost/property_tree/json_parser.hpp> | |
23 | +#include <boost/typeof/typeof.hpp> | |
24 | +#include "dmplogger.h" | |
25 | +#include "dmpserverresponse.h" | |
26 | +#include "dmpserverrequest.h" | |
27 | + | |
28 | +#include "dmpimageinfo.h" | |
29 | + | |
30 | +namespace DmpMapping | |
31 | +{ | |
32 | + void getTypefaceList(const DmpServerContext &context) | |
33 | + { | |
34 | + FcConfig *config = FcInitLoadConfigAndFonts(); | |
35 | + FcPattern *pat = FcPatternCreate(); | |
36 | + FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, (char *)0); | |
37 | + FcFontSet *fs = FcFontList(config, pat, os); | |
38 | + if (fs == nullptr) | |
39 | + { | |
40 | + context.response()->writeJson("{\"error\":\"load FcFontSet failed\"}"); | |
41 | + return; | |
42 | + } | |
43 | + //printf("Total matching fonts: %d\n", fs->nfont); | |
44 | + boost::property_tree::ptree ptDoc; | |
45 | + boost::property_tree::ptree ptRoot; | |
46 | + | |
47 | + std::map<std::string, std::string> mapFont; | |
48 | + mapFont["SimSun"] = "宋体"; | |
49 | + mapFont["NSimSun"] = "新宋体"; | |
50 | + mapFont["SimHei"] = "黑体"; | |
51 | + mapFont["FangSong"] = "仿宋"; | |
52 | + mapFont["KaiTi"] = "楷体"; | |
53 | + mapFont["LiSu"] = "隶书"; | |
54 | + mapFont["YouYuan"] = "幼圆"; | |
55 | + mapFont["STXihei"] = "华文细黑"; | |
56 | + mapFont["STKaiti"] = "华文楷体"; | |
57 | + mapFont["STSong"] = "华文宋体"; | |
58 | + mapFont["STZhongsong"] = "华文中宋"; | |
59 | + mapFont["STFangsong"] = "华文仿宋"; | |
60 | + mapFont["FZShuTi"] = "方正舒体"; | |
61 | + mapFont["FZYaoti"] = "方正姚体"; | |
62 | + mapFont["STCaiyun"] = "华文彩云"; | |
63 | + mapFont["STHupo"] = "华文琥珀"; | |
64 | + mapFont["STLiti"] = "华文隶书"; | |
65 | + mapFont["STXingkai"] = "华文行楷"; | |
66 | + mapFont["STXinwei"] = "华文新魏"; | |
67 | + mapFont["Microsoft YaHei"] = "微软雅黑"; | |
68 | + mapFont["Microsoft JhengHei"] = "微軟正黑體"; | |
69 | + mapFont["DengXian"] = "等线"; | |
70 | + mapFont["MingLiU"] = "細明體"; | |
71 | + mapFont["MingLiU_HKSCS"] = "細明體_HKSCS"; | |
72 | + mapFont["MingLiU"] = "細明體"; | |
73 | + | |
74 | + std::set<std::string> setFont; | |
75 | + char buff[1000]; | |
76 | + for (int i = 0; fs && i < fs->nfont; ++i) | |
77 | + { | |
78 | + | |
79 | + FcPattern *font = fs->fonts[i]; | |
80 | + FcChar8 *file, *style, *family, *prgname; | |
81 | + if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch && | |
82 | + FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch && | |
83 | + FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch) | |
84 | + { | |
85 | + sprintf(buff, "%s", family); | |
86 | + if (setFont.find(buff) == setFont.end()) | |
87 | + { | |
88 | + | |
89 | + setFont.insert(buff); | |
90 | + if (mapFont.find(buff) != mapFont.end()) | |
91 | + { | |
92 | + boost::property_tree::ptree ptNode; | |
93 | + ptNode.put("", buff); | |
94 | + ptRoot.push_back(std::make_pair("", ptNode)); | |
95 | + } | |
96 | + } | |
97 | + } | |
98 | + } | |
99 | + | |
100 | + for (std::set<std::string>::iterator iter = setFont.begin(); | |
101 | + iter != setFont.end(); iter++) | |
102 | + { | |
103 | + if (mapFont.find(*iter) == mapFont.end()) | |
104 | + { | |
105 | + boost::property_tree::ptree ptNode; | |
106 | + ptNode.put("", *iter); | |
107 | + ptRoot.push_back(std::make_pair("", ptNode)); | |
108 | + } | |
109 | + } | |
110 | + | |
111 | + FcFontSetDestroy(fs); | |
112 | + | |
113 | + ptDoc.add_child("value", ptRoot); | |
114 | + std::stringstream stream; | |
115 | + write_json(stream, ptDoc); | |
116 | + std::string responseStr = stream.str(); | |
117 | + context.response()->writeJson(responseStr); | |
118 | + } | |
119 | + | |
120 | + void getImage(const DmpServerContext &context) | |
121 | + { | |
122 | + DmpServerParameters params = context.request()->serverParameters(); | |
123 | + std::string name; | |
124 | + params.getValue("name", name); | |
125 | + | |
126 | + std::string imagePath = getFilePath("../symbollib/" + name); | |
127 | + FILE *file = fopen(imagePath.c_str(), "rb"); | |
128 | + | |
129 | + try | |
130 | + { | |
131 | + char buff[1024]; | |
132 | + if (file == 0) | |
133 | + { | |
134 | + context.response()->writeJson("{\"error\":\"open file failed\"}"); | |
135 | + return; | |
136 | + } | |
137 | + | |
138 | + context.response()->removeHeader("Content-Type"); | |
139 | + context.response()->setHeader("Content-Type", "image/png"); | |
140 | + | |
141 | + for (int i = 0; i < 20000; i++) | |
142 | + { | |
143 | + size_t t = fread(buff, 1, sizeof(buff), file); | |
144 | + context.response()->writeContent(buff, t); | |
145 | + | |
146 | + if (t != sizeof(buff)) | |
147 | + break; | |
148 | + } | |
149 | + fclose(file); | |
150 | + return; | |
151 | + } | |
152 | + catch (...) | |
153 | + { | |
154 | + if (file) | |
155 | + fclose(file); | |
156 | + } | |
157 | + context.response()->writeJson("{\"error\":\"Parameter name is null\"}"); | |
158 | + } | |
159 | + | |
160 | + void getImageTypeList(const DmpServerContext &context) | |
161 | + { | |
162 | + DIR *dirp; | |
163 | + struct dirent *dp; | |
164 | + std::string imagePath = getFilePath("../symbollib"); | |
165 | + dirp = opendir(imagePath.c_str()); | |
166 | + | |
167 | + boost::property_tree::ptree ptDoc; | |
168 | + boost::property_tree::ptree ptRoot; | |
169 | + | |
170 | + if (dirp) | |
171 | + { | |
172 | + while ((dp = readdir(dirp)) != NULL) | |
173 | + { | |
174 | + if (dp->d_name == NULL || dp->d_name[0] == '.') | |
175 | + { | |
176 | + continue; | |
177 | + } | |
178 | + | |
179 | + boost::property_tree::ptree ptDir; | |
180 | + | |
181 | + ptDir.add("name", dp->d_name); | |
182 | + ptRoot.push_back(std::make_pair("", ptDir)); | |
183 | + //ptRoot.add_child("imageType",ptDir); | |
184 | + } | |
185 | + closedir(dirp); | |
186 | + } | |
187 | + else | |
188 | + { | |
189 | + LOGGER_ERROR("not find dir " + imagePath); | |
190 | + context.response()->writeJson(R"({"value":[]})"); | |
191 | + return ; | |
192 | + } | |
193 | + | |
194 | + ptDoc.add_child("value", ptRoot); | |
195 | + std::stringstream stream; | |
196 | + write_json(stream, ptDoc); | |
197 | + std::string responseStr = stream.str(); | |
198 | + context.response()->writeJson(responseStr); | |
199 | + } | |
200 | + | |
201 | + void getImageList(const DmpServerContext &context) | |
202 | + { | |
203 | + DmpServerParameters params = context.request()->serverParameters(); | |
204 | + std::string name; | |
205 | + params.getValue("name", name); | |
206 | + | |
207 | + if (name.empty()) | |
208 | + { | |
209 | + context.response()->writeJson("{\"error\":\"Parameter name is null\"}"); | |
210 | + return; | |
211 | + } | |
212 | + | |
213 | + struct dirent *dp; | |
214 | + std::string imagePath = getFilePath("../symbollib/" + name); | |
215 | + DIR *dirp = opendir(imagePath.c_str()); | |
216 | + | |
217 | + boost::property_tree::ptree ptDoc; | |
218 | + boost::property_tree::ptree ptRoot; | |
219 | + | |
220 | + if (dirp) | |
221 | + { | |
222 | + while ((dp = readdir(dirp)) != NULL) | |
223 | + { | |
224 | + boost::property_tree::ptree ptDir; | |
225 | + if (dp->d_name == NULL || dp->d_name[0] == '.') | |
226 | + { | |
227 | + continue; | |
228 | + } | |
229 | + ptDir.add("name", dp->d_name); | |
230 | + ptDir.add("path", ("../symbollib/" + name + "/" + dp->d_name)); | |
231 | + ptRoot.push_back(std::make_pair("", ptDir)); | |
232 | + } | |
233 | + closedir(dirp); | |
234 | + } | |
235 | + else | |
236 | + { | |
237 | + LOGGER_ERROR("not find dir " + imagePath); | |
238 | + context.response()->writeJson(R"({"value":[]})"); | |
239 | + return ; | |
240 | + } | |
241 | + | |
242 | + ptDoc.add_child("value", ptRoot); | |
243 | + std::stringstream stream; | |
244 | + write_json(stream, ptDoc); | |
245 | + std::string responseStr = stream.str(); | |
246 | + context.response()->writeJson(responseStr); | |
247 | + } | |
248 | + | |
249 | + std::string getFilePath(const std::string &path) | |
250 | + { | |
251 | + char sz[300] = {0}; | |
252 | + if (getCurrentFolderPath(sz, sizeof(sz)) > 0) | |
253 | + { | |
254 | + std::string s; | |
255 | + s = sz; | |
256 | + size_t t = s.rfind('/'); | |
257 | + sz[t] = 0; | |
258 | + if (path[0] == '/') | |
259 | + { | |
260 | + return path; | |
261 | + } | |
262 | + int i = 0; | |
263 | + if (path[0] == '.') | |
264 | + { | |
265 | + if (path[1] == '.') | |
266 | + { | |
267 | + i++; | |
268 | + s = sz; | |
269 | + t = s.rfind('/'); | |
270 | + sz[t] = 0; | |
271 | + } | |
272 | + i++; | |
273 | + } | |
274 | + if ((sz[t] == '/' || sz[t] == '\\') && (path[i] == '/' || path[i] == '\\')) | |
275 | + { | |
276 | + i++; | |
277 | + } | |
278 | + | |
279 | + int j = t; | |
280 | + for (j = t; i < path.length(); i++, j++) | |
281 | + { | |
282 | + if (path[i] == '\\') | |
283 | + { | |
284 | + sz[j] = '/'; | |
285 | + } | |
286 | + else | |
287 | + { | |
288 | + sz[j] = path[i]; | |
289 | + } | |
290 | + } | |
291 | + sz[j] = 0; | |
292 | + //strcat(sz, path.c_str()); | |
293 | + return sz; | |
294 | + } | |
295 | + else | |
296 | + return 0; | |
297 | + } | |
298 | + | |
299 | + size_t getCurrentFolderPath(char *processdir, size_t len) | |
300 | + { | |
301 | + char *path_end; | |
302 | + if (readlink("/proc/self/exe", processdir, len) <= 0) | |
303 | + return -1; | |
304 | + path_end = strrchr(processdir, '/'); | |
305 | + if (path_end == NULL) | |
306 | + return -1; | |
307 | + ++path_end; | |
308 | + //strcpy(processname, path_end); | |
309 | + *path_end = '\0'; | |
310 | + return (size_t)(path_end - processdir); | |
311 | + } | |
312 | + | |
313 | +} | |
\ No newline at end of file | ... | ... |
1 | +/************************************************************************** | |
2 | +* file: dmpimageinfo.h | |
3 | + | |
4 | +* Author: qingxiongf | |
5 | +* Date: 2022-01-04 10:03:50 | |
6 | +* Email: qingxiongf@chinadci.com | |
7 | +* copyright: 广州城市信息研究所有限公司 | |
8 | +***************************************************************************/ | |
9 | + | |
10 | +#ifndef __dmpimageinfo_h__ | |
11 | +#define __dmpimageinfo_h__ | |
12 | + | |
13 | +#include <map> | |
14 | +#include <memory> | |
15 | +#include <functional> | |
16 | +#include "dmpservercontext.h" | |
17 | + | |
18 | + | |
19 | + | |
20 | +namespace DmpMapping | |
21 | +{ | |
22 | + void getTypefaceList(const DmpServerContext &context) ; //获取字体列表 | |
23 | + void getImageTypeList(const DmpServerContext &context) ; //获取图片目录列表 | |
24 | + void getImageList(const DmpServerContext &context) ; //获取图片列表 | |
25 | + void getImage(const DmpServerContext &context) ; //获取图片 | |
26 | + std::string getFilePath(const std::string& path); | |
27 | + size_t getCurrentFolderPath(char *processdir, size_t len); | |
28 | +} | |
29 | + | |
30 | +#endif // __dmpimageinfo_h__ | |
31 | + | ... | ... |
... | ... | @@ -17,8 +17,11 @@ |
17 | 17 | #include "dmpserverresponse.h" |
18 | 18 | #include "dmplogger.h" |
19 | 19 | #include "../wms/dmpwmsgetmap.h" |
20 | +#include "../wms/dmpwmsparameters.h" | |
20 | 21 | #include "dmpmapping.h" |
21 | 22 | #include "dmpmappingparameters.h" |
23 | +#include "dmpimageinfo.h" | |
24 | + | |
22 | 25 | using namespace std; |
23 | 26 | |
24 | 27 | namespace DmpMapping |
... | ... | @@ -47,10 +50,82 @@ namespace DmpMapping |
47 | 50 | { |
48 | 51 | loadService(context, vectorMappingProjects_); |
49 | 52 | } |
53 | + else if (boost::iequals(request, "loadDmdService")) | |
54 | + { | |
55 | + loadProjectService(context, vectorMappingProjects_); | |
56 | + } | |
57 | + else if (boost::iequals(request, "editService")) | |
58 | + { | |
59 | + editService(context, vectorMappingProjects_); | |
60 | + } | |
61 | + else if (boost::iequals(request,"gettypefacelist")) { | |
62 | + getTypefaceList(context); | |
63 | + } | |
64 | + else if (boost::iequals(request,"getimagetyplist")) { | |
65 | + getImageTypeList(context); | |
66 | + } | |
67 | + else if (boost::iequals(request,"getimagelist")) { | |
68 | + getImageList(context); | |
69 | + } | |
70 | + else if (boost::iequals(request,"getimage")) { | |
71 | + getImage(context); | |
72 | + } | |
50 | 73 | else if (boost::iequals(request, "getmap")) |
51 | 74 | { |
52 | - DmpWms::writeGetMap(context, params, nullptr); | |
75 | + const std::string mapGuid = params.MapGuid(); | |
76 | + if (vectorMappingProjects_.find(mapGuid) != vectorMappingProjects_.end()) | |
77 | + { | |
78 | + shared_ptr<DmpProject> project = vectorMappingProjects_.find(mapGuid)->second; | |
79 | + const DmpWms::DmpWmsParameters wmsParams(context.request()->serverParameters()); | |
80 | + DmpWms::writeGetMap(context, wmsParams, project.get()); | |
81 | + } | |
82 | + else | |
83 | + { | |
84 | + writeLock(rwmutex_); | |
85 | + if (vectorMappingProjects_.find(mapGuid) != vectorMappingProjects_.end()) | |
86 | + { | |
87 | + shared_ptr<DmpProject> project = vectorMappingProjects_.find(mapGuid)->second; | |
88 | + const DmpWms::DmpWmsParameters wmsParams(context.request()->serverParameters()); | |
89 | + DmpWms::writeGetMap(context, wmsParams, project.get()); | |
90 | + } | |
91 | + else | |
92 | + { | |
93 | + std::string mapRenderer = params.MapRenderer(); | |
94 | + if (!mapRenderer.empty()) | |
95 | + { | |
96 | + std::string projData; | |
97 | + for(int i = 0; i< mapRenderer.size(); i++) | |
98 | + { | |
99 | + if(mapRenderer[i] == ' ')mapRenderer[i]= '+'; | |
100 | + } | |
101 | + if (!DmpServerUtils::Base64Decode(mapRenderer, &projData)) | |
102 | + { | |
103 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\""+ mapRenderer +" base64转码错误\"}"); | |
104 | + return; | |
105 | + } | |
106 | + shared_ptr<DmpProject> project(new DmpProject()); | |
107 | + if (!project->Read(projData)) | |
108 | + { | |
109 | + context.response()->writeJson("{\"status\":\"false\",\"message\":\"DMD文档错误\"}"); | |
110 | + return; | |
111 | + } | |
112 | + const DmpWms::DmpWmsParameters wmsParams(context.request()->serverParameters()); | |
113 | + DmpWms::writeGetMap(context, wmsParams, project.get()); | |
114 | + if(!mapGuid.empty()) | |
115 | + { | |
116 | + vectorMappingProjects_[mapGuid] = project; | |
117 | + } | |
118 | + return; | |
119 | + } | |
120 | + } | |
121 | + } | |
53 | 122 | } |
123 | + | |
54 | 124 | } |
125 | + | |
126 | + | |
127 | + | |
128 | + | |
129 | + | |
55 | 130 | } |
56 | 131 | ... | ... |
... | ... | @@ -12,6 +12,12 @@ |
12 | 12 | #include <string> |
13 | 13 | #include "dmpeditservice.h" |
14 | 14 | #include "dmpservice.h" |
15 | +#include <boost/thread/shared_mutex.hpp> | |
16 | +#include <boost/thread.hpp> | |
17 | + | |
18 | +typedef boost::shared_mutex rwmutex; | |
19 | +typedef boost::shared_lock<rwmutex> readLock; | |
20 | +typedef boost::unique_lock<rwmutex> writeLock; | |
15 | 21 | namespace DmpMapping |
16 | 22 | { |
17 | 23 | class DmpMappingService : public DmpService |
... | ... | @@ -28,6 +34,7 @@ namespace DmpMapping |
28 | 34 | |
29 | 35 | //存储工程文档实例 |
30 | 36 | ProjectMap vectorMappingProjects_; |
37 | + rwmutex rwmutex_; | |
31 | 38 | }; |
32 | 39 | } |
33 | 40 | ... | ... |
... | ... | @@ -87,4 +87,28 @@ namespace DmpMapping |
87 | 87 | return value; |
88 | 88 | } |
89 | 89 | |
90 | + std::string DmpMappingParameters::Map() const | |
91 | + { | |
92 | + std::string value = ""; | |
93 | + GetStringParameter("MAP",value); | |
94 | + return value; | |
95 | + } | |
96 | + | |
97 | + std::string DmpMappingParameters::MapGuid() const | |
98 | + { | |
99 | + std::string value = ""; | |
100 | + if(!GetStringParameter("GUID",value)) | |
101 | + { | |
102 | + GetStringParameter("MappingGUID",value); | |
103 | + } | |
104 | + return value; | |
105 | + } | |
106 | + | |
107 | + std::string DmpMappingParameters::MapRenderer() const | |
108 | + { | |
109 | + std::string value = ""; | |
110 | + GetStringParameter("MapRenderer", value); | |
111 | + return value; | |
112 | + } | |
113 | + | |
90 | 114 | } // namespace DmpWms |
\ No newline at end of file | ... | ... |
... | ... | @@ -23,6 +23,10 @@ namespace DmpMapping |
23 | 23 | std::string Request() const; //必须 值为GetMap GetCapabilities GetFeatureInfo GetFeatureInfo GetLegendGraphic |
24 | 24 | std::string Version() const; //必须 服务版本, 值为 1.0.0, 1.1.0, 1.1.1, 1.3 |
25 | 25 | |
26 | + std::string Map() const; | |
27 | + std::string MapGuid() const; | |
28 | + std::string MapRenderer() const; | |
29 | + | |
26 | 30 | private: |
27 | 31 | bool GetStringParameter(const char* key, std::string &value) const; |
28 | 32 | bool GetIntParameter(const char* key, int& value) const; | ... | ... |
1 | + | |
2 | +/************************************************************************** | |
3 | +* file: dmpgmlfilter.cpp | |
4 | + | |
5 | +* Author: qingxiongf | |
6 | +* Date: 2022-01-07 14:44:06 | |
7 | +* Email: qingxiongf@chinadci.com | |
8 | +* copyright: 广州城市信息研究所有限公司 | |
9 | +***************************************************************************/ | |
10 | +#include "dmpgmlfilter.h" | |
11 | +#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS | |
12 | +#include <boost/filesystem.hpp> | |
13 | +#include <boost/function.hpp> | |
14 | +#include <boost/make_shared.hpp> | |
15 | +#include <boost/algorithm/string/predicate.hpp> | |
16 | +#include <string> | |
17 | +namespace DmpWfs | |
18 | +{ | |
19 | + | |
20 | + DmpGmlFilter::DmpGmlFilter(/* args */) | |
21 | + { | |
22 | + } | |
23 | + | |
24 | + DmpGmlFilter::~DmpGmlFilter() | |
25 | + { | |
26 | + } | |
27 | + | |
28 | + bool DmpGmlFilter::Parse(const std::string &filter) | |
29 | + { | |
30 | + try | |
31 | + { | |
32 | + std::stringstream stream(filter); | |
33 | + boost::property_tree::ptree ptree; | |
34 | + boost::property_tree::read_xml(stream, ptree); | |
35 | + boost::property_tree::ptree::iterator ptroot = ptree.begin(); | |
36 | + | |
37 | + if( ptroot !=ptree.end() && (boost::iequals(ptroot->first,"fes:Filter")|| boost::iequals(ptroot->first,"Filter") || boost::iequals(ptroot->first,"ogc:Filter"))) | |
38 | + { | |
39 | + bool isFirst = true; | |
40 | + | |
41 | + for (boost::property_tree::ptree::iterator ptchild = ptroot->second.begin(); ptchild != ptroot->second.end(); ++ptchild) | |
42 | + { | |
43 | + if (!isFirst) | |
44 | + { | |
45 | + sql_ += " or "; | |
46 | + } | |
47 | + int k = _All(ptchild->first, ptchild->second); | |
48 | + //nc++; | |
49 | + | |
50 | + printf("%s\r\n", ptchild->first.c_str()); | |
51 | + } | |
52 | + } | |
53 | + | |
54 | + /*if(!(strcmp(p,"fes:Filter")==0||strcmp(p,"Filter")==0 || strcmp(p,"ogc:Filter")==0))return Error(-12,"no filter node"); | |
55 | + bool isFirst = true; | |
56 | + for (boost::property_tree::ptree::iterator ptchild = ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
57 | + { | |
58 | + if (!isFirst) | |
59 | + { | |
60 | + sql_ += " or "; | |
61 | + } | |
62 | + | |
63 | + printf("%s\r\n",ptchild->first.c_str()); | |
64 | + | |
65 | + }*/ | |
66 | + } | |
67 | + catch (const std::exception &e) | |
68 | + { | |
69 | + | |
70 | + } | |
71 | + | |
72 | + return false; | |
73 | + } | |
74 | + | |
75 | + int DmpGmlFilter::Error(int errorcode, const char* err) | |
76 | + { | |
77 | + return 0; | |
78 | + } | |
79 | + | |
80 | + std::string DmpGmlFilter::GetFieldName(const std::string& name) | |
81 | + { | |
82 | + int len = name.size(); | |
83 | + char p[100]; | |
84 | + strcpy(p, name.c_str()); | |
85 | + for (int i = 0; i < len; i++) | |
86 | + { | |
87 | + if (name[i] == ':') | |
88 | + { | |
89 | + strcpy(p, &name[i + 1]); | |
90 | + len = strlen(p); | |
91 | + break; | |
92 | + } | |
93 | + } | |
94 | + std::string str = p; | |
95 | + return str; | |
96 | + } | |
97 | + | |
98 | + | |
99 | + | |
100 | + int DmpGmlFilter::_All(const std::string &ptname,boost::property_tree::ptree& ptree) | |
101 | + { | |
102 | + | |
103 | + std::string name = GetFieldName(ptname); | |
104 | + const char *p = name.c_str(); | |
105 | + | |
106 | + if (0 == strcmp(p, "PropertyIsNotEqualTo")) | |
107 | + return _PropertyIsNotEqualTo(ptree); | |
108 | + return 0; | |
109 | + /* | |
110 | + switch (name.length()) | |
111 | + { | |
112 | + case 2: | |
113 | + if (0 == strcmp(p, "Or")) | |
114 | + return _Or(ptree); | |
115 | + break; | |
116 | + case 3: | |
117 | + if (0 == strcmp(p, "Not")) | |
118 | + return _Not(ptree); | |
119 | + if (0 == strcmp(p, "And")) | |
120 | + return _And(ptree); | |
121 | + break; | |
122 | + case 4: | |
123 | + if (0 == strcmp(p, "BBOX")) | |
124 | + return _BBOX(ptree); | |
125 | + break; | |
126 | + case 6: | |
127 | + if (0 == strcmp(p, "Equals")) | |
128 | + return _Equals(ptree); | |
129 | + if (0 == strcmp(p, "Beyond")) | |
130 | + return _Beyond(ptree); | |
131 | + if (0 == strcmp(p, "Within")) | |
132 | + return _Within(ptree); | |
133 | + break; | |
134 | + case 7: | |
135 | + if (0 == strcmp(p, "Crosses")) | |
136 | + return _Crosses(ptree); | |
137 | + if (0 == strcmp(p, "Touches")) | |
138 | + return _Touches(ptree); | |
139 | + if (0 == strcmp(p, "DWithin")) | |
140 | + return _DWithin(ptree); | |
141 | + break; | |
142 | + case 8: | |
143 | + if (0 == strcmp(p, "Contains")) | |
144 | + return _Contains(ptree); | |
145 | + if (0 == strcmp(p, "Overlaps")) | |
146 | + return _Overlaps(ptree); | |
147 | + if (0 == strcmp(p, "Disjoint")) | |
148 | + return _Disjoint(ptree); | |
149 | + break; | |
150 | + case 9: | |
151 | + if (0 == strcmp(p, "FeatureId")) | |
152 | + return _FeatureId(ptree); | |
153 | + break; | |
154 | + case 10: | |
155 | + if (0 == strcmp(p, "Intersects")) | |
156 | + return _Intersects(ptree); | |
157 | + if (0 == strcmp(p, "ResourceId")) | |
158 | + return _FeatureId(ptree); | |
159 | + break; | |
160 | + case 11: | |
161 | + if (0 == strcmp(p, "GmlObjectId")) | |
162 | + return _GmlObjectId(ptree); | |
163 | + if (0 == strcmp(p, "DIntersects")) | |
164 | + return _DIntersects(ptree); | |
165 | + break; | |
166 | + case 14: | |
167 | + if (0 == strcmp(p, "PropertyIsLike")) | |
168 | + return _PropertyIsLike(ptree); | |
169 | + if (0 == strcmp(p, "PropertyIsNull")) | |
170 | + return _PropertyIsNull(ptree); | |
171 | + if (0 == strcmp(p, "fes:ResourceId") || 0 == strcmp(p, "ogc:ResourceId")) | |
172 | + return _FeatureId(ptree); | |
173 | + break; | |
174 | + case 17: | |
175 | + if (0 == strcmp(p, "PropertyIsBetween")) | |
176 | + return _PropertyIsBetween(ptree); | |
177 | + if (0 == strcmp(p, "PropertyIsEqualTo")) | |
178 | + return _PropertyIsEqualTo(ptree); | |
179 | + break; | |
180 | + case 18: | |
181 | + if (0 == strcmp(p, "PropertyIsLessThan")) | |
182 | + return _PropertyIsLessThan(ptree); | |
183 | + break; | |
184 | + case 20: | |
185 | + if (0 == strcmp(p, "PropertyIsNotEqualTo")) | |
186 | + return _PropertyIsNotEqualTo(ptree); | |
187 | + break; | |
188 | + case 21: | |
189 | + if (0 == strcmp(p, "PropertyIsGreaterThan")) | |
190 | + return _PropertyIsGreaterThan(ptree); | |
191 | + break; | |
192 | + case 27: | |
193 | + if (0 == strcmp(p, "PropertyIsLessThanOrEqualTo")) | |
194 | + return _PropertyIsLessThanOrEqualTo(ptree); | |
195 | + break; | |
196 | + case 30: | |
197 | + if (0 == strcmp(p, "PropertyIsGreaterThanOrEqualTo")) | |
198 | + return _PropertyIsGreaterThanOrEqualTo(ptree); | |
199 | + break; | |
200 | + default: | |
201 | + break; | |
202 | + } | |
203 | + sql_ += "1=1"; | |
204 | + error_ = "Filter type error: "; | |
205 | + error_ += p; | |
206 | + return -17;*/ | |
207 | + } | |
208 | + | |
209 | + int DmpGmlFilter::_PropertyIsNotEqualTo(boost::property_tree::ptree& ptree) | |
210 | + { | |
211 | + return _PropertyOneEqual(ptree, "<>"); | |
212 | + } | |
213 | + | |
214 | + int DmpGmlFilter::_PropertyOneEqual(boost::property_tree::ptree &ptree,const char *type, int isLike) | |
215 | + { | |
216 | + int nc = 0, isExpression; | |
217 | + for (auto ptchild = ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
218 | + { | |
219 | + if(ptchild->first == "<xmlattr>") | |
220 | + continue; | |
221 | + int r = _PropertyParse(ptchild->first, ptchild->second, isExpression, isLike); //这里IsLike设定的值是1 | |
222 | + if (r) return r; | |
223 | + | |
224 | + if (isExpression) | |
225 | + { | |
226 | + if (nc == 0) | |
227 | + { | |
228 | + sql_ += type; | |
229 | + } | |
230 | + nc++; | |
231 | + if (nc == 2) | |
232 | + return 0; | |
233 | + } | |
234 | + } | |
235 | + if (nc < 2) | |
236 | + return Error(-19, "no enough expression"); | |
237 | + return 0; | |
238 | + } | |
239 | + /* | |
240 | + //<fes:Filter | |
241 | + //xmlns:fes="http://www.opengis.net/fes/2.0" | |
242 | + //xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
243 | + //xsi:schemaLocation="http://www.opengis.net/fes/2.0 | |
244 | + //http://schemas.opengis.net/filter/2.0.0/filterAll.xsd"> | |
245 | + //<fes:PropertyIsLike wildCard="*" singleChar="#" escapeChar="!"> | |
246 | + //<fes:ValueReference>LAST_NAME</fes:ValueReference> | |
247 | + //<fes:Literal>JOHN*</fes:Literal> | |
248 | + //</fes:PropertyIsLike> | |
249 | + //</fes:Filter> | |
250 | + */ | |
251 | + | |
252 | + int DmpGmlFilter::_PropertyParse(const std::string& ptreeName, boost::property_tree::ptree& ptree, int &isExpression, int isLike) | |
253 | + { | |
254 | + | |
255 | + isExpression = 0; | |
256 | + string name = this->GetFieldName(ptreeName); | |
257 | + const char *p = name.c_str(); | |
258 | + std::string value = ptree.get_value<std::string>(); | |
259 | + if (p == 0 || p[0] == 0) | |
260 | + { | |
261 | + sql_ += "('"; | |
262 | + sql_ += value; | |
263 | + sql_ += "')"; | |
264 | + return 0; | |
265 | + } | |
266 | + if (0 == strcmp(p, "Literal")) | |
267 | + { | |
268 | + isExpression = 1; | |
269 | + if (isLike) | |
270 | + { | |
271 | + sql_ += "('%"; | |
272 | + sql_ += value; | |
273 | + sql_ += "%')"; | |
274 | + } | |
275 | + else | |
276 | + { | |
277 | + sql_ += "('"; | |
278 | + sql_ += value; | |
279 | + sql_ += "')"; | |
280 | + } | |
281 | + return 0; | |
282 | + } | |
283 | + /* if (0 == strcmp(p, "PropertyName") || 0 == strcmp(p, "ValueReference")) | |
284 | + { | |
285 | + isExpression = 1; | |
286 | + //std::string s=n->value(); | |
287 | + //s=this->td->GetFieldQuery(s); | |
288 | + _AppendProperty(sql, n->value()); //添加了一个字段? | |
289 | + | |
290 | + sql = sql + "::varchar"; | |
291 | + //sql+=n->value(); | |
292 | + return 0; | |
293 | + } | |
294 | + if (0 == strcmp(p, "Add")) | |
295 | + { | |
296 | + isExpression = 1; | |
297 | + return _PropertyParse4(ptree, "+"); | |
298 | + } | |
299 | + if (0 == strcmp(p, "Sub")) | |
300 | + { | |
301 | + isExpression = 1; | |
302 | + return _PropertyParse4(ptree, "-"); | |
303 | + } | |
304 | + if (0 == strcmp(p, "Mul")) | |
305 | + { | |
306 | + isExpression = 1; | |
307 | + return _PropertyParse4(ptree, "*"); | |
308 | + } | |
309 | + if (0 == strcmp(p, "Div")) | |
310 | + { | |
311 | + isExpression = 1; | |
312 | + return _PropertyParse4(ptree, "/"); | |
313 | + } | |
314 | + if (0 == strcmp(p, "Function")) | |
315 | + { | |
316 | + isExpression = 1; | |
317 | + return _PropertyParseFunction(ptree); | |
318 | + }*/ | |
319 | + return 0; | |
320 | + } | |
321 | +} | |
\ No newline at end of file | ... | ... |
1 | +/************************************************************************** | |
2 | +* file: dmpgmlfilter.h | |
3 | + | |
4 | +* Author: qingxiongf | |
5 | +* Date: 2022-01-07 14:43:56 | |
6 | +* Email: qingxiongf@chinadci.com | |
7 | +* copyright: 广州城市信息研究所有限公司 | |
8 | +***************************************************************************/ | |
9 | + | |
10 | +#ifndef __dmpgmlfilter_h__ | |
11 | +#define __dmpgmlfilter_h__ | |
12 | + | |
13 | +#include <boost/property_tree/ptree.hpp> | |
14 | +#include <boost/property_tree/xml_parser.hpp> | |
15 | +#include <boost/typeof/typeof.hpp> | |
16 | +#include <string> | |
17 | +#include "dmpwfsgmlobject.h" | |
18 | +/* | |
19 | +* 参考文献 | |
20 | +* https://www.mapserver.org/ogc/filter_encoding.html | |
21 | +*/ | |
22 | +using namespace std; | |
23 | +namespace DmpWfs | |
24 | +{ | |
25 | + class DmpGmlFilter | |
26 | + { | |
27 | + | |
28 | + public: | |
29 | + DmpGmlFilter(); | |
30 | + ~DmpGmlFilter(); | |
31 | + | |
32 | + bool Parse(const std::string &filter); | |
33 | + private: | |
34 | + int Error(int errorcode, const char* err); | |
35 | + std::string GetFieldName(const std::string& name); | |
36 | + int _All(const std::string &name, boost::property_tree::ptree &ptree); | |
37 | + | |
38 | + int _PropertyIsNotEqualTo(boost::property_tree::ptree &ptree); | |
39 | + | |
40 | + int _PropertyParse(const std::string& ptreeName, boost::property_tree::ptree &ptreeode, int &isExpression, int isLike = 0); | |
41 | + int _PropertyOneEqual(boost::property_tree::ptree &ptree, const char *type, int isLike = 0); | |
42 | + | |
43 | + private: | |
44 | + std::string sql_; | |
45 | + /* data */ | |
46 | + }; | |
47 | +} | |
48 | + | |
49 | +#endif // __dmpgmlfilter_h__ | ... | ... |
... | ... | @@ -35,29 +35,18 @@ namespace DmpWfs |
35 | 35 | this->resultType_ = resultType; |
36 | 36 | } |
37 | 37 | |
38 | - void DmpSqlFactory::appendCondition(char *c) | |
39 | - { | |
40 | - if (condition.size() == 0) | |
41 | - { | |
42 | - condition = c; | |
43 | - } | |
44 | - else | |
45 | - { | |
46 | - condition += " and "; | |
47 | - condition += c; | |
48 | - } | |
49 | - } | |
50 | 38 | |
51 | - void DmpSqlFactory::appendCondition(std::string &c) | |
39 | + | |
40 | + void DmpSqlFactory::appendCondition(const std::string &c) | |
52 | 41 | { |
53 | - if (condition.size() == 0) | |
42 | + if (condition_.size() == 0) | |
54 | 43 | { |
55 | - condition = c; | |
44 | + condition_ = c; | |
56 | 45 | } |
57 | 46 | else |
58 | 47 | { |
59 | - condition += " and "; | |
60 | - condition += c; | |
48 | + condition_ += " and "; | |
49 | + condition_ += c; | |
61 | 50 | } |
62 | 51 | } |
63 | 52 | |
... | ... | @@ -70,27 +59,27 @@ namespace DmpWfs |
70 | 59 | } |
71 | 60 | else |
72 | 61 | { |
73 | - if (this->prop.size() == 0) | |
62 | + if (this->prop_.size() == 0) | |
74 | 63 | { |
75 | 64 | sql += "*"; |
76 | 65 | } |
77 | 66 | else |
78 | - sql += this->prop; | |
67 | + sql += this->prop_; | |
79 | 68 | } |
80 | 69 | sql += " from \""; |
81 | - sql += this->table; | |
70 | + sql += this->table_; | |
82 | 71 | sql += "\" where "; |
83 | - if (this->condition.size() == 0) | |
72 | + if (this->condition_.size() == 0) | |
84 | 73 | { |
85 | 74 | sql += "1=1"; |
86 | 75 | } |
87 | 76 | else |
88 | 77 | { |
89 | - sql += this->condition; | |
78 | + sql += this->condition_; | |
90 | 79 | } |
91 | - if (this->order.size() > 0) | |
80 | + if (this->order_.size() > 0) | |
92 | 81 | { |
93 | - sql += this->order; | |
82 | + sql += this->order_; | |
94 | 83 | } |
95 | 84 | |
96 | 85 | if (count_ <= 0) |
... | ... | @@ -100,10 +89,12 @@ namespace DmpWfs |
100 | 89 | if (count_ > 0 || startIndex_ > 0) |
101 | 90 | { |
102 | 91 | char sz[100]; |
103 | - sprintf(sz, " limit %ld offset %ld", count_, startIndex_); | |
92 | + sprintf(sz, " limit %d offset %d", count_, startIndex_); | |
104 | 93 | sql += sz; |
105 | 94 | } |
106 | 95 | return sql; |
107 | 96 | } |
108 | 97 | |
98 | + | |
99 | + | |
109 | 100 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -20,15 +20,17 @@ namespace DmpWfs |
20 | 20 | ~DmpSqlFactory(void); |
21 | 21 | |
22 | 22 | void setStartIndexCount(int startIndex, int count, const std::string &resultType); |
23 | - void appendCondition(std::string &c); | |
24 | - void appendCondition(char *c); | |
23 | + void appendCondition(const std::string &c); | |
24 | + void setProp(const std::string& prop) { prop_ = prop; } | |
25 | + void setTable(const std::string& table){ table_ = table; } | |
26 | + void setOrder(const std::string& order){ order_ = order; } | |
25 | 27 | std::string getSql(); |
26 | 28 | |
27 | 29 | private: |
28 | - std::string prop; | |
29 | - std::string condition; | |
30 | - std::string order; | |
31 | - std::string table; | |
30 | + std::string prop_; | |
31 | + std::string condition_; | |
32 | + std::string order_; | |
33 | + std::string table_; | |
32 | 34 | |
33 | 35 | std::string resultType_; |
34 | 36 | int startIndex_; | ... | ... |
... | ... | @@ -6,15 +6,1615 @@ |
6 | 6 | * Email: qingxiongf@chinadci.com |
7 | 7 | * copyright: 广州城市信息研究所有限公司 |
8 | 8 | ***************************************************************************/ |
9 | + | |
9 | 10 | #include "dmpwfsfilter.h" |
11 | +#include <boost/algorithm/string/predicate.hpp> | |
12 | + | |
10 | 13 | namespace DmpWfs |
11 | 14 | { |
12 | - | |
13 | - dmpwfsfilter::dmpwfsfilter(/* args */) | |
15 | + DmpWfsFilter::DmpWfsFilter(/* args */) | |
14 | 16 | { |
15 | 17 | } |
16 | 18 | |
17 | - dmpwfsfilter::~dmpwfsfilter() | |
19 | + DmpWfsFilter::~DmpWfsFilter() | |
20 | + { | |
21 | + } | |
22 | + | |
23 | + bool DmpWfsFilter::Parse(const std::string& filter) | |
24 | + { | |
25 | + try | |
26 | + { | |
27 | + std::stringstream stream(filter); | |
28 | + boost::property_tree::ptree ptree; | |
29 | + boost::property_tree::read_xml(stream, ptree); | |
30 | + boost::property_tree::ptree::iterator ptroot = ptree.begin(); | |
31 | + | |
32 | + if( ptroot !=ptree.end() && (boost::iequals(ptroot->first,"fes:Filter")|| boost::iequals(ptroot->first,"Filter") || boost::iequals(ptroot->first,"ogc:Filter"))) | |
33 | + { | |
34 | + bool isFirst = true; | |
35 | + | |
36 | + for (boost::property_tree::ptree::iterator ptchild = ptroot->second.begin(); ptchild != ptroot->second.end(); ++ptchild) | |
37 | + { | |
38 | + if (!isFirst) | |
39 | + { | |
40 | + sql_ += " or "; | |
41 | + } | |
42 | + int k = _All(ptchild->first, ptchild->second); | |
43 | + } | |
44 | + } | |
45 | + } | |
46 | + catch (const std::exception &e) | |
47 | + { | |
48 | + | |
49 | + } | |
50 | + return false; | |
51 | + } | |
52 | + | |
53 | + bool DmpWfsFilter::ParseOrder(const std::string& orderby) | |
54 | + { | |
55 | + return false; | |
56 | + } | |
57 | + | |
58 | + std::string DmpWfsFilter::GetFieldName(const std::string& name) | |
59 | + { | |
60 | + int len = name.size(); | |
61 | + char p[100]; | |
62 | + strcpy(p, name.c_str()); | |
63 | + for (int i = 0; i < len; i++) | |
64 | + { | |
65 | + if (name[i] == ':') | |
66 | + { | |
67 | + strcpy(p, &name[i + 1]); | |
68 | + len = strlen(p); | |
69 | + break; | |
70 | + } | |
71 | + } | |
72 | + std::string str = p; | |
73 | + return str; | |
74 | + } | |
75 | + | |
76 | + int DmpWfsFilter::_All(const std::string &ptname,boost::property_tree::ptree& ptree) | |
77 | + { | |
78 | + | |
79 | + std::string name = GetFieldName(ptname); | |
80 | + const char *p = name.c_str(); | |
81 | + | |
82 | + switch (name.length()) | |
83 | + { | |
84 | + case 2: | |
85 | + if (0 == strcmp(p, "Or")) | |
86 | + return _Or(ptree); | |
87 | + break; | |
88 | + case 3: | |
89 | + if (0 == strcmp(p, "Not")) | |
90 | + return _Not(ptree); | |
91 | + if (0 == strcmp(p, "And")) | |
92 | + return _And(ptree); | |
93 | + break; | |
94 | + case 4: | |
95 | + if (0 == strcmp(p, "BBOX")) | |
96 | + return _BBOX(ptree); | |
97 | + break; | |
98 | + case 6: | |
99 | + if (0 == strcmp(p, "Equals")) | |
100 | + return _Equals(ptree); | |
101 | + if (0 == strcmp(p, "Beyond")) | |
102 | + return _Beyond(ptree); | |
103 | + if (0 == strcmp(p, "Within")) | |
104 | + return _Within(ptree); | |
105 | + break; | |
106 | + case 7: | |
107 | + if (0 == strcmp(p, "Crosses")) | |
108 | + return _Crosses(ptree); | |
109 | + if (0 == strcmp(p, "Touches")) | |
110 | + return _Touches(ptree); | |
111 | + if (0 == strcmp(p, "DWithin")) | |
112 | + return _DWithin(ptree); | |
113 | + break; | |
114 | + case 8: | |
115 | + if (0 == strcmp(p, "Contains")) | |
116 | + return _Contains(ptree); | |
117 | + if (0 == strcmp(p, "Overlaps")) | |
118 | + return _Overlaps(ptree); | |
119 | + if (0 == strcmp(p, "Disjoint")) | |
120 | + return _Disjoint(ptree); | |
121 | + break; | |
122 | + case 9: | |
123 | + if (0 == strcmp(p, "FeatureId")) | |
124 | + return _FeatureId(ptree); | |
125 | + break; | |
126 | + case 10: | |
127 | + if (0 == strcmp(p, "Intersects")) | |
128 | + return _Intersects(ptree); | |
129 | + if (0 == strcmp(p, "ResourceId")) | |
130 | + return _FeatureId(ptree); | |
131 | + break; | |
132 | + case 11: | |
133 | + if (0 == strcmp(p, "GmlObjectId")) | |
134 | + return _GmlObjectId(ptree); | |
135 | + if (0 == strcmp(p, "DIntersects")) | |
136 | + return _DIntersects(ptree); | |
137 | + break; | |
138 | + case 14: | |
139 | + if (0 == strcmp(p, "PropertyIsLike")) | |
140 | + return _PropertyIsLike(ptree); | |
141 | + if (0 == strcmp(p, "PropertyIsNull")) | |
142 | + return _PropertyIsNull(ptree); | |
143 | + if (0 == strcmp(p, "fes:ResourceId") || 0 == strcmp(p, "ogc:ResourceId")) | |
144 | + return _FeatureId(ptree); | |
145 | + break; | |
146 | + case 17: | |
147 | + if (0 == strcmp(p, "PropertyIsBetween")) | |
148 | + return _PropertyIsBetween(ptree); | |
149 | + if (0 == strcmp(p, "PropertyIsEqualTo")) | |
150 | + return _PropertyIsEqualTo(ptree); | |
151 | + break; | |
152 | + case 18: | |
153 | + if (0 == strcmp(p, "PropertyIsLessThan")) | |
154 | + return _PropertyIsLessThan(ptree); | |
155 | + break; | |
156 | + case 20: | |
157 | + if (0 == strcmp(p, "PropertyIsNotEqualTo")) | |
158 | + return _PropertyIsNotEqualTo(ptree); | |
159 | + break; | |
160 | + case 21: | |
161 | + if (0 == strcmp(p, "PropertyIsGreaterThan")) | |
162 | + return _PropertyIsGreaterThan(ptree); | |
163 | + break; | |
164 | + case 27: | |
165 | + if (0 == strcmp(p, "PropertyIsLessThanOrEqualTo")) | |
166 | + return _PropertyIsLessThanOrEqualTo(ptree); | |
167 | + break; | |
168 | + case 30: | |
169 | + if (0 == strcmp(p, "PropertyIsGreaterThanOrEqualTo")) | |
170 | + return _PropertyIsGreaterThanOrEqualTo(ptree); | |
171 | + break; | |
172 | + default: | |
173 | + break; | |
174 | + } | |
175 | + sql_ += "1=1"; | |
176 | + error_ = "Filter type error: "; | |
177 | + error_ += p; | |
178 | + return -17; | |
179 | + } | |
180 | + | |
181 | + int DmpWfsFilter::_Or(boost::property_tree::ptree& ptree) | |
182 | + { | |
183 | + int nc = 0; | |
184 | + sql_ += "("; | |
185 | + for (auto ptchild =ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
186 | + { | |
187 | + if (nc) | |
188 | + { | |
189 | + sql_ += " or "; | |
190 | + } | |
191 | + sql_ += "("; | |
192 | + int k = _All(ptchild->first, ptchild->second); | |
193 | + sql_ += ")"; | |
194 | + nc++; | |
195 | + } | |
196 | + sql_ += ")"; | |
197 | + return 0; | |
198 | + } | |
199 | + int DmpWfsFilter::_Not(boost::property_tree::ptree& ptree) | |
200 | + { | |
201 | + sql_ += "not ("; | |
202 | + auto ptchild = ptree.begin(); | |
203 | + // xml_node<char> *node = n->first_node(); | |
204 | + _All(ptchild->first, ptchild->second); | |
205 | + sql_ += ")"; | |
206 | + return 0; | |
207 | + } | |
208 | + int DmpWfsFilter::_And(boost::property_tree::ptree& ptree) | |
209 | + { | |
210 | + int nc = 0; | |
211 | + sql_ += "("; | |
212 | + for (auto ptchild =ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
213 | + { | |
214 | + if (nc) | |
215 | + { | |
216 | + sql_ += " and "; | |
217 | + } | |
218 | + sql_ += "("; | |
219 | + int k = _All(ptchild->first, ptchild->second); | |
220 | + sql_ += ")"; | |
221 | + nc++; | |
222 | + } | |
223 | + sql_ += ")"; | |
224 | + return 0; | |
225 | + } | |
226 | + int DmpWfsFilter::_BBOX(boost::property_tree::ptree& ptree) | |
227 | + { | |
228 | + { | |
229 | + | |
230 | + | |
231 | + // xml_node<char> *node = n->first_node("PropertyName"); | |
232 | + // if (node == 0) | |
233 | + // return -1; | |
234 | + // GetQueryField(propertyName.c_str()); | |
235 | + } | |
236 | + std::string propertyName = ptree.get<std::string>("PropertyName"); | |
237 | + const char *v = propertyName.c_str(); | |
238 | + | |
239 | + //从FILTER中得到了两个坐标点,构造一个POLYGON? | |
240 | + double x1, y1, x2, y2; | |
241 | + int re; | |
242 | + | |
243 | + boost::property_tree::ptree ptEnvelope = ptree.get_child("Envelope"); | |
244 | + // xml_node<char> *e = n->first_node("Envelope"); | |
245 | + // if (e == 0) | |
246 | + // e = n->first_node("Box"); | |
247 | + // if (ptEnvelope) | |
248 | + { | |
249 | + re = pEnvelope(ptEnvelope, &x1, &y1, &x2, &y2); | |
250 | + } | |
251 | + // else | |
252 | + { | |
253 | + // re = pEnvelope(n, &x1, &y1, &x2, &y2); | |
254 | + } | |
255 | + if (re) | |
256 | + return -1; | |
257 | + | |
258 | + // the_geom && 'BOX3D(90900 190900, 100100 200100)'::box3d | |
259 | + char s[1000]; | |
260 | + std::string ss; | |
261 | + // ConnClassAll::GetBBox(x1, y1, x2, y2, fieldTemp, (char *)srs.c_str(), this->DatabaseType, ss); | |
262 | + sql_ += ss; | |
263 | + return 0; | |
264 | + } | |
265 | + int DmpWfsFilter::_Equals(boost::property_tree::ptree& ptree) | |
266 | + { | |
267 | + return pGeometrySql("st_equals", "EQUAL", 0, ptree, false); //得到了一条SQL语句 | |
268 | + } | |
269 | + int DmpWfsFilter::_Beyond(boost::property_tree::ptree& ptree) | |
270 | + { | |
271 | + return pGeometrySql("st_disjoint", "DISJOINT", 1, ptree, true); | |
272 | + } | |
273 | + int DmpWfsFilter::_Within(boost::property_tree::ptree& ptree) | |
274 | + { | |
275 | + return pGeometrySql("st_within", "INSIDE", 0, ptree, false); | |
276 | + } | |
277 | + int DmpWfsFilter::_Crosses(boost::property_tree::ptree& ptree) | |
278 | + { | |
279 | + return pGeometrySql("st_crosses", "ANYINTERACT", 0, ptree, false); | |
280 | + } | |
281 | + int DmpWfsFilter::_Touches(boost::property_tree::ptree& ptree) | |
282 | + { | |
283 | + return pGeometrySql("st_touches", "TOUCH", 0, ptree, false); | |
284 | + } | |
285 | + int DmpWfsFilter::_DWithin(boost::property_tree::ptree& ptree) | |
286 | + { | |
287 | + return pGeometrySql("ST_DWithin", "INSIDE", 0, ptree, true); | |
288 | + } | |
289 | + int DmpWfsFilter::_Contains(boost::property_tree::ptree& ptree) | |
290 | + { | |
291 | + return pGeometrySql("st_contains", "CONTAINS", 0, ptree, false); | |
292 | + } | |
293 | + int DmpWfsFilter::_Overlaps(boost::property_tree::ptree& ptree) | |
294 | + { | |
295 | + return pGeometrySql("st_overlaps", "OVERLAPBDYDISJOINT+OVERLAPBDYINTERSECT", 0, ptree, false); | |
296 | + } | |
297 | + int DmpWfsFilter::_Disjoint(boost::property_tree::ptree& ptree) | |
298 | + { | |
299 | + return pGeometrySql("st_disjoint", "DISJOINT", 1, ptree, false); | |
300 | + } | |
301 | + int DmpWfsFilter::_FeatureId(boost::property_tree::ptree& ptree) | |
302 | + { | |
303 | + std::string str = ptree.get<std::string>("<xmlattr>.fid"); | |
304 | + /* xml_attribute<char> *a = n->first_attribute("fid"); | |
305 | + if (a == 0) | |
306 | + { | |
307 | + a = n->first_attribute("rid"); | |
308 | + } | |
309 | + if (a) | |
310 | + { | |
311 | + std::string s = a->value(); | |
312 | + int at = s.find("."); | |
313 | + if (at != string::npos) | |
314 | + s = s.substr(at + 1); | |
315 | + sql = sql + initConfig.GetGID(DatabaseType) + "='" + s + "'"; | |
316 | + }*/// | |
317 | + //<FeatureId fid=\"TREESA_1M.9012\"/> \ | |
318 | + | |
319 | + return 0; | |
320 | + } | |
321 | + int DmpWfsFilter::_Intersects(boost::property_tree::ptree& ptree) | |
322 | + { | |
323 | + //return pGeometrySql("st_intersection","ANYINTERACT",0,n,false); | |
324 | + return pGeometrySql("ST_Intersects", "ANYINTERACT", 0, ptree, false); | |
325 | + } | |
326 | + | |
327 | + int DmpWfsFilter::_DIntersects(boost::property_tree::ptree& ptree) | |
328 | + { | |
329 | + //return pGeometrySql("st_intersection","ANYINTERACT",0,n,true); | |
330 | + return pGeometrySql("ST_Intersects", "ANYINTERACT", 0, ptree, true); | |
331 | + } | |
332 | + | |
333 | + int DmpWfsFilter::_GmlObjectId(boost::property_tree::ptree& ptree) | |
334 | + { | |
335 | + return 0; | |
336 | + } | |
337 | + int DmpWfsFilter::_PropertyIsLike(boost::property_tree::ptree& ptree) | |
338 | + { | |
339 | + char wildCard = '*'; | |
340 | + char singleCard = '.'; | |
341 | + char escapeCard = '!'; | |
342 | + //首先取得用户指定的通配符,并进行适当的转换 | |
343 | + /* xml_attribute<char> *attrWildCard = n->first_attribute("wildCard"); | |
344 | + xml_attribute<char> *attrSingleCard = n->first_attribute("singleChar"); | |
345 | + xml_attribute<char> *attrEscapeCard = n->first_attribute("escape"); | |
346 | + if (attrWildCard) | |
347 | + wildCard = ((char *)attrWildCard->value())[0]; | |
348 | + if (attrSingleCard) | |
349 | + singleCard = ((char *)attrSingleCard->value())[0]; | |
350 | + if (attrEscapeCard) | |
351 | + escapeCard = ((char *)attrEscapeCard->value())[0]; | |
352 | + | |
353 | + xml_node<char> *node = n->first_node2("ValueReference", "PropertyName"); | |
354 | + if (node == 0) | |
355 | + return Error(-15, "no enough expression"); | |
356 | + _AppendProperty(sql, node->value()); | |
357 | + if (DatabaseTypePostgreSQL == this->DatabaseType) | |
358 | + { | |
359 | + sql = sql + "::varchar"; | |
360 | + } | |
361 | + sql_ += " LIKE "; | |
362 | + node = n->first_node("Literal"); | |
363 | + if (node == 0) | |
364 | + return Error(-15, "no Literal expression"); | |
365 | + char *valueTem = node->value(); | |
366 | + DmapDll::StringHelp::ReplaceWildCards(valueTem, wildCard, singleCard, escapeCard); | |
367 | + sql_ += "'"; | |
368 | + sql_ += valueTem; | |
369 | + sql_ += "'"; | |
370 | + if (escapeCard != '!') | |
371 | + { | |
372 | + sql_ += " ESCAPE "; | |
373 | + sql_ += "'"; | |
374 | + sql_ += escapeCard; | |
375 | + sql_ += "'"; | |
376 | + }*/// | |
377 | + | |
378 | + return 0; | |
379 | + //return _PropertyOneEqual(n," like",1); | |
380 | + } | |
381 | + int DmpWfsFilter::_PropertyIsNull(boost::property_tree::ptree& ptree) | |
382 | + { | |
383 | + int isExpression; | |
384 | + for (auto ptchild =ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
385 | + { | |
386 | + if(ptchild->first == "<xmlattr>")continue; | |
387 | + int r = _PropertyParse(ptchild->first,ptchild->second, isExpression); | |
388 | + if (r) | |
389 | + return r; | |
390 | + if (isExpression) | |
391 | + { | |
392 | + sql_ += " is null"; | |
393 | + } | |
394 | + return 0; | |
395 | + } | |
396 | + return Error(-24, "_PropertyIsNull node missing"); | |
397 | + } | |
398 | + | |
399 | + int DmpWfsFilter::_PropertyIsBetween(boost::property_tree::ptree& ptree) | |
400 | + { | |
401 | + int isExpression, nc = 0; | |
402 | + //sql+="("; | |
403 | + for (auto ptchild =ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
404 | + { | |
405 | + if(ptchild->first == "<xmlattr>")continue; | |
406 | + int r = _PropertyParse(ptchild->first, ptchild->second, isExpression); | |
407 | + if (r) | |
408 | + return r; | |
409 | + if (isExpression) | |
410 | + { | |
411 | + nc++; | |
412 | + break; | |
413 | + } | |
414 | + } | |
415 | + if (nc == 0) | |
416 | + return Error(-23, "no Property node"); | |
417 | + | |
418 | + sql_ += " between "; | |
419 | + /* { | |
420 | + xml_node<char> *node = n->first_node("LowerBoundary"); | |
421 | + if (node == 0 || node->first_node() == 0) | |
422 | + return Error(-22, "no LowerBoundary node"); | |
423 | + _PropertyParse(node->first_node(), isExpression); | |
424 | + } | |
425 | + sql_ += " and "; | |
426 | + { | |
427 | + xml_node<char> *node = n->first_node("UpperBoundary"); | |
428 | + if (node == 0 || node->first_node() == 0) | |
429 | + return Error(-24, "no UpperBoundary node"); | |
430 | + int isExpression; | |
431 | + _PropertyParse(ptchild->first, ptchild->second, isExpression); | |
432 | + }qingxiongf*/ | |
433 | + //sql+=")"; | |
434 | + return 0; | |
435 | + } | |
436 | + int DmpWfsFilter::_PropertyOneEqual(boost::property_tree::ptree& ptree,const char *type, int isLike) | |
437 | + { | |
438 | + int nc = 0, isExpression; | |
439 | + for (auto ptchild =ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
440 | + { | |
441 | + if(ptchild->first == "<xmlattr>")continue; | |
442 | + int r = _PropertyParse(ptchild->first,ptchild->second, isExpression, isLike); //这里IsLike设定的值是1 | |
443 | + if (r) | |
444 | + return r; | |
445 | + if (isExpression) | |
446 | + { | |
447 | + if (nc == 0) | |
448 | + { | |
449 | + sql_ += type; | |
450 | + } | |
451 | + nc++; | |
452 | + if (nc == 2) | |
453 | + return 0; | |
454 | + } | |
455 | + } | |
456 | + if (nc < 2) | |
457 | + return Error(-19, "no enough expression"); | |
458 | + return 0; | |
459 | + } | |
460 | + int DmpWfsFilter::_PropertyIsEqualTo(boost::property_tree::ptree& ptree) | |
461 | + { | |
462 | + return _PropertyOneEqual(ptree, "="); | |
463 | + } | |
464 | + int DmpWfsFilter::_PropertyParse4(boost::property_tree::ptree& ptree,const char *f) | |
465 | + { | |
466 | + int nc = 0, isExpression; | |
467 | + sql_ += "("; | |
468 | + for (auto ptchild =ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
469 | + { | |
470 | + if(ptchild->first == "<xmlattr>")continue; | |
471 | + int r = _PropertyParse(ptchild->first, ptchild->second, isExpression); | |
472 | + if (r) | |
473 | + return r; | |
474 | + if (isExpression) | |
475 | + { | |
476 | + if (nc == 0) | |
477 | + { | |
478 | + sql_ += f; | |
479 | + } | |
480 | + nc++; | |
481 | + if (nc == 2) | |
482 | + { | |
483 | + sql_ += ")"; | |
484 | + return 0; | |
485 | + } | |
486 | + } | |
487 | + } | |
488 | + if (nc < 2) | |
489 | + return Error(-19, "no enough expression"); | |
490 | + | |
491 | + return 0; | |
492 | + } | |
493 | + int DmpWfsFilter::_PropertyParseFunction(boost::property_tree::ptree& ptree) | |
494 | + { | |
495 | + { | |
496 | + std::string pattr_name = ptree.get<std::string>("<xmlattr>.name"); | |
497 | + // xml_attribute<char> *nameNode = n->first_attribute("name"); | |
498 | + //if (pattr == ptree.end()) | |
499 | + // return Error(-20, "no function name node"); | |
500 | + // char *a = nameNode->value(); | |
501 | + if (pattr_name == "") | |
502 | + return Error(-21, "no function name"); | |
503 | + sql_ += pattr_name; | |
504 | + } | |
505 | + | |
506 | + int isExpression; | |
507 | + sql_ += "("; | |
508 | + for (auto ptchild =ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
509 | + { | |
510 | + int r = _PropertyParse(ptchild->first, ptchild->second, isExpression); | |
511 | + if (r) | |
512 | + return r; | |
513 | + if (isExpression) | |
514 | + { | |
515 | + sql_ += ","; | |
516 | + } | |
517 | + } | |
518 | + | |
519 | + sql_[sql_.size() - 1] = ')'; | |
520 | + //sql+=")"; | |
521 | + return 0; | |
522 | + } | |
523 | + void DmpWfsFilter::_AppendProperty(std::string &sql, const char *str) | |
524 | + { | |
525 | + //sql_ += "\""; | |
526 | + sql_ += str; | |
527 | + //sql_ += "\""; | |
528 | + } | |
529 | + | |
530 | + //<fes:Filter | |
531 | + //xmlns:fes="http://www.opengis.net/fes/2.0" | |
532 | + //xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
533 | + //xsi:schemaLocation="http://www.opengis.net/fes/2.0 | |
534 | + //http://schemas.opengis.net/filter/2.0.0/filterAll.xsd"> | |
535 | + //<fes:PropertyIsLike wildCard="*" singleChar="#" escapeChar="!"> | |
536 | + //<fes:ValueReference>LAST_NAME</fes:ValueReference> | |
537 | + //<fes:Literal>JOHN*</fes:Literal> | |
538 | + //</fes:PropertyIsLike> | |
539 | + //</fes:Filter> | |
540 | + | |
541 | + //我感觉这里应该有一个通配符的转换 | |
542 | + int DmpWfsFilter::_PropertyParse(const std::string& ptreeName, boost::property_tree::ptree& ptree, int &isExpression, int isLike) | |
543 | + { | |
544 | + isExpression = 0; | |
545 | + string name = this->GetFieldName(ptreeName); | |
546 | + const char *p = name.c_str(); | |
547 | + std::string value = ptree.get_value<std::string>(); | |
548 | + if (p == 0 || p[0] == 0) | |
549 | + { | |
550 | + sql_ += "('"; | |
551 | + sql_ += value; | |
552 | + sql_ += "')"; | |
553 | + return 0; | |
554 | + } | |
555 | + if (0 == strcmp(p, "Literal")) | |
556 | + { | |
557 | + isExpression = 1; | |
558 | + if (isLike) | |
559 | + { | |
560 | + sql_ += "('%"; | |
561 | + sql_ += value; | |
562 | + sql_ += "%')"; | |
563 | + } | |
564 | + else | |
565 | + { | |
566 | + sql_ += "('"; | |
567 | + sql_ += value; | |
568 | + sql_ += "')"; | |
569 | + } | |
570 | + return 0; | |
571 | + } | |
572 | + if (0 == strcmp(p, "PropertyName") || 0 == strcmp(p, "ValueReference")) | |
573 | + { | |
574 | + isExpression = 1; | |
575 | + //std::string s=n->value(); | |
576 | + //s=this->td->GetFieldQuery(s); | |
577 | + _AppendProperty(sql_,value.c_str()); //添加了一个字段? | |
578 | + | |
579 | + sql_ = sql_ + "::varchar"; | |
580 | + //sql+=n->value(); | |
581 | + return 0; | |
582 | + } | |
583 | + if (0 == strcmp(p, "Add")) | |
584 | + { | |
585 | + isExpression = 1; | |
586 | + return _PropertyParse4(ptree, "+"); | |
587 | + } | |
588 | + if (0 == strcmp(p, "Sub")) | |
589 | + { | |
590 | + isExpression = 1; | |
591 | + return _PropertyParse4(ptree, "-"); | |
592 | + } | |
593 | + if (0 == strcmp(p, "Mul")) | |
594 | + { | |
595 | + isExpression = 1; | |
596 | + return _PropertyParse4(ptree, "*"); | |
597 | + } | |
598 | + if (0 == strcmp(p, "Div")) | |
599 | + { | |
600 | + isExpression = 1; | |
601 | + return _PropertyParse4(ptree, "/"); | |
602 | + } | |
603 | + if (0 == strcmp(p, "Function")) | |
604 | + { | |
605 | + isExpression = 1; | |
606 | + return _PropertyParseFunction(ptree); | |
607 | + } | |
608 | + return 0; | |
609 | + } | |
610 | + int DmpWfsFilter::_PropertyIsLessThan(boost::property_tree::ptree& ptree) | |
611 | + { | |
612 | + return _PropertyOneEqual(ptree, "<"); | |
613 | + } | |
614 | + int DmpWfsFilter::_PropertyIsNotEqualTo(boost::property_tree::ptree& ptree) | |
615 | + { | |
616 | + return _PropertyOneEqual(ptree, "<>"); | |
617 | + } | |
618 | + int DmpWfsFilter::_PropertyIsGreaterThan(boost::property_tree::ptree& ptree) | |
619 | + { | |
620 | + return _PropertyOneEqual(ptree, ">"); | |
621 | + } | |
622 | + int DmpWfsFilter::_PropertyIsLessThanOrEqualTo(boost::property_tree::ptree& ptree) | |
623 | + { | |
624 | + return _PropertyOneEqual(ptree, "<="); | |
625 | + } | |
626 | + int DmpWfsFilter::_PropertyIsGreaterThanOrEqualTo(boost::property_tree::ptree& ptree) | |
18 | 627 | { |
628 | + return _PropertyOneEqual(ptree, ">="); | |
629 | + } | |
630 | + | |
631 | + void DmpWfsFilter::pParsesrsName(boost::property_tree::ptree& ptree) | |
632 | + { | |
633 | + // xml_attribute<char> *sr = n->first_attribute("srsName"); | |
634 | + /*std::string atrr = ptree.get<std::string>("srsName"); | |
635 | + if (!atrr.empty()) | |
636 | + { | |
637 | + char *s = _strdup(sr->value()); | |
638 | + clsMalloc m(s); | |
639 | + if (s == 0 || s[0] == 0) | |
640 | + return; | |
641 | + char *ss[10]; | |
642 | + int n = DmapDll::StringHelp::ParseStringTok(s, '#', ss, 10); | |
643 | + char *sa = ss[n - 1]; | |
644 | + int len = strlen(sa); | |
645 | + for (int i = 0; i < len; i++) | |
646 | + { | |
647 | + if (sa[i] == '_') | |
648 | + sa[i] = ':'; | |
649 | + } | |
650 | + n = DmapDll::StringHelp::ParseStringTok(sa, ':', ss, 10); | |
651 | + //parse epsg:5432 | |
652 | + sa = ss[n - 1]; | |
653 | + strcpy_s((char *)srs.c_str(), sa); | |
654 | + } qingxiongf*/ | |
655 | + | |
656 | + } | |
657 | + int DmpWfsFilter::pEnvelope(boost::property_tree::ptree& ptree, double *x1, double *y1, double *x2, double *y2) | |
658 | + { | |
659 | + /* xml_node<char> *node = n->first_node("lowerCorner"); //,"ogc:PropertyName"); | |
660 | + if (node) | |
661 | + { | |
662 | + xml_node<char> *node1 = n->first_node("upperCorner"); //,"ogc:PropertyName"); | |
663 | + if (!node1) | |
664 | + return this->Error(-2, "upperCorner missing"); | |
665 | + sscanf(node->value(), "%lf %lf", x1, y1); | |
666 | + sscanf(node1->value(), "%lf %lf", x2, y2); | |
667 | + return 0; | |
668 | + } | |
669 | + else | |
670 | + { | |
671 | + std::vector<double> v; | |
672 | + int rt = pGeometryPointArray(n, v); | |
673 | + if (rt) | |
674 | + return rt; | |
675 | + if (v.size() < 4) | |
676 | + return Error(-16231, "point array too small"); | |
677 | + | |
678 | + //这里不太好吧,只要有个不合法的请求就会死掉 | |
679 | + *x1 = v[0]; | |
680 | + *y1 = v[1]; | |
681 | + *x2 = v[2]; | |
682 | + *y2 = v[3]; | |
683 | + return 0; | |
684 | + } | |
685 | + qingxiongf*/ | |
686 | + | |
687 | + return Error(-4214, "envope parse error"); | |
688 | + } | |
689 | + | |
690 | + | |
691 | + | |
692 | + //这个函数是对数字进行解析(前到空格去掉,后面的空格可以作为结束标志。。。) | |
693 | + int DmpWfsFilter::pGeometryDouble(char *d, bool space_before, bool space_after, double &dbl) | |
694 | + { | |
695 | + char *p; | |
696 | + int st; | |
697 | + enum states //用来维护状态 | |
698 | + { | |
699 | + INIT = 0, | |
700 | + NEED_DIG = 1, | |
701 | + DIG = 2, | |
702 | + NEED_DIG_DEC = 3, | |
703 | + DIG_DEC = 4, | |
704 | + EXP = 5, | |
705 | + NEED_DIG_EXP = 6, | |
706 | + DIG_EXP = 7, | |
707 | + END = 8 | |
708 | + }; | |
709 | + | |
710 | + //下面这段代码主要是进行了所传数字有效性的验证吧? | |
711 | + if (space_before) | |
712 | + while (isspace(*d)) | |
713 | + d++; //再次的消除空格 | |
714 | + for (st = INIT, p = d; *p; p++) | |
715 | + { | |
716 | + | |
717 | + if (isdigit(*p)) | |
718 | + { | |
719 | + if (st == INIT || st == NEED_DIG) | |
720 | + st = DIG; //刚开始或者是期望是数字,转换为是数字 | |
721 | + else if (st == NEED_DIG_DEC) | |
722 | + st = DIG_DEC; //期望是小数,转化为时小数 | |
723 | + else if (st == NEED_DIG_EXP || st == EXP) | |
724 | + st = DIG_EXP; //已经是一个科学计数法,或者期望是一个科学计数法 | |
725 | + else if (st == DIG || st == DIG_DEC || st == DIG_EXP) | |
726 | + ; //已经是数字,小数,科学计数法,则不做转换 | |
727 | + else | |
728 | + return Error(-4, "invalid digital"); | |
729 | + } | |
730 | + else if (*p == '.') | |
731 | + { | |
732 | + if (st == DIG) | |
733 | + st = NEED_DIG_DEC; //从数字转换到期望是小数的状态(否则出错) | |
734 | + else | |
735 | + return Error(-4, "invalid digital"); | |
736 | + } | |
737 | + else if (*p == '-' || *p == '+') | |
738 | + { | |
739 | + if (st == INIT) | |
740 | + st = NEED_DIG; | |
741 | + else if (st == EXP) | |
742 | + st = NEED_DIG_EXP; | |
743 | + else | |
744 | + return Error(-4, "invalid digital"); | |
745 | + } | |
746 | + else if (*p == 'e' || *p == 'E') //科学计数法 | |
747 | + { | |
748 | + if (st == DIG || st == DIG_DEC) | |
749 | + st = EXP; | |
750 | + else | |
751 | + return Error(-4, "invalid digital"); | |
752 | + } | |
753 | + else if (isspace(*p)) | |
754 | + { | |
755 | + if (!space_after) | |
756 | + return Error(-4, "invalid digital"); | |
757 | + if (st == DIG || st == DIG_DEC || st == DIG_EXP) | |
758 | + st = END; | |
759 | + else if (st == NEED_DIG_DEC) | |
760 | + st = END; | |
761 | + else if (st == END) | |
762 | + ; | |
763 | + else | |
764 | + return Error(-4, "invalid digital"); | |
765 | + } | |
766 | + else | |
767 | + return Error(-4, "invalid digital"); | |
768 | + } | |
769 | + | |
770 | + if (st != DIG && st != NEED_DIG_DEC && st != DIG_DEC && st != DIG_EXP && st != END) | |
771 | + return Error(-4, "invalid digital"); | |
772 | + dbl = atof(d); | |
773 | + return 0; | |
774 | + } | |
775 | + | |
776 | + //这个函数写的很棒啊。。。 | |
777 | + int DmpWfsFilter::pGeometryPointValuePos(char *pos, std::vector<double> &v) | |
778 | + { | |
779 | + while (isspace(*pos)) | |
780 | + pos++; /* Eat extra whitespaces if any */ //跳过空格 | |
781 | + /* gml:pos pattern: x1 y1 | |
782 | + * x1 y1 z1 | |
783 | + */ | |
784 | + int gml_dim = 0; | |
785 | + bool digit = false; | |
786 | + double dbl; | |
787 | + for (char *p = pos; *pos; pos++) | |
788 | + { | |
789 | + if (isdigit(*pos)) | |
790 | + digit = true; | |
791 | + if (digit && (*pos == ' ' || *(pos + 1) == '\0')) | |
792 | + { | |
793 | + if (*pos == ' ') | |
794 | + *pos = '\0'; | |
795 | + gml_dim++; | |
796 | + if (gml_dim == 1) | |
797 | + { | |
798 | + int rt = pGeometryDouble(p, true, true, dbl); | |
799 | + if (rt) | |
800 | + return rt; | |
801 | + v.push_back(dbl); | |
802 | + } | |
803 | + else if (gml_dim == 2) | |
804 | + { | |
805 | + int rt = pGeometryDouble(p, true, true, dbl); | |
806 | + if (rt) | |
807 | + return rt; | |
808 | + v.push_back(dbl); | |
809 | + } | |
810 | + else if (gml_dim == 3) | |
811 | + { | |
812 | + } | |
813 | + // pt.z = parse_gml_double(p, true, true); | |
814 | + p = pos + 1; | |
815 | + digit = false; | |
816 | + } | |
817 | + } | |
818 | + | |
819 | + return 0; | |
820 | + } | |
821 | + | |
822 | + int DmpWfsFilter::pGeometryPointValuePosList(boost::property_tree::ptree& ptree, std::vector<double> &v) | |
823 | + { | |
824 | + /* int dim = 2; | |
825 | + xml_attribute<char> *pn = n->first_attribute("dimension"); | |
826 | + if (pn) | |
827 | + { | |
828 | + dim = atoi(pn->value()); | |
829 | + } | |
830 | + if (dim > 3 || dim < 2) | |
831 | + return Error(-6, "dim >3 or dim<2"); | |
832 | + char *poslist = (char *)n->value(); | |
833 | + while (isspace(*poslist)) | |
834 | + poslist++; | |
835 | + double dbl; | |
836 | + int gml_dim = 0; //跳过空格 | |
837 | + for (char *p = poslist, digit = false; *poslist; poslist++) | |
838 | + { | |
839 | + if (isdigit(*poslist)) | |
840 | + digit = true; | |
841 | + //以空格分割 | |
842 | + if (digit && (*poslist == ' ' || *(poslist + 1) == '\0')) | |
843 | + { | |
844 | + if (*poslist == ' ') | |
845 | + *poslist = '\0'; | |
846 | + | |
847 | + gml_dim++; | |
848 | + if (gml_dim == 1) | |
849 | + { | |
850 | + int rt = pGeometryDouble(p, true, true, dbl); | |
851 | + if (rt) | |
852 | + return rt; | |
853 | + v.push_back(dbl); | |
854 | + } | |
855 | + else if (gml_dim == 2) | |
856 | + { | |
857 | + int rt = pGeometryDouble(p, true, true, dbl); | |
858 | + if (rt) | |
859 | + return rt; | |
860 | + v.push_back(dbl); | |
861 | + } | |
862 | + //else if (gml_dim == 3) pt.z = parse_gml_double(p, true, true); | |
863 | + | |
864 | + if (gml_dim == dim) | |
865 | + { | |
866 | + gml_dim = 0; | |
867 | + } | |
868 | + else if (*(poslist + 1) == '\0') | |
869 | + { | |
870 | + return Error(-7, "char missing"); | |
871 | + } | |
872 | + | |
873 | + p = poslist + 1; | |
874 | + digit = false; | |
875 | + } | |
876 | + }qingxiongf*/ | |
877 | + return 0; | |
878 | + } | |
879 | + | |
880 | + int DmpWfsFilter::pGeometryGetDis(boost::property_tree::ptree& ptree, double &dis) | |
881 | + { | |
882 | + /* | |
883 | + | |
884 | + double ratio = 1; | |
885 | + { | |
886 | + rapidxml::xml_attribute<char> *t = n->first_attribute("unit"); | |
887 | + if (t) | |
888 | + { | |
889 | + char *p = t->value(); | |
890 | + size_t size = strlen(p); | |
891 | + int found = 0; | |
892 | + for (size_t i = size - 1; i >= 0; i--) | |
893 | + { | |
894 | + if (p[i] == '#') | |
895 | + { | |
896 | + found = 1; | |
897 | + p += i + 1; | |
898 | + break; | |
899 | + } | |
900 | + } | |
901 | + if (strcmp(p, "kilometers") == 0) | |
902 | + { | |
903 | + ratio = 1000; | |
904 | + } | |
905 | + else if (strcmp(p, "kilometer") == 0) | |
906 | + { | |
907 | + ratio = 1000; | |
908 | + } | |
909 | + } | |
910 | + } | |
911 | + | |
912 | + double f = atof(n->value()); | |
913 | + f = f * ratio; | |
914 | + | |
915 | + dis = f; | |
916 | + // rapidxml::xml_node<char> * t=n->first_node("X"); | |
917 | +qingxiongf*/ | |
918 | + return 0; | |
919 | + } | |
920 | + | |
921 | + void DmpWfsFilter::GetQueryField(std::string &field) | |
922 | + { | |
923 | + return ; | |
924 | + } | |
925 | + | |
926 | + int DmpWfsFilter::Error(int code, const char *err) | |
927 | + { | |
928 | + error_ = err; | |
929 | + errorCode_ = code; | |
930 | + return code; | |
931 | + } | |
932 | + | |
933 | + int DmpWfsFilter::pGeometrySql(const char *function,const char *oracle_mask, int isDisjoin, boost::property_tree::ptree &ptree, bool useBuffer) | |
934 | + { | |
935 | + { | |
936 | + std::string value = ptree.get<std::string>("PropertyName.ValueReference"); | |
937 | + // xml_node<char> *nodeP = n->first_node2("PropertyName", "ValueReference"); //,"ogc:PropertyName"); | |
938 | + //if (nodeP == 0 || nodeP->value()[0] == 0) | |
939 | + // return Error(-15, "no PropertyName node"); | |
940 | + GetQueryField(value); | |
941 | + } | |
942 | + double dis; | |
943 | + if (useBuffer) | |
944 | + { | |
945 | + boost::property_tree::ptree pDistance = ptree.get_child("Distance"); | |
946 | + // xml_node<char> *nodeD = n->first_node("Distance"); //,"ogc:PropertyName"); | |
947 | + // if (nodeD == 0) | |
948 | + // return Error(-15, "no Distance node"); | |
949 | + int rt = pGeometryGetDis(pDistance, dis); | |
950 | + if (rt) | |
951 | + return Error(-15, "no Distance node"); | |
952 | + } | |
953 | + | |
954 | + std::string strOut; | |
955 | + double x1, y1, x2, y2; | |
956 | + int ee = GetGeomFromGml(ptree, strOut, x1, y1, x2, y2); | |
957 | + if (ee) | |
958 | + return Error(ee, "gml parse error"); | |
959 | + if (useBuffer) | |
960 | + { | |
961 | + x1 -= dis; | |
962 | + y1 -= dis; | |
963 | + x2 += dis; | |
964 | + y2 += dis; | |
965 | + } | |
966 | + | |
967 | + if (useBuffer) | |
968 | + { | |
969 | + if (strcmp(function, "ST_DWithin") == 0) | |
970 | + { | |
971 | + char sz[200]; | |
972 | + sprintf(sz, "%lf", dis); | |
973 | + std::string s = strOut + ","; | |
974 | + s += sz; | |
975 | + strOut = s; | |
976 | + } | |
977 | + else | |
978 | + { | |
979 | + if (strcmp(function, "st_intersection") == 0) | |
980 | + { | |
981 | + function = "st_intersects"; | |
982 | + } | |
983 | + | |
984 | + char sz[200]; | |
985 | + sprintf(sz, "%lf", dis); | |
986 | + std::string s = "st_buffer("; | |
987 | + s = s + strOut; | |
988 | + s = s + ","; | |
989 | + s = s + sz; | |
990 | + s = s + ")"; | |
991 | + strOut = s; | |
992 | + } | |
993 | + } | |
994 | + sql_ += function; | |
995 | + sql_ += "("; | |
996 | + { | |
997 | + std::string nameOut; | |
998 | + // ConnClassAll::GetSRIDName(fieldTemp, nameOut, (char *)srs.c_str(), this->DatabaseType); | |
999 | + sql_ += nameOut; | |
1000 | + } | |
1001 | + sql_ += ","; | |
1002 | + sql_ += strOut; | |
1003 | + sql_ += ")"; | |
1004 | + | |
1005 | + return 0; | |
1006 | + } | |
1007 | + | |
1008 | + /* | |
1009 | + int DmpWfsFilter::pGeometryPointValueCoord(boost::property_tree::ptree& ptree, std::vector<double> &v) | |
1010 | + { | |
1011 | + double x, y; | |
1012 | + rapidxml::xml_node<char> *t = n->first_node("X"); | |
1013 | + if (t == 0) | |
1014 | + return Error(-9, "X node not found"); | |
1015 | + x = atof(t->value()); | |
1016 | + t = n->first_node("Y"); | |
1017 | + if (t == 0) | |
1018 | + return Error(-10, "Y node not found"); | |
1019 | + y = atof(t->value()); | |
1020 | + v.push_back(x); | |
1021 | + v.push_back(y); | |
1022 | + return 0; | |
1023 | + } | |
1024 | + qingxiongf*/ | |
1025 | + /* | |
1026 | + int DmpWfsFilter::pGeometryPointValuePointRep(boost::property_tree::ptree& ptree, std::vector<double> &v) | |
1027 | + { | |
1028 | + double x, y; | |
1029 | + rapidxml::xml_node<char> *t = n->first_node("Point"); | |
1030 | + if (t == 0) | |
1031 | + return Error(-9, "Point node not found"); | |
1032 | + t = t->first_node("pos"); | |
1033 | + if (t == 0) | |
1034 | + return Error(-9, "pos node not found"); | |
1035 | + char *p = t->value(); | |
1036 | + sscanf(p, "%lf %lf", &x, &y); | |
1037 | + v.push_back(x); | |
1038 | + v.push_back(y); | |
1039 | + return 0; | |
1040 | + } | |
1041 | +qingxiongf*/ | |
1042 | + //来看看这个函数 | |
1043 | + int DmpWfsFilter::pGeometryPointValueCoordinates(char *p, std::vector<double> &v) | |
1044 | + { | |
1045 | + char cs, ts, dec; | |
1046 | + cs = ','; | |
1047 | + ts = ' '; | |
1048 | + dec = '.'; | |
1049 | + bool digit; | |
1050 | + int gml_dims; | |
1051 | + while (isspace(*p)) | |
1052 | + p++; | |
1053 | + char *q; | |
1054 | + double dbl; //跳过空格 | |
1055 | + for (q = p, gml_dims = 0, digit = false; *p; p++) | |
1056 | + { | |
1057 | + if (isdigit(*p)) | |
1058 | + digit = true; | |
1059 | + //逗号分割 | |
1060 | + if (*p == cs) | |
1061 | + { | |
1062 | + *p = '\0'; | |
1063 | + gml_dims++; | |
1064 | + | |
1065 | + if (*(p + 1) == '\0') | |
1066 | + return Error(-8, "invalid gml"); | |
1067 | + | |
1068 | + if (gml_dims == 1) | |
1069 | + { | |
1070 | + int rt = pGeometryDouble(q, false, true, dbl); | |
1071 | + if (rt) | |
1072 | + return rt; | |
1073 | + v.push_back(dbl); | |
1074 | + } | |
1075 | + else if (gml_dims == 2) | |
1076 | + { | |
1077 | + int rt = pGeometryDouble(q, false, true, dbl); | |
1078 | + if (rt) | |
1079 | + return rt; | |
1080 | + v.push_back(dbl); | |
1081 | + } | |
1082 | + | |
1083 | + q = p + 1; | |
1084 | + } | |
1085 | + //空格分割... | |
1086 | + else if (digit && (*p == ts || *(p + 1) == '\0')) | |
1087 | + { | |
1088 | + if (*p == ts) | |
1089 | + *p = '\0'; | |
1090 | + gml_dims++; | |
1091 | + | |
1092 | + if (gml_dims < 2 || gml_dims > 3) | |
1093 | + { | |
1094 | + return Error(-8, "invalid gml"); | |
1095 | + } | |
1096 | + | |
1097 | + if (gml_dims == 3) | |
1098 | + { | |
1099 | + int rt = pGeometryDouble(q, false, true, dbl); | |
1100 | + if (rt) | |
1101 | + return rt; | |
1102 | + } | |
1103 | + else | |
1104 | + { | |
1105 | + int rt = pGeometryDouble(q, false, true, dbl); | |
1106 | + if (rt) | |
1107 | + return rt; | |
1108 | + v.push_back(dbl); | |
1109 | + //*hasz = false; | |
1110 | + } | |
1111 | + | |
1112 | + // dynptarray_addPoint4d(dpa, &pt, 0); | |
1113 | + digit = false; | |
1114 | + | |
1115 | + q = p + 1; | |
1116 | + gml_dims = 0; | |
1117 | + | |
1118 | + /* Need to put standard decimal separator to atof handle */ | |
1119 | + } | |
1120 | + else if (*p == dec && dec != '.') | |
1121 | + *p = '.'; //处理小数 | |
1122 | + } | |
1123 | + return 0; | |
1124 | + } | |
1125 | + | |
1126 | + //得到点数组 | |
1127 | + int DmpWfsFilter::pGeometryPointArray(boost::property_tree::ptree& ptree, std::vector<double> &v) | |
1128 | + { | |
1129 | + for (auto ptchild =ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
1130 | + { | |
1131 | + std::string name = ptchild->first; | |
1132 | + | |
1133 | + if (!strcmp((char *)name.c_str(), "pos") || !strcmp((char *)name.c_str(), "gml:pos")) //以空格分割的坐标数据 | |
1134 | + { | |
1135 | + std::string value = ptchild->second.get_value<std::string>(); | |
1136 | + return pGeometryPointValuePos((char*)value.c_str(), v); | |
1137 | + } | |
1138 | + else if (!strcmp((char *)name.c_str(), "posList") || !strcmp((char *)name.c_str(), "gml:posList")) //有维度,以空格分割的坐标数据 | |
1139 | + { | |
1140 | + return pGeometryPointValuePosList( ptchild->second, v); | |
1141 | + } | |
1142 | + else if (!strcmp((char *)name.c_str(), "coordinates") || !strcmp((char *)name.c_str(), "gml:coordinates")) //以空格或者逗号分割的数据 | |
1143 | + { | |
1144 | + std::string value = ptchild->second.get_value<std::string>(); | |
1145 | + return pGeometryPointValueCoordinates((char*)value.c_str(), v); | |
1146 | + } | |
1147 | + else if (!strcmp((char *)name.c_str(), "coord") || !strcmp((char *)name.c_str(), "gml:coord")) //坐标,似乎只能得到一个点哦。。。 | |
1148 | + { | |
1149 | + return pGeometryPointValueCoord(ptchild->second, v); | |
1150 | + } | |
1151 | + else if ((!strcmp((char *)name.c_str(), "pointRep")) || (!strcmp((char *)name.c_str(), "pointProperty")) || (!strcmp((char *)name.c_str(), "gml:pointRep")) || (!strcmp((char *)name.c_str(), "gml:pointProperty"))) | |
1152 | + { | |
1153 | + return pGeometryPointValuePointRep(ptchild->second, v); | |
1154 | + } | |
1155 | + } | |
1156 | + return Error(-10, "point node not exist"); | |
1157 | + } | |
1158 | +/* | |
1159 | + int DmpWfsFilter::pGeometryEnvope(boost::property_tree::ptree& ptree, DmpWfsGmlObject **g) | |
1160 | + { | |
1161 | + pParsesrsName(n); | |
1162 | + double x1, y1, x2, y2; | |
1163 | + int re = pEnvelope(n, &x1, &y1, &x2, &y2); | |
1164 | + if (re) | |
1165 | + return Error(-25, "Envope error"); | |
1166 | + clsGmlBBox *mp = new clsGmlBBox(x1, y1, x2, y2); | |
1167 | + *g = mp; | |
1168 | + return 0; | |
1169 | + } | |
1170 | +qingxingf*/ | |
1171 | +/* | |
1172 | + int DmpWfsFilter::pGeometryMultiPoint(boost::property_tree::ptree& ptree, DmpWfsGmlObject **g) | |
1173 | + { | |
1174 | + xml_node<char> *node; | |
1175 | + clsGmlMultiPoint *mp = new clsGmlMultiPoint(); | |
1176 | + clsGmlPoint *l; | |
1177 | + for (node = n->first_node2("pointMember", "pointMembers"); node; node = node->next_sibling2("pointMember", "pointMembers")) | |
1178 | + { | |
1179 | + rapidxml::xml_node<char> *t1 = node->first_node("Point"); | |
1180 | + if (t1 == 0) | |
1181 | + { | |
1182 | + delete mp; | |
1183 | + return Error(-13, "no Point node"); | |
1184 | + } | |
1185 | + int rt = pGeometryPoint(t1, (DmpWfsGmlObject **)(&l)); | |
1186 | + if (rt) | |
1187 | + { | |
1188 | + delete mp; | |
1189 | + return rt; | |
1190 | + } | |
1191 | + mp->x.push_back(l->x); | |
1192 | + mp->y.push_back(l->y); | |
1193 | + } | |
1194 | + if (mp->x.size() < 1) | |
1195 | + { | |
1196 | + delete mp; | |
1197 | + return Error(-14, "no Point node"); | |
1198 | + } | |
1199 | + *g = mp; | |
1200 | + return 0; | |
1201 | + } | |
1202 | +qingxingf*/ | |
1203 | +/* | |
1204 | + int DmpWfsFilter::pGeometryMultiPolyline(boost::property_tree::ptree& ptree, DmpWfsGmlObject **g) | |
1205 | + { | |
1206 | + xml_node<char> *node; | |
1207 | + clsGmlPolyline *plyg = new clsGmlPolyline(); | |
1208 | + for (node = n->first_node("polylineMember"); node; node = node->next_sibling("polylineMember")) | |
1209 | + { | |
1210 | + xml_node<char> *nodeN; | |
1211 | + for (nodeN = node->first_node("Polyline"); nodeN; nodeN = nodeN->next_sibling("Polyline")) | |
1212 | + { | |
1213 | + DmpWfsGmlObject *gT; | |
1214 | + pGeometryPolyline(nodeN, &gT); | |
1215 | + if (gT) | |
1216 | + { | |
1217 | + plyg->Append((clsGmlPolyline *)gT); | |
1218 | + delete gT; | |
1219 | + } | |
1220 | + } | |
1221 | + } | |
1222 | + if (plyg->outer.size() < 1) | |
1223 | + { | |
1224 | + delete plyg; | |
1225 | + return Error(-14, "no line string"); | |
1226 | + } | |
1227 | + *g = plyg; | |
1228 | + return 0; | |
1229 | + } | |
1230 | + qingxiongf*/ | |
1231 | +/* | |
1232 | + int DmpWfsFilter::pGeometryMultiPolygon(boost::property_tree::ptree& ptree, DmpWfsGmlObject **g) | |
1233 | + { | |
1234 | + xml_node<char> *node; | |
1235 | + clsGmlPolygon *plyg = new clsGmlPolygon(); | |
1236 | + for (node = n->first_node2("polygonMember", "PolygonMember"); node; node = node->next_sibling2("polygonMember", "PolygonMember")) | |
1237 | + { | |
1238 | + xml_node<char> *nodeN; | |
1239 | + for (nodeN = node->first_node("Polygon"); nodeN; nodeN = nodeN->next_sibling("Polygon")) | |
1240 | + { | |
1241 | + DmpWfsGmlObject *gT = NULL; | |
1242 | + pGeometryPolygon(nodeN, &gT); | |
1243 | + if (gT) | |
1244 | + { | |
1245 | + plyg->Append((clsGmlPolygon *)gT); | |
1246 | + delete gT; | |
1247 | + } | |
1248 | + } | |
1249 | + } | |
1250 | + | |
1251 | + if (plyg->outer.size() < 1) | |
1252 | + { | |
1253 | + delete plyg; | |
1254 | + return Error(-14, "no exterior ring"); | |
1255 | + } | |
1256 | + *g = plyg; | |
1257 | + return 0; | |
1258 | + } | |
1259 | + qingxingf*/ | |
1260 | + /* | |
1261 | + int DmpWfsFilter::pGeometryPolygon(boost::property_tree::ptree& ptree, DmpWfsGmlObject **g) | |
1262 | + { | |
1263 | + xml_node<char> *node; | |
1264 | + clsGmlPolygon *plyg = new clsGmlPolygon(); | |
1265 | + DmpWfsGmlObject *l; | |
1266 | + for (node = n->first_node2("exterior", "outerBoundaryIs"); node; node = node->next_sibling2("exterior", "outerBoundaryIs")) | |
1267 | + { | |
1268 | + rapidxml::xml_node<char> *t1 = node->first_node("LinearRing"); | |
1269 | + if (t1 == 0) | |
1270 | + t1 = node->first_node2("LineString", "lineString"); | |
1271 | + if (t1 == 0) | |
1272 | + { | |
1273 | + delete plyg; | |
1274 | + return Error(-13, "no LineString node"); | |
1275 | + } | |
1276 | + int rt = pGeometryLineString(t1, &l); | |
1277 | + if (rt) | |
1278 | + { | |
1279 | + delete plyg; | |
1280 | + return rt; | |
1281 | + } | |
1282 | + plyg->outer.push_back((clsGmlLineString *)l); | |
1283 | + } | |
1284 | + for (node = n->first_node2("interior", "innerBoundaryIs"); node; node = node->next_sibling2("interior", "innerBoundaryIs")) | |
1285 | + { | |
1286 | + rapidxml::xml_node<char> *t1 = node->first_node("LinearRing"); | |
1287 | + if (t1 == 0) | |
1288 | + t1 = node->first_node2("LineString", "lineString"); | |
1289 | + if (t1 == 0) | |
1290 | + { | |
1291 | + delete plyg; | |
1292 | + return Error(-13, "no LineString node"); | |
1293 | + } | |
1294 | + int rt = pGeometryLineString(t1, &l); | |
1295 | + if (rt) | |
1296 | + { | |
1297 | + delete plyg; | |
1298 | + return rt; | |
1299 | + } | |
1300 | + plyg->inner.push_back((clsGmlLineString *)l); | |
1301 | + } | |
1302 | + if (plyg->outer.size() < 1) | |
1303 | + { | |
1304 | + delete plyg; | |
1305 | + return Error(-14, "no exterior ring"); | |
1306 | + } | |
1307 | + | |
1308 | + *g = plyg; | |
1309 | + return 0; | |
1310 | + } | |
1311 | +qingxingf*/ | |
1312 | +/* | |
1313 | + int DmpWfsFilter::pGeometryPolyline(boost::property_tree::ptree& ptree, DmpWfsGmlObject **g) | |
1314 | + { | |
1315 | + xml_node<char> *node; | |
1316 | + clsGmlPolyline *plyg = new clsGmlPolyline(); | |
1317 | + DmpWfsGmlObject *l; | |
1318 | + for (node = n->first_node2("lineStringMember", "gml::lineStringMember"); node; node = node->next_sibling2("lineStringMember", "gml::lineStringMember")) | |
1319 | + { | |
1320 | + rapidxml::xml_node<char> *t1 = node->first_node("LinearRing"); | |
1321 | + if (t1 == 0) | |
1322 | + t1 = node->first_node2("LineString", "lineString"); | |
1323 | + if (t1 == 0) | |
1324 | + { | |
1325 | + delete plyg; | |
1326 | + return Error(-13, "no LineString node"); | |
1327 | + } | |
1328 | + int rt = pGeometryLineString(t1, &l); | |
1329 | + if (rt) | |
1330 | + { | |
1331 | + delete plyg; | |
1332 | + return rt; | |
1333 | + } | |
1334 | + plyg->outer.push_back((clsGmlLineString *)l); | |
1335 | + } | |
1336 | + if (plyg->outer.size() < 1) | |
1337 | + { | |
1338 | + delete plyg; | |
1339 | + return Error(-14, "no linestring"); | |
1340 | + } | |
1341 | + *g = plyg; | |
1342 | + return 0; | |
1343 | + } | |
1344 | +qingxingf*/ | |
1345 | + int DmpWfsFilter::pGeometryLineString(boost::property_tree::ptree& ptree, DmpWfsGmlObject **g) | |
1346 | + { | |
1347 | + /* | |
1348 | + std::vector<double> v; | |
1349 | + int rt = pGeometryPointArray(n, v); | |
1350 | + if (rt) | |
1351 | + return rt; | |
1352 | + size_t vs = (size_t)v.size(); | |
1353 | + if (vs < 4) | |
1354 | + return Error(-11, "point array too small"); | |
1355 | + size_t vs2 = vs / 2; | |
1356 | + if ((2 * vs2) != vs) | |
1357 | + return Error(-12, "point array error"); | |
1358 | + | |
1359 | + clsGmlLineString *l = new clsGmlLineString(); | |
1360 | + //l.size= | |
1361 | + l->x.resize(vs2); | |
1362 | + l->y.resize(vs2); | |
1363 | + for (size_t i = 0, j = 0; i < vs2; i++) | |
1364 | + { | |
1365 | + l->x[i] = v[j]; | |
1366 | + j++; | |
1367 | + l->y[i] = v[j]; | |
1368 | + j++; | |
1369 | + } | |
1370 | + | |
1371 | + *g = l; qingxiongf*/ | |
1372 | + return 0; | |
1373 | + } | |
1374 | +/* | |
1375 | + void DmpWfsFilter::parse_gml_srs(boost::property_tree::ptree& ptree, gmlSrs *srs) | |
1376 | + { | |
1377 | + char *p; | |
1378 | + int is_planar; | |
1379 | + bool latlon = false; | |
1380 | + char sep = ':'; | |
1381 | + | |
1382 | + const char *srsname; | |
1383 | + xml_attribute<char> *pn = n->first_attribute("srsName"); | |
1384 | + if (pn) | |
1385 | + { | |
1386 | + srsname = pn->value(); | |
1387 | + } | |
1388 | + else | |
1389 | + { | |
1390 | + srs->srid = initConfig.DefaultSRID; | |
1391 | + srs->reverse_axis = false; | |
1392 | + return; | |
1393 | + } | |
1394 | + | |
1395 | + if (!strncmp((char *)srsname, "EPSG:", 5)) | |
1396 | + { | |
1397 | + sep = ':'; | |
1398 | + latlon = false; | |
1399 | + } | |
1400 | + else if (!strncmp((char *)srsname, "urn:ogc:def:crs:EPSG:", 21) || !strncmp((char *)srsname, "urn:x-ogc:def:crs:EPSG:", 23) || !strncmp((char *)srsname, "urn:EPSG:geographicCRS:", 23)) | |
1401 | + { | |
1402 | + sep = ':'; | |
1403 | + latlon = true; | |
1404 | + } | |
1405 | + else if (!strncmp((char *)srsname, | |
1406 | + "http://www.opengis.net/gml/srs/epsg.xml#", 40)) | |
1407 | + { | |
1408 | + sep = '#'; | |
1409 | + latlon = false; | |
1410 | + } | |
1411 | + else | |
1412 | + { | |
1413 | + srs->srid = initConfig.DefaultSRID; | |
1414 | + srs->reverse_axis = false; | |
1415 | + return; | |
1416 | + } | |
1417 | + | |
1418 | + | |
1419 | + for (p = (char *)srsname; *p; p++) | |
1420 | + ; | |
1421 | + for (--p; *p != sep; p--) | |
1422 | + { | |
1423 | + if (!isdigit(*p)) | |
1424 | + { | |
1425 | + srs->srid = initConfig.DefaultSRID; | |
1426 | + srs->reverse_axis = false; | |
1427 | + return; | |
1428 | + } | |
1429 | + } | |
1430 | + | |
1431 | + srs->srid = p; | |
1432 | + p++; // atoi(++p); | |
1433 | + int id = atoi(srs->srid.c_str()); | |
1434 | + return; | |
1435 | + } | |
1436 | + | |
1437 | + int DmpWfsFilter::pGeometryPoint(boost::property_tree::ptree& ptree, DmpWfsGmlObject **g) | |
1438 | + { | |
1439 | + std::vector<double> v; | |
1440 | + int rt = pGeometryPointArray(n, v); | |
1441 | + if (rt) | |
1442 | + return rt; | |
1443 | + if (v.size() < 2) | |
1444 | + return Error(-10, "point array too small"); | |
1445 | + clsGmlPoint *p = new clsGmlPoint(); | |
1446 | + p->x = v[0]; | |
1447 | + p->y = v[1]; | |
1448 | + *g = p; | |
1449 | + return 0; | |
1450 | + } | |
1451 | + int DmpWfsFilter::pGeometry(boost::property_tree::ptree& ptree, DmpWfsGmlObject **g) | |
1452 | + { | |
1453 | + rapidxml::xml_node<char> *t; | |
1454 | + //这种方式更好 | |
1455 | + //for (auto ptchild =ptree.begin(); ptchild != ptree.end(); ++ptchild); | |
1456 | + | |
1457 | + t = n->first_node2("Point", "gml:Point"); | |
1458 | + if (t) | |
1459 | + { | |
1460 | + pParsesrsName(t); | |
1461 | + return pGeometryPoint(t, g); | |
1462 | + } | |
1463 | + t = n->first_node2("LineString", "gml:LineString"); | |
1464 | + if (t) | |
1465 | + { | |
1466 | + pParsesrsName(t); | |
1467 | + return pGeometryLineString(t, g); | |
1468 | + } | |
1469 | + t = n->first_node2("Polygon", "MultiPolygonString"); | |
1470 | + t = t ? t : n->first_node2("gml:Polygon", "gml:MultiPolygonString"); | |
1471 | + if (t) | |
1472 | + { | |
1473 | + pParsesrsName(t); | |
1474 | + return pGeometryPolygon(t, g); | |
1475 | + } | |
1476 | + t = n->first_node2("MultiPolygon", "gml:MultiPolygon"); | |
1477 | + if (t) | |
1478 | + { | |
1479 | + pParsesrsName(t); | |
1480 | + return pGeometryMultiPolygon(t, g); | |
1481 | + } | |
1482 | + t = n->first_node2("Polyline", "MultiLineString"); | |
1483 | + t = t ? t : n->first_node2("gml:Polyline", "gml:MultiLineString"); | |
1484 | + if (t) | |
1485 | + { | |
1486 | + pParsesrsName(t); | |
1487 | + return pGeometryPolyline(t, g); | |
1488 | + } | |
1489 | + t = n->first_node2("MultiPolyline", "gml:MultiPolyline"); | |
1490 | + if (t) | |
1491 | + { | |
1492 | + pParsesrsName(t); | |
1493 | + return pGeometryMultiPolyline(t, g); | |
1494 | + } | |
1495 | + t = n->first_node2("Polyline", "MultiLine"); | |
1496 | + t = t ? t : n->first_node2("gml:Polyline", "gml:MultiLine"); | |
1497 | + if (t) | |
1498 | + { | |
1499 | + pParsesrsName(t); | |
1500 | + return pGeometryPolyline(t, g); | |
1501 | + } | |
1502 | + t = n->first_node2("MultiPoint", "gml:MultiPoint"); | |
1503 | + if (t) | |
1504 | + { | |
1505 | + pParsesrsName(t); | |
1506 | + return pGeometryMultiPoint(t, g); | |
1507 | + } | |
1508 | + t = n->first_node2("Envelope", "gml:Envelope"); | |
1509 | + if (t) | |
1510 | + { | |
1511 | + pParsesrsName(t); | |
1512 | + return pGeometryEnvope(t, g); | |
1513 | + } | |
1514 | + t = n->first_node2("BBox", "gml:BBox"); | |
1515 | + if (t) | |
1516 | + { | |
1517 | + pParsesrsName(t); | |
1518 | + return pGeometryEnvope(t, g); | |
1519 | + } | |
1520 | + return 0; | |
1521 | + } | |
1522 | + qingxionggf*/ | |
1523 | + /* | |
1524 | + int DmpWfsFilter::ParseOrder(char *xml, void *tdp, int dtp) | |
1525 | + { | |
1526 | + err[0] = 0; | |
1527 | + sql = ""; | |
1528 | + this->td = (TableDesc *)tdp; | |
1529 | + this->DatabaseType = dtp; | |
1530 | + try | |
1531 | + { | |
1532 | + xml_document<> doc; // character type defaults to char | |
1533 | + doc.parse<0>(xml); | |
1534 | + xml_node<char> *n = doc.first_node(); | |
1535 | + if (n == 0) | |
1536 | + { | |
1537 | + return Error(-12, "bad xml"); | |
1538 | + } | |
1539 | + string name = this->GetFieldName(n->name()); | |
1540 | + const char *p = name.c_str(); | |
1541 | + if (strcmp(p, "SortBy")) | |
1542 | + return Error(-12, "no filter node"); | |
1543 | + //sql="order by "; | |
1544 | + int nc = 0; //<SortBy><SortProperty><ValueReference>OBJECTID</ValueReference><SortOrder>DESC</SortOrder></SortProperty><SortProperty><ValueReference>AREA</ValueReference><SortOrder>DESC</SortOrder></SortProperty></SortBy> | |
1545 | + for (auto ptchild =ptree.begin(); ptchild != ptree.end(); ++ptchild) | |
1546 | + { | |
1547 | + if (strcmp(node->name(), "SortProperty") == 0) | |
1548 | + { | |
1549 | + xml_node<char> *node1 = node->first_node2("ValueReference", "PropertyName"); | |
1550 | + if (node1 == 0) | |
1551 | + continue; | |
1552 | + if (nc == 0) | |
1553 | + { | |
1554 | + sql_ += " order by "; | |
1555 | + } | |
1556 | + else | |
1557 | + { | |
1558 | + sql_ += ","; | |
1559 | + } | |
1560 | + _AppendProperty(sql, node1->value()); | |
1561 | + node1 = node->first_node("SortOrder"); | |
1562 | + if (node1) | |
1563 | + { | |
1564 | + sql_ += " "; | |
1565 | + sql_ += node1->value(); | |
1566 | + } | |
1567 | + nc++; | |
1568 | + } | |
1569 | + } | |
1570 | + } | |
1571 | + catch (parse_error e) | |
1572 | + { | |
1573 | + //const char *w=e.what(); | |
1574 | + strncpy(this->err, e.what(), sizeof(this->err)); | |
1575 | + return -13; | |
1576 | + } | |
1577 | + catch (...) | |
1578 | + { | |
1579 | + strncpy(this->err, "unknow error", sizeof(this->err)); | |
1580 | + return -14; | |
1581 | + } | |
1582 | + return 0; | |
1583 | + } | |
1584 | + qingxingf*/ | |
1585 | + | |
1586 | + int DmpWfsFilter::GetGeomFromGml(boost::property_tree::ptree &ptreeode, std::string &strOut, double &x1, double &y1, double &x2, double &y2, void **geoOut) | |
1587 | + { | |
1588 | + if (geoOut) | |
1589 | + { | |
1590 | + *geoOut = 0; | |
1591 | + } | |
1592 | + strOut = ""; | |
1593 | + // xml_node<char> *node = (xml_node<char> *)nn; | |
1594 | + DmpWfsGmlObject *g = 0; | |
1595 | + int e = pGeometry(ptreeode, &g); //很重要的函数 | |
1596 | + // char sz[100];//int srid=-1; | |
1597 | + // itoa(srs,sz,10); | |
1598 | + string srs = ""; | |
1599 | + //strcpy(sz,"NULL"); | |
1600 | + if (g) | |
1601 | + { | |
1602 | + //g->GetRect(x1, y1, x2, y2); | |
1603 | + std::string sql; | |
1604 | + // g->GetString(sql); | |
1605 | + strOut = "";//initConfig.geometryfromtext; | |
1606 | + strOut += "st_geomfromtext('"; //strOut="geometryfromtext('"; | |
1607 | + strOut = strOut + sql; | |
1608 | + strOut = strOut + "',"; | |
1609 | + //initConfig.DefaultGID; | |
1610 | + strOut = strOut + srs; | |
1611 | + strOut = strOut + ")"; | |
1612 | + } | |
1613 | + else | |
1614 | + { | |
1615 | + return -28102; | |
1616 | + } | |
1617 | + | |
1618 | + return 0; | |
19 | 1619 | } |
20 | 1620 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -9,19 +9,91 @@ |
9 | 9 | |
10 | 10 | #ifndef __dmpwfsfilter_h__ |
11 | 11 | #define __dmpwfsfilter_h__ |
12 | - | |
12 | +#include <boost/property_tree/ptree.hpp> | |
13 | +#include <boost/property_tree/xml_parser.hpp> | |
14 | +#include <boost/typeof/typeof.hpp> | |
15 | +#include <string> | |
16 | +#include "dmpwfsgmlobject.h" | |
17 | +using namespace std; | |
13 | 18 | namespace DmpWfs |
14 | 19 | { |
15 | - class dmpwfsfilter | |
16 | - { | |
20 | + class DmpWfsFilter | |
21 | + { | |
17 | 22 | public: |
18 | - dmpwfsfilter(/* args */); | |
19 | - ~dmpwfsfilter(); | |
23 | + DmpWfsFilter(/* args */); | |
24 | + ~DmpWfsFilter(); | |
25 | + | |
26 | + bool Parse(const std::string &filter); | |
27 | + bool ParseOrder(const std::string &orderby); | |
28 | + std::string getSql() const { return sql_; } | |
29 | + | |
30 | + private: | |
31 | + std::string sql_; | |
32 | + std::string error_; | |
33 | + int errorCode_; | |
34 | + | |
35 | + std::string GetFieldName(const std::string& name); | |
36 | + | |
37 | + int _All(const std::string &name, boost::property_tree::ptree &ptree); | |
38 | + int _Or(boost::property_tree::ptree &ptree); | |
39 | + int _Not(boost::property_tree::ptree &ptree); | |
40 | + int _And(boost::property_tree::ptree &ptree); | |
41 | + int _BBOX(boost::property_tree::ptree &ptree); | |
42 | + int _Equals(boost::property_tree::ptree &ptree); | |
43 | + int _Beyond(boost::property_tree::ptree &ptree); | |
44 | + int _Within(boost::property_tree::ptree &ptree); | |
45 | + int _Crosses(boost::property_tree::ptree &ptree); | |
46 | + int _Touches(boost::property_tree::ptree &ptree); | |
47 | + int _DWithin(boost::property_tree::ptree &ptree); | |
48 | + int _Contains(boost::property_tree::ptree &ptree); | |
49 | + int _Overlaps(boost::property_tree::ptree &ptree); | |
50 | + int _Disjoint(boost::property_tree::ptree &ptree); | |
51 | + int _FeatureId(boost::property_tree::ptree &ptree); | |
52 | + int _Intersects(boost::property_tree::ptree &ptree); | |
53 | + int _DIntersects(boost::property_tree::ptree &ptree); | |
54 | + int _GmlObjectId(boost::property_tree::ptree &ptree); | |
55 | + int _PropertyIsLike(boost::property_tree::ptree &ptree); | |
56 | + int _PropertyIsNull(boost::property_tree::ptree &ptree); | |
57 | + int _PropertyIsBetween(boost::property_tree::ptree &ptree); | |
58 | + int _PropertyIsEqualTo(boost::property_tree::ptree &ptree); | |
59 | + int _PropertyIsLessThan(boost::property_tree::ptree &ptree); | |
60 | + int _PropertyIsNotEqualTo(boost::property_tree::ptree &ptree); | |
61 | + int _PropertyIsGreaterThan(boost::property_tree::ptree &ptree); | |
62 | + int _PropertyIsLessThanOrEqualTo(boost::property_tree::ptree &ptree); | |
63 | + int _PropertyIsGreaterThanOrEqualTo(boost::property_tree::ptree &ptree); | |
64 | + int pEnvelope(boost::property_tree::ptree &ptree, double *x1, double *y1, double *x2, double *y2); | |
65 | + | |
66 | + int pGeometry(boost::property_tree::ptree &ptree, DmpWfsGmlObject **g); | |
67 | + int pGeometryPoint(boost::property_tree::ptree &ptree, DmpWfsGmlObject **g); | |
68 | + int pGeometryLineString(boost::property_tree::ptree &ptree, DmpWfsGmlObject **g); | |
69 | + int pGeometryMultiPolyline(boost::property_tree::ptree &ptree, DmpWfsGmlObject **g); | |
70 | + int pGeometryMultiPolygon(boost::property_tree::ptree &ptree, DmpWfsGmlObject **g); | |
71 | + int pGeometryPolygon(boost::property_tree::ptree &ptree, DmpWfsGmlObject **g); | |
72 | + int pGeometryMultiPoint(boost::property_tree::ptree &ptree, DmpWfsGmlObject **g); | |
73 | + int pGeometryPolyline(boost::property_tree::ptree &ptree, DmpWfsGmlObject **g); | |
74 | + int pGeometryEnvope(boost::property_tree::ptree &ptree, DmpWfsGmlObject **g); | |
75 | + int pGeometryPointArray(boost::property_tree::ptree &ptree, std::vector<double> &v); | |
76 | + int pGeometryPointValue(char *p, std::vector<double> &v); | |
77 | + int pGeometryDouble(char *d, bool space_before, bool space_after, double &dbl); | |
78 | + int pGeometryPointValuePos(char *p, std::vector<double> &v); | |
79 | + int pGeometryPointValuePosList(boost::property_tree::ptree &ptree, std::vector<double> &v); | |
80 | + int pGeometryPointValueCoordinates(char *p, std::vector<double> &v); | |
81 | + int pGeometryPointValuePointRep(boost::property_tree::ptree &ptree, std::vector<double> &v); | |
82 | + int pGeometryPointValueCoord(boost::property_tree::ptree &ptree, std::vector<double> &v); | |
83 | + int pGeometryGetDis(boost::property_tree::ptree &ptree, double &dis); | |
84 | + int pGeometrySql(const char *function,const char *oracle_mask, int isDisjoin, boost::property_tree::ptree &ptree, bool useBuffer); //char *function,char *field,DmpWfsGmlObject *g,std::string &str); | |
20 | 85 | private: |
21 | - /* data */ | |
86 | + int Error(int code,const char * err); | |
87 | + void GetQueryField(std::string &field); | |
88 | + void _AppendProperty(std::string &sql, const char *str); | |
89 | + int GetGeomFromGml(boost::property_tree::ptree &ptreeode,std::string &strOut,double &x1,double &y1,double &x2,double &y2,void **geoOut=0); | |
90 | + int _PropertyParse(const std::string& ptreeName, boost::property_tree::ptree &ptreeode, int &isExpression, int isLike = 0); | |
91 | + int _PropertyParse4(boost::property_tree::ptree &ptreeode,const char *f); | |
92 | + int _PropertyParseFunction(boost::property_tree::ptree &ptree); | |
93 | + int _PropertyOneEqual(boost::property_tree::ptree &ptree,const char *type, int isLike = 0); | |
94 | + void pParsesrsName(boost::property_tree::ptree& ptree); | |
22 | 95 | }; |
23 | - | |
24 | - | |
96 | + | |
25 | 97 | } |
26 | 98 | |
27 | 99 | #endif // __dmpwfsfilter_h__ | ... | ... |
... | ... | @@ -164,7 +164,7 @@ namespace DmpWfs |
164 | 164 | ptFeatureType.add("Name", layer->name()); |
165 | 165 | ptFeatureType.add("Title", layer->title()); |
166 | 166 | ptFeatureType.add("DisplayColumn", ""); |
167 | - ptFeatureType.add("Geometry", "点"); | |
167 | + ptFeatureType.add("Geometry", layer->GeomTypeString()); | |
168 | 168 | ptFeatureType.add("GeometryColumn", layer->geom()); |
169 | 169 | ptFeatureType.add("SRS", srs); |
170 | 170 | |
... | ... | @@ -187,7 +187,12 @@ namespace DmpWfs |
187 | 187 | ptFeatureType.add_child("LatLongBoundingBox", ptBoundingbox); |
188 | 188 | |
189 | 189 | boost::property_tree::ptree ptFields; |
190 | - for (; pPgsqlConn->next();) | |
190 | + char tablesql_buff[300]; | |
191 | + sprintf(tablesql_buff, "select column_name,data_type from information_schema.columns where table_schema = '%s' and table_name = '%s'", | |
192 | + layer->schema().c_str(), | |
193 | + layer->name().c_str()); | |
194 | + bool returnResult = pPgsqlConn->ExecWait(tablesql_buff); | |
195 | + for (;returnResult && pPgsqlConn->next();) | |
191 | 196 | { |
192 | 197 | std::string fieldname = pPgsqlConn->getString(0); |
193 | 198 | std::string typeString = pPgsqlConn->getString(1); | ... | ... |
... | ... | @@ -8,212 +8,330 @@ |
8 | 8 | ***************************************************************************/ |
9 | 9 | #include "dmpwfsgetfeature.h" |
10 | 10 | #include "dmpsqlfactory.h" |
11 | +#include "dmpmapserverutil.h" | |
12 | +#include "dmpgmlfilter.h" | |
13 | +#include "dmpwfsfilter.h" | |
14 | +#include "dmpserverresponse.h" | |
15 | +#include "dmpserverrequest.h" | |
16 | +#include "dmpserverproject.h" | |
17 | + | |
18 | +#include <string.h> | |
19 | + | |
11 | 20 | namespace DmpWfs |
12 | 21 | { |
13 | - void writeGetFeature(const DmpServerContext &context,const DmpWfsParameters& params, | |
14 | - const DmpProject* project, | |
15 | - bool projectSettings) | |
16 | - { | |
17 | - | |
18 | - } | |
19 | - | |
20 | - std::string WfsGetFeature(const DmpServerContext &context,const DmpWfsParameters& params, | |
21 | - const DmpProject* project, | |
22 | - bool projectSettings) | |
23 | - { | |
24 | - char buff[5000]; | |
25 | - DmpSqlFactory sqlFactory; | |
26 | - | |
27 | - int maxFeatures = params.MaxFeatures(); | |
28 | - int startIndex = params.StartIndex(); | |
29 | - std::string typeName = params.TypeName(); | |
30 | - std::string featureID = params.FeatureID(); | |
31 | - std::string propertyName = params.PropertyName(); | |
32 | - std::string resultType = params.ResultType(); | |
33 | - | |
34 | - sqlFactory.setStartIndexCount(startIndex, maxFeatures, resultType); | |
35 | - | |
36 | - std::vector<std::string> ids; | |
37 | - if (!featureID.empty()) | |
38 | - { | |
39 | - char *idstring[1000]; | |
40 | - //将ID值以逗号分开,并返回个数 | |
41 | - /* | |
42 | - int idn = StringHelp::ParseStringTok(parseString.featureid, ',', idstring, 1000); | |
43 | - for (int i = 0; i < idn; i++) | |
44 | - { | |
45 | - char *ss[2]; | |
46 | - //形式:LayerName.ID | |
47 | - int n = StringHelp::ParseStringTok(idstring[i], '.', ss, 2); | |
48 | - if (n == 2) | |
49 | - { | |
50 | - if (parseString.layerName == 0) | |
51 | - { | |
52 | - parseString.layerName = ss[0]; | |
53 | - } | |
54 | - ids.push_back(ss[1]); | |
55 | - } | |
56 | - else if (n == 1) | |
57 | - { | |
58 | - ids.push_back(ss[0]); | |
59 | - } | |
60 | - } | |
61 | - */ | |
62 | - } | |
22 | + void writeGetFeature(const DmpServerContext &context, const DmpWfsParameters ¶ms, | |
23 | + const DmpProject *project, | |
24 | + bool projectSettings) | |
25 | + { | |
26 | + WfsGetFeature(context, params, project, projectSettings); | |
27 | + } | |
63 | 28 | |
64 | - /* std::vector<std::string> props; | |
65 | - std::vector<std::string> propsAs; | |
66 | - if (propertyName.empty()) | |
67 | - { | |
68 | - char *idstring[1000]; | |
69 | - int idn = StringHelp::ParseStringTok(parseString.propertyname, ',', idstring, 1000); | |
70 | - for (int i = 0; i < idn; i++) | |
71 | - { | |
72 | - char *ss[2]; | |
73 | - std::string sProp, sPropAs; | |
74 | - int n = StringHelp::ParseStringTok(idstring[i], '.', ss, 2); | |
75 | - if (n == 2) | |
76 | - { | |
77 | - if (parseString.layerName == 0) | |
78 | - { | |
79 | - parseString.layerName = ss[0]; | |
80 | - } | |
81 | - //又以空格分开 | |
82 | - StringHelp::GetAsStringSql(ss[1], sProp, sPropAs); | |
83 | - props.push_back(sProp); | |
84 | - propsAs.push_back(sPropAs); | |
85 | - //sPropOrig=ss[1]; | |
86 | - } | |
87 | - else if (n == 1) | |
88 | - { | |
89 | - StringHelp::GetAsStringSql(ss[0], sProp, sPropAs); | |
90 | - props.push_back(sProp); | |
91 | - propsAs.push_back(sPropAs); //props.push_back(ss[0]); | |
92 | - } | |
93 | - } | |
94 | - } | |
95 | - */ | |
29 | + std::string WfsGetFeature(const DmpServerContext &context, const DmpWfsParameters ¶ms, | |
30 | + const DmpProject *project, | |
31 | + bool projectSettings) | |
32 | + { | |
33 | + char buff[5000]; | |
34 | + DmpSqlFactory sqlFactory; | |
96 | 35 | |
97 | - // if (parseString.layerName == 0) | |
98 | - // return Error(buff, ErrorClass::ParaError, "layername not exist", ab); | |
36 | + int maxFeatures = params.MaxFeatures(); | |
37 | + int startIndex = params.StartIndex(); | |
38 | + std::string typeName = params.TypeName(); | |
39 | + std::string featureID = params.FeatureID(); | |
40 | + std::string propertyName = params.PropertyName(); | |
41 | + DmpWfsParameters::Format resultType = params.ResultType(); | |
42 | + std::string filter = params.Filter(); | |
99 | 43 | |
100 | - //const char *realLayer=0; | |
101 | - //GetUpLayerID是干什么的? | |
102 | - //似乎就是加了些L啊什么的。。 。 | |
103 | - // if (_GetUperLayerId(parseString.layerName, sLayer) == false) | |
104 | - // return Error(buff, ErrorClass::ParaError, "layer not exist", ab); | |
44 | + std::string sortby = params.Sortby(); | |
105 | 45 | |
106 | - /* shared_ptr<MapLayer> mapLayer = service->GetLayer(parseString.layerName); | |
46 | + DmpWfsFilter wfsFilter; | |
47 | + wfsFilter.Parse(filter); | |
48 | + std::string sql0 = wfsFilter.getSql(); | |
49 | + printf("%s\r\n", sql0.c_str()); | |
107 | 50 | |
108 | - | |
109 | - if(mapLayer == nullptr) | |
110 | - { | |
111 | - return Error(buff, ErrorClass::ParaError, "layer not find", ab); | |
112 | - } | |
51 | + sqlFactory.setStartIndexCount(startIndex, maxFeatures, ""); | |
113 | 52 | |
114 | - shared_ptr<Workspace> pWorkspace = DataSourcePools::get_instance()->GetWorkspace(mapLayer->m_dbSource); | |
115 | - if(pWorkspace == nullptr) | |
116 | - { | |
117 | - return Error(buff, ErrorClass::DatabaseDisconnect, "连接数据库失败", ab); | |
118 | - } | |
119 | - shared_ptr<dmapFields> fields = pWorkspace->GetFields(mapLayer->m_layerName,""); | |
53 | + std::vector<std::string> ids; | |
54 | + if (!featureID.empty()) | |
55 | + { | |
56 | + char *idstring[1000]; | |
57 | + //将ID值以逗号分开,并返回个数 | |
120 | 58 | |
121 | - if(fields == nullptr) | |
122 | - { | |
123 | - return Error(buff, ErrorClass::ParaError, "layername not exist", ab); | |
124 | - } | |
59 | + vector<string> stringlist = mapserver::DmpMapServerUtil::stringSplit(propertyName, ","); | |
60 | + for (int i = 0; i < stringlist.size(); i++) | |
61 | + { | |
62 | + char *ss[2]; | |
63 | + //形式:LayerName.ID | |
64 | + vector<string> stringList1 = mapserver::DmpMapServerUtil::stringSplit(idstring[i], "."); | |
65 | + // int n = StringHelp::ParseStringTok(idstring[i], '.', ss, 2); | |
66 | + if (stringList1.size() == 2) | |
67 | + { | |
68 | + if (typeName.empty()) | |
69 | + { | |
70 | + typeName = stringList1[0]; | |
71 | + } | |
72 | + ids.push_back(stringList1[1]); | |
73 | + } | |
74 | + else if (stringList1.size() == 1) | |
75 | + { | |
76 | + ids.push_back(stringList1[0]); | |
77 | + } | |
78 | + } | |
79 | + } | |
125 | 80 | |
126 | - | |
81 | + std::vector<std::string> props; | |
82 | + std::vector<std::string> propsAs; | |
83 | + if (!propertyName.empty()) | |
84 | + { | |
127 | 85 | |
86 | + vector<string> stringlist = mapserver::DmpMapServerUtil::stringSplit(propertyName, ","); | |
87 | + for (int i = 0; i < stringlist.size(); i++) | |
88 | + { | |
89 | + // char *ss[2]; | |
90 | + std::string sProp, sPropAs; | |
91 | + vector<string> layernameSplit = mapserver::DmpMapServerUtil::stringSplit(stringlist[i], "."); | |
92 | + if (layernameSplit.size() == 2) | |
93 | + { | |
94 | + if (typeName.empty()) | |
95 | + { | |
96 | + typeName = layernameSplit[0]; | |
97 | + } | |
98 | + //又以空格分开 | |
99 | + // StringHelp::GetAsStringSql(ss[1], sProp, sPropAs); | |
100 | + props.push_back(sProp); | |
101 | + propsAs.push_back(sPropAs); | |
102 | + //sPropOrig=ss[1]; | |
103 | + } | |
104 | + else if (layernameSplit.size() == 1) | |
105 | + { | |
106 | + // StringHelp::GetAsStringSql(ss[0], sProp, sPropAs); | |
107 | + props.push_back(sProp); | |
108 | + propsAs.push_back(sPropAs); //props.push_back(ss[0]); | |
109 | + } | |
110 | + } | |
111 | + } | |
128 | 112 | |
129 | - shared_ptr<TableDesc> pTabledesc = this->ToTableDesc(fields,mapLayer->m_layerName); | |
130 | - | |
113 | + if (typeName.empty()) | |
114 | + { | |
115 | + return "layername not exist"; | |
116 | + } | |
131 | 117 | |
132 | - size_t propCount = props.size(); | |
133 | - if (propCount) | |
134 | - { | |
135 | - std::string sF; | |
136 | - for (int i = 0; i < propCount; i++) | |
137 | - { | |
138 | - if (i) | |
139 | - sF = sF + ","; | |
140 | - string sleft, sright, s; | |
141 | - s = props[i]; | |
142 | - int at1 = s.find("("), at2 = s.find(")"); | |
143 | - | |
144 | - if (at1 != string::npos && at2 == s.length() - 1 && at1 < at2) | |
145 | - { | |
146 | - sleft = s.substr(0, at1); | |
147 | - sright = s.substr(at1 + 1, s.length() - 2 - at1); | |
148 | - if (_stricmp(sleft.c_str(), "distinct") == 0) | |
149 | - { | |
150 | - sF = sF + sleft + " " + fields->GetFieldQuery(sright.c_str()); | |
151 | - } | |
152 | - else | |
153 | - { | |
154 | - sF = sF + sleft + "(" + fields->GetFieldQuery(sright.c_str()) + ")"; | |
155 | - } | |
156 | - } | |
157 | - else | |
158 | - { | |
159 | - sF = sF + fields->GetFieldQuery(s.c_str()); | |
160 | - } | |
161 | - | |
162 | - } | |
163 | - sqlF.prop = sF; | |
164 | - } | |
165 | - else | |
166 | - { | |
167 | - bool isJson = (parseString.format && (strcmpi(parseString.format, "geojson") ==0 || strcmpi(parseString.format, "json") ==0)); | |
168 | - this->GetAllField( srsOut, sqlF.prop,mapLayer,pWorkspace,isJson); | |
169 | - } | |
118 | + DmpVectorLayer *mapLayer = (DmpVectorLayer *)project->getLayer(typeName); //GetLayer(parseString.layerName); | |
119 | + if (mapLayer == nullptr) | |
120 | + { | |
121 | + return "layer not find"; | |
122 | + } | |
170 | 123 | |
171 | - size_t idCount = ids.size(); | |
124 | + shared_ptr<DmpPgsql> pPgsqlConn = DmpPgsqlSourcePools::get_instance()->GetPgsqlConn(mapLayer->source()); | |
125 | + if (pPgsqlConn == nullptr) | |
126 | + { | |
127 | + return "连接数据库失败"; | |
128 | + } | |
129 | + // shared_ptr<dmapFields> fields = pPgsqlConn->GetFields(mapLayer->m_layerName,""); | |
172 | 130 | |
173 | - | |
131 | + //if(fields == nullptr) | |
132 | + { | |
133 | + //return Error(buff, ErrorClass::ParaError, "layername not exist", ab); | |
134 | + } | |
174 | 135 | |
175 | - if (parseString.filter) | |
176 | - { | |
177 | - clsFilter filter(mapLayer->m_srid); | |
178 | - | |
179 | - if (filter.Parse(parseString.filter, pTabledesc.get(),DatabaseTypePostgreSQL)) | |
180 | - { | |
181 | - return Error(buff, ErrorClass::FilterError, filter.err, ab); | |
182 | - } | |
183 | - | |
184 | - sqlF.AppendCondition(filter.sql); | |
185 | - } | |
186 | - if (parseString.sortby) | |
187 | - { | |
188 | - clsFilter filter(mapLayer->m_srid); | |
189 | - if (filter.ParseOrder(parseString.sortby, pTabledesc.get(), DatabaseTypePostgreSQL)) | |
190 | - { | |
191 | - return Error(buff, ErrorClass::SortError, filter.err, ab); | |
192 | - } | |
193 | - sqlF.order = filter.sql; | |
194 | - } | |
195 | - sqlF.table = mapLayer->m_layerName; | |
196 | - std::string sq = sqlF.GetSql(DatabaseTypePostgreSQL); | |
136 | + // shared_ptr<TableDesc> pTabledesc = this->ToTableDesc(fields,mapLayer->m_layerName); | |
197 | 137 | |
198 | - bool returnResult = pWorkspace->ExecWaitBinary(sq); | |
199 | - if (!returnResult) | |
200 | - { | |
201 | - return Error(buff, ErrorClass::QueryError, pWorkspace->m_sError.c_str(), ab); | |
202 | - } | |
203 | - int ver = ParseString::GetGMLVersion(parseString.version, parseString.outputFormat); | |
204 | - if (parseString.format && (strcmpi(parseString.format, "geojson") ==0|| strcmpi(parseString.format, "json")==0)) | |
138 | + size_t propCount = props.size(); | |
139 | + if (propCount) | |
140 | + { | |
141 | + std::string sF; | |
142 | + for (int i = 0; i < propCount; i++) | |
143 | + { | |
144 | + if (i) | |
145 | + sF = sF + ","; | |
146 | + string sleft, sright, s; | |
147 | + s = props[i]; | |
148 | + int at1 = s.find("("), at2 = s.find(")"); | |
149 | + | |
150 | + if (at1 != string::npos && at2 == s.length() - 1 && at1 < at2) | |
151 | + { | |
152 | + sleft = s.substr(0, at1); | |
153 | + sright = s.substr(at1 + 1, s.length() - 2 - at1); | |
154 | + if (boost::iequals(sleft, "distinct")) | |
155 | + { | |
156 | + // sF = sF + sleft + " " + fields->GetFieldQuery(sright.c_str()); | |
157 | + } | |
158 | + else | |
159 | + { | |
160 | + // sF = sF + sleft + "(" + fields->GetFieldQuery(sright.c_str()) + ")"; | |
161 | + } | |
162 | + } | |
163 | + else | |
164 | + { | |
165 | + // sF = sF + fields->GetFieldQuery(s.c_str()); | |
166 | + } | |
167 | + } | |
168 | + | |
169 | + sqlFactory.setProp(sF); | |
170 | + } | |
171 | + else | |
172 | + { | |
173 | + std::string prop; | |
174 | + GetAllField(prop, mapLayer, pPgsqlConn, resultType); | |
175 | + sqlFactory.setProp(prop); | |
176 | + } | |
177 | + | |
178 | + size_t idCount = ids.size(); | |
179 | + | |
180 | + if (!filter.empty()) | |
181 | + { | |
182 | + DmpWfsFilter wfsFilter; | |
183 | + | |
184 | + if (wfsFilter.Parse(filter)) | |
185 | + { | |
186 | + return "解析查询器错误"; | |
187 | + } | |
188 | + | |
189 | + sqlFactory.appendCondition(wfsFilter.getSql()); | |
190 | + } | |
191 | + | |
192 | + if (!sortby.empty()) | |
193 | + { | |
194 | + DmpWfsFilter wfsFilter; | |
195 | + if (wfsFilter.ParseOrder(sortby)) | |
196 | + { | |
197 | + return "参数sortby 解析错误!"; | |
198 | + } | |
199 | + sqlFactory.setOrder(wfsFilter.getSql()); | |
200 | + } | |
201 | + sqlFactory.setTable(mapLayer->name()); | |
202 | + std::string sql = sqlFactory.getSql(); | |
203 | + if (!pPgsqlConn->ExecWaitBinary(sql)) | |
204 | + { | |
205 | + return "查询错误:" + pPgsqlConn->error(); | |
206 | + } | |
207 | + | |
208 | + if (resultType == DmpWfsParameters::Format::GeoJson) | |
209 | + { | |
210 | + std::string responseData; | |
211 | + std::string srid = std::__cxx11::to_string(mapLayer->crs().srid()); | |
212 | + DmpMapServerUtil::responseGeojson(pPgsqlConn, responseData, mapLayer->name(), srid); | |
213 | + context.response()->writeJson(responseData); | |
214 | + } | |
215 | + else | |
216 | + { | |
217 | + std::string responseData; | |
218 | + std::string srid = std::__cxx11::to_string(mapLayer->crs().srid()); | |
219 | + DmpMapServerUtil::responseGml(pPgsqlConn, responseData, mapLayer->name(), srid); | |
220 | + context.response()->removeHeader("Content-Type"); | |
221 | + context.response()->setHeader("Content-Type", "text/xml;charset=utf-8"); | |
222 | + context.response()->write(responseData); | |
223 | + } | |
224 | + | |
225 | + // int ver = ParseString::GetGMLVersion(parseString.version, parseString.outputFormat); | |
226 | + /* if (parseString.format && (strcmpi(parseString.format, "geojson") ==0|| strcmpi(parseString.format, "json")==0)) | |
205 | 227 | { |
206 | 228 | isPicture = 10; |
207 | - return this->FormatWFSJsonCAll(pWorkspace, ab, parseString.layerName, buff, ver); | |
229 | + return this->FormatWFSJsonCAll(pPgsqlConn, ab, parseString.layerName, buff, ver); | |
208 | 230 | } |
209 | 231 | else |
210 | 232 | { |
211 | 233 | isPicture = 0; |
212 | - return this->FormatWFSXMLCAll(pWorkspace, ab, parseString.layerName, buff, ver); | |
234 | + return this->FormatWFSXMLCAll(pPgsqlConn, ab, parseString.layerName, buff, ver); | |
213 | 235 | }*/ |
214 | - return ""; | |
215 | - } | |
236 | + return ""; | |
237 | + } | |
238 | + | |
239 | + void getAsStringSql(const string &str, std::string &sProp, std::string &sAs) | |
240 | + { | |
241 | + //char *ss[2]; | |
242 | + vector<string> layernameSplit = mapserver::DmpMapServerUtil::stringSplit(str, "."); | |
243 | + //int n = ParseStringTok(str, ' ', ss, 2); | |
244 | + if (layernameSplit.size() == 1) | |
245 | + { | |
246 | + sProp = layernameSplit[0]; | |
247 | + sAs = ""; | |
248 | + } | |
249 | + else if (layernameSplit.size() > 1) | |
250 | + { | |
251 | + sProp = layernameSplit[0]; | |
252 | + sAs = layernameSplit[1]; | |
253 | + } | |
254 | + } | |
255 | + | |
256 | + bool GetAllField(std::string &strOut, DmpVectorLayer *mapLayer, | |
257 | + shared_ptr<DmpPgsql> pPgsqlConn, DmpWfsParameters::Format format) | |
258 | + { | |
259 | + string fields_str; | |
260 | + if (pPgsqlConn != nullptr) | |
261 | + { | |
262 | + char tablesql_buff[300]; | |
263 | + std::sprintf(tablesql_buff, "select column_name,data_type from information_schema.columns where table_schema = '%s' and table_name = '%s'", | |
264 | + mapLayer->schema().c_str(), | |
265 | + mapLayer->name().c_str()); | |
266 | + | |
267 | + int returnResult = pPgsqlConn->ExecWait(tablesql_buff); | |
268 | + if (!returnResult) | |
269 | + { | |
270 | + string fields_str = " * "; | |
271 | + } | |
272 | + else | |
273 | + { | |
216 | 274 | |
275 | + for (int i = 0; pPgsqlConn->next(); i++) | |
276 | + { | |
277 | + if (i > 0 && fields_str.length() > 0 && fields_str[fields_str.length() - 1] != ',') | |
278 | + { | |
279 | + fields_str += ","; | |
280 | + } | |
281 | + string fieldname = pPgsqlConn->getString(0); | |
282 | + string typeString = pPgsqlConn->getString(1); | |
283 | + int typeInt = PGFieldType::VarCharFieldType; | |
284 | + if (mapLayer->geom() == fieldname || typeString == "geometry") | |
285 | + { | |
286 | + typeString = "geometry"; | |
287 | + typeInt = PGFieldType::ShapeFieldType; | |
288 | + if (format == DmpWfsParameters::Format::GeoJson) | |
289 | + { | |
290 | + fields_str += " st_asgeojson(\"" + (fieldname) + "\") as geometry_as_geojson"; | |
291 | + } | |
292 | + else | |
293 | + { | |
294 | + fields_str += " st_asgml(\"" + (fieldname) + "\") as geometry_as_gml"; | |
295 | + } | |
296 | + } | |
297 | + else if (typeString == "integer") | |
298 | + { | |
299 | + typeInt = PGFieldType::BigIntFieldType; | |
300 | + fields_str += " \"" + (fieldname) + "\"::varchar "; | |
301 | + } | |
302 | + else if (typeString == "bigint") | |
303 | + { | |
304 | + typeInt = PGFieldType::BigIntFieldType; | |
305 | + fields_str += " \"" + (fieldname) + "\"::varchar "; | |
306 | + } | |
307 | + else if (typeString == "double precision" || typeString == "real" || typeString == "numeric") | |
308 | + { | |
309 | + typeInt = PGFieldType::DoubleFieldType; | |
310 | + fields_str += " \"" + (fieldname) + "\"::varchar "; | |
311 | + } | |
312 | + else if (typeString == "character varying" || typeString == "text") | |
313 | + { | |
314 | + typeInt = PGFieldType::VarCharFieldType; | |
315 | + fields_str += " \"" + (fieldname) + "\" "; | |
316 | + } | |
317 | + else if (typeString == "bytea") | |
318 | + { | |
319 | + continue; | |
320 | + } | |
321 | + else if (typeString == "timestamp without time zone") | |
322 | + { | |
323 | + fields_str += " \"" + (fieldname) + "\"::varchar "; | |
324 | + } | |
325 | + } | |
326 | + } | |
327 | + } | |
328 | + else | |
329 | + { | |
330 | + fields_str = " * "; | |
331 | + } | |
217 | 332 | |
333 | + strOut = fields_str; | |
218 | 334 | |
335 | + return true; | |
336 | + } | |
219 | 337 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -14,22 +14,29 @@ |
14 | 14 | #include <boost/typeof/typeof.hpp> |
15 | 15 | #include <memory> |
16 | 16 | #include <vector> |
17 | +#include <string> | |
17 | 18 | #include "dmpproject.h" |
18 | 19 | #include "dmpwfsparameters.h" |
19 | 20 | #include "dmpservercontext.h" |
20 | 21 | #include "dmppgsqlsourcepools.h" |
21 | - | |
22 | +#include "dmpvectorlayer.h" | |
23 | +#include "dmpgmlfilter.h" | |
24 | +using namespace mapserver; | |
22 | 25 | namespace DmpWfs |
23 | 26 | { |
24 | 27 | void writeGetFeature(const DmpServerContext &context,const DmpWfsParameters& params, |
25 | 28 | const DmpProject* project, |
26 | 29 | bool projectSettings = false); |
27 | 30 | |
28 | - // std::string WfsGetFeature(const DmpServerContext &context,const DmpWfsParameters& params, | |
29 | - // const DmpProject* project, | |
30 | - // bool projectSettings = false); | |
31 | + std::string WfsGetFeature(const DmpServerContext &context,const DmpWfsParameters& params, | |
32 | + const DmpProject* project, | |
33 | + bool projectSettings = false); | |
34 | + | |
35 | + | |
36 | + void getAsStringSql(const string& str,std::string &sProp,std::string &sAs); | |
37 | + | |
38 | + bool GetAllField(std::string &strOut,DmpVectorLayer* mapLayer,shared_ptr<DmpPgsql> pPgsqlConn, DmpWfsParameters::Format format); | |
31 | 39 | |
32 | - | |
33 | 40 | } |
34 | 41 | |
35 | 42 | #endif // __dmpwfsgetfeature_h__ | ... | ... |
1 | +/************************************************************************** | |
2 | +* file: dmpwfsgmlobject.cpp | |
3 | + | |
4 | +* Author: qingxiongf | |
5 | +* Date: 2022-01-06 13:39:11 | |
6 | +* Email: qingxiongf@chinadci.com | |
7 | +* copyright: 广州城市信息研究所有限公司 | |
8 | +***************************************************************************/ | |
9 | + | |
10 | +#include "dmpwfsgmlobject.h" | |
11 | + | |
12 | + | |
13 | + DmpWfsGmlObject::DmpWfsGmlObject() | |
14 | +{ | |
15 | + | |
16 | +} | |
17 | + | |
18 | + | |
19 | + ~DmpWfsGmlObject::DmpWfsGmlObject() | |
20 | +{ | |
21 | + | |
22 | +} | |
\ No newline at end of file | ... | ... |
1 | +/************************************************************************** | |
2 | +* file: dmpwfsgmlobject.h | |
3 | + | |
4 | +* Author: qingxiongf | |
5 | +* Date: 2022-01-06 13:39:03 | |
6 | +* Email: qingxiongf@chinadci.com | |
7 | +* copyright: 广州城市信息研究所有限公司 | |
8 | +***************************************************************************/ | |
9 | + | |
10 | +#ifndef __dmpwfsgmlobject_h__ | |
11 | +#define __dmpwfsgmlobject_h__ | |
12 | +#include <string> | |
13 | + | |
14 | +namespace DmpWfs | |
15 | +{ | |
16 | + class DmpWfsGmlObject | |
17 | + { | |
18 | + public: | |
19 | + DmpWfsGmlObject(void); | |
20 | + | |
21 | + public: | |
22 | + ~DmpWfsGmlObject(void); | |
23 | + | |
24 | + public: | |
25 | + virtual void getString(std::string &str) = 0; | |
26 | + virtual void getObj(void *sg) = 0; | |
27 | + virtual void getRect(double &x1, double &y1, double &x2, double &y2) = 0; | |
28 | + }; | |
29 | + | |
30 | + class DmpWfsGmlPoint : public DmpWfsGmlObject | |
31 | + { | |
32 | + public: | |
33 | + DmpWfsGmlPoint(void); | |
34 | + DmpWfsGmlPoint(double x, double y); | |
35 | + ~DmpWfsGmlPoint(void); | |
36 | + | |
37 | + public: | |
38 | + void getObj(void *sg); | |
39 | + void getString(std::string &s); | |
40 | + void getRect(double &x11, double &y11, double &x22, double &y22); | |
41 | + | |
42 | + private: | |
43 | + double x; | |
44 | + double y; | |
45 | + }; | |
46 | + | |
47 | + | |
48 | + | |
49 | + | |
50 | +} | |
51 | + | |
52 | +#endif // __dmpwfsgmlobject_h__ | ... | ... |
... | ... | @@ -170,11 +170,23 @@ namespace DmpWfs |
170 | 170 | return value; |
171 | 171 | } |
172 | 172 | |
173 | - std::string DmpWfsParameters::ResultType() const //要素ID | |
173 | + DmpWfsParameters::Format DmpWfsParameters::ResultType() const | |
174 | 174 | { |
175 | 175 | std::string value = ""; |
176 | 176 | GetStringParameter("RESULTTYPE",value); |
177 | - return value; | |
177 | + if (value.empty()) { | |
178 | + GetStringParameter("FORMAT",value); | |
179 | + } | |
180 | + if (value.empty()) { | |
181 | + return DmpWfsParameters::Format::GML3; | |
182 | + } | |
183 | + | |
184 | + Format f = Format::GML3; | |
185 | + boost::to_lower(value); | |
186 | + if (value.compare("geojson") == 0 || value.compare("json") == 0 ) { | |
187 | + f = DmpWfsParameters::Format::GeoJson; | |
188 | + } | |
189 | + return f; | |
178 | 190 | } |
179 | 191 | |
180 | 192 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -51,7 +51,7 @@ namespace DmpWfs |
51 | 51 | std::string PropertyName() const; //指定返回的要素属性,没有指定不返回 |
52 | 52 | std::string SrsName() const; //空间参考坐标 |
53 | 53 | std::string FeatureID() const; //要素ID |
54 | - std::string ResultType() const; | |
54 | + DmpWfsParameters::Format ResultType() const; | |
55 | 55 | |
56 | 56 | //std::string Expiry(); |
57 | 57 | ... | ... |
... | ... | @@ -19,6 +19,8 @@ |
19 | 19 | #include "dmplogger.h" |
20 | 20 | #include "dmpwmsgetcapabilities.h" |
21 | 21 | #include "dmpwmsgetmap.h" |
22 | +#include "dmpwmsserviceinfo.h" | |
23 | +#include "dmpwmsgetfeatureinfo.h" | |
22 | 24 | using namespace std; |
23 | 25 | |
24 | 26 | namespace DmpWms |
... | ... | @@ -50,14 +52,18 @@ namespace DmpWms |
50 | 52 | { |
51 | 53 | writeGetMap(context,params, project); |
52 | 54 | } |
53 | - else if(boost::iequals(request,"thumbnail")) | |
55 | + else if(boost::iequals(request,"thumbnail") || boost::iequals(request,"getthumbnail")) | |
54 | 56 | { |
55 | 57 | writeThumbnail(context,params, project); |
56 | 58 | } |
57 | 59 | else if(boost::iequals(request, "getfeatureinfo")) |
58 | 60 | { |
59 | - | |
61 | + writeFeatureInfo(context,params, project); | |
60 | 62 | } |
63 | + else if(boost::iequals(request, "getserviceinfo")) | |
64 | + { | |
65 | + writeGetServiceInfo(context,params, project); | |
66 | + } | |
61 | 67 | else if(request == "getlegendgraphic") |
62 | 68 | { |
63 | 69 | ... | ... |
... | ... | @@ -72,9 +72,14 @@ namespace DmpWms |
72 | 72 | mapRenderer.SetExtent(rect); |
73 | 73 | string responseData; |
74 | 74 | mapRenderer.GetFeatureInfo(responseData, x, y, featureCount); |
75 | - context.response()->removeHeader("Content-Type"); | |
76 | - context.response()->setHeader("Content-Type", "image/png"); | |
77 | - context.response()->write(responseData); | |
75 | + if(responseData.empty()) | |
76 | + { | |
77 | + context.response()->writeJson("null"); | |
78 | + } | |
79 | + else | |
80 | + { | |
81 | + context.response()->writeJson(responseData); | |
82 | + } | |
78 | 83 | return ""; |
79 | 84 | } |
80 | 85 | catch (const std::exception &e) | ... | ... |
... | ... | @@ -63,7 +63,7 @@ namespace DmpWms |
63 | 63 | DmpWms::DmpWmsRenderer mapRenderer(height, width); |
64 | 64 | |
65 | 65 | std::string layers = params.Layers(); |
66 | - if (layers !="") | |
66 | + if (layers =="") | |
67 | 67 | { |
68 | 68 | mapRenderer.AddWmsMapLayers(project); |
69 | 69 | } |
... | ... | @@ -125,6 +125,7 @@ namespace DmpWms |
125 | 125 | |
126 | 126 | shared_ptr<Rect> rect (new Rect(maxy, maxx, miny, minx)); |
127 | 127 | mapRenderer.SetExtent(rect); |
128 | + mapRenderer.AddWmsMapLayers(project); | |
128 | 129 | mapRenderer.GetMap(nullptr, nullptr, nullptr, true); |
129 | 130 | string responseData; |
130 | 131 | mapRenderer.ToStream(responseData); | ... | ... |
... | ... | @@ -522,7 +522,7 @@ ST_GeometryFromText('POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',%s),\ |
522 | 522 | else if (typeString == "integer") |
523 | 523 | { |
524 | 524 | typeInt = PGFieldType::BigIntFieldType; |
525 | - fields_str += " \"" + (fieldname) + "\" "; | |
525 | + fields_str += " \"" + (fieldname) + "\"::varchar "; | |
526 | 526 | } |
527 | 527 | else if (typeString == "bigint") |
528 | 528 | { |
... | ... | @@ -532,7 +532,7 @@ ST_GeometryFromText('POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',%s),\ |
532 | 532 | else if (typeString == "double precision" || typeString == "real" || typeString == "numeric") |
533 | 533 | { |
534 | 534 | typeInt = PGFieldType::DoubleFieldType; |
535 | - fields_str += " \"" + (fieldname) + "\" "; | |
535 | + fields_str += " \"" + (fieldname) + "\"::varchar "; | |
536 | 536 | } |
537 | 537 | else if (typeString == "character varying" || typeString == "text") |
538 | 538 | { |
... | ... | @@ -572,7 +572,7 @@ ST_GeometryFromText('POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',%s),\ |
572 | 572 | |
573 | 573 | string shapeName = layer->geom(); |
574 | 574 | sql += format(" ST_DWithin(\"%s\", ST_GeometryFromText('POINT(%f %f)',%s), %f) limit %d ", |
575 | - shapeName.c_str(), x, y, layer->crs().srid(), dis, feature_count); | |
575 | + shapeName.c_str(), x, y, layer->srid().c_str(), dis, feature_count); | |
576 | 576 | //cout<<sql.c_str() <<endl; |
577 | 577 | return sql; |
578 | 578 | } |
... | ... | @@ -604,7 +604,7 @@ ST_GeometryFromText('POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',%s),\ |
604 | 604 | string sql = this->GetFeatureInfoSQL(layer, x0, y0, dis, feature_count); //sql语句中使用 ::box |
605 | 605 | if (sql == "") |
606 | 606 | continue; |
607 | - | |
607 | + printf("%s\r\n",sql.c_str()); | |
608 | 608 | string layerName = layer->name(); |
609 | 609 | try |
610 | 610 | { | ... | ... |
1 | +/************************************************************************** | |
2 | +* file: dmpwmsserviceinfo.cpp | |
3 | + | |
4 | +* Author: qingxiongf | |
5 | +* Date: 2022-01-11 14:05:33 | |
6 | +* Email: qingxiongf@chinadci.com | |
7 | +* copyright: 广州城市信息研究所有限公司 | |
8 | +***************************************************************************/ | |
9 | +#include "dmpwmsserviceinfo.h" | |
10 | +#include "dmpserverresponse.h" | |
11 | +#include "dmpserverrequest.h" | |
12 | +#include "dmpserverproject.h" | |
13 | + | |
14 | +namespace DmpWms | |
15 | +{ | |
16 | + void writeGetServiceInfo(const DmpServerContext &context, const DmpWmsParameters ¶ms, | |
17 | + const DmpProject *project, | |
18 | + bool projectSettings) | |
19 | + { | |
20 | + boost::property_tree::ptree xmlRoot; | |
21 | + | |
22 | + std::string name = context.serverProject()->name(); | |
23 | + std::string title = context.serverProject()->title(); | |
24 | + | |
25 | + boost::property_tree::ptree ptRoot; | |
26 | + | |
27 | + addServiceInfoLayers(ptRoot,project,name,title); | |
28 | + | |
29 | + | |
30 | + std::stringstream stream; | |
31 | + write_json(stream, ptRoot); | |
32 | + std::string json; | |
33 | + json = stream.str(); | |
34 | + | |
35 | + context.response()->writeJson(json); | |
36 | + } | |
37 | + | |
38 | + void addServiceInfoLayers(boost::property_tree::ptree &pt,const DmpProject* project, std::string& name, std::string& title) | |
39 | + { | |
40 | + std::string srs = "EPSG:" + std::__cxx11::to_string(project->crs().srid()); | |
41 | + | |
42 | + boost::property_tree::ptree ptProject; | |
43 | + // ptProject.add("<xmlattr>.queryable","1"); | |
44 | + ptProject.add("Name", name); | |
45 | + ptProject.add("Title", title); | |
46 | + ptProject.add("CRS", srs); | |
47 | + | |
48 | + double minx,miny,maxx,maxy; | |
49 | + int i =0; | |
50 | + std::map<std::string, DmpMapLayer*> mapLayers = project->mapLayers(); | |
51 | + for (std::map<std::string, DmpMapLayer*>::iterator iter = mapLayers.begin();iter != mapLayers.end(); iter++) | |
52 | + { | |
53 | + DmpMapLayer* layer = iter->second; | |
54 | + if(i ==0) | |
55 | + { | |
56 | + minx = layer->extent().xmin(); | |
57 | + miny = layer->extent().ymin(); | |
58 | + maxx = layer->extent().xmax(); | |
59 | + maxy = layer->extent().ymax(); | |
60 | + } | |
61 | + else | |
62 | + { | |
63 | + if(minx > layer->extent().xmin()) minx = layer->extent().xmin(); | |
64 | + if(miny > layer->extent().ymin()) miny = layer->extent().ymin(); | |
65 | + if(maxx < layer->extent().xmax()) maxx = layer->extent().xmax(); | |
66 | + if(maxy < layer->extent().ymax()) maxy = layer->extent().ymax(); | |
67 | + } | |
68 | + i++; | |
69 | + } | |
70 | + | |
71 | + boost::property_tree::ptree ptGeographicBoundingbox; | |
72 | + ptGeographicBoundingbox.add("westBoundLongitude", minx); | |
73 | + ptGeographicBoundingbox.add("eastBoundLongitude", maxx); | |
74 | + ptGeographicBoundingbox.add("southBoundLatitude", miny); | |
75 | + ptGeographicBoundingbox.add("northBoundLatitude", maxy); | |
76 | + ptProject.add_child("EX_GeographicBoundingBox",ptGeographicBoundingbox); | |
77 | + | |
78 | + boost::property_tree::ptree ptLayers; | |
79 | + for (std::map<std::string, DmpMapLayer*>::iterator iter= mapLayers.begin();iter != mapLayers.end(); iter++) | |
80 | + { | |
81 | + DmpMapLayer* layer = iter->second; | |
82 | + addServiceInfoLayer(ptLayers,(DmpVectorLayer *)layer,srs); | |
83 | + } | |
84 | + ptProject.add_child("Layers",ptLayers); | |
85 | + pt.add_child("Service", ptProject); | |
86 | + } | |
87 | + | |
88 | + void addServiceInfoLayer(boost::property_tree::ptree &pt, DmpVectorLayer* layer, const std::string& srs) | |
89 | + { | |
90 | + boost::property_tree::ptree ptLayer; | |
91 | + ptLayer.add("Name", layer->name()); | |
92 | + ptLayer.add("Title", layer->title()); | |
93 | + ptLayer.add("CRS", srs); | |
94 | + ptLayer.add("Type", layer->GeomTypeString()); | |
95 | + | |
96 | + boost::property_tree::ptree ptGeographicBoundingbox; | |
97 | + ptGeographicBoundingbox.add("westBoundLongitude", layer->extent().xmin()); | |
98 | + ptGeographicBoundingbox.add("eastBoundLongitude", layer->extent().xmax()); | |
99 | + ptGeographicBoundingbox.add("southBoundLatitude", layer->extent().ymin()); | |
100 | + ptGeographicBoundingbox.add("northBoundLatitude", layer->extent().ymax()); | |
101 | + ptLayer.add_child("EX_GeographicBoundingBox",ptGeographicBoundingbox); | |
102 | + pt.push_back(std::make_pair("", ptLayer)); | |
103 | + //pt.add_child("Layer", ptLayer); | |
104 | + } | |
105 | + | |
106 | +} | |
\ No newline at end of file | ... | ... |
1 | +/************************************************************************** | |
2 | +* file: dmpwmsserviceinfo.h | |
3 | + | |
4 | +* Author: qingxiongf | |
5 | +* Date: 2022-01-11 14:05:38 | |
6 | +* Email: qingxiongf@chinadci.com | |
7 | +* copyright: 广州城市信息研究所有限公司 | |
8 | +***************************************************************************/ | |
9 | + | |
10 | +#ifndef __dmpwmsserviceinfo_h__ | |
11 | +#define __dmpwmsserviceinfo_h__ | |
12 | +#include <boost/property_tree/ptree.hpp> | |
13 | +#include <boost/property_tree/json_parser.hpp> | |
14 | +#include <boost/typeof/typeof.hpp> | |
15 | +#include <memory> | |
16 | +#include <vector> | |
17 | +#include "dmpproject.h" | |
18 | +#include "dmpwmsgetmap.h" | |
19 | +#include "dmpservercontext.h" | |
20 | +#include "dmpvectorlayer.h" | |
21 | +namespace DmpWms | |
22 | +{ | |
23 | + | |
24 | + | |
25 | + /** | |
26 | + * Output GetServiceInfo response | |
27 | + */ | |
28 | + void writeGetServiceInfo( const DmpServerContext &context,const DmpWmsParameters& params, | |
29 | + const DmpProject* project, | |
30 | + bool projectSettings = false); | |
31 | + | |
32 | + void addServiceInfoLayers(boost::property_tree::ptree &pt,const DmpProject* project,std::string& name, std::string& title); | |
33 | + | |
34 | + void addServiceInfoLayer(boost::property_tree::ptree &pt,DmpVectorLayer* layer,const std::string& srs); | |
35 | +} | |
36 | + | |
37 | + | |
38 | +#endif // __dmpwmsserviceinfo_h__ | ... | ... |
... | ... | @@ -36,7 +36,8 @@ public: |
36 | 36 | ~DmpTileServer(); |
37 | 37 | std::string name() const override { return std::string("TileServer");} |
38 | 38 | std::string alias() const override { return std::string("瓦片服务");} |
39 | - std::string path() const override { return std::string("^/DMap/Services/?([\\w./]*)/TileServer/([\\w.]+)([\\w./]*)"); } | |
39 | + //std::string path() const override { return std::string("^/DMap/Services/?([\\w./]*)/TileServer/([\\w.]+)([\\w./]*)"); } | |
40 | + std::string path() const override { return std::string("^/DMap/Services/?([\\w\\W./]*)/TileServer/([\\w.]+)([\\w./]*)"); } | |
40 | 41 | std::string capability() const override; |
41 | 42 | void executeRequest(DmpServerRequest &request, DmpServerResponse &response) override; |
42 | 43 | bool publish(const std::string &serviceName, const std::string &title, unsigned int capability, const DmpProject &project) override; | ... | ... |
... | ... | @@ -9,6 +9,10 @@ |
9 | 9 | #include "dmpesritileprovider.h" |
10 | 10 | #include "dmpwmtsutils.h" |
11 | 11 | #include <string> |
12 | +#include "dmptileproviderfactory.h" | |
13 | +#include <iostream> | |
14 | +#include "dmptilelayer.h" | |
15 | +#include <cairo/cairo.h> | |
12 | 16 | |
13 | 17 | namespace tileserver |
14 | 18 | { |
... | ... | @@ -60,8 +64,65 @@ namespace tileserver |
60 | 64 | } |
61 | 65 | fread.close(); |
62 | 66 | } |
63 | - void DmpEsriTileProvider::GetTileThumbnail(DmpTileLayer* dmpTileLayer,DmpServerResponse& respons) | |
67 | + void DmpEsriTileProvider::GetTileThumbnail(DmpTileLayer* dmpTileLayer,DmpServerResponse& response) | |
64 | 68 | { |
69 | + std::string tilePath=dmpTileLayer->getDataSource(); | |
70 | + DmpRectangle rectangle=dmpTileLayer->extent(); | |
71 | + std::string format=dmpTileLayer->getFormat(); | |
65 | 72 | |
73 | + DmpPoint min=DmpPoint(rectangle.xmin(),rectangle.ymin()); | |
74 | + DmpPoint max=DmpPoint(rectangle.xmax(),rectangle.ymax()); | |
75 | + std::vector<DmpTileMatrixSet*> tileMatrixSets; | |
76 | + dmpTileLayer->getTileMatrixSets(tileMatrixSets); | |
77 | + double resolution; | |
78 | + DmpPoint origin; | |
79 | + int iLevel,xMinTile,yMinTile, xMaxTile, yMaxTile; | |
80 | + if(!TileProviderFactory::GetTileScale(dmpTileLayer,iLevel,xMinTile,yMinTile, xMaxTile, yMaxTile)) | |
81 | + { | |
82 | + response.sendError(500, "缩略图范围错误:("); | |
83 | + return; | |
84 | + } | |
85 | + int heigth=abs(yMaxTile-yMinTile); | |
86 | + int width=abs(xMaxTile-xMinTile); | |
87 | + cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 256*(width+1), 256*(heigth+1)); | |
88 | + cairo_t *cr =cairo_create (surface); | |
89 | + for( int i = 0 ; i <= width ; i++ ) | |
90 | + { | |
91 | + for(int j=0;j<=heigth;j++) | |
92 | + { | |
93 | + std::string filepath; | |
94 | + if(GetTile(yMaxTile+j,xMinTile+i,iLevel,format,filepath)) | |
95 | + { | |
96 | + cairo_surface_t* image = cairo_image_surface_create_from_png( filepath.c_str()); | |
97 | + TileProviderFactory::BufferCopy(image,surface,cr,i*256,j*256); | |
98 | + } | |
99 | + //TileProviderFactory::BufferCopy(image,surface,cr,i*256,j*256); | |
100 | + //cairo_surface_write_to_png (surface, "./wmts.png"); | |
101 | + } | |
102 | + } | |
103 | + std::string responseData; | |
104 | + cairo_surface_write_to_png_stream(surface, TileProviderFactory::cairo_write_func, &responseData); | |
105 | + | |
106 | + response.removeHeader("Content-Type"); | |
107 | + std::string f = (format == "jpg") ? "image/jpg" : "image/png"; | |
108 | + response.setHeader("Content-Type", f); | |
109 | + response.write(responseData); | |
110 | + cairo_destroy (cr); | |
111 | + cairo_surface_destroy (surface); | |
112 | + } | |
113 | + bool DmpEsriTileProvider::GetTile(const int row,const int col,const int level,const std::string& format,std::string& reTilePath) | |
114 | + { | |
115 | + std::string level_str = "L" + DmpWmtsUtils::IntToFormatStr(level); | |
116 | + std::string row_str = "R" + IntToHex8Str(row); | |
117 | + std::string col_str = "C" + IntToHex8Str(col); | |
118 | + | |
119 | + reTilePath = rootPath_ + level_str + "/"+ row_str+"/"+ col_str + "." + format; | |
120 | + | |
121 | + std::ifstream fread(reTilePath, std::ifstream::binary); | |
122 | + if(!fread) | |
123 | + { | |
124 | + return false; | |
125 | + } | |
126 | + | |
66 | 127 | } |
67 | 128 | } |
\ No newline at end of file | ... | ... |
... | ... | @@ -20,7 +20,8 @@ namespace tileserver |
20 | 20 | public: |
21 | 21 | DmpEsriTileProvider(const std::string& rootPath); |
22 | 22 | void WriteTile(const int row, const int col, const int level, const std::string& format, DmpServerResponse& response) override; |
23 | - void GetTileThumbnail(DmpTileLayer* dmpTileLayer,DmpServerResponse& respons) override; | |
23 | + void GetTileThumbnail(DmpTileLayer* dmpTileLayer,DmpServerResponse& response) override; | |
24 | + bool GetTile(const int row,const int col,const int level,const std::string& format,std::string& reTilePath); | |
24 | 25 | private: |
25 | 26 | std::string IntToHex8Str(const int num); |
26 | 27 | }; | ... | ... |
... | ... | @@ -105,6 +105,12 @@ namespace tileserver |
105 | 105 | iLevel=id; |
106 | 106 | resolution=relus; |
107 | 107 | break; |
108 | + } | |
109 | + else if(leviter==tileLevels.cbegin()&&(heigth+1)*(width+1)>=9) | |
110 | + { | |
111 | + iLevel=id; | |
112 | + resolution=relus; | |
113 | + break; | |
108 | 114 | } |
109 | 115 | } |
110 | 116 | } |
... | ... | @@ -145,7 +151,7 @@ namespace tileserver |
145 | 151 | } |
146 | 152 | if(cr==NULL) |
147 | 153 | { |
148 | - cr = cairo_create (pClsCSTo); | |
154 | + cr = cairo_create (pClsCSTo); | |
149 | 155 | } |
150 | 156 | cairo_set_source_surface(cr, pClsCSFrom, x, y); |
151 | 157 | cairo_paint(cr); | ... | ... |
请
注册
或
登录
后发表评论