Skip to content

Commit

Permalink
Merge branch 'release-3_6' into backport-9691-to-release-3_6
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Apr 12, 2019
2 parents e6d8c12 + e1756f5 commit d34e95a
Show file tree
Hide file tree
Showing 22 changed files with 373 additions and 239 deletions.
4 changes: 2 additions & 2 deletions python/core/auto_generated/qgslegendsettings.sip.in
Expand Up @@ -200,7 +200,7 @@ Returns the factor of map units per pixel for symbols with size given in map uni


.. seealso:: :py:func:`setMapUnitsPerPixel` .. seealso:: :py:func:`setMapUnitsPerPixel`


.. versionadded:: 3.8 .. versionadded:: 3.4
%End %End


void setMapUnitsPerPixel( double mapUnitsPerPixel ); void setMapUnitsPerPixel( double mapUnitsPerPixel );
Expand All @@ -209,7 +209,7 @@ Sets the mmPerMapUnit calculated by ``mapUnitsPerPixel`` mostly taken from the m


.. seealso:: :py:func:`mapUnitsPerPixel` .. seealso:: :py:func:`mapUnitsPerPixel`


.. versionadded:: 3.8 .. versionadded:: 3.4
%End %End


int dpi() const; int dpi() const;
Expand Down
33 changes: 18 additions & 15 deletions src/core/geometry/qgscurvepolygon.cpp
Expand Up @@ -402,22 +402,25 @@ QString QgsCurvePolygon::asJson( int precision ) const
// GeoJSON does not support curves // GeoJSON does not support curves
QString json = QStringLiteral( "{\"type\": \"Polygon\", \"coordinates\": [" ); QString json = QStringLiteral( "{\"type\": \"Polygon\", \"coordinates\": [" );


std::unique_ptr< QgsLineString > exteriorLineString( exteriorRing()->curveToLine() ); if ( exteriorRing() )
QgsPointSequence exteriorPts;
exteriorLineString->points( exteriorPts );
json += QgsGeometryUtils::pointsToJSON( exteriorPts, precision ) + ", ";

std::unique_ptr< QgsLineString > interiorLineString;
for ( int i = 0, n = numInteriorRings(); i < n; ++i )
{
interiorLineString.reset( interiorRing( i )->curveToLine() );
QgsPointSequence interiorPts;
interiorLineString->points( interiorPts );
json += QgsGeometryUtils::pointsToJSON( interiorPts, precision ) + ", ";
}
if ( json.endsWith( QLatin1String( ", " ) ) )
{ {
json.chop( 2 ); // Remove last ", " std::unique_ptr< QgsLineString > exteriorLineString( exteriorRing()->curveToLine() );
QgsPointSequence exteriorPts;
exteriorLineString->points( exteriorPts );
json += QgsGeometryUtils::pointsToJSON( exteriorPts, precision ) + QLatin1String( ", " );

std::unique_ptr< QgsLineString > interiorLineString;
for ( int i = 0, n = numInteriorRings(); i < n; ++i )
{
interiorLineString.reset( interiorRing( i )->curveToLine() );
QgsPointSequence interiorPts;
interiorLineString->points( interiorPts );
json += QgsGeometryUtils::pointsToJSON( interiorPts, precision ) + QLatin1String( ", " );
}
if ( json.endsWith( QLatin1String( ", " ) ) )
{
json.chop( 2 ); // Remove last ", "
}
} }
json += QLatin1String( "] }" ); json += QLatin1String( "] }" );
return json; return json;
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgslegendsettings.h
Expand Up @@ -181,14 +181,14 @@ class CORE_EXPORT QgsLegendSettings
/** /**
* Returns the factor of map units per pixel for symbols with size given in map units calculated by dpi and mmPerMapUnit * Returns the factor of map units per pixel for symbols with size given in map units calculated by dpi and mmPerMapUnit
* \see setMapUnitsPerPixel() * \see setMapUnitsPerPixel()
* \since QGIS 3.8 * \since QGIS 3.4
*/ */
double mapUnitsPerPixel() const; double mapUnitsPerPixel() const;


/** /**
* Sets the mmPerMapUnit calculated by \a mapUnitsPerPixel mostly taken from the map settings. * Sets the mmPerMapUnit calculated by \a mapUnitsPerPixel mostly taken from the map settings.
* \see mapUnitsPerPixel() * \see mapUnitsPerPixel()
* \since QGIS 3.8 * \since QGIS 3.4
*/ */
void setMapUnitsPerPixel( double mapUnitsPerPixel ); void setMapUnitsPerPixel( double mapUnitsPerPixel );


Expand Down
212 changes: 32 additions & 180 deletions src/core/qgspointlocator.cpp
Expand Up @@ -23,7 +23,7 @@
#include "qgslogger.h" #include "qgslogger.h"
#include "qgsrenderer.h" #include "qgsrenderer.h"
#include "qgsexpressioncontextutils.h" #include "qgsexpressioncontextutils.h"

#include "qgslinestring.h"
#include <spatialindex/SpatialIndex.h> #include <spatialindex/SpatialIndex.h>


#include <QLinkedListIterator> #include <QLinkedListIterator>
Expand Down Expand Up @@ -332,196 +332,48 @@ static QgsPointLocator::MatchList _geometrySegmentsInRect( QgsGeometry *geom, co
// we need iterator for segments... // we need iterator for segments...


QgsPointLocator::MatchList lst; QgsPointLocator::MatchList lst;
QByteArray wkb( geom->asWkb() );
if ( wkb.isEmpty() )
return lst;


_CohenSutherland cs( rect ); // geom is converted to a MultiCurve
QgsGeometry straightGeom = geom->convertToType( QgsWkbTypes::LineGeometry, true );
// and convert to straight segemnt / converts curve to linestring
straightGeom.convertToStraightSegment();


QgsConstWkbPtr wkbPtr( wkb ); // so, you must have multilinestring
wkbPtr.readHeader(); //
// Special case: Intersections cannot be done on an empty linestring like
// QgsGeometry(QgsLineString()) or QgsGeometry::fromWkt("LINESTRING EMPTY")
if ( straightGeom.isEmpty() || ( ( straightGeom.type() != QgsWkbTypes::LineGeometry ) && ( !straightGeom.isMultipart() ) ) )
return lst;


QgsWkbTypes::Type wkbType = geom->wkbType(); _CohenSutherland cs( rect );


bool hasZValue = false; int pointIndex = 0;
switch ( wkbType ) for ( auto part = straightGeom.const_parts_begin(); part != straightGeom.const_parts_end(); ++part )
{ {
case QgsWkbTypes::Point25D: // Checking for invalid linestrings
case QgsWkbTypes::Point: // A linestring should/(must?) have at least two points
case QgsWkbTypes::MultiPoint25D: if ( qgsgeometry_cast<QgsLineString *>( *part )->numPoints() < 2 )
case QgsWkbTypes::MultiPoint: continue;
{
// Points have no lines
return lst;
}

case QgsWkbTypes::LineString25D:
hasZValue = true;
//intentional fall-through
FALLTHROUGH
case QgsWkbTypes::LineString:
{
int nPoints;
wkbPtr >> nPoints;

double prevx = 0.0, prevy = 0.0;
for ( int index = 0; index < nPoints; ++index )
{
double thisx = 0.0, thisy = 0.0;
wkbPtr >> thisx >> thisy;
if ( hasZValue )
wkbPtr += sizeof( double );

if ( index > 0 )
{
if ( cs.isSegmentInRect( prevx, prevy, thisx, thisy ) )
{
QgsPointXY edgePoints[2];
edgePoints[0].set( prevx, prevy );
edgePoints[1].set( thisx, thisy );
lst << QgsPointLocator::Match( QgsPointLocator::Edge, vl, fid, 0, QgsPointXY(), index - 1, edgePoints );
}
}

prevx = thisx;
prevy = thisy;
}
break;
}

case QgsWkbTypes::MultiLineString25D:
hasZValue = true;
//intentional fall-through
FALLTHROUGH
case QgsWkbTypes::MultiLineString:
{
int nLines;
wkbPtr >> nLines;
for ( int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
{
wkbPtr.readHeader();
int nPoints;
wkbPtr >> nPoints;

double prevx = 0.0, prevy = 0.0;
for ( int pointnr = 0; pointnr < nPoints; ++pointnr )
{
double thisx = 0.0, thisy = 0.0;
wkbPtr >> thisx >> thisy;
if ( hasZValue )
wkbPtr += sizeof( double );

if ( pointnr > 0 )
{
if ( cs.isSegmentInRect( prevx, prevy, thisx, thisy ) )
{
QgsPointXY edgePoints[2];
edgePoints[0].set( prevx, prevy );
edgePoints[1].set( thisx, thisy );
lst << QgsPointLocator::Match( QgsPointLocator::Edge, vl, fid, 0, QgsPointXY(), pointIndex - 1, edgePoints );
}
}

prevx = thisx;
prevy = thisy;
++pointIndex;
}
}
break;
}


case QgsWkbTypes::Polygon25D: QgsAbstractGeometry::vertex_iterator it = ( *part )->vertices_begin();
hasZValue = true; QgsPointXY prevPoint( *it );
//intentional fall-through it++;
FALLTHROUGH while ( it != ( *part )->vertices_end() )
case QgsWkbTypes::Polygon:
{ {
int nRings; QgsPointXY thisPoint( *it );
wkbPtr >> nRings; if ( cs.isSegmentInRect( prevPoint.x(), prevPoint.y(), thisPoint.x(), thisPoint.y() ) )

for ( int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )//loop over rings
{ {
int nPoints; QgsPointXY edgePoints[2];
wkbPtr >> nPoints; edgePoints[0] = prevPoint;

edgePoints[1] = thisPoint;
double prevx = 0.0, prevy = 0.0; lst << QgsPointLocator::Match( QgsPointLocator::Edge, vl, fid, 0, QgsPointXY(), pointIndex - 1, edgePoints );
for ( int pointnr = 0; pointnr < nPoints; ++pointnr )//loop over points in a ring
{
double thisx = 0.0, thisy = 0.0;
wkbPtr >> thisx >> thisy;
if ( hasZValue )
wkbPtr += sizeof( double );

if ( pointnr > 0 )
{
if ( cs.isSegmentInRect( prevx, prevy, thisx, thisy ) )
{
QgsPointXY edgePoints[2];
edgePoints[0].set( prevx, prevy );
edgePoints[1].set( thisx, thisy );
lst << QgsPointLocator::Match( QgsPointLocator::Edge, vl, fid, 0, QgsPointXY(), pointIndex - 1, edgePoints );
}
}

prevx = thisx;
prevy = thisy;
++pointIndex;
}
} }
break; prevPoint = QgsPointXY( *it );
} it++;
pointIndex += 1;


case QgsWkbTypes::MultiPolygon25D:
hasZValue = true;
//intentional fall-through
FALLTHROUGH
case QgsWkbTypes::MultiPolygon:
{
int nPolygons;
wkbPtr >> nPolygons;
for ( int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
{
wkbPtr.readHeader();
int nRings;
wkbPtr >> nRings;
for ( int ringnr = 0; ringnr < nRings; ++ringnr )
{
int nPoints;
wkbPtr >> nPoints;

double prevx = 0.0, prevy = 0.0;
for ( int pointnr = 0; pointnr < nPoints; ++pointnr )
{
double thisx = 0.0, thisy = 0.0;
wkbPtr >> thisx >> thisy;
if ( hasZValue )
wkbPtr += sizeof( double );

if ( pointnr > 0 )
{
if ( cs.isSegmentInRect( prevx, prevy, thisx, thisy ) )
{
QgsPointXY edgePoints[2];
edgePoints[0].set( prevx, prevy );
edgePoints[1].set( thisx, thisy );
lst << QgsPointLocator::Match( QgsPointLocator::Edge, vl, fid, 0, QgsPointXY(), pointIndex - 1, edgePoints );
}
}

prevx = thisx;
prevy = thisy;
++pointIndex;
}
}
}
break;
} }

}
case QgsWkbTypes::Unknown:
default:
return lst;
} // switch (wkbType)

return lst; return lst;
} }


Expand Down
3 changes: 1 addition & 2 deletions src/gui/qgsmaptoolcapture.cpp
Expand Up @@ -811,9 +811,8 @@ QgsPoint QgsMapToolCapture::mapPoint( const QgsMapMouseEvent &e ) const
if ( e.isSnapped() ) if ( e.isSnapped() )
{ {
const QgsPointLocator::Match match = e.mapPointMatch(); const QgsPointLocator::Match match = e.mapPointMatch();
const QgsWkbTypes::Type snappedType = match.layer()->wkbType();


if ( QgsWkbTypes::hasZ( snappedType ) ) if ( match.layer() && QgsWkbTypes::hasZ( match.layer()->wkbType() ) )
{ {
const QgsFeature ft = match.layer()->getFeature( match.featureId() ); const QgsFeature ft = match.layer()->getFeature( match.featureId() );
newPoint.setZ( ft.geometry().vertexAt( match.vertexIndex() ).z() ); newPoint.setZ( ft.geometry().vertexAt( match.vertexIndex() ).z() );
Expand Down
9 changes: 9 additions & 0 deletions src/providers/gdal/qgsgdalprovider.cpp
Expand Up @@ -526,6 +526,15 @@ void QgsGdalProvider::closeDataset()
closeCachedGdalHandlesFor( this ); closeCachedGdalHandlesFor( this );
} }


void QgsGdalProvider::reloadData()
{
QMutexLocker locker( mpMutex );
closeDataset();

mHasInit = false;
( void )initIfNeeded();
}

QString QgsGdalProvider::htmlMetadata() QString QgsGdalProvider::htmlMetadata()
{ {
QMutexLocker locker( mpMutex ); QMutexLocker locker( mpMutex );
Expand Down
2 changes: 2 additions & 0 deletions src/providers/gdal/qgsgdalprovider.h
Expand Up @@ -171,6 +171,8 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
bool setNoDataValue( int bandNo, double noDataValue ) override; bool setNoDataValue( int bandNo, double noDataValue ) override;
bool remove() override; bool remove() override;


void reloadData() override;

QString validateCreationOptions( const QStringList &createOptions, const QString &format ) override; QString validateCreationOptions( const QStringList &createOptions, const QString &format ) override;
QString validatePyramidsConfigOptions( QgsRaster::RasterPyramidsFormat pyramidsFormat, QString validatePyramidsConfigOptions( QgsRaster::RasterPyramidsFormat pyramidsFormat,
const QStringList &configOptions, const QString &fileFormat ) override; const QStringList &configOptions, const QString &fileFormat ) override;
Expand Down
4 changes: 2 additions & 2 deletions src/server/services/wcs/qgswcs.cpp
Expand Up @@ -74,7 +74,7 @@ namespace QgsWcs
if ( req.isEmpty() ) if ( req.isEmpty() )
{ {
throw QgsServiceException( QStringLiteral( "OperationNotSupported" ), throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
QStringLiteral( "Please check the value of the REQUEST parameter" ) ); QStringLiteral( "Please check the value of the REQUEST parameter" ), 501 );
} }


if ( QSTR_COMPARE( req, "GetCapabilities" ) ) if ( QSTR_COMPARE( req, "GetCapabilities" ) )
Expand All @@ -93,7 +93,7 @@ namespace QgsWcs
{ {
// Operation not supported // Operation not supported
throw QgsServiceException( QStringLiteral( "OperationNotSupported" ), throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
QStringLiteral( "Request %1 is not supported" ).arg( req ) ); QStringLiteral( "Request %1 is not supported" ).arg( req ), 501 );
} }
} }


Expand Down
4 changes: 2 additions & 2 deletions src/server/services/wfs/qgswfs.cpp
Expand Up @@ -78,7 +78,7 @@ namespace QgsWfs
if ( req.isEmpty() ) if ( req.isEmpty() )
{ {
throw QgsServiceException( QStringLiteral( "OperationNotSupported" ), throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
QStringLiteral( "Please check the value of the REQUEST parameter" ) ); QStringLiteral( "Please check the value of the REQUEST parameter" ), 501 );
} }


if ( QSTR_COMPARE( req, "GetCapabilities" ) ) if ( QSTR_COMPARE( req, "GetCapabilities" ) )
Expand Down Expand Up @@ -117,7 +117,7 @@ namespace QgsWfs
{ {
// Operation not supported // Operation not supported
throw QgsServiceException( QStringLiteral( "OperationNotSupported" ), throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
QStringLiteral( "Request %1 is not supported" ).arg( req ) ); QStringLiteral( "Request %1 is not supported" ).arg( req ), 501 );
} }
} }


Expand Down

0 comments on commit d34e95a

Please sign in to comment.