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

Adds measure control and hover info #308

Merged
merged 8 commits into from
Jun 3, 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
3 changes: 3 additions & 0 deletions app/helpers/gtt_map_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ def map_tag(map: nil, layers: map&.layers,
data[:popup] = popup if popup
data[:upload] = upload
data[:collapsed] = collapsed if collapsed
data[:geocoding] = true if Setting.plugin_redmine_gtt['enable_geocoding_on_map'] == 'true'
data[:measure] = true if Setting.plugin_redmine_gtt['default_measure_enabled'] == 'true'
data[:target] = true if Setting.plugin_redmine_gtt['default_target_enabled'] == 'true'

uid = "ol-" + rand(36**8).to_s(36)

Expand Down
11 changes: 11 additions & 0 deletions app/views/settings/gtt/_general.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
@settings['default_map_fit_maxzoom_level'],
:size => 10) %>
</p>

</div>

<div class="box tabular settings">
Expand All @@ -66,6 +67,16 @@
<div class="box tabular settings">
<h3><%= l(:select_other_gtt_settings) %></h3>

<p>
<%= content_tag(:label, l(:label_default_target_enabled)) %>
<%= check_box_tag 'settings[default_target_enabled]', true, @settings[:default_target_enabled] %>
</p>

<p>
<%= content_tag(:label, l(:label_default_measure_enabled)) %>
<%= check_box_tag 'settings[default_measure_enabled]', true, @settings[:default_measure_enabled] %>
</p>

<p>
<%= content_tag(:label, l(:label_hide_map_for_invalid_geom)) %>
<%= check_box_tag 'settings[hide_map_for_invalid_geom]', 1, Setting.plugin_redmine_gtt['hide_map_for_invalid_geom'] %>
Expand Down
1 change: 1 addition & 0 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ de:
label_enable_geojson_upload_on_issue_map: Aktivieren von GeoJSON-Upload auf der
Themenkarte
label_enable_geocoding_on_map: Geokodierung auf der Karte aktivieren
label_default_target_enabled: "Show target on map center"
select_default_status_color: 'Auswahl der Standard-Statusfarbe:'
select_default_map_settings: 'Standardmäßige Kartenvoreinstellungen festlegen:'
select_edit_geometry_settings: 'Einstellungen für die Geometriebearbeitung:'
Expand Down
2 changes: 2 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ en:
label_editable_geometry_types_on_issue_map: "Editable geometry types on issue map"
label_enable_geojson_upload_on_issue_map: "Enable GeoJSON upload on issue map"
label_enable_geocoding_on_map: "Enable geocoding on map"
label_default_target_enabled: "Show target on map center"
label_default_measure_enabled: "Show measure control"

select_other_gtt_settings: "Other GTT settings"
label_hide_map_for_invalid_geom: "Hide issue map for invalid geometry"
Expand Down
1 change: 1 addition & 0 deletions config/locales/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ ja:
label_editable_geometry_types_on_issue_map: "チケット地図上で編集可能なジオメトリ種別"
label_enable_geojson_upload_on_issue_map: "チケット地図上でGeoJSONアップロードを有効化"
label_enable_geocoding_on_map: "地図上でジオコーディングを有効化"
label_default_target_enabled: "Show target on map center"

select_other_gtt_settings: "GTTのその他の設定"
label_hide_map_for_invalid_geom: "位置情報が登録されていない時に地図を隠す"
Expand Down
2 changes: 2 additions & 0 deletions init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
'default_map_maxzoom_level' => 19,
'default_map_fit_maxzoom_level' => 17,
'vector_minzoom_level' => 0,
'default_target_enabled' => false,
'default_measure_enabled' => false,
'default_geocoder_options' => '{}',
'editable_geometry_types_on_issue_map' => ["Point"],
'enable_geojson_upload_on_issue_map' => false,
Expand Down
27 changes: 27 additions & 0 deletions src/components/gtt-client/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,30 @@ export function parseHistory() {
});
}

/**
* Format length in meters or kilometers.
* @param length
* @returns
*/
export function formatLength(length: number): string {
if (length < 1000) {
return length.toFixed(0) + ' m';
} else {
return (length / 1000).toFixed(2) + ' km';
}
}

/**
* Format area in square meters or square kilometers.
* @param area
* @returns
*/
export function formatArea(area: number): string {
if (area < 10000) {
return area.toFixed(1) + ' m<sup>2</sup>';
} else {
return (area / 1000000).toFixed(2) + ' km<sup>2</sup>';
}
}


67 changes: 66 additions & 1 deletion src/components/gtt-client/init/controls.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { FullScreen, Rotate } from 'ol/control';
import { Style, RegularShape, Stroke } from 'ol/style';
import Bar from 'ol-ext/control/Bar';
import Button from 'ol-ext/control/Button';
import LayerPopup from 'ol-ext/control/LayerPopup';
import LayerSwitcher from 'ol-ext/control/LayerSwitcher';
import Target from 'ol-ext/control/Target';
import Hover from 'ol-ext/interaction/Hover';
import Notification from 'ol-ext/control/Notification';
import { position } from 'ol-ext/control/control';

import { radiansToDegrees, degreesToRadians, parseHistory } from "../helpers";
import { radiansToDegrees, degreesToRadians, parseHistory, formatLength, formatArea } from "../helpers";
import { zoomToExtent, setGeolocation, setView, setControls, setPopover } from "../openlayers";
import { createSearchControl } from '../geocoding/SearchFactory';

Expand Down Expand Up @@ -87,6 +90,35 @@ function addMaximizeControl(instance: any): void {
instance.toolbar.addControl(maximizeCtrl);
}

/**
* Adds hover control to provide additional information
* @param instance
*/
function addHoverControl(instance: any): void {
const hover = new Hover({
cursor: 'pointer',
handleEvent: (evt: any) => {
return true;
},
layerFilter: (layer: any) => {
// Respond only to the specific vector layer
return layer === instance.vector;
}
});

instance.map.addInteraction(hover);

// Show the length or area of the feature on hover
hover.on('enter', (evt: any) => {
const geometry = evt.feature.getGeometry();
if (geometry.getType() === 'LineString') {
instance.map.notification.show(formatLength(geometry.getLength()));
} else if (geometry.getType() === 'Polygon') {
instance.map.notification.show(formatArea(geometry.getArea()));
}
});
}

/**
* Handles the map rotation functionality.
* @param {any} instance - The GttClient instance.
Expand Down Expand Up @@ -124,6 +156,34 @@ function addLayerSwitcherOrPopup(instance: any): void {
}
}

/**
* Adds target control to instance map.
* @param instance
*/
function addTargetControl(instance: any): void {
if (instance.contents.target) {
// Adjust the radius and stroke width for high DPI devices
const pixelRatio = window.devicePixelRatio || 1;
const adjustedRadius = 11 / pixelRatio;
const adjustedStrokeWidth = 3 / pixelRatio;

instance.map.addControl(new Target({
composite: 'overlay',
style: new Style({
image: new RegularShape({
points: 4,
radius: adjustedRadius,
radius2: 0,
stroke: new Stroke({
color: 'rgba(220,26,26,0.7)',
width: adjustedStrokeWidth
})
})
}),
}));
}
}

/**
* Adds notification control
* @param {any} instance
Expand All @@ -146,6 +206,11 @@ export function initControls(this: any): void {
addFullScreenAndRotateControls(this);
addMaximizeControl(this);
handleMapRotation(this);
addTargetControl(this);

if (this.contents.measure) {
addHoverControl(this);
}

if (this.contents.edit) {
setControls.call(this, this.contents.edit.split(' '));
Expand Down
36 changes: 35 additions & 1 deletion src/components/gtt-client/openlayers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@ import Bar from 'ol-ext/control/Bar';
import Button from 'ol-ext/control/Button';
import Toggle from 'ol-ext/control/Toggle';
import Popup from 'ol-ext/overlay/Popup';
import Tooltip from 'ol-ext/overlay/Tooltip'
import { position } from 'ol-ext/control/control';
import { GeoJSON } from 'ol/format';

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

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

/**
* Get the z-value for a given geometry.
Expand Down Expand Up @@ -133,6 +139,18 @@ function setZValueForGeometry(feature: any, zValue: number): any {
return feature;
}

/**
* Create extended tooltip control
* @returns
*/
function createTooltip(): ExtendedTooltip {
return new Tooltip({
maximumFractionDigits: 2,
formatLength,
formatArea
}) as ExtendedTooltip;
}

/**
* Add editing tools
*/
Expand Down Expand Up @@ -165,6 +183,11 @@ export function setControls(types: Array<string>) {
zValue = getZValueForGeometry(ftr.getGeometry());
});

// Create tooltip
const tooltip = createTooltip();
this.map.addOverlay(tooltip);

// Add the draw controls
types.forEach((type: any, idx) => {

const draw = new Draw({
Expand All @@ -173,7 +196,18 @@ export function setControls(types: Array<string>) {
geometryLayout: 'XYZ'
})

draw.on('drawstart', evt => {
if (this.contents.measure) {
tooltip.setFeature(evt.feature)
}
})

draw.on('change:active', evt => {
tooltip.removeFeature()
})

draw.on('drawend', evt => {
tooltip.removeFeature()
this.vector.getSource().clear()
const feature = setZValueForGeometry(evt.feature, zValue);
updateForm(this, [feature], true)
Expand Down
Loading