[QGIS Commit] r11376 - trunk/qgis/src/providers/osm
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Fri Aug 14 10:09:52 EDT 2009
Author: wonder
Date: 2009-08-14 10:09:51 -0400 (Fri, 14 Aug 2009)
New Revision: 11376
Modified:
trunk/qgis/src/providers/osm/osmhandler.h
trunk/qgis/src/providers/osm/osmprovider.cpp
trunk/qgis/src/providers/osm/osmprovider.h
trunk/qgis/src/providers/osm/osmrenderer.cpp
trunk/qgis/src/providers/osm/osmrenderer.h
trunk/qgis/src/providers/osm/osmstyle.h
Log:
Update of OSM provider from Lukas Berka:
code documentation, refactoring, cleaning
Modified: trunk/qgis/src/providers/osm/osmhandler.h
===================================================================
--- trunk/qgis/src/providers/osm/osmhandler.h 2009-08-14 12:12:56 UTC (rev 11375)
+++ trunk/qgis/src/providers/osm/osmhandler.h 2009-08-14 14:09:51 UTC (rev 11376)
@@ -20,55 +20,78 @@
#include <sqlite3.h>
-#include <iostream>
-using namespace std;
/**
- * XML SAX handler -> while processing XML file,
- * stores data to specified sqlite database
+ * The SAX handler used for parsing input OSM XML file.
+ * While processing XML file it stores data to specified sqlite database.
*/
class OsmHandler: public QXmlDefaultHandler
{
public:
-// member variables
+ /**
+ * Construction.
+ * @param f input file with OSM data
+ * @param database opened sqlite3 database with OSM db schema to store data in
+ */
+ OsmHandler( QFile *f, sqlite3 *database );
- QFile mFile;
- sqlite3 *mDatabase;
- int mCnt;
+ /**
+ * Destruction.
+ */
+ ~OsmHandler();
- int mFileSize;
- QString mError;
- // xml processing information
- QString mObjectId; //last node, way or relation id while parsing file
- QString mObjectType; //one of strings "node", "way", "relation"
- QString mRelationType;
- float mLat;
- float mLon;
- double xMin, xMax, yMin, yMax;
+ // input OSM XML processing
- int mPointCnt;
- int mLineCnt;
- int mPolygonCnt;
+ /**
+ * Function is called after XML processing is started.
+ * @return True if start of document signal is processed without problems; False otherwise
+ */
+ bool startDocument();
- int mCurrent_way_id;
- int mPosId;
- QString firstWayMemberId;
- QString lastWayMemberId;
- int mFirstMemberAppeared;
+ /**
+ * The reader of OSM file calls this function when it has parsed a start element tag.
+ * If this function returns false the reader stops parsing and reports an error.
+ * The reader uses the function errorString() to get the error message.
+ *
+ * @param pUri namespace URI of element, or an empty string if the element has no namespace URI or if no namespace processing is done
+ * @param pLocalName local name of element (without prefix), or an empty string if no namespace processing is done
+ * @param pName qualified name of element (with prefix)
+ * @param pAttrs attributes attached to the element; if there are no attributes, atts is an empty attributes object.
+ * @return True if start of element signal is processed without problems; False otherwise
+ */
+ bool startElement( const QString & pUri, const QString & pLocalName, const QString & pName, const QXmlAttributes & pAttrs );
-//functions
+ /**
+ * The reader calls this function when it has parsed an end element tag with the qualified name pName,
+ * the local name pLocalName and the namespace URI pURI.
+ * If this function returns false the reader stops parsing and reports an error.
+ * The reader uses the function errorString() to get the error message.
+ *
+ * @param pUri namespace URI of element, or an empty string if the element has no namespace URI or if no namespace processing is done
+ * @param pLocalName local name of element (without prefix), or an empty string if no namespace processing is done
+ * @param pName qualified name of element (with prefix)
+ * @return True if end of element signal is processed without problems; False otherwise
+ */
+ bool endElement( const QString & pURI, const QString & pLocalName, const QString & pName );
- // object construction
- OsmHandler( QFile *f, sqlite3 *database );
- ~OsmHandler();
- // xml processing
+ /**
+ * Function is called after end of document is reached while XML processing.
+ * @return True if end of document signal is processed without problems; False otherwise
+ */
+ bool endDocument();
- bool startDocument();
+ /**
+ * Returns information on error that occures while parsing.
+ * @return info on error that occures while parsing
+ */
QString errorString();
- bool startElement( const QString & pUri, const QString & pLocalName, const QString & pName, const QXmlAttributes & pAttrs );
- bool endElement( const QString & pURI, const QString & pLocalName, const QString & pName );
- bool endDocument();
+ public:
+ int mPointCnt;
+ int mLineCnt;
+ int mPolygonCnt;
+ double xMin, xMax, yMin, yMax;
+
private:
sqlite3_stmt *mStmtInsertNode;
sqlite3_stmt *mStmtInsertWay;
@@ -78,6 +101,17 @@
sqlite3_stmt *mStmtInsertRelationMember;
sqlite3_stmt *mStmtUpdateNode;
sqlite3_stmt *mStmtInsertVersion;
+
+ sqlite3 *mDatabase;
+ int mPosId;
+ QString firstWayMemberId;
+ QString lastWayMemberId;
+ int mFirstMemberAppeared;
+ int mCnt;
+ QString mError;
+ QString mObjectId; //last node, way or relation id while parsing file
+ QString mObjectType; //one of "node", "way", "relation"
+ QString mRelationType;
};
Modified: trunk/qgis/src/providers/osm/osmprovider.cpp
===================================================================
--- trunk/qgis/src/providers/osm/osmprovider.cpp 2009-08-14 12:12:56 UTC (rev 11375)
+++ trunk/qgis/src/providers/osm/osmprovider.cpp 2009-08-14 14:09:51 UTC (rev 11376)
@@ -23,20 +23,15 @@
#include "qgsvectordataprovider.h"
#include "qgsapplication.h"
-#include <cstring>
-#include <iostream>
-#include <QQueue>
#include <QFileInfo>
#include <QDateTime>
#include <QByteArray>
-using namespace std;
-
static const QString TEXT_PROVIDER_KEY = "osm";
static const QString TEXT_PROVIDER_DESCRIPTION = "Open Street Map data provider";
static const QString DATE_TIME_FMT = "dd.MM.yyyy HH:mm:ss";
-static const QString PLUGIN_VERSION = "0.4";
+static const QString PROVIDER_VERSION = "0.5";
// supported attributes
const char* QgsOSMDataProvider::attr[] = { "timestamp", "user", "tags" };
@@ -46,16 +41,17 @@
QgsOSMDataProvider::QgsOSMDataProvider( QString uri )
: QgsVectorDataProvider( uri )
{
+ QgsDebugMsg( "Initializing provider: " + uri );
+
mDatabaseStmt = NULL;
mValid = false;
- QgsDebugMsg( "Initializing provider: " + uri );
// set the selection rectangle to null
mSelectionRectangle = 0;
mSelectionRectangleGeom = NULL;
mDatabase = NULL;
mInitObserver = NULL;
- mFeatureType = PointType; // default
+ mFeatureType = PointType; // default feature type ~ point
// set default boundaries
xMin = -DEFAULT_EXTENT;
@@ -63,7 +59,7 @@
yMin = -DEFAULT_EXTENT;
yMax = DEFAULT_EXTENT;
- // get the filename and the type parameter from the URI
+ // get the filename and other parameters from the URI
int fileNameEnd = uri.indexOf( '?' );
if ( fileNameEnd == -1 )
{
@@ -116,11 +112,12 @@
}
}
- // set up the attributes and the geometry type depending on the feature type - same attributes for both point and way type so far
+ // set up attributes depending on the feature type - same attributes for both point and way type so far
mAttributeFields[TimestampAttr] = QgsField( attr[TimestampAttr], QVariant::String, "string" );
mAttributeFields[UserAttr] = QgsField( attr[UserAttr], QVariant::String, "string" );
mAttributeFields[TagAttr] = QgsField( attr[TagAttr], QVariant::String, "string" );
- // add custom tags
+
+ // add custom attributes - these were chosen by user through OSM plugin
for ( int tagId = 0; tagId < mCustomTagsList.count(); ++tagId )
{
mAttributeFields[CustomTagAttr+tagId] = QgsField( mCustomTagsList[tagId], QVariant::String, "string" );
@@ -133,7 +130,8 @@
QFile osmFile( mFileName );
bool databaseExists = dbFile.exists();
- // open (and create schema if neccessary) database
+ // open database and create database schema for OSM data if neccessary
+ // (find out if such database already exists; if not create it)
if ( !openDatabase() )
{
QgsDebugMsg( "Opening sqlite3 database failed, OSM provider cannot be constructed." );
@@ -144,7 +142,7 @@
// flag determining if OSM file parsing is neccessary
bool shouldParse = true;
- // test if db file belonging to source OSM file exists and if it has the right version
+ // test if db file that belongs to source OSM file already exists and if it has the right version
if ( databaseExists && isDatabaseCompatibleWithInput( mFileName ) && isDatabaseCompatibleWithPlugin() )
shouldParse = false;
@@ -171,39 +169,33 @@
QFile dbJournalFile( QString( mFileName + ".db-journal" ) );
if ( dbJournalFile.exists() )
dbJournalFile.remove();
- // now stop the osmprovider construction!
+ // stop the osmprovider construction!
return;
}
}
else
{
- // there was no parsing, we must find out default area boundaries from database meta information
- // prepare select command
- QString cmd = QString( "SELECT val FROM meta WHERE key='default-area-boundaries';" );
-
- // just conversion "cmd" to "const char*"
- QByteArray cmd_bytes = cmd.toAscii();
- const char *ptr = cmd_bytes.data();
-
- sqlite3_stmt *databaseStmt;
- if ( sqlite3_prepare_v2( mDatabase, ptr, cmd_bytes.size(), &databaseStmt, 0 ) != SQLITE_OK )
+ // no OSM file parsing was done, we must find out default area boundaries from database meta information
+ char sqlSelectBoundary[] = "SELECT val FROM meta WHERE key='default-area-boundaries';";
+ sqlite3_stmt *stmtSelectBoundary;
+ if ( sqlite3_prepare_v2( mDatabase, sqlSelectBoundary, sizeof(sqlSelectBoundary), &stmtSelectBoundary, 0 ) != SQLITE_OK )
{
- QgsDebugMsg( "Getting default area boundaries failed." );
+ QgsDebugMsg( "Getting default area boundary failed." );
// don't worry, we just let default values in xMax, yMax, xMin and yMin variables
}
else
{
- // select command has just run successful
- if ( sqlite3_step( databaseStmt ) != SQLITE_ROW )
+ if (sqlite3_step( stmtSelectBoundary ) != SQLITE_ROW)
{
- QgsDebugMsg( "Getting default area boundaries failed." );
+ QgsDebugMsg("Getting default area boundary failed.");
// don't worry again, we just let default values in boundary variables
}
else
{
- const unsigned char *boundaries_char = sqlite3_column_text( databaseStmt, 0 );
+ const unsigned char *boundaries_char = sqlite3_column_text( stmtSelectBoundary, 0 );
QString boundaries(( const char * ) boundaries_char );
- // boundaries should be string of the following format: "xMin-yMin-xMax-yMax"
+
+ // boundaries should be string in following format: "xMin-yMin-xMax-yMax"
int separ1_pos = boundaries.indexOf( "-" );
int separ2_pos = boundaries.indexOf( "-", separ1_pos + 1 );
int separ3_pos = boundaries.indexOf( "-", separ2_pos + 1 );
@@ -215,31 +207,99 @@
}
// destroy database statement
- sqlite3_finalize( databaseStmt );
+ sqlite3_finalize( stmtSelectBoundary );
}
+
// prepare statement for tag retrieval
- const char *zSql = "SELECT key, val FROM tag WHERE object_id=? AND object_type=?";
- int rc = sqlite3_prepare_v2( mDatabase, zSql, -1, &mTagsStmt, 0 );
+ char sqlSelectTags[] = "SELECT key, val FROM tag WHERE object_id=? AND object_type=?";
+ int rc = sqlite3_prepare_v2( mDatabase, sqlSelectTags, sizeof(sqlSelectTags), &mTagsStmt, 0 );
if ( rc != SQLITE_OK )
- QgsDebugMsg( "tags for object - prepare failed." );
+ {
+ QgsDebugMsg("sqlite3 statement for feature tags selection - prepare failed.");
+ return;
+ }
- const char *zSqlC = "SELECT val FROM tag WHERE object_id=? AND object_type=? AND key=?";
- rc = sqlite3_prepare_v2( mDatabase, zSqlC, -1, &mCustomTagsStmt, 0 );
+ char sqlSelectTagValue[] = "SELECT val FROM tag WHERE object_id=? AND object_type=? AND key=?";
+ rc = sqlite3_prepare_v2( mDatabase, sqlSelectTagValue, sizeof(sqlSelectTagValue), &mCustomTagsStmt, 0 );
if ( rc != SQLITE_OK )
- QgsDebugMsg( "custom tags for object - prepare failed." );
+ {
+ QgsDebugMsg("sqlite3 statement for tag value selection - prepare failed.");
+ return;
+ }
// prepare statements for feature retrieval
- const char *zSqlW = "SELECT id, wkb, timestamp, user FROM way WHERE id=? AND status<>'R' AND u=1";
- rc = sqlite3_prepare_v2( mDatabase, zSqlW, -1, &mWayStmt, 0 );
+ char sqlSelectWay[] = "SELECT id, wkb, timestamp, user FROM way WHERE id=? AND status<>'R' AND u=1";
+ rc = sqlite3_prepare_v2( mDatabase, sqlSelectWay, sizeof(sqlSelectWay), &mWayStmt, 0 );
if ( rc != SQLITE_OK )
- QgsDebugMsg( "sqlite3 statement for way retrieval - prepare failed." );
+ {
+ QgsDebugMsg("sqlite3 statement for way retrieval - prepare failed.");
+ return;
+ }
- const char *zSqlN = "SELECT id, lat, lon, timestamp, user FROM node WHERE id=? AND usage=0 AND status<>'R' AND u=1";
- rc = sqlite3_prepare_v2( mDatabase, zSqlN, -1, &mNodeStmt, 0 );
+ char sqlSelectNode[] = "SELECT id, lat, lon, timestamp, user FROM node WHERE id=? AND usage=0 AND status<>'R' AND u=1";
+ rc = sqlite3_prepare_v2( mDatabase, sqlSelectNode, sizeof(sqlSelectNode), &mNodeStmt, 0 );
if ( rc != SQLITE_OK )
- QgsDebugMsg( "sqlite3 statement for node retrieval - prepare failed." );
+ {
+ QgsDebugMsg("sqlite3 statement for node retrieval - prepare failed.");
+ return;
+ }
+ if ( mFeatureType == PointType )
+ {
+ char sqlSelectPoints[] = "SELECT id, lat, lon, timestamp, user FROM node WHERE usage=0 AND status<>'R' AND u=1";
+ char sqlSelectPointsIn[] = "SELECT id, lat, lon, timestamp, user FROM node WHERE usage=0 AND status<>'R' AND u=1 \
+ AND lat>=? AND lat<=? AND lon>=? AND lon<=?";
+
+ if ( sqlite3_prepare_v2( mDatabase, sqlSelectPoints, sizeof(sqlSelectPoints), &mSelectFeatsStmt, 0 ) != SQLITE_OK )
+ {
+ QgsDebugMsg("sqlite3 statement for points retrieval - prepare failed.");
+ return;
+ }
+ if ( sqlite3_prepare_v2( mDatabase, sqlSelectPointsIn, sizeof(sqlSelectPointsIn), &mSelectFeatsInStmt, 0 ) != SQLITE_OK )
+ {
+ QgsDebugMsg("sqlite3 statement for points in boundary retrieval - prepare failed.");
+ return;
+ }
+ }
+ else if ( mFeatureType == LineType )
+ {
+ char sqlSelectLines[] = "SELECT w.id, w.wkb, w.timestamp, w.user FROM way w WHERE w.closed=0 AND w.status<>'R' AND w.u=1";
+ char sqlSelectLinesIn[] = "SELECT w.id, w.wkb, w.timestamp, w.user FROM way w WHERE w.closed=0 AND w.status<>'R' AND w.u=1 \
+ AND (((w.max_lat between ? AND ?) OR (w.min_lat between ? AND ?) OR (w.min_lat<? AND w.max_lat>?)) \
+ OR ((w.max_lon between ? AND ?) OR (w.min_lon between ? AND ?) OR (w.min_lon<? AND w.max_lon>?)))";
+
+ if ( sqlite3_prepare_v2( mDatabase, sqlSelectLines, sizeof(sqlSelectLines), &mSelectFeatsStmt, 0 ) != SQLITE_OK )
+ {
+ QgsDebugMsg("sqlite3 statement for lines retrieval - prepare failed.");
+ return;
+ }
+ if ( sqlite3_prepare_v2( mDatabase, sqlSelectLinesIn, sizeof(sqlSelectLinesIn), &mSelectFeatsInStmt, 0 ) != SQLITE_OK )
+ {
+ QgsDebugMsg("sqlite3 statement for lines in boundary retrieval - prepare failed.");
+ return;
+ }
+ }
+ else // mFeatureType == PolygonType
+ {
+ char sqlSelectPolys[] = "SELECT w.id, w.wkb, w.timestamp, w.user FROM way w WHERE w.closed=1 AND w.status<>'R' AND w.u=1";
+ char sqlSelectPolysIn[] = "SELECT w.id, w.wkb, w.timestamp, w.user FROM way w WHERE w.closed=1 AND w.status<>'R' AND w.u=1 \
+ AND (((w.max_lat between ? AND ?) OR (w.min_lat between ? AND ?) OR (w.min_lat<? AND w.max_lat>?)) \
+ OR ((w.max_lon between ? AND ?) OR (w.min_lon between ? AND ?) OR (w.min_lon<? AND w.max_lon>?)))";
+
+ if ( sqlite3_prepare_v2( mDatabase, sqlSelectPolys, sizeof(sqlSelectPolys), &mSelectFeatsStmt, 0 ) != SQLITE_OK )
+ {
+ QgsDebugMsg("sqlite3 statement for polygons retrieval - prepare failed.");
+ return;
+ }
+ if ( sqlite3_prepare_v2( mDatabase, sqlSelectPolysIn, sizeof(sqlSelectPolysIn), &mSelectFeatsInStmt, 0 ) != SQLITE_OK )
+ {
+ QgsDebugMsg("sqlite3 statement for polygons in boundary retrieval - prepare failed.");
+ return;
+ }
+ }
+
+ // finally OSM provider is initialized and considered to be valid!
mValid = true;
}
@@ -248,11 +308,16 @@
{
// destruct selected geometry
delete mSelectionRectangleGeom;
+
+ // finalize all created sqlite3 statements
sqlite3_finalize( mTagsStmt );
sqlite3_finalize( mCustomTagsStmt );
sqlite3_finalize( mWayStmt );
sqlite3_finalize( mNodeStmt );
- sqlite3_finalize( mDatabaseStmt );
+ sqlite3_finalize( mSelectFeatsStmt );
+ sqlite3_finalize( mSelectFeatsInStmt );
+
+ // close opened sqlite3 database
closeDatabase();
}
@@ -263,53 +328,54 @@
QFileInfo osmFileInfo( osmFile );
QDateTime mOsmFileLastModif = osmFileInfo.lastModified();
- QString cmd = QString( "SELECT val FROM meta WHERE key='osm-file-last-modified';" );
- QByteArray cmd_bytes = cmd.toAscii();
- const char *ptr = cmd_bytes.data();
+ char sqlSelectLastModif[] = "SELECT val FROM meta WHERE key='osm-file-last-modified';";
+ sqlite3_stmt *stmtSelectLastModif;
- sqlite3_stmt *databaseStmt;
- if ( sqlite3_prepare_v2( mDatabase, ptr, cmd_bytes.size(), &databaseStmt, 0 ) == SQLITE_OK )
+ if ( sqlite3_prepare_v2( mDatabase, sqlSelectLastModif, sizeof(sqlSelectLastModif), &stmtSelectLastModif, 0 ) == SQLITE_OK )
{
- if ( sqlite3_step( databaseStmt ) == SQLITE_ROW )
+ if ( sqlite3_step(stmtSelectLastModif) == SQLITE_ROW )
{
- QString oldOsmLastModifString = ( const char * ) sqlite3_column_text( databaseStmt, 0 );
+ QString oldOsmLastModifString = ( const char * ) sqlite3_column_text( stmtSelectLastModif, 0 );
QDateTime oldOsmFileLastModif = QDateTime::fromString( oldOsmLastModifString, DATE_TIME_FMT );
+ // each OSM database schema carry info on last-modified of file from which database was created;
+ // if value equals to last-modified of current input file then DB file belongs to current input file
+ // (in such case we say that "database is compatible with input")
if ( mOsmFileLastModif == oldOsmFileLastModif )
{
- sqlite3_finalize( databaseStmt );
+ sqlite3_finalize( stmtSelectLastModif );
return true;
}
}
}
// destroy database statement
- sqlite3_finalize( databaseStmt );
+ sqlite3_finalize( stmtSelectLastModif );
return false;
}
bool QgsOSMDataProvider::isDatabaseCompatibleWithPlugin()
{
- QString cmd = QString( "SELECT val FROM meta WHERE key='osm-plugin-version';" );
- QByteArray cmd_bytes = cmd.toAscii();
- const char *ptr = cmd_bytes.data();
+ char sqlSelectPluginVer[] = "SELECT val FROM meta WHERE key='osm-plugin-version';";
+ sqlite3_stmt *stmtSelectPluginVer;
- sqlite3_stmt *databaseStmt;
- if ( sqlite3_prepare_v2( mDatabase, ptr, cmd_bytes.size(), &databaseStmt, 0 ) == SQLITE_OK )
+ if ( sqlite3_prepare_v2( mDatabase, sqlSelectPluginVer, sizeof(sqlSelectPluginVer), &stmtSelectPluginVer, 0 ) == SQLITE_OK )
{
- if ( sqlite3_step( databaseStmt ) == SQLITE_ROW )
+ if ( sqlite3_step( stmtSelectPluginVer ) == SQLITE_ROW )
{
- QString osmPluginVersion = ( const char * ) sqlite3_column_text( databaseStmt, 0 );
+ QString osmPluginVersion = ( const char * ) sqlite3_column_text( stmtSelectPluginVer, 0 );
- if ( osmPluginVersion == PLUGIN_VERSION )
+ // each OSM database schema carry info on version of QGIS OSM plugin from which database was created;
+ // this provider must be of the same version to be able to manage OSM data correctly
+ if ( osmPluginVersion == PROVIDER_VERSION )
{
- sqlite3_finalize( databaseStmt );
+ sqlite3_finalize( stmtSelectPluginVer );
return true;
}
}
}
// destroy database statement
- sqlite3_finalize( databaseStmt );
+ sqlite3_finalize( stmtSelectPluginVer );
return false;
}
@@ -326,10 +392,11 @@
bool fetchGeometry,
bool useIntersect )
{
- // clear
+ // re-initialization
delete mSelectionRectangleGeom;
if ( mDatabaseStmt )
- sqlite3_finalize( mDatabaseStmt );
+ // we must reset sqlite3 statement after recent selection - make it ready for next features selection
+ sqlite3_reset( mDatabaseStmt );
// store list of attributes to fetch, rectangle of area, geometry, etc.
mSelectionRectangle = rect;
@@ -340,89 +407,90 @@
mFetchGeom = fetchGeometry;
mSelectUseIntersect = useIntersect;
- QString cmd;
- // select data from sqlite3 database
+ if ( mSelectionRectangle.isEmpty() )
+ {
+ // we want to select all features from OSM data; we will use mSelectFeatsStmt
+ // sqlite3 statement that is well prepared for this purpose
+ mDatabaseStmt = mSelectFeatsStmt;
+ return;
+ }
+
+ // we want to select features from specified boundary; we will use mSelectFeatsInStmt
+ // sqlite3 statement that is well prepared for this purpose
+ mDatabaseStmt = mSelectFeatsInStmt;
+
if ( mFeatureType == PointType )
{
- // prepare select: get all the NODE identifiers from specified area -> future calls of nextFeature () will pick them up one-by-one
- cmd = QString( "SELECT id, lat, lon, timestamp, user FROM node WHERE usage=0 AND status<>'R' AND u=1" );
-
- if ( !mSelectionRectangle.isEmpty() )
- {
- cmd += QString( " AND lat>=%1 AND lat<=%2 AND lon>=%3 AND lon<=%4;" )
- .arg( mSelectionRectangle.yMinimum(), 0, 'f', 20 )
- .arg( mSelectionRectangle.yMaximum(), 0, 'f', 20 )
- .arg( mSelectionRectangle.xMinimum(), 0, 'f', 20 )
- .arg( mSelectionRectangle.xMaximum(), 0, 'f', 20 );
- }
+ // binding variables (boundary) for points selection!
+ sqlite3_bind_double( mDatabaseStmt, 1, mSelectionRectangle.yMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 2, mSelectionRectangle.yMaximum() );
+ sqlite3_bind_double( mDatabaseStmt, 3, mSelectionRectangle.xMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 4, mSelectionRectangle.xMaximum() );
}
else if ( mFeatureType == LineType )
{
- cmd = "SELECT w.id, w.wkb, w.timestamp, w.user FROM way w WHERE w.closed=0 AND w.status<>'R' AND w.u=1";
+ // binding variables (boundary) for lines selection!
+ sqlite3_bind_double( mDatabaseStmt, 1, mSelectionRectangle.yMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 2, mSelectionRectangle.yMaximum() );
+ sqlite3_bind_double( mDatabaseStmt, 3, mSelectionRectangle.yMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 4, mSelectionRectangle.yMaximum() );
+ sqlite3_bind_double( mDatabaseStmt, 5, mSelectionRectangle.yMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 6, mSelectionRectangle.yMaximum() );
- if ( !mSelectionRectangle.isEmpty() )
- {
- cmd += QString( " AND (((w.max_lat between %1 AND %2) OR (w.min_lat between %1 AND %2) OR (w.min_lat<%1 AND w.max_lat>%2)) OR ((w.max_lon between %3 AND %4) OR (w.min_lon between %3 AND %4) OR (w.min_lon<%3 AND w.max_lon>%4)));" )
- .arg( mSelectionRectangle.yMinimum(), 0, 'f', 20 )
- .arg( mSelectionRectangle.yMaximum(), 0, 'f', 20 )
- .arg( mSelectionRectangle.xMinimum(), 0, 'f', 20 )
- .arg( mSelectionRectangle.xMaximum(), 0, 'f', 20 );
- }
+ sqlite3_bind_double( mDatabaseStmt, 7, mSelectionRectangle.xMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 8, mSelectionRectangle.xMaximum() );
+ sqlite3_bind_double( mDatabaseStmt, 9, mSelectionRectangle.xMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 10, mSelectionRectangle.xMaximum() );
+ sqlite3_bind_double( mDatabaseStmt, 11, mSelectionRectangle.xMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 12, mSelectionRectangle.xMaximum() );
}
- else if ( mFeatureType == PolygonType )
+ else // mFeatureType == PolygonType
{
- cmd = "SELECT w.id, w.wkb, w.timestamp, w.user FROM way w WHERE w.closed=1 AND w.status<>'R' AND w.u=1";
+ // binding variables (boundary) for polygons selection!
+ sqlite3_bind_double( mDatabaseStmt, 1, mSelectionRectangle.yMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 2, mSelectionRectangle.yMaximum() );
+ sqlite3_bind_double( mDatabaseStmt, 3, mSelectionRectangle.yMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 4, mSelectionRectangle.yMaximum() );
+ sqlite3_bind_double( mDatabaseStmt, 5, mSelectionRectangle.yMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 6, mSelectionRectangle.yMaximum() );
- if ( !mSelectionRectangle.isEmpty() )
- {
- cmd += QString( " AND (((w.max_lat between %1 AND %2) OR (w.min_lat between %1 AND %2) OR (w.min_lat<%1 AND w.max_lat>%2)) OR ((w.max_lon between %3 AND %4) OR (w.min_lon between %3 AND %4) OR (w.min_lon<%3 AND w.max_lon>%4)));" )
- .arg( mSelectionRectangle.yMinimum(), 0, 'f', 20 )
- .arg( mSelectionRectangle.yMaximum(), 0, 'f', 20 )
- .arg( mSelectionRectangle.xMinimum(), 0, 'f', 20 )
- .arg( mSelectionRectangle.xMaximum(), 0, 'f', 20 );
- }
+ sqlite3_bind_double( mDatabaseStmt, 7, mSelectionRectangle.xMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 8, mSelectionRectangle.xMaximum() );
+ sqlite3_bind_double( mDatabaseStmt, 9, mSelectionRectangle.xMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 10, mSelectionRectangle.xMaximum() );
+ sqlite3_bind_double( mDatabaseStmt, 11, mSelectionRectangle.xMinimum() );
+ sqlite3_bind_double( mDatabaseStmt, 12, mSelectionRectangle.xMaximum() );
}
-
- // just conversion "cmd" to "const char*"
- QByteArray cmd_bytes = cmd.toAscii();
- const char *ptr = cmd_bytes.data();
-
- if ( sqlite3_prepare_v2( mDatabase, ptr, cmd_bytes.size(), &mDatabaseStmt, 0 ) != SQLITE_OK )
- {
- QgsDebugMsg( "Selecting object information failed." );
- return;
- }
- QgsDebugMsg( QString( "SELECTING FEATURES OF TYPE %1." ).arg( mFeatureType ) );
- QgsDebugMsg( cmd );
}
int QgsOSMDataProvider::wayMemberCount( int wayId )
{
- // prepare select: get all the WAY members
- QString cmd = QString( "SELECT count(n.id) FROM way_member wm, node n WHERE wm.way_id=%1 AND wm.node_id=n.id AND wm.u=1 AND n.u=1;" )
- .arg( wayId );
+ // prepare select: get count of all the WAY members
+ char sqlWayMemberCnt[] = "SELECT count(n.id) FROM way_member wm, node n WHERE wm.way_id=? AND wm.node_id=n.id AND wm.u=1 AND n.u=1;";
+ sqlite3_stmt *stmtWayMemberCnt;
- // just conversion "cmd" to "const char*"
- QByteArray cmd_bytes = cmd.toAscii();
- const char *ptr = cmd_bytes.data();
-
- sqlite3_stmt *databaseStmt;
- if ( sqlite3_prepare_v2( mDatabase, ptr, cmd_bytes.size(), &databaseStmt, 0 ) != SQLITE_OK )
+ if ( sqlite3_prepare_v2( mDatabase, sqlWayMemberCnt, sizeof(sqlWayMemberCnt), &stmtWayMemberCnt, 0 ) != SQLITE_OK )
{
- QgsDebugMsg( "Selecting way members failed." );
+ QgsDebugMsg( "sqlite3 statement for selecting waymember count - prepare failed." );
+ sqlite3_finalize( stmtWayMemberCnt );
return -1;
}
- if ( sqlite3_step( databaseStmt ) != SQLITE_ROW )
+ // bind the way identifier
+ sqlite3_bind_int( stmtWayMemberCnt, 1, wayId );
+
+ if ( sqlite3_step( stmtWayMemberCnt ) != SQLITE_ROW )
{
- QgsDebugMsg( "Cannot find out way members count." );
+ QgsDebugMsg( "Cannot get number of way members." );
+ sqlite3_finalize( stmtWayMemberCnt );
return -1;
}
- int wayMemberCnt = sqlite3_column_int( databaseStmt, 0 );
+
+ // getting the result
+ int wayMemberCnt = sqlite3_column_int( stmtWayMemberCnt, 0 );
// destroy database statement
- sqlite3_finalize( databaseStmt );
-
+ sqlite3_finalize( stmtWayMemberCnt );
return wayMemberCnt;
}
@@ -462,8 +530,6 @@
bool fetchGeometry,
QgsAttributeList fetchAttributes )
{
-//QgsDebugMsg(QString("!!! Asking for feature:%1.").arg(featureId));
-
// load exact feature from sqlite3 database
if ( mFeatureType == PointType )
{
@@ -513,11 +579,11 @@
if ( fetchGeometry )
{
char* geo = new char[21];
- std::memset( geo, 0, 21 );
+ memset( geo, 0, 21 );
geo[0] = QgsApplication::endian();
geo[geo[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBPoint;
- std::memcpy( geo + 5, &selLon, sizeof( double ) );
- std::memcpy( geo + 13, &selLat, sizeof( double ) );
+ memcpy( geo + 5, &selLon, sizeof( double ) );
+ memcpy( geo + 13, &selLat, sizeof( double ) );
feature.setGeometryAndOwnership(( unsigned char * )geo, 24 ); // 24 is size of wkb point structure!
}
@@ -532,8 +598,7 @@
case UserAttr:
feature.addAttribute( UserAttr, QString::fromUtf8( selUser ) ); break;
case TagAttr:
- feature.addAttribute( TagAttr, tagsForObject( "node", selId ) );
- break;
+ feature.addAttribute( TagAttr, tagsForObject( "node", selId ) ); break;
default: // suppose it's a custom tag
if ( *iter >= CustomTagAttr && *iter < CustomTagAttr + mCustomTagsList.count() )
@@ -679,7 +744,8 @@
else
{
// tag wasn't found
- //QgsDebugMsg(QString("tag for object failed (%1): type %2 id %3 tag %4").arg(rc).arg(type).arg(id).arg(tagKey));
+ sqlite3_reset( mCustomTagsStmt ); // make ready for next retrieval
+ return "";
}
sqlite3_reset( mCustomTagsStmt ); // make ready for next retrieval
@@ -761,10 +827,8 @@
if ( mFeatureType == PointType )
sqlite3_prepare_v2( mDatabase, "SELECT COUNT(*) FROM node where usage=0", -1, &countStmt, 0 );
else if ( mFeatureType == LineType )
-// sqlite3_prepare_v2(mDatabase, "SELECT COUNT(*) FROM way WHERE closed=0", -1, &countStmt, 0);
sqlite3_prepare_v2( mDatabase, "SELECT count(*) FROM way w WHERE w.closed=0 AND w.status<>'R' AND w.u=1", -1, &countStmt, 0 );
else if ( mFeatureType == PolygonType )
-// sqlite3_prepare_v2(mDatabase, "SELECT COUNT(*) FROM way WHERE closed=1", -1, &countStmt, 0);
sqlite3_prepare_v2( mDatabase, "SELECT count(*) FROM way w WHERE w.closed=1 AND w.status<>'R' AND w.u=1", -1, &countStmt, 0 );
else return -1;
@@ -772,7 +836,6 @@
cnt = sqlite3_column_int( countStmt, 0 );
sqlite3_finalize( countStmt );
- QgsDebugMsg( QString( "Type:%1,FeatureCnt:%2" ).arg( mFeatureType ).arg( cnt ) );
return cnt;
}
@@ -946,11 +1009,11 @@
( *geo ) = new char[9 + 16 * memberCnt];
( *geolen ) = 9 + 16 * memberCnt;
- std::memset(( *geo ), 0, 9 + 16 * memberCnt );
+ memset(( *geo ), 0, 9 + 16 * memberCnt );
( *geo )[0] = QgsApplication::endian();
( *geo )[( *geo )[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBLineString;
- std::memcpy(( *geo ) + 5, &memberCnt, 4 );
+ memcpy(( *geo ) + 5, &memberCnt, 4 );
sqlite3_bind_int( stmtSelectMembers, 1, wayId );
@@ -972,8 +1035,8 @@
if ( selLat > maxLat ) maxLat = selLat;
if ( selLon > maxLon ) maxLon = selLon;
- std::memcpy(( *geo ) + 9 + 16 * i, &selLon, sizeof( double ) );
- std::memcpy(( *geo ) + 9 + 16 * i + 8, &selLat, sizeof( double ) );
+ memcpy(( *geo ) + 9 + 16 * i, &selLon, sizeof( double ) );
+ memcpy(( *geo ) + 9 + 16 * i + 8, &selLat, sizeof( double ) );
i++;
}
@@ -986,11 +1049,11 @@
memberCnt++;
( *geo ) = new char[13 + 16 * memberCnt];
( *geolen ) = 13 + 16 * memberCnt;
- std::memset(( *geo ), 0, 13 + 16 * memberCnt );
+ memset(( *geo ), 0, 13 + 16 * memberCnt );
( *geo )[0] = QgsApplication::endian();
( *geo )[( *geo )[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBPolygon;
- std::memcpy(( *geo ) + 5, &ringsCnt, 4 );
- std::memcpy(( *geo ) + 9, &memberCnt, 4 );
+ memcpy(( *geo ) + 5, &ringsCnt, 4 );
+ memcpy(( *geo ) + 9, &memberCnt, 4 );
sqlite3_bind_int( stmtSelectMembers, 1, wayId );
@@ -1014,8 +1077,8 @@
if ( selLat > maxLat ) maxLat = selLat;
if ( selLon > maxLon ) maxLon = selLon;
- std::memcpy(( *geo ) + 13 + 16 * i, &selLon, sizeof( double ) );
- std::memcpy(( *geo ) + 13 + 16 * i + 8, &selLat, sizeof( double ) );
+ memcpy(( *geo ) + 13 + 16 * i, &selLon, sizeof( double ) );
+ memcpy(( *geo ) + 13 + 16 * i + 8, &selLat, sizeof( double ) );
if ( firstLat == -1000.0 )
firstLat = selLat;
@@ -1024,8 +1087,8 @@
i++;
}
// add last polygon line
- std::memcpy(( *geo ) + 13 + 16 * i, &firstLon, sizeof( double ) );
- std::memcpy(( *geo ) + 13 + 16 * i + 8, &firstLat, sizeof( double ) );
+ memcpy(( *geo ) + 13 + 16 * i, &firstLon, sizeof( double ) );
+ memcpy(( *geo ) + 13 + 16 * i + 8, &firstLat, sizeof( double ) );
sqlite3_bind_blob( stmtUpdateWay, 1, ( *geo ), 13 + 16 * memberCnt, SQLITE_TRANSIENT );
}
@@ -1277,7 +1340,6 @@
return false;
}
-// if (mInitObserver) mInitObserver->setProperty("osm_status", QVariant("Running post-parsing actions."));
postparsing();
QgsDebugMsg( "Postprocessing complete." );
@@ -1298,17 +1360,17 @@
if ( sqlite3_exec( mDatabase, ptr, 0, 0, 0 ) != SQLITE_OK )
{
- cout << "Storing osm-file-last-modified info into database failed." << endl;
+ QgsDebugMsg("Storing osm-file-last-modified info into database failed.");
// its not fatal situation, lets continue..
}
- QString cmd2 = "INSERT INTO meta ( key, val ) VALUES ('osm-plugin-version','" + PLUGIN_VERSION + "');";
+ QString cmd2 = "INSERT INTO meta ( key, val ) VALUES ('osm-plugin-version','" + PROVIDER_VERSION + "');";
QByteArray cmd_bytes2 = cmd2.toAscii();
const char *ptr2 = cmd_bytes2.data();
if ( sqlite3_exec( mDatabase, ptr2, 0, 0, 0 ) != SQLITE_OK )
{
- cout << "Storing osm-plugin-version info into database failed." << endl;
+ QgsDebugMsg("Storing osm-plugin-version info into database failed.");
return false;
}
@@ -1326,7 +1388,7 @@
if ( sqlite3_exec( mDatabase, ptr3, 0, 0, 0 ) != SQLITE_OK )
{
- cout << "Storing default area boundaries information into database failed." << endl;
+ QgsDebugMsg("Storing default area boundaries information into database failed.");
// its not critical situation
}
Modified: trunk/qgis/src/providers/osm/osmprovider.h
===================================================================
--- trunk/qgis/src/providers/osm/osmprovider.h 2009-08-14 12:12:56 UTC (rev 11375)
+++ trunk/qgis/src/providers/osm/osmprovider.h 2009-08-14 14:09:51 UTC (rev 11376)
@@ -18,13 +18,15 @@
#include <QFile>
-
+/**
+ * Quantum GIS provider for OpenStreetMap data.
+ */
class QgsOSMDataProvider: public QgsVectorDataProvider
{
private:
- //! provider can manage features with one of three geometry types; variable determines feature type of this provider
+ //! provider manages features with one of three geometry types; variable determines feature type of this provider
enum { PointType, LineType, PolygonType } mFeatureType;
//! supported feature attributes
@@ -71,6 +73,12 @@
//! pointer to main sqlite3 database statement object; this statement serves to select OSM data
sqlite3_stmt *mDatabaseStmt;
+ //! pointer to main sqlite3 database statement object; this statement serves to select OSM data
+ sqlite3_stmt *mSelectFeatsStmt;
+
+ //! pointer to main sqlite3 db stmt object; this stmt serves to select OSM data from some boundary
+ sqlite3_stmt *mSelectFeatsInStmt;
+
//! sqlite3 database statement ready to select all feature tags
sqlite3_stmt *mTagsStmt;
@@ -306,19 +314,7 @@
*/
bool removeIncorrectWays();
-
/**
- * This function is part of postparsing. OpenStreetMaps nodes have to be divided in two categories here for better manipulation.
- * First category is "significant OSM nodes" - these nodes are loaded to Point vector layer and hold some significant information (in tags),
- * except the fact that they may be parts of ways geometries. The second category are "not significant OSM nodes". These are considered
- * to be a part of some way geometry only but nothing more. These nodes are not loaded to Point layer, they don't have any significant tags
- * like "name","ref",etc; OSM plugin even doesn't care of these nodes when some way geometry is changing. Plugin will just remove
- * all not significant nodes of that way and will create new ones instead of them.
- * @return true in case of success and false in case of failure
- */
- bool splitNodes();
-
- /**
* This function performs postprocessing after OSM file parsing.
*
* Parsing has stored all information into database, but such database schema is not optimal e.g. for way selection,
Modified: trunk/qgis/src/providers/osm/osmrenderer.cpp
===================================================================
--- trunk/qgis/src/providers/osm/osmrenderer.cpp 2009-08-14 12:12:56 UTC (rev 11375)
+++ trunk/qgis/src/providers/osm/osmrenderer.cpp 2009-08-14 14:09:51 UTC (rev 11376)
@@ -14,8 +14,6 @@
#include "osmrenderer.h"
-#include <iostream>
-
#include "qgslogger.h"
#include "qgsapplication.h"
#include "qgsgeometry.h"
@@ -87,14 +85,12 @@
bool OsmRenderer::willRenderFeature( QgsFeature *f )
{
- // todo: return what?
return true;
}
void OsmRenderer::renderFeature( QgsRenderContext &renderContext, QgsFeature& f, QImage* pic, bool selected, double opacity )
{
-// QgsDebugMsg("RENDERING FEAT:" + f.id());
QPainter* p = renderContext.painter();
QgsAttributeMap attr_map = f.attributeMap();
QMap<QString, QString> tags = parse_tags( attr_map[2].toString() );
@@ -102,7 +98,6 @@
if ( mGeomType == QGis::Line )
{
QPen pen = osmstyle.get_pen( tags );
- QColor penColor = pen.color();
p->setPen( osmstyle.get_pen( tags ) );
p->setOpacity( opacity );
}
Modified: trunk/qgis/src/providers/osm/osmrenderer.h
===================================================================
--- trunk/qgis/src/providers/osm/osmrenderer.h 2009-08-14 12:12:56 UTC (rev 11375)
+++ trunk/qgis/src/providers/osm/osmrenderer.h 2009-08-14 14:09:51 UTC (rev 11376)
@@ -12,66 +12,121 @@
* *
***************************************************************************/
-#include <QFile>
#include <QString>
-#include <sqlite3.h>
-#include <iostream>
+#include <QPen>
#include "qgsrenderer.h"
#include "qgsfeature.h"
#include "osmstyle.h"
-using namespace std;
-
/**
* Quantum GIS renderer for OpenStreetMap vector layers.
*/
class OsmRenderer : public QgsRenderer
{
public:
- // Object construction
+ /**
+ * Object construction.
+ * @param geometryType supported geometry type; point, line or polygon
+ * @param styleFileName name of file with OSM stylesheet
+ */
OsmRenderer( QGis::GeometryType geometryType, QString styleFileName );
-// ~OsmRenderer();
+ /**
+ * Function parses concatenated tags from string to map.
+ * @param tags concatenation of tags in form: "key1"="val1","key2"="val2","key3"="val3"
+ * @return map of tag pairs from given concatenation
+ */
QMap<QString, QString> parse_tags( QString tags );
- // ??? Determines if a feature will be rendered or not.
+ /**
+ * Determines if a feature will be rendered or not.
+ * @param f feature object
+ * @return true if a feature will be rendered; false otherwise; in this implementation function always returns True
+ */
bool willRenderFeature( QgsFeature *f );
- // A vector layer passes features to a renderer object to change the brush and pen of the qpainter.
- void renderFeature( QgsRenderContext &renderContext, QgsFeature& f, QImage* pic, bool selected, double opacity = 1.0 );
+ /**
+ * Through calling of this function a vector layer passes features to a renderer object
+ * to change the brush and pen of the qpainter.
+ * @param p pointer to QPainter object that should be changed
+ * @param f feature object
+ * @param pic pointer to QImage object - image that will be displayed on map in place of the feature
+ * @param selected true if feature is selected in qgis - ignored here (osm plugin uses its own way of feature identification and selection)
+ * @param widthScale ignored here
+ * @param rasterScaleFactor ignored here
+ */
+ void renderFeature( QgsRenderContext& renderContext, QgsFeature& f, QImage* pic, bool selected, double opacity = 1.0 );
- // Reads the renderer configuration from an XML file.
+ /**
+ * Reads the renderer configuration from an XML file.
+ * Not implemented!
+ * @param rnode
+ * @param vl
+ */
int readXML( const QDomNode &rnode, QgsVectorLayer &vl );
- // Writes the contents of the renderer to a configuration file @ return true in case of success.
+ /**
+ * Writes the contents of the renderer to a configuration file.
+ * Not implemented!
+ * @param layer_node
+ * @param document
+ * @param vl
+ * @return true in case of success.
+ */
bool writeXML( QDomNode &layer_node, QDomDocument &document, const QgsVectorLayer &vl ) const;
- // Returns true, if attribute values are used by the renderer and false otherwise.
+ /**
+ * Returns true, if attribute values are used by the renderer and false otherwise.
+ * In case of OSM renderer attributes are always used for feature rendering!
+ * @return true anytime
+ */
bool needsAttributes() const;
- // Returns a list with indexes of classification attributes.
+ /**
+ * Returns a list with indexes of classification attributes.
+ * @return list with indexes of classification attributes
+ */
QgsAttributeList classificationAttributes() const;
- // Returns the renderers name.
+ /**
+ * Returns the name of this renderer.
+ * @return the name of this renderer
+ */
QString name() const;
- // Return symbology items.
+ /**
+ * Return symbology items.
+ * Not implemented!
+ * @return symbology items
+ */
const QList< QgsSymbol * > symbols() const;
- //Returns a copy of the renderer (a deep copy on the heap).
+ /**
+ * Returns a copy of the renderer (a deep copy on the heap).
+ * Not implemented!
+ * @return a copy of the renderer (a deep copy on the heap)
+ */
QgsRenderer *clone() const;
- // ??? Returns true if this renderer returns a pixmap in the render method
+ /**
+ * Returns true if this renderer returns a pixmap in the render method.
+ * @return false anytime
+ */
bool containsPixmap() const;
- // ??? Returns true if this renderer uses its own transparency settings
+ /**
+ * Returns true if this renderer uses its own transparency settings.
+ * @return false anytime
+ */
bool usesTransparency() const;
protected:
-// member variables
+ //! OsmStyle object with info on what type of object will be painted in what style.
OsmStyle osmstyle;
+
+ //! geometry type of features this renderer handles - points, lines or polygons.
QGis::GeometryType mGeomType;
};
Modified: trunk/qgis/src/providers/osm/osmstyle.h
===================================================================
--- trunk/qgis/src/providers/osm/osmstyle.h 2009-08-14 12:12:56 UTC (rev 11375)
+++ trunk/qgis/src/providers/osm/osmstyle.h 2009-08-14 14:09:51 UTC (rev 11376)
@@ -14,31 +14,45 @@
#include <QFile>
#include <QMap>
-#include <QProgressDialog>
+#include <QBrush>
+#include <QImage>
+#include <QPen>
#include <QString>
-#include <QPen>
#include <QXmlDefaultHandler>
#include <QXmlAttributes>
-#include <iostream>
-using namespace std;
-
/**
* Class to represent a paint rule.
+ * Paint rule can be applied to all tags that will match it.
*/
class Rule
{
public:
- // construction, destruction
+ /**
+ * Construction.
+ * @param pKey tag key for which this rule should be applied
+ * @param pVal tag value for which this rule should be applied
+ * @param pPen pen that should be used when applying this rule
+ * @param pBrush brush that should be used when applying this rule
+ * @param pImg image that should be used when applying this rule
+ */
Rule( QString pKey, QString pVal, QPen pPen, QBrush pBrush, QImage pImg )
: key( pKey ), val( pVal ), pen( pPen ), brush( pBrush ), img( pImg ) {};
- // class members
+ //! tag key for which this rule should be applied
QString key;
+
+ //! tag value for which this rule should be applied
QString val;
+
+ //! pen that should be used when applying this rule
QPen pen;
+
+ //! brush that should be used when applying this rule
QBrush brush;
+
+ //! image that should be used when applying this rule
QImage img;
};
@@ -49,25 +63,69 @@
class OsmStyle
{
public:
+ /**
+ * Construction.
+ * @param filename name of the file with stylesheet information
+ */
OsmStyle( QString filename );
+
+ /**
+ * Destruction.
+ */
~OsmStyle();
- QList<Rule> rules_line;
- QList<Rule> rules_polygon;
- QList<Rule> rules_point;
-
-
+ /**
+ * Function to parse line of input file and create 'Line' rule in this way.
+ * @param line line of input file
+ */
void parse_rule_line( QString line );
+ /**
+ * Function to parse line of input file and create 'Polygon' rule in this way.
+ * @param line line of input file
+ */
void parse_rule_polygon( QString line );
+ /**
+ * Function to parse line of input file and create 'Point' rule in this way.
+ * @param line line of input file
+ */
void parse_rule_point( QString line );
+ /**
+ * Function helps to display lines.
+ * It gets list of all tags of some line, goes through all Line paint rules and returns pen,
+ * that is most suitable for line with such tags.
+ * @param line line of input file
+ */
QPen get_pen( QMap<QString, QString> tags );
- QPen get_pen_brush( QMap<QString, QString> tags, QBrush &brush ); // todo: return both pen and brush
+ /**
+ * Function helps to display polygons.
+ * It gets list of all tags of some polygon, goes through all Polygon paint rules and returns pen and brush,
+ * that are most suitable for polygon with such tags.
+ * @param line line of input file
+ */
+ QPen get_pen_brush( QMap<QString, QString> tags, QBrush &brush );
+ /**
+ * Function helps to display points.
+ * It gets list of all tags of some point, goes through all Point paint rules and returns image,
+ * that is most suitable for point with such tags.
+ * @param line line of input file
+ */
QImage get_image( QMap<QString, QString> tags );
+
+ private:
+
+ //! list of all rules for 'Lines'
+ QList<Rule> rules_line;
+
+ //! list of all rules for 'Polygon'
+ QList<Rule> rules_polygon;
+
+ //! list of all rules for 'Point'
+ QList<Rule> rules_point;
};
More information about the QGIS-commit
mailing list