Files
GEOVizor_PHP/monitoring/jscripts/geofences.js
2023-11-07 19:51:49 +06:00

673 lines
20 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//Объезды
class TGeofences //Current user with role name and access
{
constructor(map){
this.groups = [];
this.geofences = [];
//Глобальный Vue шаблон для отображения группы списке
Vue.component('c_geofence', {
props: ["geofence","index"],
template: ` <div style="width: 100%;">
<div :style="{'background-color': color}" style="width: 100%;display:table;"><div style="display:table-row;">
<div style="display: table-cell;width:24px;vertical-align:middle;text-align:center;"><img :src="geofence.expand ? '/resources/images/down.png' : '/resources/images/right.png'" alt="" style="cursor:pointer;vertical-align:middle;" v-on:click="geofence.expand = !geofence.expand"></div>
<div style="display: table-cell;width:36px;vertical-align:middle;text-align:center;"><input type="checkbox" v-model="geofence.visible"></div>
<div style="display: table-cell;width:24px;"><img v-bind:src="'../resources/images/icons/'+geofence.icon_id+'.png'" style="vertical-align:middle;" alt=""></div>
<div v-on:click="geofence.goToCenter()" style="display: table-cell; cursor: crosshair;">{{geofence.name}}</div>
<div v-on:click="geofence.goToCenter()" style="display: table-cell;width:60px;cursor: crosshair;text-align: right;">{{geofence.count}}</div>
</div></div>
<div v-show="geofence.expand" style="margin-left: 24px;background-color: var(--back-color3);">
<table style="width:100%;">
<tbody><tr>
<td style="width:100%;border: 0;">
<strong>`+trt('Geofence_type')+`</strong>: {{geofence.geofence_type_name}}
</td>
<td valign="top" style="border: 0;">
<img src="/resources/images/del24.png" alt="`+trt('Delete')+`" title="`+trt('Delete')+`" style="cursor:pointer;" v-on:click="del()">
</td>
<td valign="top" style="border: 0;">
<img src="/resources/images/edit24.png" alt="`+trt('Edit')+`" title="`+trt('Edit')+`" style="cursor:pointer;" v-on:click="edit()">
</td></tr>
</tbody>
</table>
</div>
</div>`,
computed:{
color: function(){
let result="";
if (this.index%2==0) result='var(--row-color-1)'; else result='var(--row-color-2)';
return result;
}
},
methods: {
edit() {
this.geofence.parent.editDetour({id: this.geofence.id});
},
del() {
this.geofence.del();
}
},
mounted() {
}
});
}
//Получаем список объектов
//Фильтруем объекты для заполнения в таблицу
filtering()
{
showProgressBar(document.getElementById('id5_geofences'));
let data = {
geofence_type_id: document.getElementById("geofence_type_id_id0").value,
name: document.getElementById("filter_name_geofences").value
};
$.ajax({
url: '/monitoring/pscripts/geofences.php?fn=1',
data: JSON.stringify(data),
//contentType: 'application/json; charset=utf-8',
type: "POST",
//dataType: "json",
dataType: "text",
success: (data,status) => {
if(status=='success')
{
try{
data=JSON.parse(data);
}catch(e)
{
alert2(trt('Error'),'Parsing error: ' + e.name + ":" + e.message,e.stack);
hideProgressBar('id5_geofences');
return;
}
if(data!=null)
{
if(data.errorCode==0)
{
let count=0;
this.groups.splice(0,this.groups.length); //Чистим
//let features = [];
//g_vectorSource.clear(false);
//g_vectorSource.addFeatures(features);
for(let i=0;i<data.data.length;i++)
{
for(let j=0;j<data.data[i].geofences.length;j++){
data.data[i].geofences[j]=this.newGeofence(data.data[i].geofences[j]);
count++;
}
this.groups.push({id:data.data[i].id, name:data.data[i].name,geofences: data.data[i].geofences});
}
this.fillRezDiv();
document.getElementById("count_geofences").innerHTML=count;
}else
{
alert2(trt('Error'),data.errorMessage);
}
}
}else
{
alert2(trt('Error'), status);
}
hideProgressBar('id5_geofences');
},
error: function (jqXHR, exception)
{
alert2(trt('Alert'),jqXHR.responseText);
}
});
/*
let req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
alert(data);
let data=null;
try{
data=JSON.parse(data);
}catch(e)
{
alert2(trt('Error'),'Parsing error: ' + e.name + ":" + e.message + "\n" + e.stack);
hideProgressBar('id5_geofences');
return;
}
if(data!=null)
{
if(data.errorCode==0)
{
thiz.geofences.splice(0,thiz.geofences.length);
//Приходит JSON уже в объектах
//document.getElementById("count").innerHTML=data.data.length;
//let features = [];
//g_vectorSource.clear(false);
//g_vectorSource.addFeatures(features);
//this.corteges = [];
for(let i=0;i<data.data.length;i++)
{
thiz.geofences.Array.push({id:data.data[i].id, name:data.data[i].name});
//thiz.newCortege(data.data[i]);
}
thiz.fillRezDiv();
//thiz.clear();
//Приходит JSON уже в объектах
//let features = [];
//for(i=0;i<data.length;i++)
//{
// var obj = new TGeofence(thiz);
// obj.id=data[i].id;
// obj.name=data[i].name;
// obj.count=data[i].count;
// obj.geofence_type_name=data[i].geofence_type_name;
// obj.lon=parseFloat(data[i].lon);
// obj.lat=parseFloat(data[i].lat);
// thiz.geofences.push(obj);
//}
//thiz.fillRezDiv();
}else
{
alert2(trt('Error'),data.errorMessage);
}
}
hideProgressBar(document.getElementById('id5_geofences'));
};
}
}(this);
req.open("POST", '/monitoring/pscripts/geofences.php?fn=1', true);
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(data));
*/
/*
var data = {
name: "",
type: ""
};
$.ajax({
url: '/monitoring/pscripts/geofences.php',
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
type: "POST",
dataType: "json",
success: function(thiz){return function(data,status){
if(status=='success')
{
thiz.geofences = []; //Удаляю старые объекты
g_vectorSourceGeofences.clear(); //Удаляю все отображения
for(i=0;i<data.length;i++)
{
var obj = new TRoute();
obj.id=data[i].id;
obj.name=data[i].name;
obj.count=data[i].count;
thiz.geofences.push(obj);
}
thiz.fillRezDiv();
}else
{
alert(status);
}
}}(this)
});
*/
}
//Заполнить результатом выборки DIV в виде таблицы
fillRezDiv()
{
let div=document.getElementById("id5_geofences");
delChild(div);
let html=`<table border="0" style="width:100%;" class="SShow">
<thead>
<tr style="background-color: rgb(218, 218, 218);"><th style="width:24px;"></th><th id="hideGeofencesBtn" style="width:36px;text-decoration:underline;cursor: pointer;">`+trt('View')+`.</th><th style="width:24px;"></th><th>`+trt('Geofence_name')+`</th><th style="width:60px;white-space:nowrap;vertical-align: middle;">`+trt('Points')+`</th></tr>
</thead>
<tbody>
<tr v-for="(group,index) in groups">
<td colspan="5">
<div style="width: 100%;background-color: background-color: var(--back-color3);">
<div style="display:table-cell;vertical-align:middle;padding-left:5px;">{{group.name}}</div>
<div v-for="(geofence,index) in group.geofences">
<c_geofence :geofence="geofence" :index="index"></c_geofence>
</div>
</div>
</td>
</tr>
</tbody>
</table>`;
let app = new Vue({
data: {
message: 'Hello Vue!',
color: false,
groups: this.groups
},
methods: {
setMessage: function(event){
/*this.message = event.target.value;
if(this.message=='123')
this.color = true;
else
this.color = false;*/
}
}
});
div.innerHTML=html;
app.$mount('#id5_geofences');
let hideObjectsBtn = document.getElementById("hideGeofencesBtn");
if(hideObjectsBtn!=null) hideObjectsBtn.onclick = ()=>{this.hide();};
return;
/*
var div=document.getElementById("id5_geofences");
delChild(div);
div.innerHTML='<table id="thetable_geofences" border="0" style="width:100%;" class="SShow"><thead><tr style="background-color: rgb(218, 218, 218);"><th></th><th id="cell_ch_D" style="width:1%;text-decoration:underline;cursor: pointer;">'+trt('View')+'.</th><th style="width: 90%;">'+trt('Geofence_name')+'</th><th style="width: 1%;">'+trt('Points')+'</th></tr></thead><tbody></tbody></table>';
var theTable = document.getElementById('thetable_geofences');
let type_name='';
for(i=0;i<this.geofences.length;i++)
{
if(type_name!=this.geofences[i].geofence_type_name) //Если новая группа
{
type_name=this.geofences[i].geofence_type_name;
if(type_name=='') type_name=trt('Group');
let tr = document.createElement('tr');
let bgColor='';
if (i%2==0) bgColor='var(--row-color-1)'; else bgColor='var(--row-color-2)';
tr.style.backgroundColor=bgColor;
let td = document.createElement('td');
td.innerHTML=type_name;
td.colSpan=6;
//td.style.cssText="text-align: center;";
tr.appendChild(td);
theTable.tBodies[0].appendChild(tr);
}
var tr = document.createElement('tr');
let bgColor='';
if (i%2==0) bgColor='var(--row-color-1)'; else bgColor='var(--row-color-2)';
tr.style.backgroundColor=bgColor;
tr.onmouseover=function(){this.style.backgroundColor='var(--btn-color2)';};
tr.onmouseout=function(val1,val2){return function(){val1.style.backgroundColor=val2;}}(tr,bgColor);
var td;
td = document.createElement('td');
td.style.cssText="width:24px;text-align:center;vertical-align:top;";
td.innerHTML='<img id="geofences_down_btn_'+this.geofences[i].id+'" src="/resources/images/right.png" alt="" style="cursor: pointer;">';
tr.appendChild(td);
td = document.createElement('td');
td.style.cssText="text-align: center;";
td.innerHTML='<input id="geofences_ch_'+this.geofences[i].id+'" type="checkbox"/>';
tr.appendChild(td);
td = document.createElement('td');
td.style.cursor='pointer';
td.innerHTML=this.geofences[i].name;
td.onclick=function(detour){
return function(){
detour.goToCenter();
}
}(this.geofences[i]);
tr.appendChild(td);
td = document.createElement('td');
td.style.cssText='cursor:pointer;text-align:right;';
td.innerHTML=this.geofences[i].count;
td.onclick=function(detour){
return function(){
detour.goToCenter();
}
}(this.geofences[i]);
tr.appendChild(td);
theTable.tBodies[0].appendChild(tr);
//Формирую раскрывающийся список
var tr = document.createElement('tr');
tr.id=this.geofences[i].id;
tr.style.cssText="background-color:var(--back-color-3);display:none";
td = document.createElement('td');
td.colSpan=4;
let html='<table style="width:100%;"><tr><td style="width:100%;border: 0;">';
if(this.geofences[i].geofence_type_name!=null)
html+='<b>Тип геозоны'+trt('')+'</b>: '+this.geofences[i].geofence_type_name+'<br>';
html+='</td><td valign="top" style="border: 0;"><img id="detour_del_'+this.geofences[i].id+'" src="/resources/images/del24.png" alt="'+trt('Delete')+'" title="'+trt('Delete')+'" style="cursor:pointer;"></td><td valign="top" style="border: 0;"><img id="detour_edit_'+this.geofences[i].id+'" src="/resources/images/edit24.png" alt="'+trt('Edit')+'" title="'+trt('Edit')+'" style="cursor:pointer;"></td></tr></table>';
td.innerHTML=html;
tr.appendChild(td);
theTable.tBodies[0].appendChild(tr);
var cell=document.getElementById("geofences_ch_"+this.geofences[i].id);
cell.onclick=function(route){
return function(){
var chb=document.getElementById("geofences_ch_"+route.id);
route.visible = chb.checked;
}
}(this.geofences[i]);
//Кнопка разсрыть список
var btn=document.getElementById('geofences_down_btn_'+this.geofences[i].id);
btn.onclick=function(tr,thiz,id){ return function(){
var btn=document.getElementById('geofences_down_btn_'+id);
if(btn.src.indexOf("right.png")!=-1)
{
btn.src = '/resources/images/down.png';
tr.style.display = 'table-row';
}else if(btn.src.indexOf("down.png")!=-1)
{
btn.src = '/resources/images/right.png';
tr.style.display = 'none';
}
}; }(tr,this,this.geofences[i].id);
//Кнопка удалить
btn=document.getElementById('detour_del_'+this.geofences[i].id)
btn.onclick=function(thiz,id){ return function(){ thiz.deleteDetour({id:id}); }; }(this,this.geofences[i].id);
//Кнопка редактировать
btn=document.getElementById('detour_edit_'+this.geofences[i].id)
btn.onclick=function(thiz,id){ return function(){ thiz.editDetour({id:id}); }; }(this,this.geofences[i].id);
}
//Количество элементов в дереве
var divCnt = document.getElementById("count_geofences");
delChild(divCnt);
divCnt.appendChild(document.createTextNode(this.geofences.length));
//По нажатию на заголовок инвертируем чекбуксы
divCnt = document.getElementById("cell_ch_D");
divCnt.onclick=function(thiz){
return function(){
thiz.hide();
}
}(this);
*/
}
createDetour()
{
//В настройках передаю центр карты
let center=ol.proj.transform(g_map.getView().getCenter(), 'EPSG:3857','EPSG:4326');
let eRec = new EdtRec("");
eRec.eRecNa("Geofences",-1,'<type n="Geofences"><properties><prop n="name"><![CDATA['+document.getElementById("filter_name_geofences").value+']]></prop><prop n="lat"><![CDATA['+center[1]+']]></prop><prop n="lon"><![CDATA['+center[0]+']]></prop></properties></type>');
eRec.win.onClose=function(thiz){ return function(){ thiz.filtering();};}(this);
}
editDetour(settings)
{
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
let detour=this.getDetourByID(settings.id);
let eRec = new EdtRec("");
eRec.eRecNa("Geofences",settings.id);
eRec.win.setCenter();
eRec.win.onClose=function(thiz,detour){ return function(){
detour.showPoints(false);
};}(this,detour);
if(detour!=null)
{
detour.showPoints(true);
detour.visible=true;
}
}
//Вернуть объект TDetour по идентификатору
getDetourByID(id)
{
for(let i=0;i<this.geofences.length;i++)
{
if(this.geofences[i].id==id)
return this.geofences[i];
}
return null;
}
clear()
{
//Удаляю геометриию
for(var i=0;i<this.geofences.length;i++)
{
this.geofences[i].visible=false;
}
this.geofences = [];
}
//Инвертировать видимость маршрутов
hide()
{
for(let i=0;i<this.geofences.length;i++)
{
this.geofences[i].visible=!this.geofences[i].visible;
}
}
newGeofence(data){
let obj = new TGeofence(this,data);
this.geofences.push(obj);
return obj;
}
}
class TGeofence
{
constructor(parent,conf){
this.parent=parent;
this.id=0;
this.feature=null; //Иконка на карте
this.featureG=null; //Геозона на карте (загружается отдельно)
this.shP=false; //Показывать ли точки для редактирования
this.visible_marker=false;
this.expand=false;
this.name='';
this.lon=0;
this.lat=0;
this.count=0;
this.setData(conf);
}
setData(conf){
if(conf !== undefined && conf !== null) {
if(conf.hasOwnProperty('id') && this.id != conf.id) this.id = conf.id;
if(conf.hasOwnProperty('name') && this.name != conf.name) this.name = conf.name;
if(conf.hasOwnProperty('count') && this.count != conf.count) this.count = conf.count;
if(conf.hasOwnProperty('geofence_type_name') && this.geofence_type_name != conf.geofence_type_name) this.geofence_type_name = conf.geofence_type_name;
if(conf.hasOwnProperty('lon') && this.lon != parseFloat(conf.lon)) this.lon = parseFloat(conf.lon);
if(conf.hasOwnProperty('lat') && this.lat != parseFloat(conf.lat)) this.lat = parseFloat(conf.lat);
}
}
get visible()
{
return this.visible_marker;
}
//Отобразить объект на карте
set visible(val)
{
if(val)
{
if(this.feature==null)
{
this.getGeoJSON(); //Подгружаем объект с сервера
}else
{
//Проверяю чтобы заново не добавить
let exists=false;
let features=g_vectorSourceGeofences.getFeatures();
for(let i=0;i<features.length;i++)
{
if(features[i]==this.feature)
{
exists=true;
break;
}
}
if(!exists)
g_vectorSourceGeofences.addFeature(this.feature);
}
}else{
if(this.feature!=null)
{
g_vectorSourceGeofences.removeFeature(this.feature);
this.showPoints(false);
}
}
this.visible_marker=val;
}
goToCenter()
{
let point=ol.proj.transform([this.lon, this.lat], 'EPSG:4326','EPSG:3857');
g_map.getView().setCenter(point);
if(g_map.getView().getZoom()<9)
g_map.getView().setZoom(9);
}
//Отобразить точки для редактирования
showPoints(val)
{
//alert("showPoints="+val);
this.shP=val;
if(this.shP)
enableEditPoints(this.feature);
else
disableEditPoints(this.feature);
return true;
}
//Запросить гео данные для построения объекта на карте
getGeoJSON()
{
if(this.feature!=null) return;
let data = {
id: this.id
};
$.ajax({
url: '/monitoring/pscripts/geofences.php?fn=2',
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
type: "POST",
dataType: "json",
success: function(thiz){return function(data,status){
if(status=='success')
{
let features = (new ol.format.GeoJSON()).readFeatures(data, {dataProjection: 'EPSG:4326',featureProjection: 'EPSG:3857'});
for(i=0;i<features.length;i++)
{
features[i].setStyle(new ol.style.Style({
fill: new ol.style.Fill({color: 'rgba(0, 255, 0, 0.5)'}),
stroke: new ol.style.Stroke({color: 'rgba(0, 100, 0, 0.7)', width: 2}),
text: new ol.style.Text({
font: 'bold 12px helvetica,sans-serif',
//text: userData.percent+" %",
fill: new ol.style.Fill({color: 'black'}),
stroke: new ol.style.Stroke({color: 'white', width: 1}),
offsetX: 0,
offsetY: 0
})
}));
thiz.feature=features[i]; //Должен быть один объект в объекте
thiz.feature.userData=thiz; //ссылка на родителя
g_vectorSourceGeofences.addFeature(thiz.feature);
//Если в режиме редактирования точек то отображаем эти точки
if(thiz.shP)
enableEditPoints(thiz.feature);
}
}else
{
alert2(trt('Alert'),status);
}
}}(this),
error: function (jqXHR, exception)
{
alert2(trt('Alert'),jqXHR.responseText);
}
});
}
//Удалить геозону
del()
{
confirm2(trt('Alert'), trt("Do_you_really_want_to_delete_the_record")+'?',
'',
()=>{
let data = {
id: this.id
};
$.ajax({
url: '/monitoring/pscripts/geofences.php?fn=3',
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
type: "POST",
dataType: "json",
success: (data,status)=>{
if(status=='success')
{
if(data.errorCode==0)
{
this.parent.filtering();
}else
{
alert2(trt('Error'),data.errorMessage);
}
}else
{
alert2(trt('Error'),trt('Failed_to_complete_the_request'));
}
},
error: ()=>{
alert2(trt('Error'),trt('Failed_to_complete_the_request'));
}
});
return true;
},
null);
}
}