def _geom_icon(self, table, column): # Get column type and apply the appropriate icon geometry_typ = unicode(geometryType(table, column)[0]) icon = None if geometry_typ == 'POLYGON': icon = QIcon( ':/plugins/stdm/images/icons/layer_polygon.png' ) elif geometry_typ == 'LINESTRING': icon = QIcon( ':/plugins/stdm/images/icons/layer_line.png' ) elif geometry_typ == 'POINT': icon = QIcon( ':/plugins/stdm/images/icons/layer_point.png' ) else: icon = QIcon( ':/plugins/stdm/images/icons/table.png' ) return icon
def _geom_icon(self, table, column): # Get column type and apply the appropriate icon geometry_typ = unicode(geometryType(table, column)[0]) icon = None if geometry_typ == 'POLYGON': icon = QIcon( ':/plugins/stdm/images/icons/layer_polygon.png' ) elif geometry_typ == 'LINESTRING': icon = QIcon( ':/plugins/stdm/images/icons/layer_line.png' ) elif geometry_typ == 'POINT': icon = QIcon( ':/plugins/stdm/images/icons/layer_point.png' ) elif geometry_typ == 'MULTIPOLYGON': icon = QIcon( ':/plugins/stdm/images/icons/layer_polygon.png' ) elif geometry_typ == 'MULTILINESTRING': icon = QIcon( ':/plugins/stdm/images/icons/layer_line.png' ) else: icon = QIcon( ':/plugins/stdm/images/icons/table.png' ) return icon
def _build_symbol_widget(self, sp_field_mapping): """ Build symbol widget based on geometry type. """ if isinstance(sp_field_mapping, (str, unicode)): sp_column_name = sp_field_mapping sym_layer = None else: sp_column_name = sp_field_mapping.spatialField() sym_layer = sp_field_mapping.symbolLayer() geom_type,srid = geometryType(self._ds_name, sp_column_name) if not geom_type: return None vlGeomConfig = "{0}?crs=epsg:{1!s}".format(geom_type, srid) vl = QgsVectorLayer(vlGeomConfig, "stdm_proxy", "memory") if geom_type == "POINT" or geom_type == "MULTIPOINT": symbol_editor = _SimpleMarkerSymbolLayerProxyWidget( vl, symbol_layer=sym_layer ) elif geom_type == "LINESTRING" or geom_type == "MULTILINESTRING": symbol_editor = _SimpleLineSymbolLayerProxyWidget( vl, symbol_layer=sym_layer ) elif geom_type == "POLYGON" or geom_type == "MULTIPOLYGON": symbol_editor = _SimpleFillSymbolLayerProxyWidget( vl, symbol_layer=sym_layer ) else: return None, '', -1 return symbol_editor, geom_type, srid
def _build_symbol_widget(self, sp_field_mapping): """ Build symbol widget based on geometry type. """ if isinstance(sp_field_mapping, str): sp_column_name = sp_field_mapping sym_layer = None else: sp_column_name = sp_field_mapping.spatialField() sym_layer = sp_field_mapping.symbolLayer() geom_type, srid = geometryType(self._ds_name, sp_column_name) if not geom_type: return None vlGeomConfig = "{0}?crs=epsg:{1!s}".format(geom_type, srid) vl = QgsVectorLayer(vlGeomConfig, "stdm_proxy", "memory") if geom_type == "POINT" or geom_type == "MULTIPOINT": symbol_editor = _SimpleMarkerSymbolLayerProxyWidget( vl, symbol_layer=sym_layer ) elif geom_type == "LINESTRING" or geom_type == "MULTILINESTRING": symbol_editor = _SimpleLineSymbolLayerProxyWidget( vl, symbol_layer=sym_layer ) elif geom_type == "POLYGON" or geom_type == "MULTIPOLYGON": symbol_editor = _SimpleFillSymbolLayerProxyWidget( vl, symbol_layer=sym_layer ) else: return None, '', -1 return symbol_editor, geom_type, srid
def _geom_icon(self, table, column): # Get column type and apply the appropriate icon geometry_typ = str(geometryType(table, column)[0]) icon = None if geometry_typ == 'POLYGON': icon = GuiUtils.get_icon('layer_polygon.png') elif geometry_typ == 'LINESTRING': icon = GuiUtils.get_icon('layer_line.png') elif geometry_typ == 'POINT': icon = GuiUtils.get_icon('layer_point.png') elif geometry_typ == 'MULTIPOLYGON': icon = GuiUtils.get_icon('layer_polygon.png') elif geometry_typ == 'MULTILINESTRING': icon = GuiUtils.get_icon('layer_line.png') else: icon = GuiUtils.get_icon('table.png') return icon
def run(self, *args, **kwargs): """ :param templatePath: The file path to the user-defined template. :param entityFieldName: The name of the column for the specified entity which must exist in the data source view or table. :param entityFieldValue: The value for filtering the records in the data source view or table. :param outputMode: Whether the output composition should be an image or PDF. :param filePath: The output file where the composition will be written to. Applies to single mode output generation. :param dataFields: List containing the field names whose values will be used to name the files. This is used in multiple mode configuration. :param fileExtension: The output file format. Used in multiple mode configuration. :param data_source: Name of the data source table or view whose row values will be used to name output files if the options has been specified by the user. """ templatePath = args[0] entityFieldName = args[1] entityFieldValue = args[2] outputMode = args[3] filePath = kwargs.get("filePath", None) dataFields = kwargs.get("dataFields", []) fileExtension = kwargs.get("fileExtension", "") data_source = kwargs.get("data_source", "") templateFile = QFile(templatePath) if not templateFile.open(QIODevice.ReadOnly): return False, QApplication.translate("DocumentGenerator", "Cannot read template file.") templateDoc = QDomDocument() if templateDoc.setContent(templateFile): composerDS = ComposerDataSource.create(templateDoc) spatialFieldsConfig = SpatialFieldsConfiguration.create( templateDoc) composerDS.setSpatialFieldsConfig(spatialFieldsConfig) #Check if data source exists and return if it doesn't if not self.data_source_exists(composerDS): msg = QApplication.translate( "DocumentGenerator", u"'{0}' data source does not exist in the database." u"\nPlease contact your database " u"administrator.".format(composerDS.name())) return False, msg #Set file name value formatter self._file_name_value_formatter = EntityValueFormatter( name=data_source) #Register field names to be used for file naming self._file_name_value_formatter.register_columns(dataFields) #TODO: Need to automatically register custom configuration collections #Photo config collection ph_config_collection = PhotoConfigurationCollection.create( templateDoc) #Table configuration collection table_config_collection = TableConfigurationCollection.create( templateDoc) #Create chart configuration collection object chart_config_collection = ChartConfigurationCollection.create( templateDoc) #Load the layers required by the table composer items self._table_mem_layers = load_table_layers(table_config_collection) #Execute query dsTable, records = self._exec_query(composerDS.name(), entityFieldName, entityFieldValue) if records is None or len(records) == 0: return False, QApplication.translate( "DocumentGenerator", "No matching records in the database") """ Iterate through records where a single file output will be generated for each matching record. """ for rec in records: composition = QgsComposition(self._map_renderer) composition.loadFromTemplate(templateDoc) ref_layer = None #Set value of composer items based on the corresponding db values for composerId in composerDS.dataFieldMappings().reverse: #Use composer item id since the uuid is stripped off composerItem = composition.getComposerItemById(composerId) if not composerItem is None: fieldName = composerDS.dataFieldName(composerId) fieldValue = getattr(rec, fieldName) self._composeritem_value_handler( composerItem, fieldValue) # Extract photo information self._extract_photo_info(composition, ph_config_collection, rec) # Set table item values based on configuration information self._set_table_data(composition, table_config_collection, rec) # Refresh non-custom map composer items self._refresh_composer_maps( composition, spatialFieldsConfig.spatialFieldsMapping().keys()) # Create memory layers for spatial features and add them to the map for mapId, spfmList in spatialFieldsConfig.spatialFieldsMapping( ).iteritems(): map_item = composition.getComposerItemById(mapId) if not map_item is None: # #Clear any previous map memory layer #self.clear_temporary_map_layers() for spfm in spfmList: #Use the value of the label field to name the layer lbl_field = spfm.labelField() spatial_field = spfm.spatialField() if not spatial_field: continue if lbl_field: if hasattr(rec, spfm.labelField()): layerName = getattr(rec, spfm.labelField()) else: layerName = self._random_feature_layer_name( spatial_field) else: layerName = self._random_feature_layer_name( spatial_field) #Extract the geometry using geoalchemy spatial capabilities geom_value = getattr(rec, spatial_field) if geom_value is None: continue geom_func = geom_value.ST_AsText() geomWKT = self._dbSession.scalar(geom_func) #Get geometry type geom_type, srid = geometryType( composerDS.name(), spatial_field) #Create reference layer with feature ref_layer = self._build_vector_layer( layerName, geom_type, srid) if ref_layer is None or not ref_layer.isValid(): continue #Add feature bbox = self._add_feature_to_layer( ref_layer, geomWKT) bbox.scale(spfm.zoomLevel()) #Workaround for zooming to single point extent if ref_layer.wkbType() == QGis.WKBPoint: canvas_extent = self._iface.mapCanvas( ).fullExtent() cnt_pnt = bbox.center() canvas_extent.scale(1.0 / 32, cnt_pnt) bbox = canvas_extent #Style layer based on the spatial field mapping symbol layer symbol_layer = spfm.symbolLayer() if not symbol_layer is None: ref_layer.rendererV2().symbols( )[0].changeSymbolLayer(0, spfm.symbolLayer()) ''' Add layer to map and ensure its always added at the top ''' self.map_registry.addMapLayer(ref_layer) self._iface.mapCanvas().setExtent(bbox) self._iface.mapCanvas().refresh() # Add layer to map memory layer list self._map_memory_layers.append(ref_layer.id()) self._hide_layer(ref_layer) ''' Use root layer tree to get the correct ordering of layers in the legend ''' self._refresh_map_item(map_item) #Extract chart information and generate chart self._generate_charts(composition, chart_config_collection, rec) #Build output path and generate composition if not filePath is None and len(dataFields) == 0: self._write_output(composition, outputMode, filePath) elif filePath is None and len(dataFields) > 0: docFileName = self._build_file_name( data_source, entityFieldName, entityFieldValue, dataFields, fileExtension) # Replace unsupported characters in Windows file naming docFileName = docFileName.replace('/', '_').replace \ ('\\', '_').replace(':', '_').strip('*?"<>|') if not docFileName: return ( False, QApplication.translate( "DocumentGenerator", "File name could not be generated from the data fields." )) outputDir = self._composer_output_path() if outputDir is None: return ( False, QApplication.translate( "DocumentGenerator", "System could not read the location of the output directory in the registry." )) qDir = QDir() if not qDir.exists(outputDir): return (False, QApplication.translate( "DocumentGenerator", "Output directory does not exist")) absDocPath = u"{0}/{1}".format(outputDir, docFileName) self._write_output(composition, outputMode, absDocPath) return True, "Success" return False, "Document composition could not be generated"
def featToDb(self, targettable, columnmatch, append, parentdialog, geomColumn=None, geomCode=-1, translator_manager=None): """ Performs the data import from the source layer to the STDM database. :param targettable: Destination table name :param columnmatch: Dictionary containing source columns as keys and target columns as the values. :param append: True to append, false to overwrite by deleting previous records :param parentdialog: A reference to the calling dialog. :param translator_manager: Instance of 'stdm.data.importexport.ValueTranslatorManager' containing value translators defined for the destination table columns. :type translator_manager: ValueTranslatorManager """ # Check current profile if self._current_profile is None: msg = QApplication.translate( 'OGRReader', 'The current profile could not be determined.\nPlease set it ' 'in the Options dialog or Configuration Wizard.') raise ConfigurationException(msg) if translator_manager is None: translator_manager = ValueTranslatorManager() # Delete existing rows in the target table if user has chosen to overwrite if not append: delete_table_data(targettable) # Container for mapping column names to their corresponding values lyr = self.getLayer() lyr.ResetReading() feat_defn = lyr.GetLayerDefn() numFeat = lyr.GetFeatureCount() # Configure progress dialog init_val = 0 progress = QProgressDialog("", "&Cancel", init_val, numFeat, parentdialog) progress.setWindowModality(Qt.WindowModal) lblMsgTemp = "Importing {0} of {1} to STDM..." # Set entity for use in translators destination_entity = self._data_source_entity(targettable) for feat in lyr: column_value_mapping = {} column_count = 0 progress.setValue(init_val) progressMsg = lblMsgTemp.format((init_val + 1), numFeat) progress.setLabelText(progressMsg) if progress.wasCanceled(): break # Reset source document manager for new records if destination_entity.supports_documents: if not self._source_doc_manager is None: self._source_doc_manager.reset() for f in range(feat_defn.GetFieldCount()): field_defn = feat_defn.GetFieldDefn(f) field_name = field_defn.GetNameRef() # Append value only if it has been defined by the user if field_name in columnmatch: dest_column = columnmatch[field_name] field_value = feat.GetField(f) # Create mapped class only once if self._mapped_cls is None: mapped_cls, mapped_doc_cls = self._get_mapped_class( targettable) if mapped_cls is None: msg = QApplication.translate( "OGRReader", "Something happened that caused the " "database table not to be mapped to the " "corresponding model class. Please contact" " your system administrator.") raise RuntimeError(msg) self._mapped_cls = mapped_cls self._mapped_doc_cls = mapped_doc_cls # Create source document manager if the entity supports them if destination_entity.supports_documents: self._source_doc_manager = SourceDocumentManager( destination_entity.supporting_doc, self._mapped_doc_cls) if geomColumn is not None: # Use geometry column SRID in the target table self._geomType, self._targetGeomColSRID = \ geometryType(targettable, geomColumn) ''' Check if there is a value translator defined for the specified destination column. ''' value_translator = translator_manager.translator( dest_column) if value_translator is not None: # Set destination table entity value_translator.entity = destination_entity source_col_names = value_translator.source_column_names( ) field_value_mappings = self._map_column_values( feat, feat_defn, source_col_names) # Set source document manager if required if value_translator.requires_source_document_manager: value_translator.source_document_manager = self._source_doc_manager field_value = value_translator.referencing_column_value( field_value_mappings) if not isinstance(field_value, IgnoreType): # Check column type and rename if multiple select for # SQLAlchemy compatibility col_obj = destination_entity.column(dest_column) if col_obj.TYPE_INFO == 'MULTIPLE_SELECT': lk_name = col_obj.value_list.name dest_column = '{0}_collection'.format(lk_name) column_value_mapping[dest_column] = field_value # Set supporting documents if destination_entity.supports_documents: column_value_mapping['documents'] = \ self._source_doc_manager.model_objects() column_count += 1 # Only insert geometry if it has been defined by the user if geomColumn is not None: geom = feat.GetGeometryRef() if geom is not None: # Check if the geometry types match layerGeomType = geom.GetGeometryName() # Convert polygon to multipolygon if the destination table is multi-polygon. geom_wkb, geom_type = self.auto_fix_geom_type( geom, layerGeomType, self._geomType) column_value_mapping[geomColumn] = "SRID={0!s};{1}".format( self._targetGeomColSRID, geom_wkb) if geom_type.lower() != self._geomType.lower(): raise TypeError( "The geometries of the source and destination columns do not match.\n" \ "Source Geometry Type: {0}, Destination Geometry Type: {1}".format( geom_type, self._geomType)) try: # Insert the record self._insertRow(targettable, column_value_mapping) except: progress.close() raise init_val += 1 progress.setValue(numFeat)
def db2Feat(self, parent, table, results, columns, geom=""): #Execute the export process #Create driver drv = ogr.GetDriverByName(self.getDriverName()) if drv is None: raise Exception(u"{0} driver not available.".format( self.getDriverName())) #Create data source self._ds = drv.CreateDataSource(self._targetFile) if self._ds is None: raise Exception("Creation of output file failed.") dest_crs = None #Create layer if geom != "": pgGeomType, srid = geometryType(table, geom) geomType = wkbTypes[pgGeomType] dest_crs = ogr.osr.SpatialReference() dest_crs.ImportFromEPSG(srid) else: geomType = ogr.wkbNone layer_name = self.getLayerName() lyr = self._ds.CreateLayer(layer_name, dest_crs, geomType) if lyr is None: raise Exception("Layer creation failed") #Create fields for c in columns: field_defn = self.createField(table, c) if lyr.CreateField(field_defn) != 0: raise Exception("Creating %s field failed" % (c)) #Add Geometry column to list for referencing in the result set if geom != "": columns.append(geom) featGeom = None #Configure progress dialog initVal = 0 numFeat = results.rowcount progress = QProgressDialog("", "&Cancel", initVal, numFeat, parent) progress.setWindowModality(Qt.WindowModal) lblMsgTemp = QApplication.translate('OGRWriter', 'Writing {0} of {1} to file...') entity = current_profile().entity_by_name(table) #Iterate the result set for r in results: #Progress dialog progress.setValue(initVal) progressMsg = lblMsgTemp.format(str(initVal + 1), str(numFeat)) progress.setLabelText(progressMsg) if progress.wasCanceled(): break #Create OGR Feature feat = ogr.Feature(lyr.GetLayerDefn()) for i in range(len(columns)): colName = columns[i] #Check if its the geometry column in the iteration if colName == geom: if r[i] is not None: featGeom = ogr.CreateGeometryFromWkt(r[i]) else: featGeom = ogr.CreateGeometryFromWkt("") feat.SetGeometry(featGeom) else: if isinstance(r[i], decimal.Decimal): value = int(r[i]) feat.setField(i, value) elif self.is_date(r[i]): date = datetime.datetime.strptime(r[i], "%Y-%m-%d").date() feat.setField(i, date) else: feat.SetField(i, r[i]) if lyr.CreateFeature(feat) != 0: progress.close() raise Exception("Failed to create feature in %s" % (self._targetFile)) if featGeom is not None: featGeom.Destroy() feat.Destroy() initVal += 1 progress.setValue(numFeat)
def db2Feat(self, parent, table, results, columns, geom=""): #Execute the export process #Create driver drv = ogr.GetDriverByName(self.getDriverName()) if drv is None: raise Exception("{0} driver not available.".format( self.getDriverName())) #Create data source self._ds = drv.CreateDataSource(self._targetFile) if self._ds is None: raise Exception("Creation of output file failed.") dest_crs = None #Create layer if geom != "": pgGeomType, srid = geometryType(table, geom) geomType = wkbTypes[pgGeomType] dest_crs = ogr.osr.SpatialReference() dest_crs.ImportFromEPSG(srid) else: geomType = ogr.wkbNone lyr = self._ds.CreateLayer(self.getLayerName(), dest_crs, geomType) if lyr is None: raise Exception("Layer creation failed") #Create fields for c in columns: #SQLAlchemy string values are in unicode so decoding is required in order to use in OGR encodedFieldName = c.encode('utf-8') field_defn = self.createField(table, encodedFieldName) if lyr.CreateField(field_defn) != 0: raise Exception("Creating %s field failed" % (c)) #Add Geometry column to list for referencing in the result set if geom != "": columns.append(geom) featGeom = None #Configure progress dialog initVal = 0 numFeat = results.rowcount progress = QProgressDialog("", "&Cancel", initVal, numFeat, parent) progress.setWindowModality(Qt.WindowModal) lblMsgTemp = "Writing {0} of {1} to file..." #Iterate the result set for r in results: #Progress dialog progress.setValue(initVal) progressMsg = lblMsgTemp.format(str(initVal + 1), str(numFeat)) progress.setLabelText(progressMsg) if progress.wasCanceled(): break #Create OGR Feature feat = ogr.Feature(lyr.GetLayerDefn()) for i in range(len(columns)): colName = columns[i] #Check if its the geometry column in the iteration if colName == geom: if r[i] is not None: featGeom = ogr.CreateGeometryFromWkt(r[i]) else: featGeom = ogr.CreateGeometryFromWkt("") feat.SetGeometry(featGeom) else: fieldValue = r[i] fieldValue = str(fieldValue).encode('utf-8') feat.SetField(i, fieldValue) if lyr.CreateFeature(feat) != 0: progress.close() raise Exception("Failed to create feature in %s" % (self._targetFile)) if featGeom is not None: featGeom.Destroy() feat.Destroy() initVal += 1 progress.setValue(numFeat)
def run(self, *args, **kwargs): """ :param templatePath: The file path to the user-defined template. :param entityFieldName: The name of the column for the specified entity which must exist in the data source view or table. :param entityFieldValue: The value for filtering the records in the data source view or table. :param outputMode: Whether the output composition should be an image or PDF. :param filePath: The output file where the composition will be written to. Applies to single mode output generation. :param dataFields: List containing the field names whose values will be used to name the files. This is used in multiple mode configuration. :param fileExtension: The output file format. Used in multiple mode configuration. :param data_source: Name of the data source table or view whose row values will be used to name output files if the options has been specified by the user. """ templatePath = args[0] entityFieldName = args[1] entityFieldValue = args[2] outputMode = args[3] filePath = kwargs.get("filePath", None) dataFields = kwargs.get("dataFields", []) fileExtension = kwargs.get("fileExtension", "") data_source = kwargs.get("data_source", "") templateFile = QFile(templatePath) if not templateFile.open(QIODevice.ReadOnly): return False, QApplication.translate("DocumentGenerator", "Cannot read template file.") templateDoc = QDomDocument() if templateDoc.setContent(templateFile): composerDS = ComposerDataSource.create(templateDoc) spatialFieldsConfig = SpatialFieldsConfiguration.create(templateDoc) composerDS.setSpatialFieldsConfig(spatialFieldsConfig) #Check if data source exists and return if it doesn't if not self.data_source_exists(composerDS): msg = QApplication.translate("DocumentGenerator", u"'{0}' data source does not exist in the database." u"\nPlease contact your database " u"administrator.".format(composerDS.name())) return False, msg #Set file name value formatter self._file_name_value_formatter = EntityValueFormatter( name=data_source ) #Register field names to be used for file naming self._file_name_value_formatter.register_columns(dataFields) #TODO: Need to automatically register custom configuration collections #Photo config collection ph_config_collection = PhotoConfigurationCollection.create(templateDoc) #Table configuration collection table_config_collection = TableConfigurationCollection.create(templateDoc) #Create chart configuration collection object chart_config_collection = ChartConfigurationCollection.create(templateDoc) # Create QR code configuration collection object qrc_config_collection = QRCodeConfigurationCollection.create(templateDoc) #Load the layers required by the table composer items self._table_mem_layers = load_table_layers(table_config_collection) #Execute query dsTable,records = self._exec_query(composerDS.name(), entityFieldName, entityFieldValue) if records is None or len(records) == 0: return False, QApplication.translate("DocumentGenerator", "No matching records in the database") """ Iterate through records where a single file output will be generated for each matching record. """ for rec in records: composition = QgsComposition(self._map_settings) composition.loadFromTemplate(templateDoc) ref_layer = None #Set value of composer items based on the corresponding db values for composerId in composerDS.dataFieldMappings().reverse: #Use composer item id since the uuid is stripped off composerItem = composition.getComposerItemById(composerId) if not composerItem is None: fieldName = composerDS.dataFieldName(composerId) fieldValue = getattr(rec,fieldName) self._composeritem_value_handler(composerItem, fieldValue) # Extract photo information self._extract_photo_info(composition, ph_config_collection, rec) # Set table item values based on configuration information self._set_table_data(composition, table_config_collection, rec) # Refresh non-custom map composer items self._refresh_composer_maps(composition, spatialFieldsConfig.spatialFieldsMapping().keys()) # Set use fixed scale to false i.e. relative zoom use_fixed_scale = False # Create memory layers for spatial features and add them to the map for mapId,spfmList in spatialFieldsConfig.spatialFieldsMapping().iteritems(): map_item = composition.getComposerItemById(mapId) if not map_item is None: # Clear any previous map memory layer # self.clear_temporary_map_layers() for spfm in spfmList: #Use the value of the label field to name the layer lbl_field = spfm.labelField() spatial_field = spfm.spatialField() if not spatial_field: continue if lbl_field: if hasattr(rec, spfm.labelField()): layerName = getattr(rec, spfm.labelField()) else: layerName = self._random_feature_layer_name(spatial_field) else: layerName = self._random_feature_layer_name(spatial_field) #Extract the geometry using geoalchemy spatial capabilities geom_value = getattr(rec, spatial_field) if geom_value is None: continue geom_func = geom_value.ST_AsText() geomWKT = self._dbSession.scalar(geom_func) #Get geometry type geom_type, srid = geometryType(composerDS.name(), spatial_field) #Create reference layer with feature ref_layer = self._build_vector_layer(layerName, geom_type, srid) if ref_layer is None or not ref_layer.isValid(): continue # Add feature bbox = self._add_feature_to_layer(ref_layer, geomWKT) zoom_type = spfm.zoom_type # Only scale the extents if zoom type is relative if zoom_type == 'RELATIVE': bbox.scale(spfm.zoomLevel()) #Workaround for zooming to single point extent if ref_layer.wkbType() == QGis.WKBPoint: canvas_extent = self._iface.mapCanvas().fullExtent() cnt_pnt = bbox.center() canvas_extent.scale(1.0/32, cnt_pnt) bbox = canvas_extent #Style layer based on the spatial field mapping symbol layer symbol_layer = spfm.symbolLayer() if not symbol_layer is None: ref_layer.rendererV2().symbols()[0].changeSymbolLayer(0,spfm.symbolLayer()) ''' Add layer to map and ensure its always added at the top ''' self.map_registry.addMapLayer(ref_layer) self._iface.mapCanvas().setExtent(bbox) # Set scale if type is FIXED if zoom_type == 'FIXED': self._iface.mapCanvas().zoomScale(spfm.zoomLevel()) use_fixed_scale = True self._iface.mapCanvas().refresh() # Add layer to map memory layer list self._map_memory_layers.append(ref_layer.id()) self._hide_layer(ref_layer) ''' Use root layer tree to get the correct ordering of layers in the legend ''' self._refresh_map_item(map_item, use_fixed_scale) # Extract chart information and generate chart self._generate_charts(composition, chart_config_collection, rec) # Extract QR code information in order to generate QR codes self._generate_qr_codes(composition, qrc_config_collection,rec) #Build output path and generate composition if not filePath is None and len(dataFields) == 0: self._write_output(composition, outputMode, filePath) elif filePath is None and len(dataFields) > 0: docFileName = self._build_file_name(data_source, entityFieldName, entityFieldValue, dataFields, fileExtension) # Replace unsupported characters in Windows file naming docFileName = docFileName.replace('/', '_').replace \ ('\\', '_').replace(':', '_').strip('*?"<>|') if not docFileName: return (False, QApplication.translate("DocumentGenerator", "File name could not be generated from the data fields.")) outputDir = self._composer_output_path() if outputDir is None: return (False, QApplication.translate("DocumentGenerator", "System could not read the location of the output directory in the registry.")) qDir = QDir() if not qDir.exists(outputDir): return (False, QApplication.translate("DocumentGenerator", "Output directory does not exist")) absDocPath = u"{0}/{1}".format(outputDir, docFileName) self._write_output(composition, outputMode, absDocPath) return True, "Success" return False, "Document composition could not be generated"
def db2Feat(self,parent,table,results,columns,geom=""): #Execute the export process #Create driver drv = ogr.GetDriverByName(self.getDriverName()) if drv is None: raise Exception(u"{0} driver not available.".format(self.getDriverName())) #Create data source self._ds = drv.CreateDataSource(self._targetFile) if self._ds is None: raise Exception("Creation of output file failed.") dest_crs = None #Create layer if geom != "": pgGeomType,srid = geometryType(table,geom) geomType = wkbTypes[pgGeomType] try: dest_crs = ogr.osr.SpatialReference() except AttributeError: dest_crs = osr.SpatialReference() dest_crs.ImportFromEPSG(srid) else: geomType=ogr.wkbNone layer_name = self.getLayerName() lyr = self._ds.CreateLayer(layer_name, dest_crs, geomType) if lyr is None: raise Exception("Layer creation failed") #Create fields for c in columns: field_defn = self.createField(table, c) if lyr.CreateField(field_defn) != 0: raise Exception("Creating %s field failed"%(c)) #Add Geometry column to list for referencing in the result set if geom != "": columns.append(geom) featGeom=None #Configure progress dialog initVal=0 numFeat = results.rowcount progress = QProgressDialog("","&Cancel",initVal,numFeat,parent) progress.setWindowModality(Qt.WindowModal) lblMsgTemp = QApplication.translate( 'OGRWriter', 'Writing {0} of {1} to file...') entity = current_profile().entity_by_name(table) #Iterate the result set for r in results: #Progress dialog progress.setValue(initVal) progressMsg = lblMsgTemp.format(str(initVal+1), str(numFeat)) progress.setLabelText(progressMsg) if progress.wasCanceled(): break #Create OGR Feature feat = ogr.Feature(lyr.GetLayerDefn()) for i in range(len(columns)): colName = columns[i] #Check if its the geometry column in the iteration if colName == geom: if r[i] is not None: featGeom = ogr.CreateGeometryFromWkt(r[i]) else: featGeom = ogr.CreateGeometryFromWkt("") feat.SetGeometry(featGeom) else: field_value = r[i] field_value = unicode(field_value).encode('utf-8') feat.SetField(i,field_value) if lyr.CreateFeature(feat) != 0: progress.close() raise Exception( "Failed to create feature in %s"%(self._targetFile) ) if featGeom is not None: featGeom.Destroy() feat.Destroy() initVal+=1 progress.setValue(numFeat)