All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Utils.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2001-2009 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/ogr/Utils.cpp
22 
23  \brief Utility functions for OGR support.
24 */
25 
26 // TerraLib
27 #include "../common/Exception.h"
28 #include "../common/Globals.h"
29 #include "../common/Translator.h"
30 #include "../dataaccess/dataset/DataSetType.h"
31 #include "../dataaccess/utils/Utils.h"
32 #include "../datatype/ArrayProperty.h"
33 #include "../datatype/DateTime.h"
34 #include "../datatype/DateTimeProperty.h"
35 #include "../datatype/NumericProperty.h"
36 #include "../datatype/Property.h"
37 #include "../datatype/SimpleProperty.h"
38 #include "../datatype/StringProperty.h"
39 #include "../geometry/Envelope.h"
40 #include "../geometry/Geometry.h"
41 #include "../geometry/GeometryProperty.h"
42 #include "../geometry/WKBReader.h"
43 #include "../srs/Config.h"
44 #include "Utils.h"
45 
46 // OGR
47 #include <ogrsf_frmts.h>
48 #include <ogr_spatialref.h>
49 
50 // Boost
51 #include <boost/algorithm/string.hpp>
52 #include <boost/filesystem.hpp>
53 
55 {
56  int wkbSize = ogrGeom->WkbSize();
57 
58  unsigned char* wkbArray = new unsigned char[wkbSize];
59 
60  ogrGeom->exportToWkb(wkbNDR, wkbArray);
61 
62  te::gm::Geometry* teGeom = 0;
63 
64  try
65  {
66  teGeom = te::gm::WKBReader::read((const char*)wkbArray);
67  }
68  catch(...)
69  {
70  delete [] wkbArray;
71  throw;
72  }
73 
74  delete [] wkbArray;
75 
76  return teGeom;
77 }
78 
79 OGRGeometry* te::ogr::Convert2OGR(const te::gm::Geometry* teGeom)
80 {
81  size_t size = teGeom->getWkbSize();
82 
83  char* wkbArray = new char[size];
84 
86 
87  OGRSpatialReference* srs = Convert2OGRProjection(teGeom->getSRID());
88 
89  OGRGeometry* ogrGeom = 0;
90 
91  OGRErr result = OGRGeometryFactory::createFromWkb((unsigned char*)wkbArray, srs, &ogrGeom, static_cast<int>(size));
92 
93  delete [] wkbArray;
94 
95  if(result == OGRERR_NONE)
96  return ogrGeom;
97 
98  if(result == OGRERR_NOT_ENOUGH_DATA)
99  throw te::common::Exception(TE_TR("Error when attempting convert the geometry to OGR. Not enough data."));
100 
101  if(result == OGRERR_UNSUPPORTED_GEOMETRY_TYPE)
102  throw te::common::Exception(TE_TR("Error when attempting convert the geometry to OGR. Unsupported geometry type."));
103 
104  if(result == OGRERR_CORRUPT_DATA)
105  throw te::common::Exception(TE_TR("Error when attempting convert the geometry to OGR. Corrupt data."));
106 
107  return 0;
108 }
109 
111 {
112  return new te::gm::Envelope(env->MinX, env->MinY, env->MaxX, env->MaxY);
113 }
114 
115 OGREnvelope* te::ogr::Convert2OGR(const te::gm::Envelope* env)
116 {
117  OGREnvelope* envOGR = new OGREnvelope();
118  envOGR->MinX = env->m_llx;
119  envOGR->MinY = env->m_lly;
120  envOGR->MaxX = env->m_urx;
121  envOGR->MaxY = env->m_ury;
122  return envOGR;
123 }
124 
125 int te::ogr::Convert2TerraLibProjection(OGRSpatialReference* osrs)
126 {
127  if(osrs == 0)
128  return TE_UNKNOWN_SRS;
129 
130  if(osrs->AutoIdentifyEPSG() != OGRERR_UNSUPPORTED_SRS)
131  return atoi(osrs->GetAuthorityCode(0));
132 
133  // geographic SIRGAS 2000 Datum
134  std::string straux(osrs->GetRoot()->GetChild(0)->GetValue());
135 
136  if (!boost::find_first(straux, "SIRGAS"))
137  return TE_UNKNOWN_SRS;
138 
139  if (osrs->IsGeographic())
140  return TE_SRS_SIRGAS2000;
141 
142  // UTM using SIRGAS 2000 Datum
143  if (boost::find_first(straux, "UTM "))
144  {
145  double centralm = osrs->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,-1);
146  if (centralm == -1)
147  return TE_UNKNOWN_SRS;
148  int zone = (int)(centralm/6 + 31);
149 
150  double fsnorth = osrs->GetProjParm(SRS_PP_FALSE_NORTHING,-1);
151  if (fsnorth > 0)
152  return 31960+zone;
153  else if (fsnorth == 0)
154  return 31954+zone;
155  }
156  return TE_UNKNOWN_SRS;
157 }
158 
159 OGRSpatialReference* te::ogr::Convert2OGRProjection(int srid)
160 {
161  OGRSpatialReference* osrs = new OGRSpatialReference();
162 
163  OGRErr error = osrs->importFromEPSG(srid);
164 
165  if(error != OGRERR_NONE)
166  throw(te::common::Exception(TE_TR("Error converting spatial reference system.")));
167 
168  return osrs;
169 }
170 
171 void te::ogr::Convert2TerraLib(OGRFeatureDefn* featDef, te::da::DataSetType* dt, int srs)
172 {
173  assert(dt);
174 
175  int nFields = featDef->GetFieldCount();
176 
177  for(int i = 0; i < nFields; i++)
178  {
179  OGRFieldDefn* fieldDef = featDef->GetFieldDefn(i);
180  te::dt::Property* p = Convert2TerraLib(fieldDef);
181  dt->add(p);
182  }
183 
184  OGRwkbGeometryType ogrGeomType = featDef->GetGeomType();
185 
186  if(ogrGeomType != wkbNone) // has geometry?
187  {
188  te::gm::GeomType geomType = Convert2TerraLib(ogrGeomType);
189  te::gm::GeometryProperty* geomPropertyType = new te::gm::GeometryProperty("OGR_GEOMETRY", srs, geomType);
190  dt->add(geomPropertyType);
191  }
192 }
193 
194 te::da::DataSetType* te::ogr::Convert2TerraLib(OGRFeatureDefn* featDef, int srs)
195 {
196  te::da::DataSetType* dt = new te::da::DataSetType(featDef->GetName());
197 
198  dt->setTitle(featDef->GetName());
199 
200  te::ogr::Convert2TerraLib(featDef,dt, srs);
201 
202  return dt;
203 }
204 
206 {
207  OGRFeatureDefn* featDef = new OGRFeatureDefn(dt->getName().c_str());
208  std::vector<te::dt::Property*> props = dt->getProperties();
209 
210  for(unsigned int i = 0; i < props.size(); i++)
211  {
212  te::dt::Property* p = props[i];
213  if(p->getType() != te::dt::GEOMETRY_TYPE)
214  featDef->AddFieldDefn(Convert2OGR(p));
215  }
216 
217  if(dt->hasGeom())
218  {
220  featDef->SetGeomType(Convert2OGR(geom->getGeometryType()));
221  }
222 
223  return featDef;
224 }
225 
227 {
228  te::dt::Property* p = 0;
229  std::string name = fieldDef->GetNameRef();
230  switch(fieldDef->GetType())
231  {
232  case OFTInteger:
234  break;
235 
236  case OFTIntegerList:
238  break;
239 
240  case OFTString:
241  {
242  te::dt::StringProperty* sp = 0;
243 
244  if(fieldDef->GetWidth() == 0)
245  sp = new te::dt::StringProperty(name, te::dt::STRING);
246  else
247  sp = new te::dt::StringProperty(name, te::dt::VAR_STRING, fieldDef->GetWidth());
248 
249  sp->setCharEncoding(te::common::UTF8); // GDAL/OGR handles strings internally in UTF-8
250 
251  p = sp;
252  }
253  break;
254 
255  case OFTStringList:
257  break;
258 
259  case OFTReal:
261  break;
262 
263  case OFTRealList:
265  break;
266 
267  case OFTBinary:
269  break;
270 
271  case OFTDate:
272  p = new te::dt::DateTimeProperty(name, te::dt::DATE);
273  break;
274 
275  case OFTTime:
277  break;
278 
279  case OFTDateTime:
281  break;
282 
283  default:
284  throw(te::common::Exception(TE_TR("Unexpected data type.")));
285  }
286 
287  return p;
288 }
289 
291 {
292  OGRFieldDefn* fieldDef = new OGRFieldDefn(p->getName().c_str(), OFTInteger);
293  switch(p->getType())
294  {
295  case te::dt::INT32_TYPE:
296  return fieldDef;
297  break;
298 
299  case te::dt::ARRAY_TYPE:
300  {
301  te::dt::ArrayProperty* at = static_cast<te::dt::ArrayProperty*>(p);
302  int elementType = at->getElementType()->getType();
303 
304  if(elementType == te::dt::INT32_TYPE)
305  fieldDef->SetType(OFTIntegerList);
306  else if(elementType == te::dt::STRING_TYPE)
307  fieldDef->SetType(OFTStringList);
308  else if(elementType == te::dt::DOUBLE_TYPE)
309  fieldDef->SetType(OFTRealList);
310  else
311  throw(te::common::Exception(TE_TR("Unsupported data type by OGR.")));
312  break;
313  }
314 
315  case te::dt::STRING_TYPE:
316  fieldDef->SetType(OFTString);
317  fieldDef->SetWidth(static_cast<int>(static_cast<te::dt::StringProperty*>(p)->size()));
318  break;
319 
320  case te::dt::DOUBLE_TYPE:
321  fieldDef->SetType(OFTReal);
322  break;
323 
325  fieldDef->SetType(OFTReal);
326  fieldDef->SetPrecision(static_cast<te::dt::NumericProperty*>(p)->getScale());
327  break;
328 
330  fieldDef->SetType(OFTBinary);
331  break;
332 
334  {
335  const te::dt::DateTimeProperty* dp = static_cast<const te::dt::DateTimeProperty*>(p);
336  te::dt::DateTimeType elementType = dp->getSubType();
337  if(elementType == te::dt::DATE)
338  fieldDef->SetType(OFTDate);
339  else if(elementType == te::dt::TIME_DURATION)
340  fieldDef->SetType(OFTTime);
341  else if(elementType == te::dt::TIME_INSTANT)
342  fieldDef->SetType(OFTDateTime);
343  else
344  throw(te::common::Exception(TE_TR("Unsupported data type by OGR.")));
345  break;
346  }
347 
348  default:
349  throw(te::common::Exception(TE_TR("Unsupported data type by OGR.")));
350  }
351 
352  return fieldDef;
353 }
354 
355 te::gm::GeomType te::ogr::Convert2TerraLib(OGRwkbGeometryType ogrGeomType)
356 {
357  switch(ogrGeomType)
358  {
359  case wkbPoint:
360  return te::gm::MultiPointType;
361 
362  case wkbLineString:
364 
365  case wkbPolygon:
367 
368  case wkbMultiPoint:
369  return te::gm::MultiPointType;
370 
371  case wkbMultiLineString:
373 
374  case wkbMultiPolygon:
376 
377  case wkbGeometryCollection:
379 
380  case wkbLinearRing:
381  return te::gm::LineStringType;
382 
383  case wkbPoint25D:
384  return te::gm::PointMType;
385 
386  case wkbLineString25D:
388 
389  case wkbPolygon25D:
390  return te::gm::PolygonMType;
391 
392  case wkbMultiPoint25D:
394 
395  case wkbMultiLineString25D:
397 
398  case wkbMultiPolygon25D:
400 
401  case wkbGeometryCollection25D:
403 
404  case wkbUnknown:
405  return te::gm::GeometryType;
406 
407  default:
409  }
410 }
411 
412 OGRwkbGeometryType te::ogr::Convert2OGR(te::gm::GeomType geomType)
413 {
414  switch(geomType)
415  {
417  return wkbUnknown;
418 
419  case te::gm::PointType:
420  return wkbPoint;
421 
423  return wkbLineString;
424 
425  case te::gm::PolygonType:
426  return wkbPolygon;
427 
429  return wkbMultiPoint;
430 
432  return wkbMultiLineString;
433 
435  return wkbMultiPolygon;
436 
438  return wkbGeometryCollection;
439 
440  case te::gm::PointMType:
441  return wkbPoint25D;
442 
444  return wkbLineString25D;
445 
447  return wkbPolygon25D;
448 
450  return wkbMultiPoint25D;
451 
453  return wkbMultiLineString25D;
454 
456  return wkbMultiPolygon25D;
457 
459  return wkbGeometryCollection25D;
460 
461  default:
462  throw(te::common::Exception(TE_TR("Unsupported geometry type by OGR Driver.")));
463  }
464 }
465 
466 std::string te::ogr::GetDriverName(const std::string& path)
467 {
468  boost::filesystem::path mpath(path.c_str());
469 
470  std::string ext = mpath.extension().string();
471 
472  if(ext == ".shp" || ext == ".SHP")
473  return std::string("ESRI Shapefile");
474 
475  if(ext == ".mif" || ext == ".MIF")
476  return std::string("Mapinfo File");
477 
478  if(ext == ".kml" || ext == ".KML")
479  return std::string("KML");
480 
481  if(ext == ".geojson" || ext == ".GEOJSON")
482  return std::string("GeoJSON");
483 
484  if(ext == ".gml" || ext == ".GML")
485  return std::string("GML");
486 
487  if(ext == ".dxf" || ext == ".DXF")
488  return std::string("DXF");
489 
490  if(ext == ".dgn" || ext == ".DGN")
491  return std::string("DGN");
492 
493  return "";
494 }
495 
496 std::vector<std::string> te::ogr::GetOGRDrivers(bool filterCreate
497  )
498 {
499  std::vector<std::string> drivernames;
500 
501  int ndrivers = OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount();
502 
503  for (int i = 0; i < ndrivers; ++i)
504  {
505  OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriver(i);
506  if (filterCreate && !driver->TestCapability(ODrCCreateDataSource))
507  continue;
508  drivernames.push_back(driver->GetName());
509  }
510 
511  return drivernames;
512 }
513 
514 std::string te::ogr::GetOGRConnectionInfo(const std::map<std::string, std::string>& connInfo)
515 {
516  std::map<std::string, std::string>::const_iterator it = connInfo.find("URI");
517 
518  if(it != connInfo.end())
519  return it->second;
520 
521  it = connInfo.find("SOURCE");
522 
523  if(it != connInfo.end())
524  return it->second;
525 
526  throw te::common::Exception(TE_TR("Invalid data source connection information!."));
527 }
528 
529 std::string te::ogr::RemoveSpatialSql(const std::string& sql)
530 {
531  // Try find AND
532  std::size_t pos = sql.find("AND Intersection");
533 
534  // Try find without AND
535  if(pos == std::string::npos)
536  pos = sql.find("WHERE Intersection");
537 
538  if(pos == std::string::npos)
539  return sql;
540 
541  std::string newQuery;
542 
543  std::size_t pos2 = sql.find("))", pos);
544  newQuery = sql.substr(0, pos);
545  newQuery += sql.substr(pos2 + 2);
546 
547  return newQuery;
548 }
549 
void setTitle(const std::string &title)
It sets a human descriptive title for the DataSetType.
Definition: DataSetType.h:137
int getSRID() const
It returns the Spatial Reference System ID associated to this geometric object.
Definition: Geometry.h:189
Geometric property.
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
Definition: Enums.h:41
Utility functions for the data access module.
TEOGREXPORT OGRGeometry * Convert2OGR(const te::gm::Geometry *teGeom)
It converts the TerraLib Geometry to OGR Geometry.
Definition: Utils.cpp:79
An atomic property like an integer or double.
bool hasGeom() const
It returns true if the DataSetType has at least one geometry property; otherwise, it returns false...
Definition: DataSetType.h:655
void getWkb(char *wkb, te::common::MachineByteOrder byteOrder) const
It serializes the geometry to a WKB representation into the specified buffer.
Definition: Geometry.cpp:138
A class that models the description of a dataset.
Definition: DataSetType.h:72
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
static const MachineByteOrder sm_machineByteOrder
A flag that indicates the machine byte order (Big Endian or Little Endian).
Definition: Globals.h:54
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:345
TEOGREXPORT std::string RemoveSpatialSql(const std::string &sql)
Definition: Utils.cpp:529
std::size_t getWkbSize() const
It returns the size required by a WKB representation for this geometric object.
Definition: Geometry.cpp:133
TEOGREXPORT std::vector< std::string > GetOGRDrivers(bool filterCreate=false)
It returns the list of OGR Drivers available.
Definition: Utils.cpp:496
It models a property definition.
Definition: Property.h:59
std::string GetDriverName(const std::string &path)
It tries extract the driver name used by OGR Library based on the given path.
Definition: Utils.cpp:466
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
const std::vector< Property * > & getProperties() const
It returns the list of properties describing the CompositeProperty.
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:44
TEOGREXPORT te::gm::Geometry * Convert2TerraLib(OGRGeometry *ogrGeom)
It converts the OGR Geometry to TerraLib Geometry.
Definition: Utils.cpp:54
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
The type for string types: FIXED_STRING, VAR_STRING or STRING.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
TEOGREXPORT std::string GetOGRConnectionInfo(const std::map< std::string, std::string > &connInfo)
Definition: Utils.cpp:514
int getType() const
It returns the property data type.
Definition: Property.h:143
void add(Constraint *c)
It adds a new constraint.
Property * getElementType() const
It returns the type of array elements.
Definition: ArrayProperty.h:98
The type for variable-length multidimensional arrays.
Definition: ArrayProperty.h:45
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
The type for date and time types: date, date period, date duration, time duration, time instant, time period, time instant with time zone or time period with time zone.
void setCharEncoding(const te::common::CharEncoding &ce)
It sets the string property character encoding.
#define TE_SRS_SIRGAS2000
Definition: Config.h:71
DateTimeType
The subtype of date and time type.
Definition: Enums.h:38
DateTimeType getSubType() const
It returns the date time property sub type.
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:508
TEOGREXPORT OGRSpatialReference * Convert2OGRProjection(int srid)
It converts the TerraLib Projection to OGR Projection.
Definition: Utils.cpp:159
TEOGREXPORT int Convert2TerraLibProjection(OGRSpatialReference *osrs)
It converts the OGR Projection to TerraLib Projection.
Definition: Utils.cpp:125
static Geometry * read(const char *wkb)
It returns a valid geometry from a given WKB.
Definition: WKBReader.cpp:50
const std::string & getName() const
It returns the property name.
Definition: Property.h:126