• 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
  • pn2
Pn2Runner.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 //
9 // For the Natural Earth Layer providing the Default data set at 0.5 arcminute resolution should be enough.
10 // This fileformat allows for even better packed data than the PNT format. For detailed polygons at arcminute
11 // scale on average it should use only 33% of the amount used by PNT.
12 //
13 // Description of the file format
14 //
15 // In the fileformat initially a file header is provided that provides the file format version and the number
16 // of polygons stored inside the file. A Polygon starts with the Polygon Header which provides the feature id
17 // and the number of so called "absolute nodes" that are about to follow. Absolute nodes always contain
18 // absolute geodetic coordinates. The Polygon Header also provides a flag that allows to specify whether the
19 // polygon is supposed to represent a line string ("0") or a linear ring ("1"). Each absolute node can be followed
20 // by relative nodes: These relative nodes are always nodes that follow in correct order inside the polygon after
21 // "their" absolute node. Each absolute node specifies the number of relative nodes which contain relative
22 // coordinates in reference to their absolute node. So an absolute node provides the absolute reference for
23 // relative nodes across a theoretical area of 2x2 squaredegree-area (which in practice frequently might rather
24 // amount to 1x1 square degrees).
25 //
26 // So much of the compression works by just referencing lat/lon diffs to special "absolute nodes". Hence the
27 // compression will especially work well for polygons with many nodes with a high node density.
28 //
29 // The parser has to convert these relative coordinates to absolute coordinates.
30 //
31 // Copyright 2012 Torsten Rahn <rahn@kde.org>
32 // Copyright 2012 Cezar Mocan <mocancezar@gmail.com>
33 //
34 
35 #include "Pn2Runner.h"
36 
37 #include "GeoDataDocument.h"
38 #include "GeoDataPlacemark.h"
39 #include "GeoDataStyle.h"
40 #include "GeoDataPolyStyle.h"
41 #include "MarbleDebug.h"
42 
43 #include <QFile>
44 #include <QFileInfo>
45 
46 namespace Marble
47 {
48 
49 // Polygon header flags, representing the type of polygon
50 enum polygonFlagType { LINESTRING = 0, LINEARRING = 1, OUTERBOUNDARY = 2, INNERBOUNDARY = 3, MULTIGEOMETRY = 4 };
51 
52 
53 Pn2Runner::Pn2Runner(QObject *parent) :
54  ParsingRunner(parent)
55 {
56 }
57 
58 Pn2Runner::~Pn2Runner()
59 {
60 }
61 
62 bool Pn2Runner::errorCheckLat( qint16 lat )
63 {
64  if ( lat >= -10800 && lat <= +10800 )
65  return false;
66  else
67  return true;
68 }
69 
70 bool Pn2Runner::errorCheckLon( qint16 lon )
71 {
72  if ( lon >= -21600 && lon <= +21600 )
73  return false;
74  else
75  return true;
76 }
77 
78 bool Pn2Runner::importPolygon( QDataStream &stream, GeoDataLineString* linestring, quint32 nrAbsoluteNodes )
79 {
80  qint16 lat, lon, nrRelativeNodes;
81  qint8 relativeLat, relativeLon;
82  bool error = false;
83 
84 
85  for ( quint32 absoluteNode = 1; absoluteNode <= nrAbsoluteNodes; absoluteNode++ ) {
86  stream >> lat >> lon >> nrRelativeNodes;
87 
88  error = error | errorCheckLat( lat ) | errorCheckLon( lon );
89 
90  qreal degLat = ( 1.0 * lat / 120.0 );
91  qreal degLon = ( 1.0 * lon / 120.0 );
92 
93  GeoDataCoordinates *coord = new GeoDataCoordinates( degLon / 180 * M_PI, degLat / 180 * M_PI );
94  linestring->append( *coord );
95 
96  for ( qint16 relativeNode = 1; relativeNode <= nrRelativeNodes; ++relativeNode ) {
97  stream >> relativeLat >> relativeLon;
98 
99  qint16 currLat = relativeLat + lat;
100  qint16 currLon = relativeLon + lon;
101 
102 
103  error = error | errorCheckLat( currLat ) | errorCheckLon( currLon );
104 
105  qreal currDegLat = ( 1.0 * currLat / 120.0 );
106  qreal currDegLon = ( 1.0 * currLon / 120.0 );
107 
108 
109  GeoDataCoordinates *currCoord = new GeoDataCoordinates( currDegLon / 180 * M_PI, currDegLat / 180 * M_PI );
110  linestring->append( *currCoord );
111  }
112  }
113 
114  return error;
115 }
116 
117 void Pn2Runner::parseFile( const QString &fileName, DocumentRole role = UnknownDocument )
118 {
119  QFileInfo fileinfo( fileName );
120  if( fileinfo.suffix().compare( "pn2", Qt::CaseInsensitive ) != 0 ) {
121  emit parsingFinished( 0 );
122  return;
123  }
124 
125  QFile file( fileName );
126  if ( !file.exists() ) {
127  qWarning( "File does not exist!" );
128  emit parsingFinished( 0 );
129  return;
130  }
131 
132  file.open( QIODevice::ReadOnly );
133  QDataStream stream( &file ); // read the data serialized from the file
134 
135  GeoDataDocument *document = new GeoDataDocument();
136  document->setDocumentRole( role );
137 
138  quint8 fileHeaderVersion;
139  quint32 fileHeaderPolygons;
140  bool isMapColorField; // Whether the file contains color indexes
141 
142  stream >> fileHeaderVersion >> fileHeaderPolygons >> isMapColorField;
143 
144  bool error = false;
145 
146  quint32 ID, nrAbsoluteNodes;
147  quint8 flag, prevFlag = -1;
148 
149  GeoDataStyle *style =0;
150  GeoDataPolygon *polygon = new GeoDataPolygon;
151 
152  for ( quint32 currentPoly = 1; ( currentPoly <= fileHeaderPolygons ) && ( !error ) && ( !stream.atEnd() ); currentPoly++ ) {
153 
154  stream >> ID >> nrAbsoluteNodes >> flag;
155 
156  if ( flag != INNERBOUNDARY && ( prevFlag == INNERBOUNDARY || prevFlag == OUTERBOUNDARY ) ) {
157 
158  GeoDataPlacemark *placemark = new GeoDataPlacemark;
159  placemark->setGeometry( polygon );
160  if ( isMapColorField ) {
161  if ( style ) {
162  placemark->setStyle( style );
163  }
164  }
165  document->append( placemark );
166  }
167 
168  if ( flag == LINESTRING ) {
169  GeoDataLineString *linestring = new GeoDataLineString;
170  error = error | importPolygon( stream, linestring, nrAbsoluteNodes );
171 
172  GeoDataPlacemark *placemark = new GeoDataPlacemark;
173  placemark->setGeometry( linestring );
174  document->append( placemark );
175  }
176 
177  if ( ( flag == LINEARRING ) || ( flag == OUTERBOUNDARY ) || ( flag == INNERBOUNDARY ) ) {
178 
179  if ( flag == OUTERBOUNDARY && isMapColorField ) {
180  quint8 colorIndex;
181  stream >> colorIndex;
182  style = new GeoDataStyle;
183  GeoDataPolyStyle polyStyle;
184  polyStyle.setColorIndex( colorIndex );
185  style->setPolyStyle( polyStyle );
186  }
187 
188  GeoDataLinearRing* linearring = new GeoDataLinearRing;
189  error = error | importPolygon( stream, linearring, nrAbsoluteNodes );
190 
191  if ( flag == LINEARRING ) {
192  GeoDataPlacemark *placemark = new GeoDataPlacemark;
193  placemark->setGeometry( linearring );
194  document->append( placemark );
195  }
196 
197  if ( flag == OUTERBOUNDARY ) {
198  polygon = new GeoDataPolygon;
199  polygon->setOuterBoundary( *linearring );
200  }
201 
202  if ( flag == INNERBOUNDARY ) {
203  polygon->appendInnerBoundary( *linearring );
204  }
205  }
206 
207 
208 
209  if ( flag == MULTIGEOMETRY ) {
210  // not implemented yet, for now elements inside a multigeometry are separated as individual geometries
211  }
212 
213  prevFlag = flag;
214  }
215 
216  if ( prevFlag == INNERBOUNDARY || prevFlag == OUTERBOUNDARY ) {
217  GeoDataPlacemark *placemark = new GeoDataPlacemark;
218  if ( isMapColorField ) {
219  if ( style ) {
220  placemark->setStyle( style );
221  }
222  }
223  placemark->setGeometry( polygon );
224  document->append( placemark );
225  }
226 
227  if ( error ) {
228  delete document;
229  document = 0;
230  emit parsingFinished( 0, "Errors occurred while parsing the .pn2 file!" );
231  return;
232  }
233  document->setFileName( fileName );
234 
235  emit parsingFinished( document );
236 }
237 
238 }
239 
240 #include "Pn2Runner.moc"
GeoDataDocument.h
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
Marble::Pn2Runner::errorCheckLon
static bool errorCheckLon(qint16 lon)
Definition: Pn2Runner.cpp:70
Marble::GeoDataDocument
A container for Features, Styles and in the future Schemas.
Definition: GeoDataDocument.h:65
Pn2Runner.h
Marble::INNERBOUNDARY
Definition: Pn2Runner.cpp:50
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
QDataStream
Marble::OUTERBOUNDARY
Definition: Pn2Runner.cpp:50
GeoDataStyle.h
Marble::Pn2Runner::Pn2Runner
Pn2Runner(QObject *parent=0)
Definition: Pn2Runner.cpp:53
QFile::exists
bool exists() const
MarbleDebug.h
QFile
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::LINESTRING
Definition: Pn2Runner.cpp:50
Marble::LINEARRING
Definition: Pn2Runner.cpp:50
Marble::GeoDataStyle
an addressable style group
Definition: GeoDataStyle.h:55
QObject
Marble::GeoDataPolygon
A polygon that can have "holes".
Definition: GeoDataPolygon.h:81
Marble::Pn2Runner::importPolygon
static bool importPolygon(QDataStream &stream, GeoDataLineString *linestring, quint32 nrAbsoluteNodes)
Definition: Pn2Runner.cpp:78
QString
GeoDataPlacemark.h
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QDataStream::atEnd
bool atEnd() const
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::GeoDataContainer::append
void append(GeoDataFeature *other)
add an element
Definition: GeoDataContainer.cpp:272
QFileInfo
Marble::Pn2Runner::~Pn2Runner
~Pn2Runner()
Definition: Pn2Runner.cpp:58
Marble::GeoDataPolygon::appendInnerBoundary
void appendInnerBoundary(const GeoDataLinearRing &boundary)
Appends a given LinearRing as an inner boundary of the Polygon.
Definition: GeoDataPolygon.cpp:149
Marble::MULTIGEOMETRY
Definition: Pn2Runner.cpp:50
Marble::polygonFlagType
polygonFlagType
Definition: Pn2Runner.cpp:50
QFileInfo::suffix
QString suffix() const
Marble::GeoDataDocument::setFileName
void setFileName(const QString &value)
Set a new file name for this document.
Definition: GeoDataDocument.cpp:106
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
Marble::GeoDataFeature::setStyle
void setStyle(GeoDataStyle *style)
Sets the style of the placemark.
Definition: GeoDataFeature.cpp:735
Marble::GeoDataPolyStyle
specifies the style how polygons are drawn
Definition: GeoDataPolyStyle.h:34
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::GeoDataStyle::setPolyStyle
void setPolyStyle(const GeoDataPolyStyle &style)
set the poly style
Definition: GeoDataStyle.cpp:117
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::Pn2Runner::errorCheckLat
static bool errorCheckLat(qint16 lat)
Definition: Pn2Runner.cpp:62
Marble::Pn2Runner::parseFile
virtual void parseFile(const QString &fileName, DocumentRole role)
Start a file parsing.
Definition: Pn2Runner.cpp:117
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:41 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