diff --git a/CHANGELOG.md b/CHANGELOG.md index e829082..c3cbe9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ #### Enhancements * Remove connection controls in SQL Editor +* Add composite mode in create maps. +* Add dash style to lines in create maps. +* Add join style to lines in create maps. ### 0.1.7 (2015-07-10) diff --git a/dialogs/CreateViz.py b/dialogs/CreateViz.py index 9dc881e..5af9aa4 100644 --- a/dialogs/CreateViz.py +++ b/dialogs/CreateViz.py @@ -20,7 +20,7 @@ """ from PyQt4.QtCore import Qt, QFile, QFileInfo, pyqtSlot, qDebug, QPyNullVariant from PyQt4.QtGui import QApplication, QAbstractItemView, QDialog, QListWidgetItem, QLabel, QPixmap, QPushButton, QSizePolicy -from PyQt4.QtGui import QClipboard +from PyQt4.QtGui import QClipboard, QPainter from qgis.core import QGis, QgsMapLayerRegistry, QgsMapLayer, QgsPalLayerSettings from qgis.gui import QgsMessageBar @@ -75,6 +75,11 @@ def __init__(self, toolbar, parent=None): self.ui.mapList.itemSelectionChanged.connect(self.validateButtons) self.ui.cancelBT.clicked.connect(self.reject) self.ui.saveBT.clicked.connect(self.createViz) + self.ui.cartoCssBT.clicked.connect(self.createCartoCss) + + # TODO Implement functionality + self.ui.sqlBT.hide() + self.ui.cartoCssBT.hide() layers = QgsMapLayerRegistry.instance().mapLayers() @@ -108,6 +113,15 @@ def getSize(self, layer): return size + def createCartoCss(self): + item = self.ui.availableList.currentItem() + + if item is not None: + widget = self.ui.availableList.itemWidget(item) + layer = widget.layer + cartoCSS = self.convert2CartoCSS(layer) + qDebug('CartoCSS: {}'.format(cartoCSS)) + def createViz(self): self.ui.bar.clearWidgets() self.ui.bar.pushMessage("Info", QApplication.translate('CartoDBPlugin', 'Creating Map'), level=QgsMessageBar.INFO) @@ -131,7 +145,7 @@ def cbGetLayers(self, data): item = self.ui.mapList.item(0) widget = self.ui.mapList.itemWidget(item) layer = widget.layer - cartoCSS = self.convert2cartoCSS(layer) + cartoCSS = self.convert2CartoCSS(layer) cartoDBApi = CartoDBApi(self.currentUser, self.currentApiKey, self.currentMultiuser) layer1 = data['layers'][1] layer1['options']['tile_style'] = cartoCSS @@ -144,7 +158,7 @@ def cbGetLayers(self, data): widget = self.ui.mapList.itemWidget(item) layer = widget.layer qDebug('Agregando: {} en pos: {}'.format(layer.tableName(), i)) - cartoCSS = self.convert2cartoCSS(layer) + cartoCSS = self.convert2CartoCSS(layer) # cartoDBApi.fetchContent.connect(self.cbCreateViz) newLayer = copy.deepcopy(layer1) newLayer["options"]["table_name"] = layer.tableName() @@ -177,7 +191,7 @@ def copyURL(): widget.layout().addWidget(button) self.ui.bar.pushWidget(widget, QgsMessageBar.INFO) - def convert2cartoCSS(self, layer): + def convert2CartoCSS(self, layer): renderer = layer.rendererV2() cartoCSS = '' labelCSS = '' @@ -200,7 +214,7 @@ def convert2cartoCSS(self, layer): # CSS for single symbols if renderer.type() == 'singleSymbol': symbol = renderer.symbol() - cartoCSS = self.simplePolygon(layer, symbol, '#' + layer.tableName()) + cartoCSS = self.symbol2CartoCSS(layer, symbol, '#' + layer.tableName()) # CSS for categorized symbols elif renderer.type() == 'categorizedSymbol': # qDebug('Categorized: ' + renderer.classAttribute()) @@ -217,9 +231,9 @@ def convert2cartoCSS(self, layer): # qDebug('Value {}'.format(value)) styleName = '#{}[{}={}]'.format(layer.tableName(), renderer.classAttribute(), value).decode('utf8') cartoCSS = cartoCSS + \ - self.simplePolygon(layer, symbol, styleName) + self.symbol2CartoCSS(layer, symbol, styleName) else: - cartoCSS = self.simplePolygon(layer, symbol, '#' + layer.tableName()) + cartoCSS + cartoCSS = self.symbol2CartoCSS(layer, symbol, '#' + layer.tableName()) + cartoCSS # CSS for graduated symbols elif renderer.type() == 'graduatedSymbol': # qDebug('Graduated') @@ -237,56 +251,129 @@ def upperValue(ran): )) ''' cartoCSS = cartoCSS + \ - self.simplePolygon(layer, symbol, '#' + layer.tableName() + '[' + renderer.classAttribute() + '<=' + str(ran.upperValue()) + ']') + self.symbol2CartoCSS(layer, symbol, '#' + layer.tableName() + '[' + renderer.classAttribute() + '<=' + str(ran.upperValue()) + ']') # qDebug('CartoCSS: ' + cartoCSS) return '/** Styles designed from QGISCartoDB Plugin */\n\n' + cartoCSS + '\n' + labelCSS - def simplePolygon(self, layer, symbol, styleName): + def symbol2CartoCSS(self, layer, symbol, styleName): cartoCSS = '' layerOpacity = str(float((100.0 - layer.layerTransparency())/100.0)) + + blendMode = layer.featureBlendMode() + compositionMode = 'src-over' + if blendMode == QPainter.CompositionMode_Lighten: + compositionMode = 'lighten' + elif blendMode == QPainter.CompositionMode_Screen: + compositionMode = 'screen' + elif blendMode == QPainter.CompositionMode_ColorDodge: + compositionMode = 'color-dodge' + elif blendMode == QPainter.CompositionMode_Plus: + compositionMode = 'plus' + elif blendMode == QPainter.CompositionMode_Darken: + compositionMode = 'darken' + elif blendMode == QPainter.CompositionMode_Multiply: + compositionMode = 'multiply' + elif blendMode == QPainter.CompositionMode_ColorBurn: + compositionMode = 'color-burn' + elif blendMode == QPainter.CompositionMode_Overlay: + compositionMode = 'overlay' + elif blendMode == QPainter.CompositionMode_SoftLight: + compositionMode = 'soft-light' + elif blendMode == QPainter.CompositionMode_HardLight: + compositionMode = 'hard-light' + elif blendMode == QPainter.CompositionMode_Difference: + compositionMode = 'difference' + elif blendMode == QPainter.CompositionMode_Exclusion: + compositionMode = 'exclusion' + if symbol.symbolLayerCount() > 0: - lyr = symbol.symbolLayer(0) - - # qDebug("Symbol Type: %s" % (lyr.layerType())) - filein = None - if layer.geometryType() == QGis.Point: - d = { - 'layername': styleName, - 'fillColor': lyr.fillColor().name(), - # 96 ppi = 3.7795275552 mm - 'width': round(3.7795275552 * lyr.size(), 0), - 'opacity': layerOpacity, - 'borderColor': lyr.outlineColor().name(), - 'borderWidth': round(3.7795275552 * lyr.outlineWidth(), 0) - } - filein = open(QgisCartoDB.CartoDBPlugin.PLUGIN_DIR + '/templates/simplepoint.less') - elif layer.geometryType() == QGis.Line: - d = { - 'layername': styleName, - 'lineColor': lyr.color().name(), - 'lineWidth': round(3.7795275552 * lyr.width(), 0), - 'opacity': layerOpacity - } - filein = open(QgisCartoDB.CartoDBPlugin.PLUGIN_DIR + '/templates/simpleline.less') - elif layer.geometryType() == QGis.Polygon: - d = { - 'layername': styleName, - 'fillColor': lyr.fillColor().name(), - 'opacity': layerOpacity, - 'borderColor': lyr.outlineColor().name(), - 'borderWidth': round(3.7795275552 * lyr.borderWidth(), 0) - } - filein = open(QgisCartoDB.CartoDBPlugin.PLUGIN_DIR + '/templates/simplepolygon.less') - - cartoCSS = Template(filein.read()) - cartoCSS = cartoCSS.substitute(d, - input_encoding='utf-8', - output_encoding='utf-8', - encoding_errors='replace') + lyr = None + for i in range(0, symbol.symbolLayerCount()): + lyr = symbol.symbolLayer(i) + if lyr.layerType().startswith('Simple'): + break + + # qDebug("Symbol Type: {}".format(lyr.layerType())) + # qDebug("Symbol Properties: {}".format(lyr.properties())) + + if lyr is not None and lyr.layerType().startswith('Simple'): + filein = None + if layer.geometryType() == QGis.Point: + d = { + 'layername': styleName, + 'fillColor': lyr.fillColor().name(), + # 96 ppi = 3.7795275552 mm + 'width': round(3.7795275552 * lyr.size(), 0), + 'opacity': layerOpacity, + 'borderColor': lyr.outlineColor().name(), + 'borderWidth': round(3.7795275552 * lyr.outlineWidth(), 0), + 'markerCompOp': compositionMode + } + filein = open(QgisCartoDB.CartoDBPlugin.PLUGIN_DIR + '/templates/simplepoint.less') + elif layer.geometryType() == QGis.Line: + lineWidth = round(3.7795275552 * lyr.width(), 0) + if lyr.penStyle() == Qt.NoPen: + lineWidth = 0 + + d = { + 'layername': styleName, + 'lineColor': lyr.color().name(), + 'lineWidth': lineWidth, + 'opacity': layerOpacity, + 'lineCompOp': compositionMode, + 'lineJoin': self._getLineJoin(lyr), + 'lineDasharray': self._getLineDasharray(lyr.penStyle(), lineWidth) + } + filein = open(QgisCartoDB.CartoDBPlugin.PLUGIN_DIR + '/templates/simpleline.less') + elif layer.geometryType() == QGis.Polygon: + borderWidth = round(3.7795275552 * lyr.borderWidth(), 0) + if lyr.borderStyle() == Qt.NoPen: + borderWidth = 0 + + d = { + 'layername': styleName, + 'fillColor': lyr.fillColor().name(), + 'opacity': layerOpacity, + 'borderColor': lyr.outlineColor().name(), + 'borderWidth': borderWidth, + 'polygonCompOp': compositionMode, + 'lineJoin': self._getLineJoin(lyr), + 'lineDasharray': self._getLineDasharray(lyr.borderStyle(), borderWidth) + } + filein = open(QgisCartoDB.CartoDBPlugin.PLUGIN_DIR + '/templates/simplepolygon.less') + + cartoCSS = Template(filein.read()) + cartoCSS = cartoCSS.substitute(d, + input_encoding='utf-8', + output_encoding='utf-8', + encoding_errors='replace') + else: + # TODO Manage symbols not supported. + qDebug('Symbol type: {} not supported'.format()) return cartoCSS def validateButtons(self): enabled = self.ui.mapNameTX.text() != '' and self.ui.mapList.count() > 0 self.ui.saveBT.setEnabled(enabled) + + def _getLineJoin(self, lyr): + joinStyle = 'miter' + if lyr.penJoinStyle() == Qt.BevelJoin: + joinStyle = 'bevel' + elif lyr.penJoinStyle() == Qt.RoundJoin: + joinStyle = 'round' + return joinStyle + + def _getLineDasharray(self, lineStyle, lineWidth): + lineDasharray = '0' + if lineStyle == Qt.DashLine: + lineDasharray = '5,5' + elif lineStyle == Qt.DotLine: + lineDasharray = '{},{}'.format(lineWidth, lineWidth*5) + elif lineStyle == Qt.DashDotLine: + lineDasharray = '{},{},{},{}'.format(lineWidth*10, lineWidth*10, lineWidth, lineWidth*10) + elif lineStyle == Qt.DashDotDotLine: + lineDasharray = '{},{},{},{},{},{}'.format(lineWidth*5, lineWidth*5, lineWidth, lineWidth*5, lineWidth, lineWidth*5) + return lineDasharray diff --git a/metadata.txt b/metadata.txt index 04b9650..32b3b20 100644 --- a/metadata.txt +++ b/metadata.txt @@ -24,7 +24,10 @@ about= - certifi email=michaelsalgado@gkudos.com changelog=0.1.8 - - Remove connection controls in SQL Editor + - Remove connection controls in SQL Editor. + - Add composite mode in create maps. + - Add dash style to lines in create maps. + - Add join style to lines in create maps. 0.1.7 - Do not allow to edit read-only layers. - Show owner in shared layers. diff --git a/templates/simpleline.less b/templates/simpleline.less index 6540e32..75bb7b9 100644 --- a/templates/simpleline.less +++ b/templates/simpleline.less @@ -2,4 +2,7 @@ $layername { line-color: $lineColor; line-width: $lineWidth; line-opacity: $opacity; + line-comp-op: $lineCompOp; + line-join: $lineJoin; + line-dasharray: $lineDasharray; } diff --git a/templates/simplepoint.less b/templates/simplepoint.less index 3510df8..f564b3f 100644 --- a/templates/simplepoint.less +++ b/templates/simplepoint.less @@ -8,4 +8,5 @@ $layername { marker-width: $width; marker-fill: $fillColor; marker-allow-overlap: true; + marker-comp-op: $markerCompOp; } diff --git a/templates/simplepolygon.less b/templates/simplepolygon.less index 0f76745..a01ab6a 100644 --- a/templates/simplepolygon.less +++ b/templates/simplepolygon.less @@ -1,7 +1,10 @@ $layername { polygon-fill: $fillColor; polygon-opacity: $opacity; + polygon-comp-op: $polygonCompOp; line-color: $borderColor; line-width: $borderWidth; line-opacity: $opacity; + line-join: $lineJoin; + line-dasharray: $lineDasharray; } diff --git a/ui/CreateViz.ui b/ui/CreateViz.ui index 20ef6ec..16fdc03 100644 --- a/ui/CreateViz.ui +++ b/ui/CreateViz.ui @@ -163,6 +163,13 @@ + + + + CartoCSS + + +