[QGIS Commit] r9191 - in trunk/qgis/src/plugins: . ogr_converter

svn_qgis at osgeo.org svn_qgis at osgeo.org
Wed Aug 27 09:29:01 EDT 2008


Author: mhugent
Date: 2008-08-27 09:29:01 -0400 (Wed, 27 Aug 2008)
New Revision: 9191

Added:
   trunk/qgis/src/plugins/ogr_converter/
   trunk/qgis/src/plugins/ogr_converter/CMakeLists.txt
   trunk/qgis/src/plugins/ogr_converter/README
   trunk/qgis/src/plugins/ogr_converter/dialog.cpp
   trunk/qgis/src/plugins/ogr_converter/dialog.h
   trunk/qgis/src/plugins/ogr_converter/format.cpp
   trunk/qgis/src/plugins/ogr_converter/format.h
   trunk/qgis/src/plugins/ogr_converter/ogrconverter.png
   trunk/qgis/src/plugins/ogr_converter/ogrconverter.qrc
   trunk/qgis/src/plugins/ogr_converter/ogrconverterguibase.ui
   trunk/qgis/src/plugins/ogr_converter/plugin.cpp
   trunk/qgis/src/plugins/ogr_converter/plugin.h
   trunk/qgis/src/plugins/ogr_converter/translator.cpp
   trunk/qgis/src/plugins/ogr_converter/translator.h
Modified:
   trunk/qgis/src/plugins/CMakeLists.txt
Log:
Ogr converter plugin written by mloskot

Modified: trunk/qgis/src/plugins/CMakeLists.txt
===================================================================
--- trunk/qgis/src/plugins/CMakeLists.txt	2008-08-27 13:21:17 UTC (rev 9190)
+++ trunk/qgis/src/plugins/CMakeLists.txt	2008-08-27 13:29:01 UTC (rev 9191)
@@ -21,4 +21,6 @@
 SUBDIRS (quick_print)
 
 
-SUBDIRS (coordinate_capture dxf2shp_converter) 
\ No newline at end of file
+SUBDIRS (coordinate_capture dxf2shp_converter) 
+
+SUBDIRS (ogr_converter)
\ No newline at end of file

Added: trunk/qgis/src/plugins/ogr_converter/CMakeLists.txt
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/CMakeLists.txt	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/CMakeLists.txt	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,65 @@
+# $Id$
+#
+# CMake configuration file for OGR Converter plugin
+# Author: Mateusz Loskot <mateusz at loskot.net>
+########################################################
+# Files
+
+SET (OGR_CONVERTER_SRCS
+     plugin.cpp
+     dialog.cpp
+     format.cpp
+     translator.cpp
+)
+
+SET (OGR_CONVERTER_UIS ogrconverterguibase.ui)
+
+SET (OGR_CONVERTER_MOC_HDRS
+     plugin.h
+     dialog.h
+)
+
+SET (OGR_CONVERTER_RCCS ogrconverter.qrc)
+
+SET (OGR_CONVERTER_PLUGIN ogrconverterplugin)
+
+########################################################
+# Build
+
+QT4_WRAP_UI (OGR_CONVERTER_UIS_H  ${OGR_CONVERTER_UIS})
+
+QT4_WRAP_CPP (OGR_CONVERTER_MOC_SRCS  ${OGR_CONVERTER_MOC_HDRS})
+
+QT4_ADD_RESOURCES(OGR_CONVERTER_RCC_SRCS ${OGR_CONVERTER_RCCS})
+
+ADD_LIBRARY (${OGR_CONVERTER_PLUGIN} MODULE
+    ${OGR_CONVERTER_SRCS}
+    ${OGR_CONVERTER_MOC_SRCS}
+    ${OGR_CONVERTER_RCC_SRCS}
+    ${OGR_CONVERTER_UIS_H}
+)
+
+INCLUDE_DIRECTORIES (
+    ${CMAKE_CURRENT_BINARY_DIR}
+    ../../core
+    ../../core/raster
+    ../../core/renderer
+    ../../core/symbology
+    ../../gui
+    ..
+    ${GDAL_INCLUDE_DIR}
+)
+
+TARGET_LINK_LIBRARIES(${OGR_CONVERTER_PLUGIN}
+    ${GDAL_LIBRARY}
+    qgis_core
+    qgis_gui
+)
+
+########################################################
+# Install
+
+INSTALL(TARGETS ${OGR_CONVERTER_PLUGIN}
+    RUNTIME DESTINATION ${QGIS_PLUGIN_DIR}
+    LIBRARY DESTINATION ${QGIS_PLUGIN_DIR}
+)

Added: trunk/qgis/src/plugins/ogr_converter/README
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/README	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/README	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,35 @@
+OGR Layer Converter Pluginm, Version 0.1 (Alpha)
+------------------------------------------------------------------------------
+Author: Mateusz Loskot <mateusz at loskot.net>
+
+OGR Layer Converter aims to be a GUI-based implementation of well-known
+ogr2ogr utility from GDAL/OGR package. The plugin translates layers
+between OGR supported formats built-in GDAL/OGR library available for
+particular QGIS installation.
+Built-in formats are listed in drop-down boxes.
+
+Currently, it is possible to translate one selected source
+layer to another OGR format.
+
+Testing appreciated.
+
+------------------------------------------------------------------------------
+ TODO
+------------------------------------------------------------------------------
+translator.h:    // TODO: Implement, currently always overwrite
+translator.h:    // TODO: Append option not supported
+dialog.cpp:// TODO: Add support of QGIS projection selector 
+dialog.cpp:    // TODO: Transformation support
+dialog.cpp:    // TODO: Transformation support
+dialog.cpp:    // TODO: SRS transformation support
+dialog.cpp:    // TODO: Use try-catch to display more meaningful error messages from Translator
+plugin.cpp:    // TODO: Who is responsible for OGR cleanup?
+translator.cpp:    // TODO: RAII for OGR handlers!!!
+translator.cpp:    // TODO: Support translation of all layers from input data source
+translator.cpp:        // TODO: -nlt option support
+translator.cpp:        // TODO: Implement SRS transformation 
+translator.cpp:    // TODO: Append and createion options not implemented
+translator.cpp:    // TODO: RAII for feature handlers!!!
+translator.cpp:        // TODO: Transform feature geometry
+translator.cpp:        // TODO: Skip failures support
+translator.cpp:        // TODO: Add support for creation options

Added: trunk/qgis/src/plugins/ogr_converter/dialog.cpp
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/dialog.cpp	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/dialog.cpp	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,453 @@
+// $Id$
+//////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2008 by Mateusz Loskot <mateusz at loskot.net>
+//
+// 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// qgis::plugin::ogrconv
+#include "dialog.h"
+#include "format.h"
+#include "translator.h"
+// QGIS includes
+#include <qgslogger.h>
+#include <qgscontexthelp.h>
+// TODO: Add support of QGIS projection selector 
+//#include <qgsprojectionselector.h>
+// Qt4
+#include <QtAlgorithms>
+#include <QtDebug>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QSettings>
+#include <QString>
+#include <QStringList>
+#include <QVariant>
+
+namespace qgis { namespace plugin { namespace ogrconv {
+
+// GDAL/OGR loaded into private namespace
+#include <ogr_api.h>
+#include <ogrsf_frmts.h>
+
+Dialog::Dialog(QWidget* parent, Qt::WFlags fl)
+    : QDialog(parent, fl)
+{
+    setupUi(this);
+    populateFormats();
+    resetSrcUi();
+    resetDstUi();
+}
+
+Dialog::~Dialog()
+{
+}
+
+void Dialog::resetSrcUi()
+{
+    // Clear all settings and states
+    inputSrcDataset->clear();
+    // TODO: Transformation support
+    //inputSrcSrs->clear();
+    comboSrcLayer->clear();
+    radioSrcFile->setDisabled(true);
+    radioSrcFile->setChecked(false);
+    radioSrcDirectory->setDisabled(true);
+    radioSrcDirectory->setChecked(false);
+    radioSrcProtocol->setDisabled(true);
+    radioSrcProtocol->setChecked(false);
+
+    // Configure types of input sources
+    unsigned char const& type = mSrcFormat.type();
+
+    if (isFormatType(type, Format::eFile))
+    {
+        radioSrcFile->setDisabled(false);
+        radioSrcFile->setChecked(true);
+    }
+
+    if (isFormatType(type, Format::eDirectory))
+    {
+        radioSrcDirectory->setDisabled(false);
+        if (!radioSrcFile->isEnabled())
+            radioSrcDirectory->setChecked(true);
+    }
+
+    if (isFormatType(type, Format::eProtocol))
+    {
+        radioSrcProtocol->setDisabled(false);
+
+        if (!radioSrcFile->isEnabled() && !radioSrcDirectory->isEnabled())
+        {
+            radioSrcProtocol->setChecked(true);
+            inputSrcDataset->setText(mSrcFormat.protocol());
+        }
+    }
+
+    setButtonState(buttonSelectSrc, isFormatType(type, Format::eProtocol));
+}
+
+void Dialog::resetDstUi()
+{
+    inputDstDataset->clear();
+    // TODO: Transformation support
+    //inputDstSrs->clear();
+    
+    unsigned char const& type = mDstFormat.type();
+    bool isProtocol = isFormatType(type, Format::eProtocol);
+
+    if (isProtocol)
+    {
+        inputDstDataset->setText(mDstFormat.protocol());
+    }
+    
+    setButtonState(buttonSelectDst, isProtocol);
+}
+
+void Dialog::setButtonState(QPushButton* btn, bool isProtocol)
+{
+    Q_CHECK_PTR(btn);
+
+    if (isProtocol)
+    {
+        btn->setText(tr("Connect"));
+    }
+    else
+    {
+        btn->setText(tr("Browse"));
+    }
+}
+
+void Dialog::populateFormats()
+{
+    comboSrcFormats->clear();
+    comboDstFormats->clear();
+    
+    QStringList drvSrcList;
+    QStringList drvDstList;
+    QString drvName;
+
+    if (0 >= OGRGetDriverCount())
+    {
+        OGRRegisterAll(); 
+    }
+    int const drvCount = OGRGetDriverCount();
+
+    for (int i = 0; i < drvCount; ++i)
+    {
+        OGRSFDriverH drv = OGRGetDriver(i);
+        Q_CHECK_PTR(drv);
+        if (0 != drv)
+        {
+            drvName = OGR_Dr_GetName(drv);
+            drvSrcList.append(drvName);
+
+            if (0 != OGR_Dr_TestCapability(drv, ODrCCreateDataSource))
+            {
+                drvDstList.append(drvName);
+            }
+        }
+    }
+
+    qSort(drvSrcList.begin(), drvSrcList.end());
+    qSort(drvDstList.begin(), drvDstList.end());
+    comboSrcFormats->addItems(drvSrcList);
+    comboDstFormats->addItems(drvDstList);
+}
+
+void Dialog::populateLayers(QString const& url)
+{
+    comboSrcLayer->clear();
+
+    OGRDataSourceH ds = OGROpen(url.toAscii().constData(), 0, 0);
+    if (0 != ds)
+    {
+        QString lyrName;
+        QString lyrType;
+
+        int const size = OGR_DS_GetLayerCount(ds);
+        for (int i = 0; i < size; ++i)
+        {
+            OGRLayerH lyr = OGR_DS_GetLayer(ds, i);
+            if (0 != lyr)
+            {
+                OGRFeatureDefnH lyrDef = OGR_L_GetLayerDefn(lyr);
+                Q_ASSERT(0 != lyrDef);
+                
+                lyrName = OGR_FD_GetName(lyrDef);
+                
+                OGRwkbGeometryType const geomType = OGR_FD_GetGeomType(lyrDef);
+                lyrType = OGRGeometryTypeToName(geomType);
+
+                // FIXME: Appending type to layer name prevents from layer finding
+                //comboSrcLayer->addItem(lyrName + " (" + lyrType.toUpper() + ")");
+                comboSrcLayer->addItem(lyrName);
+            }
+        }
+
+        OGR_DS_Destroy(ds);
+    }
+    else
+    {
+        QMessageBox::warning(this,
+                tr("OGR Converter"),
+                tr("Could not establish connection to: '") + url + "'",
+                QMessageBox::Close);
+    }
+}
+
+bool Dialog::testConnection(QString const& url)
+{
+    bool success = false;
+
+    OGRDataSourceH ds = OGROpen(url.toAscii().constData(), 0, 0);
+    if (0 != ds)
+    {
+        success = true;
+        OGR_DS_Destroy(ds);
+    }
+
+    return success;
+}
+
+QString Dialog::openFile()
+{
+    QSettings sets;
+    QString path = QFileDialog::getOpenFileName(this,
+            tr("Open OGR file"),
+            sets.value("/Plugin-OGR/ogr-file", "./").toString(),
+            tr("OGR File Data Source (*.*)"));
+
+    return path;
+}
+
+QString Dialog::openDirectory()
+{
+    QString path = QFileDialog::getExistingDirectory(this,
+            tr("Open Directory"), "",
+            QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
+    
+    return path;
+}
+
+void Dialog::on_buttonBox_accepted()
+{
+    // Validate input settings
+    QString srcUrl(inputSrcDataset->text());
+    QString srcLayer(comboSrcLayer->currentText());
+
+    if (srcUrl.isEmpty())
+    {
+        QMessageBox::warning(this, "OGR Layer Converter",
+                tr("Input OGR dataset is missing!"));
+        return;
+    }
+   
+    if (srcLayer.isEmpty())
+    {
+        QMessageBox::warning(this, "OGR Layer Converter",
+                tr("Input OGR layer name is missing!"));
+        return;
+    }
+
+    // Validate output settings
+    QString dstFormat(comboDstFormats->currentText());
+    QString dstUrl(inputDstDataset->text());
+    QString dstLayer(inputDstLayer->text());
+    if (dstLayer.isEmpty())
+        dstLayer = srcLayer;
+    
+    if (dstFormat.isEmpty())
+    {
+        QMessageBox::warning(this, "OGR Layer Converter",
+                tr("Target OGR format not selected!"));
+        return;
+    }
+ 
+    if (dstUrl.isEmpty())
+    {
+        QMessageBox::warning(this, "OGR Layer Converter",
+                tr("Output OGR dataset is missing!"));
+        return;
+    }
+
+    if (dstLayer.isEmpty())
+    {
+        QMessageBox::warning(this, "OGR Layer Converter",
+                tr("Output OGR layer name is missing!"));
+        return;
+    }
+
+    // TODO: SRS transformation support
+    //QString srcSrs("EPSG:");
+    //QString dstSrs("EPSG:");
+    //srcSrs += inputSrcSrs->text();
+    //dstSrs += inputDstSrs->text();
+
+    // Execute layer translation
+    bool success = false;
+    
+    // TODO: Use try-catch to display more meaningful error messages from Translator
+    Translator worker(srcUrl, dstUrl, dstFormat);
+    worker.setSourceLayer(srcLayer);
+    worker.setTargetLayer(dstLayer);
+    success = worker.translate();
+
+    if (success)
+    {
+        QMessageBox::information(this, "OGR Layer Converter",
+                tr("Successfully translated layer '") + srcLayer + "'");
+    }
+    else
+    {
+        QMessageBox::information(this, "OGR Layer Converter",
+                tr("Failed to translate layer '") + srcLayer + "'");
+    }
+
+    // Close dialog box
+    accept();
+}
+
+void Dialog::on_buttonBox_rejected()
+{
+    reject();
+}
+
+void Dialog::on_buttonBox_helpRequested()
+{
+    QgsContextHelp::run(context_id);
+}
+
+void Dialog::on_radioSrcFile_toggled(bool checked)
+{
+    if (checked)
+    {
+        unsigned char const& type = mSrcFormat.type();
+        Q_ASSERT(isFormatType(type, Format::eFile));
+
+        inputSrcDataset->clear();
+        setButtonState(buttonSelectSrc, isFormatType(type, Format::eProtocol));
+    }
+}
+
+void Dialog::on_radioSrcDirectory_toggled(bool checked)
+{
+    if (checked)
+    {
+        unsigned char const& type = mSrcFormat.type();
+        Q_ASSERT(isFormatType(type, Format::eDirectory));
+
+        inputSrcDataset->clear();
+        setButtonState(buttonSelectSrc, isFormatType(type, Format::eProtocol));
+    }
+}
+
+void Dialog::on_radioSrcProtocol_toggled(bool checked)
+{
+    if (checked)
+    {
+        unsigned char const& type = mSrcFormat.type();
+        Q_ASSERT(isFormatType(type, Format::eProtocol));
+
+        inputSrcDataset->setText(mSrcFormat.protocol());
+        setButtonState(buttonSelectSrc, isFormatType(type, Format::eProtocol));
+    }
+}
+
+void Dialog::on_comboSrcFormats_currentIndexChanged(int index)
+{
+    // Select source data format
+    QString frmtCode = comboSrcFormats->currentText(); 
+    mSrcFormat = mFrmts.find(frmtCode);
+    
+    resetSrcUi();
+}
+
+void Dialog::on_comboDstFormats_currentIndexChanged(int index)
+{
+    // Select destination data format
+    QString frmtCode = comboDstFormats->currentText(); 
+    mDstFormat = mFrmts.find(frmtCode);
+
+    resetDstUi();
+}
+
+void Dialog::on_buttonSelectSrc_clicked()
+{
+    QSettings settings;
+    QString src;
+    
+    if (radioSrcFile->isChecked())
+    {
+        src = openFile();
+    }
+    else if (radioSrcDirectory->isChecked())
+    {
+        src = openDirectory();
+    }
+    else if (radioSrcProtocol->isChecked())
+    {
+        src = inputSrcDataset->text();
+    }
+    else
+    {
+        Q_ASSERT(!"SHOULD NEVER GET HERE");
+    }
+
+    inputSrcDataset->setText(src);
+
+    if (!src.isEmpty())
+    {
+        populateLayers(src);
+    }
+}
+
+void Dialog::on_buttonSelectDst_clicked()
+{
+    QSettings settings;
+    QString dst;
+    QString msg;
+
+    unsigned char const& type = mDstFormat.type();
+    if (isFormatType(type, Format::eProtocol))
+    {
+        dst = inputDstDataset->text();
+
+        if (testConnection(dst))
+        {
+            msg = tr("Successfully connected to: '") + dst + "'";
+        }
+        else
+        {
+            msg = tr("Could not establish connection to: '") + dst + "'";
+        }
+        
+        QMessageBox::information(this, tr("OGR Converter"),
+                msg, QMessageBox::Close);
+    }
+    else if (isFormatType(type, Format::eDirectory))
+    {
+        dst = openDirectory();
+    }
+    else if (isFormatType(type, Format::eFile))
+    {
+        dst = QFileDialog::getSaveFileName(this,
+                tr("Choose a file name to save to"),
+                "output", tr("OGR File Data Source (*.*)"));
+    }
+    else
+    {
+        Q_ASSERT(!"SHOULD NEVER GET HERE");
+    }
+
+    inputDstDataset->setText(dst);
+}
+
+
+}}} // namespace qgis::plugin::ogrconv
+

Added: trunk/qgis/src/plugins/ogr_converter/dialog.h
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/dialog.h	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/dialog.h	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,69 @@
+// $Id$
+//////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2008 by Mateusz Loskot <mateusz at loskot.net>
+//
+// 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef QGIS_PLUGIN_OGRCONV_DIALOG_H_INCLUDED
+#define QGIS_PLUGIN_OGRCONV_DIALOG_H_INCLUDED
+
+// qgis::plugin::ogrconv
+#include "format.h"
+#include <ui_ogrconverterguibase.h>
+// Qt4
+#include <QDialog>
+
+namespace qgis { namespace plugin { namespace ogrconv {
+
+/**
+ at author Mateusz Loskot
+*/
+class Dialog : public QDialog, private Ui::OgrConverterGuiBase
+{
+    Q_OBJECT
+
+public:
+
+    Dialog(QWidget* parent = 0, Qt::WFlags fl = 0);
+    ~Dialog();
+
+private:
+
+    static const int context_id = 0;
+
+    FormatsRegistry mFrmts;
+    Format mSrcFormat;
+    Format mDstFormat;
+
+    void resetSrcUi();
+    void resetDstUi();
+    void setButtonState(QPushButton* btn, bool isProtocol);
+
+    void populateFormats();
+    void populateLayers(QString const& url);
+    bool testConnection(QString const& url);
+    QString openFile();
+    QString openDirectory();
+
+private slots:
+
+    void on_buttonBox_accepted();
+    void on_buttonBox_rejected();
+    void on_buttonBox_helpRequested();
+    void on_radioSrcFile_toggled(bool checked);
+    void on_radioSrcDirectory_toggled(bool checked);
+    void on_radioSrcProtocol_toggled(bool checked);
+    void on_buttonSelectSrc_clicked();
+    void on_buttonSelectDst_clicked();
+    void on_comboSrcFormats_currentIndexChanged(int index);
+    void on_comboDstFormats_currentIndexChanged(int index);
+};
+
+}}} // namespace qgis::plugin::ogrconv
+
+#endif // QGIS_PLUGIN_OGRCONV_DIALOG_H_INCLUDED

Added: trunk/qgis/src/plugins/ogr_converter/format.cpp
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/format.cpp	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/format.cpp	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,117 @@
+// $Id$
+//////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2008 by Mateusz Loskot <mateusz at loskot.net>
+//
+// 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// qgis::plugin::ogrconv
+#include "format.h"
+// Qt4
+#include <QString>
+
+namespace qgis { namespace plugin { namespace ogrconv {
+
+Format::Format()
+{
+}
+
+Format::Format(QString const& c, QString const& n)
+    : mCode(c), mName(n), mTypeFlags(0)
+{
+}
+
+Format::Format(QString const& c, QString const& n, unsigned char const& t)
+    : mCode(c), mName(n), mTypeFlags(t)
+{
+}
+
+Format::Format(QString const& c, QString const& n, QString const& p, unsigned char const& t)
+    : mCode(c), mName(n), mProtocol(p), mTypeFlags(t)
+{
+}
+
+QString const& Format::code() const
+{
+    return mCode;
+}
+
+QString const& Format::name() const
+{
+    return mName;
+}
+
+QString const& Format::protocol() const
+{
+    return mProtocol;
+}
+
+unsigned char const& Format::type() const
+{
+    return mTypeFlags;
+}
+
+
+FormatsRegistry::FormatsRegistry()
+{
+    init();
+}
+
+void FormatsRegistry::add(Format const& frmt)
+{
+    QString code = frmt.code();
+    mFrmts[code] = frmt;
+}
+
+Format const& FormatsRegistry::find(QString const& code)
+{
+    mCache = mFrmts.value(code);
+    return mCache;
+}
+
+void FormatsRegistry::init()
+{
+    add(Format("AVCBin", "Arc/Info Binary Coverage", Format::eFile));
+    add(Format("AVCE00", "Arc/Info .E00 (ASCII) Coverage", Format::eFile));
+    add(Format("BNA", "Atlas BNA", Format::eFile));
+    add(Format("CSV", "Comma Separated Value", Format::eFile | Format::eDirectory));
+    add(Format("DODS", "DODS/OPeNDAP", Format::eFile));
+    add(Format("DGN", "Microstation DGN", Format::eFile));
+    add(Format("ESRI Shapefile", "ESRI Shapefile", Format::eFile | Format::eDirectory));
+    add(Format("FMEObjects Gateway", "FMEObjects Gateway", Format::eFile));
+    add(Format("Geoconcept Text Export", "Geoconcept", Format::eFile));
+    add(Format("GML", "Geography Markup Language", Format::eFile));
+    add(Format("GMT", "GMT ASCII Vectors", Format::eFile));
+    add(Format("GPX", "GPS Exchange Format", Format::eFile));
+    add(Format("GeoJSON", "GeoJSON", Format::eFile)); // FIXME: Format::eProtocol));
+    add(Format("GRASS", "GRASS", Format::eDirectory));
+    add(Format("Informix DataBlade", "IDB", "IDB:", Format::eProtocol));
+    add(Format("Interlis 1", "INTERLIS", Format::eFile));
+    add(Format("Interlis 2", "INTERLIS", Format::eFile));
+    add(Format("Ingres Database", "INGRES", "@driver=ingres,", Format::eProtocol));
+    add(Format("KML", "KML", Format::eFile));
+    add(Format("MapInfo", "MapInfo File", Format::eFile));
+    add(Format("Memory", "Memory", Format::eFile));
+    add(Format("MySQL", "MySQL", "MySQL:", Format::eProtocol));
+    add(Format("ODBC", "Open DataBase Connectivity", "ODBC:", Format::eProtocol));
+    add(Format("OGDI", "Open Geographic Datastore Interface Vectors", "gltp:", Format::eProtocol));
+    add(Format("OCI", "Oracle Spatial", "OCI:", Format::eProtocol));
+    add(Format("PGeo", "ESRI Personal GeoDatabase", "PGeo:", Format::eFile | Format::eProtocol));
+    add(Format("PostgreSQL", "PostgreSQL", "PG:", Format::eProtocol));
+    add(Format("S57", "IHO S-57", Format::eFile));
+    add(Format("SDE", "ESRI ArcSDE", "SDE:", Format::eProtocol));
+    add(Format("SDTS", "SDTS Topological Vector Profile", Format::eFile));
+    add(Format("SQLite", "SQLite Database File", Format::eFile));
+    add(Format("UK.NTF", "UK National Transfer Format", Format::eFile));
+    add(Format("TIGER", "U.S. Census TIGER/Line", Format::eFile));
+    add(Format("VRT", "Virtual Datasource", Format::eFile));
+    add(Format("XPLANE", "X-Plane/Flighgear Aeronautical Data", Format::eFile));
+}
+
+}}} // namespace qgis::plugin::ogrconv
+

Added: trunk/qgis/src/plugins/ogr_converter/format.h
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/format.h	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/format.h	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,76 @@
+// $Id$
+//////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2008 by Mateusz Loskot <mateusz at loskot.net>
+//
+// 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef QGIS_PLUGIN_OGRCONV_FORMATS_H_INCLUDED
+#define QGIS_PLUGIN_OGRCONV_FORMATS_H_INCLUDED
+
+// Qt4
+#include <QMap>
+#include <QString>
+
+namespace qgis { namespace plugin { namespace ogrconv {
+
+class Format
+{
+public:
+
+    enum Type
+    {
+        eUnknown = 0,
+        eFile = 1,
+        eDirectory = 2,
+        eProtocol = 4
+    };
+
+    Format();
+    Format(QString const& c, QString const& n);
+    Format(QString const& c, QString const& n, unsigned char const& t);
+    Format(QString const& c, QString const& n, QString const& p, unsigned char const& t);
+
+    QString const& code() const;
+    QString const& name() const;
+    QString const& protocol() const;
+    unsigned char const& type() const;
+
+private:
+
+    QString mCode;
+    QString mName;
+    QString mProtocol;
+    unsigned char mTypeFlags;
+};
+
+inline bool isFormatType(unsigned char const& frmt, Format::Type const& type)
+{
+    return ((frmt & type) == type);
+}
+
+class FormatsRegistry
+{
+public:
+
+    FormatsRegistry();
+
+    void add(Format const& frmt);
+    Format const&  find(QString const& code);
+
+private:
+
+    void init();
+
+    QMap<QString, Format> mFrmts;
+    Format mCache;
+};
+
+
+}}} // namespace qgis::plugin::ogrconv
+
+#endif // QGIS_PLUGIN_OGRCONV_FORMATS_H_INCLUDED

Added: trunk/qgis/src/plugins/ogr_converter/ogrconverter.png
===================================================================
(Binary files differ)


Property changes on: trunk/qgis/src/plugins/ogr_converter/ogrconverter.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/qgis/src/plugins/ogr_converter/ogrconverter.qrc
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/ogrconverter.qrc	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/ogrconverter.qrc	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/ogrconverter/" >
+        <file>ogrconverter.png</file>
+    </qresource>
+</RCC>

Added: trunk/qgis/src/plugins/ogr_converter/ogrconverterguibase.ui
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/ogrconverterguibase.ui	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/ogrconverterguibase.ui	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,378 @@
+<ui version="4.0" >
+ <class>OgrConverterGuiBase</class>
+ <widget class="QDialog" name="OgrConverterGuiBase" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>521</width>
+    <height>450</height>
+   </rect>
+  </property>
+  <property name="sizePolicy" >
+   <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize" >
+   <size>
+    <width>520</width>
+    <height>450</height>
+   </size>
+  </property>
+  <property name="windowTitle" >
+   <string>OGR Layer Converter</string>
+  </property>
+  <property name="windowIcon" >
+   <iconset>
+    <normaloff/>
+   </iconset>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" >
+   <item row="0" column="0" >
+    <widget class="QGroupBox" name="srcGroupBox" >
+     <property name="title" >
+      <string>Source</string>
+     </property>
+     <widget class="QWidget" name="" >
+      <property name="geometry" >
+       <rect>
+        <x>20</x>
+        <y>30</y>
+        <width>461</width>
+        <height>28</height>
+       </rect>
+      </property>
+      <layout class="QHBoxLayout" name="horizontalLayout" >
+       <item>
+        <widget class="QLabel" name="labelSrcFormat" >
+         <property name="minimumSize" >
+          <size>
+           <width>52</width>
+           <height>22</height>
+          </size>
+         </property>
+         <property name="text" >
+          <string>Format:</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QComboBox" name="comboSrcFormats" >
+         <property name="minimumSize" >
+          <size>
+           <width>200</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maxCount" >
+          <number>200</number>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_3" >
+         <property name="orientation" >
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0" >
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="" >
+      <property name="geometry" >
+       <rect>
+        <x>20</x>
+        <y>70</y>
+        <width>461</width>
+        <height>21</height>
+       </rect>
+      </property>
+      <layout class="QHBoxLayout" name="horizontalLayout_4" >
+       <item>
+        <widget class="QRadioButton" name="radioSrcFile" >
+         <property name="text" >
+          <string>File</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QRadioButton" name="radioSrcDirectory" >
+         <property name="text" >
+          <string>Directory</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QRadioButton" name="radioSrcProtocol" >
+         <property name="text" >
+          <string>Remote source</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="" >
+      <property name="geometry" >
+       <rect>
+        <x>21</x>
+        <y>140</y>
+        <width>461</width>
+        <height>28</height>
+       </rect>
+      </property>
+      <layout class="QHBoxLayout" name="horizontalLayout_2" >
+       <item>
+        <widget class="QLabel" name="labelSrcLayer" >
+         <property name="minimumSize" >
+          <size>
+           <width>52</width>
+           <height>22</height>
+          </size>
+         </property>
+         <property name="text" >
+          <string>Layer:</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QComboBox" name="comboSrcLayer" >
+         <property name="minimumSize" >
+          <size>
+           <width>300</width>
+           <height>0</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_2" >
+         <property name="orientation" >
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0" >
+          <size>
+           <width>88</width>
+           <height>17</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="" >
+      <property name="geometry" >
+       <rect>
+        <x>21</x>
+        <y>100</y>
+        <width>457</width>
+        <height>34</height>
+       </rect>
+      </property>
+      <layout class="QHBoxLayout" name="horizontalLayout_6" >
+       <item>
+        <widget class="QLabel" name="labelSrcDataset" >
+         <property name="text" >
+          <string>Dataset:</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="inputSrcDataset" >
+         <property name="minimumSize" >
+          <size>
+           <width>300</width>
+           <height>0</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="buttonSelectSrc" >
+         <property name="minimumSize" >
+          <size>
+           <width>90</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="text" >
+          <string>Browse</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item row="2" column="0" >
+    <widget class="QDialogButtonBox" name="buttonBox" >
+     <property name="standardButtons" >
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0" >
+    <widget class="QGroupBox" name="dstGroupBox" >
+     <property name="title" >
+      <string>Target</string>
+     </property>
+     <widget class="QWidget" name="" >
+      <property name="geometry" >
+       <rect>
+        <x>22</x>
+        <y>33</y>
+        <width>454</width>
+        <height>28</height>
+       </rect>
+      </property>
+      <layout class="QHBoxLayout" name="horizontalLayout_3" >
+       <item>
+        <widget class="QLabel" name="labelDstFormat" >
+         <property name="minimumSize" >
+          <size>
+           <width>52</width>
+           <height>22</height>
+          </size>
+         </property>
+         <property name="text" >
+          <string>Format:</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QComboBox" name="comboDstFormats" >
+         <property name="minimumSize" >
+          <size>
+           <width>300</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maxCount" >
+          <number>200</number>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer" >
+         <property name="orientation" >
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0" >
+          <size>
+           <width>88</width>
+           <height>17</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="" >
+      <property name="geometry" >
+       <rect>
+        <x>20</x>
+        <y>71</y>
+        <width>457</width>
+        <height>34</height>
+       </rect>
+      </property>
+      <layout class="QHBoxLayout" name="horizontalLayout_7" >
+       <item>
+        <widget class="QLabel" name="labelDstDataset" >
+         <property name="text" >
+          <string>Dataset:</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="inputDstDataset" >
+         <property name="minimumSize" >
+          <size>
+           <width>300</width>
+           <height>0</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="buttonSelectDst" >
+         <property name="minimumSize" >
+          <size>
+           <width>90</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="text" >
+          <string>Browse</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="" >
+      <property name="geometry" >
+       <rect>
+        <x>20</x>
+        <y>110</y>
+        <width>451</width>
+        <height>24</height>
+       </rect>
+      </property>
+      <layout class="QHBoxLayout" name="horizontalLayout_8" >
+       <item>
+        <widget class="QLabel" name="labelDstLayer" >
+         <property name="minimumSize" >
+          <size>
+           <width>52</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="text" >
+          <string>Layer:</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLineEdit" name="inputDstLayer" >
+         <property name="minimumSize" >
+          <size>
+           <width>300</width>
+           <height>0</height>
+          </size>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_5" >
+         <property name="orientation" >
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0" >
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <tabstops>
+  <tabstop>inputSrcDataset</tabstop>
+  <tabstop>buttonSelectSrc</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>

Added: trunk/qgis/src/plugins/ogr_converter/plugin.cpp
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/plugin.cpp	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/plugin.cpp	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,149 @@
+// $Id$
+//////////////////////////////////////////////////////////////////////////////
+//
+// begin                : Aug 24, 2008
+// copyright            : (C) 2008 by Mateusz Loskot
+// email                : mateusz at loskot.net
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// qgis::plugin::ogrconv
+#include "plugin.h"
+#include "dialog.h"
+// QGIS
+#include <qgisinterface.h>
+#include <qgisgui.h>
+#include <qgslogger.h>
+// Qt
+#include <QAction>
+#include <QToolBar>
+// std
+#include <cassert>
+
+namespace qgis { namespace plugin { namespace ogrconv {
+
+// GDAL/OGR loaded into private namesapce
+#include <ogr_api.h>
+
+static const char * const sIdent = "$Id$";
+static const QString sName = QObject::tr("OGR Layer Converter");
+static const QString sDescription = QObject::tr("Translates vector layers between formats supported by OGR library");
+static const QString sPluginVersion = QObject::tr("Version 0.1");
+static const QgisPlugin::PLUGINTYPE sPluginType = QgisPlugin::UI;
+
+//////////////////////////////////////////////////////////////////////////////
+// THE FOLLOWING METHODS ARE MANDATORY FOR ALL PLUGINS
+//////////////////////////////////////////////////////////////////////////////
+
+OgrPlugin::OgrPlugin(QgisInterface * theQgisInterface) :
+    QgisPlugin(sName, sDescription, sPluginVersion, sPluginType),
+    mQGisIface(theQgisInterface),
+    mQActionPointer(0)
+{
+    assert(0 != mQGisIface);
+}
+
+OgrPlugin::~OgrPlugin()
+{
+}
+
+void OgrPlugin::initGui()
+{
+    // Create the action for tool
+    mQActionPointer = new QAction(QIcon(":/ogrconverter/ogrconverter.png"), tr("Run OGR Layer Converter"), this);
+
+    // Set the what's this text
+    mQActionPointer->setWhatsThis(tr("Replace this with a short description of the what the plugin does"));
+
+    // Connect the action to the run
+    connect(mQActionPointer, SIGNAL(triggered()), this, SLOT(run()));
+
+    // Add the icon to the toolbar
+    mQGisIface->addToolBarIcon(mQActionPointer);
+    mQGisIface->addPluginMenu(tr("OG&R Converter"), mQActionPointer);
+}
+
+//method defined in interface
+void OgrPlugin::help()
+{
+    //implement me!
+}
+
+void OgrPlugin::run()
+{
+    assert(0 != mQGisIface);
+
+    Dialog* ogrDialog = new Dialog(mQGisIface->getMainWindow(), QgisGui::ModalDialogFlags);
+    ogrDialog->setAttribute(Qt::WA_DeleteOnClose);
+    ogrDialog->show();
+}
+
+void OgrPlugin::unload()
+{
+    assert(0 != mQGisIface);
+
+    // TODO: Who is responsible for OGR cleanup?
+    //OGRCleanupAll();
+
+    // remove the GUI
+    mQGisIface->removePluginMenu("&OGR Layer Converter", mQActionPointer);
+    mQGisIface->removeToolBarIcon(mQActionPointer);
+    delete mQActionPointer;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//  THE FOLLOWING CODE IS AUTOGENERATED BY THE PLUGIN BUILDER SCRIPT
+//    YOU WOULD NORMALLY NOT NEED TO MODIFY THIS, AND YOUR PLUGIN
+//      MAY NOT WORK PROPERLY IF YOU MODIFY THIS INCORRECTLY
+/////////////////////////////////////////////////////////////////////////////
+
+// Required extern functions needed  for every plugin
+// These functions can be called prior to creating an instance 
+// of the plugin class.
+
+// Class factory to return a new instance of the plugin class
+QGISEXTERN QgisPlugin * classFactory(QgisInterface * theQgisInterfacePointer)
+{
+  return new OgrPlugin(theQgisInterfacePointer);
+}
+
+// Return the name of the plugin - note that we do not user class members as
+// the class may not yet be insantiated when this method is called.
+QGISEXTERN QString name()
+{
+  return sName;
+}
+
+// Return the description
+QGISEXTERN QString description()
+{
+  return sDescription;
+}
+
+// Return the type (either UI or MapLayer plugin)
+QGISEXTERN int type()
+{
+  return sPluginType;
+}
+
+// Return the version number for the plugin
+QGISEXTERN QString version()
+{
+  return sPluginVersion;
+}
+
+// Delete ourself
+QGISEXTERN void unload(QgisPlugin * thePluginPointer)
+{
+  delete thePluginPointer;
+}
+
+}}} // namespace qgis::plugin::ogrconv
+

Added: trunk/qgis/src/plugins/ogr_converter/plugin.h
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/plugin.h	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/plugin.h	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,103 @@
+// $Id$
+//////////////////////////////////////////////////////////////////////////////
+//
+// begin                : Aug 24, 2008
+// copyright            : (C) 2008 by Mateusz Loskot
+// email                : mateusz at loskot.net
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef QGIS_PLUGIN_OGRCONV_PLUGIN_H_INCLUDED
+#define QGIS_PLUGIN_OGRCONV_PLUGIN_H_INCLUDED
+
+// QGIS
+#include "../qgisplugin.h"
+// Qt4
+#include <QObject>
+
+// Forward declarations
+class QAction;
+class QToolBar;
+class QgisInterface;
+
+namespace qgis { namespace plugin { namespace ogrconv {
+
+/**
+* \class OgrPlugin
+* \brief Translates vector layers between formats supported by OGR library.
+*/
+class OgrPlugin : public QObject, public QgisPlugin
+{
+    Q_OBJECT
+
+public:
+
+    //////////////////////////////////////////////////////////////////////////
+    //                MANDATORY PLUGIN METHODS FOLLOW
+    //////////////////////////////////////////////////////////////////////////
+
+    /**
+    * Constructor for a plugin. The QgisInterface pointer is passed by
+    * QGIS when it attempts to instantiate the plugin.
+    * @param theInterface Pointer to the QgisInterface object.
+    */
+    OgrPlugin(QgisInterface * theInterface);
+
+    //! Destructor
+    virtual ~OgrPlugin();
+
+public slots:
+
+   /**
+    * Initialize the GUI interface for the plugin.
+    * This is only called once when the plugin is added to the plugin
+    * registry in the QGIS application.
+    */
+    virtual void initGui();
+
+    /**
+     * Slot called when the menu item is triggered.
+     * If you created more menu items / toolbar buttons in initiGui,
+     * you should create a separate handler for each action - this
+     * single run() method will not be enough.
+     */
+    void run();
+
+    /**
+     * Unload the plugin by cleaning up the GUI.
+     */
+    void unload();
+
+    //! show the help document
+    void help();
+
+private:
+
+    //////////////////////////////////////////////////////////////////////////
+    // MANDATORY PLUGIN PROPERTY DECLARATIONS
+    //////////////////////////////////////////////////////////////////////////
+
+    // FIXME: Is it used at all?
+    int mPluginType;
+
+    //! Pointer to the QGIS interface object
+    QgisInterface *mQGisIface;
+
+    //!pointer to the qaction for this plugin
+    QAction * mQActionPointer;
+    
+    //////////////////////////////////////////////////////////////////////////
+    // ADD YOUR OWN PROPERTY DECLARATIONS AFTER THIS POINT.....
+    //////////////////////////////////////////////////////////////////////////
+
+}; // OgrPlugin
+
+}}} // namespace qgis::plugin::ogrconv
+
+#endif // QGIS_PLUGIN_OGRCONV_PLUGIN_H_INCLUDED

Added: trunk/qgis/src/plugins/ogr_converter/translator.cpp
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/translator.cpp	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/translator.cpp	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,419 @@
+// $Id$
+//////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2008 by Mateusz Loskot <mateusz at loskot.net>
+//
+// 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// qgis::plugin::ogrconv
+#include "translator.h"
+// QGIS
+#include <qgslogger.h>
+// Qt4
+#include <QString>
+
+namespace qgis { namespace plugin { namespace ogrconv {
+
+// GDAL/OGR loaded into private namespace
+#include <ogr_api.h>
+
+Translator::Translator()
+    : mDstUpdate(false), mDstLayerOverwrite(true)
+{
+}
+
+Translator::Translator(QString const& src, QString const& dst, QString const& format)
+    : mSrcUrl(src), mDstUrl(dst), mDstFormat(format),
+        mDstUpdate(false), mDstLayerOverwrite(true)
+{
+}
+
+QString const& Translator::targetFormat() const
+{
+    return mDstFormat;
+}
+
+void Translator::setTargetFormat(QString const& format)
+{
+    mDstFormat = format;
+}
+
+QString const& Translator::targetLayer() const
+{
+    return mDstLayer;
+}
+
+void Translator::setTargetLayer(QString const& layer)
+{
+    mDstLayer = layer;
+}
+
+QString const& Translator::sourceLayer() const
+{
+    return mSrcLayer;
+}
+
+void Translator::setSourceLayer(QString const& layer)
+{
+    mSrcLayer = layer;
+}
+
+QString const& Translator::targetReferenceSystem() const
+{
+    return mDstSrs;
+}
+
+void Translator::setTargetReferenceSystem(QString const& srs)
+{
+    mDstSrs = srs;
+}
+
+QString const& Translator::sourceReferenceSystem() const
+{
+    return mSrcSrs;
+}
+
+void Translator::setSourceReferenceSystem(QString const& srs)
+{
+    mSrcSrs = srs;
+}
+
+bool Translator::isTargetUpdate() const
+{
+    return mDstUpdate;
+}
+
+void Translator::setUpdateTarget(bool update)
+{
+    mDstUpdate = update;
+}
+
+bool Translator::isTargetLayerOverwrite() const
+{
+    return mDstLayerOverwrite;
+}
+
+bool Translator::translate()
+{
+    bool success = false;
+
+    // TODO: RAII for OGR handlers!!!
+
+    // Open input data source
+    OGRDataSourceH srcDs = openDataSource(mSrcUrl, true);
+    if (0 == srcDs)
+    {
+        QgsDebugMsg("Open source failed: " + mSrcUrl);
+        return false;
+    }
+
+    // Open output data source
+    OGRDataSourceH dstDs = openDataTarget(mDstUrl, mDstUpdate);
+    if (0 == dstDs)
+    {
+        QgsDebugMsg("Open target failed: " + mDstUrl);
+        OGR_DS_Destroy(srcDs);
+        return false;
+    }
+
+    // TODO: Support translation of all layers from input data source
+    //for (int i = 0; i < OGR_DS_GetLayerCount(); ++i)
+
+    OGRLayerH srcLayer = OGR_DS_GetLayerByName(srcDs, mSrcLayer.toAscii().constData());
+    if (0 == srcLayer)
+    {
+        QgsDebugMsg("Can not find layer: " + mSrcLayer);
+        OGR_DS_Destroy(srcDs);
+        OGR_DS_Destroy(dstDs);
+        return false;
+    }
+
+    if (mDstLayer.isEmpty())
+    {
+        QgsDebugMsg("Using source layer name: " + mDstLayer);
+        mDstLayer = mSrcLayer;
+    }
+
+    QgsDebugMsg("START LAYER TRANSLATION ------");
+
+    success = translateLayer(srcDs, srcLayer, dstDs);
+
+    QgsDebugMsg("END LAYER TRANSLATION ------");
+
+    OGR_DS_Destroy(dstDs);
+    OGR_DS_Destroy(srcDs);
+
+    return success;
+}
+
+bool Translator::translateLayer(OGRDataSourceH srcDs, OGRLayerH srcLayer, OGRDataSourceH dstDs)
+{
+    // Implementation based on TranslateLayer function from ogr2ogr.cpp, from GDAL/OGR.
+    Q_ASSERT(0 != srcDs);
+    Q_ASSERT(0 != srcLayer);
+    Q_ASSERT(0 != dstDs);
+
+    bool success = false;
+
+    // Get source layer schema
+    OGRFeatureDefnH srcLayerDefn = OGR_L_GetLayerDefn(srcLayer);
+    Q_ASSERT(0 != srcLayerDefn);
+
+    // Find if layer exists in target data source 
+    int dstLayerIndex = 0;
+    OGRLayerH dstLayer = findLayer(dstDs, mDstLayer, dstLayerIndex);
+
+    // If the user requested overwrite, and we have the layer in question
+    // we need to delete it now so it will get recreated overwritten
+    if (0 != dstLayer && mDstLayerOverwrite
+        && 0 != OGR_DS_TestCapability(dstDs, ODsCDeleteLayer))
+    {
+        if (OGRERR_NONE != OGR_DS_DeleteLayer(dstDs, dstLayerIndex))
+        {
+            QgsDebugMsg("Delete layer failed when overwrite requested");
+            return false;
+        }
+    }
+
+    if (0 == dstLayer)
+    {
+        QgsDebugMsg("Destination layer not found, will attempt to create");
+
+        // If the layer does not exist, then create it
+        if (0 == OGR_DS_TestCapability(dstDs, ODsCCreateLayer))
+        {
+            QgsDebugMsg("Layer " + mDstLayer + " not found, and CreateLayer not supported by driver");
+            return false;
+        }
+
+        // FIXME: Do we need it here?
+        //CPLErrorReset();
+
+        // TODO: -nlt option support
+        OGRwkbGeometryType geomType = OGR_FD_GetGeomType(srcLayerDefn);
+        
+        // TODO: Implement SRS transformation 
+        OGRSpatialReferenceH dstLayerSrs = OGR_L_GetSpatialRef(srcLayer);
+
+        dstLayer = OGR_DS_CreateLayer(dstDs, mDstLayer.toAscii().constData(),
+                                      dstLayerSrs, geomType, 0); 
+    }
+    // TODO: Append and createion options not implemented
+    // else if (!mDstLayerAppend)
+    
+    Q_ASSERT(0 != dstLayer);
+
+    // Transfer attributes schema
+    if (!copyFields(dstLayer, srcLayerDefn))
+    {
+        QgsDebugMsg("Faild to copy fields from layer " + mSrcLayer);
+        return false;
+    }
+
+    // Transfer features
+    success = copyFeatures(srcLayer, dstLayer);
+
+    return success;
+}
+
+bool Translator::copyFields(OGRFeatureDefnH layerDefn, OGRLayerH layer)
+{
+    Q_ASSERT(0 != layerDefn);
+    Q_ASSERT(0 != layer);
+
+    int const count = OGR_FD_GetFieldCount(layerDefn);
+    for (int i = 0; i < count; ++i)
+    {
+        OGRFieldDefnH fieldDefn = OGR_FD_GetFieldDefn(layerDefn, i);
+        Q_ASSERT(0 != fieldDefn);
+
+        if (OGRERR_NONE != OGR_L_CreateField(layer, fieldDefn, true))
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool Translator::copyFeatures(OGRLayerH srcLayer, OGRLayerH dstLayer)
+{
+    Q_ASSERT(0 != srcLayer);
+    Q_ASSERT(0 != dstLayer);
+
+    bool success = false;
+    OGRFeatureDefnH srcLayerDefn = OGR_L_GetLayerDefn(srcLayer);
+    long srcFid = 0;
+    long count = 0;
+
+    // TODO: RAII for feature handlers!!!
+ 
+    while (true)
+    {
+        OGRFeatureH srcFeat = OGR_L_GetNextFeature(srcLayer);
+        if (0 == srcFeat)
+        {
+            QgsDebugMsg("Next source feature is null, finishing");
+            success = true;
+            break;
+        }
+        srcFid = OGR_F_GetFID(srcFeat);
+
+        // FIXME: Do we need it here?
+        //CPLErrorReset();
+
+        OGRFeatureH dstFeat = OGR_F_Create(srcLayerDefn);
+
+        if (OGRERR_NONE !=  OGR_F_SetFrom(dstFeat, srcFeat, true))
+        {
+            QString msg = QString("Unable to translate feature %1 from layer %2").arg(srcFid).arg(mSrcLayer);
+            QgsDebugMsg(msg);
+
+            OGR_F_Destroy(srcFeat);
+            OGR_F_Destroy(dstFeat);
+            success = false;
+            break;
+        }
+        Q_ASSERT(0 != dstFeat);
+
+        // TODO: Transform feature geometry
+
+        OGR_F_Destroy(srcFeat);
+        
+        // FIXME: Do we need it here?
+        //CPLErrorReset();
+
+        // TODO: Skip failures support
+        if (OGRERR_NONE != OGR_L_CreateFeature(dstLayer, dstFeat))
+        {
+            QgsDebugMsg("Feature creation failed");
+            OGR_F_Destroy(dstFeat);
+            success = false;
+            break;
+        }
+
+        OGR_F_Destroy(dstFeat);
+        
+        count += 1;
+        success = true;
+    }
+
+    QgsDebugMsg(QString("Number of copied features: %1").arg(count));
+
+    return success;
+}
+
+OGRSFDriverH Translator::findDriver(QString const& name)
+{
+    if (OGRGetDriverCount() <= 0)
+    {
+        OGRRegisterAll(); 
+    }
+    int const drvCount = OGRGetDriverCount();
+
+    OGRSFDriverH drv = 0;
+    QString drvName;
+
+    for (int i = 0; i < drvCount; ++i)
+    {
+        OGRSFDriverH drvTmp = OGRGetDriver(i);
+        Q_CHECK_PTR(drvTmp);
+        if (0 != drvTmp)
+        {
+            drvName = OGR_Dr_GetName(drvTmp);
+            if (name == drvName
+                && 0 != OGR_Dr_TestCapability(drvTmp, ODrCCreateDataSource))
+            {
+                QgsDebugMsg("Driver found: " + name);
+                drv = drvTmp;
+                break;
+            }
+        }
+    }
+
+    return drv;
+}
+
+OGRLayerH Translator::findLayer(OGRDataSourceH ds, QString const& name, int& index)
+{
+    if (0 == ds)
+    {
+        index = -1;
+        return 0;
+    }
+
+    OGRLayerH lyr = 0;
+    int const count = OGR_DS_GetLayerCount(ds);
+
+    for (int i = 0; i < count; ++i)
+    {
+        OGRLayerH lyrTmp = OGR_DS_GetLayer(ds, i);
+        if (0 != lyrTmp)
+        {
+            OGRFeatureDefnH defn = OGR_L_GetLayerDefn(lyrTmp);
+            Q_ASSERT(0 != defn);
+            
+            QString nameTmp(OGR_FD_GetName(defn));
+            if (name == nameTmp)
+            {
+                QgsDebugMsg("Layer found: " + nameTmp);
+                index = i;
+                lyr = lyrTmp;
+                break;
+            }
+        }
+    }
+
+    return lyr;
+}
+
+OGRDataSourceH Translator::openDataSource(QString const& url, bool readOnly)
+{
+    OGRDataSourceH ds = OGROpen(url.toAscii().constData(), !readOnly, 0);
+    if (0 == ds)
+    {
+        QgsDebugMsg("Failed to open: " + url);
+    }
+
+    return ds;
+}
+
+OGRDataSourceH Translator::openDataTarget(QString const& url, bool update)
+{
+    OGRDataSourceH ds = 0;
+
+    if (update)
+    {
+        // Try opening the output datasource as an existing, writable
+        ds = openDataSource(url, false);
+    }
+    else
+    {
+        // Find the output driver
+        OGRSFDriverH drv = findDriver(mDstFormat);
+        if (0 == drv)
+        {
+            QgsDebugMsg("Could not find driver: " + mDstFormat);
+            return 0;
+        }
+
+        // Create the output data source
+        //
+        // TODO: Add support for creation options
+        ds = OGR_Dr_CreateDataSource(drv, url.toAscii().constData(), 0);
+        if (0 == ds)
+        {
+            QgsDebugMsg("Failed to open: " + url);
+        }
+    }
+
+    return ds;
+}
+
+}}} // namespace qgis::plugin::ogrconv
+

Added: trunk/qgis/src/plugins/ogr_converter/translator.h
===================================================================
--- trunk/qgis/src/plugins/ogr_converter/translator.h	                        (rev 0)
+++ trunk/qgis/src/plugins/ogr_converter/translator.h	2008-08-27 13:29:01 UTC (rev 9191)
@@ -0,0 +1,81 @@
+// $Id$
+//////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2008 by Mateusz Loskot <mateusz at loskot.net>
+//
+// 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.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef QGIS_PLUGIN_OGRCONV_TRANSLATOR_H_INCLUDED
+#define QGIS_PLUGIN_OGRCONV_TRANSLATOR_H_INCLUDED 
+
+// Qt4
+#include <QString>
+
+namespace qgis { namespace plugin { namespace ogrconv {
+
+// GDAL/OGR loaded into private namespace
+#include <ogr_api.h>
+
+class Translator
+{
+public:
+
+    Translator();
+    Translator(QString const& src, QString const& dst, QString const& format);
+
+    QString const& targetFormat() const;
+    void setTargetFormat(QString const& format);
+
+    QString const& targetLayer() const;
+    void setTargetLayer(QString const& layer);
+
+    QString const& sourceLayer() const;
+    void setSourceLayer(QString const& layer);
+
+    QString const& targetReferenceSystem() const;
+    void setTargetReferenceSystem(QString const& srs);
+
+    QString const& sourceReferenceSystem() const;
+    void setSourceReferenceSystem(QString const& srs);
+
+    bool isTargetUpdate() const;
+    void setUpdateTarget(bool update);
+
+    bool isTargetLayerOverwrite() const;
+    // TODO: Implement, currently always overwrite
+    // void setTargetLayerOverwrite(bool overwrite);
+
+    bool translate();
+
+private:
+
+    QString mSrcUrl;
+    QString mDstUrl;
+    QString mDstFormat;
+    QString mSrcLayer;
+    QString mDstLayer;
+    QString mSrcSrs;
+    QString mDstSrs;
+    bool mDstUpdate;
+    bool mDstLayerOverwrite;
+    // TODO: Append option not supported
+    // bool mDstLayerAppend;
+
+    bool translateLayer(OGRDataSourceH srcDs, OGRLayerH srcLayer, OGRDataSourceH dstDs);
+    bool copyFields(OGRFeatureDefnH layerDefn, OGRLayerH layer);
+    bool copyFeatures(OGRLayerH srcLayer, OGRLayerH dstLayer);
+
+    OGRSFDriverH findDriver(QString const& name);
+    OGRLayerH findLayer(OGRDataSourceH ds, QString const& name, int& index);
+    OGRDataSourceH openDataSource(QString const& url, bool readOnly);
+    OGRDataSourceH openDataTarget(QString const& url, bool update);
+
+};
+
+}}} // namespace qgis::plugin::ogrconv
+
+#endif // QGIS_PLUGIN_OGRCONV_TRANSLATOR_H_INCLUDED



More information about the QGIS-commit mailing list