@geogirafe/lib-geoportal 1.1.0-dev.2433737633 → 1.1.0-dev.2438378072
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/i18n/de.json +8 -0
- package/assets/i18n/en.json +8 -0
- package/assets/i18n/fr.json +8 -0
- package/assets/i18n/it.json +8 -0
- package/base/GirafeHTMLElement.d.ts +1 -1
- package/buildtools/generate-dev-certs.sh +0 -0
- package/components/drawing/cesiumDrawing.d.ts +2 -2
- package/components/drawing/cesiumDrawing.js +5 -5
- package/components/drawing/component-mobile.js +2 -2
- package/components/drawing/component.d.ts +10 -9
- package/components/drawing/component.js +71 -39
- package/components/drawing/drawingFeature.d.ts +2 -1
- package/components/drawing/drawingFeature.js +11 -3
- package/components/drawing/fixed-dimension/component.d.ts +39 -0
- package/components/drawing/fixed-dimension/component.js +123 -0
- package/components/drawing/olDrawing.d.ts +9 -2
- package/components/drawing/olDrawing.js +101 -15
- package/components/main.d.ts +2 -0
- package/components/main.js +1 -0
- package/decorators.d.ts +5 -0
- package/decorators.js +7 -0
- package/package.json +1 -1
- package/templates/public/about.json +1 -1
- package/tools/app/geogirafeapp.js +2 -0
- package/tools/main.d.ts +1 -1
- package/tools/main.js +1 -1
- package/tools/utils/olutils.d.ts +1 -0
- package/tools/utils/olutils.js +8 -1
package/assets/i18n/de.json
CHANGED
|
@@ -70,9 +70,11 @@
|
|
|
70
70
|
"Define time restriction on group": "Zeitliche Begrenzung für Gruppe definieren",
|
|
71
71
|
"Define time restriction on layer": "Zeitliche Begrenzung für Layer definieren",
|
|
72
72
|
"delete": "Löschen",
|
|
73
|
+
"Delete all shapes": "Alle Formen löschen",
|
|
73
74
|
"Delete bookmark": "Lesezeichen löschen",
|
|
74
75
|
"Delete Feature": "Funktion löschen",
|
|
75
76
|
"Delete feature": "Objekt löschen",
|
|
77
|
+
"Delete Features": "Objekte löschen",
|
|
76
78
|
"Delete shape": "Form löschen",
|
|
77
79
|
"Delete Theme": "Thema löschen",
|
|
78
80
|
"delete_help": "Profil-Linie löschen",
|
|
@@ -85,6 +87,7 @@
|
|
|
85
87
|
"Do you want to delete this theme?": "Möchten Sie dieses Thema löschen?",
|
|
86
88
|
"Do you want to logout ?": "Möchten Sie sich abmelden?",
|
|
87
89
|
"Do you want to remove \"${feature.name}\" ?": "Möchten Sie \"${feature.name}\" entfernen?",
|
|
90
|
+
"Do you want to remove all features?": "Möchten Sie alle Objekte entfernen?",
|
|
88
91
|
"Documentation": "Dokumentation",
|
|
89
92
|
"does not contain": "enthält nicht",
|
|
90
93
|
"does not equal": "ungleich",
|
|
@@ -102,6 +105,7 @@
|
|
|
102
105
|
"Draw polygons": "Polygone zeichnen",
|
|
103
106
|
"draw_profile": "Profil-Linie zeichnen",
|
|
104
107
|
"draw_profile_help": "Profil-Linien-Zeichnen auf der Karte umschalten",
|
|
108
|
+
"Drawing List": "Zeichnungsliste",
|
|
105
109
|
"drawing-panel": "Zeichnen & messen",
|
|
106
110
|
"drawingFillColor": "Zeichnen Füllfarbe",
|
|
107
111
|
"Drawings": "Zeichnungen",
|
|
@@ -142,7 +146,10 @@
|
|
|
142
146
|
"Filter layer": "Layer filtern",
|
|
143
147
|
"Filter layer tree...": "Layerliste filtern...",
|
|
144
148
|
"Filtering deactivated: layers in layergroup don't have identical attributes.": "Filterung deaktiviert: Layer in der Layergruppe haben nicht identische Attribute.",
|
|
149
|
+
"Fix height to": "Höhe festlegen auf",
|
|
145
150
|
"Fix length to": "Länge festlegen auf",
|
|
151
|
+
"Fix side length to": "Seitenlänge festlegen auf",
|
|
152
|
+
"Fix width to": "Breite festlegen auf",
|
|
146
153
|
"Font": "Schriftart",
|
|
147
154
|
"Format": "Format",
|
|
148
155
|
"fr": "Französisch",
|
|
@@ -378,6 +385,7 @@
|
|
|
378
385
|
"selectStrokeColor": "Auswahl Strichfarbe",
|
|
379
386
|
"Send": "Senden",
|
|
380
387
|
"Send message": "Nachricht senden",
|
|
388
|
+
"Settings": "Einstellungen",
|
|
381
389
|
"Shadows": "Schatten",
|
|
382
390
|
"Share this map": "Diese Karte teilen",
|
|
383
391
|
"share-panel": "Karte teilen oder einbetten",
|
package/assets/i18n/en.json
CHANGED
|
@@ -73,6 +73,8 @@
|
|
|
73
73
|
"Delete bookmark": "Delete bookmark",
|
|
74
74
|
"Delete Feature": "Delete Feature",
|
|
75
75
|
"Delete feature": "Delete feature",
|
|
76
|
+
"Delete Features": "Delete Features",
|
|
77
|
+
"Delete all shapes": "Delete all shapes",
|
|
76
78
|
"Delete shape": "Delete shape",
|
|
77
79
|
"Delete Theme": "Delete Theme",
|
|
78
80
|
"delete_help": "Delete profile line",
|
|
@@ -85,6 +87,7 @@
|
|
|
85
87
|
"Do you want to delete this theme?": "Do you want to delete this theme?",
|
|
86
88
|
"Do you want to logout ?": "Do you want to logout?",
|
|
87
89
|
"Do you want to remove \"${feature.name}\" ?": "Do you want to remove \"${feature.name}\"?",
|
|
90
|
+
"Do you want to remove all features?": "Do you want to remove all features?",
|
|
88
91
|
"Documentation": "Documentation",
|
|
89
92
|
"does not contain": "does not contain",
|
|
90
93
|
"does not equal": "does not equal",
|
|
@@ -102,6 +105,7 @@
|
|
|
102
105
|
"Draw polygons": "Draw polygons",
|
|
103
106
|
"draw_profile": "Draw profile line",
|
|
104
107
|
"draw_profile_help": "Toggle profile line drawing on map",
|
|
108
|
+
"Drawing List": "Drawings List",
|
|
105
109
|
"drawing-panel": "Draw & measure",
|
|
106
110
|
"drawingFillColor": "Drawing fill color",
|
|
107
111
|
"Drawings": "Drawings",
|
|
@@ -143,7 +147,10 @@
|
|
|
143
147
|
"Filter layer": "Filter layer",
|
|
144
148
|
"Filter layer tree...": "Filter layer tree...",
|
|
145
149
|
"Filtering deactivated: layers in layergroup don't have identical attributes.": "Filtering deactivated: layers in layergroup don't have identical attributes.",
|
|
150
|
+
"Fix height to": "Fix height to",
|
|
146
151
|
"Fix length to": "Fix length to",
|
|
152
|
+
"Fix side length to": "Fix side length to",
|
|
153
|
+
"Fix width to": "Fix width to",
|
|
147
154
|
"Font": "Font",
|
|
148
155
|
"Format": "Format",
|
|
149
156
|
"fr": "French",
|
|
@@ -379,6 +386,7 @@
|
|
|
379
386
|
"selectStrokeColor": "Selection stroke color",
|
|
380
387
|
"Send": "Send",
|
|
381
388
|
"Send message": "Send message",
|
|
389
|
+
"Settings": "Settings",
|
|
382
390
|
"Shadows": "Shadows",
|
|
383
391
|
"Share this map": "Share this map",
|
|
384
392
|
"share-panel": "Share or embed map",
|
package/assets/i18n/fr.json
CHANGED
|
@@ -70,9 +70,11 @@
|
|
|
70
70
|
"Define time restriction on group": "Définir la restriction temporelle pour le groupe",
|
|
71
71
|
"Define time restriction on layer": "Définir la restriction temporelle sur la couche",
|
|
72
72
|
"delete": "Supprimer",
|
|
73
|
+
"Delete all shapes": "Supprimer toutes les formes",
|
|
73
74
|
"Delete bookmark": "Supprimer le favori",
|
|
74
75
|
"Delete Feature": "Supprimer la fonctionnalité",
|
|
75
76
|
"Delete feature": "Suppression de l'entité",
|
|
77
|
+
"Delete Features": "Supprimer les objets",
|
|
76
78
|
"Delete shape": "Supprimer la forme",
|
|
77
79
|
"Delete Theme": "Supprimer le thème",
|
|
78
80
|
"delete_help": "Supprimer la ligne de profil",
|
|
@@ -85,6 +87,7 @@
|
|
|
85
87
|
"Do you want to delete this theme?": "Voulez-vous supprimer ce thème ?",
|
|
86
88
|
"Do you want to logout ?": "Voulez-vous vous déconnecter ?",
|
|
87
89
|
"Do you want to remove \"${feature.name}\" ?": "Voulez-vous supprimer \"${feature.name}\" ?",
|
|
90
|
+
"Do you want to remove all features?": "Voulez-vous supprimer tous les objets ?",
|
|
88
91
|
"Documentation": "Documentation",
|
|
89
92
|
"does not contain": "ne contient pas",
|
|
90
93
|
"does not equal": "n'est pas égal à",
|
|
@@ -102,6 +105,7 @@
|
|
|
102
105
|
"Draw polygons": "Tracer des polygones",
|
|
103
106
|
"draw_profile": "Dessiner",
|
|
104
107
|
"draw_profile_help": "Activer/désactiver le dessin de la ligne de profil sur la carte",
|
|
108
|
+
"Drawing List": "Liste des dessins",
|
|
105
109
|
"drawing-panel": "Dessiner & mesurer",
|
|
106
110
|
"drawingFillColor": "Couleur de remplissage du dessin",
|
|
107
111
|
"Drawings": "Dessins",
|
|
@@ -142,7 +146,10 @@
|
|
|
142
146
|
"Filter layer": "Filtrer la couche",
|
|
143
147
|
"Filter layer tree...": "Filtrer les couches...",
|
|
144
148
|
"Filtering deactivated: layers in layergroup don't have identical attributes.": "Filtrage désactivé : les couches dans le groupe de couches n'ont pas d'attributs identiques.",
|
|
149
|
+
"Fix height to": "Fixer la hauteur à",
|
|
145
150
|
"Fix length to": "Fixer la longueur à",
|
|
151
|
+
"Fix side length to": "Fixer la longueur du côté à",
|
|
152
|
+
"Fix width to": "Fixer la largeur à",
|
|
146
153
|
"Font": "Police",
|
|
147
154
|
"Format": "Format",
|
|
148
155
|
"fr": "Français",
|
|
@@ -378,6 +385,7 @@
|
|
|
378
385
|
"selectStrokeColor": "Couleur du trait de sélection",
|
|
379
386
|
"Send": "Envoyer",
|
|
380
387
|
"Send message": "Envoyer un message",
|
|
388
|
+
"Settings": "Paramètres",
|
|
381
389
|
"Shadows": "Ombres",
|
|
382
390
|
"Share this map": "Partager cette carte",
|
|
383
391
|
"share-panel": "Partager ou intégrer la carte",
|
package/assets/i18n/it.json
CHANGED
|
@@ -70,9 +70,11 @@
|
|
|
70
70
|
"Define time restriction on group": "Definire la restrizione temporale del gruppo",
|
|
71
71
|
"Define time restriction on layer": "Definire la restrizione temporale del livello",
|
|
72
72
|
"delete": "Elimina",
|
|
73
|
+
"Delete all shapes": "Elimina tutte le forme",
|
|
73
74
|
"Delete bookmark": "Elimina segnalibro",
|
|
74
75
|
"Delete Feature": "Elimina funzionalità",
|
|
75
76
|
"Delete feature": "Eliminare l'elemento",
|
|
77
|
+
"Delete Features": "Elimina oggetti",
|
|
76
78
|
"Delete shape": "Elimina forma",
|
|
77
79
|
"Delete Theme": "Elimina tema",
|
|
78
80
|
"delete_help": "Elimina la linea di profilo",
|
|
@@ -85,6 +87,7 @@
|
|
|
85
87
|
"Do you want to delete this theme?": "Vuoi eliminare questo tema?",
|
|
86
88
|
"Do you want to logout ?": "Vuoi disconnetterti?",
|
|
87
89
|
"Do you want to remove \"${feature.name}\" ?": "Vuoi rimuovere \"${feature.name}\"?",
|
|
90
|
+
"Do you want to remove all features?": "Vuoi rimuovere tutti gli oggetti?",
|
|
88
91
|
"Documentation": "Documentazione",
|
|
89
92
|
"does not contain": "non contiene",
|
|
90
93
|
"does not equal": "diverso da",
|
|
@@ -102,6 +105,7 @@
|
|
|
102
105
|
"Draw polygons": "Disegnare un poligono",
|
|
103
106
|
"draw_profile": "Disegna linea di profilo",
|
|
104
107
|
"draw_profile_help": "Attiva/disattiva il disegno della linea di profilo sulla mappa",
|
|
108
|
+
"Drawing List": "Elenco dei disegni",
|
|
105
109
|
"drawing-panel": "Disegna e misura",
|
|
106
110
|
"drawingFillColor": "Colore di riempimento del disegno",
|
|
107
111
|
"Drawings": "Disegni",
|
|
@@ -142,7 +146,10 @@
|
|
|
142
146
|
"Filter layer": "Filtra layer",
|
|
143
147
|
"Filter layer tree...": "Albero dei livelli di filtraggio...",
|
|
144
148
|
"Filtering deactivated: layers in layergroup don't have identical attributes.": "Filtro disattivato: i layer nel gruppo non hanno attributi identici.",
|
|
149
|
+
"Fix height to": "Fissa l’altezza a",
|
|
145
150
|
"Fix length to": "Fissa la lunghezza a",
|
|
151
|
+
"Fix side length to": "Fissare la lunghezza del lato a",
|
|
152
|
+
"Fix width to": "Fissa la larghezza a",
|
|
146
153
|
"Font": "Carattere",
|
|
147
154
|
"Format": "Formato",
|
|
148
155
|
"fr": "Francese",
|
|
@@ -378,6 +385,7 @@
|
|
|
378
385
|
"selectStrokeColor": "Colore del tratto di selezione",
|
|
379
386
|
"Send": "Invia",
|
|
380
387
|
"Send message": "Invia messaggio",
|
|
388
|
+
"Settings": "Impostazioni",
|
|
381
389
|
"Shadows": "Ombre",
|
|
382
390
|
"Share this map": "Condividi questa mappa",
|
|
383
391
|
"share-panel": "Condividi o incorpora la mappa",
|
|
@@ -9,7 +9,7 @@ declare abstract class GirafeHTMLElement extends HTMLElement {
|
|
|
9
9
|
protected template: Hole | (() => Hole);
|
|
10
10
|
readonly name: string;
|
|
11
11
|
protected shadow: ShadowRoot;
|
|
12
|
-
|
|
12
|
+
protected displayStyle?: string;
|
|
13
13
|
private timeoutId?;
|
|
14
14
|
protected rendered: boolean;
|
|
15
15
|
private readonly callbacks;
|
|
File without changes
|
|
@@ -11,13 +11,13 @@ export default class CesiumDrawing {
|
|
|
11
11
|
scene: Cesium.Scene | undefined;
|
|
12
12
|
handler: Cesium.ScreenSpaceEventHandler | undefined;
|
|
13
13
|
entities: Cesium.EntityCollection | undefined;
|
|
14
|
-
|
|
14
|
+
fixedLineLength: number;
|
|
15
15
|
private readonly context;
|
|
16
16
|
private get state();
|
|
17
17
|
private get drawingState();
|
|
18
18
|
private get config();
|
|
19
19
|
constructor(map: MapComponent, toolName: string, context: IGirafeContext);
|
|
20
|
-
|
|
20
|
+
setFixedLineLength(length: number): void;
|
|
21
21
|
activateTool(tool: DrawingShape): void;
|
|
22
22
|
deactivateTool(): void;
|
|
23
23
|
pickOnGlobe(position: Cartesian2): Cesium.Cartesian3 | undefined;
|
|
@@ -13,7 +13,7 @@ export default class CesiumDrawing {
|
|
|
13
13
|
scene = undefined;
|
|
14
14
|
handler = undefined;
|
|
15
15
|
entities = undefined;
|
|
16
|
-
|
|
16
|
+
fixedLineLength = 0;
|
|
17
17
|
context;
|
|
18
18
|
get state() {
|
|
19
19
|
return this.context.stateManager.state;
|
|
@@ -36,8 +36,8 @@ export default class CesiumDrawing {
|
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
this.
|
|
39
|
+
setFixedLineLength(length) {
|
|
40
|
+
this.fixedLineLength = Number.isNaN(length) ? 0 : length;
|
|
41
41
|
}
|
|
42
42
|
activateTool(tool) {
|
|
43
43
|
if (!this.canExecute('globe.draw')) {
|
|
@@ -124,7 +124,7 @@ export default class CesiumDrawing {
|
|
|
124
124
|
this.activeShapePoints = [];
|
|
125
125
|
}
|
|
126
126
|
fixLastLength(tool, length, coord) {
|
|
127
|
-
if (this.
|
|
127
|
+
if (this.fixedLineLength > 0 && tool != DrawingShape.Rectangle) {
|
|
128
128
|
const factor = tool == DrawingShape.Square ? Math.SQRT2 / 2 : 1;
|
|
129
129
|
const pointCarto = new EllipsoidGeodesic(Cartographic.fromCartesian(coord[coord.length - 2]), Cartographic.fromCartesian(coord[coord.length - 1])).interpolateUsingSurfaceDistance(length * factor);
|
|
130
130
|
coord[coord.length - 1] = Cartographic.toCartesian(pointCarto);
|
|
@@ -140,7 +140,7 @@ export default class CesiumDrawing {
|
|
|
140
140
|
}
|
|
141
141
|
else {
|
|
142
142
|
this.activeShapePoints[this.activeShapePoints.length - 1] = newPosition;
|
|
143
|
-
this.fixLastLength(tool, this.
|
|
143
|
+
this.fixLastLength(tool, this.fixedLineLength, this.activeShapePoints);
|
|
144
144
|
}
|
|
145
145
|
this.activeShapes.forEach((e) => this.entities.remove(e));
|
|
146
146
|
this.activeShapes = this.getShapes(tool, this.activeShapePoints, new DrawingFeature(tool, this.drawingState, this.config.drawing));
|
|
@@ -7,11 +7,11 @@ export default class DrawingComponentMobile extends DrawingComponent {
|
|
|
7
7
|
return uHtml `<style>
|
|
8
8
|
*{font-family:Arial,sans-serif}.hidden{display:none!important}.gg-rotate90{transform:rotate(90deg)}.gg-rotate180{transform:rotate(180deg)}.gg-rotate270{transform:rotate(270deg)}img{filter:var(--svg-filter)}img.legend-image{filter:var(--svg-map-filter);background:var(--svg-legend-bkg)}div{scrollbar-width:thin}a,a:visited{color:var(--link-color)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spin-wait{0%{transform:rotate(0)}7%{transform:rotate(360deg)}to{transform:rotate(360deg)}}.gg-spin{animation-name:spin;animation-duration:2s;animation-timing-function:linear;animation-iteration-count:infinite}.gg-spin-wait{animation-name:spin-wait;animation-duration:10s;animation-timing-function:linear;animation-iteration-count:infinite}::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:#999}.gg-button,.gg-select,.gg-input,.gg-textarea{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);box-sizing:border-box;cursor:pointer;border-radius:3px;outline:0;margin:0;padding:0 0 0 .5rem;display:inline-block}.gg-label{background-color:var(--bkg-color);color:var(--text-color);border:none;align-items:center;margin:0;padding:0;display:flex}.gg-button,.gg-select,.gg-input,.gg-label{min-height:calc(var(--app-standard-height)/1.5)}.gg-textarea{max-height:initial;resize:vertical;height:6rem;padding:.5rem;line-height:1.3rem}.gg-input{cursor:text}.gg-checkbox{accent-color:var(--text-color);width:1.2rem}.gg-range{accent-color:var(--text-color)}.gg-button{padding:0 .5rem}.gg-button.active{border:solid 1px var(--text-color-grad2);background-color:var(--text-color-grad2);color:var(--bkg-color)}.gg-button:disabled{color:gray;cursor:not-allowed;background-color:#d3d3d3;border:none}.gg-input:disabled,.gg-select:disabled,.gg-textarea:disabled{color:gray;cursor:not-allowed;background-color:#d3d3d3}.gg-button>img{vertical-align:middle}.gg-icon-button{color:var(--text-color);cursor:pointer;background-color:#0000;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:flex}.gg-icon{justify-content:center;align-items:center;display:flex}.gg-big,.gg-big-withtext{min-width:var(--app-standard-height);min-height:var(--app-standard-height);max-height:var(--app-standard-height)}.gg-big img,.gg-big-withtext img{width:calc(var(--app-standard-height) - 1.5rem);margin:0}.gg-big-withtext span{font-variant:small-caps;padding:0 1rem;font-size:.9rem}.gg-medium,.gg-medium-withtext{min-width:calc(var(--app-standard-height)/1.2);min-height:calc(var(--app-standard-height)/1.2);max-height:calc(var(--app-standard-height)/1.2);flex-direction:row}.gg-medium img{width:calc(var(--app-standard-height)/2.4);margin:0}.gg-medium-withtext img{width:calc(var(--app-standard-height)/2.4);margin-left:.5rem}.gg-medium-withtext span{padding:0 1rem 0 .5rem;font-size:.9rem}.gg-small,.gg-small-withtext{min-width:calc(var(--app-standard-height)/2);min-height:calc(var(--app-standard-height)/2);max-height:calc(var(--app-standard-height)/2);flex-direction:row}.gg-small img{width:calc(var(--app-standard-height)/3);margin:0}.gg-small-withtext img{width:calc(var(--app-standard-height)/3);margin-left:.5rem}.gg-small-withtext span{padding:0 .5rem 0 .3rem;font-size:.9rem}.gg-button:hover,.gg-select:hover,.gg-input:hover,.gg-textarea:hover,.gg-icon-button:hover{background-color:var(--bkg-color-grad1)}.gg-opacity{opacity:.5}.gg-opacity:hover{opacity:1;background-color:#0000}.gg-tabs{cursor:pointer;grid-auto-flow:column;padding-bottom:1rem;font-size:1rem;display:grid}.gg-tab{border:none;border-bottom:var(--app-standard-border);cursor:pointer;color:var(--text-color);background:0 0;padding:.5rem}.gg-tab.active{border-bottom:solid 1px var(--text-color)}.girafe-button-big,.girafe-button-large,.girafe-button-small,.girafe-button-tiny{color:var(--text-color);background-color:#0000;border:none;flex-direction:column;display:flex}.girafe-button-big:hover,.girafe-button-large:hover,.girafe-button-small:hover,.girafe-button-tiny:hover{background-color:var(--bkg-color-grad1);cursor:pointer}.girafe-button-big.dark,.girafe-button-large.dark,.girafe-button-small.dark,.girafe-button-tiny.dark{background-color:var(--bkg-color);filter:invert()}.girafe-button-big{width:var(--app-standard-height);height:var(--app-standard-height);align-items:center;padding:1rem}.girafe-button-big img{overflow:hidden}.girafe-button-large{flex-direction:row}.girafe-button-large img{height:2rem;margin:.3rem}.girafe-button-large span{height:2rem;margin:.3rem;line-height:2rem}.girafe-button-small{min-width:calc(var(--app-standard-height)/2);height:calc(var(--app-standard-height)/2);align-items:center;padding:.5rem}.girafe-button-small img{overflow:hidden}.girafe-button-small span{text-align:left;text-overflow:ellipsis;width:100%;overflow:hidden}.girafe-button-tiny{align-items:center;width:1rem;height:1rem;padding:0}.girafe-button-tiny img{overflow:hidden}.girafe-onboarding-theme{background-color:var(--bkg-color)!important;color:var(--text-color)!important}.girafe-onboarding-theme button{background-color:var(--bkg-color)!important;color:var(--text-color)!important;text-shadow:none!important}.girafe-onboarding-theme button.driver-popover-close-btn{z-index:10000}
|
|
9
9
|
</style><style>
|
|
10
|
-
input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var(--bkg-color-input);padding-right:0}input:focus{border:1px solid var(--lt-color-gray-900)}button{border:solid 1px var(--bkg-color);color:var(--text-color);background-color:var(--bkg-color);cursor:pointer;padding:0}button:hover{border:solid 1px var(--text-color-grad2)}button.selected{border:solid 1px var(--text-color-grad2);background-color:var(--bkg-color-grad1);color:var(--bkg-color)}#toolbar{flex-wrap:wrap;display:flex}.label-container{flex-grow:1}.text-end{text-align:end}.icon{width:1.2rem;height:1.2rem;fill:var(--text-color);flex-shrink:0;margin:3px}.icon:hover{fill:var(--text-color-grad2)}.gg-icon-button:hover{border:none}.colorPicker{border:1px solid var(--text-color);border-radius:5px}.picker_wrapper{transform:translate(-250px)}.picker_arrow{transform:translate(200px)rotate(90deg)scaleX(-1)!important}.picker_wrapper,.picker_arrow:after,.picker_arrow:before{background-color:var(--bkg-color)!important}.picker_wrapper,.picker_arrow:before{box-shadow:0 0 10px 1px var(--text-color-grad1)!important}button:disabled,input:disabled,.disabled{pointer-events:none;opacity:.5}fieldset.field-wrapper{border:0;margin:0;padding:0}#panel{height:100%;color:var(--text-color);flex-direction:column;display:flex}#panel>div{padding:1rem}.
|
|
10
|
+
input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var(--bkg-color-input);padding-right:0}input:focus{border:1px solid var(--lt-color-gray-900)}button{border:solid 1px var(--bkg-color);color:var(--text-color);background-color:var(--bkg-color);cursor:pointer;padding:0}button:hover{border:solid 1px var(--text-color-grad2)}button.selected{border:solid 1px var(--text-color-grad2);background-color:var(--bkg-color-grad1);color:var(--bkg-color)}#toolbar{flex-wrap:wrap;display:flex}.label-container{flex-grow:1}.text-end{text-align:end}.icon{width:1.2rem;height:1.2rem;fill:var(--text-color);flex-shrink:0;margin:3px}.icon:hover{fill:var(--text-color-grad2)}.gg-icon-button:hover{border:none}.colorPicker{border:1px solid var(--text-color);border-radius:5px}.picker_wrapper{transform:translate(-250px)}.picker_arrow{transform:translate(200px)rotate(90deg)scaleX(-1)!important}.picker_wrapper,.picker_arrow:after,.picker_arrow:before{background-color:var(--bkg-color)!important}.picker_wrapper,.picker_arrow:before{box-shadow:0 0 10px 1px var(--text-color-grad1)!important}button:disabled,input:disabled,.disabled{pointer-events:none;opacity:.5}fieldset.field-wrapper{border:0;margin:0;padding:0}#panel{height:100%;color:var(--text-color);flex-direction:column;display:flex}#panel>div{padding:1rem}#toolParametersContainer{& .title{margin-top:.5rem;margin-bottom:.75rem;display:inline-block}}.toolParameters{flex-direction:column;justify-content:left;row-gap:.25rem;display:flex}.toolParameters>label{padding:0 5px}#drawingListContainer{flex-grow:1;overflow:hidden auto;padding-top:0!important;& .titleContainer{margin-bottom:1rem;display:flex;& .title{flex-grow:1;align-items:center;display:flex}}}#drawingList{flex-flow:column;gap:.15rem;display:flex}#drawingList .girafe{border:solid 1px var(--text-color);flex-wrap:wrap;align-items:center;padding:.3rem;display:flex;position:relative}#drawingList .girafe span{flex-grow:1;padding-left:5px}#options{box-shadow:0px -2px 3px -1px var(--text-color-grad1);z-index:100;flex-direction:column;display:flex;position:relative}#optionsTitle{text-align:center;margin-bottom:20px;font-size:1.2rem}#options hr{width:100%;margin:8px 0}#optionsTextLines,#optionsColorLine,#optionsLineLines{align-items:center;display:grid}#optionsText{margin:auto}#optionsTextLines{grid-template-columns:2fr 2fr 1fr 4em 1fr 1fr}#optionsTextLines button:hover{border:none}#optionsColor,#optionsLine,#optionsExport,#optionsArrow{margin:auto}#optionsColorLine{display:flex}#optionsColorLine>div{align-items:center;width:100%;display:flex}#optionsLineLines,#optionsArrowStyle{grid-template-columns:3fr 4em 1fr auto}#optionsExportLine{grid-template-columns:60px 60px 45px 45px;gap:.2rem;display:flex}
|
|
11
11
|
</style><style>
|
|
12
12
|
button.selected{background-color:#daebff!important;border:1px solid #54a4ff!important}#toolbar{box-sizing:border-box;grid-template-columns:repeat(5,1fr);gap:20px;width:100%;display:grid}#toolbar>button{box-sizing:border-box;filter:drop-shadow(0 4px 7px #0004382c);background-color:#fff;border-radius:8px;padding:10px}#toolbar>button>img{opacity:.7;width:100%}.icon{width:1.5rem;height:1.5rem}.gg-icon-button:hover{background-color:#0000}#panel{font-size:1.5em}#drawingList{gap:10px}#drawingList .girafe{filter:drop-shadow(0 4px 7px #0004381c);background:#fff;border:none;border-radius:8px;padding:10px}#optionsTitle{text-align:center;filter:drop-shadow(0 4px 7px #0004381c);color:#4553ff;border-radius:8px;width:100%;margin-bottom:20px;padding:10px;font-size:1.6rem}.gg-input:hover{filter:drop-shadow(0 4px 7px #4c58ff70);background-color:#fff}#optionsColorLine{flex-direction:column;display:flex}#optionsColorLine>div{text-align:end;width:100%}.selectable-label{font-size:1.3em}#optionsNameFontSize,#optionsMeasuresFontSize,#optionsStrokeWidth,#line-style,#arrow-style,#arrow-position{text-align:right;border:1px solid #e3e3e3;padding:1px;font-size:1em}.popup.popup_top{translate:15px -15px}#optionsExportLine{display:none}
|
|
13
13
|
</style>
|
|
14
|
-
<link rel="stylesheet" href="lib/vanilla-picker/vanilla-picker.csp.css"><link rel="stylesheet" href="styles/girafecolorpicker.css"><div id="panel"><div><div id="toolbar"><button id="disable" tip="Disable drawing" class="gg-icon-button gg-medium"><img alt="select icon" src="icons/arrow.svg"></button> <button id="point" tip="Point" class="gg-icon-button gg-medium"><img alt="point icon" src="icons/point.svg"></button> <button id="line" tip="Line" class="gg-icon-button gg-medium"><img alt="polyline icon" src="icons/polyline.svg"></button> <button id="polygon" tip="Polygon" class="gg-icon-button gg-medium"><img alt="polygon icon" src="icons/polygon.svg"></button> <button id="square" tip="Square" class="gg-icon-button gg-medium"><img alt="square icon" src="icons/square.svg"></button> <button id="rectangle" tip="Rectangle" class="gg-icon-button gg-medium"><img alt="rectangle icon" src="icons/rectangle.svg"></button> <button id="circle" tip="Circle" class="gg-icon-button gg-medium"><img alt="circle icon" src="icons/circle.svg"></button> <button id="freeline" tip="Freehand line" class="gg-icon-button gg-medium"><img alt="polyline-free icon" src="icons/polyline-free.svg"></button> <button id="freepolygon" tip="Freehand polygon" class="gg-icon-button gg-medium"><img alt="polygon-free icon" src="icons/polygon-free.svg"></button></div><div
|
|
14
|
+
<link rel="stylesheet" href="lib/vanilla-picker/vanilla-picker.csp.css"><link rel="stylesheet" href="styles/girafecolorpicker.css"><div id="panel"><div><div id="toolbar"><button id="disable" tip="Disable drawing" class="gg-icon-button gg-medium"><img alt="select icon" src="icons/arrow.svg"></button> <button id="point" tip="Point" class="gg-icon-button gg-medium"><img alt="point icon" src="icons/point.svg"></button> <button id="line" tip="Line" class="gg-icon-button gg-medium"><img alt="polyline icon" src="icons/polyline.svg"></button> <button id="polygon" tip="Polygon" class="gg-icon-button gg-medium"><img alt="polygon icon" src="icons/polygon.svg"></button> <button id="square" tip="Square" class="gg-icon-button gg-medium"><img alt="square icon" src="icons/square.svg"></button> <button id="rectangle" tip="Rectangle" class="gg-icon-button gg-medium"><img alt="rectangle icon" src="icons/rectangle.svg"></button> <button id="circle" tip="Circle" class="gg-icon-button gg-medium"><img alt="circle icon" src="icons/circle.svg"></button> <button id="freeline" tip="Freehand line" class="gg-icon-button gg-medium"><img alt="polyline-free icon" src="icons/polyline-free.svg"></button> <button id="freepolygon" tip="Freehand polygon" class="gg-icon-button gg-medium"><img alt="polygon-free icon" src="icons/polygon-free.svg"></button></div><div id="toolParametersContainer"><span i18n="Settings" class="title"></span><div class="toolParameters" data-tool="Polyline,Polygon"><girafe-fixed-dimension dimensionname="length" dimension="length" id="fixedLineLength" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Square"><girafe-fixed-dimension dimensionname="side length" dimension="side" id="fixedSquareSide" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Rectangle"><girafe-fixed-dimension dimensionname="width" dimension="width" id="fixedRectangleWidth" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension><girafe-fixed-dimension dimensionname="height" dimension="height" id="fixedRectangleHeight" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div></div></div><div id="drawingListContainer"><div class="titleContainer"><span i18n="Drawing List" class="title"></span> <button class="gg-icon-button icon" tip="Delete all shapes" onclick="${() => this.deleteAllFeatures()}" ?disabled="${this.drawingState.features.length === 0}">${this.htmlUnsafe(this.trashIcon)}</button></div><div id="drawingList">${this.drawingState.features.map(feature => uHtmlFor(feature, feature.id) `<div id="${'f-' + feature.id}" class="girafe"><button id="${'f-select-' + feature.id}" class="gg-icon-button gg-small" tip="Select to change appearance" onclick="${() => this.onToggleFeatureSelection(feature)}"><div class="icon">${this.htmlUnsafe(feature.selected ? this.checkedIcon : this.noCheckedIcon)}</div></button><div class="label-container"><button class="${feature.selected ? 'selectable-label gg-icon-button gg-small gg-selected' : 'selectable-label gg-icon-button gg-small gg-opacity'}" onclick="${() => this.onToggleFeatureSelection(feature)}"><span id="${'f-name-' + feature.id}">${feature.name}</span></button></div><button class="gg-icon-button icon" tip="Center on shape" onclick="${() => this.olDrawing.centerViewOnFeature(feature)}">${this.htmlUnsafe(this.locateIcon)}</button> <button class="gg-icon-button icon" tip="Delete shape" onclick="${() => this.deleteFeature(feature)}">${this.htmlUnsafe(this.trashIcon)}</button></div>`)}</div></div><div id="options" class="${this.selectedFeatures.length > 0 ? '' : 'disabled'}"><fieldset class="field-wrapper" disabled="${this.selectedFeatures.length <= 0}"><input id="optionsTitle" value="${this.getOptionsTitle()}" class="gg-input" disabled="${this.selectedFeatures.length > 1}"><div id="optionsText"><div id="optionsTextLines"><span i18n="Name">Name</span> <button class="gg-icon-button icon" id="visibleIconName" tip="Show or hide shape name" onclick="${() => this.toggleNameVisibility()}">${this.htmlUnsafe(this.isDisplayNameEnabled() ? this.visibleIcon : this.notVisibleIcon)}</button> <span i18n="Font">Font</span> <input id="optionsNameFontSize" class="gg-input" type="number" min="1" value="${this.selectedFeatures[0]?.nameFontSize}" oninput="${() => this.onOptionsChange()}"> <span>pt</span> <button class="icon colorPicker" id="nameColorPicker"></button> <span i18n="Measures">Measures</span> <button class="gg-icon-button icon" id="visibleIconMeasure" tip="Show or hide measure information" onclick="${() => this.toggleMeasureVisibility()}">${this.htmlUnsafe(this.isDisplayMeasureEnabled() ? this.visibleIcon : this.notVisibleIcon)}</button> <span i18n="Font">Font</span> <input id="optionsMeasuresFontSize" class="gg-input" type="number" min="1" value="${this.selectedFeatures[0]?.measureFontSize}" oninput="${() => this.onOptionsChange()}"> <span>pt</span> <button class="icon colorPicker" id="measureColorPicker"></button></div></div><hr><div id="optionsColor"><div id="optionsColorLine"><div><span class="text-end" i18n="Stroke color">Stroke color</span> <button class="icon colorPicker" id="strokePicker"></button></div><div><span class="${this.isFillColorEnabled() ? 'text-end' : 'text-end disabled'}" id="fillPickerSpan" i18n="Fill color">Fill color</span> <button class="icon colorPicker" disabled="${!this.isFillColorEnabled()}" id="fillPicker"></button></div></div></div><hr><div id="optionsLine"><div id="optionsLineLines"><span i18n="Line width">Line width</span> <input id="optionsStrokeWidth" type="number" class="gg-input" min="1" value="${this.selectedFeatures[0]?.strokeWidth}" oninput="${() => this.onOptionsChange()}"> <span>px</span> <select id="line-style" class="gg-select" onchange="${() => this.onOptionsChange()}">${Object.entries(this.lineStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.lineStroke === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsArrow"><div class="${this.isLineStyleEnabled() ? '' : 'disabled'}" id="optionsArrowStyles"><span i18n="Arrows style">Arrows style</span> <select id="arrow-style" class="gg-select" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowStyle === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select> <select id="arrow-position" class="gg-select" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowPositions).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowPosition === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsExport"><div id="optionsExportLine"><label for="export" class="gg-label" i18n="Export">Export</label> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('geojson')}">GeoJson</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('kml')}">KML</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('gpx')}">GPX</button></div></div></fieldset></div></div>`;
|
|
15
15
|
};
|
|
16
16
|
constructor() {
|
|
17
17
|
super('drawing-mobile');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Color } from 'vanilla-picker';
|
|
2
|
-
import DrawingFeature, {
|
|
2
|
+
import DrawingFeature, { ArrowPosition, ArrowStyle, DrawingShape, DrawingState } from './drawingFeature.js';
|
|
3
3
|
import OlDrawing from './olDrawing.js';
|
|
4
4
|
import CesiumDrawing from './cesiumDrawing.js';
|
|
5
5
|
import GirafeHTMLElement from '../../base/GirafeHTMLElement.js';
|
|
@@ -42,24 +42,25 @@ export default class DrawingComponent extends GirafeHTMLElement implements IGira
|
|
|
42
42
|
unregisterEvents(): void;
|
|
43
43
|
addColorPicker(id: string, set: (c: Color) => unknown, get: () => string): void;
|
|
44
44
|
setTool(tool?: DrawingShape | null): void;
|
|
45
|
-
|
|
45
|
+
showToolParameters(tool?: DrawingShape | null): void;
|
|
46
|
+
protected fixedDimensionValueChangedHandler(e: CustomEvent): void;
|
|
46
47
|
protected connectedCallback(): void;
|
|
47
48
|
togglePanel(visible: boolean): void;
|
|
48
49
|
get selectedFeatures(): DrawingFeature[];
|
|
49
50
|
deselectAllFeatures(): void;
|
|
50
51
|
onFeaturesChanged(oldFeatures: DrawingFeature[], newFeatures: DrawingFeature[]): void;
|
|
51
52
|
onProjectionChanged(oldProj: string, newProj: string): void;
|
|
52
|
-
onToggleBatchMode(): void;
|
|
53
|
-
onToggleFixedLength(): void;
|
|
53
|
+
protected onToggleBatchMode(): void;
|
|
54
54
|
onToggleFeatureSelection(feature: DrawingFeature): void;
|
|
55
55
|
activateLayerInTreeAndMap(layerName?: string): void;
|
|
56
56
|
deactivateLayerInTreeAnMap(): void;
|
|
57
|
-
getOptionsTitle(): string;
|
|
58
|
-
isDisplayNameEnabled(): boolean;
|
|
59
|
-
isDisplayMeasureEnabled(): boolean;
|
|
60
|
-
isLineStyleEnabled(): boolean;
|
|
61
|
-
isFillColorEnabled(): boolean;
|
|
57
|
+
protected getOptionsTitle(): string;
|
|
58
|
+
protected isDisplayNameEnabled(): boolean;
|
|
59
|
+
protected isDisplayMeasureEnabled(): boolean;
|
|
60
|
+
protected isLineStyleEnabled(): boolean;
|
|
61
|
+
protected isFillColorEnabled(): boolean;
|
|
62
62
|
deleteFeature(feature: DrawingFeature): Promise<void>;
|
|
63
|
+
deleteAllFeatures(): Promise<void>;
|
|
63
64
|
onOptionsChange(): void;
|
|
64
65
|
onArrowsChange(): void;
|
|
65
66
|
toggleNameVisibility(): void;
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
1
7
|
import { htmlFor as uHtmlFor } from 'uhtml/keyed';
|
|
2
8
|
import { html as uHtml } from 'uhtml';
|
|
3
9
|
import { v4 as uuidv4 } from 'uuid';
|
|
4
10
|
import DrawingFeature, { DrawingShape } from './drawingFeature.js';
|
|
5
11
|
import OlDrawing from './olDrawing.js';
|
|
6
12
|
import CesiumDrawing from './cesiumDrawing.js';
|
|
7
|
-
import {
|
|
13
|
+
import { GeoJSON, GPX, KML } from 'ol/format.js';
|
|
8
14
|
import { Polygon } from 'ol/geom.js';
|
|
9
15
|
import Feature from 'ol/Feature.js';
|
|
10
16
|
import GirafeHTMLElement from '../../base/GirafeHTMLElement.js';
|
|
@@ -18,14 +24,15 @@ import locateIcon from './assets/locate.svg?raw';
|
|
|
18
24
|
import visibleIcon from './assets/visible.svg?raw';
|
|
19
25
|
import notVisibleIcon from './assets/notVisible.svg?raw';
|
|
20
26
|
import LayerDrawing from '../../models/layers/layerdrawing.js';
|
|
27
|
+
import { UsedInTemplateOnly } from '../../decorators.js';
|
|
21
28
|
export default class DrawingComponent extends GirafeHTMLElement {
|
|
22
29
|
template = () => {
|
|
23
30
|
return uHtml `<style>
|
|
24
31
|
*{font-family:Arial,sans-serif}.hidden{display:none!important}.gg-rotate90{transform:rotate(90deg)}.gg-rotate180{transform:rotate(180deg)}.gg-rotate270{transform:rotate(270deg)}img{filter:var(--svg-filter)}img.legend-image{filter:var(--svg-map-filter);background:var(--svg-legend-bkg)}div{scrollbar-width:thin}a,a:visited{color:var(--link-color)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spin-wait{0%{transform:rotate(0)}7%{transform:rotate(360deg)}to{transform:rotate(360deg)}}.gg-spin{animation-name:spin;animation-duration:2s;animation-timing-function:linear;animation-iteration-count:infinite}.gg-spin-wait{animation-name:spin-wait;animation-duration:10s;animation-timing-function:linear;animation-iteration-count:infinite}::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:#999}.gg-button,.gg-select,.gg-input,.gg-textarea{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);box-sizing:border-box;cursor:pointer;border-radius:3px;outline:0;margin:0;padding:0 0 0 .5rem;display:inline-block}.gg-label{background-color:var(--bkg-color);color:var(--text-color);border:none;align-items:center;margin:0;padding:0;display:flex}.gg-button,.gg-select,.gg-input,.gg-label{min-height:calc(var(--app-standard-height)/1.5)}.gg-textarea{max-height:initial;resize:vertical;height:6rem;padding:.5rem;line-height:1.3rem}.gg-input{cursor:text}.gg-checkbox{accent-color:var(--text-color);width:1.2rem}.gg-range{accent-color:var(--text-color)}.gg-button{padding:0 .5rem}.gg-button.active{border:solid 1px var(--text-color-grad2);background-color:var(--text-color-grad2);color:var(--bkg-color)}.gg-button:disabled{color:gray;cursor:not-allowed;background-color:#d3d3d3;border:none}.gg-input:disabled,.gg-select:disabled,.gg-textarea:disabled{color:gray;cursor:not-allowed;background-color:#d3d3d3}.gg-button>img{vertical-align:middle}.gg-icon-button{color:var(--text-color);cursor:pointer;background-color:#0000;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:flex}.gg-icon{justify-content:center;align-items:center;display:flex}.gg-big,.gg-big-withtext{min-width:var(--app-standard-height);min-height:var(--app-standard-height);max-height:var(--app-standard-height)}.gg-big img,.gg-big-withtext img{width:calc(var(--app-standard-height) - 1.5rem);margin:0}.gg-big-withtext span{font-variant:small-caps;padding:0 1rem;font-size:.9rem}.gg-medium,.gg-medium-withtext{min-width:calc(var(--app-standard-height)/1.2);min-height:calc(var(--app-standard-height)/1.2);max-height:calc(var(--app-standard-height)/1.2);flex-direction:row}.gg-medium img{width:calc(var(--app-standard-height)/2.4);margin:0}.gg-medium-withtext img{width:calc(var(--app-standard-height)/2.4);margin-left:.5rem}.gg-medium-withtext span{padding:0 1rem 0 .5rem;font-size:.9rem}.gg-small,.gg-small-withtext{min-width:calc(var(--app-standard-height)/2);min-height:calc(var(--app-standard-height)/2);max-height:calc(var(--app-standard-height)/2);flex-direction:row}.gg-small img{width:calc(var(--app-standard-height)/3);margin:0}.gg-small-withtext img{width:calc(var(--app-standard-height)/3);margin-left:.5rem}.gg-small-withtext span{padding:0 .5rem 0 .3rem;font-size:.9rem}.gg-button:hover,.gg-select:hover,.gg-input:hover,.gg-textarea:hover,.gg-icon-button:hover{background-color:var(--bkg-color-grad1)}.gg-opacity{opacity:.5}.gg-opacity:hover{opacity:1;background-color:#0000}.gg-tabs{cursor:pointer;grid-auto-flow:column;padding-bottom:1rem;font-size:1rem;display:grid}.gg-tab{border:none;border-bottom:var(--app-standard-border);cursor:pointer;color:var(--text-color);background:0 0;padding:.5rem}.gg-tab.active{border-bottom:solid 1px var(--text-color)}.girafe-button-big,.girafe-button-large,.girafe-button-small,.girafe-button-tiny{color:var(--text-color);background-color:#0000;border:none;flex-direction:column;display:flex}.girafe-button-big:hover,.girafe-button-large:hover,.girafe-button-small:hover,.girafe-button-tiny:hover{background-color:var(--bkg-color-grad1);cursor:pointer}.girafe-button-big.dark,.girafe-button-large.dark,.girafe-button-small.dark,.girafe-button-tiny.dark{background-color:var(--bkg-color);filter:invert()}.girafe-button-big{width:var(--app-standard-height);height:var(--app-standard-height);align-items:center;padding:1rem}.girafe-button-big img{overflow:hidden}.girafe-button-large{flex-direction:row}.girafe-button-large img{height:2rem;margin:.3rem}.girafe-button-large span{height:2rem;margin:.3rem;line-height:2rem}.girafe-button-small{min-width:calc(var(--app-standard-height)/2);height:calc(var(--app-standard-height)/2);align-items:center;padding:.5rem}.girafe-button-small img{overflow:hidden}.girafe-button-small span{text-align:left;text-overflow:ellipsis;width:100%;overflow:hidden}.girafe-button-tiny{align-items:center;width:1rem;height:1rem;padding:0}.girafe-button-tiny img{overflow:hidden}.girafe-onboarding-theme{background-color:var(--bkg-color)!important;color:var(--text-color)!important}.girafe-onboarding-theme button{background-color:var(--bkg-color)!important;color:var(--text-color)!important;text-shadow:none!important}.girafe-onboarding-theme button.driver-popover-close-btn{z-index:10000}
|
|
25
32
|
</style><style>
|
|
26
|
-
input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var(--bkg-color-input);padding-right:0}input:focus{border:1px solid var(--lt-color-gray-900)}button{border:solid 1px var(--bkg-color);color:var(--text-color);background-color:var(--bkg-color);cursor:pointer;padding:0}button:hover{border:solid 1px var(--text-color-grad2)}button.selected{border:solid 1px var(--text-color-grad2);background-color:var(--bkg-color-grad1);color:var(--bkg-color)}#toolbar{flex-wrap:wrap;display:flex}.label-container{flex-grow:1}.text-end{text-align:end}.icon{width:1.2rem;height:1.2rem;fill:var(--text-color);flex-shrink:0;margin:3px}.icon:hover{fill:var(--text-color-grad2)}.gg-icon-button:hover{border:none}.colorPicker{border:1px solid var(--text-color);border-radius:5px}.picker_wrapper{transform:translate(-250px)}.picker_arrow{transform:translate(200px)rotate(90deg)scaleX(-1)!important}.picker_wrapper,.picker_arrow:after,.picker_arrow:before{background-color:var(--bkg-color)!important}.picker_wrapper,.picker_arrow:before{box-shadow:0 0 10px 1px var(--text-color-grad1)!important}button:disabled,input:disabled,.disabled{pointer-events:none;opacity:.5}fieldset.field-wrapper{border:0;margin:0;padding:0}#panel{height:100%;color:var(--text-color);flex-direction:column;display:flex}#panel>div{padding:1rem}.
|
|
33
|
+
input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var(--bkg-color-input);padding-right:0}input:focus{border:1px solid var(--lt-color-gray-900)}button{border:solid 1px var(--bkg-color);color:var(--text-color);background-color:var(--bkg-color);cursor:pointer;padding:0}button:hover{border:solid 1px var(--text-color-grad2)}button.selected{border:solid 1px var(--text-color-grad2);background-color:var(--bkg-color-grad1);color:var(--bkg-color)}#toolbar{flex-wrap:wrap;display:flex}.label-container{flex-grow:1}.text-end{text-align:end}.icon{width:1.2rem;height:1.2rem;fill:var(--text-color);flex-shrink:0;margin:3px}.icon:hover{fill:var(--text-color-grad2)}.gg-icon-button:hover{border:none}.colorPicker{border:1px solid var(--text-color);border-radius:5px}.picker_wrapper{transform:translate(-250px)}.picker_arrow{transform:translate(200px)rotate(90deg)scaleX(-1)!important}.picker_wrapper,.picker_arrow:after,.picker_arrow:before{background-color:var(--bkg-color)!important}.picker_wrapper,.picker_arrow:before{box-shadow:0 0 10px 1px var(--text-color-grad1)!important}button:disabled,input:disabled,.disabled{pointer-events:none;opacity:.5}fieldset.field-wrapper{border:0;margin:0;padding:0}#panel{height:100%;color:var(--text-color);flex-direction:column;display:flex}#panel>div{padding:1rem}#toolParametersContainer{& .title{margin-top:.5rem;margin-bottom:.75rem;display:inline-block}}.toolParameters{flex-direction:column;justify-content:left;row-gap:.25rem;display:flex}.toolParameters>label{padding:0 5px}#drawingListContainer{flex-grow:1;overflow:hidden auto;padding-top:0!important;& .titleContainer{margin-bottom:1rem;display:flex;& .title{flex-grow:1;align-items:center;display:flex}}}#drawingList{flex-flow:column;gap:.15rem;display:flex}#drawingList .girafe{border:solid 1px var(--text-color);flex-wrap:wrap;align-items:center;padding:.3rem;display:flex;position:relative}#drawingList .girafe span{flex-grow:1;padding-left:5px}#options{box-shadow:0px -2px 3px -1px var(--text-color-grad1);z-index:100;flex-direction:column;display:flex;position:relative}#optionsTitle{text-align:center;margin-bottom:20px;font-size:1.2rem}#options hr{width:100%;margin:8px 0}#optionsTextLines,#optionsColorLine,#optionsLineLines{align-items:center;display:grid}#optionsText{margin:auto}#optionsTextLines{grid-template-columns:2fr 2fr 1fr 4em 1fr 1fr}#optionsTextLines button:hover{border:none}#optionsColor,#optionsLine,#optionsExport,#optionsArrow{margin:auto}#optionsColorLine{display:flex}#optionsColorLine>div{align-items:center;width:100%;display:flex}#optionsLineLines,#optionsArrowStyle{grid-template-columns:3fr 4em 1fr auto}#optionsExportLine{grid-template-columns:60px 60px 45px 45px;gap:.2rem;display:flex}
|
|
27
34
|
</style>
|
|
28
|
-
<link rel="stylesheet" href="lib/vanilla-picker/vanilla-picker.csp.css"><link rel="stylesheet" href="styles/girafecolorpicker.css"><div id="panel"><div><div id="toolbar"><button id="disable" tip="Disable drawing" class="gg-icon-button gg-medium"><img alt="select icon" src="icons/arrow.svg"></button> <button id="point" tip="Point" class="gg-icon-button gg-medium"><img alt="point icon" src="icons/point.svg"></button> <button id="line" tip="Line" class="gg-icon-button gg-medium"><img alt="polyline icon" src="icons/polyline.svg"></button> <button id="polygon" tip="Polygon" class="gg-icon-button gg-medium"><img alt="polygon icon" src="icons/polygon.svg"></button> <button id="square" tip="Square" class="gg-icon-button gg-medium"><img alt="square icon" src="icons/square.svg"></button> <button id="rectangle" tip="Rectangle" class="gg-icon-button gg-medium"><img alt="rectangle icon" src="icons/rectangle.svg"></button> <button id="circle" tip="Circle" class="gg-icon-button gg-medium"><img alt="circle icon" src="icons/circle.svg"></button> <button id="freeline" tip="Freehand line" class="gg-icon-button gg-medium"><img alt="polyline-free icon" src="icons/polyline-free.svg"></button> <button id="freepolygon" tip="Freehand polygon" class="gg-icon-button gg-medium"><img alt="polygon-free icon" src="icons/polygon-free.svg"></button></div><div
|
|
35
|
+
<link rel="stylesheet" href="lib/vanilla-picker/vanilla-picker.csp.css"><link rel="stylesheet" href="styles/girafecolorpicker.css"><div id="panel"><div><div id="toolbar"><button id="disable" tip="Disable drawing" class="gg-icon-button gg-medium"><img alt="select icon" src="icons/arrow.svg"></button> <button id="point" tip="Point" class="gg-icon-button gg-medium"><img alt="point icon" src="icons/point.svg"></button> <button id="line" tip="Line" class="gg-icon-button gg-medium"><img alt="polyline icon" src="icons/polyline.svg"></button> <button id="polygon" tip="Polygon" class="gg-icon-button gg-medium"><img alt="polygon icon" src="icons/polygon.svg"></button> <button id="square" tip="Square" class="gg-icon-button gg-medium"><img alt="square icon" src="icons/square.svg"></button> <button id="rectangle" tip="Rectangle" class="gg-icon-button gg-medium"><img alt="rectangle icon" src="icons/rectangle.svg"></button> <button id="circle" tip="Circle" class="gg-icon-button gg-medium"><img alt="circle icon" src="icons/circle.svg"></button> <button id="freeline" tip="Freehand line" class="gg-icon-button gg-medium"><img alt="polyline-free icon" src="icons/polyline-free.svg"></button> <button id="freepolygon" tip="Freehand polygon" class="gg-icon-button gg-medium"><img alt="polygon-free icon" src="icons/polygon-free.svg"></button></div><div id="toolParametersContainer"><span i18n="Settings" class="title"></span><div class="toolParameters" data-tool="Polyline,Polygon"><girafe-fixed-dimension dimensionname="length" dimension="length" id="fixedLineLength" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Square"><girafe-fixed-dimension dimensionname="side length" dimension="side" id="fixedSquareSide" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Rectangle"><girafe-fixed-dimension dimensionname="width" dimension="width" id="fixedRectangleWidth" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension><girafe-fixed-dimension dimensionname="height" dimension="height" id="fixedRectangleHeight" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div></div></div><div id="drawingListContainer"><div class="titleContainer"><span i18n="Drawing List" class="title"></span> <button class="gg-icon-button icon" tip="Delete all shapes" onclick="${() => this.deleteAllFeatures()}" ?disabled="${this.drawingState.features.length === 0}">${this.htmlUnsafe(this.trashIcon)}</button></div><div id="drawingList">${this.drawingState.features.map(feature => uHtmlFor(feature, feature.id) `<div id="${'f-' + feature.id}" class="girafe"><button id="${'f-select-' + feature.id}" class="gg-icon-button gg-small" tip="Select to change appearance" onclick="${() => this.onToggleFeatureSelection(feature)}"><div class="icon">${this.htmlUnsafe(feature.selected ? this.checkedIcon : this.noCheckedIcon)}</div></button><div class="label-container"><button class="${feature.selected ? 'selectable-label gg-icon-button gg-small gg-selected' : 'selectable-label gg-icon-button gg-small gg-opacity'}" onclick="${() => this.onToggleFeatureSelection(feature)}"><span id="${'f-name-' + feature.id}">${feature.name}</span></button></div><button class="gg-icon-button icon" tip="Center on shape" onclick="${() => this.olDrawing.centerViewOnFeature(feature)}">${this.htmlUnsafe(this.locateIcon)}</button> <button class="gg-icon-button icon" tip="Delete shape" onclick="${() => this.deleteFeature(feature)}">${this.htmlUnsafe(this.trashIcon)}</button></div>`)}</div></div><div id="options" class="${this.selectedFeatures.length > 0 ? '' : 'disabled'}"><fieldset class="field-wrapper" disabled="${this.selectedFeatures.length <= 0}"><input id="optionsTitle" value="${this.getOptionsTitle()}" class="gg-input" disabled="${this.selectedFeatures.length > 1}"><div id="optionsText"><div id="optionsTextLines"><span i18n="Name">Name</span> <button class="gg-icon-button icon" id="visibleIconName" tip="Show or hide shape name" onclick="${() => this.toggleNameVisibility()}">${this.htmlUnsafe(this.isDisplayNameEnabled() ? this.visibleIcon : this.notVisibleIcon)}</button> <span i18n="Font">Font</span> <input id="optionsNameFontSize" class="gg-input" type="number" min="1" value="${this.selectedFeatures[0]?.nameFontSize}" oninput="${() => this.onOptionsChange()}"> <span>pt</span> <button class="icon colorPicker" id="nameColorPicker"></button> <span i18n="Measures">Measures</span> <button class="gg-icon-button icon" id="visibleIconMeasure" tip="Show or hide measure information" onclick="${() => this.toggleMeasureVisibility()}">${this.htmlUnsafe(this.isDisplayMeasureEnabled() ? this.visibleIcon : this.notVisibleIcon)}</button> <span i18n="Font">Font</span> <input id="optionsMeasuresFontSize" class="gg-input" type="number" min="1" value="${this.selectedFeatures[0]?.measureFontSize}" oninput="${() => this.onOptionsChange()}"> <span>pt</span> <button class="icon colorPicker" id="measureColorPicker"></button></div></div><hr><div id="optionsColor"><div id="optionsColorLine"><div><span class="text-end" i18n="Stroke color">Stroke color</span> <button class="icon colorPicker" id="strokePicker"></button></div><div><span class="${this.isFillColorEnabled() ? 'text-end' : 'text-end disabled'}" id="fillPickerSpan" i18n="Fill color">Fill color</span> <button class="icon colorPicker" disabled="${!this.isFillColorEnabled()}" id="fillPicker"></button></div></div></div><hr><div id="optionsLine"><div id="optionsLineLines"><span i18n="Line width">Line width</span> <input id="optionsStrokeWidth" type="number" class="gg-input" min="1" value="${this.selectedFeatures[0]?.strokeWidth}" oninput="${() => this.onOptionsChange()}"> <span>px</span> <select id="line-style" class="gg-select" onchange="${() => this.onOptionsChange()}">${Object.entries(this.lineStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.lineStroke === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsArrow"><div class="${this.isLineStyleEnabled() ? '' : 'disabled'}" id="optionsArrowStyles"><span i18n="Arrows style">Arrows style</span> <select id="arrow-style" class="gg-select" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowStyle === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select> <select id="arrow-position" class="gg-select" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowPositions).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowPosition === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsExport"><div id="optionsExportLine"><label for="export" class="gg-label" i18n="Export">Export</label> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('geojson')}">GeoJson</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('kml')}">KML</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('gpx')}">GPX</button></div></div></fieldset></div></div>`;
|
|
29
36
|
};
|
|
30
37
|
isPanelVisible = false;
|
|
31
38
|
panelTitle = 'drawing-panel';
|
|
@@ -111,24 +118,6 @@ input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var
|
|
|
111
118
|
this.selectedFeatures[0].name = e.target.value;
|
|
112
119
|
this.refreshRender();
|
|
113
120
|
};
|
|
114
|
-
this.getById('fixedLengthValue').oninput = (e) => {
|
|
115
|
-
const val = parseFloat(e.target.value);
|
|
116
|
-
this.olDrawing.setFixedLength(val);
|
|
117
|
-
this.cesiumDrawing.setFixedLength(val);
|
|
118
|
-
};
|
|
119
|
-
this.getById('fixedLengthEnabled').onchange = (e) => {
|
|
120
|
-
const elements = Array.from(this.shadowRoot.querySelectorAll('.fixedLengthElement'));
|
|
121
|
-
const option = e.target;
|
|
122
|
-
if (!option.disabled && option.checked) {
|
|
123
|
-
elements.forEach((e) => e.classList.remove('disabled'));
|
|
124
|
-
this.getById('fixedLengthValue').dispatchEvent(new Event('input'));
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
elements.forEach((e) => e.classList.add('disabled'));
|
|
128
|
-
this.olDrawing.setFixedLength(0);
|
|
129
|
-
this.cesiumDrawing.setFixedLength(0);
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
121
|
this.setTool();
|
|
133
122
|
}
|
|
134
123
|
this.warnWhenInWebMercator();
|
|
@@ -172,16 +161,39 @@ input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var
|
|
|
172
161
|
this.toolSelected = this.getById(this.buttons.find((x) => x.tool == tool).id);
|
|
173
162
|
this.toolSelected.classList.add('selected');
|
|
174
163
|
this.drawingState.activeTool = tool;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
164
|
+
this.showToolParameters(tool);
|
|
165
|
+
}
|
|
166
|
+
showToolParameters(tool = null) {
|
|
167
|
+
const toolName = tool ? DrawingShape[tool] : 'Pointer';
|
|
168
|
+
const toolParametersList = this.shadowRoot.querySelectorAll('.toolParameters');
|
|
169
|
+
let hasParameters = false;
|
|
170
|
+
toolParametersList.forEach((toolParameters) => {
|
|
171
|
+
const isParametersForTool = toolParameters.dataset.tool?.includes(toolName) ?? false;
|
|
172
|
+
toolParameters.style.display = isParametersForTool ? 'flex' : 'none';
|
|
173
|
+
hasParameters ||= isParametersForTool;
|
|
174
|
+
});
|
|
175
|
+
this.shadow.querySelector('#toolParametersContainer span.title').style.display = hasParameters
|
|
176
|
+
? 'inline-block'
|
|
177
|
+
: 'none';
|
|
178
|
+
}
|
|
179
|
+
fixedDimensionValueChangedHandler(e) {
|
|
180
|
+
const details = e.detail;
|
|
181
|
+
switch (details.id) {
|
|
182
|
+
case 'fixedLineLength':
|
|
183
|
+
this.olDrawing.setFixedLineLength(details.value);
|
|
184
|
+
break;
|
|
185
|
+
case 'fixedSquareSide':
|
|
186
|
+
this.olDrawing.setFixedSquareSide(details.value);
|
|
187
|
+
break;
|
|
188
|
+
case 'fixedRectangleWidth':
|
|
189
|
+
this.olDrawing.setFixedRectangleWidth(details.value);
|
|
190
|
+
break;
|
|
191
|
+
case 'fixedRectangleHeight':
|
|
192
|
+
this.olDrawing.setFixedRectangleHeight(details.value);
|
|
193
|
+
break;
|
|
194
|
+
default:
|
|
195
|
+
console.debug('Value changed for unknown Dimension with id', details.id);
|
|
196
|
+
}
|
|
185
197
|
}
|
|
186
198
|
connectedCallback() {
|
|
187
199
|
super.connectedCallback();
|
|
@@ -287,20 +299,12 @@ input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var
|
|
|
287
299
|
}
|
|
288
300
|
}
|
|
289
301
|
onToggleBatchMode() {
|
|
290
|
-
// Currently not used, will possibly be part of advanced editing/drawing tools
|
|
291
302
|
this.batchCreateMode = !this.batchCreateMode;
|
|
292
303
|
if (this.batchCreateMode) {
|
|
293
304
|
this.deselectAllFeatures();
|
|
294
305
|
}
|
|
295
306
|
this.refreshRender();
|
|
296
307
|
}
|
|
297
|
-
onToggleFixedLength() {
|
|
298
|
-
this.fixedLengthEnabled = !this.fixedLengthEnabled;
|
|
299
|
-
const val = this.fixedLengthEnabled ? parseFloat(this.getById('fixedLengthValue').value) : 0;
|
|
300
|
-
this.olDrawing.setFixedLength(val);
|
|
301
|
-
this.cesiumDrawing.setFixedLength(val);
|
|
302
|
-
this.refreshRender();
|
|
303
|
-
}
|
|
304
308
|
onToggleFeatureSelection(feature) {
|
|
305
309
|
this.setTool(null);
|
|
306
310
|
feature.selected = !feature.selected;
|
|
@@ -349,6 +353,13 @@ input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var
|
|
|
349
353
|
}
|
|
350
354
|
}
|
|
351
355
|
}
|
|
356
|
+
async deleteAllFeatures() {
|
|
357
|
+
const confirm = await window.gConfirm('Do you want to remove all features?', 'Delete Features');
|
|
358
|
+
if (confirm) {
|
|
359
|
+
this.drawingState.features = [];
|
|
360
|
+
this.refreshRender();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
352
363
|
onOptionsChange() {
|
|
353
364
|
const nameFontSize = parseInt(this.getById('optionsNameFontSize').value);
|
|
354
365
|
const measureFontSize = parseInt(this.getById('optionsMeasuresFontSize').value);
|
|
@@ -413,3 +424,24 @@ input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var
|
|
|
413
424
|
}
|
|
414
425
|
}
|
|
415
426
|
}
|
|
427
|
+
__decorate([
|
|
428
|
+
UsedInTemplateOnly()
|
|
429
|
+
], DrawingComponent.prototype, "fixedDimensionValueChangedHandler", null);
|
|
430
|
+
__decorate([
|
|
431
|
+
UsedInTemplateOnly('Currently not used, will possibly be part of advanced editing/drawing tools')
|
|
432
|
+
], DrawingComponent.prototype, "onToggleBatchMode", null);
|
|
433
|
+
__decorate([
|
|
434
|
+
UsedInTemplateOnly()
|
|
435
|
+
], DrawingComponent.prototype, "getOptionsTitle", null);
|
|
436
|
+
__decorate([
|
|
437
|
+
UsedInTemplateOnly()
|
|
438
|
+
], DrawingComponent.prototype, "isDisplayNameEnabled", null);
|
|
439
|
+
__decorate([
|
|
440
|
+
UsedInTemplateOnly()
|
|
441
|
+
], DrawingComponent.prototype, "isDisplayMeasureEnabled", null);
|
|
442
|
+
__decorate([
|
|
443
|
+
UsedInTemplateOnly()
|
|
444
|
+
], DrawingComponent.prototype, "isLineStyleEnabled", null);
|
|
445
|
+
__decorate([
|
|
446
|
+
UsedInTemplateOnly()
|
|
447
|
+
], DrawingComponent.prototype, "isFillColorEnabled", null);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Style } from 'ol/style.js';
|
|
2
2
|
import type { IBrainSerializable } from '../../tools/state/brain/decorators.js';
|
|
3
|
-
import type { Geometry } from 'ol/geom.js';
|
|
3
|
+
import type { Circle as CircleGeom, Geometry } from 'ol/geom.js';
|
|
4
4
|
import type Feature from 'ol/Feature.js';
|
|
5
5
|
import IGirafeContext from '../../tools/context/icontext.js';
|
|
6
6
|
export declare enum DrawingShape {
|
|
@@ -99,6 +99,7 @@ export default class DrawingFeature {
|
|
|
99
99
|
getLengthText(length: number): string;
|
|
100
100
|
getAreaText(area: number): string;
|
|
101
101
|
getCoordText(coord: number[]): string;
|
|
102
|
+
getAzimuthText(circle: CircleGeom): string;
|
|
102
103
|
isPointOrPolyline(): boolean;
|
|
103
104
|
getVertexStyle(activeNode?: boolean): Style;
|
|
104
105
|
static deserialize(serializedFeature: SerializedFeature, context: IGirafeContext): DrawingFeature;
|
|
@@ -3,7 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
3
3
|
import { Fill, RegularShape, Stroke, Style } from 'ol/style.js';
|
|
4
4
|
import { toRadians } from 'ol/math.js';
|
|
5
5
|
import GeoJSON from 'ol/format/GeoJSON.js';
|
|
6
|
-
import { getAreaAsMetricText, getLengthAsMetricText } from '../../tools/utils/olutils.js';
|
|
6
|
+
import { getAreaAsMetricText, getAzimuthAsText, getLengthAsMetricText } from '../../tools/utils/olutils.js';
|
|
7
7
|
export var DrawingShape;
|
|
8
8
|
(function (DrawingShape) {
|
|
9
9
|
DrawingShape[DrawingShape["Point"] = 0] = "Point";
|
|
@@ -203,6 +203,9 @@ export default class DrawingFeature {
|
|
|
203
203
|
}
|
|
204
204
|
return 'E ' + coord[0].toFixed(2) + '\nN ' + coord[1].toFixed(2);
|
|
205
205
|
}
|
|
206
|
+
getAzimuthText(circle) {
|
|
207
|
+
return getAzimuthAsText(this.displayMeasure ? circle.getProperties()['azimuth'] ?? undefined : undefined);
|
|
208
|
+
}
|
|
206
209
|
isPointOrPolyline() {
|
|
207
210
|
return (this.type === DrawingShape.Point ||
|
|
208
211
|
this.type === DrawingShape.Polyline ||
|
|
@@ -259,12 +262,17 @@ export default class DrawingFeature {
|
|
|
259
262
|
static geojsonFromOlFeature(olFeature, shapeType) {
|
|
260
263
|
if (shapeType === DrawingShape.Disk) {
|
|
261
264
|
const disk = olFeature.getGeometry();
|
|
265
|
+
const center = disk.getCenter();
|
|
266
|
+
const radius = disk.getRadius();
|
|
267
|
+
const pointer = disk.getProperties()['pointer'] ?? [center[0] + radius, center[1]];
|
|
262
268
|
return {
|
|
263
269
|
type: 'Feature',
|
|
264
270
|
geometry: {
|
|
265
271
|
type: 'Disk',
|
|
266
|
-
center:
|
|
267
|
-
radius:
|
|
272
|
+
center: center,
|
|
273
|
+
radius: radius,
|
|
274
|
+
azimuth: disk.getProperties()['azimuth'] ?? 0,
|
|
275
|
+
pointer: pointer,
|
|
268
276
|
}
|
|
269
277
|
};
|
|
270
278
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import GirafeHTMLElement from '../../../base/GirafeHTMLElement.js';
|
|
2
|
+
export type FixedDimensionValueChangedEventDetails = {
|
|
3
|
+
id: string;
|
|
4
|
+
dimension: string;
|
|
5
|
+
value: number;
|
|
6
|
+
};
|
|
7
|
+
export type DimensionUnit = {
|
|
8
|
+
name: string;
|
|
9
|
+
factor: number;
|
|
10
|
+
};
|
|
11
|
+
declare class FixedDimensionComponent extends GirafeHTMLElement {
|
|
12
|
+
static readonly observedAttributes: string[];
|
|
13
|
+
template: () => import("uhtml").Hole;
|
|
14
|
+
checkedIcon: string;
|
|
15
|
+
notCheckedIcon: string;
|
|
16
|
+
dimensionName: string;
|
|
17
|
+
dimension: string;
|
|
18
|
+
dimensionUnits: string;
|
|
19
|
+
onChange: string;
|
|
20
|
+
fixedDimensionEnabled: boolean;
|
|
21
|
+
renderedOnce: boolean;
|
|
22
|
+
lastValue: string;
|
|
23
|
+
units: DimensionUnit[];
|
|
24
|
+
unit: DimensionUnit | undefined;
|
|
25
|
+
constructor(name?: string);
|
|
26
|
+
render(): void;
|
|
27
|
+
private renderComponent;
|
|
28
|
+
protected connectedCallback(): void;
|
|
29
|
+
private refreshDimensionName;
|
|
30
|
+
private refreshDimension;
|
|
31
|
+
private refreshDimensionUnits;
|
|
32
|
+
private refreshOnChange;
|
|
33
|
+
toggleFixedDimensionEnabled(): void;
|
|
34
|
+
fixedValueChanged(e: InputEvent): void;
|
|
35
|
+
dimensionUnitChanged(e: Event): void;
|
|
36
|
+
dispatchFixedDimensionValueChangedEvent(valueAsString: string): void;
|
|
37
|
+
protected attributeChangedCallback(name: string, _oldValue: string, newValue: string): void;
|
|
38
|
+
}
|
|
39
|
+
export default FixedDimensionComponent;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html as uHtml } from 'uhtml';
|
|
8
|
+
import GirafeHTMLElement from '../../../base/GirafeHTMLElement.js';
|
|
9
|
+
import checkedIcon from '../../../assets/icons/checked-full.svg?raw';
|
|
10
|
+
import checkedNoIcon from '../../../assets/icons/checked-no.svg?raw';
|
|
11
|
+
import { UsedInTemplateOnly } from '../../../decorators.js';
|
|
12
|
+
const defaultUnits = 'm:1;km:1000';
|
|
13
|
+
class FixedDimensionComponent extends GirafeHTMLElement {
|
|
14
|
+
static observedAttributes = ['dimensionName', 'dimension', 'dimensionUnits', 'onChange'];
|
|
15
|
+
template = () => {
|
|
16
|
+
return uHtml `<style>
|
|
17
|
+
*{font-family:Arial,sans-serif}.hidden{display:none!important}.gg-rotate90{transform:rotate(90deg)}.gg-rotate180{transform:rotate(180deg)}.gg-rotate270{transform:rotate(270deg)}img{filter:var(--svg-filter)}img.legend-image{filter:var(--svg-map-filter);background:var(--svg-legend-bkg)}div{scrollbar-width:thin}a,a:visited{color:var(--link-color)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spin-wait{0%{transform:rotate(0)}7%{transform:rotate(360deg)}to{transform:rotate(360deg)}}.gg-spin{animation-name:spin;animation-duration:2s;animation-timing-function:linear;animation-iteration-count:infinite}.gg-spin-wait{animation-name:spin-wait;animation-duration:10s;animation-timing-function:linear;animation-iteration-count:infinite}::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:#999}.gg-button,.gg-select,.gg-input,.gg-textarea{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);box-sizing:border-box;cursor:pointer;border-radius:3px;outline:0;margin:0;padding:0 0 0 .5rem;display:inline-block}.gg-label{background-color:var(--bkg-color);color:var(--text-color);border:none;align-items:center;margin:0;padding:0;display:flex}.gg-button,.gg-select,.gg-input,.gg-label{min-height:calc(var(--app-standard-height)/1.5)}.gg-textarea{max-height:initial;resize:vertical;height:6rem;padding:.5rem;line-height:1.3rem}.gg-input{cursor:text}.gg-checkbox{accent-color:var(--text-color);width:1.2rem}.gg-range{accent-color:var(--text-color)}.gg-button{padding:0 .5rem}.gg-button.active{border:solid 1px var(--text-color-grad2);background-color:var(--text-color-grad2);color:var(--bkg-color)}.gg-button:disabled{color:gray;cursor:not-allowed;background-color:#d3d3d3;border:none}.gg-input:disabled,.gg-select:disabled,.gg-textarea:disabled{color:gray;cursor:not-allowed;background-color:#d3d3d3}.gg-button>img{vertical-align:middle}.gg-icon-button{color:var(--text-color);cursor:pointer;background-color:#0000;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:flex}.gg-icon{justify-content:center;align-items:center;display:flex}.gg-big,.gg-big-withtext{min-width:var(--app-standard-height);min-height:var(--app-standard-height);max-height:var(--app-standard-height)}.gg-big img,.gg-big-withtext img{width:calc(var(--app-standard-height) - 1.5rem);margin:0}.gg-big-withtext span{font-variant:small-caps;padding:0 1rem;font-size:.9rem}.gg-medium,.gg-medium-withtext{min-width:calc(var(--app-standard-height)/1.2);min-height:calc(var(--app-standard-height)/1.2);max-height:calc(var(--app-standard-height)/1.2);flex-direction:row}.gg-medium img{width:calc(var(--app-standard-height)/2.4);margin:0}.gg-medium-withtext img{width:calc(var(--app-standard-height)/2.4);margin-left:.5rem}.gg-medium-withtext span{padding:0 1rem 0 .5rem;font-size:.9rem}.gg-small,.gg-small-withtext{min-width:calc(var(--app-standard-height)/2);min-height:calc(var(--app-standard-height)/2);max-height:calc(var(--app-standard-height)/2);flex-direction:row}.gg-small img{width:calc(var(--app-standard-height)/3);margin:0}.gg-small-withtext img{width:calc(var(--app-standard-height)/3);margin-left:.5rem}.gg-small-withtext span{padding:0 .5rem 0 .3rem;font-size:.9rem}.gg-button:hover,.gg-select:hover,.gg-input:hover,.gg-textarea:hover,.gg-icon-button:hover{background-color:var(--bkg-color-grad1)}.gg-opacity{opacity:.5}.gg-opacity:hover{opacity:1;background-color:#0000}.gg-tabs{cursor:pointer;grid-auto-flow:column;padding-bottom:1rem;font-size:1rem;display:grid}.gg-tab{border:none;border-bottom:var(--app-standard-border);cursor:pointer;color:var(--text-color);background:0 0;padding:.5rem}.gg-tab.active{border-bottom:solid 1px var(--text-color)}.girafe-button-big,.girafe-button-large,.girafe-button-small,.girafe-button-tiny{color:var(--text-color);background-color:#0000;border:none;flex-direction:column;display:flex}.girafe-button-big:hover,.girafe-button-large:hover,.girafe-button-small:hover,.girafe-button-tiny:hover{background-color:var(--bkg-color-grad1);cursor:pointer}.girafe-button-big.dark,.girafe-button-large.dark,.girafe-button-small.dark,.girafe-button-tiny.dark{background-color:var(--bkg-color);filter:invert()}.girafe-button-big{width:var(--app-standard-height);height:var(--app-standard-height);align-items:center;padding:1rem}.girafe-button-big img{overflow:hidden}.girafe-button-large{flex-direction:row}.girafe-button-large img{height:2rem;margin:.3rem}.girafe-button-large span{height:2rem;margin:.3rem;line-height:2rem}.girafe-button-small{min-width:calc(var(--app-standard-height)/2);height:calc(var(--app-standard-height)/2);align-items:center;padding:.5rem}.girafe-button-small img{overflow:hidden}.girafe-button-small span{text-align:left;text-overflow:ellipsis;width:100%;overflow:hidden}.girafe-button-tiny{align-items:center;width:1rem;height:1rem;padding:0}.girafe-button-tiny img{overflow:hidden}.girafe-onboarding-theme{background-color:var(--bkg-color)!important;color:var(--text-color)!important}.girafe-onboarding-theme button{background-color:var(--bkg-color)!important;color:var(--text-color)!important;text-shadow:none!important}.girafe-onboarding-theme button.driver-popover-close-btn{z-index:10000}
|
|
18
|
+
</style><style>
|
|
19
|
+
:host{grid-template-columns:auto auto 60px auto;justify-content:left;align-items:center;display:grid}input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var(--bkg-color-input);padding-right:0}input:focus{border:1px solid var(--lt-color-gray-900)}button{border:solid 1px var(--bkg-color);color:var(--text-color);background-color:var(--bkg-color);cursor:pointer;padding:0}button:hover{border:solid 1px var(--text-color-grad2)}button.selected{border:solid 1px var(--text-color-grad2);background-color:var(--bkg-color-grad1);color:var(--bkg-color)}.icon{width:1.2rem;height:1.2rem;fill:var(--text-color);flex-shrink:0;margin:3px}.icon:hover{fill:var(--text-color-grad2)}.gg-icon-button:hover{border:none}button:disabled,input:disabled,.disabled{pointer-events:none;opacity:.5}label.gg-label{padding:0 5px!important;&.disabled{pointer-events:revert}}
|
|
20
|
+
</style>
|
|
21
|
+
<button class="gg-icon-button icon" onclick="${() => this.toggleFixedDimensionEnabled()}">${this.htmlUnsafe(this.fixedDimensionEnabled ? this.checkedIcon : this.notCheckedIcon)}</button> <label class="${this.fixedDimensionEnabled ? 'gg-label' : 'gg-label disabled'}" onclick="${() => this.toggleFixedDimensionEnabled()}" onkeyup="${() => this.toggleFixedDimensionEnabled()}" for="fixedValue" i18n="${'Fix ' + this.dimensionName + ' to'}"></label> <input class="gg-input" disabled="${!this.fixedDimensionEnabled}" oninput="${(e) => this.fixedValueChanged(e)}" type="number" id="fixedValue"> <select id="dimensionUnits" class="gg-select" disabled="${!this.fixedDimensionEnabled}" onchange="${(e) => this.dimensionUnitChanged(e)}">${this.units.map((unit) => uHtml `<option ?selected="${this.unit?.name === unit.name}" value="${unit.factor}">${unit.name}</option>`)}</select>`;
|
|
22
|
+
};
|
|
23
|
+
checkedIcon = checkedIcon;
|
|
24
|
+
notCheckedIcon = checkedNoIcon;
|
|
25
|
+
dimensionName = 'dimension';
|
|
26
|
+
dimension = 'dimension';
|
|
27
|
+
dimensionUnits = defaultUnits;
|
|
28
|
+
onChange = '';
|
|
29
|
+
fixedDimensionEnabled = false;
|
|
30
|
+
renderedOnce = false;
|
|
31
|
+
lastValue = '0';
|
|
32
|
+
units = [];
|
|
33
|
+
unit = undefined;
|
|
34
|
+
constructor(name = 'fixed-dimension') {
|
|
35
|
+
super(name);
|
|
36
|
+
this.displayStyle = 'grid';
|
|
37
|
+
}
|
|
38
|
+
render() {
|
|
39
|
+
super.render();
|
|
40
|
+
this.refreshDimensionName();
|
|
41
|
+
this.refreshDimension();
|
|
42
|
+
this.refreshDimensionUnits();
|
|
43
|
+
this.refreshOnChange();
|
|
44
|
+
this.renderComponent();
|
|
45
|
+
super.girafeTranslate();
|
|
46
|
+
}
|
|
47
|
+
renderComponent() {
|
|
48
|
+
this.show();
|
|
49
|
+
if (!this.renderedOnce) {
|
|
50
|
+
this.renderedOnce = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
connectedCallback() {
|
|
54
|
+
super.connectedCallback();
|
|
55
|
+
this.render();
|
|
56
|
+
}
|
|
57
|
+
refreshDimensionName() {
|
|
58
|
+
this.dimensionName = this.getAttribute('dimensionName') ?? 'dimension';
|
|
59
|
+
this.refreshRender();
|
|
60
|
+
}
|
|
61
|
+
refreshDimension() {
|
|
62
|
+
this.dimension = this.getAttribute('dimension') ?? 'dimension';
|
|
63
|
+
}
|
|
64
|
+
refreshDimensionUnits(dimensionUnits = defaultUnits) {
|
|
65
|
+
console.log(`Refreshing dimension units for ${this.dimension} with units ${dimensionUnits}`);
|
|
66
|
+
this.dimensionUnits = dimensionUnits ?? this.getAttribute('dimensionUnits') ?? defaultUnits;
|
|
67
|
+
this.units = this.dimensionUnits.split(';').map((unit) => {
|
|
68
|
+
const [name, factor] = unit.split(':');
|
|
69
|
+
return { name, factor: Number.parseFloat(factor) };
|
|
70
|
+
});
|
|
71
|
+
this.unit = this.units[0];
|
|
72
|
+
this.refreshRender();
|
|
73
|
+
}
|
|
74
|
+
refreshOnChange() {
|
|
75
|
+
this.onChange = this.getAttribute('onChange') ?? '';
|
|
76
|
+
console.log(`Refreshing onChange for ${this.dimension} with onChange ${this.onChange}`);
|
|
77
|
+
}
|
|
78
|
+
toggleFixedDimensionEnabled() {
|
|
79
|
+
this.fixedDimensionEnabled = !this.fixedDimensionEnabled;
|
|
80
|
+
this.dispatchFixedDimensionValueChangedEvent(this.fixedDimensionEnabled ? this.lastValue : '0');
|
|
81
|
+
this.refreshRender();
|
|
82
|
+
}
|
|
83
|
+
fixedValueChanged(e) {
|
|
84
|
+
this.lastValue = e.target.value;
|
|
85
|
+
this.dispatchFixedDimensionValueChangedEvent(this.lastValue);
|
|
86
|
+
this.htmlUnsafe(this.onChange);
|
|
87
|
+
}
|
|
88
|
+
dimensionUnitChanged(e) {
|
|
89
|
+
const selectedUnitFactor = Number.parseFloat(e.target.value);
|
|
90
|
+
this.unit = this.units.find((unit) => unit.factor == selectedUnitFactor);
|
|
91
|
+
this.dispatchFixedDimensionValueChangedEvent(this.lastValue);
|
|
92
|
+
}
|
|
93
|
+
dispatchFixedDimensionValueChangedEvent(valueAsString) {
|
|
94
|
+
const value = Number.parseFloat(valueAsString);
|
|
95
|
+
this.dispatchEvent(new CustomEvent('fixed-dimension:value-changed', {
|
|
96
|
+
bubbles: true,
|
|
97
|
+
cancelable: true,
|
|
98
|
+
detail: {
|
|
99
|
+
id: this.id,
|
|
100
|
+
dimension: this.dimension,
|
|
101
|
+
value: value * (this.unit?.factor ?? 1)
|
|
102
|
+
}
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
attributeChangedCallback(name, _oldValue, newValue) {
|
|
106
|
+
if (name === 'dimensionName') {
|
|
107
|
+
this.dimensionName = newValue;
|
|
108
|
+
}
|
|
109
|
+
else if (name === 'dimension') {
|
|
110
|
+
this.dimension = newValue;
|
|
111
|
+
}
|
|
112
|
+
else if (name === 'dimensionUnits') {
|
|
113
|
+
this.refreshDimensionUnits(newValue);
|
|
114
|
+
}
|
|
115
|
+
else if (name === 'onChange') {
|
|
116
|
+
this.onChange = newValue;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
__decorate([
|
|
121
|
+
UsedInTemplateOnly('attributeChangedCallback is not used in this component, but it is required by the HTMLElement interface.')
|
|
122
|
+
], FixedDimensionComponent.prototype, "attributeChangedCallback", null);
|
|
123
|
+
export default FixedDimensionComponent;
|
|
@@ -24,7 +24,10 @@ export default class OlDrawing {
|
|
|
24
24
|
snap: Snap | null;
|
|
25
25
|
editContextMenu: ContextMenu | null;
|
|
26
26
|
currentShape: DrawingShape | null;
|
|
27
|
-
|
|
27
|
+
fixedLineLength: number;
|
|
28
|
+
fixedSquareSide: number;
|
|
29
|
+
fixedRectangleWidth: number;
|
|
30
|
+
fixedRectangleHeight: number;
|
|
28
31
|
drawingSource: VectorSource;
|
|
29
32
|
drawingLayer: VectorLayer;
|
|
30
33
|
lastClosestFeature: Feature | null;
|
|
@@ -97,11 +100,15 @@ export default class OlDrawing {
|
|
|
97
100
|
private getOlFeatureFromDrawingSource;
|
|
98
101
|
private isOlFeatureInState;
|
|
99
102
|
createOlFeature(dFeature: DrawingFeature): Feature<Geometry>;
|
|
100
|
-
|
|
103
|
+
setFixedLineLength(length: number): void;
|
|
104
|
+
setFixedSquareSide(length: number): void;
|
|
105
|
+
setFixedRectangleWidth(width: number): void;
|
|
106
|
+
setFixedRectangleHeight(height: number): void;
|
|
101
107
|
createLineStringFixedLength(coordinates: SketchCoordType, geom: SimpleGeometry): SimpleGeometry;
|
|
102
108
|
createSquareFixedLength(coordinates: SketchCoordType, geom: SimpleGeometry, proj: Projection): SimpleGeometry;
|
|
103
109
|
createPolygonFixedLength(coordinates: SketchCoordType, geom: SimpleGeometry): SimpleGeometry;
|
|
104
110
|
createDiskFixedLength(coordinates: SketchCoordType, geom: SimpleGeometry): SimpleGeometry;
|
|
111
|
+
createRectangleFixedSides(coordinates: SketchCoordType, geom: SimpleGeometry, proj: Projection): SimpleGeometry;
|
|
105
112
|
addDrawInteraction(tool: DrawingShape): void;
|
|
106
113
|
centerViewOnFeature(drawingFeature: DrawingFeature): void;
|
|
107
114
|
getStyle(dFeature: DrawingFeature, olFeature: Feature<Geometry>): Style[];
|
|
@@ -59,7 +59,10 @@ export default class OlDrawing {
|
|
|
59
59
|
snap = null;
|
|
60
60
|
editContextMenu = null;
|
|
61
61
|
currentShape = null;
|
|
62
|
-
|
|
62
|
+
fixedLineLength = 0;
|
|
63
|
+
fixedSquareSide = 0;
|
|
64
|
+
fixedRectangleWidth = 0;
|
|
65
|
+
fixedRectangleHeight = 0;
|
|
63
66
|
drawingSource;
|
|
64
67
|
drawingLayer;
|
|
65
68
|
lastClosestFeature = null;
|
|
@@ -138,6 +141,25 @@ export default class OlDrawing {
|
|
|
138
141
|
pixelTolerance: this.map.pixelTolerance
|
|
139
142
|
});
|
|
140
143
|
this.map.olMap.addInteraction(this.modify);
|
|
144
|
+
this.modify.on('modifystart', (e) => {
|
|
145
|
+
e.features.forEach((olFeature) => {
|
|
146
|
+
olFeature.on('change', (e) => {
|
|
147
|
+
const geometry = e.target.getGeometry();
|
|
148
|
+
if (geometry && geometry.getType() == 'Circle') {
|
|
149
|
+
const circle = geometry;
|
|
150
|
+
const newRadius = circle.getRadius();
|
|
151
|
+
const properties = circle.getProperties();
|
|
152
|
+
const { pointer } = properties;
|
|
153
|
+
const oldRadiusLine = new LineString([circle.getCenter(), pointer]);
|
|
154
|
+
oldRadiusLine.scale(newRadius / oldRadiusLine.getLength());
|
|
155
|
+
circle.setProperties({
|
|
156
|
+
...properties,
|
|
157
|
+
pointer: oldRadiusLine.getLastCoordinate()
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
});
|
|
141
163
|
// Update the modified geometries in the state
|
|
142
164
|
this.modify.on('modifyend', (e) => {
|
|
143
165
|
e.features.forEach((olFeature) => this.updateGeometryInState(olFeature)); //NOSONAR(typescript:S7728) Collection<?> is a custom Implementation with custom forEach
|
|
@@ -434,7 +456,12 @@ export default class OlDrawing {
|
|
|
434
456
|
const geometry = dFeature.geojson.geometry;
|
|
435
457
|
let olFeature;
|
|
436
458
|
if (geometry.type == 'Disk') {
|
|
437
|
-
|
|
459
|
+
const geom = new CircleGeom(geometry.center, geometry.radius);
|
|
460
|
+
geom.setProperties({
|
|
461
|
+
azimuth: geometry.azimuth,
|
|
462
|
+
pointer: geometry.pointer
|
|
463
|
+
});
|
|
464
|
+
olFeature = new Feature(geom);
|
|
438
465
|
}
|
|
439
466
|
else {
|
|
440
467
|
olFeature = new Feature(new GeoJSON().readFeatures(dFeature.geojson)[0].getGeometry());
|
|
@@ -443,33 +470,91 @@ export default class OlDrawing {
|
|
|
443
470
|
olFeature.setStyle((f) => this.getStyle(dFeature, f));
|
|
444
471
|
return olFeature;
|
|
445
472
|
}
|
|
446
|
-
|
|
447
|
-
this.
|
|
473
|
+
setFixedLineLength(length) {
|
|
474
|
+
this.fixedLineLength = Number.isNaN(length) ? 0 : length;
|
|
475
|
+
}
|
|
476
|
+
setFixedSquareSide(length) {
|
|
477
|
+
this.fixedSquareSide = Number.isNaN(length) ? 0 : length;
|
|
478
|
+
}
|
|
479
|
+
setFixedRectangleWidth(width) {
|
|
480
|
+
this.fixedRectangleWidth = Number.isNaN(width) ? 0 : width;
|
|
481
|
+
}
|
|
482
|
+
setFixedRectangleHeight(height) {
|
|
483
|
+
this.fixedRectangleHeight = Number.isNaN(height) ? 0 : height;
|
|
448
484
|
}
|
|
449
485
|
createLineStringFixedLength(coordinates, geom) {
|
|
450
|
-
this.fixLastLength(this.
|
|
486
|
+
this.fixLastLength(this.fixedLineLength, coordinates);
|
|
451
487
|
geom = geom ?? new LineString(coordinates);
|
|
452
488
|
geom.setCoordinates(coordinates);
|
|
453
489
|
return geom;
|
|
454
490
|
}
|
|
455
491
|
createSquareFixedLength(coordinates, geom, proj) {
|
|
456
|
-
this.fixLastLength(this.
|
|
457
|
-
|
|
492
|
+
this.fixLastLength(this.fixedSquareSide, coordinates, Math.SQRT2);
|
|
493
|
+
const poly = createRegularPolygon(4)(coordinates, geom, proj);
|
|
494
|
+
console.log('createSquareFixedLength ' + JSON.stringify(poly.getCoordinates()));
|
|
495
|
+
return poly;
|
|
458
496
|
}
|
|
459
497
|
createPolygonFixedLength(coordinates, geom) {
|
|
460
498
|
const coord = coordinates[0];
|
|
461
|
-
this.fixLastLength(this.
|
|
499
|
+
this.fixLastLength(this.fixedLineLength, coord);
|
|
462
500
|
geom = geom ?? new Polygon([coord]);
|
|
463
501
|
geom.setCoordinates([coord]);
|
|
464
502
|
return geom;
|
|
465
503
|
}
|
|
466
504
|
createDiskFixedLength(coordinates, geom) {
|
|
467
505
|
const coord = coordinates;
|
|
468
|
-
this.fixLastLength(this.
|
|
506
|
+
this.fixLastLength(this.fixedLineLength, coord);
|
|
469
507
|
geom = geom ?? new CircleGeom(coord[0], getDistance(coord, this.state.projection));
|
|
470
508
|
geom.setCenterAndRadius(coord[0], getDistance(coord, this.state.projection));
|
|
509
|
+
geom.setProperties({
|
|
510
|
+
azimuth: ((90 - (Math.atan2(coord[1][1] - coord[0][1], coord[1][0] - coord[0][0]) * (180 / Math.PI)) + 360) % 360),
|
|
511
|
+
pointer: coord[1]
|
|
512
|
+
});
|
|
471
513
|
return geom;
|
|
472
514
|
}
|
|
515
|
+
createRectangleFixedSides(coordinates, geom, proj) {
|
|
516
|
+
if (coordinates.length < 2) {
|
|
517
|
+
geom = geom ?? createBox()(coordinates, geom, proj);
|
|
518
|
+
return geom;
|
|
519
|
+
}
|
|
520
|
+
// If no fixed dimensions are set, behave like the normal box drawing.
|
|
521
|
+
if (this.fixedRectangleWidth <= 0 && this.fixedRectangleHeight <= 0) {
|
|
522
|
+
geom = geom ?? createBox()(coordinates, geom, proj);
|
|
523
|
+
return createBox()(coordinates, geom, proj);
|
|
524
|
+
}
|
|
525
|
+
const coords = coordinates;
|
|
526
|
+
const start = coords[0];
|
|
527
|
+
const pointer = coords[1];
|
|
528
|
+
// Decide in which quadrant the user is dragging.
|
|
529
|
+
const signX = pointer[0] >= start[0] ? 1 : -1;
|
|
530
|
+
const signY = pointer[1] >= start[1] ? 1 : -1;
|
|
531
|
+
// Convert "meters" (or whatever your getDistance returns) to map units along X and Y.
|
|
532
|
+
const xUnit = [start[0] + 1, start[1]];
|
|
533
|
+
const yUnit = [start[0], start[1] + 1];
|
|
534
|
+
const metersPerMapUnitX = getDistance([start, xUnit], this.state.projection);
|
|
535
|
+
const metersPerMapUnitY = getDistance([start, yUnit], this.state.projection);
|
|
536
|
+
// Guard against division by 0 in weird edge cases.
|
|
537
|
+
if (metersPerMapUnitX <= 0 || metersPerMapUnitY <= 0) {
|
|
538
|
+
geom = geom ?? createBox()(coordinates, geom, proj);
|
|
539
|
+
return createBox()(coordinates, geom, proj);
|
|
540
|
+
}
|
|
541
|
+
const dxMapUnits = (this.fixedRectangleWidth / metersPerMapUnitX) * signX;
|
|
542
|
+
const dyMapUnits = (this.fixedRectangleHeight / metersPerMapUnitY) * signY;
|
|
543
|
+
if (dxMapUnits != 0 && dyMapUnits != 0) {
|
|
544
|
+
// Overwrite width and height
|
|
545
|
+
coords[1] = [start[0] + dxMapUnits, start[1] + dyMapUnits];
|
|
546
|
+
}
|
|
547
|
+
else if (dxMapUnits != 0) {
|
|
548
|
+
// Overwrite only width
|
|
549
|
+
coords[1] = [start[0] + dxMapUnits, pointer[1]];
|
|
550
|
+
}
|
|
551
|
+
else if (dyMapUnits != 0) {
|
|
552
|
+
// Overwrite only height
|
|
553
|
+
coords[1] = [pointer[0], start[1] + dyMapUnits];
|
|
554
|
+
}
|
|
555
|
+
geom = geom ?? createBox()(coords, geom, proj);
|
|
556
|
+
return createBox()(coords, geom, proj);
|
|
557
|
+
}
|
|
473
558
|
addDrawInteraction(tool) {
|
|
474
559
|
this.removeDrawInteraction();
|
|
475
560
|
// Block feature selection while drawing by registering 'map.select' exclusively
|
|
@@ -499,7 +584,7 @@ export default class OlDrawing {
|
|
|
499
584
|
break;
|
|
500
585
|
case DrawingShape.Rectangle:
|
|
501
586
|
olTool = 'Circle';
|
|
502
|
-
geomFunction =
|
|
587
|
+
geomFunction = this.createRectangleFixedSides.bind(this);
|
|
503
588
|
break;
|
|
504
589
|
case DrawingShape.FreehandPolyline:
|
|
505
590
|
olTool = 'LineString';
|
|
@@ -661,12 +746,13 @@ export default class OlDrawing {
|
|
|
661
746
|
addLabel(polygon.getInteriorPoint(), dFeature.getAreaText(getAreaOfPolygon(polygon, this.state.projection)));
|
|
662
747
|
}
|
|
663
748
|
else if (dFeature.type == DrawingShape.Disk) {
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
radiusDataForCircle.style
|
|
749
|
+
if (dFeature.displayMeasure) {
|
|
750
|
+
const radiusDataForCircle = getRadiusDataForCircle(geometry, defaultStyle, new Stroke({ color: measureColor, width: dFeature.strokeWidth }));
|
|
751
|
+
styles.push(radiusDataForCircle.style);
|
|
752
|
+
const lengthText = dFeature.getLengthText(radiusDataForCircle.radius);
|
|
753
|
+
const azimuthText = dFeature.getAzimuthText(geometry);
|
|
754
|
+
addLabel(getHalfPoint(radiusDataForCircle.radiusLine), `${lengthText}, ${azimuthText}`);
|
|
667
755
|
}
|
|
668
|
-
styles.push(radiusDataForCircle.style);
|
|
669
|
-
addLabel(getHalfPoint(radiusDataForCircle.radiusLine), dFeature.getLengthText(radiusDataForCircle.radius));
|
|
670
756
|
}
|
|
671
757
|
else if (dFeature.type == DrawingShape.FreehandPolygon) {
|
|
672
758
|
const polygon = geometry;
|
package/components/main.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export { default as CrossSectionViewComponent } from './cross-section/cross-sect
|
|
|
12
12
|
export { default as DisplayMenuButtonMobile } from './displaymenubutton-mobile/component.js';
|
|
13
13
|
export { default as DisplaySelectorButtonMobile } from './displayselectorbutton-mobile/component.js';
|
|
14
14
|
export { default as DrawingComponent } from './drawing/component.js';
|
|
15
|
+
export type { FixedDimensionValueChangedEventDetails, DimensionUnit } from './drawing/fixed-dimension/component.js';
|
|
16
|
+
export { default as FixedDimensionComponent } from './drawing/fixed-dimension/component.js';
|
|
15
17
|
export { default as DrawingContainerMobile } from './drawing-container-mobile/component.js';
|
|
16
18
|
export { default as EditComponent } from './edit/component.js';
|
|
17
19
|
export { default as EditFromComponent } from './edit/editform/component.js';
|
package/components/main.js
CHANGED
|
@@ -12,6 +12,7 @@ export { default as CrossSectionViewComponent } from './cross-section/cross-sect
|
|
|
12
12
|
export { default as DisplayMenuButtonMobile } from './displaymenubutton-mobile/component.js';
|
|
13
13
|
export { default as DisplaySelectorButtonMobile } from './displayselectorbutton-mobile/component.js';
|
|
14
14
|
export { default as DrawingComponent } from './drawing/component.js';
|
|
15
|
+
export { default as FixedDimensionComponent } from './drawing/fixed-dimension/component.js';
|
|
15
16
|
export { default as DrawingContainerMobile } from './drawing-container-mobile/component.js';
|
|
16
17
|
export { default as EditComponent } from './edit/component.js';
|
|
17
18
|
export { default as EditFromComponent } from './edit/editform/component.js';
|
package/decorators.d.ts
ADDED
package/decorators.js
ADDED
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.1.0-dev.
|
|
1
|
+
{"version":"1.1.0-dev.2438378072", "build":"2438378072", "date":"08/04/2026"}
|
|
@@ -47,6 +47,7 @@ import { DrawingState } from '../../components/drawing/drawingFeature.js';
|
|
|
47
47
|
import DrawingSerializer from '../../components/drawing/drawingSerializer.js';
|
|
48
48
|
import { ShareState, ShareStateSerializer } from '../../components/share/sharestate.js';
|
|
49
49
|
import SelectionToolComponent from '../../components/selectiontool/component.js';
|
|
50
|
+
import FixedDimensionComponent from '../../components/drawing/fixed-dimension/component.js';
|
|
50
51
|
export default class GeoGirafeApp {
|
|
51
52
|
readyPromise;
|
|
52
53
|
resolveReady;
|
|
@@ -138,6 +139,7 @@ export default class GeoGirafeApp {
|
|
|
138
139
|
customElements.define('girafe-tree-view-theme', TreeViewThemeComponent);
|
|
139
140
|
customElements.define('girafe-user-preferences', UserPreferencesComponent);
|
|
140
141
|
customElements.define('girafe-video-record', VideoRecordComponent);
|
|
142
|
+
customElements.define('girafe-fixed-dimension', FixedDimensionComponent);
|
|
141
143
|
}
|
|
142
144
|
async initializeServiceWorker() {
|
|
143
145
|
try {
|
package/tools/main.d.ts
CHANGED
|
@@ -106,7 +106,7 @@ export { default as UserDataManager } from './userdata/userdatamanager.js';
|
|
|
106
106
|
export { default as ColumnAliasHelper } from './utils/aliases.js';
|
|
107
107
|
export { debounce } from './utils/debounce.js';
|
|
108
108
|
export { default as GirafeColorPicker } from './utils/girafecolorpicker.js';
|
|
109
|
-
export { unByKeyAll, getOlayerByName, removeUnwantedOlParams, polygonFromCircle, getDistance, getAreaOfPolygon, getAreaOfCircle, isCoordinateInDegrees, getSelectionBoxFromMapClick, reprojectGeometry, ensurePolygonIsProperlyClosed, getHalfPoint, getLabelStyle, getRadiusDataForCircle, getLengthAsMetricText, getAreaAsMetricText } from './utils/olutils.js';
|
|
109
|
+
export { unByKeyAll, getOlayerByName, removeUnwantedOlParams, polygonFromCircle, getDistance, getAreaOfPolygon, getAreaOfCircle, isCoordinateInDegrees, getSelectionBoxFromMapClick, reprojectGeometry, ensurePolygonIsProperlyClosed, getHalfPoint, getLabelStyle, getRadiusDataForCircle, getLengthAsMetricText, getAreaAsMetricText, getAzimuthAsText } from './utils/olutils.js';
|
|
110
110
|
export { getPropertyByPath, setPropertyByPath, createObjectFromPath, deletePropertyByPath, mergeObjects } from './utils/pathUtils.js';
|
|
111
111
|
export { generateQrCode } from './utils/qrcode.js';
|
|
112
112
|
export { default as ServiceWorkerHelper } from './utils/swhelper.js';
|
package/tools/main.js
CHANGED
|
@@ -81,7 +81,7 @@ export { default as UserDataManager } from './userdata/userdatamanager.js';
|
|
|
81
81
|
export { default as ColumnAliasHelper } from './utils/aliases.js';
|
|
82
82
|
export { debounce } from './utils/debounce.js';
|
|
83
83
|
export { default as GirafeColorPicker } from './utils/girafecolorpicker.js';
|
|
84
|
-
export { unByKeyAll, getOlayerByName, removeUnwantedOlParams, polygonFromCircle, getDistance, getAreaOfPolygon, getAreaOfCircle, isCoordinateInDegrees, getSelectionBoxFromMapClick, reprojectGeometry, ensurePolygonIsProperlyClosed, getHalfPoint, getLabelStyle, getRadiusDataForCircle, getLengthAsMetricText, getAreaAsMetricText } from './utils/olutils.js';
|
|
84
|
+
export { unByKeyAll, getOlayerByName, removeUnwantedOlParams, polygonFromCircle, getDistance, getAreaOfPolygon, getAreaOfCircle, isCoordinateInDegrees, getSelectionBoxFromMapClick, reprojectGeometry, ensurePolygonIsProperlyClosed, getHalfPoint, getLabelStyle, getRadiusDataForCircle, getLengthAsMetricText, getAreaAsMetricText, getAzimuthAsText } from './utils/olutils.js';
|
|
85
85
|
export { getPropertyByPath, setPropertyByPath, createObjectFromPath, deletePropertyByPath, mergeObjects } from './utils/pathUtils.js';
|
|
86
86
|
export { generateQrCode } from './utils/qrcode.js';
|
|
87
87
|
export { default as ServiceWorkerHelper } from './utils/swhelper.js';
|
package/tools/utils/olutils.d.ts
CHANGED
|
@@ -48,3 +48,4 @@ export declare const getRadiusDataForCircle: (circle: Circle, defaultStyle: Styl
|
|
|
48
48
|
};
|
|
49
49
|
export declare const getLengthAsMetricText: (length?: number) => string;
|
|
50
50
|
export declare const getAreaAsMetricText: (area?: number) => string;
|
|
51
|
+
export declare const getAzimuthAsText: (azimuth?: number) => string;
|
package/tools/utils/olutils.js
CHANGED
|
@@ -148,7 +148,8 @@ export const getLabelStyle = (position, text, labelStyle) => {
|
|
|
148
148
|
export const getRadiusDataForCircle = (circle, defaultStyle, stroke) => {
|
|
149
149
|
const radius = circle.getRadius();
|
|
150
150
|
const center = circle.getCenter();
|
|
151
|
-
const
|
|
151
|
+
const pointer = circle.getProperties()['pointer'] ?? [center[0] + radius, center[1]];
|
|
152
|
+
const radiusLine = [center, pointer];
|
|
152
153
|
const radiusLineStyle = defaultStyle.clone();
|
|
153
154
|
radiusLineStyle.setStroke(stroke);
|
|
154
155
|
radiusLineStyle.getText().setText('');
|
|
@@ -173,3 +174,9 @@ export const getAreaAsMetricText = (area) => {
|
|
|
173
174
|
}
|
|
174
175
|
return '';
|
|
175
176
|
};
|
|
177
|
+
export const getAzimuthAsText = (azimuth) => {
|
|
178
|
+
if (azimuth) {
|
|
179
|
+
return `${azimuth.toFixed(0)}°`;
|
|
180
|
+
}
|
|
181
|
+
return '';
|
|
182
|
+
};
|