From 80df8365a7603bf05bb11973e6e712d17b8e824c Mon Sep 17 00:00:00 2001
From: Lars Bilke <lars.bilke@ufz.de>
Date: Fri, 14 Sep 2012 12:06:28 +0200
Subject: [PATCH] Re-added SHPInterface.

---
 FileIO/CMakeLists.txt   |  16 +++-
 FileIO/SHPInterface.cpp | 174 ++++++++++++++++++++++++++++++++++++++++
 FileIO/SHPInterface.h   |  58 ++++++++++++++
 3 files changed, 246 insertions(+), 2 deletions(-)
 create mode 100644 FileIO/SHPInterface.cpp
 create mode 100644 FileIO/SHPInterface.h

diff --git a/FileIO/CMakeLists.txt b/FileIO/CMakeLists.txt
index 60753c25b2f..26cbde362f7 100644
--- a/FileIO/CMakeLists.txt
+++ b/FileIO/CMakeLists.txt
@@ -1,14 +1,26 @@
 # Source files
-GET_SOURCE_FILES(SOURCES_FILEIO)
+# GET_SOURCE_FILES(SOURCES_FILEIO)
+SET( SOURCES
+	Gmsh2GeoIO.cpp
+	GMSInterface.cpp
+	PetrelInterface.cpp
+	readNonBlankLineFromInputStream.cpp
+	Writer.cpp
+)
 GET_SOURCE_FILES(SOURCES_LEGACY Legacy)
 GET_SOURCE_FILES(SOURCES_MESHIO MeshIO)
-SET ( SOURCES ${SOURCES_FILEIO} ${SOURCES_LEGACY} ${SOURCES_MESHIO})
+SET ( SOURCES ${SOURCES} ${SOURCES_LEGACY} ${SOURCES_MESHIO})
 
 IF (QT4_FOUND)
 	GET_SOURCE_FILES(SOURCES_XML XmlIO)
 	SET ( SOURCES ${SOURCES} ${SOURCES_XML})
 ENDIF (QT4_FOUND)
 
+IF (Shapelib_FOUND)
+	SET (SOURCES ${SOURCES} SHPInterface.h SHPInterface.cpp )
+	INCLUDE_DIRECTORIES (${Shapelib_INCLUDE_DIR})
+ENDIF (Shapelib_FOUND)
+
 # Create the library
 ADD_LIBRARY(FileIO STATIC ${SOURCES})
 
diff --git a/FileIO/SHPInterface.cpp b/FileIO/SHPInterface.cpp
new file mode 100644
index 00000000000..c8a9e16f155
--- /dev/null
+++ b/FileIO/SHPInterface.cpp
@@ -0,0 +1,174 @@
+/**
+ * \file SHPInterface.cpp
+ * 25/01/2010 KR Initial implementation
+ */
+
+#include "SHPInterface.h"
+#include "StringTools.h"
+
+// MathLib
+#include "AnalyticalGeometry.h"
+
+bool SHPInterface::readSHPInfo(const std::string &filename, int &shapeType, int &numberOfEntities)
+{
+	SHPHandle hSHP = SHPOpen(filename.c_str(),"rb");
+	if(!hSHP)
+		return false;
+
+	double padfMinBound[4], padfMaxBound[4];
+
+	// The SHPGetInfo() function retrieves various information about shapefile as a whole.
+	// The bounds are read from the file header, and may be inaccurate if the file was improperly generated.
+	SHPGetInfo( hSHP, &numberOfEntities, &shapeType, padfMinBound, padfMaxBound );
+
+	SHPClose(hSHP);
+	return true;
+}
+
+void SHPInterface::readSHPFile(const std::string &filename, OGSType choice, std::string listName)
+{
+	int shapeType, numberOfElements;
+	double padfMinBound[4], padfMaxBound[4];
+
+	SHPHandle hSHP = SHPOpen(filename.c_str(),"rb");
+	SHPGetInfo( hSHP, &numberOfElements, &shapeType, padfMinBound, padfMaxBound );
+
+	if ( ((shapeType - 1) % 10 == 0)  &&  (choice == SHPInterface::POINT) )
+		readPoints(hSHP, numberOfElements, listName);
+	if ( ((shapeType - 1) % 10 == 0)  &&  (choice == SHPInterface::STATION) )
+		readStations(hSHP, numberOfElements, listName);
+	if ( ((shapeType - 3) % 10 == 0 ||
+	      (shapeType - 5) % 10 == 0)  &&  (choice == SHPInterface::POLYLINE) )
+		readPolylines(hSHP, numberOfElements, listName);
+	if ( ((shapeType - 3) % 10 == 0 ||
+	      (shapeType - 5) % 10 == 0)  &&  (choice == SHPInterface::POLYGON) )
+		readPolygons(hSHP, numberOfElements, listName);
+}
+
+void SHPInterface::readPoints(const SHPHandle &hSHP, int numberOfElements, std::string listName)
+{
+	if (numberOfElements > 0)
+	{
+		std::vector<GeoLib::Point*>* points = new std::vector<GeoLib::Point*>();
+		SHPObject* hSHPObject;
+
+		for (int i = 0; i < numberOfElements; i++)
+		{
+			hSHPObject = SHPReadObject(hSHP,i);
+
+			GeoLib::Point* pnt =
+			        new GeoLib::Point( *(hSHPObject->padfX), *(hSHPObject->padfY),
+			                           *(hSHPObject->padfZ) );
+			points->push_back(pnt);
+		}
+
+		_geoObjects->addPointVec(points, listName);
+		SHPDestroyObject(hSHPObject); // de-allocate SHPObject
+	}
+}
+
+void SHPInterface::readStations(const SHPHandle &hSHP, int numberOfElements, std::string listName)
+{
+	if (numberOfElements > 0)
+	{
+		std::vector<GeoLib::Point*>* stations (new std::vector<GeoLib::Point*>);
+		stations->reserve (numberOfElements);
+		SHPObject* hSHPObject;
+
+		for (int i = 0; i < numberOfElements; i++)
+		{
+			hSHPObject = SHPReadObject(hSHP,i);
+			GeoLib::Station* stn =
+			        GeoLib::Station::createStation( number2str(i), *(hSHPObject->padfX),
+			                                        *(hSHPObject->padfY),
+			                                        *(hSHPObject->padfZ) );
+			stations->push_back(stn);
+		}
+
+		_geoObjects->addStationVec(stations, listName);
+		SHPDestroyObject(hSHPObject); // de-allocate SHPObject
+	}
+}
+
+void SHPInterface::readPolylines(const SHPHandle &hSHP, int numberOfElements, std::string listName)
+{
+	size_t noOfPoints = 0, noOfParts = 0;
+	std::vector<GeoLib::Point*>* points = new std::vector<GeoLib::Point*>();
+	std::vector<GeoLib::Polyline*>* lines = new std::vector<GeoLib::Polyline*>();
+	SHPObject* hSHPObject;
+
+	// for each polyline)
+	for (int i = 0; i < numberOfElements; i++)
+	{
+		hSHPObject = SHPReadObject(hSHP,i);
+		noOfPoints = hSHPObject->nVertices;
+		noOfParts  = hSHPObject->nParts;
+
+		for (size_t p = 0; p < noOfParts; p++)
+		{
+			int firstPnt = *(hSHPObject->panPartStart + p);
+			int lastPnt  =
+			        (p < (noOfParts - 1)) ? *(hSHPObject->panPartStart + p + 1) : noOfPoints;
+
+			GeoLib::Polyline* line = new GeoLib::Polyline(*points);
+
+			// for each point in that polyline
+			for (int j = firstPnt; j < lastPnt; j++)
+			{
+				GeoLib::Point* pnt =
+				        new GeoLib::Point( *(hSHPObject->padfX + j),
+				                           *(hSHPObject->padfY + j),
+				                           *(hSHPObject->padfZ + j) );
+				points->push_back(pnt);
+				line->addPoint(points->size() - 1);
+			}
+
+			// add polyline to polyline vector
+			lines->push_back(line);
+		}
+	}
+
+	if (numberOfElements > 0)
+	{
+		// add points vector to GEOObjects (and check for duplicate points)
+		_geoObjects->addPointVec(points, listName);
+
+		// adjust indeces of polylines, remove zero length elements and add vector to GEOObjects
+		this->adjustPolylines(lines, _geoObjects->getPointVecObj(listName)->getIDMap());
+		_geoObjects->addPolylineVec(lines, listName);
+
+		SHPDestroyObject(hSHPObject); // de-allocate SHPObject
+	}
+}
+
+void SHPInterface::readPolygons(const SHPHandle &hSHP, int numberOfElements, std::string listName)
+{
+	this->readPolylines(hSHP, numberOfElements, listName);
+
+	const std::vector<GeoLib::Polyline*>* polylines (_geoObjects->getPolylineVec(listName));
+	std::vector<GeoLib::Surface*>* sfc_vec(new std::vector<GeoLib::Surface*>);
+
+	for (std::vector<GeoLib::Polyline*>::const_iterator poly_it (polylines->begin());
+	     poly_it != polylines->end(); poly_it++)
+	{
+		std::cout << "triangulation of Polygon with " << (*poly_it)->getNumberOfPoints() <<
+		" points ... " << std::flush;
+		sfc_vec->push_back(GeoLib::Surface::createSurface(*(*poly_it)));
+	}
+
+	if (!sfc_vec->empty())
+		_geoObjects->addSurfaceVec(sfc_vec, listName);
+}
+
+void SHPInterface::adjustPolylines (std::vector<GeoLib::Polyline*>* lines,
+                                    std::vector<size_t> id_map)
+
+{
+	for (size_t i = 0; i < lines->size(); i++)
+	{
+		GeoLib::Polyline* line( (*lines)[i] );
+		size_t nPoints( line->getNumberOfPoints() );
+		for (size_t j = 0; j < nPoints; j++)
+			line->setPointID(j, id_map[line->getPointID(j)]);
+	}
+}
diff --git a/FileIO/SHPInterface.h b/FileIO/SHPInterface.h
new file mode 100644
index 00000000000..171dd252eab
--- /dev/null
+++ b/FileIO/SHPInterface.h
@@ -0,0 +1,58 @@
+/**
+ * \file SHPInterface.cpp
+ * 25/01/2010 KR Initial implementation
+ */
+#ifndef SHPINTERFACE_H
+#define SHPINTERFACE_H
+
+#include <string>
+
+//ShapeLib includes
+#include "shapefil.h"
+
+#include "GEOObjects.h"
+
+/**
+ * \brief Manages the import of ESRI shape files into GeoLib.
+ */
+class SHPInterface
+{
+public:
+	/// Connection between ESRI type system for shape files and OGS GeoLib.
+	enum OGSType
+	{
+		UNDEFINED   = 0,
+		POINT       = 1,
+		STATION     = 2,
+		POLYLINE    = 3,
+		POLYGON     = 4
+	};
+
+	/// Constructor
+	SHPInterface(GeoLib::GEOObjects* geoObjects) : _geoObjects(geoObjects) {}
+
+	/// Reads the header of the shape file.
+	bool readSHPInfo(const std::string &filename, int &shapeType, int &numberOfEntities);
+
+	/// Reads data from the shape file.
+	void readSHPFile(const std::string &filename, OGSType choice, std::string listName);
+
+private:
+	/// Reads points into a vector of Point objects.
+	void readPoints    (const SHPHandle &hSHP, int numberOfElements, std::string listName);
+
+	/// Reads points into a vector of Point objects and marks them as Station.
+	void readStations  (const SHPHandle &hSHP, int numberOfElements, std::string listName);
+
+	/// Reads lines into a vector of Polyline objects.
+	void readPolylines (const SHPHandle &hSHP, int numberOfElements, std::string listName);
+
+	/// Reads lines into a vector of Polyline and Surface objects.
+	void readPolygons  (const SHPHandle &hSHP, int numberOfElements, std::string listName);
+
+	void adjustPolylines (std::vector<GeoLib::Polyline*>* lines, std::vector<size_t>  id_map);
+
+	GeoLib::GEOObjects* _geoObjects;
+};
+
+#endif //SHPINTERFACE_H
-- 
GitLab