mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-07 00:15:48 -04:00
Add option to QgsVectorFileWriter to prefer using field aliases as output field name
This commit is contained in:
parent
f972425342
commit
94522cf844
@ -143,6 +143,11 @@ Constructor for MetaData
|
||||
SymbolLayerSymbology
|
||||
};
|
||||
|
||||
enum FieldNameSource
|
||||
{
|
||||
Original,
|
||||
PreferAlias,
|
||||
};
|
||||
|
||||
enum VectorFormatOption
|
||||
{
|
||||
@ -384,6 +389,8 @@ Constructor
|
||||
QgsVectorFileWriter::FieldValueConverter *fieldValueConverter;
|
||||
|
||||
QgsFeedback *feedback;
|
||||
|
||||
FieldNameSource fieldNameSource;
|
||||
};
|
||||
|
||||
|
||||
|
@ -107,7 +107,8 @@ QgsVectorFileWriter::QgsVectorFileWriter(
|
||||
SymbologyExport symbologyExport,
|
||||
QgsFeatureSink::SinkFlags sinkFlags,
|
||||
QString *newLayer,
|
||||
QgsCoordinateTransformContext transformContext
|
||||
QgsCoordinateTransformContext transformContext,
|
||||
FieldNameSource fieldNameSouce
|
||||
)
|
||||
: mError( NoError )
|
||||
, mWkbType( geometryType )
|
||||
@ -116,7 +117,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(
|
||||
{
|
||||
init( vectorFileName, fileEncoding, fields, geometryType,
|
||||
srs, driverName, datasourceOptions, layerOptions, newFilename, nullptr,
|
||||
QString(), CreateOrOverwriteFile, newLayer, sinkFlags, transformContext );
|
||||
QString(), CreateOrOverwriteFile, newLayer, sinkFlags, transformContext, fieldNameSouce );
|
||||
}
|
||||
|
||||
QgsVectorFileWriter::QgsVectorFileWriter(
|
||||
@ -135,7 +136,8 @@ QgsVectorFileWriter::QgsVectorFileWriter(
|
||||
ActionOnExistingFile action,
|
||||
QString *newLayer,
|
||||
QgsCoordinateTransformContext transformContext,
|
||||
QgsFeatureSink::SinkFlags sinkFlags
|
||||
QgsFeatureSink::SinkFlags sinkFlags,
|
||||
FieldNameSource fieldNameSource
|
||||
)
|
||||
: mError( NoError )
|
||||
, mWkbType( geometryType )
|
||||
@ -144,7 +146,7 @@ QgsVectorFileWriter::QgsVectorFileWriter(
|
||||
{
|
||||
init( vectorFileName, fileEncoding, fields, geometryType, srs, driverName,
|
||||
datasourceOptions, layerOptions, newFilename, fieldValueConverter,
|
||||
layerName, action, newLayer, sinkFlags, transformContext );
|
||||
layerName, action, newLayer, sinkFlags, transformContext, fieldNameSource );
|
||||
}
|
||||
|
||||
QgsVectorFileWriter *QgsVectorFileWriter::create(
|
||||
@ -163,7 +165,7 @@ QgsVectorFileWriter *QgsVectorFileWriter::create(
|
||||
return new QgsVectorFileWriter( fileName, options.fileEncoding, fields, geometryType, srs,
|
||||
options.driverName, options.datasourceOptions, options.layerOptions,
|
||||
newFilename, options.symbologyExport, options.fieldValueConverter, options.layerName,
|
||||
options.actionOnExistingFile, newLayer, transformContext, sinkFlags );
|
||||
options.actionOnExistingFile, newLayer, transformContext, sinkFlags, options.fieldNameSource );
|
||||
Q_NOWARN_DEPRECATED_POP
|
||||
}
|
||||
|
||||
@ -201,7 +203,7 @@ void QgsVectorFileWriter::init( QString vectorFileName,
|
||||
const QString &layerNameIn,
|
||||
ActionOnExistingFile action,
|
||||
QString *newLayer, SinkFlags sinkFlags,
|
||||
const QgsCoordinateTransformContext &transformContext )
|
||||
const QgsCoordinateTransformContext &transformContext, FieldNameSource fieldNameSource )
|
||||
{
|
||||
mRenderContext.setRendererScale( mSymbologyScale );
|
||||
|
||||
@ -604,10 +606,9 @@ void QgsVectorFileWriter::init( QString vectorFileName,
|
||||
attrField = fieldValueConverter->fieldDefinition( fields.at( fldIdx ) );
|
||||
}
|
||||
|
||||
QString name( attrField.name() );
|
||||
if ( action == AppendToLayerAddFields )
|
||||
{
|
||||
int ogrIdx = OGR_FD_GetFieldIndex( defn, mCodec->fromUnicode( name ) );
|
||||
int ogrIdx = OGR_FD_GetFieldIndex( defn, mCodec->fromUnicode( attrField.name() ) );
|
||||
if ( ogrIdx >= 0 )
|
||||
{
|
||||
mAttrIdxToOgrIdx.insert( fldIdx, ogrIdx );
|
||||
@ -615,6 +616,18 @@ void QgsVectorFileWriter::init( QString vectorFileName,
|
||||
}
|
||||
}
|
||||
|
||||
QString name;
|
||||
switch ( fieldNameSource )
|
||||
{
|
||||
case Original:
|
||||
name = attrField.name();
|
||||
break;
|
||||
|
||||
case PreferAlias:
|
||||
name = !attrField.alias().isEmpty() ? attrField.alias() : attrField.name();
|
||||
break;
|
||||
}
|
||||
|
||||
OGRFieldType ogrType = OFTString; //default to string
|
||||
int ogrWidth = attrField.length();
|
||||
int ogrPrecision = attrField.precision();
|
||||
|
@ -185,6 +185,16 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
|
||||
SymbolLayerSymbology //Exports one feature per symbol layer (considering symbol levels)
|
||||
};
|
||||
|
||||
/**
|
||||
* Source for exported field names.
|
||||
*
|
||||
* \since QGIS 3.18
|
||||
*/
|
||||
enum FieldNameSource
|
||||
{
|
||||
Original = 0, //!< Use original field names
|
||||
PreferAlias, //!< Use the original field alias as the exported field name, wherever one is set. Otherwise use the original field names.
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for sorting and filtering vector formats.
|
||||
@ -514,6 +524,13 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
|
||||
|
||||
//! Optional feedback object allowing cancellation of layer save
|
||||
QgsFeedback *feedback = nullptr;
|
||||
|
||||
/**
|
||||
* Source for exported field names.
|
||||
*
|
||||
* \since QGIS 3.18
|
||||
*/
|
||||
FieldNameSource fieldNameSource = Original;
|
||||
};
|
||||
|
||||
#ifndef SIP_RUN
|
||||
@ -570,7 +587,8 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
|
||||
QgsFeatureSink::SinkFlags sinkFlags = QgsFeatureSink::SinkFlags()
|
||||
#ifndef SIP_RUN
|
||||
, QString *newLayer = nullptr,
|
||||
QgsCoordinateTransformContext transformContext = QgsCoordinateTransformContext()
|
||||
QgsCoordinateTransformContext transformContext = QgsCoordinateTransformContext(),
|
||||
FieldNameSource fieldNameSource = Original
|
||||
#endif
|
||||
) SIP_DEPRECATED;
|
||||
|
||||
@ -592,6 +610,7 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
|
||||
* \param newLayer potentially modified layer name (output parameter) (added in QGIS 3.4)
|
||||
* \param transformContext transform context, needed if the output file srs is forced to specific crs (added in QGIS 3.10.3)
|
||||
* \param sinkFlags feature sink flags (added in QGIS 3.10.3)
|
||||
* \param fieldNameSource source for field names (since QGIS 3.18)
|
||||
* \note not available in Python bindings
|
||||
* \deprecated Use create() instead.
|
||||
*/
|
||||
@ -610,7 +629,8 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
|
||||
QgsVectorFileWriter::ActionOnExistingFile action,
|
||||
QString *newLayer = nullptr,
|
||||
QgsCoordinateTransformContext transformContext = QgsCoordinateTransformContext(),
|
||||
QgsFeatureSink::SinkFlags sinkFlags = QgsFeatureSink::SinkFlags()
|
||||
QgsFeatureSink::SinkFlags sinkFlags = QgsFeatureSink::SinkFlags(),
|
||||
FieldNameSource fieldNameSource = Original
|
||||
) SIP_SKIP;
|
||||
|
||||
//! QgsVectorFileWriter cannot be copied.
|
||||
@ -967,7 +987,8 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
|
||||
QgsVectorFileWriter::FieldValueConverter *fieldValueConverter,
|
||||
const QString &layerName,
|
||||
QgsVectorFileWriter::ActionOnExistingFile action, QString *newLayer, QgsFeatureSink::SinkFlags sinkFlags,
|
||||
const QgsCoordinateTransformContext &transformContext );
|
||||
const QgsCoordinateTransformContext &transformContext,
|
||||
FieldNameSource fieldNameSource );
|
||||
void resetMap( const QgsAttributeList &attributes );
|
||||
|
||||
std::unique_ptr< QgsFeatureRenderer > mRenderer;
|
||||
|
@ -99,6 +99,56 @@ class TestQgsVectorFileWriter(unittest.TestCase):
|
||||
|
||||
writeShape(self.mMemoryLayer, 'writetest.shp')
|
||||
|
||||
def testWritePreferAlias(self):
|
||||
"""Test prefering field alias."""
|
||||
layer = QgsVectorLayer(
|
||||
('Point?crs=epsg:4326&field=name:string(20)&'
|
||||
'field=age:integer&field=size:double&index=yes'),
|
||||
'test',
|
||||
'memory')
|
||||
|
||||
self.assertTrue(layer.isValid())
|
||||
myProvider = layer.dataProvider()
|
||||
|
||||
layer.setFieldAlias(0, 'My Name')
|
||||
layer.setFieldAlias(2, 'My Size')
|
||||
|
||||
ft = QgsFeature()
|
||||
ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10)))
|
||||
ft.setAttributes(['Johny', 20, 0.3])
|
||||
myResult, myFeatures = myProvider.addFeatures([ft])
|
||||
self.assertTrue(myResult)
|
||||
self.assertTrue(myFeatures)
|
||||
|
||||
options = QgsVectorFileWriter.SaveVectorOptions()
|
||||
options.driverName = 'ESRI Shapefile'
|
||||
options.fieldNameSource = QgsVectorFileWriter.Original
|
||||
|
||||
dest = os.path.join(str(QDir.tempPath()), 'alias.shp')
|
||||
result, err = QgsVectorFileWriter.writeAsVectorFormatV2(
|
||||
layer,
|
||||
dest,
|
||||
QgsProject.instance().transformContext(),
|
||||
options)
|
||||
self.assertEqual(result, QgsVectorFileWriter.NoError)
|
||||
|
||||
res = QgsVectorLayer(dest, 'result')
|
||||
self.assertTrue(res.isValid())
|
||||
self.assertEqual([f.name() for f in res.fields()], ['name', 'age', 'size'])
|
||||
|
||||
options.fieldNameSource = QgsVectorFileWriter.PreferAlias
|
||||
dest = os.path.join(str(QDir.tempPath()), 'alias2.shp')
|
||||
result, err = QgsVectorFileWriter.writeAsVectorFormatV2(
|
||||
layer,
|
||||
dest,
|
||||
QgsProject.instance().transformContext(),
|
||||
options)
|
||||
self.assertEqual(result, QgsVectorFileWriter.NoError)
|
||||
|
||||
res = QgsVectorLayer(dest, 'result')
|
||||
self.assertTrue(res.isValid())
|
||||
self.assertEqual([f.name() for f in res.fields()], ['My Name', 'age', 'My Size'])
|
||||
|
||||
def testWriteWithLongLongField(self):
|
||||
ml = QgsVectorLayer('NoGeometry?crs=epsg:4326&field=fldlonglong:long',
|
||||
'test2', 'memory')
|
||||
|
Loading…
x
Reference in New Issue
Block a user