651 lines
28 KiB
HTML
651 lines
28 KiB
HTML
{% extends 'mainapp/base.html' %}
|
||
{% load static %}
|
||
{% load static leaflet_tags %}
|
||
{% load l10n %}
|
||
|
||
{% block title %}{% if object %}Редактировать объект: {{ object.name }}{% else %}Создать объект{% endif %}{% endblock %}
|
||
|
||
{% block extra_css %}
|
||
<style>
|
||
.form-section { margin-bottom: 2rem; border: 1px solid #dee2e6; border-radius: 0.25rem; padding: 1rem; }
|
||
.form-section-header { border-bottom: 1px solid #dee2e6; padding-bottom: 0.5rem; margin-bottom: 1rem; }
|
||
.btn-action { margin-right: 0.5rem; }
|
||
.dynamic-form { border: 1px dashed #ced4da; padding: 1rem; margin-top: 1rem; border-radius: 0.25rem; }
|
||
.dynamic-form-header { display: flex; justify-content: space-between; align-items: center; }
|
||
.readonly-field { background-color: #f8f9fa; padding: 0.375rem 0.75rem; border: 1px solid #ced4da; border-radius: 0.25rem; }
|
||
.coord-group { border: 1px solid #dee2e6; padding: 0.75rem; border-radius: 0.25rem; margin-bottom: 1rem; }
|
||
.coord-group-header { font-weight: bold; margin-bottom: 0.5rem; }
|
||
.form-check-input { margin-top: 0.25rem; }
|
||
.datetime-group { display: flex; gap: 1rem; }
|
||
.datetime-group > div { flex: 1; }
|
||
#map { height: 500px; width: 100%; margin-bottom: 1rem; }
|
||
.map-container { margin-bottom: 1rem; }
|
||
.coord-sync-group { border: 1px solid #dee2e6; padding: 0.75rem; border-radius: 0.25rem; }
|
||
.map-controls {
|
||
display: flex;
|
||
gap: 10px;
|
||
margin-bottom: 1rem;
|
||
flex-wrap: wrap;
|
||
}
|
||
.map-control-btn {
|
||
padding: 0.375rem 0.75rem;
|
||
border: 1px solid #ced4da;
|
||
background-color: #f8f9fa;
|
||
border-radius: 0.25rem;
|
||
cursor: pointer;
|
||
}
|
||
.map-control-btn.active {
|
||
background-color: #e9ecef;
|
||
border-color: #dee2e6;
|
||
}
|
||
.map-control-btn.edit {
|
||
background-color: #fff3cd;
|
||
border-color: #ffeeba;
|
||
}
|
||
.map-control-btn.save {
|
||
background-color: #d1ecf1;
|
||
border-color: #bee5eb;
|
||
}
|
||
.map-control-btn.cancel {
|
||
background-color: #f8d7da;
|
||
border-color: #f5c6cb;
|
||
}
|
||
.leaflet-marker-icon {
|
||
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.3));
|
||
}
|
||
</style>
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="container-fluid px-3">
|
||
<div class="row mb-3">
|
||
<div class="col-12 d-flex justify-content-between align-items-center">
|
||
<h2>{% if object %}Редактировать объект: {{ object.name }}{% else %}Создать объект{% endif %}</h2>
|
||
<div>
|
||
{% if user.customuser.role == 'admin' or user.customuser.role == 'moderator' %}
|
||
<button type="submit" class="btn btn-primary btn-action">Сохранить</button>
|
||
{% if object %}
|
||
<a href="{% url 'mainapp:objitem_delete' object.id %}{% if request.GET.urlencode %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-danger btn-action">Удалить</a>
|
||
{% endif %}
|
||
{% endif %}
|
||
<a href="{% url 'mainapp:objitem_list' %}{% if request.GET.urlencode %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-secondary btn-action">Назад</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<form method="post">
|
||
{% csrf_token %}
|
||
|
||
<!-- Основная информация -->
|
||
<div class="form-section">
|
||
<div class="form-section-header">
|
||
<h4>Основная информация</h4>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
{% include 'mainapp/components/_form_field.html' with field=form.name %}
|
||
</div>
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label class="form-label">Дата создания:</label>
|
||
<div class="readonly-field">
|
||
{% if object.created_at %}{{ object.created_at|date:"d.m.Y H:i" }}{% else %}-{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label class="form-label">Создан пользователем:</label>
|
||
<div class="readonly-field">
|
||
{% if object.created_by %}{{ object.created_by }}{% else %}-{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label class="form-label">Дата последнего изменения:</label>
|
||
<div class="readonly-field">
|
||
{% if object.updated_at %}{{ object.updated_at|date:"d.m.Y H:i" }}{% else %}-{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label class="form-label">Изменен пользователем:</label>
|
||
<div class="readonly-field">
|
||
{% if object.updated_by %}{{ object.updated_by }}{% else %}-{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ВЧ загрузки -->
|
||
<div class="form-section">
|
||
<div class="form-section-header d-flex justify-content-between align-items-center">
|
||
<h4>ВЧ загрузка</h4>
|
||
{% if not parameter_forms.forms.0.instance.pk %}
|
||
<button type="button" class="btn btn-sm btn-outline-primary" id="add-parameter">Добавить ВЧ загрузку</button>
|
||
{% endif %}
|
||
</div>
|
||
|
||
<div id="parameters-container">
|
||
{% for param_form in parameter_forms %}
|
||
{% comment %} <div class="dynamic-form" data-parameter-index="{{ forloop.counter0 }}"> {% endcomment %}
|
||
<div class="dynamic-form-header">
|
||
{% if parameter_forms.forms|length > 1 %}
|
||
<button type="button" class="btn btn-sm btn-outline-danger remove-parameter">Удалить</button>
|
||
{% endif %}
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-3">
|
||
{% include 'mainapp/components/_form_field.html' with field=param_form.id_satellite %}
|
||
</div>
|
||
<div class="col-md-3">
|
||
{% include 'mainapp/components/_form_field.html' with field=param_form.frequency %}
|
||
</div>
|
||
<div class="col-md-3">
|
||
{% include 'mainapp/components/_form_field.html' with field=param_form.freq_range %}
|
||
</div>
|
||
<div class="col-md-3">
|
||
{% include 'mainapp/components/_form_field.html' with field=param_form.polarization %}
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-md-3">
|
||
{% include 'mainapp/components/_form_field.html' with field=param_form.bod_velocity %}
|
||
</div>
|
||
<div class="col-md-3">
|
||
{% include 'mainapp/components/_form_field.html' with field=param_form.modulation %}
|
||
</div>
|
||
<div class="col-md-3">
|
||
{% include 'mainapp/components/_form_field.html' with field=param_form.snr %}
|
||
</div>
|
||
<div class="col-md-3">
|
||
{% include 'mainapp/components/_form_field.html' with field=param_form.standard %}
|
||
</div>
|
||
</div>
|
||
{% comment %} </div> {% endcomment %}
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Блок с картой -->
|
||
<div class="form-section">
|
||
<div class="form-section-header">
|
||
<h4>Карта</h4>
|
||
</div>
|
||
<div class="map-container">
|
||
<div id="map"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Геоданные -->
|
||
<div class="form-section">
|
||
<div class="form-section-header">
|
||
<h4>Геоданные</h4>
|
||
</div>
|
||
|
||
|
||
<!-- Координаты геолокации -->
|
||
<div class="coord-sync-group">
|
||
<div class="coord-group-header">Координаты геолокации</div>
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="id_geo_latitude" class="form-label">Широта:</label>
|
||
<input type="number" step="0.000001" class="form-control"
|
||
id="id_geo_latitude" name="geo_latitude"
|
||
value="{% if object.geo_obj and object.geo_obj.coords %}{{ object.geo_obj.coords.y|unlocalize }}{% endif %}">
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="id_geo_longitude" class="form-label">Долгота:</label>
|
||
<input type="number" step="0.000001" class="form-control"
|
||
id="id_geo_longitude" name="geo_longitude"
|
||
value="{% if object.geo_obj and object.geo_obj.coords %}{{ object.geo_obj.coords.x|unlocalize }}{% endif %}">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Координаты Кубсата -->
|
||
<div class="coord-group">
|
||
<div class="coord-group-header">Координаты Кубсата</div>
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="id_kupsat_longitude" class="form-label">Долгота:</label>
|
||
<input type="number" step="0.000001" class="form-control"
|
||
id="id_kupsat_longitude" name="kupsat_longitude"
|
||
value="{% if object.geo_obj and object.geo_obj.coords_kupsat %}{{ object.geo_obj.coords_kupsat.x|unlocalize }}{% endif %}">
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="id_kupsat_latitude" class="form-label">Широта:</label>
|
||
<input type="number" step="0.000001" class="form-control"
|
||
id="id_kupsat_latitude" name="kupsat_latitude"
|
||
value="{% if object.geo_obj and object.geo_obj.coords_kupsat %}{{ object.geo_obj.coords_kupsat.y|unlocalize }}{% endif %}">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Координаты оперативников -->
|
||
<div class="coord-group">
|
||
<div class="coord-group-header">Координаты оперативников</div>
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="id_valid_longitude" class="form-label">Долгота:</label>
|
||
<input type="number" step="0.000001" class="form-control"
|
||
id="id_valid_longitude" name="valid_longitude"
|
||
value="{% if object.geo_obj and object.geo_obj.coords_valid %}{{ object.geo_obj.coords_valid.x|unlocalize }}{% endif %}">
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="id_valid_latitude" class="form-label">Широта:</label>
|
||
<input type="number" step="0.000001" class="form-control"
|
||
id="id_valid_latitude" name="valid_latitude"
|
||
value="{% if object.geo_obj and object.geo_obj.coords_valid %}{{ object.geo_obj.coords_valid.y|unlocalize }}{% endif %}">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
{% include 'mainapp/components/_form_field.html' with field=geo_form.location %}
|
||
</div>
|
||
<div class="col-md-6">
|
||
{% include 'mainapp/components/_form_field.html' with field=geo_form.comment %}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label class="form-label">Дата и время:</label>
|
||
<div class="datetime-group">
|
||
<div>
|
||
<label for="id_timestamp_date" class="form-label">Дата:</label>
|
||
<input type="date" class="form-control"
|
||
id="id_timestamp_date" name="timestamp_date"
|
||
value="{% if object.geo_obj and object.geo_obj.timestamp %}{{ object.geo_obj.timestamp|date:'Y-m-d' }}{% endif %}">
|
||
</div>
|
||
<div>
|
||
<label for="id_timestamp_time" class="form-label">Время:</label>
|
||
<input type="time" class="form-control"
|
||
id="id_timestamp_time" name="timestamp_time"
|
||
value="{% if object.geo_obj and object.geo_obj.timestamp %}{{ object.geo_obj.timestamp|time:'H:i' }}{% endif %}">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
{% include 'mainapp/components/_form_field.html' with field=geo_form.is_average %}
|
||
</div>
|
||
</div>
|
||
|
||
{% if object.geo_obj %}
|
||
<div class="row mt-3">
|
||
<div class="col-md-4">
|
||
<div class="mb-3">
|
||
<label class="form-label">Расстояние гео-кубсат, км:</label>
|
||
<div class="readonly-field">
|
||
{% if object.geo_obj.distance_coords_kup is not None %}
|
||
{{ object.geo_obj.distance_coords_kup|floatformat:2 }}
|
||
{% else %}
|
||
-
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<div class="mb-3">
|
||
<label class="form-label">Расстояние гео-опер, км:</label>
|
||
<div class="readonly-field">
|
||
{% if object.geo_obj.distance_coords_valid is not None %}
|
||
{{ object.geo_obj.distance_coords_valid|floatformat:2 }}
|
||
{% else %}
|
||
-
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<div class="mb-3">
|
||
<label class="form-label">Расстояние кубсат-опер, км:</label>
|
||
<div class="readonly-field">
|
||
{% if object.geo_obj.distance_kup_valid is not None %}
|
||
{{ object.geo_obj.distance_kup_valid|floatformat:2 }}
|
||
{% else %}
|
||
-
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</form>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block extra_js %}
|
||
{{ block.super }}
|
||
<!-- Подключаем Leaflet и его плагины -->
|
||
{% leaflet_js %}
|
||
{% leaflet_css %}
|
||
<script src="{% static 'leaflet-markers/js/leaflet-color-markers.js' %}"></script>
|
||
|
||
|
||
<script>
|
||
// Динамическое добавление ВЧ загрузок
|
||
let parameterIndex = {{ parameter_forms|length }};
|
||
|
||
document.getElementById('add-parameter')?.addEventListener('click', function() {
|
||
const container = document.getElementById('parameters-container');
|
||
const template = document.querySelector('.dynamic-form');
|
||
|
||
if (template) {
|
||
const clone = template.cloneNode(true);
|
||
clone.querySelectorAll('[id]').forEach(el => {
|
||
el.id = el.id.replace(/-\d+-/g, `-${parameterIndex}-`);
|
||
});
|
||
clone.querySelectorAll('[name]').forEach(el => {
|
||
el.name = el.name.replace(/-\d+-/g, `-${parameterIndex}-`);
|
||
});
|
||
clone.querySelectorAll('[for]').forEach(el => {
|
||
el.htmlFor = el.htmlFor.replace(/-\d+-/g, `-${parameterIndex}-`);
|
||
});
|
||
clone.querySelector('.dynamic-form-header h5').textContent = `ВЧ загрузка #${parameterIndex + 1}`;
|
||
clone.dataset.parameterIndex = parameterIndex;
|
||
container.appendChild(clone);
|
||
parameterIndex++;
|
||
}
|
||
});
|
||
|
||
// Удаление ВЧ загрузок
|
||
document.addEventListener('click', function(e) {
|
||
if (e.target.classList.contains('remove-parameter')) {
|
||
if (document.querySelectorAll('.dynamic-form').length > 1) {
|
||
e.target.closest('.dynamic-form').remove();
|
||
} else {
|
||
alert('Должна быть хотя бы одна ВЧ загрузка');
|
||
}
|
||
}
|
||
});
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// Инициализация карты
|
||
const map = L.map('map').setView([55.75, 37.62], 5);
|
||
|
||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||
}).addTo(map);
|
||
|
||
// Определяем цвета для маркеров
|
||
const colors = {
|
||
geo: 'blue',
|
||
kupsat: 'red',
|
||
valid: 'green'
|
||
};
|
||
|
||
// Функция для создания иконки маркера
|
||
function createMarkerIcon(color) {
|
||
return L.icon({
|
||
iconUrl: '{% static "leaflet-markers/img/marker-icon-" %}' + color + '.png',
|
||
shadowUrl: `{% static 'leaflet-markers/img/marker-shadow.png' %}`,
|
||
iconSize: [25, 41],
|
||
iconAnchor: [12, 41],
|
||
popupAnchor: [1, -34],
|
||
shadowSize: [41, 41]
|
||
});
|
||
}
|
||
const editableLayerGroup = new L.FeatureGroup();
|
||
map.addLayer(editableLayerGroup);
|
||
|
||
// Маркеры
|
||
const markers = {};
|
||
function createMarker(latFieldId, lngFieldId, position, color, name) {
|
||
const marker = L.marker(position, {
|
||
draggable: false,
|
||
icon: createMarkerIcon(color),
|
||
title: name
|
||
}).addTo(editableLayerGroup);
|
||
marker.bindPopup(name);
|
||
|
||
// Синхронизация при изменении формы
|
||
function syncFromForm() {
|
||
const lat = parseFloat(document.getElementById(latFieldId).value);
|
||
const lng = parseFloat(document.getElementById(lngFieldId).value);
|
||
if (!isNaN(lat) && !isNaN(lng)) {
|
||
marker.setLatLng([lat, lng]);
|
||
}
|
||
}
|
||
|
||
// Синхронизация при перетаскивании (только если активировано)
|
||
marker.on('dragend', function(event) {
|
||
const latLng = event.target.getLatLng();
|
||
document.getElementById(latFieldId).value = latLng.lat.toFixed(6);
|
||
document.getElementById(lngFieldId).value = latLng.lng.toFixed(6);
|
||
});
|
||
|
||
// Добавляем методы для управления
|
||
marker.enableEditing = function() {
|
||
this.dragging.enable();
|
||
this.openPopup();
|
||
};
|
||
|
||
marker.disableEditing = function() {
|
||
this.dragging.disable();
|
||
this.closePopup();
|
||
};
|
||
|
||
marker.syncFromForm = syncFromForm;
|
||
|
||
return marker;
|
||
}
|
||
|
||
// Создаем маркеры
|
||
markers.geo = createMarker(
|
||
'id_geo_latitude',
|
||
'id_geo_longitude',
|
||
[55.75, 37.62],
|
||
colors.geo,
|
||
'Геолокация'
|
||
);
|
||
|
||
markers.kupsat = createMarker(
|
||
'id_kupsat_latitude',
|
||
'id_kupsat_longitude',
|
||
[55.75, 37.61],
|
||
colors.kupsat,
|
||
'Кубсат'
|
||
);
|
||
|
||
markers.valid = createMarker(
|
||
'id_valid_latitude',
|
||
'id_valid_longitude',
|
||
[55.75, 37.63],
|
||
colors.valid,
|
||
'Оперативник'
|
||
);
|
||
|
||
// Устанавливаем начальные координаты из полей формы
|
||
function initMarkersFromForm() {
|
||
const geoLat = parseFloat(document.getElementById('id_geo_latitude').value) || 55.75;
|
||
const geoLng = parseFloat(document.getElementById('id_geo_longitude').value) || 37.62;
|
||
markers.geo.setLatLng([geoLat, geoLng]);
|
||
|
||
const kupsatLat = parseFloat(document.getElementById('id_kupsat_latitude').value) || 55.75;
|
||
const kupsatLng = parseFloat(document.getElementById('id_kupsat_longitude').value) || 37.61;
|
||
markers.kupsat.setLatLng([kupsatLat, kupsatLng]);
|
||
|
||
const validLat = parseFloat(document.getElementById('id_valid_latitude').value) || 55.75;
|
||
const validLng = parseFloat(document.getElementById('id_valid_longitude').value) || 37.63;
|
||
markers.valid.setLatLng([validLat, validLng]);
|
||
|
||
// Центрируем карту на первом маркере
|
||
map.setView(markers.geo.getLatLng(), 10);
|
||
}
|
||
|
||
// Настройка формы для синхронизации с маркерами
|
||
function setupFormChange(latFieldId, lngFieldId, marker) {
|
||
const latField = document.getElementById(latFieldId);
|
||
const lngField = document.getElementById(lngFieldId);
|
||
|
||
[latField, lngField].forEach(field => {
|
||
field.addEventListener('change', function() {
|
||
const lat = parseFloat(latField.value);
|
||
const lng = parseFloat(lngField.value);
|
||
|
||
if (!isNaN(lat) && !isNaN(lng)) {
|
||
marker.setLatLng([lat, lng]);
|
||
map.setView(marker.getLatLng(), 10);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// Инициализация
|
||
initMarkersFromForm();
|
||
// Настройка формы для синхронизации с маркерами
|
||
setupFormChange('id_geo_latitude', 'id_geo_longitude', markers.geo);
|
||
setupFormChange('id_kupsat_latitude', 'id_kupsat_longitude', markers.kupsat);
|
||
setupFormChange('id_valid_latitude', 'id_valid_longitude', markers.valid);
|
||
// --- УПРАВЛЕНИЕ РЕДАКТИРОВАНИЕМ ---
|
||
// Кнопки редактирования
|
||
const editControlsDiv = L.DomUtil.create('div', 'map-controls');
|
||
editControlsDiv.style.position = 'absolute';
|
||
editControlsDiv.style.top = '10px';
|
||
editControlsDiv.style.right = '10px';
|
||
editControlsDiv.style.zIndex = '1000';
|
||
editControlsDiv.style.background = 'white';
|
||
editControlsDiv.style.padding = '10px';
|
||
editControlsDiv.style.borderRadius = '4px';
|
||
editControlsDiv.style.boxShadow = '0 0 10px rgba(0,0,0,0.2)';
|
||
editControlsDiv.innerHTML = `
|
||
<div class="map-controls">
|
||
<button type="button" id="edit-btn" class="map-control-btn edit">Редактировать</button>
|
||
<button type="button" id="save-btn" class="map-control-btn save" disabled>Сохранить</button>
|
||
<button type="button" id="cancel-btn" class="map-control-btn cancel" disabled>Отмена</button>
|
||
</div>
|
||
`;
|
||
map.getContainer().appendChild(editControlsDiv);
|
||
|
||
let isEditing = false;
|
||
|
||
// Сохраняем начальные координаты для отмены
|
||
const initialPositions = {
|
||
geo: markers.geo.getLatLng(),
|
||
kupsat: markers.kupsat.getLatLng(),
|
||
valid: markers.valid.getLatLng()
|
||
};
|
||
|
||
// Включение редактирования
|
||
document.getElementById('edit-btn').addEventListener('click', function() {
|
||
if (isEditing) return;
|
||
|
||
isEditing = true;
|
||
document.getElementById('edit-btn').classList.add('active');
|
||
document.getElementById('save-btn').disabled = false;
|
||
document.getElementById('cancel-btn').disabled = false;
|
||
|
||
// Включаем drag для всех маркеров
|
||
Object.values(markers).forEach(marker => {
|
||
marker.enableEditing();
|
||
});
|
||
|
||
// Показываем подсказку
|
||
L.popup()
|
||
.setLatLng(map.getCenter())
|
||
.setContent('Перетаскивайте маркеры. Нажмите "Сохранить" или "Отмена".')
|
||
.openOn(map);
|
||
});
|
||
|
||
// Сохранение изменений
|
||
document.getElementById('save-btn').addEventListener('click', function() {
|
||
if (!isEditing) return;
|
||
|
||
isEditing = false;
|
||
document.getElementById('edit-btn').classList.remove('active');
|
||
document.getElementById('save-btn').disabled = true;
|
||
document.getElementById('cancel-btn').disabled = true;
|
||
|
||
// Отключаем редактирование
|
||
Object.values(markers).forEach(marker => {
|
||
marker.disableEditing();
|
||
});
|
||
|
||
// Обновляем начальные позиции
|
||
initialPositions.geo = markers.geo.getLatLng();
|
||
initialPositions.kupsat = markers.kupsat.getLatLng();
|
||
initialPositions.valid = markers.valid.getLatLng();
|
||
|
||
// Убираем попап подсказки
|
||
map.closePopup();
|
||
});
|
||
|
||
// Отмена изменений
|
||
document.getElementById('cancel-btn').addEventListener('click', function() {
|
||
if (!isEditing) return;
|
||
|
||
isEditing = false;
|
||
document.getElementById('edit-btn').classList.remove('active');
|
||
document.getElementById('save-btn').disabled = true;
|
||
document.getElementById('cancel-btn').disabled = true;
|
||
|
||
// Возвращаем маркеры на исходные позиции
|
||
markers.geo.setLatLng(initialPositions.geo);
|
||
markers.kupsat.setLatLng(initialPositions.kupsat);
|
||
markers.valid.setLatLng(initialPositions.valid);
|
||
|
||
// Отключаем редактирование
|
||
Object.values(markers).forEach(marker => {
|
||
marker.disableEditing();
|
||
});
|
||
|
||
// Синхронизируем форму с исходными значениями
|
||
document.getElementById('id_geo_latitude').value = initialPositions.geo.lat.toFixed(6);
|
||
document.getElementById('id_geo_longitude').value = initialPositions.geo.lng.toFixed(6);
|
||
|
||
document.getElementById('id_kupsat_latitude').value = initialPositions.kupsat.lat.toFixed(6);
|
||
document.getElementById('id_kupsat_longitude').value = initialPositions.kupsat.lng.toFixed(6);
|
||
|
||
document.getElementById('id_valid_latitude').value = initialPositions.valid.lat.toFixed(6);
|
||
document.getElementById('id_valid_longitude').value = initialPositions.valid.lng.toFixed(6);
|
||
map.closePopup();
|
||
});
|
||
|
||
// Легенда
|
||
const legend = L.control({ position: 'bottomright' });
|
||
|
||
legend.onAdd = function() {
|
||
const div = L.DomUtil.create('div', 'info legend');
|
||
div.style.fontSize = '14px';
|
||
div.style.backgroundColor = 'white';
|
||
div.style.padding = '10px';
|
||
div.style.borderRadius = '4px';
|
||
div.style.boxShadow = '0 0 10px rgba(0,0,0,0.2)';
|
||
div.innerHTML = `
|
||
<h5>Легенда</h5>
|
||
<div><span style="color: blue; font-weight: bold;">•</span> Геолокация</div>
|
||
<div><span style="color: red; font-weight: bold;">•</span> Кубсат</div>
|
||
<div><span style="color: green; font-weight: bold;">•</span> Оперативники</div>
|
||
`;
|
||
return div;
|
||
};
|
||
|
||
legend.addTo(map);
|
||
});
|
||
</script>
|
||
{% endblock %} |