• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.14
  • kdeedu
  • marble
  • src
  • plugins
  • runner
  • shp
ShpRunner.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2011 Thibaut Gridel <tgridel@free.fr>
9 
10 #include "ShpRunner.h"
11 
12 #include "GeoDataDocument.h"
13 #include "GeoDataPlacemark.h"
14 #include "GeoDataPolygon.h"
15 #include "GeoDataSchema.h"
16 #include "GeoDataSimpleField.h"
17 #include "GeoDataStyle.h"
18 #include "GeoDataPolyStyle.h"
19 #include "MarbleDebug.h"
20 
21 #include <QFileInfo>
22 
23 #include <shapefil.h>
24 
25 namespace Marble
26 {
27 
28 ShpRunner::ShpRunner(QObject *parent) :
29  ParsingRunner(parent)
30 {
31 }
32 
33 ShpRunner::~ShpRunner()
34 {
35 }
36 
37 void ShpRunner::parseFile( const QString &fileName, DocumentRole role = UnknownDocument )
38 {
39  QFileInfo fileinfo( fileName );
40  if( fileinfo.suffix().compare( "shp", Qt::CaseInsensitive ) != 0 ) {
41  emit parsingFinished( 0 );
42  return;
43  }
44 
45  SHPHandle handle = SHPOpen( fileName.toStdString().c_str(), "rb" );
46  if ( !handle ) {
47  emit parsingFinished( 0 );
48  return;
49  }
50  int entities;
51  int shapeType;
52  SHPGetInfo( handle, &entities, &shapeType, NULL, NULL );
53  mDebug() << " SHP info " << entities << " Entities "
54  << shapeType << " Shape Type ";
55 
56  DBFHandle dbfhandle;
57  dbfhandle = DBFOpen( fileName.toStdString().c_str(), "rb");
58  int nameField = DBFGetFieldIndex( dbfhandle, "Name" );
59  int noteField = DBFGetFieldIndex( dbfhandle, "Note" );
60  int mapColorField = DBFGetFieldIndex( dbfhandle, "mapcolor13" );
61 
62  GeoDataDocument *document = new GeoDataDocument;
63  document->setDocumentRole( role );
64 
65  if ( mapColorField != -1 ) {
66  GeoDataSchema schema;
67  schema.setId("default");
68  GeoDataSimpleField simpleField;
69  simpleField.setName("mapcolor13");
70  simpleField.setType( GeoDataSimpleField::Double );
71  schema.addSimpleField( simpleField );
72  document->addSchema( schema );
73  }
74 
75  for ( int i=0; i< entities; ++i ) {
76  GeoDataPlacemark *placemark = 0;
77  placemark = new GeoDataPlacemark;
78  document->append( placemark );
79 
80  SHPObject *shape = SHPReadObject( handle, i );
81  if( nameField ) {
82  const char* info = DBFReadStringAttribute( dbfhandle, i, nameField );
83  placemark->setName( info );
84  mDebug() << "name " << placemark->name();
85  }
86  if( noteField ) {
87  const char* note = DBFReadStringAttribute( dbfhandle, i, noteField );
88  placemark->setDescription( note );
89  mDebug() << "desc " << placemark->description();
90  }
91 
92  double mapColor = DBFReadDoubleAttribute( dbfhandle, i, mapColorField );
93  if ( mapColor ) {
94  GeoDataStyle *style = new GeoDataStyle;
95  if ( mapColor >= 0 && mapColor <=255 ) {
96  quint8 colorIndex = quint8( mapColor );
97  style->polyStyle().setColorIndex( colorIndex );
98  }
99  else {
100  quint8 colorIndex = 0; // mapColor is undefined in this case
101  style->polyStyle().setColorIndex( colorIndex );
102  }
103  placemark->setStyle( style );
104  }
105 
106  switch ( shapeType ) {
107  case SHPT_POINT: {
108  GeoDataPoint *point = new GeoDataPoint( *shape->padfX, *shape->padfY, 0, GeoDataCoordinates::Degree );
109  placemark->setGeometry( point );
110  mDebug() << "point " << placemark->name();
111  break;
112  }
113 
114  case SHPT_MULTIPOINT: {
115  GeoDataMultiGeometry *geom = new GeoDataMultiGeometry;
116  for( int j=0; j<shape->nVertices; ++j ) {
117  geom->append( new GeoDataPoint( GeoDataCoordinates(
118  shape->padfX[j], shape->padfY[j],
119  0, GeoDataCoordinates::Degree ) ) );
120  }
121  placemark->setGeometry( geom );
122  mDebug() << "multipoint " << placemark->name();
123  break;
124  }
125 
126  case SHPT_ARC: {
127  if ( shape->nParts != 1 ) {
128  GeoDataMultiGeometry *geom = new GeoDataMultiGeometry;
129  for( int j=0; j<shape->nParts; ++j ) {
130  GeoDataLineString *line = new GeoDataLineString;
131  int itEnd = (j + 1 < shape->nParts) ? shape->panPartStart[j+1] : shape->nVertices;
132  for( int k=shape->panPartStart[j]; k<itEnd; ++k ) {
133  line->append( GeoDataCoordinates(
134  shape->padfX[k], shape->padfY[k],
135  0, GeoDataCoordinates::Degree ) );
136  }
137  geom->append( line );
138  }
139  placemark->setGeometry( geom );
140  mDebug() << "arc " << placemark->name() << " " << shape->nParts;
141 
142  } else {
143  GeoDataLineString *line = new GeoDataLineString;
144  for( int j=0; j<shape->nVertices; ++j ) {
145  line->append( GeoDataCoordinates(
146  shape->padfX[j], shape->padfY[j],
147  0, GeoDataCoordinates::Degree ) );
148  }
149  placemark->setGeometry( line );
150  mDebug() << "arc " << placemark->name() << " " << shape->nParts;
151  }
152  break;
153  }
154 
155  case SHPT_POLYGON: {
156  if ( shape->nParts != 1 ) {
157  bool isRingClockwise = false;
158  GeoDataMultiGeometry *multigeom = new GeoDataMultiGeometry;
159  GeoDataPolygon *poly = 0;
160  for( int j=0; j<shape->nParts; ++j ) {
161  GeoDataLinearRing ring;
162  int itStart = shape->panPartStart[j];
163  int itEnd = (j + 1 < shape->nParts) ? shape->panPartStart[j+1] : shape->nVertices;
164  for( int k = itStart; k<itEnd; ++k ) {
165  ring.append( GeoDataCoordinates(
166  shape->padfX[k], shape->padfY[k],
167  0, GeoDataCoordinates::Degree ) );
168  }
169  isRingClockwise = ring.isClockwise();
170  if ( j == 0 || isRingClockwise ) {
171  poly = new GeoDataPolygon;
172  poly->setOuterBoundary( ring );
173  multigeom->append( poly );
174  }
175  else {
176  poly->appendInnerBoundary( ring );
177  }
178  // TODO: outer boundary per SHP spec is for the clockwise ring
179  // and inner holes are anticlockwise
180  }
181  placemark->setGeometry( multigeom );
182  mDebug() << "donut " << placemark->name() << " " << shape->nParts;
183 
184  } else {
185  GeoDataPolygon *poly = new GeoDataPolygon;
186  GeoDataLinearRing ring;
187  for( int j=0; j<shape->nVertices; ++j ) {
188  ring.append( GeoDataCoordinates(
189  shape->padfX[j], shape->padfY[j],
190  0, GeoDataCoordinates::Degree ) );
191  }
192  poly->setOuterBoundary( ring );
193  placemark->setGeometry( poly );
194  mDebug() << "poly " << placemark->name() << " " << shape->nParts;
195  }
196  break;
197  }
198  }
199 
200  }
201 
202  SHPClose( handle );
203 
204  DBFClose( dbfhandle );
205 
206  if ( document->size() ) {
207  document->setFileName( fileName );
208  emit parsingFinished( document );
209  } else {
210  delete document;
211  emit parsingFinished( 0 );
212  }
213 }
214 
215 }
216 
217 #include "ShpRunner.moc"
GeoDataDocument.h
Marble::GeoDataPoint
A Geometry object representing a 3d point.
Definition: GeoDataPoint.h:47
QString::toStdString
std::string toStdString() const
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
Marble::GeoDataDocument
A container for Features, Styles and in the future Schemas.
Definition: GeoDataDocument.h:65
Marble::GeoDataDocument::setDocumentRole
void setDocumentRole(DocumentRole role)
Definition: GeoDataDocument.cpp:86
Marble::GeoDataLinearRing
A LinearRing that allows to store a closed, contiguous set of line segments.
Definition: GeoDataLinearRing.h:68
GeoDataPolygon.h
Marble::GeoDataSimpleField
Definition: GeoDataSimpleField.h:25
Marble::GeoDataStyle::polyStyle
GeoDataPolyStyle & polyStyle()
Return the label style of this style.
Definition: GeoDataStyle.cpp:153
Marble::GeoDataFeature::setDescription
void setDescription(const QString &value)
Set the description of this feature to value.
Definition: GeoDataFeature.cpp:593
GeoDataSimpleField.h
GeoDataStyle.h
ShpRunner.h
Marble::GeoDataFeature::description
QString description() const
Return the text description of the feature.
Definition: GeoDataFeature.cpp:588
MarbleDebug.h
Marble::GeoDataCoordinates::Degree
Definition: GeoDataCoordinates.h:66
Marble::UnknownDocument
Definition: GeoDataDocument.h:40
Marble::ParsingRunner::parsingFinished
void parsingFinished(GeoDataDocument *document, const QString &error=QString())
File parsing is finished, result in the given document object.
Marble::GeoDataSimpleField::setType
void setType(const SimpleFieldType &type)
Definition: GeoDataSimpleField.cpp:65
Marble::GeoDataSchema::addSimpleField
void addSimpleField(const GeoDataSimpleField &value)
Definition: GeoDataSchema.cpp:84
Marble::GeoDataStyle
an addressable style group
Definition: GeoDataStyle.h:55
Marble::GeoDataFeature::setName
void setName(const QString &value)
Set a new name for this feature.
Definition: GeoDataFeature.cpp:549
QObject
Marble::GeoDataSimpleField::Double
Definition: GeoDataSimpleField.h:44
Marble::GeoDataPolygon
A polygon that can have "holes".
Definition: GeoDataPolygon.h:81
Marble::ShpRunner::parseFile
virtual void parseFile(const QString &fileName, DocumentRole role)
Start a file parsing.
Definition: ShpRunner.cpp:37
GeoDataSchema.h
Marble::GeoDataContainer::size
int size() const
size of the container
Definition: GeoDataContainer.cpp:286
Marble::ShpRunner::~ShpRunner
~ShpRunner()
Definition: ShpRunner.cpp:33
QString
GeoDataPlacemark.h
Marble::GeoDataLineString::append
void append(const GeoDataCoordinates &position)
Appends a given geodesic position as a new node to the LineString.
Definition: GeoDataLineString.cpp:225
Marble::GeoDataLineString
A LineString that allows to store a contiguous set of line segments.
Definition: GeoDataLineString.h:75
Marble::ParsingRunner
Definition: ParsingRunner.h:23
Marble::GeoDataSimpleField::setName
void setName(const QString &value)
Definition: GeoDataSimpleField.cpp:75
Marble::GeoDataContainer::append
void append(GeoDataFeature *other)
add an element
Definition: GeoDataContainer.cpp:272
Marble::GeoDataMultiGeometry::append
void append(GeoDataGeometry *other)
add an element
Definition: GeoDataMultiGeometry.cpp:187
QFileInfo
Marble::GeoDataPolygon::appendInnerBoundary
void appendInnerBoundary(const GeoDataLinearRing &boundary)
Appends a given LinearRing as an inner boundary of the Polygon.
Definition: GeoDataPolygon.cpp:149
Marble::GeoDataObject::setId
void setId(const QString &value)
Set the id of the object.
Definition: GeoDataObject.cpp:80
QFileInfo::suffix
QString suffix() const
Marble::GeoDataSchema
Definition: GeoDataSchema.h:30
Marble::GeoDataDocument::setFileName
void setFileName(const QString &value)
Set a new file name for this document.
Definition: GeoDataDocument.cpp:106
Marble::GeoDataFeature::name
QString name() const
The name of the feature.
Definition: GeoDataFeature.cpp:544
Marble::GeoDataMultiGeometry
Definition: GeoDataMultiGeometry.h:33
Marble::GeoDataFeature::setStyle
void setStyle(GeoDataStyle *style)
Sets the style of the placemark.
Definition: GeoDataFeature.cpp:735
Marble::ShpRunner::ShpRunner
ShpRunner(QObject *parent=0)
Definition: ShpRunner.cpp:28
Marble::GeoDataDocument::addSchema
void addSchema(const GeoDataSchema &schema)
Add a schema to simplemap storage.
Definition: GeoDataDocument.cpp:194
QString::compare
int compare(const QString &other) const
Marble::GeoDataPlacemark
a class representing a point of interest on the map
Definition: GeoDataPlacemark.h:54
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:36
Marble::GeoDataLinearRing::isClockwise
virtual bool isClockwise() const
Returns whether the orientaion of ring is coloskwise or not.
Definition: GeoDataLinearRing.cpp:86
Marble::DocumentRole
DocumentRole
Definition: GeoDataDocument.h:39
Marble::GeoDataPolygon::setOuterBoundary
void setOuterBoundary(const GeoDataLinearRing &boundary)
Sets the given LinearRing as an outer boundary of the Polygon.
Definition: GeoDataPolygon.cpp:133
GeoDataPolyStyle.h
Marble::GeoDataPlacemark::setGeometry
void setGeometry(GeoDataGeometry *entry)
Sets the current Geometry of this Placemark.
Definition: GeoDataPlacemark.cpp:230
Marble::GeoDataPolyStyle::setColorIndex
void setColorIndex(quint8 colorIndex)
Set the color index which will be used to assign color to brush.
Definition: GeoDataPolyStyle.cpp:120
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:42 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal