diff --git a/app/map/inputmapsettings.cpp b/app/map/inputmapsettings.cpp index a529313e3..2dfcfe09a 100644 --- a/app/map/inputmapsettings.cpp +++ b/app/map/inputmapsettings.cpp @@ -81,8 +81,13 @@ void InputMapSettings::setExtent( const QgsRectangle &extent ) if ( mMapSettings.extent() == extent ) return; + const bool scaleDidChange = !qgsDoubleNear( mMapSettings.extent().width(), extent.width() ); + mMapSettings.setExtent( extent ); emit extentChanged(); + + if ( scaleDidChange ) + emit scaleChanged(); } QgsPoint InputMapSettings::center() const diff --git a/app/map/inputmapsettings.h b/app/map/inputmapsettings.h index e8fac298e..a27e1883a 100644 --- a/app/map/inputmapsettings.h +++ b/app/map/inputmapsettings.h @@ -290,6 +290,9 @@ class InputMapSettings : public QObject //! \copydoc InputMapSettings::extent void extentChanged(); + //! Fired after extentChanged() if the new extent is on a different map scale + void scaleChanged(); + //! \copydoc InputMapSettings::destinationCrs void destinationCrsChanged(); diff --git a/app/maptools/recordingmaptool.cpp b/app/maptools/recordingmaptool.cpp index 8bd2b7071..47f16c748 100644 --- a/app/maptools/recordingmaptool.cpp +++ b/app/maptools/recordingmaptool.cpp @@ -1364,7 +1364,8 @@ QgsPoint RecordingMapTool::handlePoint( QgsPoint p1, QgsPoint p2 ) return QgsPoint(); } - double h = 15 * mapSettings()->mapUnitsPerPixel(); + constexpr int HANDLE_PIXEL_OFFSET = 42; + double h = HANDLE_PIXEL_OFFSET * mapSettings()->mapUnitsPerPixel(); double factor = QgsUnitTypes::fromUnitToUnitFactor( mapSettings()->destinationCrs().mapUnits(), mActiveLayer->crs().mapUnits() ); QgsDistanceArea da; da.setEllipsoid( QStringLiteral( "WGS84" ) ); diff --git a/app/maptools/recordingmaptool.h b/app/maptools/recordingmaptool.h index ce85210d6..5d308c27a 100644 --- a/app/maptools/recordingmaptool.h +++ b/app/maptools/recordingmaptool.h @@ -285,17 +285,19 @@ class RecordingMapTool : public AbstractMapTool public slots: void onPositionChanged(); - private slots: - void prepareEditing(); - void onFeatureAdded( QgsFeatureId newFeatureId ); - /** * Creates nodes index. Extracts existing geometry vertices and generates virtual * vertices representing midpoints (for lines and polygons) and start/end points * (for lines). + * This is also called whenever the map scale changes so that start/end point positions + * can have a stable pixel offset. Also to skip midpoints for segments below a size threshold. */ void collectVertices(); + private slots: + void prepareEditing(); + void onFeatureAdded( QgsFeatureId newFeatureId ); + /** * Creates geometries represeinting existing nodes, midpoints (for lines and polygons), * start/end points and "handles" (for lines) from the nodes index. diff --git a/app/qml/map/MMHighlight.qml b/app/qml/map/MMHighlight.qml index fb16f35a4..d52f8bd46 100644 --- a/app/qml/map/MMHighlight.qml +++ b/app/qml/map/MMHighlight.qml @@ -280,6 +280,10 @@ Item { id: shape anchors.fill: parent + // The newer CurveRenderer is used for dashed lines to avoid a bug causing off-screen lines to be generated as empty + // see https://github.com/MerginMaps/mobile/issues/2280 + preferredRendererType: highlight.lineStrokeStyle === ShapePath.DashLine ? Shape.CurveRenderer : Shape.UnknownRenderer + transform: Matrix4x4 { // the formula for x coordinate for map to screen coordinates conversion goes like this: // x_screen = (x_map + offset_x) * scale / ddp diff --git a/app/qml/map/MMMapController.qml b/app/qml/map/MMMapController.qml index 9aa6175ef..2fbfe23c5 100644 --- a/app/qml/map/MMMapController.qml +++ b/app/qml/map/MMMapController.qml @@ -1266,6 +1266,16 @@ Item { } } + + Connections { + target: mapCanvas.mapSettings + function onScaleChanged() { + if ( recordingToolsLoader.active ) { + recordingToolsLoader.item.recordingMapTool.collectVertices() + } + } + } + Connections { target: __activeProject diff --git a/app/test/testmaptools.cpp b/app/test/testmaptools.cpp index 2b7176a5c..fc70b296d 100644 --- a/app/test/testmaptools.cpp +++ b/app/test/testmaptools.cpp @@ -571,10 +571,10 @@ void TestMapTools::testMidSegmentVertices() vertices = mapTool.midPoints(); QCOMPARE( vertices.wkbType(), Qgis::WkbType::MultiPoint ); QCOMPARE( vertices.constGet()->partCount(), 4 ); - QCOMPARE( vertices.constGet()->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 0, -0.87614105022163979 ) ); + QCOMPARE( vertices.constGet()->vertexAt( QgsVertexId( 0, 0, 0 ) ), QgsPoint( 0, -2.45319494062059196 ) ); QCOMPARE( vertices.constGet()->vertexAt( QgsVertexId( 1, 0, 0 ) ), QgsPoint( 0, 0.5 ) ); QCOMPARE( vertices.constGet()->vertexAt( QgsVertexId( 2, 0, 0 ) ), QgsPoint( 0.5, 1 ) ); - QCOMPARE( vertices.constGet()->vertexAt( QgsVertexId( 3, 0, 0 ) ), QgsPoint( 1.87040839992228825, 1 ) ); + QCOMPARE( vertices.constGet()->vertexAt( QgsVertexId( 3, 0, 0 ) ), QgsPoint( 3.43714351978240718, 1 ) ); // multipoint QgsVectorLayer *pointLayer = new QgsVectorLayer( QStringLiteral( "MultiPoint?crs=epsg:4326" ), QString(), QStringLiteral( "memory" ) ); @@ -632,14 +632,14 @@ void TestMapTools::testHandles() // an existing vertex (start/end of the line) QVector expected = { - QStringLiteral( "LineString (0 -0.87614105022164, 0 0)" ), - QStringLiteral( "LineString (1 1, 1.87040839992229 1)" ), + QStringLiteral( "LineString (0 -2.45319494062059, 0 0)" ), + QStringLiteral( "LineString (1 1, 3.43714351978241 1)" ), }; const QVector parts = handles.asGeometryCollection(); for ( int i = 0; i < parts.count(); i++ ) { - QVERIFY( parts.at( i ).asWkt( 14 ) == expected.at( i ) ); + QCOMPARE( parts.at( i ).asWkt( 14 ), expected.at( i ) ); } delete lineLayer; @@ -678,7 +678,7 @@ void TestMapTools::testLookForVertex() QCOMPARE( mapTool.state(), RecordingMapTool::MapToolState::View ); // Start handle point. Active vertex is invalid, state changes to Record - QPointF screenPoint = ms->coordinateToScreen( QgsPoint( -0.05, -0.83 ) ); + QPointF screenPoint = ms->coordinateToScreen( QgsPoint( -0.05, -2.45 ) ); mapTool.lookForVertex( screenPoint ); QVERIFY( !mapTool.activeVertex().isValid() ); QCOMPARE( mapTool.state(), RecordingMapTool::MapToolState::Record ); @@ -1038,7 +1038,7 @@ void TestMapTools::testAddVertexLineLayer() mapTool.addPoint( pointsToAdd[1] ); - QCOMPARE( mapTool.handles().vertexAt( 0 ).asWkt( 14 ), "Point (-96.22182942132511 22.34151145046518)" ); + QCOMPARE( mapTool.handles().vertexAt( 0 ).asWkt( 14 ), "Point (-94.5889223797103 21.87263206130249)" ); QCOMPARE( mapTool.handles().vertexAt( 1 ), pointsToAdd[0] ); delete project;