/** * SHPParser - parse ESRI ShapeFiles containing PolyLines */ // Written by James Turner, started 2013. // // Copyright (C) 2013 James Turner // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "SHPParser.hxx" #include #include #include #include // http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf table 1 const int SHP_FILE_MAGIC = 9994; const int SHP_FILE_VERSION = 1000; const int SHP_NULL_TYPE = 0; const int SHP_POLYLINE_TYPE = 3; const int SHP_POLYGON_TYPE = 5; namespace { void sgReadIntBE ( gzFile fd, int& var ) { if ( gzread ( fd, &var, sizeof(int) ) != sizeof(int) ) { throw sg_io_exception("gzread failed"); } if ( sgIsLittleEndian() ) { sgEndianSwap( (uint32_t *) &var); } } void sgReadIntLE ( gzFile fd, int& var ) { if ( gzread ( fd, &var, sizeof(int) ) != sizeof(int) ) { throw sg_io_exception("gzread failed"); } if ( sgIsBigEndian() ) { sgEndianSwap( (uint32_t *) &var); } } void readSHPRecordHeader(gzFile fd, int &recordNumber, int& contentLength) { sgReadIntBE(fd, recordNumber); sgReadIntBE(fd, contentLength); } void parseSHPPoints2D(gzFile fd, int numPoints, flightgear::SGGeodVec& aPoints) { aPoints.reserve(numPoints); std::vector ds; ds.resize(numPoints * 2); sgReadDouble(fd, numPoints * 2, ds.data()); unsigned int index = 0; for (int i=0; i parts; parts.resize(numParts); sgReadInt(file, numParts, parts.data()); SGGeodVec points; parseSHPPoints2D(file, numPoints, points); for (int part=0; part