bool QgsExifTools::geoTagImage( const QString &imagePath, const QgsPointXY &location, const GeoTagDetails &details ) { try { std::unique_ptr< Exiv2::Image > image( Exiv2::ImageFactory::open( imagePath.toStdString() ) ); if ( !image ) return false; image->readMetadata(); Exiv2::ExifData &exifData = image->exifData(); exifData["Exif.GPSInfo.GPSVersionID"] = "2 0 0 0"; exifData["Exif.GPSInfo.GPSMapDatum"] = "WGS-84"; exifData["Exif.GPSInfo.GPSLatitude"] = doubleToExifCoordinate( location.y() ).toStdString(); exifData["Exif.GPSInfo.GPSLongitude"] = doubleToExifCoordinate( location.x() ).toStdString(); if ( !std::isnan( details.elevation ) ) { const QString elevationString = QStringLiteral( "%1/1000" ).arg( static_cast< int>( std::floor( std::abs( details.elevation ) * 1000 ) ) ); exifData["Exif.GPSInfo.GPSAltitude"] = elevationString.toStdString(); exifData["Exif.GPSInfo.GPSAltitudeRef"] = details.elevation < 0.0 ? "1" : "0"; } exifData["Exif.GPSInfo.GPSLatitudeRef"] = location.y() > 0 ? "N" : "S"; exifData["Exif.GPSInfo.GPSLongitudeRef"] = location.x() > 0 ? "E" : "W"; exifData["Exif.Image.GPSTag"] = 4908; image->writeMetadata(); } catch ( ... ) { return false; } return true; }
void QgsTessellatedPolygonGeometry::setPolygons( const QList<QgsPolygon *> &polygons, const QList<QgsFeatureId> &featureIds, const QgsPointXY &origin, float extrusionHeight, const QList<float> &extrusionHeightPerPolygon ) { Q_ASSERT( polygons.count() == featureIds.count() ); mTriangleIndexStartingIndices.reserve( polygons.count() ); mTriangleIndexFids.reserve( polygons.count() ); QgsTessellator tessellator( origin.x(), origin.y(), mWithNormals, mInvertNormals, mAddBackFaces ); for ( int i = 0; i < polygons.count(); ++i ) { Q_ASSERT( tessellator.dataVerticesCount() % 3 == 0 ); uint startingTriangleIndex = static_cast<uint>( tessellator.dataVerticesCount() / 3 ); mTriangleIndexStartingIndices.append( startingTriangleIndex ); mTriangleIndexFids.append( featureIds[i] ); QgsPolygon *polygon = polygons.at( i ); float extr = extrusionHeightPerPolygon.isEmpty() ? extrusionHeight : extrusionHeightPerPolygon.at( i ); tessellator.addPolygon( *polygon, extr ); } qDeleteAll( polygons ); QByteArray data( ( const char * )tessellator.data().constData(), tessellator.data().count() * sizeof( float ) ); int nVerts = data.count() / tessellator.stride(); mVertexBuffer->setData( data ); mPositionAttribute->setCount( nVerts ); if ( mNormalAttribute ) mNormalAttribute->setCount( nVerts ); }
bool QgsGeorefTransform::transformWorldToRaster( const QgsPointXY &world, QgsPointXY &raster ) { bool success = gdal_transform( world, raster, 1 ); // flip y coordinate due to different CS orientation raster.setY( -raster.y() ); return success; }
QgsPoint QgsMapToolCapture::mapPoint( const QgsPointXY &point ) const { QgsPoint newPoint( QgsWkbTypes::Point, point.x(), point.y() ); // get current layer QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ); if ( !vlayer ) { return newPoint; } // convert to the corresponding type for a full ZM support const QgsWkbTypes::Type type = vlayer->wkbType(); if ( QgsWkbTypes::hasZ( type ) && !QgsWkbTypes::hasM( type ) ) { newPoint.convertTo( QgsWkbTypes::PointZ ); } else if ( !QgsWkbTypes::hasZ( type ) && QgsWkbTypes::hasM( type ) ) { newPoint.convertTo( QgsWkbTypes::PointM ); } else if ( QgsWkbTypes::hasZ( type ) && QgsWkbTypes::hasM( type ) ) { newPoint.convertTo( QgsWkbTypes::PointZM ); } // set z value if necessary if ( QgsWkbTypes::hasZ( newPoint.wkbType() ) ) { newPoint.setZ( defaultZValue() ); } return newPoint; }
void QgsMapCanvasAnnotationItem::setFeatureForMapPosition() { if ( !mAnnotation || !mAnnotation->hasFixedMapPosition() ) return; QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer * >( mAnnotation->mapLayer() ); if ( !vectorLayer ) return; double halfIdentifyWidth = QgsMapTool::searchRadiusMU( mMapCanvas ); QgsPointXY mapPosition = mAnnotation->mapPosition(); try { QgsCoordinateTransform ct( mAnnotation->mapPositionCrs(), mMapCanvas->mapSettings().destinationCrs(), QgsProject::instance() ); if ( ct.isValid() ) mapPosition = ct.transform( mapPosition ); } catch ( QgsCsException & ) { } QgsRectangle searchRect( mapPosition.x() - halfIdentifyWidth, mapPosition.y() - halfIdentifyWidth, mapPosition.x() + halfIdentifyWidth, mapPosition.y() + halfIdentifyWidth ); searchRect = mMapCanvas->mapSettings().mapToLayerCoordinates( vectorLayer, searchRect ); QgsFeatureIterator fit = vectorLayer->getFeatures( QgsFeatureRequest().setFilterRect( searchRect ).setFlags( QgsFeatureRequest::ExactIntersect ).setLimit( 1 ) ); QgsFeature currentFeature; ( void )fit.nextFeature( currentFeature ); mAnnotation->setAssociatedFeature( currentFeature ); }
bool QgsClockwiseAngleComparer::operator()( const QgsPointXY &a, const QgsPointXY &b ) const { const bool aIsLeft = a.x() < mVertex.x(); const bool bIsLeft = b.x() < mVertex.x(); if ( aIsLeft != bIsLeft ) return bIsLeft; if ( qgsDoubleNear( a.x(), mVertex.x() ) && qgsDoubleNear( b.x(), mVertex.x() ) ) { if ( a.y() >= mVertex.y() || b.y() >= mVertex.y() ) { return b.y() < a.y(); } else { return a.y() < b.y(); } } else { const QgsVector oa = a - mVertex; const QgsVector ob = b - mVertex; const double det = oa.crossProduct( ob ); if ( qgsDoubleNear( det, 0.0 ) ) { return oa.lengthSquared() < ob.lengthSquared(); } else { return det < 0; } } }
QgsPointXY QgsMapToPixel::transform( const QgsPointXY &p ) const { qreal x = p.x(), y = p.y(); transformInPlace( x, y ); // QgsDebugMsg(QString("Point to pixel...X : %1-->%2, Y: %3 -->%4").arg(p.x()).arg(dx).arg(p.y()).arg(dy)); return QgsPointXY( x, y ); }
QgsFeatureList QgsAddXYFieldsAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) { if ( mTransformNeedsInitialization ) { mTransform = QgsCoordinateTransform( mSourceCrs, mCrs, context.transformContext() ); mTransformNeedsInitialization = false; } QVariant x; QVariant y; if ( feature.hasGeometry() ) { if ( feature.geometry().isMultipart() ) throw QgsProcessingException( QObject::tr( "Multipoint features are not supported - please convert to single point features first." ) ); const QgsPointXY point = feature.geometry().asPoint(); try { const QgsPointXY transformed = mTransform.transform( point ); x = transformed.x(); y = transformed.y(); } catch ( QgsCsException & ) { feedback->reportError( QObject::tr( "Could not transform point to destination CRS" ) ); } } QgsFeature f = feature; QgsAttributes attributes = f.attributes(); attributes << x << y; f.setAttributes( attributes ); return QgsFeatureList() << f; }
bool QgsDelimitedTextProvider::pointFromXY( QString &sX, QString &sY, QgsPointXY &pt, const QString &decimalPoint, bool xyDms ) { if ( ! decimalPoint.isEmpty() ) { sX.replace( decimalPoint, QLatin1String( "." ) ); sY.replace( decimalPoint, QLatin1String( "." ) ); } bool xOk, yOk; double x, y; if ( xyDms ) { x = dmsStringToDouble( sX, &xOk ); y = dmsStringToDouble( sY, &yOk ); } else { x = sX.toDouble( &xOk ); y = sY.toDouble( &yOk ); } if ( xOk && yOk ) { pt.setX( x ); pt.setY( y ); return true; } return false; }
void Qgs3DMapConfigWidget::apply() { QgsRasterLayer *demLayer = qobject_cast<QgsRasterLayer *>( cboTerrainLayer->currentLayer() ); bool needsUpdateOrigin = false; if ( demLayer ) { bool tGenNeedsUpdate = true; if ( mMap->terrainGenerator()->type() == QgsTerrainGenerator::Dem ) { // if we already have a DEM terrain generator, check whether there was actually any change QgsDemTerrainGenerator *oldDemTerrainGen = static_cast<QgsDemTerrainGenerator *>( mMap->terrainGenerator() ); if ( oldDemTerrainGen->layer() == demLayer && oldDemTerrainGen->resolution() == spinTerrainResolution->value() && oldDemTerrainGen->skirtHeight() == spinTerrainSkirtHeight->value() ) tGenNeedsUpdate = false; } if ( tGenNeedsUpdate ) { QgsDemTerrainGenerator *demTerrainGen = new QgsDemTerrainGenerator; demTerrainGen->setCrs( mMap->crs(), QgsProject::instance()->transformContext() ); demTerrainGen->setLayer( demLayer ); demTerrainGen->setResolution( spinTerrainResolution->value() ); demTerrainGen->setSkirtHeight( spinTerrainSkirtHeight->value() ); mMap->setTerrainGenerator( demTerrainGen ); needsUpdateOrigin = true; } } else if ( !demLayer && mMap->terrainGenerator()->type() != QgsTerrainGenerator::Flat ) { QgsFlatTerrainGenerator *flatTerrainGen = new QgsFlatTerrainGenerator; flatTerrainGen->setCrs( mMap->crs() ); flatTerrainGen->setExtent( mMainCanvas->fullExtent() ); mMap->setTerrainGenerator( flatTerrainGen ); needsUpdateOrigin = true; } if ( needsUpdateOrigin ) { // reproject terrain's extent to map CRS QgsRectangle te = mMap->terrainGenerator()->extent(); QgsCoordinateTransform terrainToMapTransform( mMap->terrainGenerator()->crs(), mMap->crs(), QgsProject::instance() ); te = terrainToMapTransform.transformBoundingBox( te ); QgsPointXY center = te.center(); mMap->setOrigin( QgsVector3D( center.x(), center.y(), 0 ) ); } mMap->setTerrainVerticalScale( spinTerrainScale->value() ); mMap->setMapTileResolution( spinMapResolution->value() ); mMap->setMaxTerrainScreenError( spinScreenError->value() ); mMap->setMaxTerrainGroundError( spinGroundError->value() ); mMap->setShowLabels( chkShowLabels->isChecked() ); mMap->setShowTerrainTilesInfo( chkShowTileInfo->isChecked() ); mMap->setShowTerrainBoundingBoxes( chkShowBoundingBoxes->isChecked() ); mMap->setShowCameraViewCenter( chkShowCameraViewCenter->isChecked() ); }
// // distance of point q from line through p in direction v // return >0 => q lies left of the line // <0 => q lies right of the line // double QgsGeometryValidator::distLine2Point( const QgsPointXY &p, QgsVector v, const QgsPointXY &q ) { if ( qgsDoubleNear( v.length(), 0 ) ) { throw QgsException( QObject::tr( "invalid line" ) ); } return ( v.x() * ( q.y() - p.y() ) - v.y() * ( q.x() - p.x() ) ) / v.length(); }
void QgsAnnotation::updateBalloon() { //first test if the point is in the frame. In that case we don't need a balloon. if ( !mHasFixedMapPosition || ( mOffsetFromReferencePoint.x() < 0 && ( mOffsetFromReferencePoint.x() + mFrameSize.width() ) > 0 && mOffsetFromReferencePoint.y() < 0 && ( mOffsetFromReferencePoint.y() + mFrameSize.height() ) > 0 ) ) { mBalloonSegment = -1; return; } //edge list QList<QLineF> segmentList; segmentList << segment( 0 ); segmentList << segment( 1 ); segmentList << segment( 2 ); segmentList << segment( 3 ); //find closest edge / closest edge point double minEdgeDist = std::numeric_limits<double>::max(); int minEdgeIndex = -1; QLineF minEdge; QgsPointXY minEdgePoint; QgsPointXY origin( 0, 0 ); for ( int i = 0; i < 4; ++i ) { QLineF currentSegment = segmentList.at( i ); QgsPointXY currentMinDistPoint; double currentMinDist = origin.sqrDistToSegment( currentSegment.x1(), currentSegment.y1(), currentSegment.x2(), currentSegment.y2(), currentMinDistPoint ); if ( currentMinDist < minEdgeDist ) { minEdgeIndex = i; minEdgePoint = currentMinDistPoint; minEdgeDist = currentMinDist; minEdge = currentSegment; } } if ( minEdgeIndex < 0 ) { return; } //make that configurable for the item double segmentPointWidth = 10; mBalloonSegment = minEdgeIndex; QPointF minEdgeEnd = minEdge.p2(); mBalloonSegmentPoint1 = QPointF( minEdgePoint.x(), minEdgePoint.y() ); if ( std::sqrt( minEdgePoint.sqrDist( minEdgeEnd.x(), minEdgeEnd.y() ) ) < segmentPointWidth ) { mBalloonSegmentPoint1 = pointOnLineWithDistance( minEdge.p2(), minEdge.p1(), segmentPointWidth ); } mBalloonSegmentPoint2 = pointOnLineWithDistance( mBalloonSegmentPoint1, minEdge.p2(), 10 ); }
void CoordinateCapture::update( const QgsPointXY &point ) { //this is the coordinate resolved back to lat / lon QgsPointXY myUserCrsPoint = mTransform.transform( point ); mpUserCrsEdit->setText( QString::number( myUserCrsPoint.x(), 'f', mUserCrsDisplayPrecision ) + ',' + QString::number( myUserCrsPoint.y(), 'f', mUserCrsDisplayPrecision ) ); // This is the coordinate space of the map canvas mpCanvasEdit->setText( QString::number( point.x(), 'f', mCanvasDisplayPrecision ) + ',' + QString::number( point.y(), 'f', mCanvasDisplayPrecision ) ); }
QgsRectangle QgsMapSettings::computeExtentForScale( const QgsPointXY &point, double scale, const QgsCoordinateReferenceSystem &sourceCrs ) const { QgsPointXY center = QgsCoordinateTransform( sourceCrs, destinationCrs(), mTransformContext ).transform( point ); // Output width in inches double outWIn = outputSize().width() / double( outputDpi() ); // Desired visible width (honouring scale) double scaledWIn = outWIn * scale; if ( mapUnits() == QgsUnitTypes::DistanceDegrees ) { // Start with an 1x1 extent around the center QgsRectangle ext( center.x() - 0.5, center.y() - 0.5, center.x() + 0.5, center.y() + 0.5 ); // Get scale at extent, and then scale extent to the desired scale double testScale = mScaleCalculator.calculate( ext, outputSize().width() ); ext.scale( scale / testScale ); return ext; } // Conversion from inches to mapUnits double conversionFactor = 12 * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceFeet, mapUnits() ); double delta = 0.5 * scaledWIn * conversionFactor; return QgsRectangle( center.x() - delta, center.y() - delta, center.x() + delta, center.y() + delta ); }
// return ratio [mu/lu] between map units and layer units // this is of course only an approximation double _ratioMU2LU( const QgsMapSettings &mapSettings, QgsMapLayer *layer ) { double distMU = mapSettings.mapUnitsPerPixel(); QgsPointXY ptMapCenterMU = mapSettings.visibleExtent().center(); QgsPointXY ptMapCenterRightMU( ptMapCenterMU.x() + distMU, ptMapCenterMU.y() ); QgsPointXY ptMapCenterLU = mapSettings.mapToLayerCoordinates( layer, ptMapCenterMU ); QgsPointXY ptMapCenterRightLU = mapSettings.mapToLayerCoordinates( layer, ptMapCenterRightMU ); double distLU = std::sqrt( ptMapCenterLU.sqrDist( ptMapCenterRightLU ) ); double ratio = distMU / distLU; return ratio; }
QList<QgsFeatureId> QgsSpatialIndex::nearestNeighbor( const QgsPointXY &point, int neighbors ) const { QList<QgsFeatureId> list; QgisVisitor visitor( list ); double pt[2] = { point.x(), point.y() }; Point p( pt, 2 ); QMutexLocker locker( &d->mMutex ); d->mRTree->nearestNeighborQuery( neighbors, p, visitor ); return list; }
float Qgs3DUtils::clampAltitude( const QgsPoint &p, Qgs3DTypes::AltitudeClamping altClamp, Qgs3DTypes::AltitudeBinding altBind, float height, const QgsPoint ¢roid, const Qgs3DMapSettings &map ) { float terrainZ = 0; if ( altClamp == Qgs3DTypes::AltClampRelative || altClamp == Qgs3DTypes::AltClampTerrain ) { QgsPointXY pt = altBind == Qgs3DTypes::AltBindVertex ? p : centroid; terrainZ = map.terrainGenerator()->heightAt( pt.x(), pt.y(), map ); } float geomZ = altClamp == Qgs3DTypes::AltClampAbsolute || altClamp == Qgs3DTypes::AltClampRelative ? p.z() : 0; float z = ( terrainZ + geomZ ) * map.terrainVerticalScale() + height; return z; }
void QgsMapToolRotateFeature::applyRotation( double rotation ) { mRotation = rotation; mRotationActive = false; QgsVectorLayer *vlayer = currentVectorLayer(); if ( !vlayer ) { deleteRubberband(); notifyNotVectorLayer(); return; } //calculations for affine transformation double angle = -1 * mRotation * ( M_PI / 180 ); QgsPointXY anchorPoint = toLayerCoordinates( vlayer, mStartPointMapCoords ); double a = std::cos( angle ); double b = -1 * std::sin( angle ); double c = anchorPoint.x() - std::cos( angle ) * anchorPoint.x() + std::sin( angle ) * anchorPoint.y(); double d = std::sin( angle ); double ee = std::cos( angle ); double f = anchorPoint.y() - std::sin( angle ) * anchorPoint.x() - std::cos( angle ) * anchorPoint.y(); vlayer->beginEditCommand( tr( "Features Rotated" ) ); int start; if ( vlayer->geometryType() == 2 ) { start = 1; } else { start = 0; } int i = 0; Q_FOREACH ( QgsFeatureId id, mRotatedFeatures ) { QgsFeature feat; vlayer->getFeatures( QgsFeatureRequest().setFilterFid( id ) ).nextFeature( feat ); QgsGeometry geom = feat.geometry(); i = start; QgsPointXY vertex = geom.vertexAt( i ); while ( vertex != QgsPointXY( 0, 0 ) ) { double newX = a * vertex.x() + b * vertex.y() + c; double newY = d * vertex.x() + ee * vertex.y() + f; vlayer->moveVertex( newX, newY, id, i ); i = i + 1; vertex = geom.vertexAt( i ); } }
QgsRasterIdentifyResult QgsGrassRasterProvider::identify( const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &boundingBox, int width, int height, int /*dpi*/ ) { Q_UNUSED( boundingBox ); Q_UNUSED( width ); Q_UNUSED( height ); QMap<int, QVariant> results; QMap<int, QVariant> noDataResults; noDataResults.insert( 1, QVariant() ); QgsRasterIdentifyResult noDataResult( QgsRaster::IdentifyFormatValue, results ); if ( format != QgsRaster::IdentifyFormatValue ) { return QgsRasterIdentifyResult( QGS_ERROR( tr( "Format not supported" ) ) ); } if ( !extent().contains( point ) ) { return noDataResult; } // TODO: use doubles instead of strings // attention, value tool does his own tricks with grass identify() so it stops to refresh values outside extent or null values e.g. bool ok; double value = mRasterValue.value( point.x(), point.y(), &ok ); if ( !ok ) { return QgsRasterIdentifyResult( QGS_ERROR( tr( "Cannot read data" ) ) ); } // no data? if ( std::isnan( value ) || qgsDoubleNear( value, mNoDataValue ) ) { return noDataResult; } // Apply user no data QgsRasterRangeList myNoDataRangeList = userNoDataValues( 1 ); if ( QgsRasterRange::contains( value, myNoDataRangeList ) ) { return noDataResult; } results.insert( 1, value ); return QgsRasterIdentifyResult( QgsRaster::IdentifyFormatValue, results ); }
bool QgsGeometryValidator::intersectLines( const QgsPointXY &p, QgsVector v, const QgsPointXY &q, QgsVector w, QgsPointXY &s ) { double d = v.y() * w.x() - v.x() * w.y(); if ( qgsDoubleNear( d, 0 ) ) return false; double dx = q.x() - p.x(); double dy = q.y() - p.y(); double k = ( dy * w.x() - dx * w.y() ) / d; s = p + v * k; return true; }
void QgsMapToolMoveLabel::canvasMoveEvent( QgsMapMouseEvent *e ) { if ( mLabelRubberBand ) { QgsPointXY pointCanvasCoords = toMapCoordinates( e->pos() ); double offsetX = pointCanvasCoords.x() - mStartPointMapCoords.x(); double offsetY = pointCanvasCoords.y() - mStartPointMapCoords.y(); mLabelRubberBand->setTranslationOffset( offsetX, offsetY ); mLabelRubberBand->updatePosition(); mLabelRubberBand->update(); mFixPointRubberBand->setTranslationOffset( offsetX, offsetY ); mFixPointRubberBand->updatePosition(); mFixPointRubberBand->update(); } }
void QgsMeshVectorRenderer::drawVectorArrow( const QgsPointXY &lineStart, double xVal, double yVal, double magnitude ) { QgsPointXY lineEnd; double vectorLength; double cosAlpha, sinAlpha; if ( calcVectorLineEnd( lineEnd, vectorLength, cosAlpha, sinAlpha, lineStart, xVal, yVal, magnitude ) ) return; // Make a set of vector head coordinates that we will place at the end of each vector, // scale, translate and rotate. QgsPointXY vectorHeadPoints[3]; QVector<QPointF> finalVectorHeadPoints( 3 ); double vectorHeadWidthRatio = mCfg.arrowHeadWidthRatio(); double vectorHeadLengthRatio = mCfg.arrowHeadLengthRatio(); // First head point: top of -> vectorHeadPoints[0].setX( -1.0 * vectorHeadLengthRatio ); vectorHeadPoints[0].setY( vectorHeadWidthRatio * 0.5 ); // Second head point: right of -> vectorHeadPoints[1].setX( 0.0 ); vectorHeadPoints[1].setY( 0.0 ); // Third head point: bottom of -> vectorHeadPoints[2].setX( -1.0 * vectorHeadLengthRatio ); vectorHeadPoints[2].setY( -1.0 * vectorHeadWidthRatio * 0.5 ); // Determine the arrow head coords for ( int j = 0; j < 3; j++ ) { finalVectorHeadPoints[j].setX( lineEnd.x() + ( vectorHeadPoints[j].x() * cosAlpha * vectorLength ) - ( vectorHeadPoints[j].y() * sinAlpha * vectorLength ) ); finalVectorHeadPoints[j].setY( lineEnd.y() - ( vectorHeadPoints[j].x() * sinAlpha * vectorLength ) - ( vectorHeadPoints[j].y() * cosAlpha * vectorLength ) ); } // Now actually draw the vector mContext.painter()->drawLine( lineStart.toQPointF(), lineEnd.toQPointF() ); mContext.painter()->drawPolygon( finalVectorHeadPoints ); }
void QgsMapToolMoveFeature::cadCanvasMoveEvent( QgsMapMouseEvent *e ) { if ( mRubberBand ) { QgsPointXY pointCanvasCoords = e->mapPoint(); double offsetX = pointCanvasCoords.x() - mStartPointMapCoords.x(); double offsetY = pointCanvasCoords.y() - mStartPointMapCoords.y(); mRubberBand->setTranslationOffset( offsetX, offsetY ); mRubberBand->updatePosition(); mRubberBand->update(); mSnapIndicator->setMatch( e->mapPointMatch() ); } else { mSnapIndicator->setMatch( e->mapPointMatch() ); } }
void QgsVectorLayerDiagramProvider::drawLabel( QgsRenderContext &context, pal::LabelPosition *label ) const { #if 1 // XXX strk // features are pre-rotated but not scaled/translated, // so we only disable rotation here. Ideally, they'd be // also pre-scaled/translated, as suggested here: // https://issues.qgis.org/issues/11856 QgsMapToPixel xform = context.mapToPixel(); xform.setMapRotation( 0, 0, 0 ); #else const QgsMapToPixel &xform = context.mapToPixel(); #endif QgsDiagramLabelFeature *dlf = dynamic_cast<QgsDiagramLabelFeature *>( label->getFeaturePart()->feature() ); QgsFeature feature; feature.setFields( mFields ); feature.setValid( true ); feature.setId( label->getFeaturePart()->featureId() ); feature.setAttributes( dlf->attributes() ); context.expressionContext().setFeature( feature ); //calculate top-left point for diagram //first, calculate the centroid of the label (accounts for PAL creating //rotated labels when we do not want to draw the diagrams rotated) double centerX = 0; double centerY = 0; for ( int i = 0; i < 4; ++i ) { centerX += label->getX( i ); centerY += label->getY( i ); } QgsPointXY outPt( centerX / 4.0, centerY / 4.0 ); //then, calculate the top left point for the diagram with this center position QgsPointXY centerPt = xform.transform( outPt.x() - label->getWidth() / 2, outPt.y() - label->getHeight() / 2 ); mSettings.renderer()->renderDiagram( feature, context, centerPt.toQPointF(), mSettings.dataDefinedProperties() ); //insert into label search tree to manipulate position interactively mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, QString(), QFont(), true, false ); }
bool ProjectorData::checkRows( const QgsCoordinateTransform &ct ) { if ( !ct.isValid() ) { return false; } for ( int r = 0; r < mCPRows; r++ ) { for ( int c = 1; c < mCPCols - 1; c += 2 ) { double myDestX, myDestY; destPointOnCPMatrix( r, c, &myDestX, &myDestY ); QgsPointXY myDestPoint( myDestX, myDestY ); QgsPointXY mySrcPoint1 = mCPMatrix[r][c - 1]; QgsPointXY mySrcPoint2 = mCPMatrix[r][c]; QgsPointXY mySrcPoint3 = mCPMatrix[r][c + 1]; QgsPointXY mySrcApprox( ( mySrcPoint1.x() + mySrcPoint3.x() ) / 2, ( mySrcPoint1.y() + mySrcPoint3.y() ) / 2 ); if ( !mCPLegalMatrix[r][c - 1] || !mCPLegalMatrix[r][c] || !mCPLegalMatrix[r][c + 1] ) { // There was an error earlier in transform, just abort return false; } try { QgsPointXY myDestApprox = ct.transform( mySrcApprox, QgsCoordinateTransform::ReverseTransform ); double mySqrDist = myDestApprox.sqrDist( myDestPoint ); if ( mySqrDist > mSqrTolerance ) { return false; } } catch ( QgsCsException &e ) { Q_UNUSED( e ); // Caught an error in transform return false; } } } return true; }
void QgsMapToolIdentify::closestPointAttributes( const QgsAbstractGeometry &geometry, QgsMapLayer *layer, const QgsPointXY &layerPoint, QMap< QString, QString > &derivedAttributes ) { Q_UNUSED( layer ); // measure if ( QgsWkbTypes::hasM( geometry.wkbType() ) ) { QgsPoint closestPoint = QgsGeometryUtils::closestPoint( geometry, QgsPoint( layerPoint.x(), layerPoint.y() ) ); QString str = QLocale::system().toString( closestPoint.m(), 'g', 10 ); derivedAttributes.insert( QStringLiteral( "Closest point M" ), str ); } }
void QgsTessellatedPolygonGeometry::setPolygons( const QList<QgsPolygon *> &polygons, const QgsPointXY &origin, float extrusionHeight, const QList<float> &extrusionHeightPerPolygon ) { QgsTessellator tessellator( origin.x(), origin.y(), mWithNormals, mInvertNormals ); for ( int i = 0; i < polygons.count(); ++i ) { QgsPolygon *polygon = polygons.at( i ); float extr = extrusionHeightPerPolygon.isEmpty() ? extrusionHeight : extrusionHeightPerPolygon.at( i ); tessellator.addPolygon( *polygon, extr ); } qDeleteAll( polygons ); QByteArray data( ( const char * )tessellator.data().constData(), tessellator.data().count() * sizeof( float ) ); int nVerts = data.count() / tessellator.stride(); mVertexBuffer->setData( data ); mPositionAttribute->setCount( nVerts ); if ( mNormalAttribute ) mNormalAttribute->setCount( nVerts ); }
int QgsCurveEditorWidget::findNearestControlPoint( QPointF point ) const { double minDist = 3.0 / mPlot->width(); int currentPlotMarkerIndex = -1; QList< QgsPointXY > controlPoints = mCurve.controlPoints(); for ( int i = 0; i < controlPoints.count(); ++i ) { QgsPointXY currentPoint = controlPoints.at( i ); double currentDist; currentDist = qPow( point.x() - currentPoint.x(), 2.0 ) + qPow( point.y() - currentPoint.y(), 2.0 ); if ( currentDist < minDist ) { minDist = currentDist; currentPlotMarkerIndex = i; } } return currentPlotMarkerIndex; }
QgsVector3D Qgs3DUtils::transformWorldCoordinates( const QgsVector3D &worldPoint1, const QgsVector3D &origin1, const QgsCoordinateReferenceSystem &crs1, const QgsVector3D &origin2, const QgsCoordinateReferenceSystem &crs2, const QgsCoordinateTransformContext &context ) { QgsVector3D mapPoint1 = worldToMapCoordinates( worldPoint1, origin1 ); QgsVector3D mapPoint2 = mapPoint1; if ( crs1 != crs2 ) { // reproject if necessary QgsCoordinateTransform ct( crs1, crs2, context ); try { QgsPointXY pt = ct.transform( QgsPointXY( mapPoint1.x(), mapPoint1.y() ) ); mapPoint2.set( pt.x(), pt.y(), mapPoint1.z() ); } catch ( const QgsCsException & ) { // bad luck, can't reproject for some reason } } return mapToWorldCoordinates( mapPoint2, origin2 ); }
void QgsMeshVectorRenderer::drawVectorDataOnFaces() { const QVector<QgsMeshVertex> ¢roids = mTriangularMesh.centroids(); for ( int i = 0; i < centroids.count(); i++ ) { //if (elemOutsideView(elemIndex)) // continue; QgsPointXY center = centroids.at( i ); double xVal = mDatasetValuesX[i]; double yVal = mDatasetValuesY[i]; if ( nodataValue( xVal, yVal ) ) continue; double V = mDatasetValuesMag[i]; // pre-calculated magnitude QgsPointXY lineStart = mContext.mapToPixel().transform( center.x(), center.y() ); drawVectorArrow( lineStart, xVal, yVal, V ); } }