提交 380261be7c46485db374f03801854c0d7bcaba17

作者 WZP 万忠平
2 个父辈 0a90deaa 9b022cef
正在显示 62 个修改的文件 包含 4955 行增加523 行删除
@@ -11,21 +11,22 @@ @@ -11,21 +11,22 @@
11 #include "dmpvectorlayerrenderer.h" 11 #include "dmpvectorlayerrenderer.h"
12 #include "dmpproviderregistry.h" 12 #include "dmpproviderregistry.h"
13 #include "libpq-fe.h" 13 #include "libpq-fe.h"
  14 +#include "clsUtil.h"
  15 +#include <boost/algorithm/string/predicate.hpp>
14 16
15 DmpVectorLayer::DmpVectorLayer(const std::string &path, 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 DmpVectorLayer::~DmpVectorLayer() 32 DmpVectorLayer::~DmpVectorLayer()
@@ -34,147 +35,254 @@ DmpVectorLayer::~DmpVectorLayer() @@ -34,147 +35,254 @@ DmpVectorLayer::~DmpVectorLayer()
34 35
35 DmpMapLayerRenderer *DmpVectorLayer::createMapRenderer(DmpRenderContext &rendererContext) 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 bool DmpVectorLayer::readXml(const boost::property_tree::ptree &layerNode) 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 bool DmpVectorLayer::writeXml(boost::property_tree::ptree &layerNode) 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 void DmpVectorLayer::setDataSource(const std::string &dataSource, const std::string &baseName, const std::string &provider, bool loadDefaultStyleFlag) 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 DmpWkbTypes::GeometryType DmpVectorLayer::GeometryType() const 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 ConnStatusType t = PQstatus(pPGconn); 215 ConnStatusType t = PQstatus(pPGconn);
117 if (t != CONNECTION_OK) 216 if (t != CONNECTION_OK)
118 - return false; 217 + return false;
119 int re = PQsetClientEncoding(pPGconn, "UTF-8"); 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 char *sz = PQerrorMessage(pPGconn); 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 if (!geomtype) 242 if (!geomtype)
141 return false; 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 PQfinish(pPGconn); 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 int outTime = 600; 286 int outTime = 600;
179 if(this->dataCount >500000 && this->m_pDataset->m_MapLayerThinning.size() ==0) 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,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 - }  
  316 + }
  317 + return nullptr;
  318 +}
@@ -44,6 +44,7 @@ class CORE_EXPORT DmpVectorLayer : public DmpMapLayer @@ -44,6 +44,7 @@ class CORE_EXPORT DmpVectorLayer : public DmpMapLayer
44 DmpMapLayerRenderer *createMapRenderer(DmpRenderContext &rendererContext); 44 DmpMapLayerRenderer *createMapRenderer(DmpRenderContext &rendererContext);
45 bool readXml(const boost::property_tree::ptree &layerNode); 45 bool readXml(const boost::property_tree::ptree &layerNode);
46 bool writeXml(boost::property_tree::ptree &layerNode); 46 bool writeXml(boost::property_tree::ptree &layerNode);
  47 + bool writejson(std::string& json);
47 48
48 DmpFeatureRenderer *renderer() { return renderer_; } 49 DmpFeatureRenderer *renderer() { return renderer_; }
49 void setRenderer(DmpFeatureRenderer *renderer); 50 void setRenderer(DmpFeatureRenderer *renderer);
@@ -59,7 +60,10 @@ class CORE_EXPORT DmpVectorLayer : public DmpMapLayer @@ -59,7 +60,10 @@ class CORE_EXPORT DmpVectorLayer : public DmpMapLayer
59 std::string schema() { return schema_;} 60 std::string schema() { return schema_;}
60 std::string geom() { return geom_;} 61 std::string geom() { return geom_;}
61 std::string wherestr() { return wherestr_;} 62 std::string wherestr() { return wherestr_;}
  63 + std::string GeomTypeString(){return wkbTypeString_;}
  64 + std::string srid(){return srid_;}
62 size_t featurecount(){return featurecount_;} 65 size_t featurecount(){return featurecount_;}
  66 + bool IsInit(){return isinit_;}
63 private: 67 private:
64 bool readExtentFromXml_; 68 bool readExtentFromXml_;
65 DmpWkbTypes::Type wkbType_ = DmpWkbTypes::Unknown; 69 DmpWkbTypes::Type wkbType_ = DmpWkbTypes::Unknown;
@@ -69,10 +73,15 @@ class CORE_EXPORT DmpVectorLayer : public DmpMapLayer @@ -69,10 +73,15 @@ class CORE_EXPORT DmpVectorLayer : public DmpMapLayer
69 std::string schema_; 73 std::string schema_;
70 std::string geom_; 74 std::string geom_;
71 size_t featurecount_; 75 size_t featurecount_;
  76 + std::string wkbTypeString_;
  77 + std::string srid_;
72 78
73 std::string wherestr_; 79 std::string wherestr_;
  80 + bool isinit_ = false;
74 shared_ptr<DmapCore_30::Renderer> renderer_30_ = nullptr; 81 shared_ptr<DmapCore_30::Renderer> renderer_30_ = nullptr;
75 vector<shared_ptr<DmpVectorThinLayer>> thinLayers_; 82 vector<shared_ptr<DmpVectorThinLayer>> thinLayers_;
  83 +
  84 +
76 85
77 }; 86 };
78 #endif //__dmpvectorlayer_h__ 87 #endif //__dmpvectorlayer_h__
@@ -53,22 +53,34 @@ namespace DmapCore_30 @@ -53,22 +53,34 @@ namespace DmapCore_30
53 for (auto ptchild = pt.begin(); ptchild != pt.end(); ++ptchild) 53 for (auto ptchild = pt.begin(); ptchild != pt.end(); ++ptchild)
54 { 54 {
55 string sz = ptchild->first; 55 string sz = ptchild->first;
  56 +
56 if (boost::iequals(sz, "OTHER")) 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 else if (boost::iequals(sz, "EXACT")) 69 else if (boost::iequals(sz, "EXACT"))
62 { 70 {
63 string sValue = clsXML::XMLGetPropByString(ptchild->second, "value"); 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 else{ ; } 85 else{ ; }
74 } 86 }
@@ -587,6 +587,104 @@ namespace DmapCore_30 @@ -587,6 +587,104 @@ namespace DmapCore_30
587 *bValue = false; 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, "&", "&amp;");
  597 + str1 = s.c_str();
  598 + }
  599 + if (strstr(str1, "<"))
  600 + {
  601 + s = clsUtil::CharReplace(s, "<", "&lt;");
  602 + str1 = s.c_str();
  603 + }
  604 + if (strstr(str1, ">"))
  605 + {
  606 + s = clsUtil::CharReplace(s, ">", "&gt;");
  607 + str1 = s.c_str();
  608 + }
  609 + if (strstr(str1, "\""))
  610 + {
  611 + s = clsUtil::CharReplace(s, "\"", "&quot;");
  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, "'", "&apos;");
  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 std::string clsUtil::fmt(char* fmt, ...) 688 std::string clsUtil::fmt(char* fmt, ...)
591 { 689 {
592 va_list argptr; 690 va_list argptr;
@@ -73,7 +73,11 @@ else { to[index]->Release(); to[index] = from; }\ @@ -73,7 +73,11 @@ else { to[index]->Release(); to[index] = from; }\
73 73
74 static void GetFiles(string path, string exd, vector<string> & files); 74 static void GetFiles(string path, string exd, vector<string> & files);
75 static int ParseStringTok(char * sz, char toK, char ** szPtr, int maxPtr); 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 static std::string fmt(char *, ...); 81 static std::string fmt(char *, ...);
78 static std::string fmt(const char*, ...); 82 static std::string fmt(const char*, ...);
79 static void ValueString(string * s, bool* bValue); 83 static void ValueString(string * s, bool* bValue);
@@ -32,6 +32,7 @@ SET (DMAP_SERVER_SRCS @@ -32,6 +32,7 @@ SET (DMAP_SERVER_SRCS
32 dmpserverparameters.cpp 32 dmpserverparameters.cpp
33 dmpserverplugins.cpp 33 dmpserverplugins.cpp
34 dmpserverutils.cpp 34 dmpserverutils.cpp
  35 + dmpserverdes.cpp
35 dmpserverloader.cpp 36 dmpserverloader.cpp
36 dmpserverproject.cpp 37 dmpserverproject.cpp
37 dmpserverregistry.cpp 38 dmpserverregistry.cpp
@@ -39,7 +40,6 @@ SET (DMAP_SERVER_SRCS @@ -39,7 +40,6 @@ SET (DMAP_SERVER_SRCS
39 python/dmpserverwrapper.cpp 40 python/dmpserverwrapper.cpp
40 dmphttpbase.cpp 41 dmphttpbase.cpp
41 dmphttputils.cpp 42 dmphttputils.cpp
42 -  
43 ) 43 )
44 44
45 SET (DMAP_SERVER_HDRS 45 SET (DMAP_SERVER_HDRS
@@ -63,6 +63,7 @@ SET (DMAP_SERVER_HDRS @@ -63,6 +63,7 @@ SET (DMAP_SERVER_HDRS
63 dmpserverparameters.h 63 dmpserverparameters.h
64 dmpserverplugins.h 64 dmpserverplugins.h
65 dmpserverutils.h 65 dmpserverutils.h
  66 + dmpserverdes.h
66 dmpservice.h 67 dmpservice.h
67 dmpservermodule.h 68 dmpservermodule.h
68 dmpserverloader.h 69 dmpserverloader.h
@@ -71,7 +72,6 @@ SET (DMAP_SERVER_HDRS @@ -71,7 +72,6 @@ SET (DMAP_SERVER_HDRS
71 python/dmppythonutils.h 72 python/dmppythonutils.h
72 dmphttpbase.h 73 dmphttpbase.h
73 dmphttputils.h 74 dmphttputils.h
74 -  
75 ) 75 )
76 76
77 ############################################################# 77 #############################################################
@@ -49,7 +49,8 @@ public: @@ -49,7 +49,8 @@ public:
49 { 49 {
50 return; 50 return;
51 } 51 }
52 - 52 +
  53 +
53 DmpSpServerRequest dmpRequest(request); 54 DmpSpServerRequest dmpRequest(request);
54 DmpSpServerResponse dmpResponse(response); 55 DmpSpServerResponse dmpResponse(response);
55 pDmpServer->HandleRequest(dmpRequest, dmpResponse); 56 pDmpServer->HandleRequest(dmpRequest, dmpResponse);
@@ -54,25 +54,25 @@ if (temp_data.find(http_) == 0) { @@ -54,25 +54,25 @@ if (temp_data.find(http_) == 0) {
54 int DmpHttp::DmpHttpBase::buildPostRequest(const std::string& server, const std::string& path, 54 int DmpHttp::DmpHttpBase::buildPostRequest(const std::string& server, const std::string& path,
55 std::ostream& out_request) { 55 std::ostream& out_request) {
56 // 分割path中的json数据 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 return HTTP_SUCCESS; 76 return HTTP_SUCCESS;
77 } 77 }
78 78
@@ -11,8 +11,8 @@ @@ -11,8 +11,8 @@
11 #include <iostream> 11 #include <iostream>
12 #include <boost/asio.hpp> 12 #include <boost/asio.hpp>
13 namespace DmpHttp 13 namespace DmpHttp
14 -{  
15 - #define HTTP_SUCCESS (0) // 操作成功 14 +{
  15 + #define HTTP_SUCCESS (0) // 操作成功
16 #define HTTP_ERROR_UNKNOWN (-1) // 未知的错误 16 #define HTTP_ERROR_UNKNOWN (-1) // 未知的错误
17 #define HTTP_ERROR_NETWORK (-2) // 网络连接失败 17 #define HTTP_ERROR_NETWORK (-2) // 网络连接失败
18 #define HTTP_ERROR_HTTP_HEAD (-3) // 未找到协议头 http || https 18 #define HTTP_ERROR_HTTP_HEAD (-3) // 未找到协议头 http || https
@@ -35,6 +35,7 @@ namespace DmpHttp @@ -35,6 +35,7 @@ namespace DmpHttp
35 virtual ~DmpHttpBase(); 35 virtual ~DmpHttpBase();
36 // Post请求 36 // Post请求
37 virtual int post(const std::string& url) = 0; 37 virtual int post(const std::string& url) = 0;
  38 + virtual int post(const std::string& url, std::string& postData)= 0;
38 // get请求 39 // get请求
39 virtual int get(const std::string& url) = 0; 40 virtual int get(const std::string& url) = 0;
40 virtual std::string getResponse(void) = 0; 41 virtual std::string getResponse(void) = 0;
@@ -18,6 +18,11 @@ int DmpHttp::DmpHttpUtils::post(const std::string& url) @@ -18,6 +18,11 @@ int DmpHttp::DmpHttpUtils::post(const std::string& url)
18 handleRequestResolve(url, DmpHttpBase::buildPostRequest); 18 handleRequestResolve(url, DmpHttpBase::buildPostRequest);
19 return HTTP_SUCCESS; 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 int DmpHttp::DmpHttpUtils::get(const std::string& url) 26 int DmpHttp::DmpHttpUtils::get(const std::string& url)
22 { 27 {
23 handleRequestResolve(url, DmpHttpBase::buildGetRequest); 28 handleRequestResolve(url, DmpHttpBase::buildGetRequest);
@@ -47,6 +52,32 @@ void DmpHttp::DmpHttpUtils::handleRequestResolve(const std::string& url, pBuildR @@ -47,6 +52,32 @@ void DmpHttp::DmpHttpUtils::handleRequestResolve(const std::string& url, pBuildR
47 } 52 }
48 return; 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 void DmpHttp::DmpHttpUtils::handleResolve(const boost::system::error_code& err, 81 void DmpHttp::DmpHttpUtils::handleResolve(const boost::system::error_code& err,
51 boost::asio::ip::tcp::resolver::iterator endpoint_iterator) { 82 boost::asio::ip::tcp::resolver::iterator endpoint_iterator) {
52 if (err) { 83 if (err) {
@@ -173,7 +204,14 @@ std::string DmpHttp::post(const std::string &url) { @@ -173,7 +204,14 @@ std::string DmpHttp::post(const std::string &url) {
173 io.run(); 204 io.run();
174 return c.getResponse(); 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 std::string DmpHttp::get(const std::string &url) { 215 std::string DmpHttp::get(const std::string &url) {
178 boost::asio::io_service io; 216 boost::asio::io_service io;
179 DmpHttp::DmpHttpUtils c(io); 217 DmpHttp::DmpHttpUtils c(io);
@@ -20,12 +20,14 @@ namespace DmpHttp @@ -20,12 +20,14 @@ namespace DmpHttp
20 DmpHttpUtils(boost::asio::io_service& io_service); 20 DmpHttpUtils(boost::asio::io_service& io_service);
21 virtual ~DmpHttpUtils(); 21 virtual ~DmpHttpUtils();
22 virtual int post(const std::string& url); 22 virtual int post(const std::string& url);
  23 + virtual int post(const std::string& url, std::string& postData);
23 virtual int get(const std::string& url); 24 virtual int get(const std::string& url);
24 25
25 virtual std::string getResponse(void) {return responseData_;} 26 virtual std::string getResponse(void) {return responseData_;}
26 private: 27 private:
27 // 建立请求 28 // 建立请求
28 void handleRequestResolve(const std::string& url, pBuildRequest func); 29 void handleRequestResolve(const std::string& url, pBuildRequest func);
  30 + void handleRequestResolve(const std::string& url, std::string& path, pBuildRequest func);
29 // 解析后 31 // 解析后
30 void handleResolve(const boost::system::error_code& err, 32 void handleResolve(const boost::system::error_code& err,
31 boost::asio::ip::tcp::resolver::iterator endpoint_iterator); 33 boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
@@ -52,6 +54,7 @@ namespace DmpHttp @@ -52,6 +54,7 @@ namespace DmpHttp
52 std::string responseData_; 54 std::string responseData_;
53 }; 55 };
54 std::string post(const std::string &url); 56 std::string post(const std::string &url);
  57 + std::string post(const std::string& url, std::string& postData);
55 std::string get(const std::string &url); 58 std::string get(const std::string &url);
56 } 59 }
57 60
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 #include <iostream> 10 #include <iostream>
11 #include "dmpserverconfig.h" 11 #include "dmpserverconfig.h"
12 #include "dmpapplication.h" 12 #include "dmpapplication.h"
13 - 13 +#include "dmphttputils.h"
14 DmpServerConfig::DmpServerConfig() 14 DmpServerConfig::DmpServerConfig()
15 { 15 {
16 std::string iniFile = DmpApplication::Instance()->libexecPath() + iniFileName_; 16 std::string iniFile = DmpApplication::Instance()->libexecPath() + iniFileName_;
@@ -82,4 +82,14 @@ std::string DmpServerConfig::getValue(const std::string &section,const std::stri @@ -82,4 +82,14 @@ std::string DmpServerConfig::getValue(const std::string &section,const std::stri
82 std::cerr << "Exception: " << e.what() << "\n"; 82 std::cerr << "Exception: " << e.what() << "\n";
83 } 83 }
84 return value; 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 }
@@ -22,6 +22,9 @@ public: @@ -22,6 +22,9 @@ public:
22 std::string getPqsqlConnect(); 22 std::string getPqsqlConnect();
23 std::string getMetaUrl(); 23 std::string getMetaUrl();
24 std::string getValue(const std::string &section,const std::string &key); 24 std::string getValue(const std::string &section,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 private: 28 private:
26 DmpServerConfig(); 29 DmpServerConfig();
27 boost::property_tree::ptree ptIni_; 30 boost::property_tree::ptree ptIni_;
  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 +}
  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,7 +9,7 @@
9 #include "dmpservermanager.h" 9 #include "dmpservermanager.h"
10 #include "dmpserver.h" 10 #include "dmpserver.h"
11 #include "dmphttputils.h" 11 #include "dmphttputils.h"
12 -#include "dmpserverConfig.h" 12 +#include "dmpserverconfig.h"
13 #include <memory> 13 #include <memory>
14 #include <boost/property_tree/ptree.hpp> 14 #include <boost/property_tree/ptree.hpp>
15 #include <boost/property_tree/json_parser.hpp> 15 #include <boost/property_tree/json_parser.hpp>
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 #include "dmpserverregistry.h" 20 #include "dmpserverregistry.h"
21 21
22 22
23 -#define URI_RELOAD ("/API/Service/TileService/Reload") //加载已注册服务接口 23 +#define URI_RELOAD ("/API/Service/Reload") //加载已注册服务接口
24 class SERVER_EXPORT DmpServerManager 24 class SERVER_EXPORT DmpServerManager
25 { 25 {
26 public: 26 public:
@@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
16 // #include <boost/algorithm/string.hpp> 16 // #include <boost/algorithm/string.hpp>
17 #include "dmplogger.h" 17 #include "dmplogger.h"
18 18
  19 +
  20 +
19 DmpServerRequest::DmpServerRequest() 21 DmpServerRequest::DmpServerRequest()
20 { 22 {
21 isRestful_ = false; 23 isRestful_ = false;
@@ -39,19 +39,21 @@ DmpSpServerRequest::DmpSpServerRequest(SP_HttpRequest* request) @@ -39,19 +39,21 @@ DmpSpServerRequest::DmpSpServerRequest(SP_HttpRequest* request)
39 } 39 }
40 40
41 //获取querystring 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 if (pos != std::string::npos) { 47 if (pos != std::string::npos) {
46 - std::string path = url.substr(0, pos); 48 + std::string path = deurl.substr(0, pos);
47 setPath(path); 49 setPath(path);
48 std::string queryString; 50 std::string queryString;
49 - queryString = url.substr(pos+1,url.length()); 51 + queryString = deurl.substr(pos+1,deurl.length());
50 setQuery(queryString); 52 setQuery(queryString);
51 } 53 }
52 else { 54 else {
53 isRestful_ = true; 55 isRestful_ = true;
54 - setPath(url); 56 + setPath(deurl);
55 } 57 }
56 58
57 // for(int i=0; i< request->getParamCount(); i++) { 59 // for(int i=0; i< request->getParamCount(); i++) {
@@ -71,4 +73,50 @@ const void * DmpSpServerRequest::GetData() const @@ -71,4 +73,50 @@ const void * DmpSpServerRequest::GetData() const
71 int DmpSpServerRequest::GetDataLength() const 73 int DmpSpServerRequest::GetDataLength() const
72 { 74 {
73 return dataLen_; 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 }
@@ -23,6 +23,7 @@ public: @@ -23,6 +23,7 @@ public:
23 DmpSpServerRequest(SP_HttpRequest* request); 23 DmpSpServerRequest(SP_HttpRequest* request);
24 const void * GetData() const override; 24 const void * GetData() const override;
25 int GetDataLength() const override; 25 int GetDataLength() const override;
  26 + bool UrlDecode(const std::string& src, std::string& dst);
26 private: 27 private:
27 const void* data_; 28 const void* data_;
28 int dataLen_; 29 int dataLen_;
@@ -130,16 +130,16 @@ void DmpManagerApiHandler::regService(const DmpServerApiContext &context) const @@ -130,16 +130,16 @@ void DmpManagerApiHandler::regService(const DmpServerApiContext &context) const
130 break; 130 break;
131 } 131 }
132 132
133 - default: 133 + default:
134 break; 134 break;
135 } 135 }
136 136
137 - context.response()->write("{\"status\":\""+std::to_string(flag)+"\",\"url\":\""+url+"\",\"message\":\"Pulish service successful!\"}");  
138 // std::string projData; 137 // std::string projData;
139 // DmpServerUtils::Base64Decode(project, &projData); 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 else 144 else
145 { 145 {
@@ -312,6 +312,12 @@ void DmpManagerApiHandler::GetTileServiceInfo(const DmpServerApiContext &context @@ -312,6 +312,12 @@ void DmpManagerApiHandler::GetTileServiceInfo(const DmpServerApiContext &context
312 path= pt.get<std::string>("projectlayers.maplayer.datasource"); 312 path= pt.get<std::string>("projectlayers.maplayer.datasource");
313 confcdipath=path+"/conf.cdi"; 313 confcdipath=path+"/conf.cdi";
314 confxmlpath=path+"/conf.xml"; 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 //读取切片配置文件conf.cdi 321 //读取切片配置文件conf.cdi
316 boost::property_tree::ptree pt_confcdi; 322 boost::property_tree::ptree pt_confcdi;
317 boost::property_tree::read_xml(confcdipath,pt_confcdi); 323 boost::property_tree::read_xml(confcdipath,pt_confcdi);
@@ -334,6 +340,8 @@ void DmpManagerApiHandler::GetTileServiceInfo(const DmpServerApiContext &context @@ -334,6 +340,8 @@ void DmpManagerApiHandler::GetTileServiceInfo(const DmpServerApiContext &context
334 std::string tileCols=pt_confxml.get<std::string>("CacheInfo.TileCacheInfo.TileCols"); 340 std::string tileCols=pt_confxml.get<std::string>("CacheInfo.TileCacheInfo.TileCols");
335 std::string tileRows=pt_confxml.get<std::string>("CacheInfo.TileCacheInfo.TileRows"); 341 std::string tileRows=pt_confxml.get<std::string>("CacheInfo.TileCacheInfo.TileRows");
336 std::string dpi=pt_confxml.get<std::string>("CacheInfo.TileCacheInfo.DPI"); 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 pt.put("projectCrs.spatialrefsys.wkt",strWKT); 345 pt.put("projectCrs.spatialrefsys.wkt",strWKT);
338 pt.put("projectCrs.spatialrefsys.srid",wkid); 346 pt.put("projectCrs.spatialrefsys.srid",wkid);
339 347
@@ -9,18 +9,23 @@ SET (MAPSERVER_SRCS @@ -9,18 +9,23 @@ SET (MAPSERVER_SRCS
9 dmppgsqlpool.cpp 9 dmppgsqlpool.cpp
10 dmppgsqlsourcepools.cpp 10 dmppgsqlsourcepools.cpp
11 wfs/dmpwfs.cpp 11 wfs/dmpwfs.cpp
  12 + wfs/dmpwfsfilter.cpp
  13 + wfs/dmpgmlfilter.cpp
12 wfs/dmpwfsgetcapabilities.cpp 14 wfs/dmpwfsgetcapabilities.cpp
13 wfs/dmpwfsgetfeature.cpp 15 wfs/dmpwfsgetfeature.cpp
14 wfs/dmpwfsparameters.cpp 16 wfs/dmpwfsparameters.cpp
  17 + wfs/dmpsqlfactory.cpp
15 wms/dmpwmsrenderer.cpp 18 wms/dmpwmsrenderer.cpp
16 wms/dmpwms.cpp 19 wms/dmpwms.cpp
17 wms/dmpwmsparameters.cpp 20 wms/dmpwmsparameters.cpp
18 wms/dmpwmsgetcapabilities.cpp 21 wms/dmpwmsgetcapabilities.cpp
19 wms/dmpwmsgetmap.cpp 22 wms/dmpwmsgetmap.cpp
  23 + wms/dmpwmsserviceinfo.cpp
20 wms/dmpwmsgetfeatureinfo.cpp 24 wms/dmpwmsgetfeatureinfo.cpp
21 mapping/dmpmapping.cpp 25 mapping/dmpmapping.cpp
22 mapping/dmpeditservice.cpp 26 mapping/dmpeditservice.cpp
23 mapping/dmpmappingparameters.cpp 27 mapping/dmpmappingparameters.cpp
  28 + mapping/dmpimageinfo.cpp
24 ) 29 )
25 30
26 SET (MAPSERVER_HDRS 31 SET (MAPSERVER_HDRS
@@ -30,18 +35,23 @@ SET (MAPSERVER_HDRS @@ -30,18 +35,23 @@ SET (MAPSERVER_HDRS
30 dmppgsqlpool.h 35 dmppgsqlpool.h
31 dmppgsqlsourcepools.h 36 dmppgsqlsourcepools.h
32 wfs/dmpwfs.h 37 wfs/dmpwfs.h
  38 + wfs/dmpwfsfilter.h
  39 + wfs/dmpgmlfilter.h
33 wfs/dmpwfsgetcapabilities.h 40 wfs/dmpwfsgetcapabilities.h
34 wfs/dmpwfsgetfeature.h 41 wfs/dmpwfsgetfeature.h
35 wfs/dmpwfsparameters.h 42 wfs/dmpwfsparameters.h
  43 + wfs/dmpsqlfactory.h
36 wms/dmpwmsrenderer.h 44 wms/dmpwmsrenderer.h
37 wms/dmpwms.h 45 wms/dmpwms.h
38 wms/dmpwmsparameters.h 46 wms/dmpwmsparameters.h
39 wms/dmpwmsgetcapabilities.h 47 wms/dmpwmsgetcapabilities.h
40 wms/dmpwmsgetmap.h 48 wms/dmpwmsgetmap.h
  49 + wms/dmpwmsserviceinfo.h
41 wms/dmpwmsgetfeatureinfo.h 50 wms/dmpwmsgetfeatureinfo.h
42 mapping/dmpmapping.h 51 mapping/dmpmapping.h
43 mapping/dmpeditservice.h 52 mapping/dmpeditservice.h
44 mapping/dmpmappingparameters.h 53 mapping/dmpmappingparameters.h
  54 + mapping/dmpimageinfo.h
45 ) 55 )
46 56
47 ######################################################## 57 ########################################################
@@ -34,7 +34,8 @@ public: @@ -34,7 +34,8 @@ public:
34 ~DmpMapServer(); 34 ~DmpMapServer();
35 std::string name() const override { return std::string("MapServer");} 35 std::string name() const override { return std::string("MapServer");}
36 std::string alias() const override { return std::string("矢量地图服务");} 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 std::string capability() const override; 39 std::string capability() const override;
39 void executeRequest(DmpServerRequest &request, DmpServerResponse &response) override; 40 void executeRequest(DmpServerRequest &request, DmpServerResponse &response) override;
40 bool publish(const std::string &serviceName, const std::string &title, unsigned int capability, const DmpProject &project) override; 41 bool publish(const std::string &serviceName, const std::string &title, unsigned int capability, const DmpProject &project) override;
@@ -7,11 +7,109 @@ @@ -7,11 +7,109 @@
7 * copyright: 广州城市信息研究所有限公司 7 * copyright: 广州城市信息研究所有限公司
8 ***************************************************************************/ 8 ***************************************************************************/
9 #include "dmpmapserverutil.h" 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 namespace mapserver 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 //以GeoJson的形式返回 113 //以GeoJson的形式返回
16 void DmpMapServerUtil::responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::string &responseData,const string& layerName,const string& srid) 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,10 +126,10 @@ void DmpMapServerUtil::responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::str
28 int fieldsCount = pPgsqlConn->GetFieldCount(); 126 int fieldsCount = pPgsqlConn->GetFieldCount();
29 for (int featureIndex = 0; pPgsqlConn->next(); featureIndex++) 127 for (int featureIndex = 0; pPgsqlConn->next(); featureIndex++)
30 { 128 {
31 -  
32 if (featureIndex > 0) 129 if (featureIndex > 0)
33 responseData.append(","); 130 responseData.append(",");
34 - //ab->AppendString(R"({"type":"Feature")"); 131 +
  132 + responseData.append(R"({"type":"Feature")");
35 133
36 string geometry = ""; 134 string geometry = "";
37 string properties = ""; 135 string properties = "";
@@ -43,6 +141,7 @@ void DmpMapServerUtil::responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::str @@ -43,6 +141,7 @@ void DmpMapServerUtil::responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::str
43 { 141 {
44 break; 142 break;
45 } 143 }
  144 +
46 145
47 if (strncmp(sfieldName, "RN_RN", 5) == 0) 146 if (strncmp(sfieldName, "RN_RN", 5) == 0)
48 continue; 147 continue;
@@ -148,4 +247,184 @@ void DmpMapServerUtil::responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::str @@ -148,4 +247,184 @@ void DmpMapServerUtil::responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::str
148 } 247 }
149 return strsrc; 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 }
@@ -14,14 +14,20 @@ @@ -14,14 +14,20 @@
14 #include <memory> 14 #include <memory>
15 #include "dmppgsqlsourcepools.h" 15 #include "dmppgsqlsourcepools.h"
16 16
  17 +
17 namespace mapserver 18 namespace mapserver
18 { 19 {
19 class DmpMapServerUtil 20 class DmpMapServerUtil
20 { 21 {
21 public: 22 public:
22 static void responseGeojson(shared_ptr<DmpPgsql> pPgsqlConn, std::string &responseData,const string& layerName,const std::string &srid); 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 static void toJsonString(std::string &s); 25 static void toJsonString(std::string &s);
24 static std::string replace(std::string strsrc, std::string strfind, std::string strrep); 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,8 +13,11 @@
13 #define MAX_SIZE 40 13 #define MAX_SIZE 40
14 namespace mapserver 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 waitConnectSize_ = MAX_SIZE; 21 waitConnectSize_ = MAX_SIZE;
19 connectionTimeout_ = 15000; 22 connectionTimeout_ = 15000;
20 } 23 }
@@ -19,42 +19,42 @@ @@ -19,42 +19,42 @@
19 namespace mapserver 19 namespace mapserver
20 { 20 {
21 class DmpPgsqlPool 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 ~DmpPgsqlPool(); 25 ~DmpPgsqlPool();
26 - void ScannerConnectionTask(); 26 + void ScannerConnectionTask();
27 std::shared_ptr<DmpPgsql> TestDmpPgsql(void); 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 void Close(void); 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 int waitConnectSize_; 44 int waitConnectSize_;
43 int connectSize_ = 0; 45 int connectSize_ = 0;
44 mutex mutex_; 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 #endif //__dmppgsqlpool_h__ 60 #endif //__dmppgsqlpool_h__
60 -  
@@ -9,6 +9,15 @@ @@ -9,6 +9,15 @@
9 9
10 #include "dmppgsqlsourcepools.h" 10 #include "dmppgsqlsourcepools.h"
11 #include <iostream> 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 //#include "DES.h" 21 //#include "DES.h"
13 //#include "StringHelp.h" 22 //#include "StringHelp.h"
14 23
@@ -79,9 +88,9 @@ namespace mapserver @@ -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 if (poolIter2 != this->pgsqlPool_.end()) 94 if (poolIter2 != this->pgsqlPool_.end())
86 { 95 {
87 shared_ptr<DmpPgsqlPool> pool = poolIter2->second; 96 shared_ptr<DmpPgsqlPool> pool = poolIter2->second;
@@ -166,6 +175,9 @@ namespace mapserver @@ -166,6 +175,9 @@ namespace mapserver
166 return ""; 175 return "";
167 } 176 }
168 177
  178 +
  179 +
  180 +
169 bool DmpPgsqlSourcePools::UpdateDatabasePool() 181 bool DmpPgsqlSourcePools::UpdateDatabasePool()
170 { 182 {
171 printf("InitDatabasePool\r\n"); 183 printf("InitDatabasePool\r\n");
@@ -319,13 +331,6 @@ namespace mapserver @@ -319,13 +331,6 @@ namespace mapserver
319 string alias = pPgsqlConn->getString(2); 331 string alias = pPgsqlConn->getString(2);
320 string uri = pPgsqlConn->getString(3); 332 string uri = pPgsqlConn->getString(3);
321 string connectstr = pPgsqlConn->getString(4); 333 string connectstr = pPgsqlConn->getString(4);
322 - /* if(guid == "74c73a18-00c9-11ec-aced-0242ac110002")  
323 - {  
324 - continue;  
325 - }*/  
326 -  
327 -  
328 -  
329 string pgConnect= ""; 334 string pgConnect= "";
330 if(connectstr != "") 335 if(connectstr != "")
331 { 336 {
@@ -440,13 +445,95 @@ namespace mapserver @@ -440,13 +445,95 @@ namespace mapserver
440 445
441 bool DmpPgsqlSourcePools::CreateDefaultDatabasePool(string dataType, string connStr) 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 defaultPool_ = newPool; 449 defaultPool_ = newPool;
445 bool result = defaultPool_->Connect(connStr.c_str()); 450 bool result = defaultPool_->Connect(connStr.c_str());
446 - 451 +
447 return true; 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 bool DmpPgsqlSourcePools::AddDatabasePool(string dataType, 537 bool DmpPgsqlSourcePools::AddDatabasePool(string dataType,
451 string guid, 538 string guid,
452 string databaseName, 539 string databaseName,
@@ -454,7 +541,7 @@ namespace mapserver @@ -454,7 +541,7 @@ namespace mapserver
454 string connStr) 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 // newPool->guid() = guid; 545 // newPool->guid() = guid;
459 // newPool->m_name = databaseName; 546 // newPool->m_name = databaseName;
460 // newPool->m_alias = alias; 547 // newPool->m_alias = alias;
@@ -468,7 +555,7 @@ namespace mapserver @@ -468,7 +555,7 @@ namespace mapserver
468 { 555 {
469 if(pgsqlPool_.find(guid) == pgsqlPool_.end()) 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 // newPool->guid() = guid; 559 // newPool->guid() = guid;
473 // newPool->m_name = databaseName; 560 // newPool->m_name = databaseName;
474 // newPool->m_alias = alias; 561 // newPool->m_alias = alias;
@@ -7,58 +7,61 @@ @@ -7,58 +7,61 @@
7 * copyright: 广州城市信息研究所有限公司 7 * copyright: 广州城市信息研究所有限公司
8 ***************************************************************************/ 8 ***************************************************************************/
9 9
10 -  
11 #ifndef __dmppgsqlsourcepools_h__ 10 #ifndef __dmppgsqlsourcepools_h__
12 #define __dmppgsqlsourcepools_h__ 11 #define __dmppgsqlsourcepools_h__
13 12
14 #include <map> 13 #include <map>
15 #include "dmppgsqlpool.h" 14 #include "dmppgsqlpool.h"
16 #include <mutex> 15 #include <mutex>
  16 +#include "dmpserverconfig.h"
  17 +
17 #define DMAP_DMDMS_DATABASE "dmdms_database" 18 #define DMAP_DMDMS_DATABASE "dmdms_database"
18 #define DMAP_SCHEMA "public" 19 #define DMAP_SCHEMA "public"
19 #define MAXCOUNT 200000 20 #define MAXCOUNT 200000
20 21
21 namespace mapserver 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,6 +11,7 @@
11 #include "dmpserverresponse.h" 11 #include "dmpserverresponse.h"
12 #include "dmpserverrequest.h" 12 #include "dmpserverrequest.h"
13 #include "dmpproject.h" 13 #include "dmpproject.h"
  14 +#include "dmpvectorlayer.h"
14 #include "dmpserverproject.h" 15 #include "dmpserverproject.h"
15 #include <boost/property_tree/ptree.hpp> 16 #include <boost/property_tree/ptree.hpp>
16 #include <boost/property_tree/json_parser.hpp> 17 #include <boost/property_tree/json_parser.hpp>
@@ -21,7 +22,9 @@ namespace DmpMapping @@ -21,7 +22,9 @@ namespace DmpMapping
21 bool loadService(const DmpServerContext &context, ProjectMap& vectorMappingProjects) 22 bool loadService(const DmpServerContext &context, ProjectMap& vectorMappingProjects)
22 { 23 {
23 const char *data = (char *)(context.request()->GetData()); 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 LOGGER_ERROR("post 参数错误"); 29 LOGGER_ERROR("post 参数错误");
27 context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}"); 30 context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}");
@@ -31,12 +34,14 @@ namespace DmpMapping @@ -31,12 +34,14 @@ namespace DmpMapping
31 if(!context.serverProject()) 34 if(!context.serverProject())
32 { 35 {
33 LOGGER_ERROR("加载服务信息失败,服务名称是否错误"); 36 LOGGER_ERROR("加载服务信息失败,服务名称是否错误");
34 - context.response()->writeJson("{\"status\":\"false\",\"message\":\"加载服务信息失败,服务名称是否错误!\"}"); 37 + context.response()->writeJson("{\"status\":\"false\",\"message\":\"加载服务信息失败,服务名称错误!\"}");
35 return false; 38 return false;
36 } 39 }
37 40
38 try 41 try
39 { 42 {
  43 + std::string name = context.serverProject()->name();
  44 + std::string title = context.serverProject()->title();
40 std::stringstream stream(data); 45 std::stringstream stream(data);
41 boost::property_tree::ptree pt; 46 boost::property_tree::ptree pt;
42 boost::property_tree::read_json(stream, pt); 47 boost::property_tree::read_json(stream, pt);
@@ -54,9 +59,55 @@ namespace DmpMapping @@ -54,9 +59,55 @@ namespace DmpMapping
54 return false; 59 return false;
55 } 60 }
56 vectorMappingProjects[guid] = project; 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 return true; 111 return true;
61 } 112 }
62 else 113 else
@@ -82,7 +133,7 @@ namespace DmpMapping @@ -82,7 +133,7 @@ namespace DmpMapping
82 return false; 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 const char *data = (char *)(context.request()->GetData()); 138 const char *data = (char *)(context.request()->GetData());
88 if(data== nullptr || *data == '\0') 139 if(data== nullptr || *data == '\0')
@@ -91,11 +142,112 @@ namespace DmpMapping @@ -91,11 +142,112 @@ namespace DmpMapping
91 context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}"); 142 context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}");
92 return false; 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 return false; 251 return false;
100 } 252 }
101 253
@@ -112,15 +264,18 @@ namespace DmpMapping @@ -112,15 +264,18 @@ namespace DmpMapping
112 std::string projData; 264 std::string projData;
113 if (!DmpServerUtils::Base64Decode(project, &projData)) 265 if (!DmpServerUtils::Base64Decode(project, &projData))
114 { 266 {
  267 + context.response()->writeJson("{\"status\":\"false\",\"message\":\"base64转码错误\"}");
115 return false; 268 return false;
116 } 269 }
117 shared_ptr<DmpProject> project(new DmpProject()); 270 shared_ptr<DmpProject> project(new DmpProject());
118 if (!project->Read(projData)) 271 if (!project->Read(projData))
119 { 272 {
  273 + context.response()->writeJson("{\"status\":\"false\",\"message\":\"DMD文档错误\"}");
120 return false; 274 return false;
121 } 275 }
122 vectorMappingProjects[guid] = project; 276 vectorMappingProjects[guid] = project;
123 context.response()->writeJson("{\"status\":\"true\",\"message\":\"创建编辑服务工作空间成功!\"}"); 277 context.response()->writeJson("{\"status\":\"true\",\"message\":\"创建编辑服务工作空间成功!\"}");
  278 + return true;
124 } 279 }
125 else 280 else
126 { 281 {
@@ -128,7 +283,6 @@ namespace DmpMapping @@ -128,7 +283,6 @@ namespace DmpMapping
128 context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}"); 283 context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误!\"}");
129 return false; 284 return false;
130 } 285 }
131 -  
132 } 286 }
133 catch (boost::property_tree::ptree_bad_path &e) 287 catch (boost::property_tree::ptree_bad_path &e)
134 { 288 {
@@ -142,7 +296,8 @@ namespace DmpMapping @@ -142,7 +296,8 @@ namespace DmpMapping
142 context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误\"}"); 296 context.response()->writeJson("{\"status\":\"false\",\"message\":\"post 参数错误\"}");
143 return false; 297 return false;
144 } 298 }
145 - return false; 299 + context.response()->writeJson("{\"status\":\"false\",\"message\":\"未知错误\"}");
  300 + return false;
146 } 301 }
147 302
148 } 303 }
@@ -22,7 +22,7 @@ namespace DmpMapping @@ -22,7 +22,7 @@ namespace DmpMapping
22 22
23 bool loadService(const DmpServerContext &context,ProjectMap& vectorMappingProjects); 23 bool loadService(const DmpServerContext &context,ProjectMap& vectorMappingProjects);
24 24
25 - 25 + bool loadProjectService(const DmpServerContext &context,ProjectMap& vectorMappingProjects);
26 bool editService(const DmpServerContext &context,ProjectMap& vectorMappingProjects); 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 +}
  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,8 +17,11 @@
17 #include "dmpserverresponse.h" 17 #include "dmpserverresponse.h"
18 #include "dmplogger.h" 18 #include "dmplogger.h"
19 #include "../wms/dmpwmsgetmap.h" 19 #include "../wms/dmpwmsgetmap.h"
  20 +#include "../wms/dmpwmsparameters.h"
20 #include "dmpmapping.h" 21 #include "dmpmapping.h"
21 #include "dmpmappingparameters.h" 22 #include "dmpmappingparameters.h"
  23 +#include "dmpimageinfo.h"
  24 +
22 using namespace std; 25 using namespace std;
23 26
24 namespace DmpMapping 27 namespace DmpMapping
@@ -47,10 +50,82 @@ namespace DmpMapping @@ -47,10 +50,82 @@ namespace DmpMapping
47 { 50 {
48 loadService(context, vectorMappingProjects_); 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 else if (boost::iequals(request, "getmap")) 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,6 +12,12 @@
12 #include <string> 12 #include <string>
13 #include "dmpeditservice.h" 13 #include "dmpeditservice.h"
14 #include "dmpservice.h" 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 namespace DmpMapping 21 namespace DmpMapping
16 { 22 {
17 class DmpMappingService : public DmpService 23 class DmpMappingService : public DmpService
@@ -28,6 +34,7 @@ namespace DmpMapping @@ -28,6 +34,7 @@ namespace DmpMapping
28 34
29 //存储工程文档实例 35 //存储工程文档实例
30 ProjectMap vectorMappingProjects_; 36 ProjectMap vectorMappingProjects_;
  37 + rwmutex rwmutex_;
31 }; 38 };
32 } 39 }
33 40
@@ -87,4 +87,28 @@ namespace DmpMapping @@ -87,4 +87,28 @@ namespace DmpMapping
87 return value; 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 } // namespace DmpWms 114 } // namespace DmpWms
@@ -23,6 +23,10 @@ namespace DmpMapping @@ -23,6 +23,10 @@ namespace DmpMapping
23 std::string Request() const; //必须 值为GetMap GetCapabilities GetFeatureInfo GetFeatureInfo GetLegendGraphic 23 std::string Request() const; //必须 值为GetMap GetCapabilities GetFeatureInfo GetFeatureInfo GetLegendGraphic
24 std::string Version() const; //必须 服务版本, 值为 1.0.0, 1.1.0, 1.1.1, 1.3 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 private: 30 private:
27 bool GetStringParameter(const char* key, std::string &value) const; 31 bool GetStringParameter(const char* key, std::string &value) const;
28 bool GetIntParameter(const char* key, int& value) const; 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 +}
  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,29 +35,18 @@ namespace DmpWfs
35 this->resultType_ = resultType; 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 else 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,27 +59,27 @@ namespace DmpWfs
70 } 59 }
71 else 60 else
72 { 61 {
73 - if (this->prop.size() == 0) 62 + if (this->prop_.size() == 0)
74 { 63 {
75 sql += "*"; 64 sql += "*";
76 } 65 }
77 else 66 else
78 - sql += this->prop; 67 + sql += this->prop_;
79 } 68 }
80 sql += " from \""; 69 sql += " from \"";
81 - sql += this->table; 70 + sql += this->table_;
82 sql += "\" where "; 71 sql += "\" where ";
83 - if (this->condition.size() == 0) 72 + if (this->condition_.size() == 0)
84 { 73 {
85 sql += "1=1"; 74 sql += "1=1";
86 } 75 }
87 else 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 if (count_ <= 0) 85 if (count_ <= 0)
@@ -100,10 +89,12 @@ namespace DmpWfs @@ -100,10 +89,12 @@ namespace DmpWfs
100 if (count_ > 0 || startIndex_ > 0) 89 if (count_ > 0 || startIndex_ > 0)
101 { 90 {
102 char sz[100]; 91 char sz[100];
103 - sprintf(sz, " limit %ld offset %ld", count_, startIndex_); 92 + sprintf(sz, " limit %d offset %d", count_, startIndex_);
104 sql += sz; 93 sql += sz;
105 } 94 }
106 return sql; 95 return sql;
107 } 96 }
108 97
  98 +
  99 +
109 } 100 }
@@ -20,15 +20,17 @@ namespace DmpWfs @@ -20,15 +20,17 @@ namespace DmpWfs
20 ~DmpSqlFactory(void); 20 ~DmpSqlFactory(void);
21 21
22 void setStartIndexCount(int startIndex, int count, const std::string &resultType); 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 std::string getSql(); 27 std::string getSql();
26 28
27 private: 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 std::string resultType_; 35 std::string resultType_;
34 int startIndex_; 36 int startIndex_;
@@ -52,7 +52,7 @@ namespace DmpWfs @@ -52,7 +52,7 @@ namespace DmpWfs
52 { 52 {
53 writeGetCapabilities(context,params, project); 53 writeGetCapabilities(context,params, project);
54 } 54 }
55 - else if(boost::iequals(request, "getmap")) 55 + else if(boost::iequals(request, "getfeature"))
56 { 56 {
57 writeGetFeature(context,params, project); 57 writeGetFeature(context,params, project);
58 } 58 }
@@ -6,15 +6,1615 @@ @@ -6,15 +6,1615 @@
6 * Email: qingxiongf@chinadci.com 6 * Email: qingxiongf@chinadci.com
7 * copyright: 广州城市信息研究所有限公司 7 * copyright: 广州城市信息研究所有限公司
8 ***************************************************************************/ 8 ***************************************************************************/
  9 +
9 #include "dmpwfsfilter.h" 10 #include "dmpwfsfilter.h"
  11 +#include <boost/algorithm/string/predicate.hpp>
  12 +
10 namespace DmpWfs 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 }
@@ -9,19 +9,91 @@ @@ -9,19 +9,91 @@
9 9
10 #ifndef __dmpwfsfilter_h__ 10 #ifndef __dmpwfsfilter_h__
11 #define __dmpwfsfilter_h__ 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 namespace DmpWfs 18 namespace DmpWfs
14 { 19 {
15 - class dmpwfsfilter  
16 - { 20 + class DmpWfsFilter
  21 + {
17 public: 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 private: 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 #endif // __dmpwfsfilter_h__ 99 #endif // __dmpwfsfilter_h__
@@ -164,7 +164,7 @@ namespace DmpWfs @@ -164,7 +164,7 @@ namespace DmpWfs
164 ptFeatureType.add("Name", layer->name()); 164 ptFeatureType.add("Name", layer->name());
165 ptFeatureType.add("Title", layer->title()); 165 ptFeatureType.add("Title", layer->title());
166 ptFeatureType.add("DisplayColumn", ""); 166 ptFeatureType.add("DisplayColumn", "");
167 - ptFeatureType.add("Geometry", "点"); 167 + ptFeatureType.add("Geometry", layer->GeomTypeString());
168 ptFeatureType.add("GeometryColumn", layer->geom()); 168 ptFeatureType.add("GeometryColumn", layer->geom());
169 ptFeatureType.add("SRS", srs); 169 ptFeatureType.add("SRS", srs);
170 170
@@ -187,7 +187,12 @@ namespace DmpWfs @@ -187,7 +187,12 @@ namespace DmpWfs
187 ptFeatureType.add_child("LatLongBoundingBox", ptBoundingbox); 187 ptFeatureType.add_child("LatLongBoundingBox", ptBoundingbox);
188 188
189 boost::property_tree::ptree ptFields; 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 std::string fieldname = pPgsqlConn->getString(0); 197 std::string fieldname = pPgsqlConn->getString(0);
193 std::string typeString = pPgsqlConn->getString(1); 198 std::string typeString = pPgsqlConn->getString(1);
@@ -8,212 +8,330 @@ @@ -8,212 +8,330 @@
8 ***************************************************************************/ 8 ***************************************************************************/
9 #include "dmpwfsgetfeature.h" 9 #include "dmpwfsgetfeature.h"
10 #include "dmpsqlfactory.h" 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 namespace DmpWfs 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 &params,
  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 &params,
  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 isPicture = 10; 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 else 231 else
210 { 232 {
211 isPicture = 0; 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 }
@@ -14,22 +14,29 @@ @@ -14,22 +14,29 @@
14 #include <boost/typeof/typeof.hpp> 14 #include <boost/typeof/typeof.hpp>
15 #include <memory> 15 #include <memory>
16 #include <vector> 16 #include <vector>
  17 +#include <string>
17 #include "dmpproject.h" 18 #include "dmpproject.h"
18 #include "dmpwfsparameters.h" 19 #include "dmpwfsparameters.h"
19 #include "dmpservercontext.h" 20 #include "dmpservercontext.h"
20 #include "dmppgsqlsourcepools.h" 21 #include "dmppgsqlsourcepools.h"
21 - 22 +#include "dmpvectorlayer.h"
  23 +#include "dmpgmlfilter.h"
  24 +using namespace mapserver;
22 namespace DmpWfs 25 namespace DmpWfs
23 { 26 {
24 void writeGetFeature(const DmpServerContext &context,const DmpWfsParameters& params, 27 void writeGetFeature(const DmpServerContext &context,const DmpWfsParameters& params,
25 const DmpProject* project, 28 const DmpProject* project,
26 bool projectSettings = false); 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 #endif // __dmpwfsgetfeature_h__ 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 +}
  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,11 +170,23 @@ namespace DmpWfs
170 return value; 170 return value;
171 } 171 }
172 172
173 - std::string DmpWfsParameters::ResultType() const //要素ID 173 + DmpWfsParameters::Format DmpWfsParameters::ResultType() const
174 { 174 {
175 std::string value = ""; 175 std::string value = "";
176 GetStringParameter("RESULTTYPE",value); 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 }
@@ -51,7 +51,7 @@ namespace DmpWfs @@ -51,7 +51,7 @@ namespace DmpWfs
51 std::string PropertyName() const; //指定返回的要素属性,没有指定不返回 51 std::string PropertyName() const; //指定返回的要素属性,没有指定不返回
52 std::string SrsName() const; //空间参考坐标 52 std::string SrsName() const; //空间参考坐标
53 std::string FeatureID() const; //要素ID 53 std::string FeatureID() const; //要素ID
54 - std::string ResultType() const; 54 + DmpWfsParameters::Format ResultType() const;
55 55
56 //std::string Expiry(); 56 //std::string Expiry();
57 57
@@ -19,6 +19,8 @@ @@ -19,6 +19,8 @@
19 #include "dmplogger.h" 19 #include "dmplogger.h"
20 #include "dmpwmsgetcapabilities.h" 20 #include "dmpwmsgetcapabilities.h"
21 #include "dmpwmsgetmap.h" 21 #include "dmpwmsgetmap.h"
  22 +#include "dmpwmsserviceinfo.h"
  23 +#include "dmpwmsgetfeatureinfo.h"
22 using namespace std; 24 using namespace std;
23 25
24 namespace DmpWms 26 namespace DmpWms
@@ -50,14 +52,18 @@ namespace DmpWms @@ -50,14 +52,18 @@ namespace DmpWms
50 { 52 {
51 writeGetMap(context,params, project); 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 writeThumbnail(context,params, project); 57 writeThumbnail(context,params, project);
56 } 58 }
57 else if(boost::iequals(request, "getfeatureinfo")) 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 else if(request == "getlegendgraphic") 67 else if(request == "getlegendgraphic")
62 { 68 {
63 69
@@ -72,9 +72,14 @@ namespace DmpWms @@ -72,9 +72,14 @@ namespace DmpWms
72 mapRenderer.SetExtent(rect); 72 mapRenderer.SetExtent(rect);
73 string responseData; 73 string responseData;
74 mapRenderer.GetFeatureInfo(responseData, x, y, featureCount); 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 return ""; 83 return "";
79 } 84 }
80 catch (const std::exception &e) 85 catch (const std::exception &e)
@@ -63,7 +63,7 @@ namespace DmpWms @@ -63,7 +63,7 @@ namespace DmpWms
63 DmpWms::DmpWmsRenderer mapRenderer(height, width); 63 DmpWms::DmpWmsRenderer mapRenderer(height, width);
64 64
65 std::string layers = params.Layers(); 65 std::string layers = params.Layers();
66 - if (layers !="") 66 + if (layers =="")
67 { 67 {
68 mapRenderer.AddWmsMapLayers(project); 68 mapRenderer.AddWmsMapLayers(project);
69 } 69 }
@@ -125,6 +125,7 @@ namespace DmpWms @@ -125,6 +125,7 @@ namespace DmpWms
125 125
126 shared_ptr<Rect> rect (new Rect(maxy, maxx, miny, minx)); 126 shared_ptr<Rect> rect (new Rect(maxy, maxx, miny, minx));
127 mapRenderer.SetExtent(rect); 127 mapRenderer.SetExtent(rect);
  128 + mapRenderer.AddWmsMapLayers(project);
128 mapRenderer.GetMap(nullptr, nullptr, nullptr, true); 129 mapRenderer.GetMap(nullptr, nullptr, nullptr, true);
129 string responseData; 130 string responseData;
130 mapRenderer.ToStream(responseData); 131 mapRenderer.ToStream(responseData);
@@ -522,7 +522,7 @@ ST_GeometryFromText('POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',%s),\ @@ -522,7 +522,7 @@ ST_GeometryFromText('POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',%s),\
522 else if (typeString == "integer") 522 else if (typeString == "integer")
523 { 523 {
524 typeInt = PGFieldType::BigIntFieldType; 524 typeInt = PGFieldType::BigIntFieldType;
525 - fields_str += " \"" + (fieldname) + "\" "; 525 + fields_str += " \"" + (fieldname) + "\"::varchar ";
526 } 526 }
527 else if (typeString == "bigint") 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,7 +532,7 @@ ST_GeometryFromText('POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',%s),\
532 else if (typeString == "double precision" || typeString == "real" || typeString == "numeric") 532 else if (typeString == "double precision" || typeString == "real" || typeString == "numeric")
533 { 533 {
534 typeInt = PGFieldType::DoubleFieldType; 534 typeInt = PGFieldType::DoubleFieldType;
535 - fields_str += " \"" + (fieldname) + "\" "; 535 + fields_str += " \"" + (fieldname) + "\"::varchar ";
536 } 536 }
537 else if (typeString == "character varying" || typeString == "text") 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,7 +572,7 @@ ST_GeometryFromText('POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',%s),\
572 572
573 string shapeName = layer->geom(); 573 string shapeName = layer->geom();
574 sql += format(" ST_DWithin(\"%s\", ST_GeometryFromText('POINT(%f %f)',%s), %f) limit %d ", 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 //cout<<sql.c_str() <<endl; 576 //cout<<sql.c_str() <<endl;
577 return sql; 577 return sql;
578 } 578 }
@@ -604,7 +604,7 @@ ST_GeometryFromText('POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',%s),\ @@ -604,7 +604,7 @@ ST_GeometryFromText('POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',%s),\
604 string sql = this->GetFeatureInfoSQL(layer, x0, y0, dis, feature_count); //sql语句中使用 ::box 604 string sql = this->GetFeatureInfoSQL(layer, x0, y0, dis, feature_count); //sql语句中使用 ::box
605 if (sql == "") 605 if (sql == "")
606 continue; 606 continue;
607 - 607 + printf("%s\r\n",sql.c_str());
608 string layerName = layer->name(); 608 string layerName = layer->name();
609 try 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 &params,
  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 +}
  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,7 +36,8 @@ public:
36 ~DmpTileServer(); 36 ~DmpTileServer();
37 std::string name() const override { return std::string("TileServer");} 37 std::string name() const override { return std::string("TileServer");}
38 std::string alias() const override { return std::string("瓦片服务");} 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 std::string capability() const override; 41 std::string capability() const override;
41 void executeRequest(DmpServerRequest &request, DmpServerResponse &response) override; 42 void executeRequest(DmpServerRequest &request, DmpServerResponse &response) override;
42 bool publish(const std::string &serviceName, const std::string &title, unsigned int capability, const DmpProject &project) override; 43 bool publish(const std::string &serviceName, const std::string &title, unsigned int capability, const DmpProject &project) override;
@@ -45,6 +45,7 @@ namespace tileserver @@ -45,6 +45,7 @@ namespace tileserver
45 } 45 }
46 fread.close(); 46 fread.close();
47 } 47 }
  48 +
48 void DmpTmsTileProvider::GetTileThumbnail(DmpTileLayer* dmpTileLayer,DmpServerResponse& respons) 49 void DmpTmsTileProvider::GetTileThumbnail(DmpTileLayer* dmpTileLayer,DmpServerResponse& respons)
49 { 50 {
50 int tilematrix=0; 51 int tilematrix=0;
@@ -9,6 +9,10 @@ @@ -9,6 +9,10 @@
9 #include "dmpesritileprovider.h" 9 #include "dmpesritileprovider.h"
10 #include "dmpwmtsutils.h" 10 #include "dmpwmtsutils.h"
11 #include <string> 11 #include <string>
  12 +#include "dmptileproviderfactory.h"
  13 +#include <iostream>
  14 +#include "dmptilelayer.h"
  15 +#include <cairo/cairo.h>
12 16
13 namespace tileserver 17 namespace tileserver
14 { 18 {
@@ -60,8 +64,65 @@ namespace tileserver @@ -60,8 +64,65 @@ namespace tileserver
60 } 64 }
61 fread.close(); 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 }
@@ -20,7 +20,8 @@ namespace tileserver @@ -20,7 +20,8 @@ namespace tileserver
20 public: 20 public:
21 DmpEsriTileProvider(const std::string& rootPath); 21 DmpEsriTileProvider(const std::string& rootPath);
22 void WriteTile(const int row, const int col, const int level, const std::string& format, DmpServerResponse& response) override; 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 private: 25 private:
25 std::string IntToHex8Str(const int num); 26 std::string IntToHex8Str(const int num);
26 }; 27 };
@@ -105,6 +105,12 @@ namespace tileserver @@ -105,6 +105,12 @@ namespace tileserver
105 iLevel=id; 105 iLevel=id;
106 resolution=relus; 106 resolution=relus;
107 break; 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,7 +151,7 @@ namespace tileserver
145 } 151 }
146 if(cr==NULL) 152 if(cr==NULL)
147 { 153 {
148 - cr = cairo_create (pClsCSTo); 154 + cr = cairo_create (pClsCSTo);
149 } 155 }
150 cairo_set_source_surface(cr, pClsCSFrom, x, y); 156 cairo_set_source_surface(cr, pClsCSFrom, x, y);
151 cairo_paint(cr); 157 cairo_paint(cr);
注册登录 后发表评论