diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 2f29ad786..09f9e4099 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -246,7 +246,7 @@ jobs: -S ../ \ -B ./ - - name: build APK + - name: Build APK env: ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }} ANDROID_NDK_HOST: darwin-x86_64 @@ -271,7 +271,7 @@ jobs: path: ${{ github.workspace }}/merginmaps-${{ env.INPUT_VERSION_CODE }}.apk name: Mergin Maps ${{ env.INPUT_VERSION_CODE }} APK [v7 + v8a] - - name: build AAB + - name: Build AAB if: ${{ github.ref_name == 'master' || github.ref_type == 'tag' }} env: ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }} @@ -298,4 +298,3 @@ jobs: with: path: ${{ github.workspace }}/merginmaps-${{ env.INPUT_VERSION_CODE }}.aab name: Mergin Maps ${{ env.INPUT_VERSION_CODE }} AAB - diff --git a/.zenodo.json b/.zenodo.json index 679504442..360d0b6ca 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -2,7 +2,7 @@ "description": "

Mergin Maps mobile app is a QGIS powered app for Android and iOS devices.

", "license": "GPLv3", "title": "Mergin Maps mobile app", - "version": "2024.5.0", + "version": "2024.5.1", "upload_type": "software", "publication_date": "2022-02-24", "creators": [ @@ -39,7 +39,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/MerginMaps/mobile/tree/2024.5.0", + "identifier": "https://github.com/MerginMaps/mobile/tree/2024.5.1", "relation": "isSupplementTo" }, { diff --git a/CITATION.cff b/CITATION.cff index 8b1d6266b..5819d1869 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,4 +1,4 @@ -cff-version: 2024.5.0 +cff-version: 2024.5.1 message: "If you use this software, please cite it as below." authors: - family-names: "Martin" diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a883047c..abeb14fe3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.22) # TODO automatically change with the scripts/update version script set(MM_VERSION_MAJOR "2024") set(MM_VERSION_MINOR "5") -set(MM_VERSION_PATCH "0") +set(MM_VERSION_PATCH "1") set(QT_VERSION_DEFAULT "6.6.3") # Note: we cannot set this for non-android build, since CMake will start looking for diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index b96c77c27..cf9201375 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -27,6 +27,7 @@ set(MM_SRCS maptools/abstractmaptool.cpp maptools/recordingmaptool.cpp maptools/splittingmaptool.cpp + maptools/measurementmaptool.cpp ios/iosimagepicker.cpp ios/iosutils.cpp position/providers/abstractpositionprovider.cpp @@ -109,6 +110,7 @@ set(MM_HDRS maptools/abstractmaptool.h maptools/recordingmaptool.h maptools/splittingmaptool.h + maptools/measurementmaptool.h ios/iosimagepicker.h ios/iosutils.h position/providers/abstractpositionprovider.h diff --git a/app/i18n/input_de.qm b/app/i18n/input_de.qm index 155bb4b43..0e21377b3 100644 Binary files a/app/i18n/input_de.qm and b/app/i18n/input_de.qm differ diff --git a/app/i18n/input_de.ts b/app/i18n/input_de.ts index 9742ce1b6..5cf3b404f 100644 --- a/app/i18n/input_de.ts +++ b/app/i18n/input_de.ts @@ -25,7 +25,7 @@ Layer has invalid CRS assigned. Recording tools have undefined behaviour. - Dem Layer ist ein ungültiges Koordinatenreferenzsystem zugewiesen. Aufnahme und Speicher Funktionen verhalten sich undefiniert. + Dem Layer ist ein ungültiges Koordinatenreferenzsystem zugewiesen. Aufnahme- und Speicherfunktionen verhalten sich undefiniert! @@ -33,23 +33,23 @@ Internal (fused) - Intern (fused) + Intern (fusioniert) Internal (gps) - Intern (gps) + Intern (GPS) No location permissions - Keine Standortberechtigungen + Keine Standortberechtigungen Fused location not available - Fused Standort ist nicht verfügbar + Fusionierter Standort ist nicht verfügbar @@ -64,27 +64,27 @@ There was an error and tracking could not start, please contact support - Es ist eine Fehler aufgetreten und Tracking konnte nicht gestartet werden, kontaktieren Sie den Support + Es ist ein Fehler aufgetreten und das Tracking konnte nicht gestartet werden. Kontaktieren Sie bitte den Support. Your device does not support tracking, available from Android 8.0 - Ihr Gerät unterstützt kein Tracking. Mindestanforderung ist Android 8.0 + Ihr Gerät unterstützt kein Tracking - erst ab Android 8.0. Please enable location permission before starting tracking - Bitte aktivieren Sie die Berechtigung zur Standortbestimmung, bevor Sie das Tracking starten + Bitte aktivieren Sie die Berechtigung zur Standortbestimmung, bevor Sie das Tracking starten. Please enable location services on your device before starting tracking - Bitte aktivieren Sie die Standortbestimmung ihres Gerätes, bevor Sie das Tracking starten + Bitte aktivieren Sie die Standortbestimmung ihres Gerätes, bevor Sie das Tracking starten. Enable notifications to see tracking in the notifications tray - Aktivieren Sie Benachrichtigungen, um den Tracking-Status im Benachrichtigungsfeld zu sehen. + Aktivieren Sie *Benachrichtigungen*, um den Tracking-Status im Benachrichtigungsfeld zu sehen. @@ -92,22 +92,22 @@ Storage permission is permanently denied, please allow it in settings in order to load pictures from gallery - Die Speicherberechtigung wurde dauerhaft verweigert. Erlauben Sie dies in den Einstellungen, um Bilder aus der Galerie zu laden + Die Speicherberechtigung wurde dauerhaft verweigert. Geben Sie diese in den Einstellungen, um Bilder aus der Galerie laden zu können. Mergin Maps needs a storage permission in order to load pictures from gallery - Mergin Maps benötigt Speicherberechtigung um Bilder aus der Gallerie zu laden + Mergin Maps benötigt Speicherberechtigung, um Bilder aus der Gallerie zu laden. Camera permission is permanently denied, please allow it in settings - Keine Kameraerlaubnis erteilt, bitte in Einstellungen genehmigen + Keine Kameraerlaubnis erteilt, bitte in den Einstellungen genehmigen. We need a camera permission in order to take a photo - Wir benötigen eine Kameraerlaubnis, um ein Foto zu machen + Wir benötigen eine Kameraerlaubnis, um ein Foto zu machen. @@ -127,17 +127,17 @@ No connection, reconnecting in (%1) - Keine Verbindung, Verbindungsaufbau wird wiederholt in (%1) + Keine Verbindung. Der Verbindungsaufbau wird in (%1) wiederholt. Bluetooth permission disabled - Bluetooth Berechtigung deaktiviert + Bluetooth-Berechtigung deaktiviert Could not connect to device, not paired - Die Verbindung zum Gerät konnte nicht hergestellt werden, da es nicht gepaart ist. + Die Verbindung zum Gerät konnte nicht hergestellt werden, da es nicht gekoppelt ist. @@ -154,7 +154,7 @@ FeaturesModel - + Unknown title Unbekannter Titel @@ -164,7 +164,7 @@ Please fill a name of previous field before adding a new field. - Vor dem Hinzufügen eines neuen Feldes bitte den Namen des vorhergehenden Feldes eingeben + Vor dem Hinzufügen eines neuen Feldes bitte den Namen des vorhergehenden Feldes eingeben. @@ -184,12 +184,12 @@ Wird dem Projekt nicht hinzugefügt. Missing required PROJ datum shift grid: %1. For newly downloaded project please restart Mergin Maps. - Erforderliche PROJ Datum-Shift-Grids fehlen: %1. Für das zuletzt heruntergeladene Projekt bitte Mergin Maps-Neustart durchführen. + Erforderliches PROJ Datum-Shift-Grid fehlt: %1. Für das zuletzt heruntergeladene Projekt bitte einen Mergin Maps-Neustart durchführen. Error creating custom PROJ operation. For newly downloaded project please restart Mergin Maps. - Fehler bei benutzerdefinierter PROJ Operation. Für das zuletzt heruntergeladene Projekt bitte Mergin Maps-Neustart durchführen. + Fehler bei benutzerdefinierter PROJ-Operation. Für das zuletzt heruntergeladene Projekt bitte einen Mergin Maps-Neustart durchführen. @@ -200,119 +200,119 @@ Wird dem Projekt nicht hinzugefügt. InputUtils - + just now gerade jetzt - + %1 minutes ago vor %1 Minuten - + %1 minute ago vor %1 Minute - + %1 hours ago vor %1 Stunden - + %1 hour ago vor %1 Stunde - - + + %1 days ago vor %1 Tagen - - + + %1 day ago vor %1 Tag - + %1 weeks ago vor %1 Wochen - + %1 week ago vor %1 Woche - + %1 months ago vor %1 Monaten - + %1 month ago vor %1 Monat - + %1 years ago vor %1 Jahren - + %1 year ago vor %1 Jahr - + screen resolution: %1x%2 px Bildschirmauflösung: %1x%2 px - + screen DPI: %1x%2 - Bildschirm DPI: %1x%2 + Bildschirm-DPI: %1x%2 - + screen size: %1x%2 mm Bildschirmgröße: %1x%2 mm - + reported device pixel ratio: %1 Gemeldetes Gerätepixelverhältnis: %1 - + calculated device pixel ratio: %1 Berechnetes Gerätepixelverhältnis: %1 - + used dp scale: %1 verwendete DP-Skala: %1 - + You need to add at least %1 point(s) to every part. Sie müssen mindestens %1 Punkt(e) zu jedem Teil hinzufügen. - + You need to add at least %1 point(s). Sie müssen mindestens %1 Punkt(e) hinzufügen. @@ -336,17 +336,17 @@ Wird dem Projekt nicht hinzugefügt. Download failed, remove and retry - Download fehlgeschlagen, Datei entfernen und erneut versuchen + Download fehlgeschlagen. Datei entfernen und erneut versuchen. Found multiple QGIS project files - Mehrere QGIS Projektdateien gefunden + Mehrere QGIS-Projektdateien gefunden Failed to find a QGIS project file - Es konnte keine QGIS Projektdatei gefunden werden. + Es konnte keine QGIS-Projektdatei gefunden werden. @@ -359,7 +359,7 @@ Wird dem Projekt nicht hinzugefügt. We are bringing the benefits of open source GIS to businesses without compromises - Wir bringen die Vorteile von Open Source GIS ohne Kompromisse in Unternehmen + Wir bringen die Vorteile von Open Source-GIS ohne Kompromisse in Unternehmen. @@ -377,7 +377,7 @@ Wird dem Projekt nicht hinzugefügt. You have pending workspace invitations.<br>Please %1accept or reject%2 them. - Sie haben eine ausstehende Einladung zu einem Arbeitsbereich<br> Bitte %1akzeptieren oder ablehnen%2. + Sie haben eine ausstehende Einladung zu einem Arbeitsbereich<br>. Bitte %1akzeptieren oder ablehnen%2. @@ -385,12 +385,12 @@ Wird dem Projekt nicht hinzugefügt. You have been invited to a workspace - Sie wurden zu einem Arbeitsbereich eingeladen + Sie wurden zu einem Arbeitsbereich eingeladen. Join the workspace and explore together! - Treten Sie dem Arbeitsbereich bei und entdecken Sie gemeinsam + Treten Sie dem Arbeitsbereich bei und nehmen Sie gemeinsam auf! @@ -423,7 +423,7 @@ Wird dem Projekt nicht hinzugefügt. I accept the %1Terms and Conditions%3 and %2Privacy Policy%3 - Ich stimme den %1Allgemeinen Geschäftsbedingungen%3 und der %2Datenschutzerklärung%3 von Mergin zu. + Ich stimme den %1Allgemeinen Geschäftsbedingungen%3 und der %2Datenschutzerklärung%3 zu. @@ -484,7 +484,7 @@ Wird dem Projekt nicht hinzugefügt. You need to enable Bluetooth in order to connect new GPS receiver - Sie müssen Bluetooth aktivieren, um den neuen GPS-Empfänger zu verbinden. + Sie müssen Bluetooth aktivieren, um einen neuen GPS-Empfänger zu verbinden. @@ -540,8 +540,7 @@ Wird dem Projekt nicht hinzugefügt. We were not able to connect to the specified device. Please make sure your device is powered on and can be connected to. - Wir konnten keine Verbindung mit dem angegebenen Gerät herstellen. - Bitte stellen Sie sicher, dass Ihr Gerät eingeschaltet ist und eine Verbindung hergestellt werden kann.%1 %2Hier erfahren Sie mehr%3. + Wir konnten keine Verbindung mit dem angegebenen Gerät herstellen. Bitte stellen Sie sicher, dass Ihr Gerät eingeschaltet ist und eine Verbindung hergestellt werden kann. @@ -572,7 +571,7 @@ Wird dem Projekt nicht hinzugefügt. See what changed since you were last here. - Änderungen seit Ihrem letzten Besuch anzeigen + Sehen Sie, was sich seit Ihrem letzten Besuch geändert hat. @@ -585,7 +584,7 @@ Wird dem Projekt nicht hinzugefügt. This action will delete your account. If you are a workspace owner, you need to transfer the ownership to somebody else or close the workspace. - Diese Aktion löscht Ihren Account. Sollten Sie Eigentümer eines Arbeitsbereiches sein, müssen Sie diesen zuerst an jemand anderen übertragen. + Diese Aktion löscht Ihren Account. Sollten Sie Eigentümer eines Arbeitsbereiches sein, müssen Sie diesen zuerst an jemand anderen übertragen oder den Arbeitsbereich schließen. @@ -692,12 +691,12 @@ Wird dem Projekt nicht hinzugefügt. Clicking ‘Yes’ discards your changes to the geometry. If you would like to save the changes instead, hit ‘No’ and then ‘Done’ in the toolbar. - Wenn Sie auf 'Ja' klicken, werden Ihre Änderungen an der Geometrie verworfen. Wenn Sie die Änderungen stattdessen speichern möchten, klicken Sie auf 'Nein' und dann auf 'Fertig' in der Symbolleiste. + Wenn Sie auf 'Ja' klicken, werden Ihre Änderungen an der Geometrie verworfen. Wenn Sie die Änderungen stattdessen speichern möchten, klicken Sie auf 'Nein' und dann in der Symbolleiste auf 'Fertig'. Clicking ‘Yes’ discards your new geometry and no feature will be saved. If you would like to save the geometry instead, hit ‘No’ and then ‘Done’ in the toolbar. - Wenn Sie auf 'Ja' klicken, werden neuen Geometrien verworfen und kein Feature gespeichert. Wenn Sie die Geometrie stattdessen speichern möchten, klicken Sie auf 'Nein' und dann auf 'Fertig' in der Symbolleiste. + Wenn Sie auf 'Ja' klicken, werden neuen Geometrien verworfen und kein Feature gespeichert. Wenn Sie die Geometrie stattdessen speichern möchten, klicken Sie auf 'Nein' und dann in der Symbolleiste auf 'Fertig'. @@ -721,8 +720,7 @@ Wird dem Projekt nicht hinzugefügt. Would you like to download project %1 ? - Möchten Sie das Projekt herunterladen - %1 ? + Möchten Sie das Projekt %1 herunterladen? @@ -738,7 +736,7 @@ Wird dem Projekt nicht hinzugefügt. MMFeaturesListPage - + Add feature Objekt hinzufügen @@ -748,7 +746,7 @@ Wird dem Projekt nicht hinzugefügt. Search for features... - nach Objekten suchen... + Nach Objekten suchen... @@ -789,7 +787,7 @@ Wird dem Projekt nicht hinzugefügt. Failed to save changes. This should not happen normally. Please restart the app and try again — if that does not help, please contact support. - Das Speichern der Änderungen schlug fehl. Dies sollte normalerweise nicht passieren. Bitte die App neustarten und nochmal probieren - wenn dies auch nicht hilft, kontaktieren Sie den Support. + Das Speichern der Änderungen schlug fehl. Dies sollte normalerweise nicht passieren. Bitte die App neu starten und noch einmal probieren - wenn dies auch nicht hilft, kontaktieren Sie bitte den Support. @@ -808,7 +806,7 @@ Wird dem Projekt nicht hinzugefügt. Edit feature - Bearbeite Objekt + Objekt bearbeiten @@ -823,7 +821,7 @@ Wird dem Projekt nicht hinzugefügt. Feature could not be saved, please check all required fields - Objekt konnte nicht gespeichert werden, bitte überprüfen Sie alle Pflichtfelder + Objekt konnte nicht gespeichert werden, bitte überprüfen Sie alle Pflichtfelder. @@ -846,12 +844,12 @@ Wird dem Projekt nicht hinzugefügt. Could not create directory %1. - Ordner %1 konnte nicht erstellt werden + Ordner %1 konnte nicht erstellt werden. Failed to process the image - Das Bild konnte nicht verarbeitet werden + Das Bild konnte nicht verarbeitet werden. @@ -895,7 +893,7 @@ Wird dem Projekt nicht hinzugefügt. Yes, I want to save - Ja, ich möchte speichern + Ja, ich möchte speichern. @@ -908,12 +906,12 @@ Wird dem Projekt nicht hinzugefügt. GPS info - GPS info + GPS-Info Source - GPS Gerät + GPS-Gerät @@ -928,7 +926,7 @@ Wird dem Projekt nicht hinzugefügt. Longitude - Longitude + Längengrad @@ -948,12 +946,12 @@ Wird dem Projekt nicht hinzugefügt. N/A - N/A + k. A. Latitude - Latitude + Breitengrad @@ -983,12 +981,12 @@ Wird dem Projekt nicht hinzugefügt. Fix quality - Fixierungstyp + Fix-Typ Satellites (in use/view) - Satelliten (in Verwendung/Ansicht) + Satelliten (in Verwendung/Blick) @@ -1018,7 +1016,7 @@ Wird dem Projekt nicht hinzugefügt. GPS antenna height - GPS Antennen Höhe + GPS-Antennenhöhe @@ -1028,7 +1026,7 @@ Wird dem Projekt nicht hinzugefügt. Manage GPS receivers - GPS Empfänger verwalten + GPS-Empfänger verwalten @@ -1051,12 +1049,12 @@ Wird dem Projekt nicht hinzugefügt. QGIS website - QGIS Webseite + QGIS-Webseite Application store - App Store + App-Store @@ -1121,7 +1119,7 @@ Wird dem Projekt nicht hinzugefügt. Please specify the source - Bitte geben Sie eine Quelle an + Bitte geben Sie eine Quelle an. @@ -1139,7 +1137,7 @@ Wird dem Projekt nicht hinzugefügt. Visible on map - Sichtbar auf der Karte + Auf der Karte sichtbar @@ -1149,17 +1147,17 @@ Wird dem Projekt nicht hinzugefügt. Attribution - Attribution + Attribuierung Features - Features + Objekte Layer info - Layer Info + Layer-Info @@ -1224,7 +1222,7 @@ Wird dem Projekt nicht hinzugefügt. Log in - Log in + Log-in @@ -1244,7 +1242,7 @@ Wird dem Projekt nicht hinzugefügt. Sign in - Login + Anmelden @@ -1264,7 +1262,7 @@ Wird dem Projekt nicht hinzugefügt. Server address - Server Adresse + Server-Adresse @@ -1275,97 +1273,102 @@ Wird dem Projekt nicht hinzugefügt. MMMapController - + Mark the geometry on the map and click record - Setzen Sie einen Punkt auf der Karte und klicken Sie danach auf "Erfassen" + Setzen Sie einen Punkt auf der Karte und klicken Sie danach auf "Erfassen". - + Create line to split the selected feature - Linie erstellen, um das ausgewählte Feature zu teilen + Linie erstellen, um das ausgewählte Feature zu teilen. + + + + Add points to measure distance, close the shape to measure area + Fügen Sie Punkte für die Streckenmessung hinzu. Für die Flächenmessung setzen Sie den Endpunkt auf den Anfangspunkt, um das Polygon zu schließen. - + streaming fortlaufende Aufzeichnung - + Connecting to %1 Verbindet mit %1 - + Connected, no position Verbunden, keine Position - + Unknown accuracy Unbekannte Genauigkeit - + GPS currently unavailable GPS derzeit nicht verfügbar. - + Choose Active Layer Aktiven Layer wählen - + Could not find any editable layers in the project. Konnte keinen editierbaren Layer im Projekt finden. - + See how to enable digitizing in your project. Sehen Sie, wie Sie das Digitalisieren in Ihrem Projekt aktivieren können. - + More options Mehr Optionen - + Split geometry Geometrie teilen - + Redraw geometry Geometrie neu zeichnen - + Streaming mode Fortlaufende Aufzeichnung - + Active Aktiv - + Splitting done successfully Aufteilung erfolgreich durchgeführt - + Select some point to start editing the geometry Wähle einen Punkt aus, um mit der Bearbeitung der Geometrie zu beginnen. - + Record new geometry for the feature Neue Geometrie für das Feature erfassen - + GPS currently unavailable. GPS derzeit nicht verfügbar. @@ -1385,7 +1388,63 @@ Wird dem Projekt nicht hinzugefügt. Learn more about %1how to setup themes%2. - Finden Sie heraus wie man %1 Kartenthemen erstellen %2 kann + Finden Sie heraus wie man %1 Kartenthemen erstellen %2 kann. + + + + MMMeasureCrosshair + + + Close shape + Polygon schließen + + + + MMMeasureDrawer + + + Measure + Messen + + + + Repeat + Wiederholen + + + + Undo + Rückgängig machen + + + + Perimeter + Umfang + + + + Length + Länge + + + + Area + Fläche + + + + Close shape + Polygon schließen + + + + Add point + Punkt hinzufügen + + + + Done + Fertig @@ -1406,7 +1465,7 @@ Wird dem Projekt nicht hinzugefügt. This project is currently not uploaded on cloud. Upload it in order to activate synchronization and collaboration. - Dieses Projekt ist derzeit nicht in der Cloud hochgeladen. Laden Sie es hoch, um die Synchronisation und Zusammenarbeit zu aktivieren. + Dieses Projekt ist derzeit nicht in der Cloud hochgeladen. Laden Sie es hoch, um die Synchronisierung und Zusammenarbeit zu aktivieren. @@ -1424,17 +1483,17 @@ Wird dem Projekt nicht hinzugefügt. Sign in to your account - Melden Sie sich bei Ihrem Konto an + Melden Sie sich bei Ihrem Konto an. You need to be signed in to your account in order to synchronise the project. - Sie müssen bei Ihrem Mergin Maps Konto angemeldet sein, um das Projekt zu synchronisieren. + Sie müssen bei Ihrem Mergin Maps-Konto angemeldet sein, um das Projekt synchronisieren zu können. Yes, I want to sign in - Ja, ich möchte mich anmelden + Ja, ich möchte mich anmelden. @@ -1452,12 +1511,12 @@ Wird dem Projekt nicht hinzugefügt. You are not allowed to synchronise your changes in this project. Contact the project owner to assign you the correct permission. If you are the project owner, log in to the dashboard. - Sie dürfen Ihre Änderungen in diesem Projekt nicht synchronisieren. Wenden Sie sich an den Projekt Eigentümer, um Ihnen die richtige Berechtigung zuzuweisen. Wenn Sie der Projekt Eigentümer sind, melden Sie sich beim Dashboard an. + Sie dürfen Ihre Änderungen in diesem Projekt nicht synchronisieren. Wenden Sie sich an den Projekt-Eigentümer, damit er Ihnen die richtige Berechtigung zuweist. Wenn Sie der Projekt-Eigentümer sind, melden Sie sich beim Dashboard an. Ok, I understand - Ok, ich verstehe + Ok, ich verstehe. @@ -1465,7 +1524,7 @@ Wird dem Projekt nicht hinzugefügt. Your server will soon be out of date - Ihr Server wird in Kürze veraltet veraltet sein + Ihr Server wird in Kürze veraltet sein. @@ -1521,12 +1580,12 @@ Wird dem Projekt nicht hinzugefügt. Connecting to external receivers via bluetooth is not supported - Eine Verbindung zu externen Empfängern über Bluetooth wird nicht unterstützt + Eine Verbindung zu externen Empfängern über Bluetooth wird nicht unterstützt. This function is not available on iOS. Your hardware vendor may provide a custom app that connects to the receiver and sets position. The app will still think it is the internal GPS of your phone/tablet. - Diese Funktion ist auf iOS nicht verfügbar. Ihr Hardware-Hersteller könnte eine spezielle App bereitstellen, die sich mit dem Empfänger verbindet und die Position bereitstellt. Mergin Maps wird dennoch annehmen, dass es sich um das interne GPS Ihres Handys/Tablets handelt. + Diese Funktion ist auf iOS nicht verfügbar. Ihr Hardware-Hersteller könnte eine spezielle App bereitstellen, die sich mit dem Empfänger verbindet und die Position bereitstellt. Mergin Maps wird dann dennoch annehmen, dass es sich um das interne GPS Ihres Handys/Tablets handelt. @@ -1536,7 +1595,7 @@ Wird dem Projekt nicht hinzugefügt. Manage GPS receivers - GPS Empfänger verwalten + GPS-Empfänger verwalten @@ -1544,17 +1603,17 @@ Wird dem Projekt nicht hinzugefügt. Position tracking - Positions Tracking + Positions-Aufzeichnung Track your routes even with your screen off. Your records are stored in a separate layer. Finalised tracks are synced like any other feature. - Verfolgen Sie Ihre Routen auch bei ausgeschaltetem Bildschirm. Ihre Aufzeichnungen werden in einem separaten Layer gespeichert. Fertiggestellte Strecken werden wie alle anderen Objekte synchronisiert. + Nehmen Sie Ihre Routen auch bei ausgeschaltetem Bildschirm auf. Ihre Aufzeichnungen werden in einem separaten Layer gespeichert. Fertiggestellte Strecken werden wie alle anderen Objekte synchronisiert. The app can track your position on this project. - Mergin Maps kann Ihre Position in diesem Projekt aufzeichnen. + Mergin Maps kann Ihre Positionen in diesem Projekt aufzeichnen. @@ -1595,7 +1654,7 @@ Wird dem Projekt nicht hinzugefügt. PROJ Error - PROJ Fehler + PROJ-Fehler @@ -1631,7 +1690,7 @@ Wird dem Projekt nicht hinzugefügt. Unsupported server, please contact your server administrator. - Server wird nicht unterstützt. Bitte kontaktieren Sie Ihren Server Administrator + Server wird nicht unterstützt. Bitte kontaktieren Sie Ihren Server Administrator. @@ -1644,7 +1703,7 @@ Wird dem Projekt nicht hinzugefügt. Please don't close the app. - Bitte App nicht schließen + Bitte App nicht schließen. @@ -1692,12 +1751,12 @@ Wird dem Projekt nicht hinzugefügt. Your attention is required - Ihre Aufmerksamkeit ist erforderlich + Ihre Aufmerksamkeit ist erforderlich. Click here to access the dashboard - Klicken Sie hier um zum Mergin Maps Dashboard zu gelangen + Klicken Sie hier um zum Mergin Maps-Dashboard zu gelangen. @@ -1707,12 +1766,12 @@ Wird dem Projekt nicht hinzugefügt. Create your workspace by clicking here - Klicken Sie hier um einen Arbeitsbereich zu erstellen + Klicken Sie hier, um einen Arbeitsbereich zu erstellen. Currently open - derzeit geöffnet + Derzeit geöffnet @@ -1730,7 +1789,7 @@ Wird dem Projekt nicht hinzugefügt. QGIS log - QGIS log + QGIS-Protokoll @@ -1738,7 +1797,7 @@ Wird dem Projekt nicht hinzugefügt. You have reached a maximum number of projects - Sie haben die maximale Anzahl an Projekten erreicht + Sie haben die maximale Anzahl an Projekten erreicht. @@ -1756,7 +1815,7 @@ Wird dem Projekt nicht hinzugefügt. The project can not be opened - Das Projekt kann nicht geöffnet werden + Das Projekt kann nicht geöffnet werden. @@ -1771,12 +1830,12 @@ Wird dem Projekt nicht hinzugefügt. Let's get started - Lassen Sie uns anfangen + Lassen Sie uns anfangen! First step is to create your brand new project. - Erster Schritt ist ein neues Projekt zu erstellen + Im ersten Schritt erstellen wir ein neues Projekt. @@ -1804,7 +1863,7 @@ Wird dem Projekt nicht hinzugefügt. Unfortunately, your project could not be opened, please refer to our documentation to understand common problems. - Leider konnte Ihr Projekt nicht geöffnet werden. Bitte ziehen Sie unsere Dokumentation zu Rate, um häufige Probleme zu verstehen. + Leider konnte Ihr Projekt nicht geöffnet werden. Bitte ziehen Sie unsere Dokumentation zurate, um häufige Probleme verstehen zu lernen. @@ -1851,7 +1910,7 @@ Wird dem Projekt nicht hinzugefügt. Your local changes - Änderungen + Ihre lokalen Änderungen @@ -1861,12 +1920,12 @@ Wird dem Projekt nicht hinzugefügt. There are currently no local changes - Es gibt momentan keine lokalen Änderungen + Es gibt momentan keine lokalen Änderungen. Once you have made some changes, they will appear here. - Sobald Sie einige Änderungen vorgenommen haben, werden sie hier erscheinen + Sobald Sie einige Änderungen vorgenommen haben, werden sie hier erscheinen. @@ -1912,17 +1971,17 @@ Wird dem Projekt nicht hinzugefügt. Do you want to remove receiver from the list of recent receivers? - Wollen Sie den Empfänger von der Liste der letzten Empfänger entfernen? + Wollen Sie den Empfänger von der Liste der zuletzt genutzten Empfänger entfernen? Yes, I want to remove - Ja, ich will entfernen + Ja, ich will ihn entfernen. No, thanks - Nein, Danke + Nein, Danke. @@ -1930,7 +1989,7 @@ Wird dem Projekt nicht hinzugefügt. Undo - Rückgängig + Rückgängig machen @@ -1964,7 +2023,7 @@ Wird dem Projekt nicht hinzugefügt. Would you like to delete or unlink the photo? Deleting removes the photo from your project entirely, while unlinking keeps the photo in your project but removes it from this specific feature. - Möchten Sie das Foto löschen oder die Verknüpfung aufheben? Durch das Löschen wird das Foto vollständig aus Ihrem Projekt entfernt, während durch das Aufheben der Verknüpfung das Foto in Ihrem Projekt verbleibt, aber nicht mehr mit dem spezifischen Objekt verknüpft ist. + Möchten Sie das Foto löschen oder die Verknüpfung aufheben? Durch das Löschen wird das Foto vollständig aus Ihrem Projekt entfernt. Durch das Aufheben der Verknüpfung verbleibt das Foto in Ihrem Projekt, ist aber nicht mehr mit dem spezifischen Objekt verknüpft. @@ -1974,7 +2033,7 @@ Wird dem Projekt nicht hinzugefügt. Unlink photo - Unlink Foto + Foto-Verknüpfung aufheben @@ -1988,7 +2047,7 @@ Wird dem Projekt nicht hinzugefügt. Any unsynchronised changes will be lost in project %1 - Alle nicht synchronisierten Änderungen im Projekt gehen verloren %1 + Alle nicht synchronisierten Änderungen im Projekt %1 gehen verloren. @@ -2006,7 +2065,7 @@ Wird dem Projekt nicht hinzugefügt. Changelog could not be loaded - Änderungen können nicht geladen werden + Änderungen können nicht geladen werden. @@ -2038,42 +2097,42 @@ Wird dem Projekt nicht hinzugefügt. GPS accuracy threshold - GPS Genauigkeitsschwellenwert + GPS-Genauigkeitsschwellenwert Determines when the accuracy indicator turns yellow - Bestimmt, wann der Genauigkeitsindikator gelb wird + Bestimmt, wann der Genauigkeitsindikator gelb wird. GPS accuracy threshold, in meters - GPS Genauigkeitsschwellenwert, in Metern + GPS-Genauigkeitsschwellenwert, in Metern Manage GPS receivers - GPS Empfänger verwalten + GPS-Empfänger verwalten GPS antenna height - GPS Antennen Höhe + GPS-Antennenhöhe Includes pole height and GPS receiver’s antenna height - Enthält die Stabhöhe und die Höhe der GPS-Empfängerantenne + Ist die Stabhöhe + die Höhe der GPS-Empfängerantenne GPS antenna height, in meters - GPS Antennenhöhe, in Metern + GPS-Antennenhöhe, in Metern Streaming mode - Aufzeichnungs Modus + Aufzeichnungs-Modus @@ -2083,7 +2142,7 @@ Wird dem Projekt nicht hinzugefügt. Choose a type of threshold for streaming mode - Wählen Sie eine Intervall Typ zur automatischen Aufzeichnung + Wählen Sie eine Intervall-Typ für die automatische Aufzeichnung. @@ -2093,22 +2152,22 @@ Wird dem Projekt nicht hinzugefügt. Threshold interval - Intervall Schwelle + Intervall-Schwelle Streaming mode will add a point to the object at each interval - Im Aufzeichnungs-Modus wird in jedem Intervall ein Punk zum Objekt hinzugefügt + Im Aufzeichnungs-Modus wird nach jedem Intervall ein Punkt zum Objekt hinzugefügt. Threshold interval, in meters - Intervall Schwelle, in Metern + Intervall-Schwelle, in Metern Threshold interval, in seconds - Intervall Schwelle, in Sekunden + Intervall-Schwelle, in Sekunden @@ -2118,32 +2177,32 @@ Wird dem Projekt nicht hinzugefügt. Reuse last entered value - Letzten Wert wiederverwenden + Zuletzt eingegebenen Wert wiederverwenden Each field offers an option to reuse its value on the next feature - Jedes Feld bietet die Option, den gleichen Wert für das nächste Objekt wiederzuverwenden + Jedes Feld bietet die Option, denselben Wert wieder für das nächste Objekt zu verwenden. Automatically sync changes - Änderungen werden automatisch synchronisiert + Änderungen werden automatisch synchronisiert. Each time you save changes, the app will sync automatically - Jedes Mal, wenn Sie Änderungen speichern, wird die App automatisch synchronisieren + Jedes Mal, wenn Sie Änderungen speichern, wird die App diese automatisch synchronisieren. Auto-lock position - Auto-Lock Position + Position auto-sperren Each time you start recording, the app centers to GPS - Bei jedem Start der Aufnahme, zentriert sich die App auf die GPS-Position + Bei jedem Start der Aufnahme, zentriert sich die App auf die GPS-Position. @@ -2212,12 +2271,12 @@ Wird dem Projekt nicht hinzugefügt. I want to subscribe to the newsletter - Ich möchte mich für den Newsletter anmelden + Ich möchte mich für den Newsletter anmelden. Already have an account? - Ich habe bereits ein Benutzerkonto + Ich habe bereits ein Benutzerkonto. @@ -2230,17 +2289,17 @@ Wird dem Projekt nicht hinzugefügt. We could not split the feature - Das Feature konnte nicht geteilt werden + Das Feature konnte nicht geteilt werden. Please make sure that the split line crosses your feature. The feature needs to have a valid geometry in order to split it. - Bitte stellen Sie sicher, dass die geteilte Linie Ihr Feature kreuzt. Das Feature muss eine gültige Geometrie haben, damit es geteilt werden kann. + Bitte stellen Sie sicher, dass die Teilungs-Linie Ihr Objekt schneidet. Das Objekt muss eine gültige Geometrie haben, damit es geteilt werden kann. Ok, I understand - Ok, ich verstehe + Ok, ich verstehe. @@ -2248,7 +2307,7 @@ Wird dem Projekt nicht hinzugefügt. Undo - Rückgängig + Rückgängig machen @@ -2274,19 +2333,19 @@ Wird dem Projekt nicht hinzugefügt. Abstecken - + Feature Objekt - + Distance Distanz - + N/A - N/A + k. A. @@ -2294,7 +2353,7 @@ Wird dem Projekt nicht hinzugefügt. You have reached a data limit - Sie haben ein Datenlimit erreicht + Sie haben ein Datenlimit erreicht. @@ -2309,7 +2368,7 @@ Wird dem Projekt nicht hinzugefügt. Using - in Verwendung + In Verwendung @@ -2322,7 +2381,7 @@ Wird dem Projekt nicht hinzugefügt. Move around your designated object to record its geometry. You can stop this anytime. - Bewegen Sie sich um das festgelegte Objekt, um seine Geometrie aufzuzeichnen. Sie können dies jederzeit beenden. + Umrunden Sie das festgelegte Objekt, um seine Geometrie aufzuzeichnen. Sie können dies jederzeit beenden. @@ -2373,7 +2432,7 @@ Wird dem Projekt nicht hinzugefügt. Ok, I understand - Ok, ich verstehe + Ok, ich verstehe. @@ -2399,12 +2458,12 @@ Wird dem Projekt nicht hinzugefügt. We've been busy making the app even better! This update brings a fresh look and improved navigation, making it faster to find what you need. Take a look around! - Wir waren fleißig und haben Mergin Maps noch besser gemacht! Dieses Update bringt ein frisches Design und verbesserte Navigation mit sich. Finden Sie schneller was Sie benötigen. Schauen Sie sich um! + Wir waren fleißig und haben Mergin Maps noch besser gemacht! Dieses Update bringt ein frisches Design und eine verbesserte Navigation mit sich. Finden Sie nun schneller, was Sie benötigen. Schauen Sie sich um! Let's start! - Lassen Sie uns anfangen + Lassen Sie uns anfangen! @@ -2472,7 +2531,7 @@ Wird dem Projekt nicht hinzugefügt. Specify your industry - Bitte geben Sie Ihre Branche an + Bitte geben Sie Ihre Branche an. @@ -2482,12 +2541,12 @@ Wird dem Projekt nicht hinzugefügt. Crafting your workspace: let us know your industry - Erstellen Ihres Arbeitsbereichs: Teilen Sie uns Ihre Branche mit. + Erstellung Ihres Arbeitsbereichs: Teilen Sie uns Ihre Branche mit. Please specify the industry - Bitte geben Sie Ihre Branche an + Bitte geben Sie Ihre Branche an. @@ -2506,32 +2565,32 @@ only allows up to %1 downloaded projects. Username must have at least 4 characters - Der Benutzername muss mindestens 4 Zeichen haben + Der Benutzername muss mindestens 4 Zeichen haben. Username contains invalid characters - Der Benutzername enthält ungültige Zeichen + Der Benutzername enthält ungültige Zeichen. Please enter a valid email - Bitte eine gültige E-Mail-Adresse eingeben + Bitte eine gültige E-Mail-Adresse eingeben. Password not strong enough. It must%1 be at least 8 characters long%1 contain lowercase characters%1 contain uppercase characters%1 contain digits or special characters - Passwort nicht sicher genug. Es muss%1 mindestens 8 Zeichen haben%1 Kleinbuchstaben enthalten%1 Großbuchstaben enthalten%1 Zahlen oder Sonderzeichen enthalten + Passwort nicht sicher genug. Es muss%1 mindestens 8 Zeichen haben%1 Klein- und Großbuchstaben enthalten%1 und Zahlen oder Sonderzeichen enthalten. Passwords do not match - Passwörter nicht identisch + Passwörter sind nicht identisch. Please accept Terms and Privacy Policy - Bitte den Geschäftsbedingungen und der Datenschutzerklärung zustimmen + Bitte den Geschäftsbedingungen und der Datenschutzerklärung zustimmen. @@ -2566,12 +2625,12 @@ only allows up to %1 downloaded projects. Workspace name contains invalid characters - Der Name des Arbeitsbereiches enthält ungültige Zeichen + Der Name des Arbeitsbereiches enthält ungültige Zeichen. Workspace %1 already exists - Arbeitsbereich %1 ist bereits vorhanden + Arbeitsbereich %1 ist bereits vorhanden. @@ -2584,7 +2643,7 @@ only allows up to %1 downloaded projects. Failed to determine changes - Änderungen konnten nicht übernommen werden + Änderungen konnten nicht übernommen werden. @@ -2597,12 +2656,12 @@ only allows up to %1 downloaded projects. GPS receiver of this device - GPS Empfänger dieses Gerätes + GPS-Empfänger dieses Gerätes Internal (fused) - Intern (fused) + Intern (fusioniert) @@ -2617,7 +2676,7 @@ only allows up to %1 downloaded projects. Internal (gps) - Intern (gps) + Intern (GPS) @@ -2627,12 +2686,12 @@ only allows up to %1 downloaded projects. Bluetooth device - Bluetooth Gerät + Bluetooth-Gerät Bluetooth device - Bluetooth Gerät + Bluetooth-Gerät @@ -2640,17 +2699,17 @@ only allows up to %1 downloaded projects. Could not find tracking layer for the project - Konnten den Aufzeichnungs-Layer für das Projekt nicht finden + Konnte den Tracking-Layer für das Projekt nicht finden. Tracking layer not found or invalid - Aufzeichnungs-Layer wurde nicht gefunden oder ist ungültig + Tracking-Layer wurde nicht gefunden oder ist ungültig. Failed to start tracking, please contact support - Aufzeichnung konnte nicht gestartet werden, bitte kontaktieren Sie den Support + Tracking konnte nicht gestartet werden, bitte kontaktieren Sie den Support. @@ -2658,7 +2717,7 @@ only allows up to %1 downloaded projects. Project name contains invalid characters - Der Projekt Name enthält ungültige Zeichen + Der Projektname enthält ungültige Zeichen. @@ -2671,7 +2730,7 @@ only allows up to %1 downloaded projects. Pending changes to synchronise - Anstehende Änderungen für die Synchronisation + Zur Synchronisierung anstehende Änderungen @@ -2766,27 +2825,27 @@ only allows up to %1 downloaded projects. DGPS fix - DGPS Fix + DGPS-Fix PPS fix - PPS Fix + PPS-Fix RTK fix - RTK Fix + RTK-Fix RTK float - RTK Float + RTK-Float Estimated fix (dead reckoning) - Geschätzter Fixpunkt (Koppelnavigation) + Geschätzter Fix (Koppelnavigation) @@ -2796,7 +2855,7 @@ only allows up to %1 downloaded projects. Report submitted. Please contact us on %1 - Bericht gesendet. Kontaktiere uns unter %1 + Bericht gesendet. Kontaktieren Sie uns unter %1. @@ -2806,7 +2865,7 @@ only allows up to %1 downloaded projects. Synchronisation canceled - Synchronisation abgebrochen + Synchronisierung abgebrochen @@ -2820,113 +2879,118 @@ only allows up to %1 downloaded projects. main - + Sync Sync - + Add Hinzufügen - + No editable layers found. - Keine zu bearbeitenden Layer gefunden! + Keine bearbeitbaren Layer gefunden! - + Layers Layers - + Projects Projekte - + Zoom to project - Gesamtansicht + Auf Projekt zoomen - + Map themes Kartenthemen - + Position tracking - Positions Tracking + Positions-Tracking + + + + Measure + Messen - + Local changes - Änderungen + Lokale Änderungen - + Settings Einstellungen - - + + not tracking - keine Aufzeichnung + kein Tracking - + Select feature Objekt auswählen - + Somebody else is syncing, we will try again later - Jemand anderes synchronisiert gerade, wir versuchen es später noch einmal + Jemand anderes synchronisiert gerade, wir versuchen es später noch einmal. - + Details Details - + Failed to communicate with server. Try improving your network connection. Die Kommunikation mit dem Server ist fehlgeschlagen. Versuchen Sie, Ihre Netzwerkverbindung zu verbessern. - + Up to date Auf dem neuesten Stand - + There were issues loading the project. %1View details%2 Beim Laden des Projekts traten Probleme auf. %1Details anzeigen%2 - + Stake out is disabled because location is unavailable! Abstecken ist deaktiviert, weil der Standort nicht verfügbar ist! - + Successfully synchronised Synchronisierung erfolgreich - + There was an issue during synchronisation, we will try again. Click to learn more - Bei der Synchronisierung ist ein Problem aufgetreten. Wir werden es erneut versuchen. Klicken Sie hier, um mehr zu erfahren + Bei der Synchronisierung ist ein Problem aufgetreten. Wir werden es erneut versuchen. Klicken Sie hier, um mehr zu erfahren. - + Could not read the project file: Konnte die Projektdatei nicht lesen: - + Press back again to quit the app Drücken Sie erneut auf "Zurück", um die Anwendung zu beenden. diff --git a/app/i18n/input_en.qm b/app/i18n/input_en.qm index 38cc9c4ed..5b93e96c2 100644 Binary files a/app/i18n/input_en.qm and b/app/i18n/input_en.qm differ diff --git a/app/i18n/input_en.ts b/app/i18n/input_en.ts index 4513cea6d..4102b0bf6 100644 --- a/app/i18n/input_en.ts +++ b/app/i18n/input_en.ts @@ -201,117 +201,117 @@ Won't be added to the project. InputUtils - + just now - + %1 minutes ago - + %1 minute ago - + %1 hours ago - + %1 hour ago - - + + %1 days ago - - + + %1 day ago - + %1 weeks ago - + %1 week ago - + %1 months ago - + %1 month ago - + %1 years ago - + %1 year ago - + screen resolution: %1x%2 px screen resolution: %1x%2 px - + screen DPI: %1x%2 screen DPI: %1x%2 - + screen size: %1x%2 mm screen size: %1x%2 mm - + reported device pixel ratio: %1 - + calculated device pixel ratio: %1 - + used dp scale: %1 - + You need to add at least %1 point(s) to every part. - + You need to add at least %1 point(s). @@ -1272,97 +1272,102 @@ Won't be added to the project. MMMapController - + Mark the geometry on the map and click record - + Create line to split the selected feature - + + Add points to measure distance, close the shape to measure area + + + + streaming - + Connecting to %1 - + Connected, no position - + Unknown accuracy - + GPS currently unavailable - + Choose Active Layer - + Could not find any editable layers in the project. - + See how to enable digitizing in your project. - + More options - + Split geometry - + Redraw geometry - + Streaming mode - + Active - + Splitting done successfully - + Select some point to start editing the geometry - + Record new geometry for the feature - + GPS currently unavailable. @@ -1385,6 +1390,62 @@ Won't be added to the project. + + MMMeasureCrosshair + + + Close shape + + + + + MMMeasureDrawer + + + Measure + + + + + Repeat + + + + + Undo + Undo + + + + Perimeter + + + + + Length + + + + + Area + + + + + Close shape + + + + + Add point + + + + + Done + Done + + MMMessage @@ -2271,17 +2332,17 @@ Won't be added to the project. - + Feature - + Distance - + N/A @@ -2791,12 +2852,12 @@ only allows up to %1 downloaded projects. - + Report submitted. Please contact us on %1 - + Failed to submit report. Please check your internet connection. @@ -2817,113 +2878,118 @@ only allows up to %1 downloaded projects. main - + Sync - + Add - + No editable layers found. - + Layers - + Projects Projects - + Zoom to project Zoom to project - + Map themes Map themes - + Position tracking - + + Measure + + + + Local changes - + Settings Settings - - + + not tracking - + Select feature - + Somebody else is syncing, we will try again later - + Details - + Failed to communicate with server. Try improving your network connection. - + Up to date - + There were issues loading the project. %1View details%2 - + Stake out is disabled because location is unavailable! - + Successfully synchronised - + There was an issue during synchronisation, we will try again. Click to learn more - + Could not read the project file: - + Press back again to quit the app diff --git a/app/i18n/input_fr.qm b/app/i18n/input_fr.qm index 39c5ce7d7..36824a897 100644 Binary files a/app/i18n/input_fr.qm and b/app/i18n/input_fr.qm differ diff --git a/app/i18n/input_fr.ts b/app/i18n/input_fr.ts index ad62c15fe..7c502e3ce 100644 --- a/app/i18n/input_fr.ts +++ b/app/i18n/input_fr.ts @@ -154,7 +154,7 @@ FeaturesModel - + Unknown title Titre inconnu @@ -200,119 +200,119 @@ Ne sera pas ajouté au projet. InputUtils - + just now à l'instant - + %1 minutes ago il y a %1 minutes - + %1 minute ago il y a %1 minute - + %1 hours ago il y a %1 heures - + %1 hour ago il y a %1 heure - - + + %1 days ago il y a %1 jours - - + + %1 day ago il y a %1 jour - + %1 weeks ago il y a %1 semaines - + %1 week ago il y a %1 semaine - + %1 months ago il y a %1 mois - + %1 month ago il y a %1 mois - + %1 years ago il y a %1 ans - + %1 year ago il y a %1 an - + screen resolution: %1x%2 px résolution de l'écran : %1x%2 px - + screen DPI: %1x%2 DPI de l'écran : %1x%2 - + screen size: %1x%2 mm taille de l'écran : %1x%2 mm - + reported device pixel ratio: %1 Ratio rapporté de pixels de l'appareil: %1 - + calculated device pixel ratio: %1 Ratio calculé de pixels de l'appareil: %1 - + used dp scale: %1 Échelle dp utilisée: %1 - + You need to add at least %1 point(s) to every part. Vous devez ajouter au moins %1 point(s) à chaque partie. - + You need to add at least %1 point(s). Vous devez ajouter au moins %1 point(s). @@ -737,7 +737,7 @@ Ne sera pas ajouté au projet. MMFeaturesListPage - + Add feature Ajouter un élément @@ -1274,97 +1274,102 @@ Ne sera pas ajouté au projet. MMMapController - + Mark the geometry on the map and click record Marquez la géométrie sur la carte et cliquez sur Enregistrer. - + Create line to split the selected feature Créer une ligne pour diviser l'élément sélectionné - + + Add points to measure distance, close the shape to measure area + Ajouter des points pour mesurer une distance, fermer le polygone pour mesurer une surface + + + streaming streaming - + Connecting to %1 Connexion à %1 - + Connected, no position Connecté, aucune position - + Unknown accuracy Précision inconnue - + GPS currently unavailable GPS actuellement indisponible - + Choose Active Layer Choisir la couche active - + Could not find any editable layers in the project. Aucune couche éditable n'a été trouvée dans le projet. - + See how to enable digitizing in your project. Découvrez comment activer la digitalisation dans votre projet. - + More options Plus d'options - + Split geometry Fractionner la géométrie - + Redraw geometry Redessiner la géométrie - + Streaming mode Mode streaming - + Active Active - + Splitting done successfully Le fractionnement a été effectué avec succès - + Select some point to start editing the geometry Sélectionner un point pour commencer à modifier la géométrie - + Record new geometry for the feature Enregistrer une nouvelle géométrie pour l'élément - + GPS currently unavailable. GPS actuellement indisponible. @@ -1387,6 +1392,62 @@ Ne sera pas ajouté au projet. En savoir plus sur %1comment configurer les thèmes%2. + + MMMeasureCrosshair + + + Close shape + Fermer la couche + + + + MMMeasureDrawer + + + Measure + Mesurer + + + + Repeat + Recommencer + + + + Undo + Annuler + + + + Perimeter + Périmètre + + + + Length + Longueur + + + + Area + Surface + + + + Close shape + Fermer la couche + + + + Add point + Ajouter un point + + + + Done + Fait + + MMMessage @@ -2274,17 +2335,17 @@ Ne sera pas ajouté au projet. Piquetage - + Feature Entité - + Distance Distance - + N/A N/A @@ -2820,113 +2881,118 @@ only allows up to %1 downloaded projects. main - + Sync Synchroniser - + Add Ajouter - + No editable layers found. Aucune couche éditable n'a pu être trouvée. - + Layers Couches - + Projects Projets - + Zoom to project Se localiser - + Map themes Thèmes - + Position tracking Enregistrement de la position - + + Measure + Mesure + + + Local changes Changements locaux - + Settings Paramètres - - + + not tracking Pas d'enregistrement de la position - + Select feature Sélectionner une entité - + Somebody else is syncing, we will try again later Quelqu'un d'autre est une train de synchroniser, veuillez réessayer plus tard - + Details Détails - + Failed to communicate with server. Try improving your network connection. La connexion avec le serveur a échoué. Essayez avec un meilleur réseau - + Up to date À jour - + There were issues loading the project. %1View details%2 Il y a eu des problèmes au chargement du projet. %1 Voir les détails %2 - + Stake out is disabled because location is unavailable! Le piquetage est désactivé car aucune position n'est disponible! - + Successfully synchronised Synchronisation effectuée avec succès - + There was an issue during synchronisation, we will try again. Click to learn more Il y a eu un problème lors de la synchronisation, nous allons réessayer. Cliquez pour en savoir plus - + Could not read the project file: Le fichier du projet n'a pu être lu - + Press back again to quit the app Appuyer à nouveau sur retour pour quitter l'application diff --git a/app/i18n/input_fr_FR.qm b/app/i18n/input_fr_FR.qm index db450eb18..8abbe7789 100644 Binary files a/app/i18n/input_fr_FR.qm and b/app/i18n/input_fr_FR.qm differ diff --git a/app/i18n/input_fr_FR.ts b/app/i18n/input_fr_FR.ts index dd41c17bd..e4f369e19 100644 --- a/app/i18n/input_fr_FR.ts +++ b/app/i18n/input_fr_FR.ts @@ -156,7 +156,7 @@ FeaturesModel - + Unknown title Titre inconnu @@ -202,119 +202,119 @@ Ne sera pas ajouté au projet. InputUtils - + just now à l'instant - + %1 minutes ago il y a %1 minutes - + %1 minute ago il y a %1 minute - + %1 hours ago il y a %1 heures - + %1 hour ago il y a %1 heure - - + + %1 days ago il y a %1 jours - - + + %1 day ago il y a %1 jour - + %1 weeks ago il y a %1 semaines - + %1 week ago il y a %1 semaine - + %1 months ago il y a %1 mois - + %1 month ago il y a %1 mois - + %1 years ago il y a %1 ans - + %1 year ago il y a %1 an - + screen resolution: %1x%2 px résolution de l'écran : %1x%2 px - + screen DPI: %1x%2 DPI de l'écran : %1x%2 - + screen size: %1x%2 mm taille de l'écran : %1x%2 mm - + reported device pixel ratio: %1 Ratio rapporté de pixels de l'appareil: %1 - + calculated device pixel ratio: %1 Ratio calculé de pixels de l'appareil: %1 - + used dp scale: %1 Échelle dp utilisée: %1 - + You need to add at least %1 point(s) to every part. Vous devez ajouter au moins %1 point(s) à chaque partie. - + You need to add at least %1 point(s). Vous devez ajouter au moins %1 point(s). @@ -743,7 +743,7 @@ Ne sera pas ajouté au projet. MMFeaturesListPage - + Add feature Ajouter un élément @@ -818,7 +818,7 @@ Ne sera pas ajouté au projet. Delete - Suprimmer + Supprimer @@ -1280,102 +1280,107 @@ Ne sera pas ajouté au projet. MMMapController - + Mark the geometry on the map and click record Marquez la géométrie sur la carte et cliquez sur Enregistrer. - + Create line to split the selected feature Créer une ligne pour diviser l'élément sélectionné - + + Add points to measure distance, close the shape to measure area + Ajouter des points pour mesurer une distance, fermer le polygone pour mesurer une surface + + + streaming streaming - + Connecting to %1 Connexion à %1 - + Connected, no position Connecté, aucune position - + Unknown accuracy Précision inconnue - + GPS currently unavailable GPS actuellement indisponible - + Choose Active Layer Choisir la couche active - + Could not find any editable layers in the project. Aucune couche éditable n'a été trouvée dans le projet. - + See how to enable digitizing in your project. Découvrez comment activer la digitalisation dans votre projet. - + More options Plus d'options - + Split geometry Fractionner la géométrie - + Redraw geometry Redessiner la géométrie - + Streaming mode Mode streaming - + Active Active - + Splitting done successfully Le fractionnement a été effectué avec succès - + Select some point to start editing the geometry Sélectionner un point pour commencer à modifier la géométrie - + Record new geometry for the feature Enregistrer une nouvelle géométrie pour l'élément - + GPS currently unavailable. GPS actuellement indisponible. @@ -1398,6 +1403,62 @@ Ne sera pas ajouté au projet. En savoir plus sur %1comment configurer les thèmes%2. + + MMMeasureCrosshair + + + Close shape + Fermer la couche + + + + MMMeasureDrawer + + + Measure + Mesurer + + + + Repeat + Recommencer + + + + Undo + Annuler + + + + Perimeter + Périmètre + + + + Length + Longueur + + + + Area + Surface + + + + Close shape + Fermer la couche + + + + Add point + Ajouter un point + + + + Done + Fait + + MMMessage @@ -2288,17 +2349,17 @@ Ne sera pas ajouté au projet. Piquetage - + Feature Entité - + Distance Distance - + N/A N/A @@ -2836,113 +2897,118 @@ only allows up to %1 downloaded projects. main - + Sync Synchroniser - + Add Ajouter - + No editable layers found. Aucune couche éditable n'a pu être trouvée. - + Layers Couches - + Projects Projets - + Zoom to project Se localiser - + Map themes Thèmes - + Position tracking Enregistrement de la position - + + Measure + Mesure + + + Local changes Changements locaux - + Settings Paramètres - - + + not tracking Pas d'enregistrement de la position - + Select feature Sélectionner une entité - + Somebody else is syncing, we will try again later Quelqu'un d'autre est une train de synchroniser, veuillez réessayer plus tard - + Details Détails - + Failed to communicate with server. Try improving your network connection. La connexion avec le serveur a échoué. Essayez avec un meilleur réseau - + Up to date À jour - + There were issues loading the project. %1View details%2 Il y a eu des problèmes au chargement du projet. %1 Voir les détails %2 - + Stake out is disabled because location is unavailable! Le piquetage est désactivé car aucune position n'est disponible! - + Successfully synchronised Synchronisation effectuée avec succès - + There was an issue during synchronisation, we will try again. Click to learn more Il y a eu un problème lors de la synchronisation, nous allons réessayer. Cliquez pour en savoir plus - + Could not read the project file: Le fichier du projet n'a pu être lu - + Press back again to quit the app Appuyer à nouveau sur retour pour quitter l'application diff --git a/app/i18n/input_hr.qm b/app/i18n/input_hr.qm index 34c0f2c53..be89cb49b 100644 Binary files a/app/i18n/input_hr.qm and b/app/i18n/input_hr.qm differ diff --git a/app/i18n/input_hr.ts b/app/i18n/input_hr.ts index 65d85b1f2..b93109fa5 100644 --- a/app/i18n/input_hr.ts +++ b/app/i18n/input_hr.ts @@ -154,7 +154,7 @@ FeaturesModel - + Unknown title Nepoznati naslov @@ -199,119 +199,119 @@ Won't be added to the project. InputUtils - + just now upravo - + %1 minutes ago prije %1 minuta - + %1 minute ago prije %1 minute - + %1 hours ago prije %1 sati - + %1 hour ago prije %1 sata - - + + %1 days ago prije %1 dana - - + + %1 day ago prije %1 dana - + %1 weeks ago prije %1 tjedana - + %1 week ago prije %1 tjedna - + %1 months ago prije %1 mjeseci - + %1 month ago prije %1 mjeseca - + %1 years ago prije %1 godina - + %1 year ago prije %1 godine - + screen resolution: %1x%2 px rezolucija zaslona: %1x%2 px - + screen DPI: %1x%2 DPI zaslona: %1x%2 - + screen size: %1x%2 mm veličina zaslona: %1x%2 mm - + reported device pixel ratio: %1 prijavljeni omjer piksela zaslona uređaja: %1 - + calculated device pixel ratio: %1 izračunati omjer piksela zaslona uređaja: %1 - + used dp scale: %1 korišteno dp mjerilo: %1 - + You need to add at least %1 point(s) to every part. Morate dodati barem %1 točku u svakom od segmenata. - + You need to add at least %1 point(s). Morate dodati barem %1 točku(točaka). @@ -736,7 +736,7 @@ Won't be added to the project. MMFeaturesListPage - + Add feature Dodaj objekt @@ -1273,97 +1273,102 @@ Won't be added to the project. MMMapController - + Mark the geometry on the map and click record Označi geometriju na karti i klikni - + Create line to split the selected feature Stvori liniju kako bi razdvojio odabrani objekt - + + Add points to measure distance, close the shape to measure area + Dodajte točke za mjerenje udaljenosti, zatvorite površinu za mjerenje površine + + + streaming kontinuirano snimanje - + Connecting to %1 Povezivanje na %1 - + Connected, no position Povezano, nema pozicije - + Unknown accuracy Nepoznata preciznost - + GPS currently unavailable GPS trenutno nije dostupan - + Choose Active Layer Odaberi aktivni sloj - + Could not find any editable layers in the project. Nema slojeva predviđenih za snimanje u projektu! - + See how to enable digitizing in your project. Pogledajte kako omogućiti snimanje u projektu - + More options Više mogućnosti - + Split geometry Razdvoji geometriju - + Redraw geometry Ponovno iscrtaj geometriju - + Streaming mode Kontinuirano snimanje - + Active Aktivno - + Splitting done successfully Razdvajanje uspješno izvršeno - + Select some point to start editing the geometry Odaberite jednu od točaka za početak izmjene geometrije - + Record new geometry for the feature Snimi novu geometriju za objekt - + GPS currently unavailable. GPS trenutno nije dostupan @@ -1386,6 +1391,62 @@ Won't be added to the project. Saznaj više o tome %1kako postaviti teme%2. + + MMMeasureCrosshair + + + Close shape + Zatvori površinu + + + + MMMeasureDrawer + + + Measure + Izmjeri + + + + Repeat + Ponovi + + + + Undo + Poništi + + + + Perimeter + Opseg + + + + Length + Duljina + + + + Area + Površina + + + + Close shape + Zatvori površinu + + + + Add point + Dodaj točku + + + + Done + Završi + + MMMessage @@ -2273,17 +2334,17 @@ Won't be added to the project. Navođenje - + Feature Objekt - + Distance Udaljenost - + N/A N/A @@ -2820,113 +2881,118 @@ dozvoljava samo %1 preuzetih projekata. main - + Sync Sinkronizacija - + Add Dodaj - + No editable layers found. Nema slojeva za uređivanje. - + Layers Slojevi - + Projects Projekti - + Zoom to project Zumiraj na projekt - + Map themes Teme karte - + Position tracking Praćenje pozicije - + + Measure + Izmjeri + + + Local changes Lokalne izmjene - + Settings Postavke - - + + not tracking ne pratim - + Select feature Odaberi objekt - + Somebody else is syncing, we will try again later Netko upravo sinkronizira podatke, pokušati ćemo nešto kasnije - + Details Detalji - + Failed to communicate with server. Try improving your network connection. Neuspješna komunikacija sa poslužiteljem. Provjerite mrežne postavke i kvalitetu signala. - + Up to date Ažurno - + There were issues loading the project. %1View details%2 Došlo je do problema prilikom učitavanja projekta. %1Pogledajte detalje%2 - + Stake out is disabled because location is unavailable! Navođenje je onemogućeno zbog nedostupnosti lokacije! - + Successfully synchronised Uspješno sinkronizirano - + There was an issue during synchronisation, we will try again. Click to learn more Došlo je do problema prilikom sinkronizacije, pokušati ćemo ponovno. Klikni za više - + Could not read the project file: Nije bilo moguće otvoriti datoteku projekta: - + Press back again to quit the app Odaberite "nazad" još jednom za izlaz iz aplikacije diff --git a/app/i18n/input_hr_BA.qm b/app/i18n/input_hr_BA.qm index adbc14ed9..b19011e04 100644 Binary files a/app/i18n/input_hr_BA.qm and b/app/i18n/input_hr_BA.qm differ diff --git a/app/i18n/input_hr_BA.ts b/app/i18n/input_hr_BA.ts index 2821b7449..67df63269 100644 --- a/app/i18n/input_hr_BA.ts +++ b/app/i18n/input_hr_BA.ts @@ -154,7 +154,7 @@ FeaturesModel - + Unknown title Nepoznati naslov @@ -199,119 +199,119 @@ Won't be added to the project. InputUtils - + just now upravo - + %1 minutes ago prije %1 minuta - + %1 minute ago prije %1 minute - + %1 hours ago prije %1 sati - + %1 hour ago prije %1 sata - - + + %1 days ago prije %1 dana - - + + %1 day ago prije %1 dana - + %1 weeks ago prije %1 tjedana - + %1 week ago prije %1 tjedna - + %1 months ago prije %1 mjeseci - + %1 month ago prije %1 mjeseca - + %1 years ago prije %1 godina - + %1 year ago prije %1 godine - + screen resolution: %1x%2 px rezolucija zaslona: %1x%2 px - + screen DPI: %1x%2 DPI zaslona: %1x%2 - + screen size: %1x%2 mm veličina zaslona: %1x%2 mm - + reported device pixel ratio: %1 prijavljeni omjer piksela zaslona uređaja: %1 - + calculated device pixel ratio: %1 izračunati omjer piksela zaslona uređaja: %1 - + used dp scale: %1 korišteno dp mjerilo: %1 - + You need to add at least %1 point(s) to every part. Morate dodati barem %1 točku(točaka) u svakom od segmenata. - + You need to add at least %1 point(s). Morate dodati barem %1 točku(točaka). @@ -736,7 +736,7 @@ Won't be added to the project. MMFeaturesListPage - + Add feature Dodaj objekt @@ -1273,97 +1273,102 @@ Won't be added to the project. MMMapController - + Mark the geometry on the map and click record Označi geometriju na karti i klikni - + Create line to split the selected feature Stvori liniju kako bi razdvojio odabrani objekt - + + Add points to measure distance, close the shape to measure area + Dodajte točke za mjerenje udaljenosti, zatvorite oblik za mjerenje površine + + + streaming kontinuirano snimanje - + Connecting to %1 Povezivanje na %1 - + Connected, no position Povezano, nema pozicije - + Unknown accuracy Nepoznata preciznost - + GPS currently unavailable GPS trenutno nije dostupan - + Choose Active Layer Odaberi aktivni sloj - + Could not find any editable layers in the project. Nema slojeva predviđenih za snimanje u projektu! - + See how to enable digitizing in your project. Pogledajte kako omogućiti snimanje u projektu - + More options Više mogućnosti - + Split geometry Razdvoji geometriju - + Redraw geometry Ponovno iscrtaj geometriju - + Streaming mode Kontinuirano snimanje - + Active Aktivno - + Splitting done successfully Razdvajanje uspješno izvršeno - + Select some point to start editing the geometry Odaberite jednu od točaka za početak izmjene geometrije - + Record new geometry for the feature Snimi novu geometriju za objekt - + GPS currently unavailable. GPS trenutno nije dostupan @@ -1386,6 +1391,62 @@ Won't be added to the project. Saznaj više o tome %1kako postaviti teme%2. + + MMMeasureCrosshair + + + Close shape + Zatvori objekt + + + + MMMeasureDrawer + + + Measure + Izmjeri + + + + Repeat + Ponovi + + + + Undo + Poništi + + + + Perimeter + Opseg + + + + Length + Duljina + + + + Area + Površina + + + + Close shape + Zatvori objekt + + + + Add point + Dodaj točku + + + + Done + Završi + + MMMessage @@ -2273,17 +2334,17 @@ Won't be added to the project. Navođenje - + Feature Objekt - + Distance Udaljenost - + N/A N/A @@ -2820,113 +2881,118 @@ dozvoljava samo %1 preuzetih projekata. main - + Sync Sinkronizacija - + Add Dodaj - + No editable layers found. Nema slojeva za uređivanje. - + Layers Slojevi - + Projects Projekti - + Zoom to project Zumiraj na projekt - + Map themes Teme karte - + Position tracking Praćenje pozicije - + + Measure + Izmjeri + + + Local changes Lokalne izmjene - + Settings Postavke - - + + not tracking ne pratim - + Select feature Odaberi objekt - + Somebody else is syncing, we will try again later Netko upravo sinkronizira podatke, pokušati ćemo nešto kasnije - + Details Detalji - + Failed to communicate with server. Try improving your network connection. Neuspješna komunikacija sa poslužiteljem. Provjerite mrežne postavke i kvalitetu signala. - + Up to date Ažurno - + There were issues loading the project. %1View details%2 Došlo je do problema prilikom učitavanja projekta. %1Pogledajte detalje%2 - + Stake out is disabled because location is unavailable! Navođenje je onemogućeno zbog nedostupnosti lokacije! - + Successfully synchronised Uspješno sinkronizirano - + There was an issue during synchronisation, we will try again. Click to learn more Došlo je do problema prilikom sinkronizacije, pokušati ćemo ponovno. Klikni za više - + Could not read the project file: Nije bilo moguće otvoriti datoteku projekta: - + Press back again to quit the app Odaberite "nazad" još jednom za izlaz iz aplikacije diff --git a/app/i18n/input_hr_HR.qm b/app/i18n/input_hr_HR.qm index d7e2f196e..22206aec5 100644 Binary files a/app/i18n/input_hr_HR.qm and b/app/i18n/input_hr_HR.qm differ diff --git a/app/i18n/input_hr_HR.ts b/app/i18n/input_hr_HR.ts index 650fed386..2ad41ae50 100644 --- a/app/i18n/input_hr_HR.ts +++ b/app/i18n/input_hr_HR.ts @@ -154,7 +154,7 @@ FeaturesModel - + Unknown title Nepoznati naslov @@ -199,119 +199,119 @@ Won't be added to the project. InputUtils - + just now upravo - + %1 minutes ago prije %1 minuta - + %1 minute ago prije %1 minute - + %1 hours ago prije %1 sati - + %1 hour ago prije %1 sata - - + + %1 days ago prije %1 dana - - + + %1 day ago prije %1 dana - + %1 weeks ago prije %1 tjedana - + %1 week ago prije %1 tjedna - + %1 months ago prije %1 mjeseci - + %1 month ago prije %1 mjeseca - + %1 years ago prije %1 godina - + %1 year ago prije %1 godine - + screen resolution: %1x%2 px rezolucija zaslona: %1x%2 px - + screen DPI: %1x%2 DPI zaslona: %1x%2 - + screen size: %1x%2 mm veličina zaslona: %1x%2 mm - + reported device pixel ratio: %1 prijavljeni omjer piksela zaslona uređaja: %1 - + calculated device pixel ratio: %1 izračunati omjer piksela zaslona uređaja: %1 - + used dp scale: %1 korišteno dp mjerilo: %1 - + You need to add at least %1 point(s) to every part. Morate dodati barem %1 točku(točaka) u svakom od segmenata. - + You need to add at least %1 point(s). Morate dodati barem %1 točku(točaka). @@ -736,7 +736,7 @@ Won't be added to the project. MMFeaturesListPage - + Add feature Dodaj objekt @@ -1273,97 +1273,102 @@ Won't be added to the project. MMMapController - + Mark the geometry on the map and click record Označi geometriju na karti i klikni - + Create line to split the selected feature Stvori liniju kako bi razdvojio odabrani objekt - + + Add points to measure distance, close the shape to measure area + Dodajte točke za mjerenje udaljenosti, zatvorite oblik za mjerenje površine + + + streaming kontinuirano snimanje - + Connecting to %1 Povezivanje na %1 - + Connected, no position Povezano, nema pozicije - + Unknown accuracy Nepoznata preciznost - + GPS currently unavailable GPS trenutno nije dostupan - + Choose Active Layer Odaberi aktivni sloj - + Could not find any editable layers in the project. Nema slojeva predviđenih za snimanje u projektu! - + See how to enable digitizing in your project. Pogledajte kako omogućiti snimanje u projektu - + More options Više mogućnosti - + Split geometry Razdvoji geometriju - + Redraw geometry Ponovno iscrtaj geometriju - + Streaming mode Kontinuirano snimanje - + Active Aktivno - + Splitting done successfully Razdvajanje uspješno izvršeno - + Select some point to start editing the geometry Odaberite jednu od točaka za početak izmjene geometrije - + Record new geometry for the feature Snimi novu geometriju za objekt - + GPS currently unavailable. GPS trenutno nije dostupan @@ -1386,6 +1391,62 @@ Won't be added to the project. Saznaj više o tome %1kako postaviti teme%2. + + MMMeasureCrosshair + + + Close shape + Zatvori objekt + + + + MMMeasureDrawer + + + Measure + Izmjeri + + + + Repeat + Ponovi + + + + Undo + Poništi + + + + Perimeter + Opseg + + + + Length + Duljina + + + + Area + Površina + + + + Close shape + Zatvori objekt + + + + Add point + Dodaj točku + + + + Done + Završi + + MMMessage @@ -2273,17 +2334,17 @@ Won't be added to the project. Navođenje - + Feature Objekt - + Distance Udaljenost - + N/A N/A @@ -2820,113 +2881,118 @@ dozvoljava samo %1 preuzetih projekata. main - + Sync Sinkronizacija - + Add Dodaj - + No editable layers found. Nema slojeva za uređivanje. - + Layers Slojevi - + Projects Projekti - + Zoom to project Zumiraj na projekt - + Map themes Teme karte - + Position tracking Praćenje pozicije - + + Measure + Izmjeri + + + Local changes Lokalne izmjene - + Settings Postavke - - + + not tracking ne pratim - + Select feature Odaberi objekt - + Somebody else is syncing, we will try again later Netko upravo sinkronizira podatke, pokušati ćemo nešto kasnije - + Details Detalji - + Failed to communicate with server. Try improving your network connection. Neuspješna komunikacija sa poslužiteljem. Provjerite mrežne postavke i kvalitetu signala. - + Up to date Ažurno - + There were issues loading the project. %1View details%2 Došlo je do problema prilikom učitavanja projekta. %1Pogledajte detalje%2 - + Stake out is disabled because location is unavailable! Navođenje je onemogućeno zbog nedostupnosti lokacije! - + Successfully synchronised Uspješno sinkronizirano - + There was an issue during synchronisation, we will try again. Click to learn more Došlo je do problema prilikom sinkronizacije, pokušati ćemo ponovno. Klikni za više - + Could not read the project file: Nije bilo moguće otvoriti datoteku projekta: - + Press back again to quit the app Odaberite "nazad" još jednom za izlaz iz aplikacije diff --git a/app/i18n/input_hu.qm b/app/i18n/input_hu.qm index e28299bfa..d84bc05a8 100644 Binary files a/app/i18n/input_hu.qm and b/app/i18n/input_hu.qm differ diff --git a/app/i18n/input_hu.ts b/app/i18n/input_hu.ts index de2366333..92c4d6ae3 100644 --- a/app/i18n/input_hu.ts +++ b/app/i18n/input_hu.ts @@ -154,7 +154,7 @@ FeaturesModel - + Unknown title Ismeretlen cím @@ -200,119 +200,119 @@ Nem lesz hozzáadva a projekthez. InputUtils - + just now csak most - + %1 minutes ago %1 perccel ezelőtt - + %1 minute ago %1 perccel ezelőtt - + %1 hours ago %1 órával ezelőtt - + %1 hour ago %1 órával ezelőtt - - + + %1 days ago %1 nappal ezelőtt - - + + %1 day ago %1 nappal ezelőtt - + %1 weeks ago %1 héttel ezelőtt - + %1 week ago %1 héttel ezelőtt - + %1 months ago %1 hónappal ezelőtt - + %1 month ago %1 hónappal ezelőtt - + %1 years ago %1 évvel ezelőtt - + %1 year ago %1 évvel ezelőtt - + screen resolution: %1x%2 px képernyő felbontás: %1x%2 pixel - + screen DPI: %1x%2 képernyő DPI: %1x%2 - + screen size: %1x%2 mm képernyő méret: %1x%2 mm - + reported device pixel ratio: %1 jelentett eszköz pixelarány: %1 - + calculated device pixel ratio: %1 számított eszköz pixelarány: %1 - + used dp scale: %1 használt dp skála: %1 - + You need to add at least %1 point(s) to every part. Minden részhez legalább %1 pontot kell hozzáadnia. - + You need to add at least %1 point(s). Legalább %1 pontot kell hozzáadnia. @@ -737,7 +737,7 @@ Nem lesz hozzáadva a projekthez. MMFeaturesListPage - + Add feature Elem hozzáadása @@ -1274,97 +1274,102 @@ Nem lesz hozzáadva a projekthez. MMMapController - + Mark the geometry on the map and click record Válassza ki a geometriát a térképen, és bökjön a rögzítésre - + Create line to split the selected feature Vonal létrehozása a kiválasztott elem felosztásához - + + Add points to measure distance, close the shape to measure area + Adjon hozzá pontokat a távolság méréséhez, zárja be az alakzatot a terület méréséhez + + + streaming streaming - + Connecting to %1 Csatlakozás: %1 - + Connected, no position Csatlakozva, nincs pozíció - + Unknown accuracy Ismeretlen pontosság - + GPS currently unavailable A GPS jelenleg nem elérhető - + Choose Active Layer Aktív réteg kiválasztása - + Could not find any editable layers in the project. A projektben nem található semmilyen szerkeszthető réteg. - + See how to enable digitizing in your project. Nézze meg, hogy lehet engedélyezni a digitalizálást a projektjében. - + More options Több lehetőség - + Split geometry Geometria felosztása - + Redraw geometry Geometria újrarajzolása - + Streaming mode Streaming mód - + Active Aktív - + Splitting done successfully A felosztás sikeresen megtörtént - + Select some point to start editing the geometry Válasszon ki egy pontot a geometria szerkesztésének megkezdéséhez - + Record new geometry for the feature Új geometria létrehozása az elemhez - + GPS currently unavailable. A GPS jelenleg nem elérhető. @@ -1387,6 +1392,62 @@ Nem lesz hozzáadva a projekthez. Tudjon meg többet %1hogyan lehet beállítani egy térkép témát%2. + + MMMeasureCrosshair + + + Close shape + Alakzat zárása + + + + MMMeasureDrawer + + + Measure + Mérés + + + + Repeat + Ismét + + + + Undo + Mégsem + + + + Perimeter + Kerület + + + + Length + Hosszúság + + + + Area + Terület + + + + Close shape + Alakzat zárása + + + + Add point + Pont hozzáadása + + + + Done + Kész + + MMMessage @@ -2274,17 +2335,17 @@ Nem lesz hozzáadva a projekthez. Áthelyezés - + Feature Elem - + Distance Távolság - + N/A N/A @@ -2821,113 +2882,118 @@ legfeljebb %1 letöltött projektet engedélyez. main - + Sync Szinkronizálás - + Add Hozzáadás - + No editable layers found. Nem található szerkeszthető réteg. - + Layers Rétegek - + Projects Projektek - + Zoom to project Nagyítás a projektre - + Map themes Térkép témák - + Position tracking Pozíció követése - + + Measure + Mérés + + + Local changes Helyi változások - + Settings Beállítások - - + + not tracking nincs követés - + Select feature Elem kiválasztása - + Somebody else is syncing, we will try again later Valaki más is szinkronizál, később újra megpróbáljuk - + Details Részletek - + Failed to communicate with server. Try improving your network connection. Nem sikerült kommunikálni a szerverrel. Próbálja meg javítani a hálózati kapcsolatot. - + Up to date Naprakész - + There were issues loading the project. %1View details%2 Probléma történt a projekt betöltése során. %1Nézze meg a részleteket%2 - + Stake out is disabled because location is unavailable! Az áthelyezés le van tiltva, mert a helymeghatározás nem elérhető! - + Successfully synchronised Sikeresen szinkronizálva - + There was an issue during synchronisation, we will try again. Click to learn more Hiba történt a szinkronizálás során, újra megpróbáljuk. Kattintson a további információért - + Could not read the project file: Nem sikerült beolvasni a projektfájlt: - + Press back again to quit the app Nyomja meg újra a vissza gombot az alkalmazásból való kilépéshez diff --git a/app/i18n/input_i18n.qrc b/app/i18n/input_i18n.qrc index 022f7565f..e5a5d2be8 100644 --- a/app/i18n/input_i18n.qrc +++ b/app/i18n/input_i18n.qrc @@ -1,39 +1,39 @@ - input_hr.qm input_vi_VN.qm - input_fi.qm - input_hr_BA.qm - input_pl.qm - input_es_419.qm - input_et.qm - input_sl.qm - input_ar_EG.qm - input_zh_CN.qm - input_az.qm - input_fr_FR.qm + input_zh-Hans.qm input_sl_SI.qm - input_pt_BR.qm - input_pt_PT.qm - input_es_ES.qm - input_hr_HR.qm - input_ar_IQ.qm - input_de.qm - input_et_EE.qm input_ca.qm - input_zh-Hans.qm - input_ja_JP.qm - input_fi_FI.qm + input_az_AZ.qm + input_hr.qm + input_hu.qm + input_es_ES.qm + input_ar_EG.qm + input_sl.qm input_ar.qm - input_sk.qm input_it.qm - input_es.qm + input_fr_FR.qm + input_zh_CN.qm + input_fi_FI.qm + input_de.qm + input_et_EE.qm input_en.qm - input_id_ID.qm - input_zh.qm + input_es_419.qm + input_ar_IQ.qm input_fr.qm - input_az_AZ.qm - input_hu.qm + input_az.qm + input_et.qm + input_pt_PT.qm + input_pl.qm + input_pt_BR.qm + input_es.qm + input_sk.qm input_sk_SK.qm + input_hr_BA.qm + input_hr_HR.qm + input_ja_JP.qm + input_zh.qm + input_fi.qm + input_id_ID.qm diff --git a/app/i18n/input_it.qm b/app/i18n/input_it.qm index cb0ccb33d..867104e83 100644 Binary files a/app/i18n/input_it.qm and b/app/i18n/input_it.qm differ diff --git a/app/i18n/input_it.ts b/app/i18n/input_it.ts index f92ae1fe6..857701293 100644 --- a/app/i18n/input_it.ts +++ b/app/i18n/input_it.ts @@ -154,7 +154,7 @@ FeaturesModel - + Unknown title Titolo sconosciuto @@ -200,119 +200,119 @@ Non verrà aggiunto al progetto. InputUtils - + just now Proprio ora - + %1 minutes ago %1 minuti fa - + %1 minute ago %1 minuto fa - + %1 hours ago %1 ore fa - + %1 hour ago %1 ora fa - - + + %1 days ago %1 giorni fa - - + + %1 day ago %1 giorno fa - + %1 weeks ago %1 settimane fa - + %1 week ago %1 settimana fa - + %1 months ago %1 mesi fa - + %1 month ago %1 mese fa - + %1 years ago %1 anni fa - + %1 year ago %1 anno fa - + screen resolution: %1x%2 px risoluzione dello schermo: %1x%2 px - + screen DPI: %1x%2 DPI dello schermo: %1x%2 - + screen size: %1x%2 mm dimensioni dello schermo: %1x%2 mm - + reported device pixel ratio: %1 pixel ratio del dispositivo riportato: %1 - + calculated device pixel ratio: %1 pixel ratio del dispositivo calcolato: %1 - + used dp scale: %1 usa scala dp: %1 - + You need to add at least %1 point(s) to every part. È necessario aggiungere almeno %1 punti per ciascuna parte. - + You need to add at least %1 point(s). È necessario aggiungere almeno %1 punti. @@ -737,7 +737,7 @@ Non verrà aggiunto al progetto. MMFeaturesListPage - + Add feature Aggiungi elemento @@ -1274,97 +1274,102 @@ Non verrà aggiunto al progetto. MMMapController - + Mark the geometry on the map and click record Contrassegna la geometria sulla mappa e premi su registra - + Create line to split the selected feature Disegna una linea per tagliare la geometria selezionata - + + Add points to measure distance, close the shape to measure area + Aggiungi dei punti per misurare la distanza, chiudi il poligono per misurare l'area + + + streaming streaming - + Connecting to %1 Connessione a %1 - + Connected, no position Connesso, nessuna posizione - + Unknown accuracy Accuratezza sconosciuta - + GPS currently unavailable GPS attualmente non disponibile. - + Choose Active Layer Scegli un layer attivo - + Could not find any editable layers in the project. Impossibile trovare il layer modificabile nel progetto - + See how to enable digitizing in your project. Vedi come abilitare la modifica nel tuo progetto - + More options Più opzioni - + Split geometry Dividi geometria - + Redraw geometry Ridisegna geometria - + Streaming mode Modalità streaming - + Active Attivo - + Splitting done successfully Divisione eseguita con successo - + Select some point to start editing the geometry Seleziona un punto per iniziare a modificare la geometria - + Record new geometry for the feature Registra la nuova geometria per l'elemento. - + GPS currently unavailable. GPS attualmente non disponibile. @@ -1387,6 +1392,62 @@ Non verrà aggiunto al progetto. Scopri come %1impostare i temi mappa%2. + + MMMeasureCrosshair + + + Close shape + Chiudi il poligono + + + + MMMeasureDrawer + + + Measure + Misura + + + + Repeat + Ricomincia + + + + Undo + Annulla + + + + Perimeter + Perimetro + + + + Length + Lunghezza + + + + Area + Area + + + + Close shape + Chiudi il poligono + + + + Add point + Aggiungi punto + + + + Done + Fatto + + MMMessage @@ -2274,17 +2335,17 @@ Non verrà aggiunto al progetto. Picchettamento (stake out) - + Feature Elemento - + Distance Distanza - + N/A N/A @@ -2821,113 +2882,118 @@ consente solo fino a %1 progetti scaricati. main - + Sync Sincronizza - + Add Aggiungi - + No editable layers found. Non è stato trovato nessun layer modificabile. - + Layers Layer - + Projects Progetti - + Zoom to project Ingrandisci il progetto - + Map themes Temi mappa - + Position tracking Tracciamento posizione - + + Measure + Misura + + + Local changes Modifiche locali - + Settings Impostazioni - - + + not tracking non in tracciamento - + Select feature Seleziona elemento - + Somebody else is syncing, we will try again later Un altro utente sta sincronizzando, riproveremo più tardi - + Details Dettagli - + Failed to communicate with server. Try improving your network connection. Impossibile comunicare con Mergin. Prova a migliorare la qualità della tua connessione - + Up to date Aggiornato - + There were issues loading the project. %1View details%2 Problemi durante il caricamento del progetto. %1Vedi i dettagli%2 - + Stake out is disabled because location is unavailable! Picchettamento disabilitato perché la posizione non è disponibile! - + Successfully synchronised Sincronizzato con successo - + There was an issue during synchronisation, we will try again. Click to learn more Errore durante la sincronizzazione, riproveremo più tardi. Clicca per avere maggiori informazioni - + Could not read the project file: Impossibile leggere il file del progetto: - + Press back again to quit the app Premi di nuovo indietro per uscire dall'app diff --git a/app/i18n/input_sl.qm b/app/i18n/input_sl.qm index 91f9f5a6a..e3995a85f 100644 Binary files a/app/i18n/input_sl.qm and b/app/i18n/input_sl.qm differ diff --git a/app/i18n/input_sl.ts b/app/i18n/input_sl.ts index 6a7813f45..dcdd8861b 100644 --- a/app/i18n/input_sl.ts +++ b/app/i18n/input_sl.ts @@ -154,7 +154,7 @@ FeaturesModel - + Unknown title Neznan naslov @@ -200,119 +200,119 @@ V projekt ne bo dodano. InputUtils - + just now zdaj - + %1 minutes ago pred %1 minutami - + %1 minute ago pred %1 minuto - + %1 hours ago pred %1 urami - + %1 hour ago pred %1 uro - - + + %1 days ago pred %1 dnevi - - + + %1 day ago pred %1 dnevom - + %1 weeks ago pred %1 tedni - + %1 week ago pred %1 tednom - + %1 months ago pred %1 meseci - + %1 month ago pred %1 mesecem - + %1 years ago pred %1 leti - + %1 year ago pred %1 letom - + screen resolution: %1x%2 px ločljivost zaslona: %1x%2 px - + screen DPI: %1x%2 DPI zaslona: %1x%2 - + screen size: %1x%2 mm velikost zaslona: %1x%2 mm - + reported device pixel ratio: %1 poročano razmerje slikovnih pik naprave: %1 - + calculated device pixel ratio: %1 izračunano razmerje slikovnih pik naprave: %1 - + used dp scale: %1 uporabljeno dp merilo: %1 - + You need to add at least %1 point(s) to every part. Vsaj %1 točk(a) je zahtevanih za vsak del. - + You need to add at least %1 point(s). Dodaj vsaj %1 točk(o). @@ -737,7 +737,7 @@ V projekt ne bo dodano. MMFeaturesListPage - + Add feature Dodaj element @@ -912,7 +912,7 @@ V projekt ne bo dodano. Source - vir + Vir @@ -1125,7 +1125,7 @@ V projekt ne bo dodano. Source - vir + Vir @@ -1274,97 +1274,102 @@ V projekt ne bo dodano. MMMapController - + Mark the geometry on the map and click record Označi geometrijo na karti in klikni na Zajemi - + Create line to split the selected feature Nariši linijo kjer boš razdelil izbran element - + + Add points to measure distance, close the shape to measure area + Dodaj točke za izračun razdalje, zaključi lik za izračun površine + + + streaming sledenje - + Connecting to %1 povezovanje z %1 - + Connected, no position povezano, brez lokacije - + Unknown accuracy neznana natančnost - + GPS currently unavailable GPS trenutno nedostopen. - + Choose Active Layer Izberi sloj za urejanje - + Could not find any editable layers in the project. Ne najdem sloja za urejanje v projektu. - + See how to enable digitizing in your project. Oglej si, kako omogočiti urejanje v vašem projektu. - + More options Več možnosti - + Split geometry Razdeli geometrijo - + Redraw geometry Osveži geometrijo - + Streaming mode Način sledenja - + Active Aktiven - + Splitting done successfully Delitev uspela - + Select some point to start editing the geometry Izberi nekaj točk za začetek urejanja geometrije - + Record new geometry for the feature Zajemi novo geometrijo za element - + GPS currently unavailable. GPS trenutno nedostopen. @@ -1387,6 +1392,62 @@ V projekt ne bo dodano. Preberi si %1kako nastaviti teme v projektu%2. + + MMMeasureCrosshair + + + Close shape + Zaključi lik + + + + MMMeasureDrawer + + + Measure + Meri + + + + Repeat + Ponovi + + + + Undo + Razveljavi + + + + Perimeter + Obseg + + + + Length + Dolžina + + + + Area + Površina + + + + Close shape + Zaključi lik + + + + Add point + Dodaj točko + + + + Done + Končaj + + MMMessage @@ -2274,17 +2335,17 @@ V projekt ne bo dodano. Zakoličba - + Feature Element - + Distance razdalja - + N/A N/A @@ -2821,113 +2882,118 @@ omogoča do %1 prenešenih projektov. main - + Sync Sinhr. - + Add Dodaj - + No editable layers found. Ni slojev za urejanje. - + Layers Sloji - + Projects Projekti - + Zoom to project Prikaži vse - + Map themes Teme - + Position tracking Sledenje lokacije - + + Measure + Meri + + + Local changes Lokalne spremembe - + Settings Nastavitve - - + + not tracking sledenje se ne izvaja - + Select feature Izberi element - + Somebody else is syncing, we will try again later Sinhronizacija je ravno v teku, bomo poskusili kasneje - + Details podrobnosti - + Failed to communicate with server. Try improving your network connection. Napaka pri povezavi z Merginom. Poskusi izboljšati omrežno povezavo. - + Up to date Posodobljeno - + There were issues loading the project. %1View details%2 Napake pri odpiranju projekta. %1Podrobnosti%2 - + Stake out is disabled because location is unavailable! Zakoličba ni mogoča, ker lokacija ni na voljo! - + Successfully synchronised Uspešno sinhronizirano - + There was an issue during synchronisation, we will try again. Click to learn more Pri sinhronizaciji je prišlo do napake, bomo še poskušali kasneje. Več informacij - + Could not read the project file: Ne morem prebrati projekta: - + Press back again to quit the app Ponovni pritisni nazaj za izhod iz aplikacije diff --git a/app/i18n/input_sl_SI.qm b/app/i18n/input_sl_SI.qm index b375e978f..016e8f22e 100644 Binary files a/app/i18n/input_sl_SI.qm and b/app/i18n/input_sl_SI.qm differ diff --git a/app/i18n/input_sl_SI.ts b/app/i18n/input_sl_SI.ts index 835b58300..fa40361b5 100644 --- a/app/i18n/input_sl_SI.ts +++ b/app/i18n/input_sl_SI.ts @@ -154,7 +154,7 @@ FeaturesModel - + Unknown title Neznan naslov @@ -200,119 +200,119 @@ V projekt ne bo dodano. InputUtils - + just now zdaj - + %1 minutes ago pred %1 minutami - + %1 minute ago pred %1 minuto - + %1 hours ago pred %1 urami - + %1 hour ago pred %1 uro - - + + %1 days ago pred %1 dnevi - - + + %1 day ago pred %1 dnevom - + %1 weeks ago pred %1 tedni - + %1 week ago pred %1 tednom - + %1 months ago pred %1 meseci - + %1 month ago pred %1 mesecem - + %1 years ago pred %1 leti - + %1 year ago pred %1 letom - + screen resolution: %1x%2 px ločljivost zaslona: %1x%2 px - + screen DPI: %1x%2 DPI zaslona: %1x%2 - + screen size: %1x%2 mm velikost zaslona: %1x%2 mm - + reported device pixel ratio: %1 poročano razmerje slikovnih pik naprave: %1 - + calculated device pixel ratio: %1 izračunano razmerje slikovnih pik naprave: %1 - + used dp scale: %1 uporabljeno dp merilo: %1 - + You need to add at least %1 point(s) to every part. Vsaj %1 točka je zahtevana za vsak del. - + You need to add at least %1 point(s). Dodaj vsa %1 točk() @@ -737,7 +737,7 @@ V projekt ne bo dodano. MMFeaturesListPage - + Add feature Dodaj element @@ -1274,97 +1274,102 @@ V projekt ne bo dodano. MMMapController - + Mark the geometry on the map and click record Označi geometrijo na karti in klikni na Snemanje - + Create line to split the selected feature Nariši linijo kjer boš razdelil izbran element - + + Add points to measure distance, close the shape to measure area + Dodaj točke za izračun razdalje, zaključi lik za izračun površine + + + streaming pretakanje - + Connecting to %1 povezovanje z %1 - + Connected, no position povezano, brez lokacije - + Unknown accuracy neznana natančnost - + GPS currently unavailable GPS trenutno nedostopen. - + Choose Active Layer Izberi sloj za urejanje - + Could not find any editable layers in the project. Ne najdem sloja za urejanje v projektu. - + See how to enable digitizing in your project. Oglej si, kako omogočiti urejanje v vašem projektu. - + More options Več možnosti - + Split geometry Razdeli geometrijo - + Redraw geometry Osveži geometrijo - + Streaming mode pretočni način - + Active Aktiven - + Splitting done successfully Delitev uspela - + Select some point to start editing the geometry Izberi nekaj točk za začetek urejanja geometrije - + Record new geometry for the feature Posnemi novo geometrijo za element - + GPS currently unavailable. GPS trenutno nedostopen. @@ -1387,6 +1392,62 @@ V projekt ne bo dodano. Podrobnosti o tem %1kako nastaviti teme v projektu%2. + + MMMeasureCrosshair + + + Close shape + Zaključi lik + + + + MMMeasureDrawer + + + Measure + Meri + + + + Repeat + Ponovi + + + + Undo + Razveljavi + + + + Perimeter + Obseg + + + + Length + Dolžina + + + + Area + Površina + + + + Close shape + Zaključi lik + + + + Add point + Dodaj točko + + + + Done + Končaj + + MMMessage @@ -2274,17 +2335,17 @@ V projekt ne bo dodano. Zakoličba - + Feature Element - + Distance razdalja - + N/A N/A @@ -2821,113 +2882,118 @@ omogoča do %1 prenešenih projektov. main - + Sync Sinhr. - + Add Dodaj - + No editable layers found. Ni slojev za urejanje. - + Layers Sloji - + Projects Projekti - + Zoom to project Prikaži vse - + Map themes Teme - + Position tracking Sledenje lokacije - + + Measure + Meri + + + Local changes Lokalne spremembe - + Settings Nastavitve - - + + not tracking sledenje se ne izvaja - + Select feature Izberi element - + Somebody else is syncing, we will try again later Sinhronizacija je ravno v teku, bomo poskusili kasneje - + Details podrobnosti - + Failed to communicate with server. Try improving your network connection. Napaka pri povezavi z Merginom. Poskusi izboljšati omrežno povezavo. - + Up to date Posodobljeno - + There were issues loading the project. %1View details%2 Napake pri odpiranju projekta. %1Podrobnosti%2 - + Stake out is disabled because location is unavailable! Zakoličba ni mogoča, ker lokacija ni na voljo! - + Successfully synchronised Uspešno sinhronizirano - + There was an issue during synchronisation, we will try again. Click to learn more Pri sinhronizaciji je prišlo do napake, bomo še poskušali kasneje. Več informacij - + Could not read the project file: Ne morem prebrati projekta: - + Press back again to quit the app Ponovni pritisni nazaj za izhodi iz aplikacije diff --git a/app/icons/CloseShape.svg b/app/icons/CloseShape.svg new file mode 100644 index 000000000..594a3a78e --- /dev/null +++ b/app/icons/CloseShape.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/icons/Measure.svg b/app/icons/Measure.svg new file mode 100644 index 000000000..0666bf957 --- /dev/null +++ b/app/icons/Measure.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/icons/icons.qrc b/app/icons/icons.qrc index c3f553a97..3f88e0ec6 100644 --- a/app/icons/icons.qrc +++ b/app/icons/icons.qrc @@ -97,5 +97,7 @@ ZoomToProject.svg StakeOut.svg Student.svg + Measure.svg + CloseShape.svg diff --git a/app/images/NeutralMMSymbol.svg b/app/images/NeutralMMSymbol.svg new file mode 100644 index 000000000..e31c406a2 --- /dev/null +++ b/app/images/NeutralMMSymbol.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/images/images.qrc b/app/images/images.qrc index ac0474d90..b0b772a30 100644 --- a/app/images/images.qrc +++ b/app/images/images.qrc @@ -23,6 +23,7 @@ ExternalGpsGreen.svg NegativeMMSymbol.svg PositiveMMSymbol.svg + NeutralMMSymbol.svg CloseAccount.svg Attention.svg Bubble.svg diff --git a/app/inpututils.cpp b/app/inpututils.cpp index 5b40e14c0..218c024e1 100644 --- a/app/inpututils.cpp +++ b/app/inpututils.cpp @@ -168,25 +168,48 @@ QString InputUtils::formatNumber( const double number, int precision ) return QString::number( number, 'f', precision ); } -QString InputUtils::formatDistanceInProjectUnit( const double distanceInMeters, int precision, Qgis::DistanceUnit destUnit ) +QString InputUtils::formatDistanceInProjectUnit( const double distanceInMeters, int precision, QgsProject *project ) { - Qgis::DistanceUnit distUnit = destUnit; + if ( !project ) + return QString(); + + return InputUtils::formatDistanceHelper( distanceInMeters, precision, project->distanceUnits() ); +} - if ( distUnit == Qgis::DistanceUnit::Unknown ) +QString InputUtils::formatDistanceHelper( const double distanceInMeters, int precision, Qgis::DistanceUnit destUnit ) +{ + if ( destUnit == Qgis::DistanceUnit::Unknown ) { - distUnit = QgsProject::instance()->distanceUnits(); + destUnit = Qgis::DistanceUnit::Meters; } - if ( distUnit == Qgis::DistanceUnit::Unknown ) + const double factor = QgsUnitTypes::fromUnitToUnitFactor( Qgis::DistanceUnit::Meters, destUnit ); + const double distance = distanceInMeters * factor; + const QString abbreviation = QgsUnitTypes::toAbbreviatedString( destUnit ); + + return QString( "%L1 %2" ).arg( QString::number( distance, 'f', precision ), abbreviation ); +} + +QString InputUtils::formatAreaInProjectUnit( const double areaInSquareMeters, int precision, QgsProject *project ) +{ + if ( !project ) + return QString(); + + return InputUtils::formatAreaHelper( areaInSquareMeters, precision, project->areaUnits() ); +} + +QString InputUtils::formatAreaHelper( const double areaInSquareMeters, int precision, Qgis::AreaUnit destUnit ) +{ + if ( destUnit == Qgis::AreaUnit::Unknown ) { - return QString::number( distanceInMeters, 'f', precision ); + destUnit = Qgis::AreaUnit::SquareMeters; } - double factor = QgsUnitTypes::fromUnitToUnitFactor( Qgis::DistanceUnit::Meters, distUnit ); - double distance = distanceInMeters * factor; - QString abbreviation = QgsUnitTypes::toAbbreviatedString( distUnit ); + const double factor = QgsUnitTypes::fromUnitToUnitFactor( Qgis::AreaUnit::SquareMeters, destUnit ); + const double area = areaInSquareMeters * factor; + const QString abbreviation = QgsUnitTypes::toAbbreviatedString( destUnit ); - return QString( "%1 %2" ).arg( QString::number( distance, 'f', precision ), abbreviation ); + return QString( "%L1 %2" ).arg( QString::number( area, 'f', precision ), abbreviation ); } QString InputUtils::formatDateTimeDiff( const QDateTime &tMin, const QDateTime &tMax ) @@ -2194,3 +2217,8 @@ bool InputUtils::openLink( const QString &homePath, const QString &link ) return true; } + +double InputUtils::pixelDistanceBetween( const QPointF &p1, const QPointF &p2 ) +{ + return std::hypot( p1.x() - p2.x(), p1.y() - p2.y() ); +} diff --git a/app/inpututils.h b/app/inpututils.h index 2ba463900..83be81f39 100644 --- a/app/inpututils.h +++ b/app/inpututils.h @@ -75,7 +75,12 @@ class InputUtils: public QObject Q_INVOKABLE QString getFileName( const QString &filePath ); Q_INVOKABLE QString formatProjectName( const QString &fullProjectName ); Q_INVOKABLE QString formatNumber( const double number, int precision = 1 ); - Q_INVOKABLE QString formatDistanceInProjectUnit( const double distanceInMeters, int precision = 1, Qgis::DistanceUnit destUnit = Qgis::DistanceUnit::Unknown ); + Q_INVOKABLE QString formatDistanceInProjectUnit( const double distanceInMeters, int precision, QgsProject *project ); + Q_INVOKABLE QString formatAreaInProjectUnit( const double areaInSquareMeters, int precision, QgsProject *project ); + + static QString formatDistanceHelper( const double distanceInMeters, int precision, Qgis::DistanceUnit destUnit ); + static QString formatAreaHelper( const double areaInSquareMeters, int precision, Qgis::AreaUnit destUnit ); + Q_INVOKABLE void setExtentToFeature( const FeatureLayerPair &pair, InputMapSettings *mapSettings ); /** @@ -579,6 +584,11 @@ class InputUtils: public QObject */ static QVector qgisProfilerLog(); + /** + * Calculates the Euclidean distance between two pixel points + */ + static double pixelDistanceBetween( const QPointF &p1, const QPointF &p2 ); + public slots: void onQgsLogMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level ); diff --git a/app/main.cpp b/app/main.cpp index d0c35cd24..2ff044e83 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -114,6 +114,7 @@ #include "maptools/abstractmaptool.h" #include "maptools/recordingmaptool.h" #include "maptools/splittingmaptool.h" +#include "maptools/measurementmaptool.h" #include "layer/layertreemodel.h" #include "layer/layertreemodelpixmapprovider.h" @@ -348,6 +349,7 @@ void initDeclarative() qmlRegisterUncreatableType< AbstractMapTool >( "mm", 1, 0, "AbstractMapTool", "Instantiate one of child map tools instead" ); qmlRegisterType< RecordingMapTool >( "mm", 1, 0, "RecordingMapTool" ); qmlRegisterType< SplittingMapTool >( "mm", 1, 0, "SplittingMapTool" ); + qmlRegisterType< MeasurementMapTool >( "mm", 1, 0, "MeasurementMapTool" ); } void addQmlImportPath( QQmlEngine &engine ) diff --git a/app/maptools/abstractmaptool.cpp b/app/maptools/abstractmaptool.cpp index dd8b25636..ee81f1dc0 100644 --- a/app/maptools/abstractmaptool.cpp +++ b/app/maptools/abstractmaptool.cpp @@ -26,6 +26,10 @@ void AbstractMapTool::setMapSettings( InputMapSettings *newMapSettings ) { if ( mMapSettings == newMapSettings ) return; + + emit onAboutToChangeMapSettings(); + mMapSettings = newMapSettings; + emit mapSettingsChanged( mMapSettings ); } diff --git a/app/maptools/abstractmaptool.h b/app/maptools/abstractmaptool.h index ec6a9ca99..e6eba3532 100644 --- a/app/maptools/abstractmaptool.h +++ b/app/maptools/abstractmaptool.h @@ -30,11 +30,10 @@ class AbstractMapTool : public QObject void setMapSettings( InputMapSettings *newMapSettings ); signals: - + void onAboutToChangeMapSettings(); void mapSettingsChanged( InputMapSettings *mapSettings ); private: - InputMapSettings *mMapSettings = nullptr; }; diff --git a/app/maptools/measurementmaptool.cpp b/app/maptools/measurementmaptool.cpp new file mode 100644 index 000000000..dcaad908b --- /dev/null +++ b/app/maptools/measurementmaptool.cpp @@ -0,0 +1,319 @@ +/*************************************************************************** + * * + * 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 "measurementmaptool.h" + +MeasurementMapTool::MeasurementMapTool( QObject *parent ) + : AbstractMapTool{ parent } +{ + connect( this, &AbstractMapTool::onAboutToChangeMapSettings, this, &MeasurementMapTool::resetMapSettings ); + connect( this, &AbstractMapTool::mapSettingsChanged, this, &MeasurementMapTool::updateMapSettings ); +} + +MeasurementMapTool::~MeasurementMapTool() = default; + +void MeasurementMapTool::addPoint() +{ + if ( mapSettings() ) + { + QgsPoint transformedPoint = mapSettings()->screenToCoordinate( mCrosshairPoint ); + + if ( !mPoints.empty() && transformedPoint == mPoints.back() ) + return; + + mPoints.push_back( transformedPoint ); + rebuildGeometry(); + } +} + +void MeasurementMapTool::removePoint() +{ + if ( !mPoints.isEmpty() && mapSettings() ) + { + mPoints.pop_back(); + checkCanCloseShape(); + rebuildGeometry(); + updateDistance(); + } +} + +void MeasurementMapTool::updateDistance() +{ + if ( mPoints.isEmpty() || !mapSettings() ) + { + setLengthWithGuideline( 0.0 ); + return; + } + + checkCanCloseShape(); + + QgsPoint lastPoint = mPoints.last(); + QgsPoint transformedCrosshairPoint = mapSettings()->screenToCoordinate( mCrosshairPoint ); + + double calculatedLength = mPerimeter + mDistanceArea.measureLine( transformedCrosshairPoint, lastPoint ); + setLengthWithGuideline( calculatedLength ); +} + +void MeasurementMapTool::checkCanCloseShape() +{ + if ( !mRecordedGeometry.isEmpty() && mapSettings() && mPoints.count() < 3 ) + { + setCanCloseShape( false ); + return; + } + + QgsPoint firstPoint = mPoints.first(); + QPointF firstPointScreen = mapSettings()->coordinateToScreen( firstPoint ); + double distanceToFirstPoint = InputUtils::pixelDistanceBetween( mCrosshairPoint, firstPointScreen ); + setCanCloseShape( distanceToFirstPoint <= CLOSE_THRESHOLD ); +} + +void MeasurementMapTool::finalizeMeasurement( bool closeShapeClicked ) +{ + if ( mPoints.count() < 2 || !mapSettings() ) + return; + + QList pointList; + for ( const QgsPoint &point : mPoints ) + pointList.append( QgsPointXY( point.x(), point.y() ) ); + + QgsGeometry geometry; + double perimeter = 0.0; + + if ( closeShapeClicked && mCanCloseShape ) + { + geometry = QgsGeometry::fromPolygonXY( QList>() << pointList ); + perimeter = mDistanceArea.measurePerimeter( geometry ); + setArea( mDistanceArea.measureArea( geometry ) ); + setCanCloseShape( false ); + } + else + { + geometry = QgsGeometry::fromPolylineXY( pointList ); + perimeter = mDistanceArea.measureLength( geometry ); + } + + setRecordedGeometry( geometry ); + setPerimeter( perimeter ); + setMeasurementFinalized( true ); +} + +void MeasurementMapTool::resetMeasurement() +{ + mPoints.clear(); + + setPerimeter( 0.0 ); + setArea( 0.0 ); + setLengthWithGuideline( 0.0 ); + setCanCloseShape( false ); + setMeasurementFinalized( false ); + + rebuildGeometry(); +} + +void MeasurementMapTool::rebuildGeometry() +{ + if ( !mapSettings() ) + return; + + QgsGeometry geometry; + + QgsMultiPoint *existingVertices = new QgsMultiPoint(); + mExistingVertices.set( existingVertices ); + + if ( mPoints.count() > 0 ) + { + geometry = QgsGeometry::fromPolyline( mPoints ); + + for ( const QgsPoint &point : mPoints ) + { + existingVertices->addGeometry( point.clone() ); + } + + double perimeter = mDistanceArea.measureLength( geometry ); + setPerimeter( perimeter ); + setCanUndo( true ); + } + else + { + setCanUndo( false ); + } + + // If we have more two or more points, "Done" button will be enabled + bool hasValidGeometry = !mRecordedGeometry.isEmpty() && mPoints.count() >= 2; + setIsValidGeometry( hasValidGeometry ); + + emit existingVerticesChanged( mExistingVertices ); + setRecordedGeometry( geometry ); +} + +void MeasurementMapTool::resetMapSettings() +{ + InputMapSettings *currentMapSettings = mapSettings(); + + if ( currentMapSettings ) + { + disconnect( currentMapSettings ); + } +} + +void MeasurementMapTool::updateMapSettings( InputMapSettings *newMapSettings ) +{ + AbstractMapTool::setMapSettings( newMapSettings ); + + InputMapSettings *updatedMapSettings = mapSettings(); + + if ( updatedMapSettings ) + { + connect( updatedMapSettings, &InputMapSettings::extentChanged, this, &MeasurementMapTool::updateDistance ); + + mDistanceArea.setEllipsoid( updatedMapSettings->project()->ellipsoid() ); + mDistanceArea.setSourceCrs( updatedMapSettings->destinationCrs(), updatedMapSettings->transformContext() ); + } +} + +const QgsGeometry &MeasurementMapTool::recordedGeometry() const +{ + return mRecordedGeometry; +} + +QgsGeometry MeasurementMapTool::existingVertices() const +{ + return mExistingVertices; +} + +void MeasurementMapTool::setExistingVertices( const QgsGeometry &vertices ) +{ + if ( mExistingVertices.equals( vertices ) ) + return; + + mExistingVertices = vertices; + emit existingVerticesChanged( mExistingVertices ); +} + +double MeasurementMapTool::area() const +{ + return mArea; +} + +double MeasurementMapTool::perimeter() const +{ + return mPerimeter; +} + +QPointF MeasurementMapTool::crosshairPoint() const +{ + return mCrosshairPoint; +} + +double MeasurementMapTool::lengthWithGuideline() const +{ + return mLengthWithGuideline; +} + +bool MeasurementMapTool::canUndo() const +{ + return mCanUndo; +} + +void MeasurementMapTool::setCanUndo( bool newCanUndo ) +{ + if ( mCanUndo == newCanUndo ) + return; + + mCanUndo = newCanUndo; + emit canUndoChanged( mCanUndo ); +} + +bool MeasurementMapTool::canCloseShape() const +{ + return mCanCloseShape; +} + +void MeasurementMapTool::setCanCloseShape( bool newCanCloseShape ) +{ + if ( mCanCloseShape == newCanCloseShape ) + return; + + mCanCloseShape = newCanCloseShape; + emit canCloseShapeChanged( mCanCloseShape ); +} + +bool MeasurementMapTool::isValidGeometry() const +{ + return mIsValidGeometry; +} + +void MeasurementMapTool::setIsValidGeometry( bool hasValidGeometry ) +{ + if ( mIsValidGeometry != hasValidGeometry ) + { + mIsValidGeometry = hasValidGeometry; + emit isValidGeometryChanged( hasValidGeometry ); + } +} + +bool MeasurementMapTool::measurementFinalized() const +{ + return mMeasurementFinalized; +} + +void MeasurementMapTool::setMeasurementFinalized( bool newMeasurementFinalized ) +{ + if ( mMeasurementFinalized == newMeasurementFinalized ) + return; + + mMeasurementFinalized = newMeasurementFinalized; + emit measurementFinalizedChanged( mMeasurementFinalized ); +} + +void MeasurementMapTool::setRecordedGeometry( const QgsGeometry &newRecordedGeometry ) +{ + if ( mRecordedGeometry.equals( newRecordedGeometry ) ) + return; + + mRecordedGeometry = newRecordedGeometry; + emit recordedGeometryChanged( mRecordedGeometry ); +} + +void MeasurementMapTool::setLengthWithGuideline( const double &lengthWithGuideline ) +{ + if ( mLengthWithGuideline == lengthWithGuideline ) + return; + + mLengthWithGuideline = lengthWithGuideline; + emit lengthWithGuidelineChanged( lengthWithGuideline ); +} + +void MeasurementMapTool::setArea( const double &area ) +{ + if ( mArea == area ) + return; + + mArea = area; + emit areaChanged( area ); +} + +void MeasurementMapTool::setPerimeter( const double &perimeter ) +{ + if ( mPerimeter == perimeter ) + return; + + mPerimeter = perimeter; + emit perimeterChanged( perimeter ); +} + +void MeasurementMapTool::setCrosshairPoint( const QPointF &point ) +{ + if ( mCrosshairPoint == point ) + return; + + mCrosshairPoint = point; + emit crosshairPointChanged( mCrosshairPoint ); +} diff --git a/app/maptools/measurementmaptool.h b/app/maptools/measurementmaptool.h new file mode 100644 index 000000000..1d041b203 --- /dev/null +++ b/app/maptools/measurementmaptool.h @@ -0,0 +1,139 @@ +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef MEASUREMENTMAPTOOL_H +#define MEASUREMENTMAPTOOL_H + +#include "abstractmaptool.h" +#include +#include "qgsdistancearea.h" +#include "qgsgeometry.h" +#include "inpututils.h" +#include "qgspolygon.h" +#include "qgsgeometry.h" +#include "qgsvectorlayer.h" +#include "qgsmultipoint.h" + +const double CLOSE_THRESHOLD = 10.0; // in pixels + +class MeasurementMapTool : public AbstractMapTool +{ + Q_OBJECT + + Q_PROPERTY( QgsGeometry recordedGeometry READ recordedGeometry WRITE setRecordedGeometry NOTIFY recordedGeometryChanged ) + Q_PROPERTY( QgsGeometry existingVertices READ existingVertices WRITE setExistingVertices NOTIFY existingVerticesChanged ) + Q_PROPERTY( QPointF crosshairPoint READ crosshairPoint WRITE setCrosshairPoint NOTIFY crosshairPointChanged ) + + Q_PROPERTY( double lengthWithGuideline READ lengthWithGuideline WRITE setLengthWithGuideline NOTIFY lengthWithGuidelineChanged ) + Q_PROPERTY( double perimeter READ perimeter WRITE setPerimeter NOTIFY perimeterChanged ) + Q_PROPERTY( double area READ area WRITE setArea NOTIFY areaChanged ) + + Q_PROPERTY( bool canUndo READ canUndo WRITE setCanUndo NOTIFY canUndoChanged ) + Q_PROPERTY( bool canCloseShape READ canCloseShape WRITE setCanCloseShape NOTIFY canCloseShapeChanged ) + Q_PROPERTY( bool isValidGeometry READ isValidGeometry WRITE setIsValidGeometry NOTIFY isValidGeometryChanged ) + Q_PROPERTY( bool measurementFinalized READ measurementFinalized WRITE setMeasurementFinalized NOTIFY measurementFinalizedChanged ) + + public: + explicit MeasurementMapTool( QObject *parent = nullptr ); + virtual ~MeasurementMapTool() override; + + /** + * Adds point to the end of the recorded geometry; updates recordedGeometry afterwards + * Passed point needs to be in map CRS + */ + Q_INVOKABLE void addPoint(); + + /** + * Removes last point from recorded geometry if there is at least one point + * Updates recordedGeometry afterwards + */ + Q_INVOKABLE void removePoint(); + + /** + * Finalizes measurement by forming a polygon if "Close shape" button was clicked + * and there are at least 3 points; otherwise, if "Done" button was clicked, forms a polyline. + * Updates recorded geometry, calculates perimeter, and calculates the area if it's a polygon. + */ + Q_INVOKABLE void finalizeMeasurement( bool closeShapeClicked ); + + /** + * Repeats measurement process. + * Clears all recorded points and rebuilds the geometry. + */ + Q_INVOKABLE void resetMeasurement(); + + // Getter and Setters + double lengthWithGuideline() const; + void setLengthWithGuideline( const double &length ); + + double perimeter() const; + void setPerimeter( const double &perimeter ); + + double area() const; + void setArea( const double &area ); + + QPointF crosshairPoint() const; + void setCrosshairPoint( const QPointF &point ); + + bool canUndo() const; + void setCanUndo( bool newCanUndo ); + + bool canCloseShape() const; + void setCanCloseShape( bool newCanCloseShape ); + + bool isValidGeometry() const; + void setIsValidGeometry( bool hasValidGeometry ); + + bool measurementFinalized() const; + void setMeasurementFinalized( bool newMeasurementFinalized ); + + const QgsGeometry &recordedGeometry() const; + void setRecordedGeometry( const QgsGeometry &newRecordedGeometry ); + + QgsGeometry existingVertices() const; + void setExistingVertices( const QgsGeometry &vertices ); + + void resetMapSettings(); + void updateMapSettings( InputMapSettings *newMapSettings ); + + signals: + void lengthWithGuidelineChanged( const double &lengthWithGuideline ); + void perimeterChanged( const double &perimeter ); + void areaChanged( const double &area ); + void canUndoChanged( bool canUndo ); + void canCloseShapeChanged( bool canUndo ); + void measurementFinalizedChanged( bool measurementFinalized ); + void recordedGeometryChanged( const QgsGeometry &recordedGeometry ); + void existingVerticesChanged( const QgsGeometry &vertices ); + void crosshairPointChanged( const QPointF &crosshairPoint ); + void isValidGeometryChanged( bool canFinalize ); + + protected: + void rebuildGeometry(); + void checkCanCloseShape(); + + public slots: + void updateDistance(); + + private: + QVector mPoints; + QgsGeometry mRecordedGeometry; + QgsGeometry mExistingVertices; + QgsDistanceArea mDistanceArea; + QPointF mCrosshairPoint; + double mLengthWithGuideline = 0; + double mPerimeter = 0; + double mArea = 0; + bool mCanUndo = false; + bool mCanCloseShape = false; + bool mIsValidGeometry = false; + bool mMeasurementFinalized = false; +}; + +#endif // MEASUREMENTMAPTOOL_H diff --git a/app/mmstyle.h b/app/mmstyle.h index 7d65b0e91..16587bb81 100644 --- a/app/mmstyle.h +++ b/app/mmstyle.h @@ -168,6 +168,8 @@ class MMStyle: public QObject Q_PROPERTY( QUrl streamingIcon READ streamingIcon CONSTANT ) Q_PROPERTY( QUrl redrawGeometryIcon READ redrawGeometryIcon CONSTANT ) Q_PROPERTY( QUrl cloudIcon READ cloudIcon CONSTANT ) + Q_PROPERTY( QUrl measurementToolIcon READ measurementToolIcon CONSTANT ) + Q_PROPERTY( QUrl closeShapeIcon READ closeShapeIcon CONSTANT ) // Filled Icons - for visualizing of selected item in toolbar Q_PROPERTY( QUrl projectsFilledIcon READ projectsFilledIcon CONSTANT ) @@ -215,6 +217,7 @@ class MMStyle: public QObject Q_PROPERTY( QUrl externalGpsRedImage READ externalGpsRedImage CONSTANT ) Q_PROPERTY( QUrl negativeMMSymbolImage READ negativeMMSymbolImage CONSTANT ) Q_PROPERTY( QUrl positiveMMSymbolImage READ positiveMMSymbolImage CONSTANT ) + Q_PROPERTY( QUrl neutralMMSymbolImage READ neutralMMSymbolImage CONSTANT ) Q_PROPERTY( QUrl closeAccountImage READ closeAccountImage CONSTANT ) Q_PROPERTY( QUrl attentionImage READ attentionImage CONSTANT ) Q_PROPERTY( QUrl blueInfoImage READ blueInfoImage CONSTANT ) @@ -276,7 +279,9 @@ class MMStyle: public QObject // Page Q_PROPERTY( double pageMargins READ number20 CONSTANT ) // distance between screen edge and components + Q_PROPERTY( double spacing2 READ number2 CONSTANT ) Q_PROPERTY( double spacing5 READ number5 CONSTANT ) + Q_PROPERTY( double spacing10 READ number10 CONSTANT ) Q_PROPERTY( double spacing12 READ number12 CONSTANT ) // distance between page header, page content and page footer Q_PROPERTY( double spacing20 READ number20 CONSTANT ) Q_PROPERTY( double spacing30 READ number30 CONSTANT ) @@ -422,6 +427,8 @@ class MMStyle: public QObject QUrl moreVerticalIcon() {return QUrl( "qrc:/MoreVertical.svg" );} QUrl morePhotosIcon() {return QUrl( "qrc:/MorePhotos.svg" );} QUrl mouthIcon() {return QUrl( "qrc:/Mouth.svg" );} + QUrl measurementToolIcon() {return QUrl( "qrc:/Measure.svg" );} + QUrl closeShapeIcon() {return QUrl( "qrc:/CloseShape.svg" );} QUrl naturalResourcesIcon() {return QUrl( "qrc:/NaturalResources.svg" );} QUrl nextIcon() {return QUrl( "qrc:/Next.svg" );} QUrl otherIcon() {return QUrl( "qrc:/Other.svg" );} @@ -498,6 +505,7 @@ class MMStyle: public QObject QUrl externalGpsRedImage() {return QUrl( "qrc:/images/ExternalGpsRed.svg" );} QUrl negativeMMSymbolImage() {return QUrl( "qrc:/images/NegativeMMSymbol.svg" );} QUrl positiveMMSymbolImage() {return QUrl( "qrc:/images/PositiveMMSymbol.svg" );} + QUrl neutralMMSymbolImage() {return QUrl( "qrc:/images/NeutralMMSymbol.svg" );} QUrl closeAccountImage() {return QUrl( "qrc:/images/CloseAccount.svg" );} QUrl attentionImage() {return QUrl( "qrc:/images/Attention.svg" );} QUrl blueInfoImage() {return QUrl( "qrc:/images/BlueInfo.svg" );} diff --git a/app/qml/CMakeLists.txt b/app/qml/CMakeLists.txt index bf848bd61..ccf99a8d5 100644 --- a/app/qml/CMakeLists.txt +++ b/app/qml/CMakeLists.txt @@ -116,6 +116,7 @@ set(MM_QML gps/MMGpsDataDrawer.qml gps/MMPositionProviderPage.qml gps/MMStakeoutDrawer.qml + gps/MMMeasureDrawer.qml gps/components/MMGpsDataText.qml inputs/MMComboboxInput.qml inputs/MMPasswordInput.qml @@ -135,8 +136,10 @@ set(MM_QML map/MMSplittingTools.qml map/MMStakeoutTools.qml map/MMRecordingTools.qml + map/MMMeasurementTools.qml map/components/MMHidingBox.qml map/components/MMCrosshair.qml + map/components/MMMeasureCrosshair.qml map/components/MMMapHidingLabel.qml map/components/MMMapButton.qml map/components/MMMapLabel.qml diff --git a/app/qml/components/MMButton.qml b/app/qml/components/MMButton.qml index 631a26b3e..3cce97fc9 100644 --- a/app/qml/components/MMButton.qml +++ b/app/qml/components/MMButton.qml @@ -15,8 +15,10 @@ Button { id: root enum Types { Primary, Secondary, Tertiary } + enum Sizes { Small, Regular } property int type: MMButton.Types.Primary + property int size: MMButton.Sizes.Regular property color fontColor: { if ( type === MMButton.Types.Primary ) return __style.forestColor @@ -161,10 +163,10 @@ Button { state: "default" implicitHeight: root.type === MMButton.Types.Tertiary ? buttonContent.height : buttonContent.height + topPadding + bottomPadding - implicitWidth: row.paintedChildrenWidth + 2 * __style.margin20 + implicitWidth: row.paintedChildrenWidth + 2 * ( root.size === MMButton.Sizes.Small ? __style.margin16 : __style.margin20 ) - topPadding: root.type === MMButton.Types.Tertiary ? 0 : 11 * __dp - bottomPadding: root.type === MMButton.Types.Tertiary ? 0 : 11 * __dp + topPadding: ( root.type === MMButton.Types.Tertiary ) ? 0 : 11 * __dp + bottomPadding: ( root.type === MMButton.Types.Tertiary ) ? 0 : 11 * __dp rightPadding: 0 leftPadding: 0 @@ -177,14 +179,21 @@ Button { id: row property real paintedChildrenWidth: buttonIconLeft.paintedWidth + buttonContent.implicitWidth + buttonIconRight.paintedWidth + spacing - property real maxWidth: parent.width - 2 * __style.margin20 + property real maxWidth: parent.width - 2 * ( root.size === MMButton.Sizes.Small ? __style.margin16 : __style.margin20 ) x: ( parent.width - width ) / 2 width: Math.min( paintedChildrenWidth, maxWidth ) height: Math.max( buttonContent.paintedHeight, buttonIconRight.height ) - spacing: buttonIconRight.visible || buttonIconLeft.visible ? __style.spacing12 : 0 + spacing: { + if ( ( root.size === MMButton.Sizes.Small ) ) + return __style.spacing2; + else if ( ( buttonIconRight.visible || buttonIconLeft.visible ) ) + return __style.spacing12; + else + return 0; + } MMIcon { id: buttonIconLeft diff --git a/app/qml/components/MMDrawerHeader.qml b/app/qml/components/MMDrawerHeader.qml index 8d5a5cfc2..b40c2ce1e 100644 --- a/app/qml/components/MMDrawerHeader.qml +++ b/app/qml/components/MMDrawerHeader.qml @@ -22,7 +22,9 @@ Rectangle { property font titleFont: __style.t3 property bool hasCloseButton: true + property alias closeButton: closeBtn + property alias topLeftItemContent: topLeftButtonGroup.children color: __style.transparentColor @@ -31,14 +33,26 @@ Rectangle { implicitHeight: 60 * __dp implicitWidth: ApplicationWindow.window?.width ?? 0 + Item { + id: topLeftButtonGroup + + width: childrenRect.width + height: parent.height + } + Text { - // If the close button is visible, we need to properly center the text - property real margin: internal.closeBtnRealWidth + internal.headerSpacing + __style.pageMargins + property real leftMarginShift: { + return Math.max( internal.closeBtnRealWidth, topLeftButtonGroup.width ) + internal.headerSpacing + __style.pageMargins + } + + property real rightMarginShift: { + return Math.max( internal.closeBtnRealWidth, topLeftButtonGroup.width ) + internal.headerSpacing + __style.pageMargins + } anchors { fill: parent - leftMargin: margin - rightMargin: margin + leftMargin: leftMarginShift + rightMargin: rightMarginShift } text: root.title diff --git a/app/qml/gps/MMMeasureDrawer.qml b/app/qml/gps/MMMeasureDrawer.qml new file mode 100644 index 000000000..75910e175 --- /dev/null +++ b/app/qml/gps/MMMeasureDrawer.qml @@ -0,0 +1,119 @@ +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Qt5Compat.GraphicalEffects +import QtQuick.Shapes + +import mm 1.0 as MM + +import "../components" +import "../map/components" +import "./components" as MMGpsComponents + +MMDrawer { + id: root + + property var mapTool + + readonly property alias panelHeight: root.height + + property bool canCloseShape: mapTool?.canCloseShape ?? false + property bool canUndo: mapTool?.canUndo ?? false + property bool isValidGeometry: mapTool?.isValidGeometry ?? false + property bool measurementFinalized: mapTool?.measurementFinalized ?? false + + property string perimeter: mapTool?.perimeter ?? 0 + property string area: mapTool?.area ?? 0 + property bool isPolygon: area > 0 + + signal measureFinished() + + Component.onCompleted: root.open() + + modal: false + interactive: false + closePolicy: Popup.CloseOnEscape + + dropShadow: true + + onClosed: root.measureFinished() + + Behavior on implicitHeight { + PropertyAnimation { properties: "implicitHeight"; easing.type: Easing.InOutQuad } + } + + drawerHeader.title: qsTr( "Measure" ) + + drawerHeader.topLeftItemContent: MMButton { + type: MMButton.Types.Primary + text: measurementFinalized ? qsTr( "Repeat" ) : qsTr( "Undo" ) + iconSourceLeft: measurementFinalized ? __style.syncIcon : __style.undoIcon + bgndColor: __style.lightGreenColor + size: MMButton.Sizes.Small + enabled: measurementFinalized || canUndo + + anchors { + left: parent.left + leftMargin: __style.pageMargins + __style.safeAreaLeft + verticalCenter: parent.verticalCenter + } + + onClicked: measurementFinalized ? root.mapTool.resetMeasurement() : root.mapTool.removePoint() + } + + drawerContent: Column { + id: mainColumn + + width: parent.width + spacing: __style.margin10 + + Row { + width: parent.width + + MMGpsComponents.MMGpsDataText{ + width: ( parent.width + parent.spacing ) / 2 + + title: measurementFinalized && root.isPolygon ? qsTr( "Perimeter" ) : qsTr( "Length" ) //Perimeter only if its a polygon + value: __inputUtils.formatDistanceInProjectUnit( root.perimeter, 1, __activeProject.qgsProject ) + } + + MMGpsComponents.MMGpsDataText{ + width: ( parent.width + parent.spacing ) / 2 + + title: qsTr( "Area" ) + value: __inputUtils.formatAreaInProjectUnit( root.area, 1, __activeProject.qgsProject ) + alignmentRight: true + visible: measurementFinalized && root.isPolygon + } + } + + Row { + width: parent.width + spacing: __style.margin12 + visible: !root.measurementFinalized + + MMButton { + text: root.canCloseShape ? qsTr( "Close shape" ) : qsTr( "Add point" ) + iconSourceLeft: canCloseShape ? __style.closeShapeIcon : __style.plusIcon + onClicked: canCloseShape ? root.mapTool.finalizeMeasurement( true ) : root.mapTool.addPoint() + } + + MMButton { + type: MMButton.Types.Secondary + text: qsTr( "Done" ) + iconSourceLeft: __style.doneCircleIcon + enabled: root.isValidGeometry + onClicked: root.mapTool.finalizeMeasurement( false ) + } + } + } +} diff --git a/app/qml/gps/MMStakeoutDrawer.qml b/app/qml/gps/MMStakeoutDrawer.qml index 918436976..61f6ca354 100644 --- a/app/qml/gps/MMStakeoutDrawer.qml +++ b/app/qml/gps/MMStakeoutDrawer.qml @@ -97,7 +97,6 @@ MMDrawer { Row { width: parent.width - spacing: __style.margi8 MMGpsComponents.MMGpsDataText{ width: ( parent.width + parent.spacing ) / 2 @@ -110,7 +109,7 @@ MMDrawer { width: ( parent.width + parent.spacing ) / 2 title: qsTr( "Distance" ) - value: remainingDistance >= 0 ?__inputUtils.formatDistanceInProjectUnit( remainingDistance, 2 ) : qsTr( "N/A" ) + value: remainingDistance >= 0 ?__inputUtils.formatDistanceInProjectUnit( remainingDistance, 2, __activeProject.qgsProject ) : qsTr( "N/A" ) alignmentRight: true } } diff --git a/app/qml/main.qml b/app/qml/main.qml index 822e7bd41..d6b7ea116 100644 --- a/app/qml/main.qml +++ b/app/qml/main.qml @@ -158,6 +158,10 @@ ApplicationWindow { // if stakeout panel is opened return stakeoutPanelLoader.item.panelHeight - mapToolbar.height } + else if ( measurePanelLoader.active ) + { + return measurePanelLoader.item.panelHeight - mapToolbar.height + } else if ( formsStackManager.takenVerticalSpace > 0 ) { // if feature preview panel is opened @@ -219,6 +223,11 @@ ApplicationWindow { stakeoutPanelLoader.item.targetPair = pair } + onMeasureStarted: function( pair ) { + measurePanelLoader.active = true + measurePanelLoader.focus = true + } + onLocalChangesPanelRequested: { stateManager.state = "projects" projectController.openChangesPanel( __activeProject.projectFullName(), true ) @@ -326,6 +335,12 @@ ApplicationWindow { } } + MMToolbarButton { + text: qsTr("Measure") + iconSource: __style.measurementToolIcon + onClicked: map.measure() + } + MMToolbarButton { text: qsTr("Local changes") iconSource: __style.localChangesIcon @@ -596,6 +611,32 @@ ApplicationWindow { } } + Loader { + id: measurePanelLoader + + focus: true + active: false + asynchronous: true + + sourceComponent: measurePanelComponent + } + + Component { + id: measurePanelComponent + + MMMeasureDrawer { + id: measurePanel + + width: window.width + mapTool: map.mapToolComponent + + onMeasureFinished: { + measurePanelLoader.active = false + map.finishMeasure() + } + } + } + MMFormStackController { id: formsStackManager diff --git a/app/qml/map/MMMapController.qml b/app/qml/map/MMMapController.qml index a1c8c7fb4..43f76d8af 100644 --- a/app/qml/map/MMMapController.qml +++ b/app/qml/map/MMMapController.qml @@ -35,6 +35,10 @@ Item { property bool isStreaming: recordingToolsLoader.active ? recordingToolsLoader.item.recordingMapTool.recordingType === MM.RecordingMapTool.StreamMode : false property bool centeredToGPS: false + property var mapToolComponent: { + measurementToolsLoader.active ? measurementToolsLoader.item.mapTool : null + } + property MM.PositionTrackingManager trackingManager: tracking.item?.manager ?? null signal featureIdentified( var pair ) @@ -60,6 +64,8 @@ Item { signal stakeoutStarted( var pair ) signal accuracyButtonClicked() + signal measureStarted() + signal localChangesPanelRequested() signal openTrackingPanel() @@ -86,6 +92,9 @@ Item { State { name: "stakeout" }, + State { + name: "measure" + }, State { name: "inactive" // ignores touch input } @@ -143,6 +152,13 @@ Item { break } + case "measure": { + root.showInfoTextMessage( qsTr( "Add points to measure distance, close the shape to measure area" ) ) + root.hideHighlight() + root.measureStarted() + break + } + case "inactive": { break } @@ -381,6 +397,17 @@ Item { sourceComponent: splittingToolsComponent } + Loader { + id: measurementToolsLoader + + anchors.fill: mapCanvas + + asynchronous: true + active: root.state === "measure" + + sourceComponent: measurementToolsComponent + } + // map available content within safe area Item { anchors { @@ -497,10 +524,10 @@ Item { anchors.bottom: parent.bottom - anchors.bottomMargin: root.state === "stakeout" ? root.mapExtentOffset : 0 + anchors.bottomMargin: root.state === "stakeout" || root.state === "measure" ? root.mapExtentOffset : 0 visible: { - if ( root.state === "stakeout" ) + if ( root.state === "stakeout" || root.state === "measure" ) return true else return root.mapExtentOffset > 0 ? false : true @@ -962,6 +989,18 @@ Item { } } + Component { + id: measurementToolsComponent + + MMMeasurementTools { + anchors.fill: parent + + map: mapCanvas + positionMarkerComponent: positionMarker + onFinishMeasurement: root.finishMeasure() + } + } + Component { id: splittingToolsComponent @@ -1111,6 +1150,10 @@ Item { state = "stakeout" } + function measure() { + state = "measure" + } + function toggleStreaming() { // start/stop the streaming mode if ( recordingToolsLoader.active ) { @@ -1127,6 +1170,10 @@ Item { root.centeredToGPS = internal.centeredToGPSBeforeStakeout } + function finishMeasure() { + state = "view" + } + function centerToPair( pair ) { __inputUtils.setExtentToFeature( pair, mapCanvas.mapSettings ) } diff --git a/app/qml/map/MMMeasurementTools.qml b/app/qml/map/MMMeasurementTools.qml new file mode 100644 index 000000000..e4a785961 --- /dev/null +++ b/app/qml/map/MMMeasurementTools.qml @@ -0,0 +1,101 @@ +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +import QtQuick +import QtQuick.Shapes + +import mm 1.0 as MM + +import "../components" +import "./components" +import "../gps" +import "../dialogs" + +Item { + id: root + + required property MMMapCanvas map + required property MMPositionMarker positionMarkerComponent + + property var mapTool: mapTool + + signal finishMeasurement() + + MM.MeasurementMapTool { + id: mapTool + + mapSettings: root.map.mapSettings + crosshairPoint: crosshair.screenPoint + } + + MM.GuidelineController { + id: guidelineController + + allowed: !mapTool.measurementFinalized + mapSettings: root.map.mapSettings + crosshairPosition: crosshair.screenPoint + realGeometry: mapTool.recordedGeometry + } + + MMHighlight { + id: guideline + + height: root.map.height + width: root.map.width + + markerColor: __style.deepOceanColor + lineColor: __style.deepOceanColor + lineStrokeStyle: ShapePath.DashLine + lineWidth: MMHighlight.LineWidths.Narrow + + mapSettings: root.map.mapSettings + geometry: guidelineController.guidelineGeometry + } + + MMHighlight { + id: highlight + + height: map.height + width: map.width + + markerColor: __style.deepOceanColor + lineColor: __style.deepOceanColor + lineWidth: MMHighlight.LineWidths.Narrow + + mapSettings: root.map.mapSettings + geometry: mapTool.recordedGeometry + } + + MMHighlight { + id: existingVerticesHighlight + + height: root.map.height + width: root.map.width + + mapSettings: root.map.mapSettings + geometry: mapTool.existingVertices + + markerType: MMHighlight.MarkerTypes.Circle + markerSize: MMHighlight.MarkerSizes.Bigger + } + + MMMeasureCrosshair { + id: crosshair + + anchors.fill: parent + qgsProject: __activeProject.qgsProject + mapSettings: root.map.mapSettings + visible: !mapTool.measurementFinalized + + text: __inputUtils.formatDistanceInProjectUnit( mapTool.lengthWithGuideline, 1, __activeProject.qgsProject ) + canCloseShape: mapTool.canCloseShape + + onCloseShapeClicked: root.mapTool.finalizeMeasurement( true ) + } +} diff --git a/app/qml/map/components/MMCrosshair.qml b/app/qml/map/components/MMCrosshair.qml index a9c7ec465..82892ff25 100644 --- a/app/qml/map/components/MMCrosshair.qml +++ b/app/qml/map/components/MMCrosshair.qml @@ -28,6 +28,9 @@ Item { property real outerSize: 60 * __dp property real innerDotSize: 10 * __dp + property alias crosshairForeground: crosshairForeground + property alias snapUtils: snapUtils + MM.SnapUtils { id: snapUtils diff --git a/app/qml/map/components/MMMapHidingLabel.qml b/app/qml/map/components/MMMapHidingLabel.qml index 7a0ab3720..63941982d 100644 --- a/app/qml/map/components/MMMapHidingLabel.qml +++ b/app/qml/map/components/MMMapHidingLabel.qml @@ -24,12 +24,14 @@ MMHidingBox { root.visible = false } - height: __style.row40 + height: text.lineCount * __style.row40 timerInterval: 10000 fadeOutDuration: 1000 // Text Text { + id: text + height: parent.height width: parent.width - 2 * __style.pageMargins anchors.verticalCenter: parent.verticalCenter @@ -40,6 +42,8 @@ MMHidingBox { font: __style.t3 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter + maximumLineCount: 3 + wrapMode: Text.WordWrap elide: Text.ElideRight } } diff --git a/app/qml/map/components/MMMeasureCrosshair.qml b/app/qml/map/components/MMMeasureCrosshair.qml new file mode 100644 index 000000000..3102def00 --- /dev/null +++ b/app/qml/map/components/MMMeasureCrosshair.qml @@ -0,0 +1,106 @@ +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +import QtQuick +import Qt5Compat.GraphicalEffects + +import mm 1.0 as MM +import "../../components" + +Item { + id: root + + required property string text + /*required*/ property var qgsProject + /*required*/ property var mapSettings + + property bool canCloseShape: false + property bool shouldUseSnapping: false + + property point center: Qt.point( root.width / 2, root.height / 2 ) + + property var recordPoint: crosshair.recordPoint + + property point screenPoint: crosshair.snapUtils.snapped && __activeLayer.vectorLayer ? __inputUtils.transformPointToScreenCoordinates(__activeLayer.vectorLayer.crs, mapSettings, recordPoint) : center + + property real outerSize: 60 * __dp + property real innerDotSize: 10 * __dp + + implicitWidth: row.width + implicitHeight: __style.mapItemHeight + + signal closeShapeClicked + + MMCrosshair { + id: crosshair + + anchors.fill: parent + qgsProject: __activeProject.qgsProject + mapSettings: root.mapSettings + } + + Rectangle { + y: crosshair.crosshairForeground.y + crosshair.crosshairForeground.height + __style.spacing2 + x: crosshair.crosshairForeground.x - ( ( width - crosshair.crosshairForeground.width ) / 2 ) + + width: Math.max( root.outerSize - __style.spacing10 , row.width ) + height: root.outerSize * 0.6 + radius: root.height / 2 + color: textBg.color + + layer.enabled: true + layer.effect: MMShadow {} + + Row { + id: row + + anchors.centerIn: parent + leftPadding: 8 * __dp + rightPadding: leftPadding + spacing: 4 * __dp + height: parent.height + + MMIcon { + id: icon + anchors.verticalCenter: parent.verticalCenter + source: root.canCloseShape ? __style.closeShapeIcon : "" + size: root.canCloseShape ? __style.icon24 : 0 + } + + Rectangle { + id: textBg + property real spacing: __style.spacing5 + anchors.verticalCenter: parent.verticalCenter + color: root.canCloseShape ? __style.grassColor : __style.forestColor + height: text.height + spacing + width: text.width + 3 * spacing + radius: height / 2 + + MMText { + id: text + + property real textSurroundingItemsWidth: textBg.spacing + icon.width + row.spacing + 2 * row.leftPadding + + width: ( implicitWidth + textSurroundingItemsWidth ) > root.maxWidth ? root.maxWidth - textSurroundingItemsWidth : implicitWidth + anchors.centerIn: parent + color: root.canCloseShape ? __style.forestColor: __style.polarColor + text: root.canCloseShape ? qsTr( "Close shape" ) : root.text + font: __style.t3 + elide: Text.ElideRight + } + } + } + + MouseArea { + anchors.fill: parent + enabled: root.canCloseShape + onClicked: root.closeShapeClicked() + } + } +} diff --git a/app/test/testmaptools.cpp b/app/test/testmaptools.cpp index 3b359a399..c90fb4de2 100644 --- a/app/test/testmaptools.cpp +++ b/app/test/testmaptools.cpp @@ -29,6 +29,7 @@ #include "snaputils.h" #include "maptools/splittingmaptool.h" #include "maptools/recordingmaptool.h" +#include "maptools/measurementmaptool.h" #include "featurelayerpair.h" #include "streamingintervaltype.h" @@ -276,6 +277,87 @@ void TestMapTools::testRecording() delete recordTool; } +void TestMapTools::testMeasuring() +{ + MeasurementMapTool *measurementTool = new MeasurementMapTool(); + + InputMapCanvasMap canvas; + InputMapSettings *ms = canvas.mapSettings(); + + QgsProject *project = TestUtils::loadPlanesTestProject(); + QVERIFY( project && !project->homePath().isEmpty() ); + + setupMapSettings( ms, project, QgsRectangle( -10, -10, 10, 10 ), QSize( 600, 600 ) ); + + measurementTool->setMapSettings( ms ); + + QgsDistanceArea distanceArea; + distanceArea.setEllipsoid( ms->project()->ellipsoid() ); + distanceArea.setSourceCrs( ms->destinationCrs(), ms->transformContext() ); + + QPointF crosshairPoint1 = ms->coordinateToScreen( QgsPoint( 0, 0 ) ); + measurementTool->setCrosshairPoint( crosshairPoint1 ); + measurementTool->addPoint(); + + measurementTool->updateDistance(); + QCOMPARE( measurementTool->lengthWithGuideline(), 0.0 ); + + QPointF crosshairPoint2 = ms->coordinateToScreen( QgsPoint( 0, 1 ) ); + measurementTool->setCrosshairPoint( crosshairPoint2 ); + measurementTool->addPoint(); + + measurementTool->updateDistance(); + + QList points; + points.append( QgsPointXY( 0, 0 ) ); + points.append( QgsPointXY( 0, 1 ) ); + + QgsGeometry lineGeometry = QgsGeometry::fromPolylineXY( points ); + double expectedPerimeter = distanceArea.measureLength( lineGeometry ); + QCOMPARE( measurementTool->perimeter(), expectedPerimeter ); + + QPointF crosshairPoint3 = ms->coordinateToScreen( QgsPoint( 1, 1 ) ); + measurementTool->setCrosshairPoint( crosshairPoint3 ); + measurementTool->addPoint(); + + measurementTool->updateDistance(); + points.append( QgsPointXY( 1, 1 ) ); + lineGeometry = QgsGeometry::fromPolylineXY( points ); + expectedPerimeter = distanceArea.measureLength( lineGeometry ); + QCOMPARE( measurementTool->perimeter(), expectedPerimeter ); + + measurementTool->finalizeMeasurement( false ); + + QVERIFY( measurementTool->recordedGeometry().wkbType() == Qgis::WkbType::LineString ); + + measurementTool->resetMeasurement(); + + measurementTool->setCrosshairPoint( crosshairPoint1 ); + measurementTool->addPoint(); + + measurementTool->setCrosshairPoint( crosshairPoint2 ); + measurementTool->addPoint(); + + measurementTool->setCrosshairPoint( crosshairPoint3 ); + measurementTool->addPoint(); + + measurementTool->setCrosshairPoint( crosshairPoint1 ); + measurementTool->updateDistance(); + + QVERIFY( measurementTool->canCloseShape() ); + + measurementTool->finalizeMeasurement( true ); + + QVERIFY( measurementTool->recordedGeometry().wkbType() == Qgis::WkbType::Polygon ); + + QgsGeometry polygonGeometry = QgsGeometry::fromPolygonXY( QList>() << points ); + double expectedArea = distanceArea.measureArea( polygonGeometry ); + QCOMPARE( measurementTool->area(), expectedArea ); + + delete project; + delete measurementTool; +} + void TestMapTools::testExistingVertices() { RecordingMapTool mapTool; diff --git a/app/test/testmaptools.h b/app/test/testmaptools.h index deb24e0c4..e06c748aa 100644 --- a/app/test/testmaptools.h +++ b/app/test/testmaptools.h @@ -29,6 +29,7 @@ class TestMapTools : public QObject void testSnapping(); void testSplitting(); void testRecording(); + void testMeasuring(); void testExistingVertices(); void testMidSegmentVertices(); diff --git a/app/test/testutilsfunctions.cpp b/app/test/testutilsfunctions.cpp index 603d8e319..564b8458b 100644 --- a/app/test/testutilsfunctions.cpp +++ b/app/test/testutilsfunctions.cpp @@ -856,35 +856,93 @@ void TestUtilsFunctions::testParsePositionUpdates() } } -void TestUtilsFunctions::testFormatDistanceInDistanceUnit() +void TestUtilsFunctions::testFormatDistanceInProjectUnit() { - QString dist2str = mUtils->formatDistanceInProjectUnit( 1222.234, 2, Qgis::DistanceUnit::Meters ); + QgsProject *project = QgsProject::instance(); + QVERIFY( project != nullptr ); + + // Set the project distance units to meters + project->setDistanceUnits( Qgis::DistanceUnit::Meters ); + + QString dist2str = mUtils->formatDistanceInProjectUnit( 1222.234, 2, project ); QVERIFY( dist2str == "1222.23 m" ); - dist2str = mUtils->formatDistanceInProjectUnit( 1222.234, 1, Qgis::DistanceUnit::Meters ); + dist2str = mUtils->formatDistanceInProjectUnit( 1222.234, 1, project ); QVERIFY( dist2str == "1222.2 m" ); - dist2str = mUtils->formatDistanceInProjectUnit( 1222.234, 0, Qgis::DistanceUnit::Meters ); + dist2str = mUtils->formatDistanceInProjectUnit( 1222.234, 0, project ); QVERIFY( dist2str == "1222 m" ); - dist2str = mUtils->formatDistanceInProjectUnit( 700.22, 1, Qgis::DistanceUnit::Meters ); + dist2str = mUtils->formatDistanceInProjectUnit( 700.22, 1, project ); QVERIFY( dist2str == "700.2 m" ); - dist2str = mUtils->formatDistanceInProjectUnit( 0.22, 0, Qgis::DistanceUnit::Meters ); + dist2str = mUtils->formatDistanceInProjectUnit( 0.22, 0, project ); QVERIFY( dist2str == "0 m" ); - dist2str = mUtils->formatDistanceInProjectUnit( -0.22, 0, Qgis::DistanceUnit::Meters ); + dist2str = mUtils->formatDistanceInProjectUnit( -0.22, 0, project ); QVERIFY( dist2str == "-0 m" ); - dist2str = mUtils->formatDistanceInProjectUnit( 1.222234, 2, Qgis::DistanceUnit::Kilometers ); + // Change project distance units to kilometers + project->setDistanceUnits( Qgis::DistanceUnit::Kilometers ); + + dist2str = mUtils->formatDistanceInProjectUnit( 1.222234, 2, project ); QVERIFY( dist2str == "0.00 km" ); - dist2str = mUtils->formatDistanceInProjectUnit( 6000, 1, Qgis::DistanceUnit::Feet ); + // Change project distance units to feet + project->setDistanceUnits( Qgis::DistanceUnit::Feet ); + + dist2str = mUtils->formatDistanceInProjectUnit( 6000, 1, project ); QVERIFY( dist2str == "19685.0 ft" ); - dist2str = mUtils->formatDistanceInProjectUnit( 5, 1, Qgis::DistanceUnit::Feet ); + dist2str = mUtils->formatDistanceInProjectUnit( 5, 1, project ); QVERIFY( dist2str == "16.4 ft" ); - dist2str = mUtils->formatDistanceInProjectUnit( 7000, 1, Qgis::DistanceUnit::Feet ); + dist2str = mUtils->formatDistanceInProjectUnit( 7000, 1, project ); QVERIFY( dist2str == "22965.9 ft" ); } + + +void TestUtilsFunctions::testFormatAreaInProjectUnit() +{ + QgsProject *project = QgsProject::instance(); + QVERIFY( project != nullptr ); + + // Set project area units to square meters + project->setAreaUnits( Qgis::AreaUnit::SquareMeters ); + + QString area2str = mUtils->formatAreaInProjectUnit( 1500.234, 2, project ); + QVERIFY( area2str == "1500.23 m²" ); + + area2str = mUtils->formatAreaInProjectUnit( 1500.234, 1, project ); + QVERIFY( area2str == "1500.2 m²" ); + + area2str = mUtils->formatAreaInProjectUnit( 1500.234, 0, project ); + QVERIFY( area2str == "1500 m²" ); + + area2str = mUtils->formatAreaInProjectUnit( 500.22, 1, project ); + QVERIFY( area2str == "500.2 m²" ); + + area2str = mUtils->formatAreaInProjectUnit( 0.22, 0, project ); + QVERIFY( area2str == "0 m²" ); + + area2str = mUtils->formatAreaInProjectUnit( -0.22, 0, project ); + QVERIFY( area2str == "-0 m²" ); + + // Change project area units to square kilometers + project->setAreaUnits( Qgis::AreaUnit::SquareKilometers ); + + area2str = mUtils->formatAreaInProjectUnit( 1.222234, 2, project ); + QVERIFY( area2str == "0.00 km²" ); + + // Change project area units to acres + project->setAreaUnits( Qgis::AreaUnit::Acres ); + + area2str = mUtils->formatAreaInProjectUnit( 6000, 1, project ); + QVERIFY( area2str == "1.5 ac" ); + + area2str = mUtils->formatAreaInProjectUnit( 5, 1, project ); + QVERIFY( area2str == "0.0 ac" ); + + area2str = mUtils->formatAreaInProjectUnit( 7000, 1, project ); + QVERIFY( area2str == "1.7 ac" ); +} diff --git a/app/test/testutilsfunctions.h b/app/test/testutilsfunctions.h index f74cf140f..75b497c78 100644 --- a/app/test/testutilsfunctions.h +++ b/app/test/testutilsfunctions.h @@ -48,7 +48,8 @@ class TestUtilsFunctions: public QObject void testInvalidGeometryWarning(); void testAttribution(); void testParsePositionUpdates(); - void testFormatDistanceInDistanceUnit(); + void testFormatDistanceInProjectUnit(); + void testFormatAreaInProjectUnit(); private: void testFormatDuration( const QDateTime &t0, qint64 diffSecs, const QString &expectedResult ); diff --git a/gallery/qml/pages/ButtonsPage.qml b/gallery/qml/pages/ButtonsPage.qml index 97fabbb3e..4e0bc636e 100644 --- a/gallery/qml/pages/ButtonsPage.qml +++ b/gallery/qml/pages/ButtonsPage.qml @@ -87,8 +87,24 @@ ScrollView { iconSourceLeft: __style.uploadIcon } - MMButton { - text: "Primary flex width (no witdth set)" + Row { + width: parent.width + spacing: 20 + + MMButton { + text: "Primary flex width (no witdth set)" + } + + MMButton { + text: "Small Primary" + size: MMButton.Sizes.Small + } + + MMButton { + text: "Small Primary with Icon" + iconSourceLeft: __style.syncIcon + size: MMButton.Sizes.Small + } } MMListSpacer { height: __style.margin20 } @@ -142,11 +158,29 @@ ScrollView { iconSourceRight: __style.arrowLinkRightIcon } - MMButton { - type: MMButton.Types.Secondary - text: "Secondary flex width (no witdth set)" - iconSourceLeft: __style.uploadIcon - iconSourceRight: __style.uploadIcon + Row { + width: parent.width + spacing: 20 + + MMButton { + type: MMButton.Types.Secondary + text: "Secondary flex width (no witdth set)" + iconSourceLeft: __style.uploadIcon + iconSourceRight: __style.uploadIcon + } + + MMButton { + text: "Small Secondary" + type: MMButton.Types.Secondary + size: MMButton.Sizes.Small + } + + MMButton { + text: "Small Secondary with Icon" + type: MMButton.Types.Secondary + iconSourceLeft: __style.syncIcon + size: MMButton.Sizes.Small + } } MMListSpacer { height: __style.margin20 } @@ -200,11 +234,29 @@ ScrollView { iconSourceRight: __style.arrowLinkRightIcon } - MMButton { - type: MMButton.Types.Tertiary - text: "Tertiary flex width (no witdth set)" - fontColor: __style.nightColor - iconSourceLeft: __style.globeIcon + Row { + width: parent.width + spacing: 20 + + MMButton { + type: MMButton.Types.Tertiary + text: "Tertiary flex width (no witdth set)" + fontColor: __style.nightColor + iconSourceLeft: __style.globeIcon + } + + MMButton { + text: "Small Tertiary" + type: MMButton.Types.Tertiary + size: MMButton.Sizes.Small + } + + MMButton { + text: "Small Tertiary with Icon" + type: MMButton.Types.Tertiary + iconSourceLeft: __style.syncIcon + size: MMButton.Sizes.Small + } } } } diff --git a/gallery/qml/pages/IconsPage.qml b/gallery/qml/pages/IconsPage.qml index a9d56b6dd..999d34c26 100644 --- a/gallery/qml/pages/IconsPage.qml +++ b/gallery/qml/pages/IconsPage.qml @@ -76,6 +76,8 @@ ScrollView { GalleryComponents.IconLine { name: "morePhotosIcon"; source: __style.morePhotosIcon; showRect: checkboxBorder.checked; invertColors: checkboxColor.checked } GalleryComponents.IconLine { name: "plusIcon"; source: __style.plusIcon; showRect: checkboxBorder.checked; invertColors: checkboxColor.checked } GalleryComponents.IconLine { name: "positionTrackingIcon"; source: __style.positionTrackingIcon; showRect: checkboxBorder.checked; invertColors: checkboxColor.checked } + GalleryComponents.IconLine { name: "measurementToolIcon"; source: __style.measurementToolIcon; showRect: checkboxBorder.checked; invertColors: checkboxColor.checked } + GalleryComponents.IconLine { name: "closeShapeIcon"; source: __style.closeShapeIcon; showRect: checkboxBorder.checked; invertColors: checkboxColor.checked } GalleryComponents.IconLine { name: "qrCodeIcon"; source: __style.qrCodeIcon; showRect: checkboxBorder.checked; invertColors: checkboxColor.checked } GalleryComponents.IconLine { name: "satelliteIcon"; source: __style.satelliteIcon; showRect: checkboxBorder.checked; invertColors: checkboxColor.checked } GalleryComponents.IconLine { name: "searchIcon"; source: __style.searchIcon; showRect: checkboxBorder.checked; invertColors: checkboxColor.checked }