71 changes: 44 additions & 27 deletions python/console_sci.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def __init__(self, parent=None):
# Set Python lexer
# Set style for Python comments (style number 1) to a fixed-width
# courier.
self.setLexers(True)
self.setLexers()

# Indentation
#self.setAutoIndent(True)
Expand Down Expand Up @@ -120,10 +120,11 @@ def showHistory(self):

def autoComplete(self):
self.autoCompleteFromAll()

def clearConsole(self):
"""Clear the contents of the console."""
self.setText('')
self.SendScintilla(QsciScintilla.SCI_CLEARALL)
#self.setText('')
self.insertInitText()
self.displayPrompt(False)
self.setFocus()
Expand Down Expand Up @@ -156,32 +157,39 @@ def commandConsole(self, command):
self.append('from PyQt4.QtGui import *')
self.move_cursor_to_end()
self.setFocus()
def setLexers(self, lexer):

def setLexers(self):
from qgis.core import QgsApplication
if lexer:
font = QFont()
font.setFamily('Mono') ## Courier New
font.setFixedPitch(True)
## check platform for font size
if sys.platform.startswith('darwin'):
font.setPointSize(13)
else:
font.setPointSize(10)
self.setFont(font)
self.setMarginsFont(font)
self.lexer = QsciLexerPython()
self.lexer.setDefaultFont(font)
self.lexer.setColor(Qt.red, 1)
self.lexer.setColor(Qt.darkGreen, 5)
self.lexer.setColor(Qt.darkBlue, 15)
self.lexer.setFont(font, 1)
self.lexer.setFont(font, 3)
self.lexer.setFont(font, 4)
self.api = QsciAPIs(self.lexer)

self.lexer = QsciLexerPython()
settings = QSettings()
loadFont = settings.value("pythonConsole/fontfamilytext", "Monospace").toString()
fontSize = settings.value("pythonConsole/fontsize", 10).toInt()[0]

font = QFont(loadFont)
font.setFixedPitch(True)
font.setPointSize(fontSize)

self.lexer.setDefaultFont(font)
self.lexer.setColor(Qt.red, 1)
self.lexer.setColor(Qt.darkGreen, 5)
self.lexer.setColor(Qt.darkBlue, 15)
self.lexer.setFont(font, 1)
self.lexer.setFont(font, 3)
self.lexer.setFont(font, 4)

self.api = QsciAPIs(self.lexer)
chekBoxAPI = settings.value( "pythonConsole/preloadAPI" ).toBool()
if chekBoxAPI:
self.api.loadPrepared( QgsApplication.pkgDataPath() + "/python/qsci_apis/pyqgis_master.pap" )
else:
apiPath = settings.value("pythonConsole/userAPI").toStringList()
for i in range(0, len(apiPath)):
self.api.load(QString(unicode(apiPath[i])))
self.api.prepare()
self.lexer.setAPIs(self.api)

self.setLexer(self.lexer)
self.setLexer(self.lexer)

## TODO: show completion list for file and directory

Expand Down Expand Up @@ -263,6 +271,9 @@ def new_prompt(self, prompt):
self.ensureCursorVisible()
self.ensureLineVisible(line)

def refreshLexerProperties(self):
self.setLexers()

# def check_selection(self):
# """
# Check if selected text is r/w,
Expand Down Expand Up @@ -484,9 +495,10 @@ def currentCommand(self):
return cmd

def runCommand(self, cmd):
import webbrowser
self.updateHistory(cmd)
self.SendScintilla(QsciScintilla.SCI_NEWLINE)
if cmd in ('_save', '_clear', '_clearAll'):
if cmd in ('_save', '_clear', '_clearAll', '_pyqgis', '_api'):
if cmd == '_save':
self.writeHistoryFile()
print QCoreApplication.translate("PythonConsole",
Expand All @@ -508,6 +520,11 @@ def runCommand(self, cmd):
self.clearHistoryFile()
print QCoreApplication.translate("PythonConsole",
"## History cleared successfully ##")
elif cmd == '_pyqgis':
webbrowser.open( "http://www.qgis.org/pyqgis-cookbook/" )
elif cmd == '_api':
webbrowser.open( "http://www.qgis.org/api/" )

output = sys.stdout.get_and_clean_data()
if output:
self.append(output)
Expand Down
161 changes: 161 additions & 0 deletions python/console_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# -*- coding:utf-8 -*-
"""
/***************************************************************************
Python Conosle for QGIS
-------------------
begin : 2012-09-10
copyright : (C) 2012 by Salvatore Larosa
email : lrssvtml (at) gmail (dot) com
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
Some portions of code were taken from https://code.google.com/p/pydee/
"""

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from ui_console_settings import Ui_SettingsDialog

class optionsDialog(QDialog, Ui_SettingsDialog):
def __init__(self, parent):
QDialog.__init__(self, parent)
self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Settings Python Console"))
#self.iface = iface
self.parent = parent
self.setupUi(self)
#self.show()

self.listPath = []

self.restoreSettings()
self.initialCheck()
self.fontConfig()

self.lineEdit.setReadOnly(True)
self.tabWidget.setTabText(0, QCoreApplication.translate("PythonConsole", "General"))
self.tabWidget.setTabIcon(0, QIcon(":/images/themes/default/propertyicons/general.png"))
self.tabWidget.setTabText(1, QCoreApplication.translate("PythonConsole", "About"))
self.tabWidget.setTabIcon(1, QIcon(":/images/console/iconAboutConsole.png"))

self.addAPIpath.setIcon(QIcon(":/images/themes/default/symbologyAdd.png"))
self.addAPIpath.setToolTip(QCoreApplication.translate("PythonConsole", "Add API path"))
self.removeAPIpath.setIcon(QIcon(":/images/themes/default/symbologyRemove.png"))
self.removeAPIpath.setToolTip(QCoreApplication.translate("PythonConsole", "Remove API path"))

self.connect( self.preloadAPI,
SIGNAL("stateChanged(int)"), self.initialCheck)
self.connect(self.browseButton,
SIGNAL("clicked()"), self.loadAPIFile)
self.connect(self.addAPIpath,
SIGNAL("clicked()"), self.addAPI)
self.connect(self.removeAPIpath,
SIGNAL("clicked()"), self.removeAPI)

def initialCheck(self):
if self.preloadAPI.isChecked():
self.enableDisable(False)
else:
self.enableDisable(True)

def enableDisable(self, value):
self.tableWidget.setEnabled(value)
self.lineEdit.setEnabled(value)
self.browseButton.setEnabled(value)
self.addAPIpath.setEnabled(value)
self.removeAPIpath.setEnabled(value)

def loadAPIFile(self):
settings = QSettings()
lastDirPath = settings.value("pythonConsole/lastDirAPIPath").toString()
fileAPI = QFileDialog.getOpenFileName(
self, "Open API File", lastDirPath, "API file (*.api)")
self.lineEdit.setText(fileAPI)

lastDirPath = QFileInfo(fileAPI).path()
settings.setValue("pythonConsole/lastDirAPIPath", QVariant(fileAPI))

def accept(self):
if not self.preloadAPI.isChecked():
if self.tableWidget.rowCount() == 0:
QMessageBox.information(self, self.tr("Warning!"),
self.tr('Please specify API file or check "Use preloaded API files"'))
return
self.saveSettings()
self.listPath = []
QDialog.accept( self )

def addAPI(self):
if self.lineEdit.text() == "":
return
path = self.lineEdit.text()
count = self.tableWidget.rowCount()
self.tableWidget.setColumnCount(2)
self.tableWidget.insertRow(count)
pathItem = QTableWidgetItem(path)
pathSplit = path.split("/")
apiName = pathSplit[-1][0:-4]
apiNameItem = QTableWidgetItem(apiName)
self.tableWidget.setItem(count, 0, apiNameItem)
self.tableWidget.setItem(count, 1, pathItem)
self.tableWidget.setHorizontalHeaderLabels([self.tr("API"), self.tr("PATH")])
self.tableWidget.horizontalHeader().setResizeMode(0, QHeaderView.ResizeToContents)
self.tableWidget.horizontalHeader().show()
self.tableWidget.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)
#self.tableWidget.resizeRowsToContents()
self.lineEdit.clear()

def removeAPI(self):
listItemSel = self.tableWidget.selectedIndexes()
#row = self.tableWidget.currentRow()
for indx in listItemSel:
self.tableWidget.removeRow(indx.row())

def fontConfig(self):
#fontFamily = ['Courier','Monospace','Aurulent Sans','Bitstream Vera Serif']
#for i in range(0, len(fontFamily)):
#self.comboBox.addItem(fontFamily[i])
settings = QSettings()
self.fontComboBox.setCurrentIndex(settings.value("pythonConsole/fontfamilyindex").toInt()[0])

def saveSettings(self):
settings = QSettings()
settings.setValue("pythonConsole/preloadAPI", QVariant(self.preloadAPI.isChecked()))
fontFamilyIndex = self.fontComboBox.currentIndex()
settings.setValue("pythonConsole/fontfamilyindex", QVariant(fontFamilyIndex))
fontFamilyText = self.fontComboBox.currentText()
settings.setValue("pythonConsole/fontfamilytext", QVariant(fontFamilyText))
fontSize = self.spinBox.value()
for i in range(0, self.tableWidget.rowCount()):
text = self.tableWidget.item(i, 1).text()
self.listPath.append(text)
settings.setValue("pythonConsole/fontsize", QVariant(fontSize))
settings.setValue("pythonConsole/userAPI", QVariant(self.listPath))

def restoreSettings(self):
settings = QSettings()
self.spinBox.setValue(settings.value("pythonConsole/fontsize").toInt()[0])
self.preloadAPI.setChecked(settings.value( "pythonConsole/preloadAPI" ).toBool())
itemTable = settings.value("pythonConsole/userAPI").toStringList()
for i in range(len(itemTable)):
self.tableWidget.insertRow(i)
self.tableWidget.setColumnCount(2)
pathSplit = itemTable[i].split("/")
apiName = pathSplit[-1][0:-4]
self.tableWidget.setItem(i, 0, QTableWidgetItem(apiName))
self.tableWidget.setItem(i, 1, QTableWidgetItem(itemTable[i]))
self.tableWidget.setHorizontalHeaderLabels([self.tr("API"), self.tr("PATH")])
self.tableWidget.horizontalHeader().setResizeMode(0, QHeaderView.ResizeToContents)
self.tableWidget.horizontalHeader().show()
self.tableWidget.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)
#self.comboBox.setCurrentIndex(settings.value("pythonConsole/fontfamilyindex").toInt()[0])

def reject( self ):
QDialog.reject( self )
297 changes: 297 additions & 0 deletions python/console_settings.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SettingsDialog</class>
<widget class="QDialog" name="SettingsDialog">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>472</width>
<height>388</height>
</rect>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
<string>Tab 1</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="1" column="0">
<widget class="QCheckBox" name="preloadAPI">
<property name="text">
<string>Use preloaded API file</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="3">
<widget class="QSpinBox" name="spinBox">
<property name="minimumSize">
<size>
<width>51</width>
<height>26</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>51</width>
<height>26</height>
</size>
</property>
<property name="minimum">
<number>6</number>
</property>
<property name="maximum">
<number>15</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Font</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QFontComboBox" name="fontComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QPushButton" name="addAPIpath">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="removeAPIpath">
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QTableWidget" name="tableWidget">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerItem</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="rowCount">
<number>0</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>API file</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QPushButton" name="browseButton">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabAbout">
<attribute name="title">
<string>Tab 2</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QTextEdit" name="textEdit">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Aurulent Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Python Console for QGIS&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Developed by Salvatore Larosa&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;---------------------------&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;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.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SettingsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SettingsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
6 changes: 5 additions & 1 deletion python/core/raster/qgsrasterdataprovider.sip
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
Histogram,
Size,
Create,
Remove
Remove,
IdentifyValue,
IdentifyText,
IdentifyHtml,
IdentifyFeature
};

// This is modified copy of GDALColorInterp
Expand Down
2 changes: 1 addition & 1 deletion python/core/raster/qgsrasterinterface.sip
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class QgsRasterInterface
virtual QgsRasterInterface * input() const;

/** Is on/off */
virtual bool on();
virtual bool on() const;

/** Set on/off */
virtual void setOn( bool on );
Expand Down
17 changes: 17 additions & 0 deletions python/plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@

MACRO (PLUGIN_INSTALL plugin subdir )
INSTALL(FILES ${ARGN} DESTINATION ${QGIS_DATA_DIR}/python/plugins/${plugin}/${subdir})
STRING(REPLACE "/" "_" subdir_sane "${subdir}")
ADD_CUSTOM_TARGET(${plugin}_${subdir_sane}_stageinstall ALL DEPENDS ${ARGN})
FOREACH(file ${ARGN})
ADD_CUSTOM_COMMAND(TARGET ${plugin}_${subdir_sane}_stageinstall
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${PYTHON_OUTPUT_DIRECTORY}/plugins/${plugin}/${subdir}
COMMAND ${CMAKE_COMMAND} -E copy ${file} ${PYTHON_OUTPUT_DIRECTORY}/plugins/${plugin}/${subdir}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
#COMMENT "copying ${file} to ${PYTHON_OUTPUT_DIRECTORY}/plugins/${plugin}/${subdir}"
)
ENDFOREACH(file)
ENDMACRO (PLUGIN_INSTALL)


ADD_SUBDIRECTORY(plugin_installer)
ADD_SUBDIRECTORY(mapserver_export)
ADD_SUBDIRECTORY(fTools)
Expand Down
9 changes: 2 additions & 7 deletions python/plugins/db_manager/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
SET (DB_MANAGER_PLUGIN_DIR ${QGIS_DATA_DIR}/python/plugins/db_manager)

ADD_SUBDIRECTORY(db_plugins)
ADD_SUBDIRECTORY(icons)

Expand All @@ -9,9 +7,6 @@ FILE(GLOB PY_FILES *.py)
FILE(GLOB UI_FILES ui/*.ui)
PYQT4_WRAP_UI(PYUI_FILES ${UI_FILES})
PYQT4_ADD_RESOURCES(PYRC_FILES resources.qrc)
ADD_CUSTOM_TARGET(db_manager ALL DEPENDS ${PYUI_FILES} ${PYRC_FILES})

INSTALL(FILES ${OTHER_FILES} DESTINATION ${DB_MANAGER_PLUGIN_DIR})
INSTALL(FILES ${PY_FILES} DESTINATION ${DB_MANAGER_PLUGIN_DIR})
INSTALL(FILES ui/__init__.py ${PYUI_FILES} DESTINATION ${DB_MANAGER_PLUGIN_DIR}/ui)
INSTALL(FILES ${PYRC_FILES} DESTINATION ${DB_MANAGER_PLUGIN_DIR})
PLUGIN_INSTALL(db_manager . ${OTHER_FILES} ${PY_FILES} ${PYRC_FILES})
PLUGIN_INSTALL(db_manager ui ${PYUI_FILES} ui/__init__.py)
2 changes: 1 addition & 1 deletion python/plugins/db_manager/db_plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ ADD_SUBDIRECTORY(postgis)
ADD_SUBDIRECTORY(spatialite)

FILE(GLOB PY_FILES *.py)
INSTALL(FILES ${PY_FILES} DESTINATION ${DB_MANAGER_PLUGIN_DIR}/db_plugins)
PLUGIN_INSTALL(db_manager db_plugins ${PY_FILES})
9 changes: 3 additions & 6 deletions python/plugins/db_manager/db_plugins/postgis/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
SET (DB_MANAGER_POSTGIS_DIR ${DB_MANAGER_PLUGIN_DIR}/db_plugins/postgis)

FILE(GLOB PY_FILES *.py)
FILE(GLOB ICON_FILES icons/*.png)

PYQT4_ADD_RESOURCES(PYRC_FILES resources.qrc)
ADD_CUSTOM_TARGET(db_manager_postgis ALL DEPENDS ${PYRC_FILES})

INSTALL(FILES ${PY_FILES} DESTINATION ${DB_MANAGER_POSTGIS_DIR})
INSTALL(FILES ${PYRC_FILES} DESTINATION ${DB_MANAGER_POSTGIS_DIR})
INSTALL(FILES ${ICON_FILES} DESTINATION ${DB_MANAGER_POSTGIS_DIR}/icons)
PLUGIN_INSTALL(db_manager db_plugins/postgis ${PY_FILES} ${PYRC_FILES})
PLUGIN_INSTALL(db_manager db_plugins/postgis/icons ${ICON_FILES})

ADD_SUBDIRECTORY(plugins)

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
INSTALL(FILES __init__.py DESTINATION ${DB_MANAGER_POSTGIS_DIR}/plugins)

ADD_SUBDIRECTORY(qgis_topoview)
ADD_SUBDIRECTORY(versioning)

PLUGIN_INSTALL(db_manager db_plugins/postgis/plugins __init__.py)
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
SET (DB_MANAGER_POSTGIS_TOPOVIEW_DIR ${DB_MANAGER_POSTGIS_DIR}/plugins/qgis_topoview)

FILE(GLOB PY_FILES *.py)

INSTALL(FILES ${PY_FILES} DESTINATION ${DB_MANAGER_POSTGIS_TOPOVIEW_DIR})

ADD_SUBDIRECTORY(templates)

PLUGIN_INSTALL(db_manager db_plugins/postgis/plugins/qgis_topoview ${PY_FILES})
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
SET (DB_MANAGER_POSTGIS_TOPOVIEW_TEMPLATE_DIR ${DB_MANAGER_POSTGIS_DIR}/plugins/qgis_topoview/templates)

FILE(GLOB QML_FILES *.qml)

INSTALL(FILES ${QML_FILES} DESTINATION ${DB_MANAGER_POSTGIS_TOPOVIEW_TEMPLATE_DIR})
PLUGIN_INSTALL(db_manager db_plugins/postgis/plugins/qgis_topoview/templates ${QML_FILES})
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
SET (DB_MANAGER_POSTGIS_VERSIONING_DIR ${DB_MANAGER_POSTGIS_DIR}/plugins/versioning)

FILE(GLOB PY_FILES *.py)

FILE(GLOB UI_FILES *.ui)
PYQT4_WRAP_UI(PYUI_FILES ${UI_FILES})
ADD_CUSTOM_TARGET(db_manager_postgis_versioning ALL DEPENDS ${PYUI_FILES})

INSTALL(FILES ${PY_FILES} DESTINATION ${DB_MANAGER_POSTGIS_VERSIONING_DIR})
INSTALL(FILES ${PYUI_FILES} DESTINATION ${DB_MANAGER_POSTGIS_VERSIONING_DIR})

PLUGIN_INSTALL(db_manager db_plugins/postgis/plugins/versioning ${PY_FILES} ${PYUI_FILES})
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
SET (DB_MANAGER_SPATIALITE_DIR ${DB_MANAGER_PLUGIN_DIR}/db_plugins/spatialite)

FILE(GLOB PY_FILES *.py)
FILE(GLOB ICON_FILES icons/*.png)

PYQT4_ADD_RESOURCES(PYRC_FILES resources.qrc)
ADD_CUSTOM_TARGET(db_manager_spatialite ALL DEPENDS ${PYRC_FILES})

INSTALL(FILES ${PY_FILES} DESTINATION ${DB_MANAGER_SPATIALITE_DIR})
INSTALL(FILES ${PYRC_FILES} DESTINATION ${DB_MANAGER_SPATIALITE_DIR})
INSTALL(FILES ${ICON_FILES} DESTINATION ${DB_MANAGER_SPATIALITE_DIR}/icons)
PLUGIN_INSTALL(db_manager db_plugins/spatialite ${PY_FILES} ${PYRC_FILES})
PLUGIN_INSTALL(db_manager db_plugins/spatialite/icons ${ICON_FILES})

3 changes: 2 additions & 1 deletion python/plugins/db_manager/icons/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
FILE(GLOB ICON_FILES *.png *.xpm toolbar/*.png)
INSTALL(FILES ${ICON_FILES} DESTINATION ${DB_MANAGER_PLUGIN_DIR}/icons)

PLUGIN_INSTALL(db_manager icons ${ICON_FILES})
2 changes: 2 additions & 0 deletions python/plugins/fTools/tools/doGeoprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ def convex_hull(self, useField ):
hull = []
first = True
outID = 0
vproviderA.rewind()
for inFeat in selectionA:
atMap = inFeat.attributeMap()
idVar = atMap[ self.myParam ]
Expand Down Expand Up @@ -546,6 +547,7 @@ def convex_hull(self, useField ):
hull = []
first = True
outID = 0
vproviderA.rewind()
while vproviderA.nextFeature( inFeat ):
atMap = inFeat.attributeMap()
idVar = atMap[ self.myParam ]
Expand Down
4 changes: 2 additions & 2 deletions python/plugins/sextante/core/QGisLayers.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ def load(layer, name = None, crs = None, style = None):
name = path.split(layer)[1]
qgslayer = QgsVectorLayer(layer, name , 'ogr')
if qgslayer.isValid():
if crs != None:
qgslayer.setCrs(crs,False)
if crs is not None and qgslayer.crs() is None:
qgslayer.setCrs(crs, False)
if style == None:
if qgslayer.geometryType == 0:
style = SextanteConfig.getSetting(SextanteConfig.VECTOR_POINT_STYLE)
Expand Down
2 changes: 0 additions & 2 deletions python/plugins/sextante/core/Sextante.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from sextante.wps.WPSAlgorithmProvider import WPSAlgorithmProvider
from sextante.saga.SagaAlgorithmProvider import SagaAlgorithmProvider
from sextante.script.ScriptAlgorithmProvider import ScriptAlgorithmProvider
from sextante.core.QGisLayers import QGisLayers
Expand Down Expand Up @@ -123,7 +122,6 @@ def initialize():
Sextante.addProvider(SagaAlgorithmProvider())
Sextante.addProvider(GrassAlgorithmProvider())
Sextante.addProvider(ScriptAlgorithmProvider())
Sextante.addProvider(WPSAlgorithmProvider())
Sextante.modeler.initializeSettings();
#and initialize
SextanteLog.startLogging()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/sextanteexampleprovider/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

from sextanteexampleprovider.SextanteExampleProviderPlugin import SextanteExampleProviderPlugin
def name():
return "SEXTANTE example provider"
def description():
Expand All @@ -35,4 +34,5 @@ def icon():
def qgisMinimumVersion():
return "1.0"
def classFactory(iface):
from sextanteexampleprovider.SextanteExampleProviderPlugin import SextanteExampleProviderPlugin
return SextanteExampleProviderPlugin()
20 changes: 19 additions & 1 deletion src/app/qgsidentifyresults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ QgsIdentifyResults::QgsIdentifyResults( QgsMapCanvas *canvas, QWidget *parent, Q
, mDock( NULL )
{
setupUi( this );

mExpandToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionExpandTree.png" ) );
mCollapseToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionCollapseTree.png" ) );
mExpandNewToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionExpandNewTree.png" ) );

QSettings mySettings;
restoreGeometry( mySettings.value( "/Windows/Identify/geometry" ).toByteArray() );
bool myDockFlag = mySettings.value( "/qgis/dockIdentifyResults", false ).toBool();
Expand All @@ -98,6 +103,7 @@ QgsIdentifyResults::QgsIdentifyResults( QgsMapCanvas *canvas, QWidget *parent, Q
mDock->setWidget( this );
QgisApp::instance()->addDockWidget( Qt::LeftDockWidgetArea, mDock );
}
mExpandNewToolButton->setChecked( mySettings.value( "/Map/identifyExpand", false ).toBool() );
lstResults->setColumnCount( 2 );
setColumnText( 0, tr( "Feature" ) );
setColumnText( 1, tr( "Value" ) );
Expand Down Expand Up @@ -371,6 +377,12 @@ void QgsIdentifyResults::show()
layItem->setExpanded( true );
}

// expand all if enabled
if ( mExpandNewToolButton->isChecked() )
{
lstResults->expandAll();
}

QDialog::show();
raise();
}
Expand Down Expand Up @@ -948,7 +960,7 @@ void QgsIdentifyResults::layerProperties()
void QgsIdentifyResults::layerProperties( QTreeWidgetItem *item )
{
QgsVectorLayer *vlayer = vectorLayer( item );
if( !vlayer )
if ( !vlayer )
return;

QgisApp::instance()->showLayerProperties( vlayer );
Expand Down Expand Up @@ -1007,3 +1019,9 @@ void QgsIdentifyResults::openUrl( const QUrl &url )
QMessageBox::warning( this, tr( "Could not open url" ), tr( "Could not open URL '%1'" ).arg( url.toString() ) );
}
}

void QgsIdentifyResults:: on_mExpandNewToolButton_toggled( bool checked )
{
QSettings settings;
settings.setValue( "/Map/identifyExpand", checked );
}
5 changes: 5 additions & 0 deletions src/app/qgsidentifyresults.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ class QgsIdentifyResults: public QDialog, private Ui::QgsIdentifyResultsBase

void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }

void on_mExpandNewToolButton_toggled( bool checked );

void on_mExpandToolButton_clicked( bool checked ) { expandAll(); }
void on_mCollapseToolButton_clicked( bool checked ) { collapseAll(); }

void openUrl( const QUrl &url );

private:
Expand Down
75 changes: 29 additions & 46 deletions src/app/qgsmaptoolidentify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,62 +335,45 @@ bool QgsMapToolIdentify::identifyRasterLayer( QgsRasterLayer *layer, int x, int
QgsDebugMsg( QString( "coordinate not reprojectable: %1" ).arg( cse.what() ) );
return false;
}
QgsDebugMsg( QString( "idPoint = %1 %2" ).arg( idPoint.x() ).arg( idPoint.y() ) );

if ( !layer->extent().contains( idPoint ) ) return false;

#if 0
if ( layer->providerType() == "wms" )
{
type = tr( "WMS layer" );

//if WMS layer does not cover the view origin,
//we need to map the view pixel coordinates
//to WMS layer pixel coordinates
QgsRectangle viewExtent = toLayerCoordinates( layer, mCanvas->extent() );
QgsRectangle layerExtent = layer->extent();
double mapUnitsPerPixel = mCanvas->mapUnitsPerPixel();
if ( mapUnitsPerPixel > 0 && viewExtent.intersects( layerExtent ) )
{
double xMinView = viewExtent.xMinimum();
double yMaxView = viewExtent.yMaximum();
double xMinLayer = layerExtent.xMinimum();
double yMaxLayer = layerExtent.yMaximum();

idPoint.set(
xMinView < xMinLayer ? floor( x - ( xMinLayer - xMinView ) / mapUnitsPerPixel ) : x,
yMaxView > yMaxLayer ? floor( y - ( yMaxView - yMaxLayer ) / mapUnitsPerPixel ) : y
);

attributes.insert( tr( "Feature info" ), layer->identifyAsHtml( idPoint ) );
}
else
{
res = false;
}
}
#endif
QgsRectangle viewExtent = mCanvas->extent();

// TODO: extent, width, heigh are approximated only if layer is reprojected!!!!
// How to do it better? We dont know source resolution used to reproject the layer.
QMap< QString, QString > attributes, derivedAttributes;

QgsRectangle viewExtent = mCanvas->extent();
// We can only use context (extent, width, heigh) if layer is not reprojected,
// otherwise we don't know source resolution (size).
if ( mCanvas->hasCrsTransformEnabled() && dprovider->crs() != mCanvas->mapRenderer()->destinationCrs() )
{
viewExtent = toLayerCoordinates( layer, viewExtent );
attributes = dprovider->identify( idPoint );
}
else
{
// It would be nice to use the same extent and size which was used for drawing,
// so that WCS can use cache from last draw, unfortunately QgsRasterLayer::draw()
// is doing some tricks with extent and size to allign raster to output which
// would be difficult to replicate here.
// Note: cutting the extent may result in slightly different x and y resolutions
// and thus shifted point calculated back in QGIS WMS (using average resolution)
//viewExtent = dprovider->extent().intersect( &viewExtent );

// cut by layer extent to use possible cache, the same done when drawing
viewExtent = dprovider->extent().intersect( &viewExtent );

double mapUnitsPerPixel = mCanvas->mapUnitsPerPixel();
// Width and height are calculated from not projected extent and we hope that
// are similar to source width and height used to reproject layer for drawing.
int width = mCanvas->extent().width() / mapUnitsPerPixel;
int height = mCanvas->extent().height() / mapUnitsPerPixel;

QMap< QString, QString > attributes, derivedAttributes;

attributes = dprovider->identify( idPoint, viewExtent, width, height );
double mapUnitsPerPixel = mCanvas->mapUnitsPerPixel();
// Width and height are calculated from not projected extent and we hope that
// are similar to source width and height used to reproject layer for drawing.
// TODO: may be very dangerous, because it may result in different resolutions
// in source CRS, and WMS server (QGIS server) calcs wrong coor using average resolution.
int width = qRound( viewExtent.width() / mapUnitsPerPixel );
int height = qRound( viewExtent.height() / mapUnitsPerPixel );

QgsDebugMsg( QString( "viewExtent.width = %1 viewExtent.height = %2" ).arg( viewExtent.width() ).arg( viewExtent.height() ) );
QgsDebugMsg( QString( "width = %1 height = %2" ).arg( width ).arg( height ) );
QgsDebugMsg( QString( "xRes = %1 yRes = %2 mapUnitsPerPixel = %3" ).arg( viewExtent.width() / width ).arg( viewExtent.height() / height ).arg( mapUnitsPerPixel ) );

attributes = dprovider->identify( idPoint, viewExtent, width, height );
}

QString type;
type = tr( "Raster" );
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsprojectlayergroupdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ void QgsProjectLayerGroupDialog::changeProjectFile()
//check we are not embedding from/to the same project
if ( mProjectFileLineEdit->isVisible() && mProjectFileLineEdit->text() == QgsProject::instance()->fileName() )
{
QMessageBox::critical( 0, tr( "Recursive embeding not possible" ), tr( "It is not possible to embed layers / groups from the current project" ) );
QMessageBox::critical( 0, tr( "Recursive embedding not possible" ), tr( "It is not possible to embed layers / groups from the current project." ) );
return;
}

Expand Down
141 changes: 133 additions & 8 deletions src/app/qgsprojectproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include "qgsrenderer.h"
#include "qgssnappingdialog.h"
#include "qgsrasterlayer.h"
#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h"
#include "qgsscaleutils.h"
#include "qgsgenericprojectionselector.h"
#include "qgsstylev2.h"
Expand Down Expand Up @@ -298,8 +300,20 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
}

QStringList wfsLayerIdList = QgsProject::instance()->readListEntry( "WFSLayers", "/" );

twWFSLayers->setColumnCount( 2 );
QStringList wfstUpdateLayerIdList = QgsProject::instance()->readListEntry( "WFSTLayers", "Update" );
QStringList wfstInsertLayerIdList = QgsProject::instance()->readListEntry( "WFSTLayers", "Insert" );
QStringList wfstDeleteLayerIdList = QgsProject::instance()->readListEntry( "WFSTLayers", "Delete" );

QSignalMapper *smPublied = new QSignalMapper(this);
connect(smPublied, SIGNAL(mapped(int)), this, SLOT(on_cbxWFSPublied_stateChanged(int)));
QSignalMapper *smUpdate = new QSignalMapper(this);
connect(smUpdate, SIGNAL(mapped(int)), this, SLOT(on_cbxWFSUpdate_stateChanged(int)));
QSignalMapper *smInsert = new QSignalMapper(this);
connect(smInsert, SIGNAL(mapped(int)), this, SLOT(on_cbxWFSInsert_stateChanged(int)));
QSignalMapper *smDelete = new QSignalMapper(this);
connect(smDelete, SIGNAL(mapped(int)), this, SLOT(on_cbxWFSDelete_stateChanged(int)));

twWFSLayers->setColumnCount( 5 );
twWFSLayers->horizontalHeader()->setVisible( true );
twWFSLayers->setRowCount( mapLayers.size() );

Expand All @@ -319,11 +333,44 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
twi->setFlags( twi->flags() & ~Qt::ItemIsEditable );
twWFSLayers->setItem( j, 0, twi );

QCheckBox *cb = new QCheckBox();
cb->setChecked( wfsLayerIdList.contains( currentLayer->id() ) );
twWFSLayers->setCellWidget( j, 1, cb );
j++;
QCheckBox* cbp = new QCheckBox();
cbp->setChecked( wfsLayerIdList.contains( currentLayer->id() ) );
twWFSLayers->setCellWidget( j, 1, cbp );

smPublied->setMapping(cbp, j);
connect(cbp, SIGNAL(stateChanged(int)), smPublied, SLOT(map()));

QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>( currentLayer );
QgsVectorDataProvider* provider = vlayer->dataProvider();
if ( (provider->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) && (provider->capabilities() & QgsVectorDataProvider::ChangeGeometries ) )
{
QCheckBox* cbu = new QCheckBox();
cbu->setChecked( wfstUpdateLayerIdList.contains( currentLayer->id() ) );
twWFSLayers->setCellWidget( j, 2, cbu );

smUpdate->setMapping(cbu, j);
connect(cbu, SIGNAL(stateChanged(int)), smUpdate, SLOT(map()));
}
if ( ( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) )
{
QCheckBox* cbi = new QCheckBox();
cbi->setChecked( wfstInsertLayerIdList.contains( currentLayer->id() ) );
twWFSLayers->setCellWidget( j, 3, cbi );

smInsert->setMapping(cbi, j);
connect(cbi, SIGNAL(stateChanged(int)), smInsert, SLOT(map()));
}
if ( ( provider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) )
{
QCheckBox* cbd = new QCheckBox();
cbd->setChecked( wfstDeleteLayerIdList.contains( currentLayer->id() ) );
twWFSLayers->setCellWidget( j, 4, cbd );

smDelete->setMapping(cbd, j);
connect(cbd, SIGNAL(stateChanged(int)), smDelete, SLOT(map()));
}

j++;
}
}
twWFSLayers->setRowCount( j );
Expand Down Expand Up @@ -610,16 +657,38 @@ void QgsProjectProperties::apply()
}

QStringList wfsLayerList;
QStringList wfstUpdateLayerList;
QStringList wfstInsertLayerList;
QStringList wfstDeleteLayerList;
for ( int i = 0; i < twWFSLayers->rowCount(); i++ )
{
QCheckBox *cb = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( i, 1 ) );
QString id = twWFSLayers->item( i, 0 )->data( Qt::UserRole ).toString();
QCheckBox* cb;
cb = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( i, 1 ) );
if ( cb && cb->isChecked() )
{
QString id = twWFSLayers->item( i, 0 )->data( Qt::UserRole ).toString();
wfsLayerList << id;
}
cb = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( i, 2 ) );
if ( cb && cb->isChecked() )
{
wfstUpdateLayerList << id;
}
cb = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( i, 3 ) );
if ( cb && cb->isChecked() )
{
wfstInsertLayerList << id;
}
cb = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( i, 4 ) );
if ( cb && cb->isChecked() )
{
wfstDeleteLayerList << id;
}
}
QgsProject::instance()->writeEntry( "WFSLayers", "/", wfsLayerList );
QgsProject::instance()->writeEntry( "WFSTLayers", "Update", wfstUpdateLayerList );
QgsProject::instance()->writeEntry( "WFSTLayers", "Insert", wfstInsertLayerList );
QgsProject::instance()->writeEntry( "WFSTLayers", "Delete", wfstDeleteLayerList );

// Default Styles
QgsProject::instance()->writeEntry( "DefaultStyles", "/Marker", cboStyleMarker->currentText() );
Expand Down Expand Up @@ -691,6 +760,62 @@ void QgsProjectProperties::on_cbxProjectionEnabled_stateChanged( int state )
}
}

void QgsProjectProperties::on_cbxWFSPublied_stateChanged( int aIdx )
{
QCheckBox* cb = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( aIdx, 1 ) );
if ( cb && !cb->isChecked() )
{
QCheckBox* cbn = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( aIdx, 2 ) );
if ( cbn )
cbn->setChecked(false);
}
}

void QgsProjectProperties::on_cbxWFSUpdate_stateChanged( int aIdx )
{
QCheckBox* cb = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( aIdx, 2 ) );
if ( cb && cb->isChecked() )
{
QCheckBox* cbn = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( aIdx, 1 ) );
if ( cbn )
cbn->setChecked(true);
}
else if ( cb && !cb->isChecked() )
{
QCheckBox* cbn = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( aIdx, 3 ) );
if ( cbn )
cbn->setChecked(false);
}
}

void QgsProjectProperties::on_cbxWFSInsert_stateChanged( int aIdx )
{
QCheckBox* cb = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( aIdx, 3 ) );
if ( cb && cb->isChecked() )
{
QCheckBox* cbn = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( aIdx, 2 ) );
if ( cbn )
cbn->setChecked(true);
}
else if ( cb && !cb->isChecked() )
{
QCheckBox* cbn = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( aIdx, 4 ) );
if ( cbn )
cbn->setChecked(false);
}
}

void QgsProjectProperties::on_cbxWFSDelete_stateChanged( int aIdx )
{
QCheckBox* cb = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( aIdx, 4 ) );
if ( cb && cb->isChecked() )
{
QCheckBox* cbn = qobject_cast<QCheckBox *>( twWFSLayers->cellWidget( aIdx, 3 ) );
if ( cbn )
cbn->setChecked(true);
}
}

void QgsProjectProperties::setMapUnitsToCurrentProjection()
{
long myCRSID = projectionSelector->selectedCrsId();
Expand Down
8 changes: 8 additions & 0 deletions src/app/qgsprojectproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ class QgsProjectProperties : public QDialog, private Ui::QgsProjectPropertiesBas
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }

void on_cbxProjectionEnabled_stateChanged( int state );

/*!
* Slot to link WFS checkboxes
*/
void on_cbxWFSPublied_stateChanged( int aIdx );
void on_cbxWFSUpdate_stateChanged( int aIdx );
void on_cbxWFSInsert_stateChanged( int aIdx );
void on_cbxWFSDelete_stateChanged( int aIdx );

/*!
* If user changes the CRS, set the corresponding map units
Expand Down
1 change: 1 addition & 0 deletions src/app/qgsrasterlayerproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,7 @@ void QgsRasterLayerProperties::on_pbnExportTransparentPixelValues_clicked()

void QgsRasterLayerProperties::transparencyCellTextEdited( const QString & text )
{
Q_UNUSED( text );
QgsDebugMsg( QString( "text = %1" ).arg( text ) );
QgsRasterRenderer* renderer = mRendererWidget->renderer();
if ( !renderer )
Expand Down
6 changes: 3 additions & 3 deletions src/core/qgis.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,20 @@ inline bool doubleNearSig( double a, double b, int significantDigits = 10 )
Works like C malloc() but prints debug message by QgsLogger if allocation fails.
@param size size in bytes
*/
void *QgsMalloc( size_t size );
void CORE_EXPORT *QgsMalloc( size_t size );

/** Allocates memory for an array of nmemb elements of size bytes each and returns
a pointer to the allocated memory. Works like C calloc() but prints debug message
by QgsLogger if allocation fails.
@param nmemb number of elements
@param size size of element in bytes
*/
void *QgsCalloc( size_t nmemb, size_t size );
void CORE_EXPORT *QgsCalloc( size_t nmemb, size_t size );

/** Frees the memory space pointed to by ptr. Works like C free().
@param ptr pointer to memory space
*/
void QgsFree( void *ptr );
void CORE_EXPORT QgsFree( void *ptr );

/** Wkt string that represents a geographic coord sys
* @note added in 1.8 to replace GEOWkt
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgscoordinatereferencesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@ void QgsCoordinateReferenceSystem::setupESRIWktFix( )
QgsDebugMsg( QString( "set GDAL_FIX_ESRI_WKT : %1" ).arg( configNew ) );
}
else
{
QgsDebugMsg( QString( "GDAL_FIX_ESRI_WKT was already set : %1" ).arg( configNew ) );
}
#endif
}

Expand Down
959 changes: 935 additions & 24 deletions src/core/qgsgeometry.cpp

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions src/core/qgsgeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ email : morb at ozemail dot com dot au

#include <QString>
#include <QVector>
#include <QDomDocument>

#include "qgis.h"

Expand Down Expand Up @@ -88,6 +89,11 @@ class CORE_EXPORT QgsGeometry
/** static method that creates geometry from Wkt */
static QgsGeometry* fromWkt( QString wkt );

/** static method that creates geometry from GML2
@note added in 1.9
*/
static QgsGeometry* fromGML2( const QDomNode& geometryNode );

/** construct geometry from a point */
static QgsGeometry* fromPoint( const QgsPoint& point );
/** construct geometry from a multipoint */
Expand Down Expand Up @@ -383,6 +389,12 @@ class CORE_EXPORT QgsGeometry
*/
QString exportToGeoJSON();

/** Exports the geometry to mGML2
@return true in case of success and false else
* @note added in 1.9
*/
QDomElement exportToGML2( QDomDocument& doc );

/* Accessor functions for getting geometry data */

/** return contents of the geometry as a point
Expand Down Expand Up @@ -488,6 +500,24 @@ class CORE_EXPORT QgsGeometry

// Private functions

/** static method that creates geometry from GML2 Point */
bool setFromGML2Point( const QDomElement& geometryElement );
/** static method that creates geometry from GML2 LineString */
bool setFromGML2LineString( const QDomElement& geometryElement );
/** static method that creates geometry from GML2 Polygon */
bool setFromGML2Polygon( const QDomElement& geometryElement );
/** static method that creates geometry from GML2 MultiPoint */
bool setFromGML2MultiPoint( const QDomElement& geometryElement );
/** static method that creates geometry from GML2 MultiLineString */
bool setFromGML2MultiLineString( const QDomElement& geometryElement );
/** static method that creates geometry from GML2 MultiPolygon */
bool setFromGML2MultiPolygon( const QDomElement& geometryElement );
/**Reads the <gml:coordinates> element and extracts the coordinates as points
@param coords list where the found coordinates are appended
@param elem the <gml:coordinates> element
@return boolean for success*/
bool readGML2Coordinates( std::list<QgsPoint>& coords, const QDomElement elem ) const;

/** Converts from the WKB geometry to the GEOS geometry.
@return true in case of success and false else
*/
Expand Down
4 changes: 4 additions & 0 deletions src/core/qgsmaprenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ void QgsMapRenderer::adjustExtentToSize()
mExtent.setYMinimum( dymin );
mExtent.setYMaximum( dymax );

QgsDebugMsg( QString( "Adjusted map units per pixel (x,y) : %1, %2" ).arg( mExtent.width() / myWidth, 0, 'f', 8 ).arg( mExtent.height() / myHeight, 0, 'f', 8 ) );

QgsDebugMsg( QString( "Recalced pixmap dimensions (x,y) : %1, %2" ).arg( mExtent.width() / mMapUnitsPerPixel, 0, 'f', 8 ).arg( mExtent.height() / mMapUnitsPerPixel, 0, 'f', 8 ) );

// update the scale
updateScale();

Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsvectorlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
@note added in version 1.2*/
QString attributeDisplayName( int attributeIndex ) const;

const QMap< QString, QString >& attributeAliases() const { return mAttributeAliasMap; }

const QSet<QString>& excludeAttributesWMS() const { return mExcludeAttributesWMS; }
void setExcludeAttributesWMS( const QSet<QString>& att ) { mExcludeAttributesWMS = att; }

Expand Down
15 changes: 6 additions & 9 deletions src/core/raster/qgsrasterblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ QgsRasterBlock::QgsRasterBlock( DataType theDataType, int theWidth, int theHeigh
QgsRasterBlock::~QgsRasterBlock()
{
QgsFree( mData );

delete mImage;
}

bool QgsRasterBlock::reset( DataType theDataType, int theWidth, int theHeight, double theNoDataValue )
Expand Down Expand Up @@ -253,7 +253,7 @@ bool QgsRasterBlock::isNoDataValue( double value ) const

double QgsRasterBlock::value( size_t index ) const
{
if ( index < 0 || index >= ( size_t )mWidth*mHeight )
if ( index >= ( size_t )mWidth*mHeight )
{
QgsDebugMsg( QString( "Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
return mNoDataValue;
Expand Down Expand Up @@ -282,7 +282,7 @@ QRgb QgsRasterBlock::color( int row, int column ) const

bool QgsRasterBlock::isNoData( size_t index )
{
if ( index < 0 || index >= ( size_t )mWidth*mHeight )
if ( index >= ( size_t )mWidth*mHeight )
{
QgsDebugMsg( QString( "Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
return true; // we consider no data if outside
Expand All @@ -303,7 +303,7 @@ bool QgsRasterBlock::setValue( size_t index, double value )
QgsDebugMsg( "Data block not allocated" );
return false;
}
if ( index < 0 || index >= ( size_t )mWidth*mHeight )
if ( index >= ( size_t )mWidth*mHeight )
{
QgsDebugMsg( QString( "Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
return false;
Expand Down Expand Up @@ -375,7 +375,7 @@ bool QgsRasterBlock::setIsNoData()
char * QgsRasterBlock::bits( size_t index )
{
// Not testing type to avoid too much overhead because this method is called per pixel
if ( index < 0 || index >= ( size_t )mWidth*mHeight )
if ( index >= ( size_t )mWidth*mHeight )
{
QgsDebugMsg( QString( "Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
return 0;
Expand Down Expand Up @@ -416,12 +416,9 @@ bool QgsRasterBlock::convert( QgsRasterBlock::DataType destDataType )
}
else if ( typeIsColor( mDataType ) && typeIsColor( destDataType ) )
{
// It would be probably faster to convert value by value here instead of
// creating new image, QImage (4.8) does not have any method to convert in place
QImage::Format format = imageFormat( destDataType );
QImage image = mImage->convertToFormat( format );
memcpy( mImage->bits(), image.bits(), mImage->byteCount() );
//mImage = new QImage( mWidth, mHeight, format );
*mImage = image;
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/core/raster/qgsrasterinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class CORE_EXPORT QgsRasterInterface
virtual QgsRasterInterface * input() const { return mInput; }

/** Is on/off */
virtual bool on() { return mOn; }
virtual bool on() const { return mOn; }

/** Set on/off */
virtual void setOn( bool on ) { mOn = on; }
Expand Down
1 change: 1 addition & 0 deletions src/core/raster/qgsrasterprojector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,7 @@ QgsRasterBlock * QgsRasterProjector::block( int bandNo, QgsRectangle const & ex
if ( ! mSrcCRS.isValid() || ! mDestCRS.isValid() || mSrcCRS == mDestCRS )
{
QgsDebugMsg( "No projection necessary" );
delete outputBlock;
return mInput->block( bandNo, extent, width, height );
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/raster/qgsrasterrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const QRgb QgsRasterRenderer::NODATA_COLOR = qRgba( 0, 0, 0, 0 );
QgsRasterRenderer::QgsRasterRenderer( QgsRasterInterface* input, const QString& type )
: QgsRasterInterface( input )
, mType( type ), mOpacity( 1.0 ), mRasterTransparency( 0 )
, mAlphaBand( -1 ), mInvertColor( false ), mMaxOversampling( 2.0 )
, mAlphaBand( -1 ), mInvertColor( false )
{
}

Expand Down
3 changes: 0 additions & 3 deletions src/core/raster/qgsrasterrenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
int mAlphaBand;

bool mInvertColor;

/**Maximum boundary for oversampling (to avoid too much data traffic). Default: 2.0*/
double mMaxOversampling;
};

#endif // QGSRASTERRENDERER_H
10 changes: 10 additions & 0 deletions src/core/symbology-ng/qgscptcityarchive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,15 @@ QMap< QString, QString > QgsCptCityArchive::description( const QString& fileName

QDomElement e = docElem.firstChildElement( "name" );
if ( e.isNull() )
{
QgsDebugMsg( "name tag missing" );
}
descMap[ "name" ] = e.text().simplified();
e = docElem.firstChildElement( "full" );
if ( e.isNull() )
{
QgsDebugMsg( "full tag missing" );
}
descMap[ "full" ] = e.text().simplified();

return descMap;
Expand Down Expand Up @@ -376,7 +380,9 @@ QMap< double, QPair<QColor, QColor> >QgsCptCityArchive::gradientColorMap( const
colorMap[offset] = qMakePair( color, color );
}
else
{
QgsDebugMsg( QString( "at offset=%1 invalid color" ).arg( offset ) );
}
}
else
{
Expand Down Expand Up @@ -460,7 +466,9 @@ void QgsCptCityArchive::initArchives( bool loadAll )
if ( QDir( it.value() ).exists() )
QgsCptCityArchive::initArchive( it.key(), it.value() );
else
{
QgsDebugMsg( QString( "not loading archive [%1] because dir %2 does not exist " ).arg( it.key() ).arg( it.value() ) );
}
}
mDefaultArchiveName = defArchiveName;
}
Expand Down Expand Up @@ -837,7 +845,9 @@ QVector< QgsCptCityDataItem* > QgsCptCityCollectionItem::childrenRamps( bool rec
// should also delete item from parent, but we are in a loop now
}
else
{
QgsDebugMsg( "invalid item " + childItem->path() );
}
}
return rampItems;
}
Expand Down
4 changes: 4 additions & 0 deletions src/gui/qgscollapsiblegroupbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,13 @@ void QgsCollapsibleGroupBox::showEvent( QShowEvent * event )
else
mParentScrollArea = 0;
if ( mParentScrollArea )
{
QgsDebugMsg( "found a QScrollArea parent: " + mParentScrollArea->objectName() );
}
else
{
QgsDebugMsg( "did not find a QScrollArea parent" );
}

loadState();

Expand Down
1 change: 1 addition & 0 deletions src/gui/raster/qgsmultibandcolorrendererwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ void QgsMultiBandColorRendererWidget::onBandChanged( int index )

void QgsMultiBandColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
{
Q_UNUSED( theOrigin );
QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );

QLineEdit *myMinLineEdit, *myMaxLineEdit;
Expand Down
1 change: 1 addition & 0 deletions src/gui/raster/qgssinglebandgrayrendererwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ QgsRasterRenderer* QgsSingleBandGrayRendererWidget::renderer()

void QgsSingleBandGrayRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
{
Q_UNUSED( theBandNo );
Q_UNUSED( theOrigin );
QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );

Expand Down
1 change: 1 addition & 0 deletions src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ void QgsSingleBandPseudoColorRendererWidget::on_mBandComboBox_currentIndexChange

void QgsSingleBandPseudoColorRendererWidget::loadMinMax( int theBandNo, double theMin, double theMax, int theOrigin )
{
Q_UNUSED( theBandNo );
QgsDebugMsg( QString( "theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );

if ( qIsNaN( theMin ) )
Expand Down
4 changes: 4 additions & 0 deletions src/gui/symbology-ng/qgscptcitycolorrampv2dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,9 @@ void QgsCptCityColorRampV2Dialog::updateTreeView( QgsCptCityDataItem *item, bool
updateListWidget( item );
}
else
{
QgsDebugMsg( QString( "item %1 has invalid type %2" ).arg( item->path() ).arg(( int )item->type() ) );
}
}

void QgsCptCityColorRampV2Dialog::on_mListWidget_itemClicked( QListWidgetItem * item )
Expand All @@ -308,7 +310,9 @@ void QgsCptCityColorRampV2Dialog::on_mListWidget_itemClicked( QListWidgetItem *
populateVariants();
}
else
{
QgsDebugMsg( QString( "item %1 has invalid type %2" ).arg( rampItem->path() ).arg(( int )rampItem->type() ) );
}
}

void QgsCptCityColorRampV2Dialog::on_tabBar_currentChanged( int index )
Expand Down
20 changes: 20 additions & 0 deletions src/mapserver/qgis_map_serv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,26 @@ int main( int argc, char * argv[] )
continue;
}
}
else if ( request == "Transaction" )
{
QDomDocument transactionDocument;
try
{
transactionDocument = theServer->transaction( parameterMap.value( "REQUEST_BODY" ) );
}
catch ( QgsMapServiceException& ex )
{
theRequestHandler->sendServiceException( ex );
delete theRequestHandler;
delete theServer;
continue;
}
QgsDebugMsg( "sending Transaction response" );
theRequestHandler->sendGetCapabilitiesResponse( transactionDocument );
delete theRequestHandler;
delete theServer;
continue;
}

return 0;
}
Expand Down
13 changes: 3 additions & 10 deletions src/mapserver/qgsconfigparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ class QgsConfigParser
virtual QStringList identifyDisabledLayers() const { return QStringList(); }
/**Returns an ID-list of layers which queryable in WFS service*/
virtual QStringList wfsLayers() const { return QStringList(); }
virtual QStringList wfstUpdateLayers() const { return QStringList(); }
virtual QStringList wfstInsertLayers() const { return QStringList(); }
virtual QStringList wfstDeleteLayers() const { return QStringList(); }

/**Returns a set of supported epsg codes for the capabilities document. An empty list means
that all possible CRS should be advertised (which could result in very long capabilities documents)*/
Expand All @@ -105,16 +108,6 @@ class QgsConfigParser
/**True if the feature info response should contain the wkt geometry for vector features*/
virtual bool featureInfoWithWktGeometry() const { return false; }

/**Returns information about vector layer aliases. First key is the layer id, (second) key is the field id, value the alias.
Default implementation returns an empty map*/
virtual QMap< QString, QMap< int, QString > > layerAliasInfo() const { return QMap< QString, QMap<int, QString> > (); }

/**Returns attributes excluded from WMS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wmsExcludedAttributes() const { return QMap< QString, QSet<QString> >(); }

/**Returns attributes excluded from WFS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wfsExcludedAttributes() const { return QMap< QString, QSet<QString> >(); }

/**Creates a print composition, usually for a GetPrint request. Replaces map and label parameters*/
QgsComposition* createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const;

Expand Down
35 changes: 33 additions & 2 deletions src/mapserver/qgspostrequesthandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
* (at your option) any later version. *
* *
***************************************************************************/

#include <stdlib.h>
#include "qgspostrequesthandler.h"
#include "qgslogger.h"
#include <QDomDocument>

QgsPostRequestHandler::QgsPostRequestHandler()
{
Expand All @@ -32,6 +33,36 @@ QMap<QString, QString> QgsPostRequestHandler::parseInput()
QMap<QString, QString> parameters;
QString inputString = readPostBody();
QgsDebugMsg( inputString );
requestStringToParameterMap( inputString, parameters );

QDomDocument doc;
QString errorMsg;
if ( !doc.setContent( inputString, true, &errorMsg ) )
{
requestStringToParameterMap( inputString, parameters );
}
else
{
QString queryString;
const char* qs = getenv( "QUERY_STRING" );
if ( qs )
{
queryString = QString( qs );
QgsDebugMsg( "query string is: " + queryString );
}
else
{
QgsDebugMsg( "error, no query string found but a QDomDocument" );
return parameters; //no query string? something must be wrong...
}

requestStringToParameterMap( queryString, parameters );

QDomElement docElem = doc.documentElement();
parameters.insert( "VERSION", docElem.attribute( "version" ) );
parameters.insert( "SERVICE", docElem.attribute( "service" ) );
parameters.insert( "REQUEST", docElem.localName() );
parameters.insert( "REQUEST_BODY", inputString );
}

return parameters;
}
251 changes: 162 additions & 89 deletions src/mapserver/qgsprojectparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement,
void QgsProjectParser::featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const
{
QStringList wfsLayersId = wfsLayers();
QStringList wfstUpdateLayersId = wfstUpdateLayers();
QStringList wfstInsertLayersId = wfstInsertLayers();
QStringList wfstDeleteLayersId = wfstDeleteLayers();

if ( mProjectLayerElements.size() < 1 )
{
Expand Down Expand Up @@ -194,6 +197,37 @@ void QgsProjectParser::featureTypeList( QDomElement& parentElement, QDomDocument
bBoxElement.setAttribute( "maxy", QString::number( layerExtent.yMaximum() ) );
layerElem.appendChild( bBoxElement );

//wfs:Operations element
QDomElement operationsElement = doc.createElement( "Operations"/*wfs:Operations*/ );
//wfs:Query element
QDomElement queryElement = doc.createElement( "Query"/*wfs:Query*/ );
operationsElement.appendChild( queryElement );

QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>( layer );
QgsVectorDataProvider* provider = vlayer->dataProvider();
if (( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) && wfstInsertLayersId.contains( layer->id() ) )
{
//wfs:Insert element
QDomElement insertElement = doc.createElement( "Insert"/*wfs:Insert*/ );
operationsElement.appendChild( insertElement );
}
if (( provider->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) &&
( provider->capabilities() & QgsVectorDataProvider::ChangeGeometries ) &&
wfstUpdateLayersId.contains( layer->id() ) )
{
//wfs:Update element
QDomElement updateElement = doc.createElement( "Update"/*wfs:Update*/ );
operationsElement.appendChild( updateElement );
}
if (( provider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) && wfstDeleteLayersId.contains( layer->id() ) )
{
//wfs:Delete element
QDomElement deleteElement = doc.createElement( "Delete"/*wfs:Delete*/ );
operationsElement.appendChild( deleteElement );
}

layerElem.appendChild( operationsElement );

parentElement.appendChild( layerElem );
}
}
Expand All @@ -209,8 +243,6 @@ void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElemen
}

QStringList wfsLayersId = wfsLayers();
QMap< QString, QMap< int, QString > > aliasInfo = layerAliasInfo();
QMap< QString, QSet<QString> > excludedAttrs = wfsExcludedAttributes();

foreach ( const QDomElement &elem, mProjectLayerElements )
{
Expand All @@ -228,21 +260,8 @@ void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElemen
continue;
}

//is there alias info for this vector layer?
QMap< int, QString > layerAliasInfo;
QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( mLayer->id() );
if ( aliasIt != aliasInfo.constEnd() )
{
layerAliasInfo = aliasIt.value();
}

//hidden attributes for this layer
QSet<QString> layerExcludedAttributes;
QMap< QString, QSet<QString> >::const_iterator exclIt = excludedAttrs.find( mLayer->id() );
if ( exclIt != excludedAttrs.constEnd() )
{
layerExcludedAttributes = exclIt.value();
}
const QSet<QString>& layerExcludedAttributes = layer->excludeAttributesWFS();

QString typeName = layer->name();
typeName = typeName.replace( QString( " " ), QString( "_" ) );
Expand Down Expand Up @@ -315,7 +334,7 @@ void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElemen
{

QString attributeName = it.value().name();
//skip attribute if it has edit type 'hidden'
//skip attribute if excluded from WFS publication
if ( layerExcludedAttributes.contains( attributeName ) )
{
continue;
Expand All @@ -333,11 +352,10 @@ void QgsProjectParser::describeFeatureType( const QString& aTypeName, QDomElemen

sequenceElem.appendChild( geomElem );

//check if the attribute name should be replaced with an alias
QMap<int, QString>::const_iterator aliasIt = layerAliasInfo.find( it.key() );
if ( aliasIt != layerAliasInfo.constEnd() )
QString alias = layer->attributeAlias( it.key() );
if ( !alias.isEmpty() )
{
geomElem.setAttribute( "alias", aliasIt.value() );
geomElem.setAttribute( "alias", alias );
}
}
}
Expand Down Expand Up @@ -549,6 +567,7 @@ void QgsProjectParser::addLayerProjectSettings( QDomElement& layerElem, QDomDocu
if ( currentLayer->type() == QgsMapLayer::VectorLayer )
{
QgsVectorLayer* vLayer = static_cast<QgsVectorLayer*>( currentLayer );
const QSet<QString>& excludedAttributes = vLayer->excludeAttributesWMS();

//displayfield
layerElem.setAttribute( "displayField", vLayer->displayField() );
Expand All @@ -559,8 +578,12 @@ void QgsProjectParser::addLayerProjectSettings( QDomElement& layerElem, QDomDocu
QgsFieldMap::const_iterator fieldIt = layerFields.constBegin();
for ( ; fieldIt != layerFields.constEnd(); ++fieldIt )
{
if ( excludedAttributes.contains( fieldIt->name() ) )
{
continue;
}
QDomElement attributeElem = doc.createElement( "Attribute" );
attributeElem.setAttribute( "name", fieldIt->name() );
attributeElem.setAttribute( "name", vLayer->attributeDisplayName( fieldIt.key() ) );
attributeElem.setAttribute( "type", QVariant::typeToName( fieldIt->type() ) );

//edit type to text
Expand Down Expand Up @@ -954,6 +977,123 @@ QStringList QgsProjectParser::wfsLayers() const
return wfsList;
}

QStringList QgsProjectParser::wfstUpdateLayers() const
{
QStringList publiedIds = wfsLayers();
QStringList wfsList;
if ( !mXMLDoc )
{
return wfsList;
}

QDomElement qgisElem = mXMLDoc->documentElement();
if ( qgisElem.isNull() )
{
return wfsList;
}
QDomElement propertiesElem = qgisElem.firstChildElement( "properties" );
if ( propertiesElem.isNull() )
{
return wfsList;
}
QDomElement wfstLayersElem = propertiesElem.firstChildElement( "WFSTLayers" );
if ( wfstLayersElem.isNull() )
{
return wfsList;
}
QDomElement wfstUpdateLayersElem = wfstLayersElem.firstChildElement( "Update" );
if ( wfstUpdateLayersElem.isNull() )
{
return wfsList;
}
QDomNodeList valueList = wfstUpdateLayersElem.elementsByTagName( "value" );
for ( int i = 0; i < valueList.size(); ++i )
{
QString id = valueList.at( i ).toElement().text();
if ( publiedIds.contains( id ) )
wfsList << id;
}
return wfsList;
}

QStringList QgsProjectParser::wfstInsertLayers() const
{
QStringList updateIds = wfstUpdateLayers();
QStringList wfsList;
if ( !mXMLDoc )
{
return wfsList;
}

QDomElement qgisElem = mXMLDoc->documentElement();
if ( qgisElem.isNull() )
{
return wfsList;
}
QDomElement propertiesElem = qgisElem.firstChildElement( "properties" );
if ( propertiesElem.isNull() )
{
return wfsList;
}
QDomElement wfstLayersElem = propertiesElem.firstChildElement( "WFSTLayers" );
if ( wfstLayersElem.isNull() )
{
return wfsList;
}
QDomElement wfstInsertLayersElem = wfstLayersElem.firstChildElement( "Insert" );
if ( wfstInsertLayersElem.isNull() )
{
return wfsList;
}
QDomNodeList valueList = wfstInsertLayersElem.elementsByTagName( "value" );
for ( int i = 0; i < valueList.size(); ++i )
{
QString id = valueList.at( i ).toElement().text();
if ( updateIds.contains( id ) )
wfsList << id;
}
return wfsList;
}

QStringList QgsProjectParser::wfstDeleteLayers() const
{
QStringList insertIds = wfstInsertLayers();
QStringList wfsList;
if ( !mXMLDoc )
{
return wfsList;
}

QDomElement qgisElem = mXMLDoc->documentElement();
if ( qgisElem.isNull() )
{
return wfsList;
}
QDomElement propertiesElem = qgisElem.firstChildElement( "properties" );
if ( propertiesElem.isNull() )
{
return wfsList;
}
QDomElement wfstLayersElem = propertiesElem.firstChildElement( "WFSTLayers" );
if ( wfstLayersElem.isNull() )
{
return wfsList;
}
QDomElement wfstDeleteLayersElem = wfstLayersElem.firstChildElement( "Delete" );
if ( wfstDeleteLayersElem.isNull() )
{
return wfsList;
}
QDomNodeList valueList = wfstDeleteLayersElem.elementsByTagName( "value" );
for ( int i = 0; i < valueList.size(); ++i )
{
QString id = valueList.at( i ).toElement().text();
if ( insertIds.contains( id ) )
wfsList << id;
}
return wfsList;
}

QStringList QgsProjectParser::supportedOutputCrsList() const
{
QStringList crsList;
Expand Down Expand Up @@ -1029,73 +1169,6 @@ bool QgsProjectParser::featureInfoWithWktGeometry() const
return ( wktElem.text().compare( "true", Qt::CaseInsensitive ) == 0 );
}

QMap< QString, QMap< int, QString > > QgsProjectParser::layerAliasInfo() const
{
QMap< QString, QMap< int, QString > > resultMap;

QList<QDomElement>::const_iterator layerIt = mProjectLayerElements.constBegin();
for ( ; layerIt != mProjectLayerElements.constEnd(); ++layerIt )
{
QDomNodeList aNodeList = layerIt->elementsByTagName( "aliases" );
if ( aNodeList.size() > 0 )
{
QMap<int, QString> aliasMap;
QDomNodeList aliasNodeList = aNodeList.at( 0 ).toElement().elementsByTagName( "alias" );
for ( int i = 0; i < aliasNodeList.size(); ++i )
{
QDomElement aliasElem = aliasNodeList.at( i ).toElement();
aliasMap.insert( aliasElem.attribute( "index" ).toInt(), aliasElem.attribute( "name" ) );
}
resultMap.insert( layerId( *layerIt ) , aliasMap );
}
}

return resultMap;
}

QMap< QString, QSet<QString> > QgsProjectParser::wmsExcludedAttributes() const
{
QMap< QString, QSet<QString> > resultMap;
QList<QDomElement>::const_iterator layerIt = mProjectLayerElements.constBegin();
for ( ; layerIt != mProjectLayerElements.constEnd(); ++layerIt )
{
QDomElement excludeWMSElem = layerIt->firstChildElement( "excludeAttributesWMS" );
QDomNodeList attributeNodeList = excludeWMSElem.elementsByTagName( "attribute" );
if ( attributeNodeList.size() > 0 )
{
QSet<QString> layerExcludedAttributes;
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
layerExcludedAttributes.insert( attributeNodeList.at( i ).toElement().text() );
}
resultMap.insert( layerId( *layerIt ), layerExcludedAttributes );
}
}
return resultMap;
}

/**Returns attributes excluded from WFS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
QMap< QString, QSet<QString> > QgsProjectParser::wfsExcludedAttributes() const
{
QMap< QString, QSet<QString> > resultMap;
QList<QDomElement>::const_iterator layerIt = mProjectLayerElements.constBegin();
for ( ; layerIt != mProjectLayerElements.constEnd(); ++layerIt )
{
QDomElement excludeWMSElem = layerIt->firstChildElement( "excludeAttributesWFS" );
QDomNodeList attributeNodeList = excludeWMSElem.elementsByTagName( "attribute" );
if ( attributeNodeList.size() > 0 )
{
QSet<QString> layerExcludedAttributes;
for ( int i = 0; i < attributeNodeList.size(); ++i )
{
layerExcludedAttributes.insert( attributeNodeList.at( i ).toElement().text() );
}
resultMap.insert( layerId( *layerIt ), layerExcludedAttributes );
}
}
return resultMap;
}

QgsRectangle QgsProjectParser::mapRectangle() const
{
if ( !mXMLDoc )
Expand Down
13 changes: 3 additions & 10 deletions src/mapserver/qgsprojectparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class QgsProjectParser: public QgsConfigParser

/**Returns an ID-list of layers queryable for WFS service (comes from <properties> -> <WFSLayers> in the project file*/
virtual QStringList wfsLayers() const;
virtual QStringList wfstUpdateLayers() const;
virtual QStringList wfstInsertLayers() const;
virtual QStringList wfstDeleteLayers() const;

/**Returns a set of supported epsg codes for the capabilities document. The list comes from the property <WMSEpsgList> in the project file.
An empty set means that all possible CRS should be advertised (which could result in very long capabilities documents)
Expand All @@ -83,16 +86,6 @@ class QgsProjectParser: public QgsConfigParser
/**True if the feature info response should contain the wkt geometry for vector features*/
virtual bool featureInfoWithWktGeometry() const;

/**Returns information about vector layer aliases. First key is the layer id, (second) key is the field id, value the alias.
Default implementation returns an empty map*/
virtual QMap< QString, QMap< int, QString > > layerAliasInfo() const;

/**Returns attributes excluded from WMS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wmsExcludedAttributes() const;

/**Returns attributes excluded from WFS publication. Key is layer id, value is a set containing the names of the hidden attributes*/
virtual QMap< QString, QSet<QString> > wfsExcludedAttributes() const;

/**Returns map rectangle for the project file*/
QgsRectangle mapRectangle() const;

Expand Down
678 changes: 450 additions & 228 deletions src/mapserver/qgswfsserver.cpp

Large diffs are not rendered by default.

22 changes: 12 additions & 10 deletions src/mapserver/qgswfsserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <QMap>
#include <QString>
#include <map>
#include "qgis.h"
#include "qgsvectorlayer.h"

class QgsCoordinateReferenceSystem;
class QgsComposerLayerItem;
Expand Down Expand Up @@ -66,6 +68,10 @@ class QgsWFSServer
@return 0 in case of success*/
int getFeature( QgsRequestHandler& request, const QString& format );

/**Read and apply the transaction
@return 0 in case of success*/
QDomDocument transaction( const QString& requestBody );

/**Sets configuration parser for administration settings. Does not take ownership*/
void setAdminConfigParser( QgsConfigParser* parser ) { mConfigParser = parser; }

Expand All @@ -85,26 +91,22 @@ class QgsWFSServer
void sendGetFeature( QgsRequestHandler& request, const QString& format, QgsFeature* feat, int featIdx, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes );
void endGetFeature( QgsRequestHandler& request, const QString& format );

//method for transaction
QgsFeatureIds getFeatureIdsFromFilter( QDomElement filter, QgsVectorLayer* layer );

//methods to write GeoJSON
QString createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/;

//methods to write GML2
QDomElement createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/;
QDomElement createFeatureGML2( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> excludedAttributes ) /*const*/;

QDomElement createBoxElem( QgsRectangle* box, QDomDocument& doc ) /* const */;
QDomElement createGeometryElem( QgsGeometry* g, QDomDocument& doc ) /*const*/;
QDomElement createLineStringElem( QgsGeometry* geom, QDomDocument& doc ) const;
QDomElement createMultiLineStringElem( QgsGeometry* geom, QDomDocument& doc ) const;
QDomElement createPointElem( QgsGeometry* geom, QDomDocument& doc ) const;
QDomElement createMultiPointElem( QgsGeometry* geom, QDomDocument& doc ) const;
QDomElement createPolygonElem( QgsGeometry* geom, QDomDocument& doc ) const;
QDomElement createMultiPolygonElem( QgsGeometry* geom, QDomDocument& doc ) const;
QDomElement createBoxGML2( QgsRectangle* box, QDomDocument& doc ) /* const */;

/**Create a GML coordinate string from a point list.
@param points list of data points
@param coordString out: GML coord string
@return 0 in case of success*/
QDomElement createCoordinateElem( const QVector<QgsPoint> points, QDomDocument& doc ) const;
QDomElement createCoordinateGML2( const QVector<QgsPoint> points, QDomDocument& doc ) const;
};

#endif
82 changes: 45 additions & 37 deletions src/mapserver/qgswmsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,10 @@ QDomDocument QgsWMSServer::getCapabilities( QString version, bool fullProjectInf
{
//Insert <ComposerTemplate> elements derived from wms:_ExtendedCapabilities
mConfigParser->printCapabilities( capabilityElement, doc );
}

if ( mConfigParser && fullProjectInformation )
{
//WFS layers
QStringList wfsLayers = mConfigParser->wfsLayerNames();
if ( wfsLayers.size() > 0 )
Expand Down Expand Up @@ -648,6 +651,10 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )
return 2;
}

QgsDebugMsg( "mMapRenderer->extent(): " + mMapRenderer->extent().toString() );
QgsDebugMsg( QString( "mMapRenderer width = %1 height = %2" ).arg( mMapRenderer->outputSize().width() ).arg( mMapRenderer->outputSize().height() ) );
QgsDebugMsg( QString( "mMapRenderer->mapUnitsPerPixel() = %1" ).arg( mMapRenderer->mapUnitsPerPixel() ) );

//find out the current scale denominater and set it to the SLD parser
QgsScaleCalculator scaleCalc(( outputImage->logicalDpiX() + outputImage->logicalDpiY() ) / 2 , mMapRenderer->destinationCrs().mapUnits() );
QgsRectangle mapExtent = mMapRenderer->extent();
Expand Down Expand Up @@ -726,8 +733,6 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )
result.appendChild( getFeatureInfoElement );

QStringList nonIdentifiableLayers = mConfigParser->identifyDisabledLayers();
QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo();
QMap< QString, QSet<QString> > excludedAttributes = mConfigParser->wmsExcludedAttributes();

//Render context is needed to determine feature visibility for vector layers
QgsRenderContext renderContext;
Expand Down Expand Up @@ -776,24 +781,8 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, QString version )
QgsVectorLayer* vectorLayer = dynamic_cast<QgsVectorLayer*>( currentLayer );
if ( vectorLayer )
{
//is there alias info for this vector layer?
QMap< int, QString > layerAliasInfo;
QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( currentLayer->id() );
if ( aliasIt != aliasInfo.constEnd() )
{
layerAliasInfo = aliasIt.value();
}

//excluded attributes for this layer
QSet<QString> layerExcludedAttributes;
QMap< QString, QSet<QString> >::const_iterator excludedIt = excludedAttributes.find( currentLayer->id() );
if ( excludedIt != excludedAttributes.constEnd() )
{
layerExcludedAttributes = excludedIt.value();
}

if ( featureInfoFromVectorLayer( vectorLayer, infoPoint, featureCount, result, layerElement, mMapRenderer, renderContext,
layerAliasInfo, layerExcludedAttributes, version, featuresRect ) != 0 )
version, featuresRect ) != 0 )
{
continue;
}
Expand Down Expand Up @@ -1127,9 +1116,28 @@ int QgsWMSServer::infoPointToLayerCoordinates( int i, int j, QgsPoint* layerCoor
}

//first transform i,j to map output coordinates
QgsPoint mapPoint = mapRender->coordinateTransform()->toMapCoordinates( i, j );
// toMapCoordinates() is currently (Oct 18 2012) using average resolution
// to calc point but GetFeatureInfo request may be sent with different
// resolutions in each axis
//QgsPoint mapPoint = mapRender->coordinateTransform()->toMapCoordinates( i, j );
double xRes = mapRender->extent().width() / mapRender->width();
double yRes = mapRender->extent().height() / mapRender->height();
QgsPoint mapPoint( mapRender->extent().xMinimum() + i * xRes,
mapRender->extent().yMaximum() - j * yRes );

QgsDebugMsg( QString( "mapPoint (corner): %1 %2" ).arg( mapPoint.x() ).arg( mapPoint.y() ) );
// use pixel center instead of corner
// Unfortunately going through pixel (integer) we cannot reconstruct precisely
// the coordinate clicked on client and thus result may differ from
// the same raster loaded and queried localy on client
mapPoint.setX( mapPoint.x() + xRes / 2 );
mapPoint.setY( mapPoint.y() - yRes / 2 );

QgsDebugMsg( QString( "mapPoint (pixel center): %1 %2" ).arg( mapPoint.x() ).arg( mapPoint.y() ) );

//and then to layer coordinates
*layerCoords = mapRender->mapToLayerCoordinates( layer, mapPoint );
QgsDebugMsg( QString( "mapPoint: %1 %2" ).arg( mapPoint.x() ).arg( mapPoint.y() ) );
return 0;
}

Expand All @@ -1140,8 +1148,6 @@ int QgsWMSServer::featureInfoFromVectorLayer( QgsVectorLayer* layer,
QDomElement& layerElement,
QgsMapRenderer* mapRender,
QgsRenderContext& renderContext,
QMap<int, QString>& aliasMap,
QSet<QString>& excludedAttributes,
QString version,
QgsRectangle* featureBBox ) const
{
Expand Down Expand Up @@ -1185,6 +1191,7 @@ int QgsWMSServer::featureInfoFromVectorLayer( QgsVectorLayer* layer,
int featureCounter = 0;
const QgsFieldMap& fields = provider->fields();
bool addWktGeometry = mConfigParser && mConfigParser->featureInfoWithWktGeometry();
const QSet<QString>& excludedAttributes = layer->excludeAttributesWMS();

provider->select( provider->attributeIndexes(), searchRect, addWktGeometry || featureBBox, true );
while ( provider->nextFeature( feature ) )
Expand Down Expand Up @@ -1229,24 +1236,14 @@ int QgsWMSServer::featureInfoFromVectorLayer( QgsVectorLayer* layer,
featureAttributes = feature.attributeMap();
for ( QgsAttributeMap::const_iterator it = featureAttributes.begin(); it != featureAttributes.end(); ++it )
{

QString attributeName = fields[it.key()].name();
//skip attribute if it is explicitely excluded from WMS publication
if ( excludedAttributes.contains( attributeName ) )
if ( excludedAttributes.contains( fields[it.key()].name() ) )
{
continue;
}

//check if the attribute name should be replaced with an alias
QMap<int, QString>::const_iterator aliasIt = aliasMap.find( it.key() );
if ( aliasIt != aliasMap.constEnd() )
{
QString aliasName = aliasIt.value();
if ( !aliasName.isEmpty() )
{
attributeName = aliasName;
}
}
//replace attribute name if there is an attribute alias?
QString attributeName = layer->attributeDisplayName( it.key() );

QDomElement attributeElement = infoDocument.createElement( "Attribute" );
attributeElement.setAttribute( "name", attributeName );
Expand Down Expand Up @@ -1303,9 +1300,20 @@ int QgsWMSServer::featureInfoFromRasterLayer( QgsRasterLayer* layer,
return 1;
}

QgsDebugMsg( QString( "infoPoint: %1 %2" ).arg( infoPoint->x() ).arg( infoPoint->y() ) );

QMap<QString, QString> attributes;
// TODO: use context extent, width height (comes with request) to use WCS cache
attributes = layer->dataProvider()->identify( *infoPoint );
// use context extent, width height (comes with request) to use WCS cache
// We can only use context if raster is not reprojected, otherwise it is difficult
// to guess correct source resolution
if ( mMapRenderer->hasCrsTransformEnabled() && layer->dataProvider()->crs() != mMapRenderer->destinationCrs() )
{
attributes = layer->dataProvider()->identify( *infoPoint );
}
else
{
attributes = layer->dataProvider()->identify( *infoPoint, mMapRenderer->extent(), mMapRenderer->outputSize().width(), mMapRenderer->outputSize().height() );
}

for ( QMap<QString, QString>::const_iterator it = attributes.constBegin(); it != attributes.constEnd(); ++it )
{
Expand Down
2 changes: 1 addition & 1 deletion src/mapserver/qgswmsserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class QgsWMSServer
@param featureBBox the bounding box of the selected features in output CRS
@return 0 in case of success*/
int featureInfoFromVectorLayer( QgsVectorLayer* layer, const QgsPoint* infoPoint, int nFeatures, QDomDocument& infoDocument, QDomElement& layerElement, QgsMapRenderer* mapRender,
QgsRenderContext& renderContext, QMap<int, QString>& aliasMap, QSet<QString>& excludedAttributes, QString version, QgsRectangle* featureBBox = 0 ) const;
QgsRenderContext& renderContext, QString version, QgsRectangle* featureBBox = 0 ) const;
/**Appends feature info xml for the layer to the layer element of the dom document*/
int featureInfoFromRasterLayer( QgsRasterLayer* layer, const QgsPoint* infoPoint, QDomDocument& infoDocument, QDomElement& layerElement, QString version ) const;

Expand Down
24 changes: 19 additions & 5 deletions src/plugins/globe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ SET (globe_plugin_SRCS
globe_plugin.cpp
qgsosgearthtilesource.cpp
globe_plugin_dialog.cpp
osgEarthQt/ViewerWidget.cpp
osgEarthUtil/Controls.cpp
)
IF (NOT HAVE_OSGEARTHQT)
SET(globe_plugin_SRCS
${globe_plugin_SRCS}
osgEarthQt/ViewerWidget.cpp
osgEarthUtil/Controls.cpp
)
ENDIF (NOT HAVE_OSGEARTHQT)

SET (globe_plugin_UIS
globe_plugin_dialog_guibase.ui
Expand Down Expand Up @@ -51,6 +56,17 @@ INCLUDE_DIRECTORIES(
..
)

SET (OSGEARTH_LIBS
${OSGEARTH_LIBRARY}
${OSGEARTHFEATURES_LIBRARY}
${OSGEARTHUTIL_LIBRARY}
)
IF (HAVE_OSGEARTHQT)
SET(OSGEARTH_LIBS
${OSGEARTH_LIBS}
${OSGEARTHQT_LIBRARY}
)
ENDIF (HAVE_OSGEARTHQT)
TARGET_LINK_LIBRARIES(globeplugin
qgis_core
qgis_gui
Expand All @@ -61,9 +77,7 @@ TARGET_LINK_LIBRARIES(globeplugin
${OSG_LIBRARY}
${OSGQT_LIBRARY}
${OSGVIEWER_LIBRARY}
${OSGEARTH_LIBRARY}
${OSGEARTHFEATURES_LIBRARY}
${OSGEARTHUTIL_LIBRARY}
${OSGEARTH_LIBS}
${OPENTHREADS_LIBRARY}
)

Expand Down
72 changes: 60 additions & 12 deletions src/plugins/globe/globe_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
#include "globe_plugin.h"
#include "globe_plugin_dialog.h"
#include "qgsosgearthtilesource.h"
#ifdef HAVE_OSGEARTHQT
#include <osgEarthQt/ViewerWidget>
#else
#include "osgEarthQt/ViewerWidget"
#endif

#include <cmath>

Expand Down Expand Up @@ -52,12 +56,13 @@
#include <osgEarth/Map>
#include <osgEarth/MapNode>
#include <osgEarth/TileSource>
#include <osgEarthUtil/SkyNode>
#include <osgEarthUtil/AutoClipPlaneHandler>
#include <osgEarthDrivers/gdal/GDALOptions>
#include <osgEarthDrivers/tms/TMSOptions>

using namespace osgEarth::Drivers;
using namespace osgEarth::Util::Controls21;
using namespace osgEarth::Util;

#define MOVE_OFFSET 0.05

Expand Down Expand Up @@ -187,18 +192,25 @@ void GlobePlugin::initGui()
// Create the action for tool
mQActionPointer = new QAction( QIcon( ":/globe/globe.png" ), tr( "Launch Globe" ), this );
mQActionSettingsPointer = new QAction( QIcon( ":/globe/globe.png" ), tr( "Globe Settings" ), this );
QAction* actionUnload = new QAction( tr( "Unload Globe" ), this );

// Set the what's this text
mQActionPointer->setWhatsThis( tr( "Overlay data on a 3D globe" ) );
mQActionSettingsPointer->setWhatsThis( tr( "Settings for 3D globe" ) );
// Connect the action to the run
actionUnload->setWhatsThis( tr( "Unload globe" ) );

// Connect actions
connect( mQActionPointer, SIGNAL( triggered() ), this, SLOT( run() ) );
// Connect to the setting slot
connect( mQActionSettingsPointer, SIGNAL( triggered() ), this, SLOT( settings() ) );
connect( actionUnload, SIGNAL( triggered() ), this, SLOT( reset() ) );

// Add the icon to the toolbar
mQGisIface->addToolBarIcon( mQActionPointer );

//Add menu
mQGisIface->addPluginToMenu( tr( "&Globe" ), mQActionPointer );
mQGisIface->addPluginToMenu( tr( "&Globe" ), mQActionSettingsPointer );
mQGisIface->addPluginToMenu( tr( "&Globe" ), actionUnload );

connect( mQGisIface->mapCanvas() , SIGNAL( extentsChanged() ),
this, SLOT( extentsChanged() ) );
Expand Down Expand Up @@ -231,9 +243,9 @@ void GlobePlugin::run()
mIsGlobeRunning = true;
setupProxy();

if ( getenv( "MAPXML" ) )
if ( getenv( "GLOBE_MAPXML" ) )
{
char* mapxml = getenv( "MAPXML" );
char* mapxml = getenv( "GLOBE_MAPXML" );
QgsDebugMsg( mapxml );
osg::Node* node = osgDB::readNodeFile( mapxml );
if ( !node )
Expand All @@ -250,6 +262,15 @@ void GlobePlugin::run()
setupMap();
}

if ( getenv( "GLOBE_SKY" ) )
{
SkyNode* sky = new SkyNode( mMapNode->getMap() );
sky->setDateTime( 2011, 1, 6, 17.0 );
//sky->setSunPosition( osg::Vec3(0,-1,0) );
sky->attach( mOsgViewer );
mRootNode->addChild( sky );
}

// create a surface to house the controls
mControlCanvas = ControlCanvas::get( mOsgViewer );
mRootNode->addChild( mControlCanvas );
Expand Down Expand Up @@ -312,20 +333,21 @@ void GlobePlugin::settings()
void GlobePlugin::setupMap()
{
QSettings settings;
/*
QString cacheDirectory = settings.value( "cache/directory", QgsApplication::qgisSettingsDirPath() + "cache" ).toString();
TMSCacheOptions cacheOptions;
cacheOptions.setPath( cacheDirectory.toStdString() );
*/

MapOptions mapOptions;
mapOptions.cache() = cacheOptions;
//mapOptions.cache() = cacheOptions;
osgEarth::Map *map = new osgEarth::Map( mapOptions );

//Default image layer
/*
GDALOptions driverOptions;
driverOptions.url() = QDir::cleanPath( QgsApplication::pkgDataPath() + "/globe/world.tif" ).toStdString();
ImageLayerOptions layerOptions( "world", driverOptions );
layerOptions.cacheEnabled() = false;
map->addImageLayer( new osgEarth::ImageLayer( layerOptions ) );
*/
TMSOptions imagery;
Expand Down Expand Up @@ -633,9 +655,14 @@ void GlobePlugin::setupControls()

//END ZOOM CONTROLS

//EXTRA CONTROLS
//EXTRA CONTROLS
//#define ENABLE_SYNC_BUTTON 1
#if ENABLE_SYNC_BUTTON
//Horizontal container
HBox* extraControls = new HBox();
#else
VBox* extraControls = new VBox();
#endif
extraControls->setFrame( new RoundedFrame() );
extraControls->getFrame()->setBackColor( 1, 1, 1, 0.5 );
extraControls->setMargin( 0 );
Expand All @@ -646,13 +673,19 @@ void GlobePlugin::setupControls()
#endif
extraControls->setVertAlign( Control::ALIGN_CENTER );
extraControls->setHorizAlign( Control::ALIGN_CENTER );
extraControls->setPosition( 5, 220 );
#if ENABLE_SYNC_BUTTON
extraControls->setPosition( 5, 231 );
#else
extraControls->setPosition( 35, 231 );
#endif
extraControls->setPadding( 6 );

//Sync Extent
#if ENABLE_SYNC_BUTTON
osg::Image* extraSyncImg = osgDB::readImageFile( imgDir + "/sync-extent.png" );
ImageControl* extraSync = new NavigationControl( extraSyncImg );
extraSync->addEventHandler( new SyncExtentControlHandler( this ) );
#endif

//Zoom Reset
osg::Image* extraHomeImg = osgDB::readImageFile( imgDir + "/zoom-home.png" );
Expand All @@ -665,7 +698,9 @@ void GlobePlugin::setupControls()
extraRefresh->addEventHandler( new RefreshControlHandler( this ) );

//add controls to extraControls group
#if ENABLE_SYNC_BUTTON
extraControls->addControl( extraSync );
#endif
extraControls->addControl( extraHome );
extraControls->addControl( extraRefresh );

Expand Down Expand Up @@ -735,7 +770,7 @@ void GlobePlugin::imageLayersChanged()
ImageLayerOptions options( "QGIS" );
mQgisMapLayer = new ImageLayer( options, mTileSource );
map->addImageLayer( mQgisMapLayer );
mQgisMapLayer->setCache( 0 ); //disable caching
//[layer->setCache is private in 1.3.0] mQgisMapLayer->setCache( 0 ); //disable caching
}
else
{
Expand Down Expand Up @@ -772,7 +807,7 @@ void GlobePlugin::elevationLayersChanged()
for ( int i = 0; i < table->rowCount(); ++i )
{
QString type = table->item( i, 0 )->text();
bool cache = table->item( i, 1 )->checkState();
//bool cache = table->item( i, 1 )->checkState();
QString uri = table->item( i, 2 )->text();
ElevationLayer* layer = 0;

Expand All @@ -790,7 +825,7 @@ void GlobePlugin::elevationLayersChanged()
}
map->addElevationLayer( layer );

if ( !cache || type == "Worldwind" ) layer->setCache( 0 ); //no tms cache for worldwind (use worldwind_cache)
//if ( !cache || type == "Worldwind" ) layer->setCache( 0 ); //no tms cache for worldwind (use worldwind_cache)
}
}
else
Expand All @@ -800,8 +835,21 @@ void GlobePlugin::elevationLayersChanged()
}
}

void GlobePlugin::reset()
{
if (mViewerWidget) {
delete mViewerWidget;
mViewerWidget = 0;
}
if (mOsgViewer) {
delete mOsgViewer;
mOsgViewer = 0;
}
}

void GlobePlugin::unload()
{
reset();
// remove the GUI
mQGisIface->removePluginMenu( "&Globe", mQActionPointer );
mQGisIface->removeToolBarIcon( mQActionPointer );
Expand Down
24 changes: 19 additions & 5 deletions src/plugins/globe/globe_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,25 @@
#ifndef QGS_GLOBE_PLUGIN_H
#define QGS_GLOBE_PLUGIN_H

#include "../qgisplugin.h"
#include "qgsconfig.h"
#include "qgisplugin.h"
#include "qgsosgearthtilesource.h"
#include "globe_plugin_dialog.h"
#include <QObject>
#include <osgViewer/Viewer>
#include <osgEarth/MapNode>
#include <osgEarth/ImageLayer>
#include <osgEarthUtil/EarthManipulator>
//#include <osgEarthUtil/Controls>
#ifndef HAVE_OSGEARTHQT //use backported controls if osgEarth <= 2.1
#define USE_BACKPORTED_CONTROLS
#endif
#ifdef USE_BACKPORTED_CONTROLS
#include "osgEarthUtil/Controls"
using namespace osgEarth::Util::Controls21;
#else
#include <osgEarthUtil/Controls>
using namespace osgEarth::Util::Controls;
#endif
#include <osgEarthUtil/ElevationManager>
#include <osgEarthUtil/ObjectPlacer>

Expand All @@ -52,6 +61,8 @@ class GlobePlugin : public QObject, public QgisPlugin
void run();
//! Show the settings dialog box
void settings();
//! Reset globe
void reset();
//! unload the plugin
void unload();
//! show the help document
Expand Down Expand Up @@ -87,7 +98,6 @@ class GlobePlugin : public QObject, public QgisPlugin
//! get elevation of user right click
double getSelectedElevation();


//! Place an OSG model on the globe
void placeNode( osg::Node* node, double lat, double lon, double alt = 0.0 );

Expand Down Expand Up @@ -125,7 +135,7 @@ class GlobePlugin : public QObject, public QgisPlugin
//! Tile source
osgEarth::Drivers::QgsOsgEarthTileSource* mTileSource;
//! Control Canvas
osgEarth::Util::Controls21::ControlCanvas* mControlCanvas;
ControlCanvas* mControlCanvas;
//! Elevation manager
osgEarth::Util::ElevationManager* mElevationManager;
//! Object placer
Expand Down Expand Up @@ -192,7 +202,11 @@ namespace osgEarth
{
namespace Util
{
namespace Controls21
#ifdef USE_BACKPORTED_CONTROLS
namespace Controls21
#else
namespace Controls
#endif
{
class NavigationControlHandler : public ControlEventHandler
{
Expand Down
9 changes: 4 additions & 5 deletions src/plugins/globe/globe_plugin_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ void QgsGlobePluginDialog::on_elevationAdd_clicked()
QTableWidgetItem *type = new QTableWidgetItem( elevationCombo->currentText() );
QTableWidgetItem *uri = new QTableWidgetItem( elevationPath->text() );
QTableWidgetItem* cache = new QTableWidgetItem();
cache->setCheckState(( elevationCombo->currentText() == "Worldwind" ) ? Qt::Checked : Qt::Unchecked ); //worldwind_cache will be active
//cache->setCheckState(( elevationCombo->currentText() == "Worldwind" ) ? Qt::Checked : Qt::Unchecked ); //worldwind_cache will be active
elevationDatasourcesWidget->setRowCount( 1 + i );
elevationDatasourcesWidget->setItem( i, 0, type );
elevationDatasourcesWidget->setItem( i, 1, cache );
Expand Down Expand Up @@ -257,13 +257,12 @@ void QgsGlobePluginDialog::resetElevationDatasources()
elevationDatasourcesWidget->setRowCount( 1 );
elevationDatasourcesWidget->setItem( 0, 0, new QTableWidgetItem("TMS") );
elevationDatasourcesWidget->setItem( 0, 1, new QTableWidgetItem() );
elevationDatasourcesWidget->item( 0, 1 )->setCheckState( Qt::Unchecked );
//elevationDatasourcesWidget->item( 0, 1 )->setCheckState( Qt::Unchecked );
elevationDatasourcesWidget->setItem( 0, 2, new QTableWidgetItem("http://readymap.org/readymap/tiles/1.0.0/9/") );
}

void QgsGlobePluginDialog::readElevationDatasources()
{
//showMessageBox("reading");
// clear the widget
elevationDatasourcesWidget->clearContents();
elevationDatasourcesWidget->setRowCount( 0 );
Expand All @@ -276,12 +275,12 @@ void QgsGlobePluginDialog::readElevationDatasources()
QgsProject::instance()->readEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/type" ) );
QTableWidgetItem *uri = new QTableWidgetItem(
QgsProject::instance()->readEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/uri" ) );
bool cache = QgsProject::instance()->readBoolEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/cache" );
//bool cache = QgsProject::instance()->readBoolEntry( "Globe-Plugin", "/elevationDatasources/L" + iNum + "/cache" );

elevationDatasourcesWidget->setRowCount( 1 + i );
elevationDatasourcesWidget->setItem( i, 0, type );
QTableWidgetItem* chkBoxItem = new QTableWidgetItem();
chkBoxItem->setCheckState( cache ? Qt::Checked : Qt::Unchecked );
//chkBoxItem->setCheckState( cache ? Qt::Checked : Qt::Unchecked );
elevationDatasourcesWidget->setItem( i, 1, chkBoxItem );
elevationDatasourcesWidget->setItem( i, 2, uri );
}
Expand Down
Binary file modified src/plugins/globe/images/gui/zoom-out.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading