提交 380261be7c46485db374f03801854c0d7bcaba17

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