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

marble

  • sources
  • kde-4.12
  • 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 "MarbleDebug.h"
40 
41 #include <QFile>
42 #include <QFileInfo>
43 
44 namespace Marble
45 {
46 
47 // Polygon header flags, representing the type of polygon
48 enum polygonFlagType { LINESTRING = 0, LINEARRING = 1, OUTERBOUNDARY = 2, INNERBOUNDARY = 3, MULTIGEOMETRY = 4 };
49 
50 
51 Pn2Runner::Pn2Runner(QObject *parent) :
52  ParsingRunner(parent)
53 {
54 }
55 
56 Pn2Runner::~Pn2Runner()
57 {
58 }
59 
60 bool Pn2Runner::errorCheckLat( qint16 lat )
61 {
62  if ( lat >= -10800 && lat <= +10800 )
63  return false;
64  else
65  return true;
66 }
67 
68 bool Pn2Runner::errorCheckLon( qint16 lon )
69 {
70  if ( lon >= -21600 && lon <= +21600 )
71  return false;
72  else
73  return true;
74 }
75 
76 bool Pn2Runner::importPolygon( QDataStream &stream, GeoDataLineString* linestring, quint32 nrAbsoluteNodes )
77 {
78  qint16 lat, lon, nrRelativeNodes;
79  qint8 relativeLat, relativeLon;
80  bool error = false;
81 
82 
83  for ( quint32 absoluteNode = 1; absoluteNode <= nrAbsoluteNodes; absoluteNode++ ) {
84  stream >> lat >> lon >> nrRelativeNodes;
85 
86  error = error | errorCheckLat( lat ) | errorCheckLon( lon );
87 
88  qreal degLat = ( 1.0 * lat / 120.0 );
89  qreal degLon = ( 1.0 * lon / 120.0 );
90 
91  GeoDataCoordinates *coord = new GeoDataCoordinates( degLon / 180 * M_PI, degLat / 180 * M_PI );
92  linestring->append( *coord );
93 
94  for ( qint16 relativeNode = 1; relativeNode <= nrRelativeNodes; ++relativeNode ) {
95  stream >> relativeLat >> relativeLon;
96 
97  qint16 currLat = relativeLat + lat;
98  qint16 currLon = relativeLon + lon;
99 
100 
101  error = error | errorCheckLat( currLat ) | errorCheckLon( currLon );
102 
103  qreal currDegLat = ( 1.0 * currLat / 120.0 );
104  qreal currDegLon = ( 1.0 * currLon / 120.0 );
105 
106 
107  GeoDataCoordinates *currCoord = new GeoDataCoordinates( currDegLon / 180 * M_PI, currDegLat / 180 * M_PI );
108  linestring->append( *currCoord );
109  }
110  }
111 
112  return error;
113 }
114 
115 void Pn2Runner::parseFile( const QString &fileName, DocumentRole role = UnknownDocument )
116 {
117  QFileInfo fileinfo( fileName );
118  if( fileinfo.suffix().compare( "pn2", Qt::CaseInsensitive ) != 0 ) {
119  emit parsingFinished( 0 );
120  return;
121  }
122 
123  QFile file( fileName );
124  if ( !file.exists() ) {
125  qWarning( "File does not exist!" );
126  emit parsingFinished( 0 );
127  return;
128  }
129 
130  file.open( QIODevice::ReadOnly );
131  QDataStream stream( &file ); // read the data serialized from the file
132 
133  GeoDataDocument *document = new GeoDataDocument();
134  document->setDocumentRole( role );
135 
136  quint8 fileHeaderVersion;
137  quint32 fileHeaderPolygons;
138 
139  stream >> fileHeaderVersion >> fileHeaderPolygons;
140 
141  bool error = false;
142 
143  quint32 ID, nrAbsoluteNodes;
144  quint8 flag, prevFlag = -1;
145 
146  GeoDataPolygon *polygon = new GeoDataPolygon;
147 
148  for ( quint32 currentPoly = 1; ( currentPoly <= fileHeaderPolygons ) && ( !error ) && ( !stream.atEnd() ); currentPoly++ ) {
149 
150  stream >> ID >> nrAbsoluteNodes >> flag;
151 
152  if ( flag != INNERBOUNDARY && ( prevFlag == INNERBOUNDARY || prevFlag == OUTERBOUNDARY ) ) {
153 
154  GeoDataPlacemark *placemark = new GeoDataPlacemark;
155  placemark->setGeometry( polygon );
156  document->append( placemark );
157  }
158 
159  if ( flag == LINESTRING ) {
160  GeoDataLineString *linestring = new GeoDataLineString;
161  error = error | importPolygon( stream, linestring, nrAbsoluteNodes );
162 
163  GeoDataPlacemark *placemark = new GeoDataPlacemark;
164  placemark->setGeometry( linestring );
165  document->append( placemark );
166  }
167 
168  if ( ( flag == LINEARRING ) || ( flag == OUTERBOUNDARY ) || ( flag == INNERBOUNDARY ) ) {
169  GeoDataLinearRing* linearring = new GeoDataLinearRing;
170  error = error | importPolygon( stream, linearring, nrAbsoluteNodes );
171 
172  if ( flag == LINEARRING ) {
173  GeoDataPlacemark *placemark = new GeoDataPlacemark;
174  placemark->setGeometry( linearring );
175  document->append( placemark );
176  }
177 
178  if ( flag == OUTERBOUNDARY ) {
179  polygon = new GeoDataPolygon;
180  polygon->setOuterBoundary( *linearring );
181  }
182 
183  if ( flag == INNERBOUNDARY ) {
184  polygon->appendInnerBoundary( *linearring );
185  }
186  }
187 
188 
189 
190  if ( flag == MULTIGEOMETRY ) {
191  // not implemented yet, for now elements inside a multigeometry are separated as individual geometries
192  }
193 
194  prevFlag = flag;
195  }
196 
197  if ( prevFlag == INNERBOUNDARY || prevFlag == OUTERBOUNDARY ) {
198  GeoDataPlacemark *placemark = new GeoDataPlacemark;
199  placemark->setGeometry( polygon );
200  document->append( placemark );
201  }
202 
203  if ( error ) {
204  delete document;
205  document = 0;
206  emit parsingFinished( 0, "Errors occurred while parsing the .pn2 file!" );
207  return;
208  }
209  document->setFileName( fileName );
210 
211  emit parsingFinished( document );
212 }
213 
214 }
215 
216 #include "Pn2Runner.moc"
GeoDataDocument.h
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
Marble::Pn2Runner::errorCheckLon
bool errorCheckLon(qint16 lon)
Definition: Pn2Runner.cpp:68
Marble::GeoDataDocument
A container for Features, Styles and in the future Schemas.
Definition: GeoDataDocument.h:64
Pn2Runner.h
Marble::INNERBOUNDARY
Definition: Pn2Runner.cpp:48
Marble::GeoDataDocument::setDocumentRole
void setDocumentRole(DocumentRole role)
Definition: GeoDataDocument.cpp:62
Marble::GeoDataLinearRing
A LinearRing that allows to store a closed, contiguous set of line segments.
Definition: GeoDataLinearRing.h:68
Marble::OUTERBOUNDARY
Definition: Pn2Runner.cpp:48
Marble::Pn2Runner::Pn2Runner
Pn2Runner(QObject *parent=0)
Definition: Pn2Runner.cpp:51
QObject
MarbleDebug.h
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:48
Marble::LINEARRING
Definition: Pn2Runner.cpp:48
Marble::GeoDataPolygon
A polygon that can have "holes".
Definition: GeoDataPolygon.h:81
Marble::Pn2Runner::importPolygon
bool importPolygon(QDataStream &stream, GeoDataLineString *linestring, quint32 nrAbsoluteNodes)
Definition: Pn2Runner.cpp:76
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:221
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:165
Marble::Pn2Runner::~Pn2Runner
~Pn2Runner()
Definition: Pn2Runner.cpp:56
Marble::GeoDataPolygon::appendInnerBoundary
void appendInnerBoundary(const GeoDataLinearRing &boundary)
Appends a given LinearRing as an inner boundary of the Polygon.
Definition: GeoDataPolygon.cpp:111
Marble::MULTIGEOMETRY
Definition: Pn2Runner.cpp:48
Marble::polygonFlagType
polygonFlagType
Definition: Pn2Runner.cpp:48
Marble::GeoDataDocument::setFileName
void setFileName(const QString &value)
Set a new file name for this document.
Definition: GeoDataDocument.cpp:82
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
Marble::GeoDataPlacemark
a class representing a point of interest on the map
Definition: GeoDataPlacemark.h:54
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:95
Marble::Pn2Runner::errorCheckLat
bool errorCheckLat(qint16 lat)
Definition: Pn2Runner.cpp:60
Marble::Pn2Runner::parseFile
virtual void parseFile(const QString &fileName, DocumentRole role)
Start a file parsing.
Definition: Pn2Runner.cpp:115
Marble::GeoDataPlacemark::setGeometry
void setGeometry(GeoDataGeometry *entry)
Sets the current Geometry of this Placemark.
Definition: GeoDataPlacemark.cpp:136
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:52 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
  • kstars
  • libkdeedu
  •   keduvocdocument
  • 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