Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'release-3_6' into backport-9691-to-release-3_6
  • 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`

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

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`

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

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
QString json = QStringLiteral( "{\"type\": \"Polygon\", \"coordinates\": [" );

std::unique_ptr< QgsLineString > exteriorLineString( exteriorRing()->curveToLine() );
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( ", " ) ) )
if ( exteriorRing() )
{
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( "] }" );
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
* \see setMapUnitsPerPixel()
* \since QGIS 3.8
* \since QGIS 3.4
*/
double mapUnitsPerPixel() const;

/**
* Sets the mmPerMapUnit calculated by \a mapUnitsPerPixel mostly taken from the map settings.
* \see mapUnitsPerPixel()
* \since QGIS 3.8
* \since QGIS 3.4
*/
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 "qgsrenderer.h"
#include "qgsexpressioncontextutils.h"

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

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

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 );
wkbPtr.readHeader();
// so, you must have multilinestring
//
// 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;
switch ( wkbType )
int pointIndex = 0;
for ( auto part = straightGeom.const_parts_begin(); part != straightGeom.const_parts_end(); ++part )
{
case QgsWkbTypes::Point25D:
case QgsWkbTypes::Point:
case QgsWkbTypes::MultiPoint25D:
case QgsWkbTypes::MultiPoint:
{
// 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;
}
// Checking for invalid linestrings
// A linestring should/(must?) have at least two points
if ( qgsgeometry_cast<QgsLineString *>( *part )->numPoints() < 2 )
continue;

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

for ( int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )//loop over rings
QgsPointXY thisPoint( *it );
if ( cs.isSegmentInRect( prevPoint.x(), prevPoint.y(), thisPoint.x(), thisPoint.y() ) )
{
int nPoints;
wkbPtr >> nPoints;

double prevx = 0.0, prevy = 0.0;
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;
}
QgsPointXY edgePoints[2];
edgePoints[0] = prevPoint;
edgePoints[1] = thisPoint;
lst << QgsPointLocator::Match( QgsPointLocator::Edge, vl, fid, 0, QgsPointXY(), pointIndex - 1, edgePoints );
}
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;
}

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() )
{
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() );
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 );
}

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

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

QString QgsGdalProvider::htmlMetadata()
{
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 remove() override;

void reloadData() override;

QString validateCreationOptions( const QStringList &createOptions, const QString &format ) override;
QString validatePyramidsConfigOptions( QgsRaster::RasterPyramidsFormat pyramidsFormat,
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() )
{
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" ) )
Expand All @@ -93,7 +93,7 @@ namespace QgsWcs
{
// Operation not supported
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() )
{
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" ) )
Expand Down Expand Up @@ -117,7 +117,7 @@ namespace QgsWfs
{
// Operation not supported
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.