Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE][processing] Line substring algorithm
This algorithm returns the portion of a line (or curve) which falls between the specified start and end distances (measured from the beginning of the line). Z and M values are linearly interpolated from existing values.
- Loading branch information
1 parent
a4386d6
commit 7ef5631
Showing
10 changed files
with
406 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,43 @@ | |||
<GMLFeatureClassList> | |||
<GMLFeatureClass> | |||
<Name>airports</Name> | |||
<ElementPath>airports</ElementPath> | |||
<!--POINT--> | |||
<GeometryType>1</GeometryType> | |||
<SRSName>EPSG:2964</SRSName> | |||
<DatasetSpecificInfo> | |||
<FeatureCount>76</FeatureCount> | |||
<ExtentXMin>-4480198.52221</ExtentXMin> | |||
<ExtentXMax>4615124.97899</ExtentXMax> | |||
<ExtentYMin>1433525.79887</ExtentYMin> | |||
<ExtentYMax>6502586.83035</ExtentYMax> | |||
</DatasetSpecificInfo> | |||
<PropertyDefn> | |||
<Name>ID</Name> | |||
<ElementPath>ID</ElementPath> | |||
<Type>Integer</Type> | |||
</PropertyDefn> | |||
<PropertyDefn> | |||
<Name>fk_region</Name> | |||
<ElementPath>fk_region</ElementPath> | |||
<Type>Integer</Type> | |||
</PropertyDefn> | |||
<PropertyDefn> | |||
<Name>ELEV</Name> | |||
<ElementPath>ELEV</ElementPath> | |||
<Type>Real</Type> | |||
</PropertyDefn> | |||
<PropertyDefn> | |||
<Name>NAME</Name> | |||
<ElementPath>NAME</ElementPath> | |||
<Type>String</Type> | |||
<Width>26</Width> | |||
</PropertyDefn> | |||
<PropertyDefn> | |||
<Name>USE</Name> | |||
<ElementPath>USE</ElementPath> | |||
<Type>String</Type> | |||
<Width>23</Width> | |||
</PropertyDefn> | |||
</GMLFeatureClass> | |||
</GMLFeatureClassList> |
Binary file modified
BIN
+0 Bytes
(100%)
python/plugins/processing/tests/testdata/custom/circular_strings.gpkg
Binary file not shown.
43 changes: 43 additions & 0 deletions
43
python/plugins/processing/tests/testdata/expected/airportsvoronoidiagram.gfs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,43 @@ | |||
<GMLFeatureClassList> | |||
<GMLFeatureClass> | |||
<Name>airportsvoronoidiagram</Name> | |||
<ElementPath>airportsvoronoidiagram</ElementPath> | |||
<!--POLYGON--> | |||
<GeometryType>3</GeometryType> | |||
<SRSName>EPSG:2964</SRSName> | |||
<DatasetSpecificInfo> | |||
<FeatureCount>76</FeatureCount> | |||
<ExtentXMin>-4480198.52221</ExtentXMin> | |||
<ExtentXMax>4615124.97899</ExtentXMax> | |||
<ExtentYMin>1433525.79887</ExtentYMin> | |||
<ExtentYMax>6502586.83035</ExtentYMax> | |||
</DatasetSpecificInfo> | |||
<PropertyDefn> | |||
<Name>ID</Name> | |||
<ElementPath>ID</ElementPath> | |||
<Type>Integer</Type> | |||
</PropertyDefn> | |||
<PropertyDefn> | |||
<Name>fk_region</Name> | |||
<ElementPath>fk_region</ElementPath> | |||
<Type>Integer</Type> | |||
</PropertyDefn> | |||
<PropertyDefn> | |||
<Name>ELEV</Name> | |||
<ElementPath>ELEV</ElementPath> | |||
<Type>Real</Type> | |||
</PropertyDefn> | |||
<PropertyDefn> | |||
<Name>NAME</Name> | |||
<ElementPath>NAME</ElementPath> | |||
<Type>String</Type> | |||
<Width>26</Width> | |||
</PropertyDefn> | |||
<PropertyDefn> | |||
<Name>USE</Name> | |||
<ElementPath>USE</ElementPath> | |||
<Type>String</Type> | |||
<Width>23</Width> | |||
</PropertyDefn> | |||
</GMLFeatureClass> | |||
</GMLFeatureClassList> |
48 changes: 48 additions & 0 deletions
48
python/plugins/processing/tests/testdata/expected/line_substring.gml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,48 @@ | |||
<?xml version="1.0" encoding="utf-8" ?> | |||
<ogr:FeatureCollection | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://ogr.maptools.org/ line_substring.xsd" | |||
xmlns:ogr="http://ogr.maptools.org/" | |||
xmlns:gml="http://www.opengis.net/gml"> | |||
<gml:boundedBy> | |||
<gml:Box> | |||
<gml:coord><gml:X>-0.8</gml:X><gml:Y>-3</gml:Y></gml:coord> | |||
<gml:coord><gml:X>7.8</gml:X><gml:Y>2</gml:Y></gml:coord> | |||
</gml:Box> | |||
</gml:boundedBy> | |||
|
|||
<gml:featureMember> | |||
<ogr:line_substring fid="lines.0"> | |||
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>6.2,2.0 6.8,2.0</gml:coordinates></gml:LineString></ogr:geometryProperty> | |||
</ogr:line_substring> | |||
</gml:featureMember> | |||
<gml:featureMember> | |||
<ogr:line_substring fid="lines.1"> | |||
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>-0.8,-1.0 -0.2,-1.0</gml:coordinates></gml:LineString></ogr:geometryProperty> | |||
</ogr:line_substring> | |||
</gml:featureMember> | |||
<gml:featureMember> | |||
<ogr:line_substring fid="lines.2"> | |||
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>2.0,0.2 2.0,0.8</gml:coordinates></gml:LineString></ogr:geometryProperty> | |||
</ogr:line_substring> | |||
</gml:featureMember> | |||
<gml:featureMember> | |||
<ogr:line_substring fid="lines.3"> | |||
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>3.2,1.0 3.8,1.0</gml:coordinates></gml:LineString></ogr:geometryProperty> | |||
</ogr:line_substring> | |||
</gml:featureMember> | |||
<gml:featureMember> | |||
<ogr:line_substring fid="lines.4"> | |||
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>7.2,-3.0 7.8,-3.0</gml:coordinates></gml:LineString></ogr:geometryProperty> | |||
</ogr:line_substring> | |||
</gml:featureMember> | |||
<gml:featureMember> | |||
<ogr:line_substring fid="lines.5"> | |||
<ogr:geometryProperty><gml:LineString srsName="EPSG:4326"><gml:coordinates>6.14142135623731,-2.85857864376269 6.56568542494924,-2.43431457505076</gml:coordinates></gml:LineString></ogr:geometryProperty> | |||
</ogr:line_substring> | |||
</gml:featureMember> | |||
<gml:featureMember> | |||
<ogr:line_substring fid="lines.6"> | |||
</ogr:line_substring> | |||
</gml:featureMember> | |||
</ogr:FeatureCollection> |
23 changes: 23 additions & 0 deletions
23
python/plugins/processing/tests/testdata/expected/line_substring.xsd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,23 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0"> | |||
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/> | |||
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/> | |||
<xs:complexType name="FeatureCollectionType"> | |||
<xs:complexContent> | |||
<xs:extension base="gml:AbstractFeatureCollectionType"> | |||
<xs:attribute name="lockId" type="xs:string" use="optional"/> | |||
<xs:attribute name="scope" type="xs:string" use="optional"/> | |||
</xs:extension> | |||
</xs:complexContent> | |||
</xs:complexType> | |||
<xs:element name="line_substring" type="ogr:line_substring_Type" substitutionGroup="gml:_Feature"/> | |||
<xs:complexType name="line_substring_Type"> | |||
<xs:complexContent> | |||
<xs:extension base="gml:AbstractFeatureType"> | |||
<xs:sequence> | |||
<xs:element name="geometryProperty" type="gml:LineStringPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/> | |||
</xs:sequence> | |||
</xs:extension> | |||
</xs:complexContent> | |||
</xs:complexType> | |||
</xs:schema> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,163 @@ | |||
/*************************************************************************** | |||
qgsalgorithmlinesubstring.cpp | |||
--------------------- | |||
begin : August 2018 | |||
copyright : (C) 2018 by Nyall Dawson | |||
email : nyall dot dawson 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. * | |||
* * | |||
***************************************************************************/ | |||
|
|||
#include "qgsalgorithmlinesubstring.h" | |||
#include "qgsgeometrycollection.h" | |||
#include "qgscurve.h" | |||
|
|||
///@cond PRIVATE | |||
|
|||
QString QgsLineSubstringAlgorithm::name() const | |||
{ | |||
return QStringLiteral( "linesubstring" ); | |||
} | |||
|
|||
QString QgsLineSubstringAlgorithm::displayName() const | |||
{ | |||
return QObject::tr( "Line substring" ); | |||
} | |||
|
|||
QStringList QgsLineSubstringAlgorithm::tags() const | |||
{ | |||
return QObject::tr( "linestring,curve,split,portion,reference,referencing,distance,interpolate" ).split( ',' ); | |||
} | |||
|
|||
QString QgsLineSubstringAlgorithm::group() const | |||
{ | |||
return QObject::tr( "Vector geometry" ); | |||
} | |||
|
|||
QString QgsLineSubstringAlgorithm::groupId() const | |||
{ | |||
return QStringLiteral( "vectorgeometry" ); | |||
} | |||
|
|||
QString QgsLineSubstringAlgorithm::outputName() const | |||
{ | |||
return QObject::tr( "Substring" ); | |||
} | |||
|
|||
QString QgsLineSubstringAlgorithm::shortHelpString() const | |||
{ | |||
return QObject::tr( "This algorithm returns the portion of a line (or curve) which falls " | |||
"between the specified start and end distances (measured from the " | |||
"beginning of the line).\n\n" | |||
"Z and M values are linearly interpolated from existing values." ); | |||
} | |||
|
|||
QString QgsLineSubstringAlgorithm::shortDescription() const | |||
{ | |||
return QObject::tr( "Returns the substring of lines which fall between start and end distances." ); | |||
} | |||
|
|||
QList<int> QgsLineSubstringAlgorithm::inputLayerTypes() const | |||
{ | |||
return QList<int>() << QgsProcessing::TypeVectorLine; | |||
} | |||
|
|||
QgsProcessing::SourceType QgsLineSubstringAlgorithm::outputLayerType() const | |||
{ | |||
return QgsProcessing::TypeVectorLine; | |||
} | |||
|
|||
QgsLineSubstringAlgorithm *QgsLineSubstringAlgorithm::createInstance() const | |||
{ | |||
return new QgsLineSubstringAlgorithm(); | |||
} | |||
|
|||
void QgsLineSubstringAlgorithm::initParameters( const QVariantMap & ) | |||
{ | |||
std::unique_ptr< QgsProcessingParameterDistance> startDistance = qgis::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "START_DISTANCE" ), | |||
QObject::tr( "Start distance" ), 0.0, QStringLiteral( "INPUT" ), false, 0 ); | |||
startDistance->setIsDynamic( true ); | |||
startDistance->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Start Distance" ), QObject::tr( "Start distance" ), QgsPropertyDefinition::DoublePositive ) ); | |||
startDistance->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) ); | |||
addParameter( startDistance.release() ); | |||
|
|||
std::unique_ptr< QgsProcessingParameterDistance> endDistance = qgis::make_unique< QgsProcessingParameterDistance >( QStringLiteral( "END_DISTANCE" ), | |||
QObject::tr( "End distance" ), 1.0, QStringLiteral( "INPUT" ), false, 0 ); | |||
endDistance->setIsDynamic( true ); | |||
endDistance->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "End Distance" ), QObject::tr( "End distance" ), QgsPropertyDefinition::DoublePositive ) ); | |||
endDistance->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) ); | |||
addParameter( endDistance.release() ); | |||
} | |||
|
|||
QgsProcessingFeatureSource::Flag QgsLineSubstringAlgorithm::sourceFlags() const | |||
{ | |||
// skip geometry checks - this algorithm doesn't care about invalid geometries | |||
return QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks; | |||
} | |||
|
|||
bool QgsLineSubstringAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * ) | |||
{ | |||
mStartDistance = parameterAsDouble( parameters, QStringLiteral( "START_DISTANCE" ), context ); | |||
mDynamicStartDistance = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "START_DISTANCE" ) ); | |||
if ( mDynamicStartDistance ) | |||
mStartDistanceProperty = parameters.value( QStringLiteral( "START_DISTANCE" ) ).value< QgsProperty >(); | |||
|
|||
mEndDistance = parameterAsDouble( parameters, QStringLiteral( "END_DISTANCE" ), context ); | |||
mDynamicEndDistance = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "END_DISTANCE" ) ); | |||
if ( mDynamicEndDistance ) | |||
mEndDistanceProperty = parameters.value( QStringLiteral( "END_DISTANCE" ) ).value< QgsProperty >(); | |||
|
|||
return true; | |||
} | |||
|
|||
QgsFeatureList QgsLineSubstringAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * ) | |||
{ | |||
QgsFeature f = feature; | |||
if ( f.hasGeometry() ) | |||
{ | |||
const QgsGeometry geometry = f.geometry(); | |||
double startDistance = mStartDistance; | |||
if ( mDynamicStartDistance ) | |||
startDistance = mStartDistanceProperty.valueAsDouble( context.expressionContext(), startDistance ); | |||
|
|||
double endDistance = mEndDistance; | |||
if ( mDynamicEndDistance ) | |||
endDistance = mEndDistanceProperty.valueAsDouble( context.expressionContext(), endDistance ); | |||
|
|||
const QgsCurve *curve = nullptr; | |||
if ( !geometry.isMultipart() ) | |||
curve = qgsgeometry_cast< const QgsCurve * >( geometry.constGet() ); | |||
else | |||
{ | |||
if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( geometry.constGet() ) ) | |||
{ | |||
if ( collection->numGeometries() > 0 ) | |||
{ | |||
curve = qgsgeometry_cast< const QgsCurve * >( collection->geometryN( 0 ) ); | |||
} | |||
} | |||
} | |||
if ( curve ) | |||
{ | |||
std::unique_ptr< QgsCurve > substring( curve->curveSubstring( startDistance, endDistance ) ); | |||
QgsGeometry result( std::move( substring ) ); | |||
f.setGeometry( result ); | |||
} | |||
else | |||
{ | |||
f.clearGeometry(); | |||
} | |||
} | |||
return QgsFeatureList() << f; | |||
} | |||
|
|||
///@endcond | |||
|
|||
|
Oops, something went wrong.