Skip to content

Commit

Permalink
Merge pull request #311 from gtt-project/dkastl/issue310
Browse files Browse the repository at this point in the history
Improved editor control
  • Loading branch information
dkastl authored Jun 5, 2024
2 parents 9a5152b + 66b8d09 commit fee38bf
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 6 deletions.
4 changes: 4 additions & 0 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ de:
linestring: Linieneditor
polygon: Flächeneditor
clear_map: "Clear map"
remove_point: "Remove point"
geolocation_activated: Geolokalisierung aktiviert
geolocation_deactivated: Geolokalisierung deaktiviert
copied_location_to_clipboard: Standort in die Zwischenablage kopiert
Expand All @@ -81,6 +82,9 @@ de:
messages:
baselayer_missing: "Es ist kein Baselayer verfügbar!"
zoom_in_more: "Zoomen Sie hinein, um die Objekte zu sehen."
modify_start: "Hold down <code>ALT</code> and click on a vertex to delete it."
modify_start_mac: "Hold down <code>Option</code> and click on a vertex to delete it."
modify_start_touch: "Tap on a vertex to delete it."
gtt_map_rotate_label: Kartenrotation
gtt_map_rotate_info_html: Halten Sie <code>Shift+Alt</code> gedrückt und ziehen
Sie die Karte, um sie zu drehen.
Expand Down
4 changes: 4 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,14 @@ en:
linestring: "Line editor"
polygon: "Area editor"
clear_map: "Clear map"
remove_point: "Remove point"
copied_location_to_clipboard: "Copied location to clipboard"
modal:
load: "Load"
cancel: "Cancel"
messages:
baselayer_missing: "There is no baselayer available!"
zoom_in_more: "Zoom in to view objects."
modify_start: "Hold down <code>ALT</code> and click on a vertex to delete it."
modify_start_mac: "Hold down <code>Option</code> and click on a vertex to delete it."
modify_start_touch: "Tap on a vertex to delete it."
4 changes: 4 additions & 0 deletions config/locales/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,14 @@ ja:
linestring: ライン編集
polygon: エリア編集
clear_map: "地図をクリア"
remove_point: "Remove point"
copied_location_to_clipboard: 位置情報をクリップボードにコピーしました
modal:
load: 読み込み
cancel: キャンセル
messages:
baselayer_missing: "背景レイヤーが存在しません!"
zoom_in_more: "地物表示のためズームします。"
modify_start: "Hold down <code>ALT</code> and click on a vertex to delete it."
modify_start_mac: "Hold down <code>Option</code> and click on a vertex to delete it."
modify_start_touch: "Tap on a vertex to delete it."
17 changes: 17 additions & 0 deletions src/components/gtt-client/helpers/platforms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Utility function to detect touch devices
* @param isTouchDevice - boolean
* @returns boolean
*/
export const isTouchDevice = (): boolean => {
return ('ontouchstart' in window) || (navigator.maxTouchPoints > 0);
}

/**
* Utility function to detect macOS
* @param isMacOS - boolean
* @returns boolean
*/
export const isMacOS = (): boolean => {
return /Macintosh|MacIntel|MacPPC|Mac68K/.test(navigator.userAgent);
}
123 changes: 117 additions & 6 deletions src/components/gtt-client/openlayers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { Style, Fill, Stroke, Circle } from 'ol/style';
import { createEmpty, extend, containsCoordinate } from 'ol/extent';
import { transform, fromLonLat } from 'ol/proj';

import { Modify, Draw, Select } from 'ol/interaction'
import { Draw, Select, Snap } from 'ol/interaction'
import ModifyTouch from 'ol-ext/interaction/ModifyTouch';
import Bar from 'ol-ext/control/Bar';
import Button from 'ol-ext/control/Button';
import Toggle from 'ol-ext/control/Toggle';
Expand All @@ -16,12 +17,30 @@ import { position } from 'ol-ext/control/control';
import { GeoJSON } from 'ol/format';

import { getCookie, getMapSize, degreesToRadians, updateForm, formatLength, formatArea } from "../helpers";
import { isTouchDevice, isMacOS } from "../helpers/platforms";

// Define the types for the Tooltip and the custom methods you added
interface ExtendedTooltip extends Tooltip {
prevHTML?: string;
}

/**
* Helper class to manage the visibility of controls.
*/
class ControlManager {
static hide(controls: any[]) {
controls.forEach(control => {
control.element.style.display = 'none';
});
}

static show(controls: any[]) {
controls.forEach(control => {
control.element.style.display = '';
});
}
}

/**
* Get the z-value for a given geometry.
* If the geometry is a Point, return the z-coordinate of the Point.
Expand Down Expand Up @@ -156,9 +175,17 @@ function createTooltip(): ExtendedTooltip {
*/
export function setControls(types: Array<string>) {
// Make vector features editable
const modify = new Modify({
const modify = new ModifyTouch({
title: this.i18n.control.remove_point,
features: this.vector.getSource().getFeaturesCollection()
})
} as any)

modify.on('showpopup', evt => {
const geometryType = evt.feature.getGeometry().getType();
if (geometryType === 'Point') {
modify.removePoint(); // don't show the popup
}
});

modify.on('modifyend', evt => {
updateForm(this, evt.features.getArray(), true)
Expand Down Expand Up @@ -197,20 +224,43 @@ export function setControls(types: Array<string>) {
})

draw.on('drawstart', evt => {
// Change the style of existing features to light gray and transparent and dashed line
this.vector.getSource().getFeatures().forEach((feature: any) => {
feature.setStyle(new Style({
fill: new Fill({
color: 'rgba(0, 0, 0, 0.1)'
}),
stroke: new Stroke({
color: 'rgba(0, 0, 0, 0.5)',
width: 2,
lineDash: [5, 5]
})
}));
});

if (this.contents.measure) {
tooltip.setFeature(evt.feature)
}
})

draw.on('change:active', evt => {
tooltip.removeFeature()
})
// If the Draw interaction is deactivated
if (!evt.target.getActive()) {
// Reset the style of existing features
this.vector.getSource().getFeatures().forEach((feature: any) => {
feature.setStyle(null); // Reset the style to the default style
});
}

tooltip.removeFeature();
});

draw.on('drawend', evt => {
tooltip.removeFeature()
this.vector.getSource().clear()
const feature = setZValueForGeometry(evt.feature, zValue);
updateForm(this, [feature], true)
ControlManager.show([editModeControl, clearMapCtrl]);
})

// Material design icon
Expand All @@ -230,22 +280,83 @@ export function setControls(types: Array<string>) {
html: `<i class="mdi ${mdi}" ></i>`,
title: this.i18n.control[type.toLowerCase()],
interaction: draw,
active: (type === geometryType)
active: false,
onToggle: (active: boolean) => {
modify.setActive(false);
if (active) {
draw.setActive(true);
} else {
draw.setActive(false);
}
}
})
editbar.addControl(control)
})

// Add the edit control
const editModeControl = new Toggle({
html: '<i class="mdi mdi-pencil"></i>',
title: this.i18n.control.edit_mode,
active: false,
onToggle: (active: boolean) => {
if (active) {
modify.setActive(true);
this.map.getInteractions().forEach((interaction: any) => {
if (interaction instanceof Draw) {
interaction.setActive(false);
}
});

if (this.vector.getSource().getFeatures().length > 0) {
const firstFeature = this.vector.getSource().getFeatures()[0];
if (firstFeature && firstFeature.getGeometry().getType() !== 'Point') {
// Code to execute if the first feature is not a Point
let message = this.i18n.messages.modify_start;
if (isTouchDevice()) {
message = this.i18n.messages.modify_start_touch;
} else if (isMacOS()) {
message = this.i18n.messages.modify_start_mac;
}
this.map.notification.show(message);
}
}
} else {
modify.setActive(false);
}
}
});
editbar.addControl(editModeControl);

// Add the clear map control
const clearMapCtrl = new Button({
html: '<i class="mdi mdi-delete"></i>',
title: this.i18n.control.clear_map,
handleClick: () => {
this.vector.getSource().clear();
updateForm(this, null);
(editbar.getControls()[0] as Toggle).setActive(true);
ControlManager.hide([editModeControl, clearMapCtrl]);
}
});
editbar.addControl(clearMapCtrl);

// if the vector layer is not empty, set the editModeControl to active
if (this.vector.getSource().getFeatures().length > 0) {
editModeControl.setActive(true);
ControlManager.show([editModeControl, clearMapCtrl]);
}
// otherwise set the first draw control to active
else {
(editbar.getControls()[0] as Toggle).setActive(true);
ControlManager.hide([editModeControl, clearMapCtrl]);
}

// Add the snap interaction
const snap = new Snap({
source: this.vector.getSource(),
});
this.map.addInteraction(snap);

// Uses jQuery UI for GeoJSON Upload modal window
const mapObj = this
const dialog = $("#dialog-geojson-upload").dialog({
Expand Down

0 comments on commit fee38bf

Please sign in to comment.