mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
commit
1fee34b3db
12 changed files with 159 additions and 12 deletions
|
|
@ -1 +1 @@
|
|||
0.7.1
|
||||
0.8.0
|
||||
|
|
|
|||
15
CHANGELOG.md
15
CHANGELOG.md
|
|
@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [0.8.0] — 2024-06-25
|
||||
|
||||
### Added
|
||||
|
||||
- New Settings page to change Dawarich settings.
|
||||
- New "Fog of War" toggle on the map controls.
|
||||
- New "Fog of War meters" field in Settings. This field allows you to set the radius in meters around the point to be shown on the map. The map outside of this radius will be covered with a fog of war.
|
||||
|
||||
### Changed
|
||||
|
||||
- Order of points on Points page is now descending by timestamp instead of ascending.
|
||||
|
||||
---
|
||||
|
||||
## [0.7.1] — 2024-06-20
|
||||
|
||||
In new Settings page you can now change the following settings:
|
||||
|
|
@ -22,6 +36,7 @@ In new Settings page you can now change the following settings:
|
|||
- Old settings page is now available undeer Account link in user menu.
|
||||
|
||||
---
|
||||
|
||||
## [0.7.0] — 2024-06-19
|
||||
|
||||
## The GPX MVP Release
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
21
app/assets/stylesheets/fog-of-war.css
Normal file
21
app/assets/stylesheets/fog-of-war.css
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/* Ensure fog overlay is positioned relative to the map container */
|
||||
#fog {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.8); /* Adjust the opacity here */
|
||||
pointer-events: none;
|
||||
mix-blend-mode: multiply;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.unfogged-circle {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border-radius: 50%;
|
||||
background: white;
|
||||
mix-blend-mode: destination-out;
|
||||
filter: blur(3px); /* Apply no blur to the circles */
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ class MapController < ApplicationController
|
|||
def index
|
||||
@points = current_user.tracked_points.without_raw_data.where('timestamp >= ? AND timestamp <= ?', start_at, end_at).order(timestamp: :asc)
|
||||
|
||||
@countries_and_cities = Visits::Calculate.new(@points).uniq_visits
|
||||
@countries_and_cities = CountriesAndCities.new(@points).call
|
||||
@coordinates =
|
||||
@points.pluck(:latitude, :longitude, :battery, :altitude, :timestamp, :velocity, :id)
|
||||
.map { [_1.to_f, _2.to_f, _3.to_s, _4.to_s, _5.to_s, _6.to_s, _7] }
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ class PointsController < ApplicationController
|
|||
.tracked_points
|
||||
.without_raw_data
|
||||
.where(timestamp: start_at..end_at)
|
||||
.order(timestamp: :asc)
|
||||
.order(timestamp: :desc)
|
||||
.paginate(page: params[:page], per_page: 50)
|
||||
|
||||
@start_at = Time.zone.at(start_at)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ class SettingsController < ApplicationController
|
|||
private
|
||||
|
||||
def settings_params
|
||||
params.require(:settings).permit(:meters_between_routes, :minutes_between_routes)
|
||||
params.require(:settings).permit(
|
||||
:meters_between_routes, :minutes_between_routes, :fog_of_war_meters
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { Controller } from "@hotwired/stimulus";
|
|||
import L from "leaflet";
|
||||
import "leaflet.heat";
|
||||
|
||||
// Connects to data-controller="maps"
|
||||
export default class extends Controller {
|
||||
static targets = ["container"];
|
||||
|
||||
|
|
@ -13,6 +12,7 @@ export default class extends Controller {
|
|||
let center = markers[markers.length - 1] || JSON.parse(this.element.dataset.center);
|
||||
center = center === undefined ? [52.514568, 13.350111] : center;
|
||||
const timezone = this.element.dataset.timezone;
|
||||
const clearFogRadius = this.element.dataset.fog_of_war_meters;
|
||||
|
||||
const map = L.map(this.containerTarget, {
|
||||
layers: [this.osmMapLayer(), this.osmHotMapLayer()],
|
||||
|
|
@ -24,11 +24,12 @@ export default class extends Controller {
|
|||
|
||||
const polylinesLayer = this.createPolylinesLayer(markers, map, timezone);
|
||||
const heatmapLayer = L.heatLayer(heatmapMarkers, { radius: 20 }).addTo(map);
|
||||
|
||||
const fogOverlay = L.layerGroup(); // Initialize fog layer
|
||||
const controlsLayer = {
|
||||
Points: markersLayer,
|
||||
Polylines: polylinesLayer,
|
||||
Heatmap: heatmapLayer,
|
||||
"Fog of War": fogOverlay
|
||||
};
|
||||
|
||||
L.control
|
||||
|
|
@ -40,7 +41,74 @@ export default class extends Controller {
|
|||
})
|
||||
.addTo(map);
|
||||
|
||||
L.control.layers(this.baseMaps(), controlsLayer).addTo(map);
|
||||
const layerControl = L.control.layers(this.baseMaps(), controlsLayer).addTo(map);
|
||||
|
||||
let fogEnabled = false;
|
||||
|
||||
// Hide fog by default
|
||||
document.getElementById('fog').style.display = 'none';
|
||||
|
||||
// Toggle fog layer visibility
|
||||
map.on('overlayadd', function(e) {
|
||||
if (e.name === 'Fog of War') {
|
||||
fogEnabled = true;
|
||||
document.getElementById('fog').style.display = 'block';
|
||||
updateFog(markers, clearFogRadius);
|
||||
}
|
||||
});
|
||||
|
||||
map.on('overlayremove', function(e) {
|
||||
if (e.name === 'Fog of War') {
|
||||
fogEnabled = false;
|
||||
document.getElementById('fog').style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// Update fog circles on zoom and move
|
||||
map.on('zoomend moveend', function() {
|
||||
if (fogEnabled) {
|
||||
updateFog(markers, clearFogRadius);
|
||||
}
|
||||
});
|
||||
|
||||
function updateFog(markers, clearFogRadius) {
|
||||
if (fogEnabled) {
|
||||
var fog = document.getElementById('fog');
|
||||
fog.innerHTML = ''; // Clear previous circles
|
||||
markers.forEach(function(point) {
|
||||
const radiusInPixels = metersToPixels(map, clearFogRadius);
|
||||
clearFog(point[0], point[1], radiusInPixels);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function metersToPixels(map, meters) {
|
||||
const zoom = map.getZoom();
|
||||
const latLng = map.getCenter(); // Get map center for correct projection
|
||||
const metersPerPixel = getMetersPerPixel(latLng.lat, zoom);
|
||||
return meters / metersPerPixel;
|
||||
}
|
||||
|
||||
function getMetersPerPixel(latitude, zoom) {
|
||||
// Might be a total bullshit, generated by ChatGPT, but works
|
||||
const earthCircumference = 40075016.686; // Earth's circumference in meters
|
||||
const metersPerPixel = earthCircumference * Math.cos(latitude * Math.PI / 180) / Math.pow(2, zoom + 8);
|
||||
return metersPerPixel;
|
||||
}
|
||||
|
||||
function clearFog(lat, lng, radius) {
|
||||
var fog = document.getElementById('fog');
|
||||
var point = map.latLngToContainerPoint([lat, lng]);
|
||||
var size = radius * 2;
|
||||
var circle = document.createElement('div');
|
||||
circle.className = 'unfogged-circle';
|
||||
circle.style.width = size + 'px';
|
||||
circle.style.height = size + 'px';
|
||||
circle.style.left = (point.x - radius) + 'px';
|
||||
circle.style.top = (point.y - radius) + 'px';
|
||||
circle.style.backdropFilter = 'blur(0px)'; // Remove blur for the circles
|
||||
fog.appendChild(circle);
|
||||
}
|
||||
|
||||
this.addTileLayer(map);
|
||||
this.addLastMarker(map, markers);
|
||||
|
|
@ -67,7 +135,7 @@ export default class extends Controller {
|
|||
baseMaps() {
|
||||
return {
|
||||
OpenStreetMap: this.osmMapLayer(),
|
||||
"OpenStreetMap.HOT": this.osmHotMapLayer(),
|
||||
"OpenStreetMap.HOT": this.osmHotMapLayer()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,8 +46,11 @@
|
|||
data-center="<%= MAP_CENTER %>"
|
||||
data-timezone="<%= Rails.configuration.time_zone %>"
|
||||
data-meters_between_routes="<%= current_user.settings['meters_between_routes'] %>"
|
||||
data-minutes_between_routes="<%= current_user.settings['minutes_between_routes'] %>">
|
||||
<div data-maps-target="container" class="h-[25rem] w-auto min-h-screen"></div>
|
||||
data-minutes_between_routes="<%= current_user.settings['minutes_between_routes'] %>"
|
||||
data-fog_of_war_meters="<%= current_user.settings['fog_of_war_meters'] %>">
|
||||
<div data-maps-target="container" class="h-[25rem] w-auto min-h-screen">
|
||||
<div id="fog" class="fog"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,30 @@
|
|||
<% end %>
|
||||
<%= f.number_field :minutes_between_routes, value: current_user.settings['minutes_between_routes'], class: "input input-bordered" %>
|
||||
</div>
|
||||
<div class="form-control my-2">
|
||||
<%= f.label :fog_of_war_meters do %>
|
||||
Fog of War meters
|
||||
|
||||
<!-- The button to open modal -->
|
||||
<label for="fog_of_war_meters_info" class="btn">?</label>
|
||||
|
||||
<!-- Put this part before </body> tag -->
|
||||
<input type="checkbox" id="fog_of_war_meters_info" class="modal-toggle" />
|
||||
<div class="modal" role="dialog">
|
||||
<div class="modal-box">
|
||||
<h3 class="text-lg font-bold">Fog of War meters</h3>
|
||||
<p class="py-4">
|
||||
Value in meters.
|
||||
</p>
|
||||
<p class="py-4">
|
||||
Here you can set the radius of the "cleared" area around a point when Fog of War mode is enabled. The area around the point will be cleared, and the rest of the map will be covered with fog. The cleared area will be a circle with the point as the center and the radius as the value you set here.
|
||||
</p>
|
||||
</div>
|
||||
<label class="modal-backdrop" for="fog_of_war_meters_info">Close</label>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= f.number_field :fog_of_war_meters, value: current_user.settings['fog_of_war_meters'], class: "input input-bordered" %>
|
||||
</div>
|
||||
<div class="form-control my-2">
|
||||
<%= f.submit "Update", class: "btn btn-primary" %>
|
||||
</div>
|
||||
|
|
|
|||
14
db/data/20240625201842_add_fog_of_war_meters_to_settings.rb
Normal file
14
db/data/20240625201842_add_fog_of_war_meters_to_settings.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddFogOfWarMetersToSettings < ActiveRecord::Migration[7.1]
|
||||
def up
|
||||
User.find_each do |user|
|
||||
user.settings = user.settings.merge(fog_of_war_meters: 100)
|
||||
user.save!
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
||||
|
|
@ -1 +1 @@
|
|||
DataMigrate::Data.define(version: 20240610170930)
|
||||
DataMigrate::Data.define(version: 20240625201842)
|
||||
|
|
|
|||
Loading…
Reference in a new issue