raster/serialization/xml/Serializer.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/raster/serialization/xml/Serializer.cpp
22 
23  \brief Support for serialization of Raster information.
24 */
25 
26 // TerraLib
27 #include "../../../geometry/Envelope.h"
28 #include "../../../geometry/serialization/xml/Serializer.h"
29 #include "../../../xml/AbstractWriter.h"
30 #include "../../../xml/AbstractWriterFactory.h"
31 #include "../../../xml/Reader.h"
32 #include "../../Band.h"
33 #include "../../BandProperty.h"
34 #include "../../Grid.h"
35 #include "../../Raster.h"
36 #include "Serializer.h"
37 
38 // STL
39 #include <cassert>
40 #include <fstream>
41 #include <memory>
42 
43 // Boost
44 #include <boost/lexical_cast.hpp>
45 
46 void te::serialize::xml::ReadRasterInfo(std::map<std::string, std::string>& rinfo, te::xml::Reader& reader)
47 {
48  assert(reader.getNodeType() == te::xml::START_ELEMENT);
49  assert(reader.getElementLocalName() == "Info");
50 
51  reader.next();
52 
53  while(reader.getNodeType() == te::xml::START_ELEMENT &&
54  reader.getElementLocalName() == "kvp")
55  {
56  std::string k = reader.getAttr("k");
57  std::string v = reader.getAttr("v");
58 
59  rinfo[k] = v;
60 
61  reader.next();
62 
63  assert(reader.getNodeType() == te::xml::END_ELEMENT);
64  reader.next();
65  }
66 }
67 
68 void te::serialize::xml::SaveRasterInfo(std::map<std::string, std::string>& rinfo, te::xml::AbstractWriter& writer)
69 {
70  if(rinfo.empty())
71  return;
72 
73  writer.writeStartElement("Info");
74 
75  std::map<std::string, std::string>::const_iterator it = rinfo.begin();
76  std::map<std::string, std::string>::const_iterator itend = rinfo.end();
77 
78  while(it != itend)
79  {
80  writer.writeStartElement("kvp");
81  writer.writeAttribute("k", it->first);
82  writer.writeAttribute("v", it->second);
83  writer.writeEndElement("kvp");
84 
85  ++it;
86  }
87 
88  writer.writeEndElement("Info");
89 }
90 
91 void te::serialize::xml::Save(const te::rst::Raster* raster, const std::string& fileName)
92 {
93  std::fstream ostr(fileName.c_str(), std::ios_base::out);
94 
95  Save(raster, ostr);
96 
97  ostr.close();
98 }
99 
101  std::ostream& /*ostr*/)
102 {
103  std::unique_ptr<te::xml::AbstractWriter> w(te::xml::AbstractWriterFactory::make());
104 
105  Save(raster, *w.get());
106 }
107 
109 {
110  writer.writeStartDocument("UTF-8", "no");
111 
112  writer.writeStartElement("Raster");
113 
114  writer.writeAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
115  writer.writeAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema-instance");
116  writer.writeAttribute("xmlns", "http://www.terralib.org/schemas/raster");
117  writer.writeAttribute("xsd:schemaLocation", "http://www.terralib.org/schemas/raster C:/Users/gribeiro/Documents/terralib5/trunk/myschemas/terralib/raster/raster.xsd");
118  writer.writeAttribute("version", "5.0.0");
119  writer.writeAttribute("release", "2011-01-01");
120 
121  writer.writeElement("Name", raster->getName());
122 
123  Save(raster->getGrid(), writer);
124 
125  writer.writeStartElement("Bands");
126 
127  for(std::size_t i = 0; i < raster->getNumberOfBands(); ++i)
128  Save(raster->getBand(i)->getProperty(), writer);
129 
130  writer.writeEndElement("Bands");
131 
132  std::map<std::string, std::string> rinfo = raster->getInfo();
133 
134  SaveRasterInfo(rinfo, writer);
135 
136  writer.writeEndElement("Raster");
137 }
138 
140 {
141  assert(reader.getNodeType() == te::xml::START_ELEMENT);
142  assert(reader.getElementLocalName() == "GeoTransform");
143 
144  double* geo = new double[6];
145 
146  geo[0] = reader.getAttrAsDouble(0);
147  geo[1] = reader.getAttrAsDouble(1);
148  geo[2] = reader.getAttrAsDouble(2);
149  geo[3] = reader.getAttrAsDouble(3);
150  geo[4] = reader.getAttrAsDouble(4);
151  geo[5] = reader.getAttrAsDouble(5);
152 
153  reader.next();
154 
155  assert(reader.getNodeType() == te::xml::END_ELEMENT);
156  reader.next();
157 
158  return geo;
159 }
160 
162 {
163  assert(reader.getNodeType() == te::xml::START_ELEMENT);
164  assert(reader.getElementLocalName() == "Grid");
165 
166  reader.next();
167 
168  /* Extent Element */
169  assert(reader.getNodeType() == te::xml::START_ELEMENT);
170  assert(reader.getElementLocalName() == "Extent");
171  std::unique_ptr<te::gm::Envelope> e(ReadExtent(reader));
172 
173  /* NumCols Element */
174  assert(reader.getNodeType() == te::xml::START_ELEMENT);
175  assert(reader.getElementLocalName() == "NumCols");
176  reader.next();
177  assert(reader.getNodeType() == te::xml::VALUE);
178  unsigned int ncols = reader.getElementValueAsInt32();
179  reader.next();
180  assert(reader.getNodeType() == te::xml::END_ELEMENT);
181 
182  /* NumRows Element */
183  reader.next();
184  assert(reader.getNodeType() == te::xml::START_ELEMENT);
185  assert(reader.getElementLocalName() == "NumRows");
186  reader.next();
187  assert(reader.getNodeType() == te::xml::VALUE);
188  unsigned int nrows = reader.getElementValueAsInt32();
189  reader.next();
190  assert(reader.getNodeType() == te::xml::END_ELEMENT);
191 
192  /* SRID Element */
193  reader.next();
194  assert(reader.getNodeType() == te::xml::START_ELEMENT);
195  assert(reader.getElementLocalName() == "SRID");
196  reader.next();
197  assert(reader.getNodeType() == te::xml::VALUE);
198  int srid = reader.getElementValueAsInt32();
199  reader.next();
200  assert(reader.getNodeType() == te::xml::END_ELEMENT);
201 
202  /* GeoTransform Element */
203  reader.next();
204  double* geo = ReadGeoTransform(reader);
205 
206  te::rst::Grid* grid = new te::rst::Grid(ncols, nrows);
207 
208  grid->setGeoreference(geo, srid);
209 
210  delete [] geo;
211 
212  assert(reader.getNodeType() == te::xml::END_ELEMENT);
213  reader.next();
214 
215  return grid;
216 }
217 
219 {
220  writer.writeStartElement("Grid");
221 
222  const te::gm::Envelope* e = grid->getExtent();
223 
224  SaveExtent(*e, writer);
225 
226  writer.writeElement("NumCols", grid->getNumberOfColumns());
227  writer.writeElement("NumRows", grid->getNumberOfRows());
228  writer.writeElement("SRID", grid->getSRID());
229 
230  writer.writeStartElement("GeoTransform");
231  writer.writeAttribute("c1", grid->getGeoreference()[0]);
232  writer.writeAttribute("c2", grid->getGeoreference()[1]);
233  writer.writeAttribute("c3", grid->getGeoreference()[2]);
234  writer.writeAttribute("c4", grid->getGeoreference()[3]);
235  writer.writeAttribute("c5", grid->getGeoreference()[4]);
236  writer.writeAttribute("c6", grid->getGeoreference()[5]);
237  writer.writeEndElement("GeoTransform");
238 
239  writer.writeEndElement("Grid");
240 }
241 
242 std::vector<te::rst::BandProperty*> te::serialize::xml::ReadBandPropertyVector(te::xml::Reader& reader)
243 {
244  assert(reader.getNodeType() == te::xml::START_ELEMENT);
245  assert(reader.getElementLocalName() == "Bands");
246 
247  std::vector<te::rst::BandProperty*> bands;
248 
249  reader.next();
250  assert(reader.getNodeType() == te::xml::START_ELEMENT);
251  assert(reader.getElementLocalName() == "Band");
252 
253  while(reader.getNodeType() == te::xml::START_ELEMENT &&
254  reader.getElementLocalName() == "Band")
255  {
257  bands.push_back(bp);
258  }
259 
260  assert(reader.getNodeType() == te::xml::END_ELEMENT);
261  reader.next();
262 
263  return bands;
264 }
265 
267 {
268  assert(reader.getNodeType() == te::xml::START_ELEMENT);
269  assert(reader.getElementLocalName() == "Band");
270 
271  int num = reader.getAttrAsInt32(0);
272  int datatype = reader.getAttrAsInt32(1);
273  double noData = reader.getAttrAsDouble(2);
274 
275  reader.next();
276  assert(reader.getNodeType() == te::xml::START_ELEMENT);
277  assert(reader.getElementLocalName() == "BlockInfo");
278 
279  int blkw = reader.getAttrAsInt32(0);
280  int blkh = reader.getAttrAsInt32(1);
281  int nblocksx = reader.getAttrAsInt32(2);
282  int nblocksy = reader.getAttrAsInt32(3);
283 
284  reader.next();
285  assert(reader.getNodeType() == te::xml::END_ELEMENT); // End of BlockInfo Element
286 
287  reader.next();
288  assert(reader.getNodeType() == te::xml::END_ELEMENT); // End of Band Element
289 
290  reader.next();
291 
292  te::rst::BandProperty* bp = new te::rst::BandProperty(num, datatype);
293 
294  bp->m_blkw = blkw;
295  bp->m_blkh = blkh;
296  bp->m_nblocksx = nblocksx;
297  bp->m_nblocksy = nblocksy;
298  bp->m_noDataValue = noData;
299 
300  return bp;
301 }
302 
304 {
305  writer.writeStartElement("Band");
306 
307  writer.writeAttribute("num", boost::lexical_cast<std::string>(bp->m_idx));
308  writer.writeAttribute("datatype", bp->m_type);
309  writer.writeAttribute("no_data", bp->m_noDataValue);
310 
311  writer.writeStartElement("BlockInfo");
312  writer.writeAttribute("blkw", bp->m_blkw);
313  writer.writeAttribute("blkh", bp->m_blkh);
314  writer.writeAttribute("nblocksx", bp->m_nblocksx);
315  writer.writeAttribute("nblocksy", bp->m_nblocksy);
316  writer.writeEndElement("BlockInfo");
317 
318  //writer.writeElement(ostr, "Description", bp->m_description);
319 
320  writer.writeEndElement("Band");
321 }
322 
323 
324 
unsigned int getNumberOfRows() const
Returns the grid number of rows.
TEXSDEXPORT void Save(All *all, te::xml::AbstractWriter &writer)
std::size_t m_idx
The band index.
Definition: BandProperty.h:132
virtual boost::int32_t getElementValueAsInt32() const
It returns the element data value in the case of VALUE node.
Definition: xml/Reader.cpp:32
This class models a XML reader object.
Definition: xml/Reader.h:55
TERASTEREXPORT te::rst::Grid * ReadGrid(te::xml::Reader &reader)
A raster band description.
Definition: BandProperty.h:61
virtual void writeStartElement(const std::string &qName)=0
int getSRID() const
Returns the grid spatial reference system identifier.
int m_nblocksx
The number of blocks in x.
Definition: BandProperty.h:145
int m_nblocksy
The number of blocks in y.
Definition: BandProperty.h:146
static te::xml::AbstractWriter * make()
It creates a new XML writer using the dafault implementation.
virtual std::string getElementLocalName() const =0
It returns the local part of the element name in the case of an element node.
void setGeoreference(const te::gm::Coord2D &ulLocation, int srid, double resX, double resY)
Sets the information needed to georeference the grid.
int m_type
The data type of the elements in the band ( See te::dt namespace basic data types for reference )...
Definition: BandProperty.h:133
TERASTEREXPORT void ReadRasterInfo(std::map< std::string, std::string > &rinfo, te::xml::Reader &reader)
double m_noDataValue
Value to indicate elements where there is no data, default is std::numeric_limits<double>::max().
Definition: BandProperty.h:136
This class models a XML writer object.
TERASTEREXPORT double * ReadGeoTransform(te::xml::Reader &reader)
virtual boost::int32_t getAttrAsInt32(const std::string &name) const
It returns the attribute value in the case of an element node with valid attributes.
Definition: xml/Reader.cpp:49
TERASTEREXPORT te::rst::BandProperty * ReadBandProperty(te::xml::Reader &reader)
virtual std::map< std::string, std::string > getInfo() const =0
It returns additional information about the raster.
virtual void writeElement(const std::string &qName, const std::string &value)=0
virtual std::string getAttr(const std::string &name) const =0
It returns the attribute value in the case of an element node with valid attributes.
TEGEOMEXPORT std::unique_ptr< te::gm::Envelope > ReadExtent(te::xml::Reader &reader)
An Envelope defines a 2D rectangular region.
An abstract class for raster data strucutures.
Auxiliary classes and functions to read geometry information from a XML document. ...
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
const double * getGeoreference() const
Returns a list of 6 coefficients describing an affine transformation to georeference a grid...
BandProperty * getProperty()
Returns the band property.
int m_blkw
Block width (pixels).
Definition: BandProperty.h:143
TEDATAACCESSEXPORT void Save(const std::string &fileName)
unsigned int getNumberOfColumns() const
Returns the grid number of columns.
list bands
Definition: compose.py:2
TEGEOMEXPORT void SaveExtent(const te::gm::Envelope &e, te::xml::AbstractWriter &writer)
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
Grid * getGrid()
It returns the raster grid.
const std::string & getName() const
Returns the raster name.
virtual void writeAttribute(const std::string &attName, const std::string &value)=0
te::gm::Envelope * getExtent()
Returns the geographic extension of the grid.
TERASTEREXPORT std::vector< te::rst::BandProperty * > ReadBandPropertyVector(te::xml::Reader &reader)
virtual double getAttrAsDouble(const std::string &name) const
It returns the attribute value in the case of an element node with valid attributes.
Definition: xml/Reader.cpp:69
virtual void writeEndElement(const std::string &qName)=0
virtual void writeStartDocument(const std::string &encoding, const std::string &standalone)=0
virtual NodeType getNodeType() const =0
It return the type of node read.
int m_blkh
Block height (pixels).
Definition: BandProperty.h:144
TERASTEREXPORT void SaveRasterInfo(std::map< std::string, std::string > &rinfo, te::xml::AbstractWriter &writer)
A rectified grid is the spatial support for raster data.
Definition: raster/Grid.h:68
virtual bool next()=0
It gets the next event to be read.