All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator 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(TR_OGR("Error when attempting convert the geometry to OGR. Not enough data."));
100 
101  if(result == OGRERR_UNSUPPORTED_GEOMETRY_TYPE)
102  throw te::common::Exception(TR_OGR("Error when attempting convert the geometry to OGR. Unsupported geometry type."));
103 
104  if(result == OGRERR_CORRUPT_DATA)
105  throw te::common::Exception(TR_OGR("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(TR_OGR("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  if(fieldDef->GetWidth() == 0)
242  p = new te::dt::StringProperty(name, te::dt::STRING);
243  else
244  p = new te::dt::StringProperty(name, te::dt::VAR_STRING, fieldDef->GetWidth());
245  break;
246 
247  case OFTStringList:
249  break;
250 
251  case OFTReal:
253  break;
254 
255  case OFTRealList:
257  break;
258 
259  case OFTBinary:
261  break;
262 
263  case OFTDate:
264  p = new te::dt::DateTimeProperty(name, te::dt::DATE);
265  break;
266 
267  case OFTTime:
269  break;
270 
271  case OFTDateTime:
273  break;
274 
275  default:
276  throw(te::common::Exception(TR_OGR("Unexpected data type.")));
277  }
278 
279  return p;
280 }
281 
283 {
284  OGRFieldDefn* fieldDef = new OGRFieldDefn(p->getName().c_str(), OFTInteger);
285  switch(p->getType())
286  {
287  case te::dt::INT32_TYPE:
288  return fieldDef;
289  break;
290 
291  case te::dt::ARRAY_TYPE:
292  {
293  te::dt::ArrayProperty* at = static_cast<te::dt::ArrayProperty*>(p);
294  int elementType = at->getElementType()->getType();
295 
296  if(elementType == te::dt::INT32_TYPE)
297  fieldDef->SetType(OFTIntegerList);
298  else if(elementType == te::dt::STRING_TYPE)
299  fieldDef->SetType(OFTStringList);
300  else if(elementType == te::dt::DOUBLE_TYPE)
301  fieldDef->SetType(OFTRealList);
302  else
303  throw(te::common::Exception(TR_OGR("Unsupported data type by OGR.")));
304  break;
305  }
306 
307  case te::dt::STRING_TYPE:
308  fieldDef->SetType(OFTString);
309  fieldDef->SetWidth(static_cast<int>(static_cast<te::dt::StringProperty*>(p)->size()));
310  break;
311 
312  case te::dt::DOUBLE_TYPE:
313  fieldDef->SetType(OFTReal);
314  break;
315 
317  fieldDef->SetType(OFTReal);
318  fieldDef->SetPrecision(static_cast<te::dt::NumericProperty*>(p)->getScale());
319  break;
320 
322  fieldDef->SetType(OFTBinary);
323  break;
324 
326  {
327  const te::dt::DateTimeProperty* dp = static_cast<const te::dt::DateTimeProperty*>(p);
328  te::dt::DateTimeType elementType = dp->getSubType();
329  if(elementType == te::dt::DATE)
330  fieldDef->SetType(OFTDate);
331  else if(elementType == te::dt::TIME_DURATION)
332  fieldDef->SetType(OFTTime);
333  else if(elementType == te::dt::TIME_INSTANT)
334  fieldDef->SetType(OFTDateTime);
335  else
336  throw(te::common::Exception(TR_OGR("Unsupported data type by OGR.")));
337  break;
338  }
339 
340  default:
341  throw(te::common::Exception(TR_OGR("Unsupported data type by OGR.")));
342  }
343 
344  return fieldDef;
345 }
346 
347 te::gm::GeomType te::ogr::Convert2TerraLib(OGRwkbGeometryType ogrGeomType)
348 {
349  switch(ogrGeomType)
350  {
351  case wkbPoint:
352  return te::gm::MultiPointType;
353 
354  case wkbLineString:
356 
357  case wkbPolygon:
359 
360  case wkbMultiPoint:
361  return te::gm::MultiPointType;
362 
363  case wkbMultiLineString:
365 
366  case wkbMultiPolygon:
368 
369  case wkbGeometryCollection:
371 
372  case wkbLinearRing:
373  return te::gm::LineStringType;
374 
375  case wkbPoint25D:
376  return te::gm::PointMType;
377 
378  case wkbLineString25D:
380 
381  case wkbPolygon25D:
382  return te::gm::PolygonMType;
383 
384  case wkbMultiPoint25D:
386 
387  case wkbMultiLineString25D:
389 
390  case wkbMultiPolygon25D:
392 
393  case wkbGeometryCollection25D:
395 
396  case wkbUnknown:
397  return te::gm::GeometryType;
398 
399  default:
401  }
402 }
403 
404 OGRwkbGeometryType te::ogr::Convert2OGR(te::gm::GeomType geomType)
405 {
406  switch(geomType)
407  {
409  return wkbUnknown;
410 
411  case te::gm::PointType:
412  return wkbPoint;
413 
415  return wkbLineString;
416 
417  case te::gm::PolygonType:
418  return wkbPolygon;
419 
421  return wkbMultiPoint;
422 
424  return wkbMultiLineString;
425 
427  return wkbMultiPolygon;
428 
430  return wkbGeometryCollection;
431 
432  case te::gm::PointMType:
433  return wkbPoint25D;
434 
436  return wkbLineString25D;
437 
439  return wkbPolygon25D;
440 
442  return wkbMultiPoint25D;
443 
445  return wkbMultiLineString25D;
446 
448  return wkbMultiPolygon25D;
449 
451  return wkbGeometryCollection25D;
452 
453  default:
454  throw(te::common::Exception(TR_OGR("Unsupported geometry type by OGR Driver.")));
455  }
456 }
457 
458 std::string te::ogr::GetDriverName(const std::string& path)
459 {
460  boost::filesystem::path mpath(path.c_str());
461 
462  std::string ext = mpath.extension().string();
463 
464  if(ext == ".shp" || ext == ".SHP")
465  return std::string("ESRI Shapefile");
466 
467  if(ext == ".mif" || ext == ".MIF")
468  return std::string("Mapinfo File");
469 
470  if(ext == ".kml" || ext == ".KML")
471  return std::string("KML");
472 
473  if(ext == ".geojson" || ext == ".GEOJSON")
474  return std::string("GeoJSON");
475 
476  if(ext == ".gml" || ext == ".GML")
477  return std::string("GML");
478 
479  if(ext == ".dxf" || ext == ".DXF")
480  return std::string("DXF");
481 
482  if(ext == ".dgn" || ext == ".DGN")
483  return std::string("DGN");
484 
485  return "";
486 }
487 
488 std::vector<std::string> te::ogr::GetOGRDrivers(bool filterCreate
489  )
490 {
491  std::vector<std::string> drivernames;
492 
493  int ndrivers = OGRSFDriverRegistrar::GetRegistrar()->GetDriverCount();
494 
495  for (int i = 0; i < ndrivers; ++i)
496  {
497  OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriver(i);
498  if (filterCreate && !driver->TestCapability(ODrCCreateDataSource))
499  continue;
500  drivernames.push_back(driver->GetName());
501  }
502 
503  return drivernames;
504 }
505 
506 std::string te::ogr::GetOGRConnectionInfo(const std::map<std::string, std::string>& connInfo)
507 {
508  std::map<std::string, std::string>::const_iterator it = connInfo.find("URI");
509 
510  if(it != connInfo.end())
511  return it->second;
512 
513  it = connInfo.find("SOURCE");
514 
515  if(it != connInfo.end())
516  return it->second;
517 
518  throw te::common::Exception(TR_OGR("Invalid data source connection information!."));
519 }
TEOGREXPORT int Convert2TerraLibProjection(OGRSpatialReference *osrs)
It converts the OGR Projection to TerraLib Projection.
Definition: Utils.cpp:125
The type for variable-length multidimensional arrays.
Definition: ArrayProperty.h:45
int getSRID() const
It returns the Spatial Reference System ID associated to this geometric object.
Definition: Geometry.h:189
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
An atomic property like an integer or double.
std::size_t getWkbSize() const
It returns the size required by a WKB representation for this geometric object.
Definition: Geometry.cpp:133
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
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:504
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:458
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.
The type for string types: FIXED_STRING, VAR_STRING or STRING.
DateTimeType getSubType() const
It returns the date time property sub type.
const std::string & getName() const
It returns the property name.
Definition: Property.h:126
void add(Constraint *c)
It adds a new constraint.
static Geometry * read(const char *wkb)
It returns a valid geometry from a given WKB.
Definition: WKBReader.cpp:50
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:72
Property * getElementType() const
It returns the type of array elements.
Definition: ArrayProperty.h:98
TEOGREXPORT std::vector< std::string > GetOGRDrivers(bool filterCreate=false)
It returns the list of OGR Drivers available.
Definition: Utils.cpp:488
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
static const MachineByteOrder sm_machineByteOrder
A flag that indicates the machine byte order (Big Endian or Little Endian).
Definition: Globals.h:55
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
bool hasGeom() const
It returns true if the DataSetType has at least one geometry property; otherwise, it returns false...
Definition: DataSetType.h:655
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
const std::vector< Property * > & getProperties() const
It returns the list of properties describing the CompositeProperty.
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
Definition: Enums.h:41
#define TR_OGR(message)
It marks a string in order to get translated. This is a special mark used in the DataAccess module of...
Definition: Config.h:62
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
#define TE_SRS_SIRGAS2000
Definition: Config.h:99
DateTimeType
The subtype of date and time type.
Definition: Enums.h:38
A class that models the description of a dataset.
Definition: DataSetType.h:72
TEOGREXPORT te::gm::Geometry * Convert2TerraLib(OGRGeometry *ogrGeom)
It converts the OGR Geometry to TerraLib Geometry.
Definition: Utils.cpp:54
It models a property definition.
Definition: Property.h:59
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
TEOGREXPORT std::string GetOGRConnectionInfo(const std::map< std::string, std::string > &connInfo)
Definition: Utils.cpp:506
int getType() const
It returns the property data type.
Definition: Property.h:143
void setTitle(const std::string &title)
It sets a human descriptive title for the DataSetType.
Definition: DataSetType.h:137
TEOGREXPORT OGRSpatialReference * Convert2OGRProjection(int srid)
It converts the TerraLib Projection to OGR Projection.
Definition: Utils.cpp:159
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
Geometric property.