Skip to content
Permalink
Browse files
[qgis_process] When specifying input settings via stdin, also allow
specifying distance units, area unit, ellipsoid and project path

These settings can be specified through JSON like:

    {
      'ellipsoid': 'EPSG:7019',
      'distance_units': 'feet',
      'area_units': 'ha',
      'project_path': 'c:/temp/my_project.qgs'
      'inputs': {'DISTANCE': 5, ..... }
    }
  • Loading branch information
nyalldawson committed Dec 20, 2021
1 parent 5fd9b20 commit eb55d8a04f8f76dcf88e46d2b0ef16391f9d7d9c
Showing with 110 additions and 0 deletions.
  1. +28 −0 src/process/qgsprocess.cpp
  2. +82 −0 tests/src/python/test_qgsprocessexecutable.py
@@ -369,6 +369,32 @@ int QgsProcessingExec::run( const QStringList &constArgs )

// JSON format for input parameters implies JSON output format
useJson = true;

ellipsoid = json.value( QStringLiteral( "ellipsoid" ) ).toString();
projectPath = json.value( QStringLiteral( "project_path" ) ).toString();
if ( json.contains( "distance_units" ) )
{
bool ok = false;
const QString distanceUnitsString = json.value( QStringLiteral( "distance_units" ) ).toString();
distanceUnit = QgsUnitTypes::decodeDistanceUnit( distanceUnitsString, &ok );
if ( !ok )
{
std::cerr << QStringLiteral( "%1 is not a valid distance unit value." ).arg( distanceUnitsString ).toLocal8Bit().constData() << std::endl;
return 1;
}
}

if ( json.contains( "area_units" ) )
{
bool ok = false;
const QString areaUnitsString = json.value( QStringLiteral( "area_units" ) ).toString();
areaUnit = QgsUnitTypes::decodeAreaUnit( areaUnitsString, &ok );
if ( !ok )
{
std::cerr << QStringLiteral( "%1 is not a valid area unit value." ).arg( areaUnitsString ).toLocal8Bit().constData() << std::endl;
return 1;
}
}
}
else
{
@@ -1007,6 +1033,7 @@ int QgsProcessingExec::execute( const QString &inputId, const QVariantMap &param
return 1;
}
QgsProject::setInstance( project.get() );
json.insert( QStringLiteral( "project_path" ), projectPath );
}

if ( !useJson )
@@ -1050,6 +1077,7 @@ int QgsProcessingExec::execute( const QString &inputId, const QVariantMap &param
json.insert( QStringLiteral( "area_unit" ), QgsUnitTypes::toString( areaUnit ) );
}


QgsProcessingContext context;
context.setEllipsoid( ellipsoid );
context.setDistanceUnit( distanceUnit );
@@ -232,6 +232,88 @@ def testAlgorithmRunStdIn(self):
self.assertTrue(os.path.exists(output_file))
self.assertEqual(rc, 0)

def testAlgorithmRunStdInExtraSettings(self):
output_file = self.TMP_DIR + '/polygon_centroid_json.shp'

params = {
'inputs': {
'INPUT': TEST_DATA_DIR + '/polys.shp',
'OUTPUT': output_file
},
'ellipsoid': 'EPSG:7019',
'distance_units': 'feet',
'area_units': 'ha',
'project_path': TEST_DATA_DIR + '/joins.qgs'
}

rc, output, err = self.run_process_stdin(['run', 'native:centroids', '-'], json.dumps(params))

res = json.loads(output)

self.assertIn('gdal_version', res)
self.assertIn('geos_version', res)
self.assertIn('proj_version', res)
self.assertIn('python_version', res)
self.assertIn('qt_version', res)
self.assertIn('qgis_version', res)

self.assertEqual(res['algorithm_details']['name'], 'Centroids')
self.assertEqual(res['ellipsoid'], 'EPSG:7019')
self.assertEqual(res['distance_unit'], 'feet')
self.assertEqual(res['area_unit'], 'hectares')
self.assertEqual(res['project_path'], TEST_DATA_DIR + '/joins.qgs')
self.assertEqual(res['inputs']['INPUT'], TEST_DATA_DIR + '/polys.shp')
self.assertEqual(res['inputs']['OUTPUT'], output_file)
self.assertEqual(res['results']['OUTPUT'], output_file)

self.assertTrue(os.path.exists(output_file))
self.assertEqual(rc, 0)

def testAlgorithmRunStdInExtraSettingsBadDistanceUnit(self):
output_file = self.TMP_DIR + '/polygon_centroid_json.shp'

params = {
'inputs': {
'INPUT': TEST_DATA_DIR + '/polys.shp',
'OUTPUT': output_file
},
'distance_units': 'xxx',
}

rc, output, err = self.run_process_stdin(['run', 'native:centroids', '-'], json.dumps(params))
self.assertEqual(rc, 1)
self.assertIn('xxx is not a valid distance unit value', err)

def testAlgorithmRunStdInExtraSettingsBadAreaUnit(self):
output_file = self.TMP_DIR + '/polygon_centroid_json.shp'

params = {
'inputs': {
'INPUT': TEST_DATA_DIR + '/polys.shp',
'OUTPUT': output_file
},
'area_units': 'xxx',
}

rc, output, err = self.run_process_stdin(['run', 'native:centroids', '-'], json.dumps(params))
self.assertEqual(rc, 1)
self.assertIn('xxx is not a valid area unit value', err)

def testAlgorithmRunStdInExtraSettingsBadProjectPath(self):
output_file = self.TMP_DIR + '/polygon_centroid_json.shp'

params = {
'inputs': {
'INPUT': TEST_DATA_DIR + '/polys.shp',
'OUTPUT': output_file
},
'project_path': 'xxx',
}

rc, output, err = self.run_process_stdin(['run', 'native:centroids', '-'], json.dumps(params))
self.assertEqual(rc, 1)
self.assertIn('Could not load the QGIS project "xxx"', err)

def testAlgorithmRunStdInMissingInputKey(self):
output_file = self.TMP_DIR + '/polygon_centroid_json.shp'

0 comments on commit eb55d8a

Please sign in to comment.