353 lines
8.1 KiB
Plaintext
353 lines
8.1 KiB
Plaintext
<div class="container-fluid">
|
||
<div class="row">
|
||
<div class="col-12">
|
||
<div class="card shadow-sm mb-3">
|
||
<div class="card-header d-flex justify-content-between align-items-center">
|
||
<div>
|
||
<h5 class="mb-0">Редактирование участков</h5>
|
||
<?php if(!empty($cat->cat_name)): ?>
|
||
<small class="text-muted d-block">Раздел: <?php echo \htmlentities($cat->cat_name, ENT_QUOTES, 'UTF-8', false); ?></small>
|
||
<?php endif; ?>
|
||
</div>
|
||
<button type="button" class="btn btn-primary btn-sm" id="btn-create-zone">
|
||
<i class="fa fa-draw-polygon mr-1"></i> Создать участок
|
||
</button>
|
||
</div>
|
||
|
||
<div class="card-body p-0">
|
||
<div id="map" class="w-100 map-container"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
#newzoneedit {
|
||
display: none;
|
||
}
|
||
|
||
.map-container {
|
||
height: 600px;
|
||
min-height: 400px;
|
||
}
|
||
|
||
.balloon-response {
|
||
font-size: 0.875rem;
|
||
}
|
||
</style>
|
||
|
||
<script type="text/javascript" src="assets/js/jquery.ajaxform.js"></script>
|
||
<script src="//api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
|
||
|
||
<script>
|
||
// Конфиг для запросов
|
||
var POLYGON_CONFIG = {
|
||
baseUrl: <?php echo json_encode('?cat=' . $cat->cat, 15, 512); ?> // строка вида "?cat=admin_polygon"
|
||
};
|
||
|
||
var PolygonEditor = {
|
||
myMap: null,
|
||
myPolygon: null,
|
||
isDrawing: false,
|
||
poligons: {},
|
||
|
||
init: function () {
|
||
var self = this;
|
||
|
||
self.myMap = new ymaps.Map('map', {
|
||
center: [59.859605, 30.340733],
|
||
zoom: 14,
|
||
controls: ['smallMapDefaultSet']
|
||
});
|
||
|
||
// Кнопка создания участка
|
||
$('#btn-create-zone').on('click', function () {
|
||
if (!self.isDrawing) {
|
||
self.startDrawing();
|
||
} else {
|
||
self.cancelDrawing();
|
||
}
|
||
});
|
||
|
||
// Рендер существующих участков
|
||
<?php if(!empty($rows)): ?>
|
||
<?php $__currentLoopData = $rows; $this->addLoop($__currentLoopData);$this->getFirstLoop();
|
||
foreach($__currentLoopData as $row): $loop = $this->incrementLoopIndices(); ?>
|
||
self.addPolygon(
|
||
<?php echo $row['coords']; ?>,
|
||
<?php echo \htmlentities((int)$row['id'], ENT_QUOTES, 'UTF-8', false); ?>,
|
||
<?php echo json_encode($row['title']); ?>
|
||
|
||
);
|
||
<?php endforeach; $this->popLoop(); $loop = $this->getFirstLoop(); ?>
|
||
<?php endif; ?>
|
||
},
|
||
|
||
setDrawButtonState: function (active) {
|
||
this.isDrawing = !!active;
|
||
var $btn = $('#btn-create-zone');
|
||
|
||
if (this.isDrawing) {
|
||
$btn
|
||
.removeClass('btn-primary')
|
||
.addClass('btn-danger')
|
||
.html('<i class="fa fa-check mr-1"></i> Завершить рисование');
|
||
} else {
|
||
$btn
|
||
.removeClass('btn-danger')
|
||
.addClass('btn-primary')
|
||
.html('<i class="fa fa-draw-polygon mr-1"></i> Создать участок');
|
||
}
|
||
},
|
||
|
||
startDrawing: function () {
|
||
var self = this;
|
||
|
||
if (self.isDrawing) {
|
||
return;
|
||
}
|
||
|
||
self.myPolygon = new ymaps.Polygon([], {}, {
|
||
editorDrawingCursor: "crosshair",
|
||
editorMaxPoints: 999,
|
||
fillColor: '#ed4543',
|
||
strokeColor: '#ed4543',
|
||
fillOpacity: 0.6,
|
||
strokeWidth: 1
|
||
});
|
||
|
||
self.myMap.geoObjects.add(self.myPolygon);
|
||
|
||
self.attachEditorMonitor(self.myPolygon, function () {
|
||
self.stopDrawing();
|
||
});
|
||
|
||
self.myPolygon.editor.startDrawing();
|
||
self.setDrawButtonState(true);
|
||
},
|
||
|
||
cancelDrawing: function () {
|
||
if (!this.myPolygon) {
|
||
this.setDrawButtonState(false);
|
||
return;
|
||
}
|
||
|
||
this.myPolygon.editor.stopDrawing();
|
||
this.myMap.geoObjects.remove(this.myPolygon);
|
||
this.myPolygon = null;
|
||
this.setDrawButtonState(false);
|
||
},
|
||
|
||
stopDrawing: function () {
|
||
var self = this;
|
||
|
||
if (!self.myPolygon) {
|
||
self.setDrawButtonState(false);
|
||
return;
|
||
}
|
||
|
||
var coords = self.myPolygon.geometry.getCoordinates();
|
||
self.myPolygon.editor.stopDrawing();
|
||
self.myMap.geoObjects.remove(self.myPolygon);
|
||
self.myPolygon = null;
|
||
|
||
self.setDrawButtonState(false);
|
||
|
||
// ВАЖНО: используем сигнатуру $.post(url, data, success, dataType)
|
||
$.post(
|
||
POLYGON_CONFIG.baseUrl + '&act=editgeom&id=0',
|
||
{ geom: coords },
|
||
function (data) {
|
||
if (data && data.id && data.id !== 0) {
|
||
self.addPolygon(coords, data.id, data.title || '');
|
||
}
|
||
},
|
||
'json'
|
||
).fail(function () {
|
||
console.error('Ошибка сохранения нового участка');
|
||
});
|
||
},
|
||
|
||
addPolygon: function (coords, id, title) {
|
||
var self = this;
|
||
|
||
// $.get(url, success, dataType)
|
||
$.get(
|
||
POLYGON_CONFIG.baseUrl + '&act=getForm&id=' + id,
|
||
function (params) {
|
||
params = params || {};
|
||
self._addPolygonHtml(
|
||
coords,
|
||
id,
|
||
params.title || title || '',
|
||
params.html || '',
|
||
params.color || '#00FF00'
|
||
);
|
||
},
|
||
'json'
|
||
).fail(function () {
|
||
console.error('Ошибка получения формы участка');
|
||
});
|
||
},
|
||
|
||
_addPolygonHtml: function (coords, id, title, html, fillcolor) {
|
||
var self = this;
|
||
fillcolor = fillcolor || "#00FF00";
|
||
|
||
self.poligons[id] = new ymaps.GeoObject({
|
||
geometry: {
|
||
type: "Polygon",
|
||
coordinates: coords,
|
||
fillRule: "nonZero"
|
||
},
|
||
properties: {
|
||
myid: id,
|
||
balloonContentHeader: title,
|
||
balloonContent: html,
|
||
balloonContentFooter:
|
||
'<div class="mt-2">' +
|
||
'<a href="#" onclick="PolygonEditor.editPolygon(' + id + ');return false;">Редактировать контур</a>' +
|
||
' | ' +
|
||
'<a href="#" class="text-danger" onclick="PolygonEditor.removePolygon(' + id + ');return false;">Удалить участок</a>' +
|
||
'</div>'
|
||
}
|
||
}, {
|
||
fillColor: fillcolor,
|
||
strokeColor: '#0000FF',
|
||
opacity: 0.5,
|
||
strokeWidth: 1,
|
||
strokeStyle: 'shortdash'
|
||
});
|
||
|
||
self.attachEditorMonitor(self.poligons[id], function (e) {
|
||
if (e.originalEvent && e.originalEvent.target) {
|
||
var tid = e.originalEvent.target.properties.get('myid');
|
||
var tcoords = e.originalEvent.target.geometry.getCoordinates();
|
||
|
||
if (!tid) {
|
||
self.stopDrawing();
|
||
return;
|
||
}
|
||
|
||
$.post(
|
||
POLYGON_CONFIG.baseUrl + '&act=editgeom&id=' + tid,
|
||
{ geom: tcoords },
|
||
function (data) {
|
||
if (data && data.id && data.id !== 0) {
|
||
self.addPolygon(tcoords, data.id, data.title || '');
|
||
}
|
||
},
|
||
'json'
|
||
).fail(function () {
|
||
console.error('Ошибка обновления контура участка');
|
||
});
|
||
}
|
||
});
|
||
|
||
self.myMap.geoObjects.add(self.poligons[id]);
|
||
},
|
||
|
||
editPolygon: function (id) {
|
||
var polygon = this.poligons[id];
|
||
if (!polygon) {
|
||
return;
|
||
}
|
||
|
||
var self = this;
|
||
|
||
self.myPolygon = polygon;
|
||
self.myMap.geoObjects.add(self.myPolygon);
|
||
|
||
self.attachEditorMonitor(self.myPolygon, function () {
|
||
self.stopDrawing();
|
||
});
|
||
|
||
self.myPolygon.editor.startDrawing();
|
||
self.setDrawButtonState(true);
|
||
},
|
||
|
||
removePolygon: function (id) {
|
||
var self = this;
|
||
|
||
if (!self.poligons[id]) {
|
||
return;
|
||
}
|
||
|
||
$.get(
|
||
POLYGON_CONFIG.baseUrl + '&act=remove&id=' + id,
|
||
function () {
|
||
self.myMap.geoObjects.remove(self.poligons[id]);
|
||
delete self.poligons[id];
|
||
}
|
||
).fail(function () {
|
||
console.error('Ошибка удаления участка');
|
||
});
|
||
},
|
||
|
||
submitForm: function (id, idn) {
|
||
var self = this;
|
||
var $resp = $('#resp' + idn);
|
||
|
||
var options = {
|
||
dataType: 'json',
|
||
success: function (params) {
|
||
params = params || {};
|
||
var data = params.html || '';
|
||
|
||
$resp
|
||
.addClass('balloon-response')
|
||
.html('<span class="text-success">Данные сохранены</span>' + data);
|
||
|
||
if (self.poligons[id]) {
|
||
self.poligons[id].properties.set('balloonContent', data);
|
||
if (params.color) {
|
||
self.poligons[id].options.set('fillColor', params.color);
|
||
}
|
||
}
|
||
},
|
||
error: function () {
|
||
$resp
|
||
.addClass('balloon-response')
|
||
.html('<span class="text-danger">Ошибка сохранения</span>');
|
||
}
|
||
};
|
||
|
||
$('#form' + idn).ajaxSubmit(options);
|
||
$resp.html("<img src='img/loader.gif' alt='' class='img-fluid'>");
|
||
|
||
return false;
|
||
},
|
||
|
||
attachEditorMonitor: function (polygon, onStopCallback) {
|
||
var stateMonitor = new ymaps.Monitor(polygon.editor.state);
|
||
stateMonitor.add("drawing", function (newValue) {
|
||
polygon.options.set("strokeColor", newValue ? '#FF0000' : '#0000FF');
|
||
});
|
||
|
||
polygon.events.add(['editorstatechange'], function (e) {
|
||
if (
|
||
e.originalEvent &&
|
||
e.originalEvent.originalEvent &&
|
||
e.originalEvent.originalEvent.originalEvent &&
|
||
e.originalEvent.originalEvent.originalEvent.newDrawing === false &&
|
||
e.originalEvent.originalEvent.originalEvent.oldDrawing === true
|
||
) {
|
||
if (typeof onStopCallback === 'function') {
|
||
onStopCallback(e);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
// Для совместимости со старой формой: onsubmit="return submit_form(id, idn)"
|
||
function submit_form(id, idn) {
|
||
return PolygonEditor.submitForm(id, idn);
|
||
}
|
||
|
||
ymaps.ready(function () {
|
||
PolygonEditor.init();
|
||
});
|
||
</script>
|