Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved editor control #311

Merged
merged 6 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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."
sanak marked this conversation as resolved.
Show resolved Hide resolved
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
Loading