Старт

This commit is contained in:
2023-11-07 19:51:49 +06:00
commit 86542a157f
5002 changed files with 199551 additions and 0 deletions

24
monitoring/config.php Normal file
View File

@ -0,0 +1,24 @@
<?php
$db_connection="pgsql:host=geovizor.com;dbname=monitoring_new;";
$db_login="postgres";
$db_password="y7HMHi0ATxx1VC3UU5WG";
$Schema="main.";
function connectToDB()
{
global $db_connection,$db_login,$db_password;
$db = null;
try
{
$db = new PDO($db_connection, $db_login, $db_password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $ex)
{
print $ex->getMessage();
error_log($ex->getMessage());
}
return $db;
}

View File

@ -0,0 +1,42 @@
.ol-popup {
position: absolute;
background-color: white;
-webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 350px;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}

69
monitoring/get.php Normal file
View File

@ -0,0 +1,69 @@
<?php
// error_reporting(E_ALL | E_STRICT);
// ini_set('display_errors','On');
ini_set('display_errors','Off'); //Чтоб ошибки не отправлялись клиентам
//ini_set("error_log", "php-error.log"); //Закоментил потому что удобней смотреть в 1м месте а не лазить по всем папкам...
date_default_timezone_set("UTC"); //Чтоб всё было по гринвичу
function createPath($path)
{
if (is_dir($path)) return true;
$prev_path = substr($path, 0, strrpos($path, '/', -2) + 1 );
$return = createPath($prev_path);
return ($return && is_writable($prev_path)) ? mkdir($path) : false;
}
if(isset($_REQUEST['x'])) $x=$_REQUEST['x']; else $x='';
if(isset($_REQUEST['y'])) $y=$_REQUEST['y']; else $y='';
if(isset($_REQUEST['z'])) $z=$_REQUEST['z']; else $z='';
if(isset($_REQUEST['s'])) $s=$_REQUEST['s']; else $s='';
if(isset($_REQUEST['lyrs'])) $lyrs=$_REQUEST['lyrs']; else $lyrs='m'; //Тип карты гибрид или чтото другое
//Проверяем есть ли файл в буфере
if (file_exists('./google/'.$lyrs.'/'.$z.'/'.$x.'/'.$y.'.png'))
{
//Чтоб переписать старенькие
$time_sec=time();
$time_file=filemtime('./google/'.$lyrs.'/'.$z.'/'.$x.'/'.$y.'.png');
$time=$time_sec-$time_file;
if($time<3*30*24*60*60) //Не старше 3х месяцев
{
header("Content-Type: image/png");
readfile('./google/'.$lyrs.'/'.$z.'/'.$x.'/'.$y.'.png');
Exit();
}
}
//Request URL: http://uspdmanager.istt.kz/get.php?hl=ru-RU&lyrs=m&x=357&y=193&z=9&s=
//$key = "YOUR KEY HERE";
//$url = "http://maps.google.com/maps/geo?q=".$address."&output=csv&key=".$key;
//$url = 'http://mt2.google.com/vt/v=w2.114&hl=ru-RU&gl=cn&&x='.$x.'&y='.$y.'&z='.$z.'&s='.$s;
$url = 'http://mt1.google.com/vt/lyrs='.$lyrs.'@199000000&hl=ru&src=app&x='.$x.'&y='.$y.'&z='.$z.'&s=Galileo';
//$url = 'http://mt1.google.com/vt/lyrs=m@152000000&hl=ru&x='.$x.'&y='.$y.'&z='.$z.'&s=Gali';
//Загружаем с помощью CURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER,0); //Change this to a 1 to return headers
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"]);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
//Сохраняем файл в буфер
if(strlen($data)>0)
{
createPath('./google/'.$lyrs.'/'.$z.'/'.$x);
$fp = fopen('./google/'.$lyrs.'/'.$z.'/'.$x.'/'.$y.'.png', 'w');
fwrite($fp, $data);
fclose($fp);
}
header("Content-Type: image/png");
echo $data;

62
monitoring/index.css Normal file
View File

@ -0,0 +1,62 @@
@charset "UTF-8";
body{
background-color: #3a3a3a;
scrollbar-base-color:#369;
scrollbar-width: thin;
scrollbar-color: var(--btn-color) var(--back-color-2);
}
table
{
font-size: 14px;
font-family: Arial;
}
input[type="text"], input[type="password"], textarea {
background-color : #454555;
}
select option {
background: var(--row-color-2);
color: var(--text-color-1);
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
}
select {
background: #454555;
color: #ffffff;
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
}
a {
color: #adadff;
}
blink {
-webkit-animation: 1s linear infinite condemned_blink_effect;
animation: 1s linear infinite condemned_blink_effect;
}
@-webkit-keyframes condemned_blink_effect {
0% {
visibility: hidden;
}
50% {
visibility: hidden;
}
100% {
visibility: visible;
}
}
@keyframes condemned_blink_effect {
0% {
visibility: hidden;
}
50% {
visibility: hidden;
}
100% {
visibility: visible;
}
}

264
monitoring/index.js Normal file
View File

@ -0,0 +1,264 @@
/**
* Igor Ivanov irigm@mail.ru
* [^\x00-\x7F]
*/
this.divsh=document.createElement('div'); //Shadow
divsh.style.cssText="display: none; position: fixed; z-index: 1000; top:0; left:0; height: 100%; width: 100%; background: rgba(0,0,0,0.3);";
var g_count=0;
var g_winCntMsg=null;
var g_events=null;
//Произграть музыку
function beep()
{
let audio = new Audio('/resources/sound/dilin.mp3');
audio.play();
}
//Назначить новое сообщение текущему пользователю (события разбиты по приоритету 0 низкий приоритет > 0 самый высокий)
function takeMessage()
{
g_winCntMsg.showProgressBar();
var data = {
test: ''
};
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
return;
}
if(data!=null)
{
if(data.errorCode=='0')
{
alert('Вам присвоено событие для обработки.'); //: "'+data.id+'"
}else
{
alert('Error: '+data.errorMessage);
}
}
g_winCntMsg.hideProgressBar();
}
};
}(this);
req.open("POST", '/monitoring/pscripts/messages.php?fn=2', true);
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(data));
}
//Выбор даты времени по щелчке на изображении
function setCalendar(field,img,day)
{
if (typeof field === 'string' || field instanceof String)
field=document.getElementById(field);
if (typeof img === 'string' || img instanceof String)
img=document.getElementById(img);
//Если задано смещение в датах то вставляем эту дату
if(typeof day === 'number')
{
var d = new Date();
d.setDate(d.getDate()+day);
field.value=d.toString();
}
new Calendar({
inputField: field,
dateFormat: "%Y-%m-%d %H:%M:%S",
trigger: img,
align: "Bl",
bottomBar: false,
showTime: true,
//singleClick: true,
onSelect: function(){ this.hide(); }
});
}
//Показать окно настроек (смена подложки и пароля)
function showConfigWidget()
{
this.win=new TWin();
this.win.BuildGUI(10,10);
this.win.setCaption(trt('Settings'));
let str='<div style="width: 100%; height: 100%; padding: 3px; text-align: left;">\n\
<div style="position: relative; padding-bottom:10px;">\n\
<b style="text-align:left; font-weight:bold;">Сменить стиль</b>\n\
<select id="theme-selector" style="width:100%;" onchange="changeTheme();"><option value="1">Тёмная тема</option><option value="2">Светлая тема</option></select>\n\
<b style="text-align:left; font-weight:bold;">'+trt('Substrate')+'</b>\n\
<table border="0" style="width: 100%;"><tr><td style="padding: 2px;">\n\
<select id="SubstrateID" style="width:100%;" onchange="changeMap();"><option value="OpenStreetMap">OpenStreetMap</option><option value="BingAerial">Bing aerial</option><option value="StamenTerrain">Stamen.com terrain</option><option value="GoogleMaps">Google maps</option><option value="GoogleMapsHybrid">Google maps hybrid</option><option value="yandex">Yandex maps</option></select>\n\
</td><td style="padding: 2px; width: 30px;">\n\
<button class="button-secondary" style="width:30px;" onclick="openLayoutsWin();">...</button><br>\n\
</td></tr></table>\n\
</div>\n\
<hr>\n\
<a href="#" id="call_change_pass">'+trt('Change_password')+'</a>\n\
</div>';
this.win.setContent(str);
this.win.setSize("420px","140px");
this.win.setCenter();
this.win.shadow=true;
this.win.hide(false);
document.getElementById('call_change_pass').onclick=function(){return function(){
g_user.changePassword();
};}();
//document.getElementById('id_exit_pass').onclick=function(win){return function(){win.Close();};}(win);
}
//Customize the visual elements on the access level.
function configGUIbyAccessLevel()
{
g_user.loadAccess();
g_user.onUpdate=function(user)
{
if(user.getAccess("Carrier")) //Если это перевозчик
{
deleteHTML('btnTerminalsModels');
deleteHTML('btnRoutes');
deleteHTML('btnRoutesCompanies');
//Скрываю "Сообщения"
//deleteHTML('lblMessages');
deleteHTML('btnMessages');
deleteHTML('btnMessagesUsers');
//Скрываю "Администрирование"
deleteHTML('lblAdministration');
deleteHTML('btnActions');
deleteHTML('btnAccess');
deleteHTML('btnGroups');
deleteHTML('btnUsers');
deleteHTML('btnHistory');
deleteHTML('btnMetadata');
//Скрываю "Компании"
deleteHTML('lblCompanies');
deleteHTML('btnCompanies');
deleteHTML('btnCompaniesTypes');
//Скрываю "Язык"
deleteHTML('lblLanguage');
deleteHTML('btnLanguage');
deleteHTML('btnTranslation');
}
//Если это автобусная станция то скрываем мониторинг
if(user.getAccess("Station")) //Если это перевозчик
{
//Скрываю "Администрирование"
deleteHTML('lblAdministration');
deleteHTML('btnActions');
deleteHTML('btnAccess');
deleteHTML('btnGroups');
deleteHTML('btnUsers');
deleteHTML('btnHistory');
deleteHTML('btnMetadata');
//Скрываю "Язык"
deleteHTML('lblLanguage');
deleteHTML('btnLanguage');
deleteHTML('btnTranslation');
//Скрываю вкладку мониторинг
//g_tab.delTab(g_tb_monitoring);
}
}
}
//Запросить данные для заполнения в всплывающее окно которое отображается при щелчке на значке на карте
function callObjectData(object_id)
{
$.ajax({
url: '/transit/object.php?object_id='+object_id,
type: "POST",
dataType: "text",
success: function(thiz){return function(data,status){
if(status=='success')
{
//alert('data = '+data);
m_winPP.hideProgressBar();
m_winPP.setContent(data);
}else
{
alert(status);
}
}}(this)
});
}
//Стиль для иконок пломб
function createFatypeStyleDel(feature,red)
{
return function(){
var zoom = g_map.getView().getZoom();
var text = zoom > 6 ? feature.get('name') : '';
var iconStyleG;
iconStyleG = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 25],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: '../resources/data/icons/'+feature.get('icon_name')
})),
text: new ol.style.Text({
font: '12px helvetica,sans-serif',
text: text,
fill: new ol.style.Fill({color: '#000'}),
stroke: new ol.style.Stroke({color: '#fff', width: 2})
})
});
return iconStyleG;
}
}
//Стиль для иконок пломб
function createFatypeStyleEvent(feature,red)
{
return function(){
var zoom = g_map.getView().getZoom();
//var text = zoom > 6 ? feature.get('name') : '';
var iconStyleG;
iconStyleG = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 25],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: '../resources/data/icons/'+feature.get('icon_name')
})),
text: new ol.style.Text({
font: '12px helvetica,sans-serif',
//text: text,
fill: new ol.style.Fill({color: '#000'}),
stroke: new ol.style.Stroke({color: '#fff', width: 2})
})
});
return iconStyleG;
}
}

1951
monitoring/index.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,491 @@
//Объезды
class TDetours
{
constructor(map){
this.detours = []; //Список маршрутов
}
//Получаем список объектов
//Фильтруем объекты для заполнения в таблицу
filtering()
{
showProgressBar(document.getElementById('id5_detours'));
var data = {
name: document.getElementById("filter_name_detours").value
};
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
return;
}
if(data!=null)
{
if(data.errorMessage !== undefined && data.errorMessage!='')
{
alert(data.errorMessage);
return;
}
thiz.clear();
//Приходит JSON уже в объектах
//features = [];
for(i=0;i<data.length;i++)
{
var obj = new TDetour(thiz);
obj.id=data[i].id;
obj.name=data[i].name;
obj.count=data[i].count;
obj.date_start=data[i].date_start;
obj.date_end=data[i].date_end;
obj.lon=parseFloat(data[i].lon);
obj.lat=parseFloat(data[i].lat);
thiz.detours.push(obj);
}
thiz.fillRezDiv();
}
hideProgressBar(document.getElementById('id5_detours'));
};
}
}(this);
req.open("POST", '/monitoring/pscripts/detours.php?fn=1', true);
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(data));
/*
var data = {
name: "",
type: ""
};
$.ajax({
url: '/monitoring/pscripts/detours.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.detours = []; //Удаляю старые объекты
g_vectorSourceDetours.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.detours.push(obj);
}
thiz.fillRezDiv();
}else
{
alert(status);
}
}}(this)
});
*/
}
//Заполнить результатом выборки DIV в виде таблицы
fillRezDiv()
{
var div=document.getElementById("id5_detours");
delChild(div);
div.innerHTML='<table id="thetable_detours" 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('Bypass_name')+'</th><th style="width: 1%;">Дата начала</th><th style="width: 1%;">Дата окончания</th><th style="width: 1%;">'+trt('Points')+'</th></tr></thead><tbody></tbody></table>';
var theTable = document.getElementById('thetable_detours');
for(i=0;i<this.detours.length;i++)
{
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;
tr.onmouseover=function(){ this.style.backgroundColor='var(--btn-color2)'; };
tr.onmouseout=function(val1,val2){return function(){val1.style.backgroundColor=val2;}}(tr,bgColor);
//tr.id='cell_e_'+this.detours[i].id;
let td;
td = document.createElement('td');
td.style.cssText="width:24px;text-align:center;vertical-align:top;";
td.innerHTML='<img id="detours_down_btn_'+this.detours[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="detours_ch_'+this.detours[i].id+'" type="checkbox"/>';
tr.appendChild(td);
td = document.createElement('td');
td.style.cursor='pointer';
td.innerHTML=this.detours[i].name;
td.onclick=function(detour){
return function(){
detour.goToCenter();
}
}(this.detours[i]);
tr.appendChild(td);
td = document.createElement('td');
td.style.cssText='cursor:pointer;text-align:right;';
td.innerHTML=this.detours[i].date_start;
td.onclick=function(detour){
return function(){
detour.goToCenter();
}
}(this.detours[i]);
tr.appendChild(td);
td = document.createElement('td');
td.style.cssText='cursor:pointer;text-align:right;';
td.innerHTML=this.detours[i].date_end;
td.onclick=function(detour){
return function(){
detour.goToCenter();
}
}(this.detours[i]);
tr.appendChild(td);
td = document.createElement('td');
td.style.cssText='cursor:pointer;text-align:right;';
td.innerHTML=this.detours[i].count;
td.onclick=function(detour){
return function(){
detour.goToCenter();
}
}(this.detours[i]);
tr.appendChild(td);
theTable.tBodies[0].appendChild(tr);
//Формирую раскрывающийся список
tr = document.createElement('tr');
tr.id=this.detours[i].id;
tr.style.cssText="background-color:var(--back-color-3);display:none";
td = document.createElement('td');
td.colSpan=6;
var html='<table style="width:100%;"><tr><td style="width:100%;border: 0;">';
html+=' ';
html+='</td><td valign="top" style="border: 0;"><img id="detour_del_'+this.detours[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.detours[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("detours_ch_"+this.detours[i].id);
cell.onclick=function(route){
return function(){
var chb=document.getElementById("detours_ch_"+route.id);
route.setVisibility(chb.checked);
}
}(this.detours[i]);
//Кнопка разсрыть список
var btn=document.getElementById('detours_down_btn_'+this.detours[i].id);
btn.onclick=function(tr,thiz,id){ return function(){
var btn=document.getElementById('detours_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.detours[i].id);
/*
//При щелчке по иконке календаря отображаем календарь выбора
//setCalendar("filter_date_route_start_"+this.detours[i].id,"filter_date_route_start_trigger_"+this.detours[i].id,-2);
//setCalendar("filter_date_route_end_"+this.detours[i].id,"filter_date_route_end_trigger_"+this.detours[i].id);
this.detours[i].getGeoJSON();
*/
//Кнопка удалить
btn=document.getElementById('detour_del_'+this.detours[i].id)
btn.onclick=function(thiz,id){ return function(){ thiz.deleteDetour({id:id}); }; }(this,this.detours[i].id);
//Кнопка редактировать
btn=document.getElementById('detour_edit_'+this.detours[i].id)
btn.onclick=function(thiz,id){ return function(){ thiz.editDetour({id:id}); }; }(this,this.detours[i].id);
}
//Количество элементов в дереве
var divCnt = document.getElementById("count_detours");
delChild(divCnt);
divCnt.appendChild(document.createTextNode(this.detours.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("Detours",-1,'<type n="Detours"><properties><prop n="name"><![CDATA['+document.getElementById("filter_name_detours").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);
}
//Удалить объезд
deleteDetour(settings)
{
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
if (confirm(trt("Do_you_really_want_to_delete_the_record")+'?')) {
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
return;
}
if(data!=null)
{
if(data.errorMessage !== undefined && data.errorMessage!='')
{
alert(data.errorMessage);
thiz.win.hideProgressBar();
}else
{
}
}
//Фильтрую список заново
thiz.filtering();
}
};
}(this);
req.open("POST", '/monitoring/pscripts/detours.php?fn=3', true);
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(settings));
this.filtering();
}
return true;
}
editDetour(settings)
{
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
var detour=this.getDetourByID(settings.id);
let eRec = new EdtRec("");
eRec.eRecNa("Detours",settings.id);
eRec.win.onClose=function(thiz,detour){ return function(){
detour.showPoints(false);
//thiz.filtering();
};}(this,detour);
if(detour!=null)
{
detour.showPoints(true);
detour.setVisibility(true);
}
}
//Вернуть объект TDetour по идентификатору
getDetourByID(id)
{
for(var i=0;i<this.detours.length;i++)
{
if(this.detours[i].id==id)
return this.detours[i];
}
return null;
}
clear()
{
//Удаляю геометриию
for(var i=0;i<this.detours.length;i++)
{
this.detours[i].setVisibility(false);
}
this.detours = [];
}
//Инвертировать видимость маршрутов
hide()
{
for(var i=0;i<this.detours.length;i++)
{
this.detours[i].setVisibility(!this.detours[i].getVisibility());
}
}
}
class TDetour
{
constructor(detours)
{
this.id='';
this.feature=null; //Объект который отображается на карте
this.shP=false; //Показывать ли точки для редактирования
this.detours=detours;
this.visible=false; //По умолчанию всё видим
}
getVisibility()
{
return this.visible;
}
//Отобразить объект на карте
setVisibility(val)
{
var chb=document.getElementById("detours_ch_"+this.id);
if(val)
{
if(!chb.checked) chb.checked=true;
if(this.feature==null)
{
this.getGeoJSON(); //Подгружаем объект с сервера
}else
{
//Проверяю чтобы заново не добавить
var exists=false;
var features=g_vectorSourceDetours.getFeatures();
for(var i=0;i<features.length;i++)
{
if(features[i]==this.feature)
{
exists=true;
break;
}
}
if(!exists)
g_vectorSourceDetours.addFeature(this.feature);
}
}else{
if(chb!=null && chb.checked) chb.checked=false;
if(this.feature!=null)
{
g_vectorSourceDetours.removeFeature(this.feature);
this.showPoints(false);
}
}
this.visible=val;
}
goToCenter()
{
var 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;
var data = {
id: this.id
};
$.ajax({
url: '/monitoring/pscripts/detours.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')
{
var 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_vectorSourceDetours.addFeature(thiz.feature);
//Если в режиме редактирования точек то отображаем эти точки
if(thiz.shP)
enableEditPoints(thiz.feature);
}
}else
{
alert(status);
}
}}(this)
});
}
};

View File

@ -0,0 +1,200 @@
/**
*
*/
//Список событий
class TEvents
{
constructor(map){
this.events = []; //Список событий
}
filtering()
{
var date;
var date_s,date_e;
date_s=document.getElementById("filter_X1_date_start_e").value;
date = new Date(date_s.replace(/-/g, "/"));
date_s=date.getTime()/1000;
if(isNaN(date_s)) date_s='';
date_e=document.getElementById("filter_X1_date_end_e").value;
date = new Date(date_e.replace(/-/g, "/"));
date_e=date.getTime()/1000;
if(isNaN(date_e)) date_e='';
var data = {
active: document.getElementById("active_e").value, //Установленна либо снята пломба
cnumber: document.getElementById("cnumber_e").value, //Гос. номер
tnumber: document.getElementById("tnumber_e").value, //Номер ТД
type: document.getElementById("type_e").value,
date_start: date_s,
date_end: date_e
};
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
return;
}
if(data!=null)
{
if(data.errorMessage !== undefined && data.errorMessage!='')
{
alert(data.errorMessage);
return;
}
thiz.events = [];
//Приходит JSON уже в объектах
features = [];
for(i=0;i<data.length;i++)
{
var feature=null;
var lon=parseFloat(data[i].lon);
var lat=parseFloat(data[i].lat);
if(!isNaN(lat) && !isNaN(lon))
{
feature = new ol.Feature({geometry: new ol.geom.Point(ol.proj.transform([lon,lat], 'EPSG:4326','EPSG:3857')),name: data[i].name,icon_name: data[i].icon_name});
feature.setStyle(createFatypeStyleEvent(feature,false));
feature.userType="TEvent";
//feature.userName='terrain';
feature.userID=data[i].id;
features.push(feature);
}
var obj = new TEvent();
obj.feature=feature;
obj.id=data[i].id;
obj.name=data[i].name;
obj.sensor_name=data[i].sensor_name;
obj.lon=parseFloat(data[i].lon);
obj.lat=parseFloat(data[i].lat);
obj.value=data[i].value;
obj.date=data[i].date;
//alert('obj.name = '+obj.name);
/*obj.declaration=data[i].declaration;
obj.icon_name=data[i].icon_name;
obj.lon=parseFloat(data[i].lon);
obj.lat=parseFloat(data[i].lat);
obj.alt=parseFloat(data[i].alt);
obj.utime=parseInt(data[i].utime);
obj.date=data[i].date;
obj.bat=parseFloat(data[i].bat);
obj.bat_date=data[i].bat_date;
obj.tros=parseFloat(data[i].tros);
obj.tros_date=data[i].tros_date;
obj.box=parseFloat(data[i].box);
obj.box_date=data[i].box_date;*/
thiz.events.push(obj);
}
g_vectorSource.clear(false);
g_vectorSource.addFeatures(features);
thiz.fillRezDiv();
}
};
}(this);
}
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(data));
req.open("POST", '/transit/events.php', true);
}
//Заполнить результатом выборки DIV в виде таблицы
fillRezDiv()
{
//alert('fillRezDiv');
var div=document.getElementById("div_tbl_e");
delChild(div);
div.innerHTML='<table id="thetable_e" border="0" style="width:100%;" class="SShow"><thead><tr style="background-color: rgb(218, 218, 218);"><th style="width: 1%;">Гос. номер</th><th style="width: 1%;">Тип события</th><th style="width: 1%;">Значение</th><th style="width: 1%;">Дата</th></tr></thead><tbody></tbody></table>';
var theTable = document.getElementById('thetable_e');
for(i=0;i<this.events.length;i++)
{
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);
tr.id='cell_e_'+this.events[i].id;
tr.style.cursor='pointer';
var td;
td = document.createElement('td');
td.innerHTML=this.events[i].name;
tr.appendChild(td);
td = document.createElement('td');
td.innerHTML=this.events[i].sensor_name;
tr.appendChild(td);
td = document.createElement('td');
td.innerHTML=this.events[i].value;
tr.appendChild(td);
td = document.createElement('td');
//ts.style.whiteSpace='nowrap';
td.innerHTML=this.events[i].date;
tr.appendChild(td);
theTable.tBodies[0].appendChild(tr);
//При щелчке на ячейку перемещаем карту на точку
var cell=document.getElementById("cell_e_"+this.events[i].id);
cell.onclick=function(object){
return function(){
alert('lon='+object.lon);
if(!isNaN(parseFloat(object.lon)))
{
g_map.getView().setCenter(ol.proj.transform([object.lon,object.lat], 'EPSG:4326','EPSG:3857'));
if(g_map.getView().getZoom()<9)
g_map.getView().setZoom(9);
}
}
}(this.events[i]);
//При щелчке по иконке календаря отображаем календарь выбора
//setCalendar("filter_date_route_start_"+this.events[i].id,"filter_date_route_start_trigger_"+this.events[i].id,-2);
//setCalendar("filter_date_route_end_"+this.events[i].id,"filter_date_route_end_trigger_"+this.events[i].id);
}
//Количество элементов в дереве
var divCnt = document.getElementById("count_e");
delChild(divCnt);
divCnt.appendChild(document.createTextNode(this.events.length));
}
}
//Событие из списка
class TEvent
{
constructor(map){
}
}

View File

@ -0,0 +1,672 @@
//Объезды
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);
}
}

View File

@ -0,0 +1,332 @@
//Класс для отображения и обработки сообщения пользователя
class TUserMessage
{
constructor(parent){
this.id=null;
this.parent = parent;
this.win = null;
}
//Отметить сообщение как обработанное
MarkAsProcessed(id)
{
var description=document.getElementById("msg_desc").value;
var data = {
id: id,
description: description
};
$.ajax({
url: '/monitoring/pscripts/messages.php?fn=5',
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
type: "POST",
dataType: "json",
success: function(thiz){return function(data,status){
if(status=='success')
{
if(data.errorCode=='0')
{
//alert(trt('Saved')+'!');
thiz.win.Close();
//Обновляю список
thiz.parent.Filtering();
}else
{
alert(trt('Error')+': "'+data.errorMessage);
thiz.win.hideProgressBar();
}
}else
{
alert(status);
thiz.win.hideProgressBar();
}
}}(this)
});
this.win.showProgressBar();
}
//Загрузить сообщение в окно
ShowMessage(id)
{
if(this.win!=null) this.win.Close();
this.win = new TWin();
this.win.setParent(this.parent.win);
this.win.BuildGUI(10,10);
this.win.setCaption(trt('Message'));
this.win.setSize("600px","400px");
this.win.setCenter();
this.win.hide(false);
this.win.showProgressBar();
//Запрашиваю данные для отображения в окне
var data = {
id: id
};
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
thiz.win.hideProgressBar(); //Всё "OK" скрываю "Progress bar"
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
}
if(data!=null)
{
//Отображаю окошко с необработанными сообщениями
var html='<table class="SShow" style="width:100%;height:100%; background-color: #3a3a3a;">';
html+='<thead><tr><th style="width:30%;">'+trt('Name')+'</th><th style="width:70%;">'+trt('Value')+'</th></tr></thead>';
html+='<tr><td style="padding:2px;font-weight:bold;vertical-align:top;">'+trt('Theme')+'</td><td style="padding: 2px;vertical-align:top;">'+trt(data.subject)+'</td>';
html+='<tr style="height:100%;"><td style="font-weight:bold;padding:2px;vertical-align:top;">'+trt('Content')+'</td><td style="padding: 2px;vertical-align:top;">'+data.text+'</td></tr>';
if(data.action_name!='' && data.action_name!=null)
{
html+='<tr"><td style="padding:2px;vertical-align:top;">'+trt('Action')+'</td><td style="padding: 2px;vertical-align:top;"><button type="button" class="button-secondary" id="create_msg_a" style="width:100%;">'+trt(data.action_name)+'</button></td></tr>';
}
html+='<tr style="height:100%;"><td style="padding:2px;vertical-align:top;">'+trt('Additional_Information')+' ('+trt('Action_taken')+')'+'</td><td style="padding: 2px;vertical-align:top;"><textarea id="msg_desc" style="width:100%;height:100px;"></textarea></td></tr>';
html+='<tr><td style="padding: 2px;text-align:right;" colspan="2"><button class="button-secondary" onclick="g_UserMessage.MarkAsProcessed('+data.id+');">'+trt('Mark_as_processed')+'</button></td></tr>';
html+='</table>';
thiz.win.setContent(html);
//Обработчик события нажатия на кнопку действия
var btn = document.getElementById('create_msg_a');
if(btn!=null)
{
btn.onclick=function(name,settings){ return function(){
if(name=='Create_trip')
g_trips.createTrip(settings);
else if(name=='Edit_trip')
g_trips.editTrip(settings);
else
alert('Unknown action "'+name+'"!');
}; }(data.action_name,data.action_settings);
}
}
}
};
}(this);
req.open("POST", '/monitoring/pscripts/messages.php?fn=4', true);
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(data));
}
}
class TUserMessages
{
consctuctor(){
this.win = null;
}
//this.win.addResizeListener(function(obj){return function(){obj.updateSize();}}(this));
//Update dimensions of the elements (the main table in absolute coordinates).
updateSize()
{
var dv1=document.getElementById("tblMsgContainer");
var dv2=document.getElementById("tblMsgSContainer");
if(dv1!=null && dv2!=null)
{
dv1.style.width = dv2.offsetWidth+"px";
dv1.style.height = dv2.offsetHeight+"px";
}
}
//Отобразить окно с сообщениями пользователя
ShowMessages()
{
if(this.win!=null) this.win.Close();
this.win=new TWin();
this.win.BuildGUI(10,10);
this.win.setCaption(trt('User_messages'));
this.win.setSize("1000px","500px");
this.win.hide(false);
var content = '';
content+='<table style="width:100%; height:100%;"><tr><td>';
content+='<table style="width:100%; border: 1px solid rgb(99, 99, 99); table-layout: auto; margin-bottom: 10px;">';
content+='<caption></caption>';
content+='<thead></thead>';
content+='<tbody>';
content+=' <tr><td style="padding: 1px; white-space: nowrap;">'+trt('Company')+'</td><td style="padding: 1px; width: 100%;"><select id="sCompany_3" style="width: 100%;"></select></td></tr>';
content+=' <tr><td style="padding: 1px; white-space: nowrap;">'+trt('Status')+'</td><td style="padding: 1px; width: 100%;"><select id="sEvents_3" style="width: 100%;"><option value="1">'+trt('Processed')+'</option><option selected="selected" value="0">'+trt('Unprocessed')+'</option></select></td></tr>';
content+=' <tr><td style="padding: 1px;"></td><td style="padding: 1px; text-align:right;"><input class="button-secondary" type="button" value="Фильтровать" id="btnfilter_3"></td></tr>';
content+='</tbody>';
content+='</table>';
//Контент
content+='</td></tr><tr><td style="width:100%; height:100%;">';
content+='<div id="tblMsgSContainer" style="width:100%; height:100%;" bgcolor="green">';
content+='<div id="tblMsgContainer" style="position: absolute; overflow: scroll; width: 400px; height: 300px;">';
content+='</div>';
content+='</div>';
content+='</td></tr></table>';
this.win.setContent(content);
this.win.setCenter();
this.win.addResizeListener(function(thiz){return function(){thiz.updateSize();}}(this));
//Кнопочка фильтровать
var obj = document.getElementById("btnfilter_3");
obj.onclick = function(thiz){ return function(){ thiz.Filtering(); };}(this);
//Запрашиваю данные для заполнения выпадающего списка компаний
this.Filtering();
//Запрашиваю данные для заполнения компании
$.ajax({
url: "/monitoring/pscripts/user.php?fn=10",
type: "POST",
success: function(response) {
let b = document.getElementById("sCompany_3");
b.innerHTML += response;
}
});
}
//Запросить данные для отображения в фильтре
Filtering()
{
var data = {
state: ''
};
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
}
if(data!=null)
{
if(data.errorMessage !== undefined && data.errorMessage!='')
{
alert(data.errorMessage);
thiz.win.hideProgressBar();
return;
}
//Отображаю окошко с необработанными сообщениями
var html='<table class="SShow">';
html+='<thead><tr style="background-color: rgb(218, 218, 218);"><th>Тема</th><th>Содержание</th></tr></thead>';
for(i=0;i<data.length;i++)
{
let bgColor='';
if (i%2==0) bgColor='var(--row-color-1)'; else bgColor='var(--row-color-2)';
html+='<tr onclick="g_UserMessage.ShowMessage('+data[i].id+');" onmouseover="this.style.backgroundColor=\'var(--btn-color2)\';" onmouseout="this.style.backgroundColor=\''+bgColor+'\';" style="cursor: pointer; background-color:'+bgColor+';">';
//html+='<td>'+data[i].id+'</td>';
html+='<td>'+data[i].subject+'</td>';
html+='<td>'+data[i].text+'</td>';
html+='</tr>';
/*var userMessage = new TUserMessage();
userMessage.id=data[i].id;
thiz.messages.push(userMessage);*/
}
html+='</table>';
var cont=document.getElementById("tblMsgContainer");
cont.innerHTML = html;
}
thiz.win.hideProgressBar();
}
};
}(this);
req.open( "GET", '/monitoring/pscripts/messages.php?fn=3&status='+document.getElementById("sEvents_3").value, true );
req.send( null );
this.win.showProgressBar();
}
}
var g_UserMessages = new TUserMessages();
var g_UserMessage = new TUserMessage(g_UserMessages);
//Функция для переодическогой проверки количество сообщений требующих обработки а также кол-во сообщений для текущего пользователя
function getAllMessagesCount()
{
var data = {
test: ''
};
$.ajax({
url: '/monitoring/pscripts/messages.php?fn=1',
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
type: "POST",
dataType: "json",
success: function(thiz){return function(data,status){
if(status=='success')
{
//Отображаю окошко с количеством необработанных сообщений
if(g_winCntMsg==null || g_winCntMsg.closed==true)
{
g_winCntMsg=new TWin();
g_winCntMsg.BuildGUI(20,60);
g_winCntMsg.setCaption(trt('Messages'));
//this.win.setContent(str);
g_winCntMsg.setSize("130px","120px");
//g_winCntMsg.setCenter();
//g_winCntMsg.shadow=true;
g_winCntMsg.hide(false);
}
//g_winCntMsg.setLeftTop(20,60);
g_winCntMsg.hide(false);
if(g_count!=parseInt(data.count))
{
beep();
g_count = parseInt(data.count);
}
var mCNTUser = parseInt(data.user);
var content = '';
content+=trt("Unassigned")+":<br>";
if(g_count>0){
content+="<button class=\"button-secondary\" id=\"takeMessage\" style=\"width:100%;height:50px;font-size:24pt;font-weight:bold;color:red;\" onclick=\"takeMessage();\"><blink class=\"blink\">"+g_count+"</blink></button>";
}else{
content+="<button class=\"button-secondary\" id=\"takeMessage\" style=\"width:100%;height:50px;font-size:24pt;font-weight:bold;\" onclick=\"takeMessage();\">"+g_count+"</button>";
}
content+=trt("Designated")+":<br>";
if(mCNTUser>0){
content+="<button class=\"button-secondary\" style=\"width:100%;height:50px;font-size:24pt;font-weight:bold;color:red;\" onclick=\"g_UserMessages.ShowMessages();\"><blink class=\"blink\">"+mCNTUser+"</blink></button>";
}else{
content+="<button class=\"button-secondary\" style=\"width:100%;height:50px;font-size:24pt;font-weight:bold;\" onclick=\"g_UserMessages.ShowMessages();\">0</button>";
}
g_winCntMsg.setContent(content);
}else
{
alert(status);
}
}}(this)
});
}
//Запрашиваем каждые 5 секунд
var timerId = setInterval(function() {
getAllMessagesCount();
}, 5000);

View File

@ -0,0 +1,857 @@
//Список автомобилей
class TObjects
{
constructor(map)
{
this.objects = [];
this.map=map;
setInterval(_=>{this.updateData();}, 10000); //Запускаю таймер для обновления объектов раз в 10 секунд
setInterval(_=>{this.updateForecastLonLat();}, 500); //Запускаю функцию для перемещения объектов по прогнозному маршруту
}
//Фильтруем объекты для заполнения в таблицу
filtering()
{
showProgressBar(document.getElementById('div_tbl_monitoring'));
let company_id=document.getElementById("company_id_m");
if(company_id==null)
{
company_id=g_user.company_id;
}else
{
company_id=company_id.value;
}
let data = {
company_id: company_id,
cnumber: document.getElementById("cnumber_m").value
};
$.ajax({
url: '/monitoring/pscripts/objects.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.objects = []; //Удаляю старые объекты
//Приходит JSON уже в объектах
let features = [];
for(let i=0;i<data.length;i++)
{
let feature=null;
let lon=parseFloat(data[i].lon);
let lat=parseFloat(data[i].lat);
if(!isNaN(lat) && !isNaN(lon))
{
let point = new ol.geom.Point(ol.proj.transform([lon,lat], 'EPSG:4326','EPSG:3857'));
feature = new ol.Feature({geometry: point,name: data[i].name,icon_name: data[i].icon_name});
feature.setStyle(createFatypeStyleDel(feature,false));
feature.userType="TObject";
feature.userID=data[i].id;
features.push(feature);
}
var obj = new TObject();
obj.feature=feature;
obj.id=data[i].id;
obj.seq=data[i].seq;
obj.active=data[i].active; //Активная или нет перевозка
obj.name=data[i].name;
obj.terminal_name=data[i].terminal_name;
obj.declaration=data[i].declaration;
obj.icon_name=data[i].icon_name;
obj.lon=parseFloat(data[i].lon);
obj.lat=parseFloat(data[i].lat);
obj.alt=parseFloat(data[i].alt);
obj.utime=parseInt(data[i].utime);
obj.speed=data[i].speed;
obj.date=data[i].date;
obj.geofences=data[i].geofences;
obj.bat=parseFloat(data[i].bat);
obj.bat_date=data[i].bat_date;
obj.tros=parseFloat(data[i].tros);
obj.tros_date=data[i].tros_date;
obj.box=parseFloat(data[i].box);
obj.box_date=data[i].box_date;
obj.sensors=data[i].sensors;
//alert("obj.box = "+obj.box+" obj.box_date = "+obj.box_date);
thiz.objects.push(obj);
}
g_vectorSource.clear(false);
g_vectorSource.addFeatures(features);
thiz.fillRezDiv();
}else
{
alert(status);
}
hideProgressBar(document.getElementById('div_tbl_monitoring'));
}}(this)
});
}
//Заполнить результатом выборки DIV в виде таблицы
fillRezDiv()
{
let div=document.getElementById("div_tbl_monitoring");
delChild(div);
div.innerHTML='<table id="thetable" border="0" style="width:100%;" class="SShow"><thead><tr style="background-color: rgb(218, 218, 218);"><th style="width:24px;"></th><th id="object_ch_M" style="width:36px;text-decoration:underline;cursor: pointer;">'+trt('View')+'.</th><th></th><th>'+trt('Object_of_observation')+'</th><th style="width:70px;">'+trt('Speed')+'</th><th style="width:75px;white-space:nowrap;" valign="middle"><img src="/resources/images/clock.png" alt="">'+trt('Date')+'</th></tr></thead><tbody></tbody></table>';
var theTable = document.getElementById('thetable');
for(i=0;i<this.objects.length;i++)
{
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;
tr.onmouseover=function(){this.style.backgroundColor='var(--btn-color2)';};
tr.onmouseout=function(val1,val2){return function(){val1.style.backgroundColor=val2;}}(tr,bgColor);
let td;
td = document.createElement('td');
td.style.cssText="width:24px;text-align:center;vertical-align:top;";
td.innerHTML='<img id="object_down_btn_'+this.objects[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="object_ch_'+this.objects[i].uid+'" type="checkbox" checked/>';
tr.appendChild(td);
td = document.createElement('td');
td.style.cssText="text-align: center; width:30px;";
td.innerHTML='<img src="../resources/data/icons/'+this.objects[i].icon_name+'" alt="">';
tr.appendChild(td);
td = document.createElement('td');
td.style.cursor='pointer';
td.innerHTML=this.objects[i].name;
td.onclick=function(object){return function(){object.goToCenter();}}(this.objects[i]);
tr.appendChild(td);
td = document.createElement('td');
td.style.cssText="white-space:nowrap;";
td.style.cursor='pointer';
if(this.objects[i].speed!=null)
td.innerHTML=this.objects[i].speed+' '+trt('km_h');
td.onclick=function(object){return function(){object.goToCenter();}}(this.objects[i]);
tr.appendChild(td);
td = document.createElement('td');
td.id='date_'+this.objects[i].uid;
td.style.cursor='pointer';
td.innerHTML=this.objects[i].date;
td.onclick=function(object){return function(){object.goToCenter();}}(this.objects[i]);
tr.appendChild(td);
/*td = document.createElement('td');
var tros='-';
if(!isNaN(this.objects[i].tros))
tros=this.objects[i].tros +' '+ trt('Flag');
var tros_date='-';
if (typeof this.objects[i].tros_date != 'undefined')
tros_date=this.objects[i].tros_date;
var bat='-';
if(!isNaN(this.objects[i].bat)) bat= this.objects[i].bat+'%';
var bat_date='-';
if (typeof this.objects[i].bat_date != 'undefined')
bat_date=this.objects[i].bat_date;
var box='-';
if(!isNaN(this.objects[i].box))
box=this.objects[i].box +' '+ trt('Flag');
var box_date='-';
if (typeof this.objects[i].box_date != 'undefined')
box_date=this.objects[i].box_date;
td.innerHTML='<table border="0" style="width:100%;">\
<tr id="cell_'+this.objects[i].id+'" style="cursor: pointer;"><td style="width:30px;"></td><td></td><td style="width:20px;"><img src="/resources/images/clock.png" alt=""></td><td style="width:145px;"></td></tr>\
<tr style="background-color: #ffffff;"><td colspan="4" id="cell_data_'+this.objects[i].id+'" style="display: none;">\
<table border="0" style="width:100%;">\
<tr><td style="width:30px;"> </td><td style="border-bottom: 1px solid #7a7a7a;" colspan="4">\
<table>\
<tr>\
<td style="padding: 1px; width: 100%;">\
<table style="width: 100%;" border="0">\
<tr>\
<td style="width: 10px; padding: 1px; white-space: nowrap;">Маршрут, </td>\
<td style="width: 10px; padding: 1px;">c</td>\
<td style="width: 40%; padding: 1px;">\
<table style="width: 100%; table-layout: fixed; border-spacing: 0px; border-collapse: collapse;" border="0">\
<tr>\
<td style="width: 100%;"><input style="width: 100%;" name="date_start" value="" id="filter_date_route_start_'+this.objects[i].id+'" type="text"></td>\
<td style="width: 25px;"><img id="filter_date_route_start_trigger_'+this.objects[i].id+'" src="../resources/images/datepicker.jpg" style="margin-left: 1px; cursor: pointer;"></td>\
</tr>\
</table>\
</td>\
<td style="width: 10px; padding: 1px; white-space: nowrap;" width="1%">по</td>\
<td style="width: 40%; padding: 1px;">\
<table style="width: 100%; table-layout: fixed; border-spacing: 0px; border-collapse: collapse;" border="0">\
<tr>\
<td style="width: 100%;"><input style="width: 100%;" name="date_end" value="" id="filter_date_route_end_'+this.objects[i].id+'" type="text"></td>\
<td style="width: 25px;"><img id="filter_date_route_end_trigger_'+this.objects[i].id+'" src="../resources/images/datepicker.jpg" style="cursor: pointer; margin-left: 1px;"></td>\
</tr>\
</table>\
</td>\
</tr>\
</table>\
</td>\
</tr>\
<tr>\
<td style="padding: 1px; width: 100%;">\
<table style="width: 100%;" border="0">\
<tr>\
<td style="padding: 1px; white-space: nowrap;text-align:left;"><button onclick="g_objects.getObjectByID('+this.objects[i].id+').showDetailedInformation();">'+trt('Detailed_information')+'</button></td><td><td style="padding: 1px; white-space: nowrap;text-align:right;" width="1%" colspan="3"><button onclick="g_objects.getObjectByID('+this.objects[i].id+').getObjectTrack();">Отобразить маршрут</button><button onclick="g_objects.getObjectByID('+this.objects[i].id+').hideObjectTrack();">Скрыть</button></td>\
</tr>\
</table>\
</td>\
</tr>\
</table>\
</td></tr>\
</table>\
</td></tr></table>';
tr.appendChild(td);*/
theTable.tBodies[0].appendChild(tr);
//Формирую раскрывающийся список
tr = document.createElement('tr');
tr.id=this.objects[i].id;
tr.style.cssText="background-color:var(--back-color-3);display:none";
td = document.createElement('td');
td.colSpan=6;
let html='';
html+='<b>'+trt('Geofence_groups')+':</b> <img id="object_edit4_'+this.objects[i].uid+'" src="/resources/images/edit16.png" alt="'+trt('Edit')+'" title="'+trt('Edit')+'" style="cursor:pointer;"> '+this.objects[i].geofences+'<br>';
html+=' <table border="0" style="width:100%; border:none;">\
<tr><td style="width:30px;border:none;"> </td><td style="width: 50%;border:none;border-bottom: 1px solid #7a7a7a;">'+trt('Terminal')+'</td><td colspan="4" style="border:none;border-bottom: 1px solid #7a7a7a;">'+this.objects[i].terminal_name+'</td></tr>';
for(let j=0;j<this.objects[i].sensors.length;j++)
{
html+='<tr><td style="width:30px;border:none;"> </td><td style="width: 50%;border:none;border-bottom: 1px solid #7a7a7a;">'+trt(this.objects[i].sensors[j].name)+'</td><td id="svalue_'+this.objects[i].sensors[j].id+'_'+this.objects[i].uid+'" style="border:none;border-bottom: 1px solid #7a7a7a;">'+this.objects[i].sensors[j].value+'</td><td>'+this.objects[i].sensors[j].type_name+'</td><td style="width:20px;border:none;border-bottom: 1px solid #7a7a7a;"><img src="/resources/images/clock.png" alt=""></td><td id="sdate_'+this.objects[i].sensors[j].id+'_'+this.objects[i].uid+'" style="width:145px;border:none;border-bottom: 1px solid #7a7a7a;">'+this.objects[i].sensors[j].date+'</td></tr>';
}
html+='\
<tr style="width: 100%;"><td style="border:none; text-align: right; width: 100%;" colspan="6">\
<table>\
<tr>\
<td style="padding: 1px; width: 100%; border:none;">\
<table style="width: 100%;" border="0">\
<tr>\
<td style="width: 10px; padding: 1px; white-space: nowrap; border:none;">'+trt('Route')+', </td>\
<td style="width: 10px; padding: 1px;border:none;">c</td>\
<td style="width: 40%; padding: 1px;border:none;">\
<table style="width: 100%; table-layout: fixed; border-spacing: 0px; border-collapse: collapse;" border="0">\
<tr>\
<td style="width: 100%;border:none;"><input style="width: 100%;" name="date_start" value="" id="filter_date_route_start_'+this.objects[i].id+'" type="text"></td>\
<td style="width: 25px;border:none;"><img id="filter_date_route_start_trigger_'+this.objects[i].id+'" src="../resources/images/datepicker.jpg" style="margin-left: 1px; cursor: pointer;"></td>\
</tr>\
</table>\
</td>\
<td style="width: 10px; padding: 1px; white-space: nowrap;border:none;" width="1%">по</td>\
<td style="width: 40%; padding: 1px;border:none;">\
<table style="width: 100%; table-layout: fixed; border-spacing: 0px; border-collapse: collapse;" border="0">\
<tr>\
<td style="width: 100%;border:none;"><input style="width: 100%;" name="date_end" value="" id="filter_date_route_end_'+this.objects[i].id+'" type="text"></td>\
<td style="width: 25px;border:none;"><img id="filter_date_route_end_trigger_'+this.objects[i].id+'" src="../resources/images/datepicker.jpg" style="cursor: pointer; margin-left: 1px;"></td>\
</tr>\
</table>\
</td>\
</tr>\
</table>\
</td>\
</tr>\
<tr>\
<td style="padding: 1px; width: 100%;border:none;">\
<table style="width: 100%;" border="0">\
<tr>\
<td style="padding: 1px; white-space: nowrap;text-align:left;border:none;"><button class="button-secondary" onclick="g_objects.getObjectByID('+this.objects[i].id+').showDetailedInformation();">'+trt('Detailed_information')+'</button></td><td style="padding: 1px; white-space: nowrap;text-align:right;border:none;" width="1%" colspan="3"><button class="button-secondary" onclick="g_objects.getObjectByID('+this.objects[i].id+').getObjectTrack();">'+trt('Show_route')+'</button><button class="button-secondary" onclick="g_objects.getObjectByID('+this.objects[i].id+').hideObjectTrack();">'+trt('Hide')+'</button></td>\
</tr>\
</table>\
</td>\
</tr>\
</table>\
</td></tr>\
</table>';
td.innerHTML=html;
tr.appendChild(td);
theTable.tBodies[0].appendChild(tr);
//Кнопка редактировать грепп геозон объекта
btn=document.getElementById('object_edit4_'+this.objects[i].uid)
btn.onclick=function(thiz,id){ return function(){
var settings='<type n="ObjectsGeofences"><objects-list><filter><column n="object_id"><![CDATA['+id+']]></column></filter></objects-list></type>';
myFunction('ObjectsGeofences',settings);
}; }(this,this.objects[i].id);
//Чекбукс скрыть показать
var cell=document.getElementById("object_ch_"+this.objects[i].uid);
cell.onclick=function(object){
return function(){
var chb=document.getElementById("object_ch_"+object.uid);
object.setVisibility(chb.checked);
}
}(this.objects[i]);
//Кнопка разсрыть список
var btn=document.getElementById('object_down_btn_'+this.objects[i].id);
btn.onclick=function(tr,thiz,id){ return function(){
var btn=document.getElementById('object_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.objects[i].id);
/*
//При щелчке на ячейку открываем содержимое и перемещаем карту на точку
var cell=document.getElementById("cell_"+this.objects[i].id);
cell.onclick=function(object){
return function(){
var cell=document.getElementById("cell_data_"+object.id);
if(cell.style.display=="none")
{
cell.style.display="table-cell";
}else{
cell.style.display="none";
}
//Пытаемся переместиться на точку на карте
if(!isNaN(parseFloat(object.lon)))
{
g_map.getView().setCenter(ol.proj.transform([object.lon,object.lat], 'EPSG:4326','EPSG:3857'));
if(g_map.getView().getZoom()<9)
g_map.getView().setZoom(9);
}
}
}(this.objects[i]);
*/
//При щелчке по иконке календаря отображаем календарь выбора
setCalendar("filter_date_route_start_"+this.objects[i].id,"filter_date_route_start_trigger_"+this.objects[i].id,-2);
setCalendar("filter_date_route_end_"+this.objects[i].id,"filter_date_route_end_trigger_"+this.objects[i].id);
}
//Количество элементов в дереве
var divCnt = document.getElementById("count_m");
delChild(divCnt);
divCnt.appendChild(document.createTextNode(this.objects.length));
//По нажатию на заголовок инвертируем чекбуксы
divCnt = document.getElementById("object_ch_M");
divCnt.onclick=function(thiz){
return function(){
thiz.hide();
}
}(this);
}
getObjectByID(id)
{
var obj=null;
for(var i=0;i<this.objects.length;i++)
{
if(this.objects[i].id==id)
{
obj = this.objects[i];
}
}
return obj;
}
//Обновляю дату и коордионаты для выбраного списка (вызывается раз в 10 секунд)
updateData()
{
//console.log("updateData len="+this.objects.length);
if(this.objects.length==0) return true;
//Пересылаю список идентификаторов для которых хотим получить обновления
var data = [];
for(i=0;i<this.objects.length;i++)
{
data.push(parseInt(this.objects[i].id));
}
$.ajax({
url: '/monitoring/pscripts/objects.php?fn=1',
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
type: "POST",
dataType: "json",
success: function(thiz){return function(data,status){
if(status=='success')
{
//console.log("data1 = "+JSON.stringify(data));
//Перебираю элементы и обновляю соответствующие поля
for(var i=0;i<data.length;i++)
{
//console.log("data[i].id = "+data[i].id);
//console.log("data[i].date = "+data[i].date);
var obj=thiz.getObjectByID(data[i].id);
if(obj!=null)
{
obj.date=data[i].date;
obj.setLonLat(data[i].lon,data[i].lat);
for(let j=0;j<data[i].sensors.length;j++)
{
let sns=obj.getSensorByID(data[i].sensors[j].id);
if(sns!=null)
{
sns.value=data[i].sensors[j].value;
sns.date=data[i].sensors[j].date;
}
}
obj.updateGUI();
}
}
}else
{
alert(status);
}
}}(this)
});
}
//Инвертировать видимость маршрутов
hide()
{
for(var i=0;i<this.objects.length;i++)
{
this.objects[i].setVisibility(!this.objects[i].getVisibility());
}
}
//Обновить прогнозные точки в автомобилях (раз в 0.5 секунд)
updateForecastLonLat()
{
if(g_user.getSettings('route_forecast',false)!=='true') return;
for(let i=0;i<this.objects.length;i++)
{
this.objects[i].goToForecast();
}
}
}
//Конкретный автомобиль (объект, установка)
class TObject
{
constructor(){
this.uid=getUID(); //Уникальный идентификатор
this.active=1; //1 - пломба активная, 0 - пломба не активная
this.name=''; //Гос номер автомобиля
this.id=0; //Идентификатор записи (установки)
this.lon=0; //Долгота
this.lat=0; //Широта
this.alt=0; //Высота в метрах
this.icon_name="testicon";
this.sensors=null;
//Трос
//Аккумулятор
//Датчик вскрытия
this.feature=null; //Объект который отображается на карте
this.visible=true; //По умолчанию всё видим
}
getVisibility()
{
return this.visible;
}
//Отобразить объект на карте
setVisibility(val)
{
var chb=document.getElementById("object_ch_"+this.uid);
if(val)
{
if(!chb.checked) chb.checked=true;
if(this.feature==null)
{
//this.getGeoJSON(); //Подгружаем объект с сервера
}else
{
//Проверяю чтобы заново не добавить
var exists=false;
var features=g_vectorSource.getFeatures();
for(var i=0;i<features.length;i++)
{
if(features[i]==this.feature)
{
exists=true;
break;
}
}
if(!exists)
g_vectorSource.addFeature(this.feature);
}
}else{
if(chb!=null && chb.checked) chb.checked=false;
if(this.feature!=null)
{
g_vectorSource.removeFeature(this.feature);
//this.showPoints(false);
}
}
this.visible=val;
}
//Запрашиваем трек автомобиля (объект, установка)
getObjectTrack()
{
var dStart=new Date(document.getElementById("filter_date_route_start_"+this.id).value).getTime() / 1000;
var dEnd=new Date(document.getElementById("filter_date_route_end_"+this.id).value).getTime() / 1000;
if(isNaN(dStart)) dStart='';
if(isNaN(dEnd)) dEnd='';
//alert('dStart = '+dStart+' dEnd = ' + dEnd);
var data = {
object_id: this.id, //Идентификатор объекта
date_start: dStart, //Начало выборки UNIX время
date_end: dEnd //Конец выборки UNIX время
};
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
}
if(data!=null)
{
//alert('data.length = '+data.length);
if(data.length>=2) //Если количество точек >2
{
//Создаю массив точек
var points=[];
for(i=0;i<data.length;i++)
{
var point=[parseFloat(data[i].lon),parseFloat(data[i].lat)];
point = ol.proj.transform(point, 'EPSG:4326', 'EPSG:3857');
points.push(point);
}
var line = new ol.geom.LineString(points)
let featureL = new ol.Feature({
geometry: line
});
featureL.userID=thiz.id;
var style=new ol.style.Style(
{
fill: new ol.style.Fill({ color: '#6363fc', weight: 4 }),
stroke: new ol.style.Stroke({ color: '#6363fc', width: 3 })
});
featureL.setStyle(style);
g_vectorSource.addFeature(featureL);
//Создаю точки для отображения подробной информации
for(let i=0;i<data.length;i++)
{
var lon=parseFloat(data[i].lon);
var lat=parseFloat(data[i].lat);
if(!isNaN(lat) && !isNaN(lon))
{
let feature = new ol.Feature({geometry: new ol.geom.Point(ol.proj.transform([parseFloat(data[i].lon),parseFloat(data[i].lat)], 'EPSG:4326','EPSG:3857'))});
feature.userID=thiz.id;
let style = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 0.5],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
src: '../resources/images/point.png'
}))
});
feature.setStyle(style);
feature.userType='TTrackPoint';
feature.userHTML='<b>'+trt('Date')+'</b>: '+(new Date(data[i].udate*1000))+'<br>';
feature.userHTML+='<b>'+trt('Latitude')+'</b>: '+data[i].lat+' <b>'+trt('Longitude')+'</b>: '+data[i].lon+'<br>';
feature.userHTML+='<b>'+trt('Speed')+'</b>: '+data[i].speed+' '+trt('km_h')+" (GPS: "+data[i].velocity+trt('km_h')+')<br>';
g_vectorSource.addFeature(feature);
}
}
var pointS=featureL.getGeometry().getCoordinates()[0]; //Коордионаты первой точки в треке
var pointE=featureL.getGeometry().getCoordinates()[featureL.getGeometry().getCoordinates().length-1]; //Координаты последней точки
//Также создаю иконки старта трека и окончания трека
let featureS = new ol.Feature({geometry: new ol.geom.Point(pointS)});
featureS.userID=thiz.id;
featureS.setStyle(new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 37],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: '../resources/images/istart.png'
}))
}));
g_vectorSource.addFeature(featureS);
//Также создаю иконку окончания трека
let featureE = new ol.Feature({geometry: new ol.geom.Point(pointE)});
featureE.userID=thiz.id;
featureE.setStyle(new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 37],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: '../resources/images/istop.png'
}))
}));
g_vectorSource.addFeature(featureE);
//Перемещаемся на первую точку маршрута
g_map.getView().setCenter(pointS);
if(g_map.getView().getZoom()<9)
g_map.getView().setZoom(9);
}else
{
thiz.hideObjectTrack(); //Пытаемся спрятать если 0 точек
}
//Востанавливаю курсор
hideProgressBarIco();
}
}
};
}(this);
req.open("POST", '/monitoring/pscripts/track.php', true);
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(data));
//Курсор ожидание со стрелочкой
showProgressBarIco();
}
hideObjectTrack()
{
let delList = [];
let features=g_vectorSource.getFeatures();
for(let i=0;i<features.length;i++)
{
if(features[i].userID==this.id)
{
delList.push(features[i]);
}
}
for(let i=0;i<delList.length;i++)
{
g_vectorSource.removeFeature(delList[i]);
}
}
goToCenter()
{
//Пытаемся переместиться на точку на карте
if(!isNaN(parseFloat(this.lon)))
{
g_map.getView().setCenter(ol.proj.transform([this.lon,this.lat], 'EPSG:4326','EPSG:3857'));
if(g_map.getView().getZoom()<9)
g_map.getView().setZoom(9);
}
}
//Отобразить окно с детальной информацией о установке
showDetailedInformation()
{
//Запрашиваем информацию о объекте и отображаем в отдельном всплывающем окне
if(m_winPP!=null) m_winPP.Close();
m_winPP=new TWin();
m_winPP.BuildGUI(pageX-100,pageY-100);
m_winPP.setSize(500,100);
m_winPP.setCaption(this.name);
m_winPP.showProgressBar();
m_winPP.setCenter();
m_winPP.setContent('<table style="width:100%;height:100%;"><tr><td id="winPP_m"></td></tr><tr><td style="padding-top:5px;"></td></tr></table>');
//<button id="winPP_mm">Деактивировать ЭЗПУ</button>
/*var obj=document.getElementById("winPP_mm");
if(this.active==1)
{
obj.onclick = function(thiz){ return function(){ thiz.deactivation(); }; }(this);
}else
{
obj.style.display="none";
}*/
//alert('/monitoring/pscripts/object.php?object_id='+this.id);
$.ajax({
url: '/monitoring/pscripts/object.php?object_id='+this.id,
type: "POST",
dataType: "text",
success: function(thiz){return function(data,status){
if(status=='success')
{
m_winPP.hideProgressBar();
//m_winPP.setContent(data);
var obj=document.getElementById("winPP_m");
if(obj!=null)
{
obj.innerHTML=data;
}
m_winPP.setCenter();
}else
{
alert(status);
}
}}(this)
});
}
//Обновить графические элементы (дата если она отображается пользователю)
updateGUI()
{
var obj=document.getElementById('date_'+this.uid);
if(obj!=null){
obj.innerHTML=this.date;
}
if(this.sensors!=null)
{
for(let i=0;i<this.sensors.length;i++)
{
let obj=document.getElementById('svalue_'+this.sensors[i].id+'_'+this.uid);
if(obj!=null) obj.innerHTML=this.sensors[i].value;
obj=document.getElementById('sdate_'+this.sensors[i].id+'_'+this.uid);
if(obj!=null) obj.innerHTML=this.sensors[i].date;
}
}
}
//Переместить точку автомобиля в прогнозную точку
goToForecast(){
//if(this.name=='VIRTUAL') {
//Отдаляем последнюю точку ещё дальше
if (this.time != 0 && this.time_p != 0 && this.time != this.time_p && this.lon_p != this.lon && this.lat_p != this.lat) { //Чтобы не поделить на 0
//console.log('Object = ' + this.id+') '+this.name + ' предпоследний = ' + this.time + ' последний = ' + this.time_p);
let p = ((new Date()).getTime() - this.time) / (this.time - this.time_p);
p=p/1.2; //замедление 80%
//console.log('p = ' + p); //Процент от 0 до 1
if (p <= 1) {
let lat_c=this.lat+(this.lat-this.lat_p);
let lon_c=this.lon+(this.lon-this.lon_p);
this.lat_f = this.lat * (1 - p) + lat_c * p;
this.lon_f = this.lon * (1 - p) + lon_c * p;
//console.log('p = ' + p+' this.lat_f = '+this.lat_f+' this.lon_f = '+this.lon_f); //Процент от 0 до 1
this.setMarkerPosition(this.lon_f, this.lat_f);
//console.log('p = ' + p); //Процент от 0 до 1
}
}
//}
}
//Обновить коордионаты и иконку на карте
setLonLat(lon,lat)
{
lon = parseFloat(lon); //Долгота
lat = parseFloat(lat); //Широта
//Сохраняю предыдущее значение
if(this.time!=this.time_p){
this.time_p=this.time;
this.lon_p=this.lon;
this.lat_p=this.lat;
}
this.time=(new Date()).getTime(); //Текущее время для прогноза
this.lon=lon; //Долгота
this.lat=lat; //Широта
this.setMarkerPosition(lon,lat);
}
//Задать позицию маркера
setMarkerPosition(lon,lat){
if(!isNaN(lat) && !isNaN(lon))
{
let point = new ol.geom.Point(ol.proj.transform([lon,lat], 'EPSG:4326','EPSG:3857'));
if(this.feature==null)
{
let features = [];
this.feature = new ol.Feature({geometry: point,name: this.name,icon_name: this.icon_name});
this.feature.setStyle(createFatypeStyleDel(this.feature,false));
this.feature.userType="TObject";
//feature.userName='terrain';
this.feature.userID=this.id;
features.push(this.feature);
g_vectorSource.addFeatures(features);
}
this.feature.set('geometry', point);
}
}
getSensorByID(id)
{
let result=null;
if(this.sensors!=null)
{
for(let i=0;i<this.sensors.length;i++)
{
if(this.sensors[i].id==id)
{
result=this.sensors[i];
break;
}
}
}
return result;
}
}

View File

@ -0,0 +1,856 @@
class TRoutes
{
constructor(map)
{
this.routes = []; //Список маршрутов
}
//Получаем список объектов
//Фильтруем объекты для заполнения в таблицу
filtering()
{
showProgressBar(document.getElementById('div_tbl_e'));
var data = {
name: "",
type: ""
};
$.ajax({
url: '/monitoring/pscripts/routes.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.routes = []; //Удаляю старые объекты
g_vectorSourceRoute.clear(); //Удаляю все отображения
for(i=0;i<data.length;i++)
{
var obj = new TRoute();
obj.id=data[i].id;
obj.name=data[i].name;
obj.station=data[i].station;
obj.carriers=data[i].carriers;
obj.count=data[i].count;
obj.length=data[i].length;
obj.lon=parseFloat(data[i].lon);
obj.lat=parseFloat(data[i].lat);
obj.schedules=data[i].schedules;
obj.checkpoints = [];
for(var j=0;j<data[i].checkpoints.length;j++)
{
var chp = new TCheckPoint();
Object.assign(chp,data[i].checkpoints[j]); //Копирую все свойства в новый объект
obj.checkpoints.push(chp);
}
thiz.routes.push(obj);
}
thiz.fillRezDiv();
}else
{
alert(status);
}
hideProgressBar(document.getElementById('div_tbl_e'));
}}(this)
});
}
//Заполнить результатом выборки DIV в виде таблицы
fillRezDiv()
{
var div=document.getElementById("div_tbl_e");
delChild(div);
div.innerHTML='<table id="thetable_e" border="0" style="width:100%;" class="SShow"><thead><tr style="background-color: rgb(218, 218, 218);"><th></th><th id="route_ch_M" style="width:1%;text-decoration:underline;cursor: pointer;">'+trt('View')+'.</th><th style="width: 90%;">'+trt('Route_name')+'</th><th style="width: 1%;">'+trt('Points')+'</th><th style="width: 1%;">'+trt('Length')+'</th></tr></thead><tbody></tbody></table>';
var theTable = document.getElementById('thetable_e');
for(i=0;i<this.routes.length;i++)
{
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;
tr.onmouseover=function(){this.style.backgroundColor='var(--btn-color2)';};
tr.onmouseout=function(val1,val2){return function(){val1.style.backgroundColor=val2;}}(tr,bgColor);
tr.id='cell_e_'+this.routes[i].id;
var td;
td = document.createElement('td');
td.style.cssText="width:24px;text-align:center;vertical-align:top;";
td.innerHTML='<img id="routes_down_btn_'+this.routes[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="route_ch_'+this.routes[i].id+'" type="checkbox"/>';
tr.appendChild(td);
td = document.createElement('td');
td.style.cursor='pointer';
td.innerHTML=this.routes[i].name;
td.onclick=function(route){
return function(){
route.goToStart();
}
}(this.routes[i]);
tr.appendChild(td);
td = document.createElement('td');
td.style.cssText='cursor:pointer;text-align:right;';
td.innerHTML=this.routes[i].count;
td.onclick=function(route){
return function(){
route.goToStart();
}
}(this.routes[i]);
tr.appendChild(td);
td = document.createElement('td');
td.style.cssText='cursor:pointer;white-space:nowrap;text-align:right;';
td.innerHTML=this.routes[i].length+' '+trt('km');
td.onclick=function(route){
return function(){
route.goToStart();
}
}(this.routes[i]);
tr.appendChild(td);
/*td = document.createElement('td');
td.innerHTML=this.routes[i].value;
tr.appendChild(td);*/
/*td = document.createElement('td');
td.innerHTML=this.routes[i].date;
tr.appendChild(td);*/
theTable.tBodies[0].appendChild(tr);
//Формирую раскрывающийся список
tr = document.createElement('tr');
tr.id=this.routes[i].id;
tr.style.cssText="background-color:var(--back-color-3);display:none";
td = document.createElement('td');
td.colSpan=6;
var html='<table style="width:100%;"><tr><td style="width:100%;border: 0;">';
html+='<b>'+trt('Bus_station')+':</b> <img id="route_edit2_'+this.routes[i].id+'" src="/resources/images/edit16.png" alt="'+trt('Edit')+'" title="'+trt('Edit')+'" style="cursor:pointer;"> '+this.routes[i].station+'<br>';
html+='<b>'+trt('Carrier')+':</b> <img id="route_edit3_'+this.routes[i].id+'" src="/resources/images/edit16.png" alt="'+trt('Edit')+'" title="'+trt('Edit')+'" style="cursor:pointer;"> '+this.routes[i].carriers+'<br>';
html+='<b>'+trt('Schedule')+':</b> <img id="route_edit4_'+this.routes[i].id+'" src="/resources/images/edit16.png" alt="'+trt('Edit')+'" title="'+trt('Edit')+'" style="cursor:pointer;"><br>';
for(let j=0;j<this.routes[i].schedules.length;j++)
{
html+='<span style="padding-left:1em">'+this.routes[i].schedules[j].direction+': '+this.routes[i].schedules[j].time+' '+this.routes[i].schedules[j].carrier+'</span><br>';
}
html+='<b>Контрольные точки:</b> <img id="route_edit5_'+this.routes[i].id+'" src="/resources/images/rplus16.png" alt="'+trt('Create')+'" title="'+trt('Create')+'" style="cursor:pointer;"> <img id="route_edit6_'+this.routes[i].id+'" src="/resources/images/edit16.png" alt="'+trt('Edit')+'" title="'+trt('Edit')+'" style="cursor:pointer;"><br>';
for(var j=0;j<this.routes[i].checkpoints.length;j++)
{
html+='<span style="padding-left:1em"><input id="route_ch_c_'+this.routes[i].checkpoints[j].id+'" type="checkbox"/> <div id="route_ch_cd_'+this.routes[i].checkpoints[j].uid+'" style="display:inline;cursor:pointer;">'+this.routes[i].checkpoints[j].direction+': '+this.routes[i].checkpoints[j].time+' '+this.routes[i].checkpoints[j].name+'</div> <img id="route_edit_cp1_'+this.routes[i].checkpoints[j].id+'" src="/resources/images/edit16.png" alt="'+trt('Edit')+'" title="'+trt('Edit')+'" style="cursor:pointer;"> <img id="route_edit_cp2_'+this.routes[i].checkpoints[j].id+'" src="/resources/images/rdel16.png" alt="'+trt('Delete')+'" title="'+trt('Delete')+'" style="cursor:pointer;"></span><br>';
}
html+='</td><td valign="top" style="border: 0;"><img id="route_rev_'+this.routes[i].id+'" src="/resources/images/rev24.png" alt="'+trt('Swap')+' A B" title="'+trt('Swap')+' A B" style="cursor:pointer;"></td><td valign="top" style="border: 0;"><img id="route_edit_'+this.routes[i].id+'" src="/resources/images/edit24.png" alt="'+trt('Edit')+'" title="'+trt('Edit')+'" style="cursor:pointer;"></td><td valign="top" style="border: 0;"><img id="route_del_'+this.routes[i].id+'" src="/resources/images/del24.png" alt="'+trt('Delete')+'" title="'+trt('Delete')+'" style="cursor:pointer;"></td></tr></table>';
td.innerHTML=html;
tr.appendChild(td);
theTable.tBodies[0].appendChild(tr);
//При щелчке на ячейку перемещаем карту на точку
/*var cell=document.getElementById("cell_e_"+this.routes[i].id);
cell.onclick=function(object){
return function(){
object.getGeoJSON();
}
}(this.routes[i]);*/
var cell=document.getElementById("route_ch_"+this.routes[i].id);
cell.onclick=function(route){
return function(){
var chb=document.getElementById("route_ch_"+route.id);
route.setVisibility(chb.checked);
}
}(this.routes[i]);
//Кнопка разсрыть список
var btn=document.getElementById('routes_down_btn_'+this.routes[i].id);
btn.onclick=function(tr,thiz,id){ return function(){
var btn=document.getElementById('routes_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.routes[i].id);
//Кнопка поменять местами начальную и конечную точку
btn=document.getElementById('route_rev_'+this.routes[i].id)
btn.onclick=function(thiz,id){ return function(){ thiz.swapPoints({id:id}); }; }(this,this.routes[i].id);
//Кнопка редактировать
btn=document.getElementById('route_edit_'+this.routes[i].id)
btn.onclick=function(thiz,id){ return function(){ thiz.editRoute({id:id}); }; }(this,this.routes[i].id);
//Кнопка удалить
btn=document.getElementById('route_del_'+this.routes[i].id)
btn.onclick=function(thiz,id){ return function(){ thiz.deleteRoute({id:id}); }; }(this,this.routes[i].id);
//Кнопка редактировать "Автовокзал", "Перевозчик"
var eBtn=function(thiz,id){ return function(){
var settings='<type n="RoutesCompanies"><objects-list><filter><column n="route_id"><![CDATA['+id+']]></column></filter></objects-list></type>';
myFunction('RoutesCompanies',settings);
}; }(this,this.routes[i].id);
btn=document.getElementById('route_edit2_'+this.routes[i].id)
btn.onclick=eBtn;
btn=document.getElementById('route_edit3_'+this.routes[i].id)
btn.onclick=eBtn;
//Кнопка редактировать расписание рейса
btn=document.getElementById('route_edit4_'+this.routes[i].id)
btn.onclick=function(thiz,id){ return function(){
var settings='<type n="TripsSchedules"><objects-list><filter><column n="route_id"><![CDATA['+id+']]></column></filter></objects-list></type>';
myFunction('TripsSchedules',settings);
}; }(this,this.routes[i].id);
//Кнопка создать контрольную точку
btn=document.getElementById('route_edit5_'+this.routes[i].id)
btn.onclick=function(thiz,id){ return function(){
thiz.createCheckPoint(id);
}; }(this,this.routes[i].id);
//Кнопка редактировать контрольные точки (табличка)
btn=document.getElementById('route_edit6_'+this.routes[i].id)
btn.onclick=function(thiz,id){ return function(){
var settings='<type n="RoutesCheckpoints"><objects-list><filter><column n="route_id"><![CDATA['+id+']]></column></filter></objects-list></type>';
myFunction('RoutesCheckpoints',settings);
}; }(this,this.routes[i].id);
//Кнопки редактировать контрольные точки
for(var j=0;j<this.routes[i].checkpoints.length;j++)
{
//Чекбукс видимости контрольной точки
var bnt=document.getElementById("route_ch_c_"+this.routes[i].checkpoints[j].id);
bnt.onclick=function(checkPoint){
return function(){
var chb=document.getElementById("route_ch_c_"+checkPoint.id);
checkPoint.setVisibility(chb.checked);
}
}(this.routes[i].checkpoints[j]);
//Центрировать на контрольной точке
btn=document.getElementById('route_ch_cd_'+this.routes[i].checkpoints[j].uid);
btn.onclick=function(checkpoint){ return function(){ checkpoint.goToCenter(); }; }(this.routes[i].checkpoints[j]);
//Кнопка редактировать
btn=document.getElementById('route_edit_cp1_'+this.routes[i].checkpoints[j].id);
btn.onclick=function(thiz,id){ return function(){ thiz.editCheckPoint({id:id}); }; }(this,this.routes[i].checkpoints[j].id);
//Кнопка удалить контрольную точку
btn=document.getElementById('route_edit_cp2_'+this.routes[i].checkpoints[j].id);
btn.onclick=function(thiz,id){ return function(){ thiz.deleteControlPoint({id:id}); }; }(this,this.routes[i].checkpoints[j].id);
}
}
//Количество элементов в дереве
var divCnt = document.getElementById("count_e");
delChild(divCnt);
divCnt.appendChild(document.createTextNode(this.routes.length));
//По нажатию на заголовок инвертируем чекбуксы
divCnt = document.getElementById("route_ch_M");
divCnt.onclick=function(thiz){
return function(){
thiz.hide();
}
}(this);
}
//Поменять местами начальную и конечную точки
swapPoints(settings)
{
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
if (confirm(trt("Do_you_really_want_to_swap_the_points")+'?')) {
}
}
createRoute()
{
//В настройках передаю центр карты
let center=ol.proj.transform(g_map.getView().getCenter(), 'EPSG:3857','EPSG:4326');
let eRec = new EdtRec("");
eRec.eRecNa("Routes",-1,'<type n="Routes"><properties><prop n="name"><![CDATA['+document.getElementById("cnumber_e").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);
}
createCheckPoint(id)
{
//В настройках передаю центр карты
let center=ol.proj.transform(g_map.getView().getCenter(), 'EPSG:3857','EPSG:4326');
let eRec = new EdtRec("");
eRec.eRecNa("RoutesCheckpoints",-1,'<type n="RoutesCheckpoints"><properties><prop n="route_id"><![CDATA['+id+']]></prop><prop n="name"><![CDATA['+document.getElementById("cnumber_e").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);
}
//Удалить маршрут
deleteRoute(settings)
{
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
if (confirm(trt("Do_you_really_want_to_delete_the_record")+'?')) {
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
return;
}
if(data!=null)
{
if(data.errorMessage !== undefined && data.errorMessage!='')
{
alert(data.errorMessage);
thiz.win.hideProgressBar();
}else
{
}
}
//Фильтрую список заново
thiz.filtering();
}
};
}(this);
req.open("POST", '/monitoring/pscripts/routes.php?fn=3', true);
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(settings));
this.filtering();
}
return true;
}
//Удалить маршрут
deleteControlPoint(settings)
{
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
if (confirm(trt("Do_you_really_want_to_delete_the_record")+'?')) {
alert(settings.id);
/*var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
return;
}
if(data!=null)
{
if(data.errorMessage !== undefined && data.errorMessage!='')
{
alert(data.errorMessage);
thiz.win.hideProgressBar();
}else
{
}
}
//Фильтрую список заново
thiz.filtering();
}
};
}(this);
req.open("POST", '/monitoring/pscripts/routes.php?fn=3', true);
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(settings));
this.filtering();*/
}
return true;
}
editRoute(settings)
{
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
let route=this.getRouteByID(settings.id);
let eRec = new EdtRec("");
eRec.eRecNa("Routes",settings.id);
eRec.win.onClose=function(thiz,route){ return function(){
route.showPoints(false);
//thiz.filtering();
};}(this,route);
if(route!=null)
{
route.showPoints(true);
route.setVisibility(true);
}
}
editCheckPoint(settings)
{
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
let checkPoint=this.getCheckPointByID(settings.id);
let eRec = new EdtRec("");
eRec.eRecNa("RoutesCheckpoints",settings.id);
eRec.win.onClose=function(thiz,checkPoint){ return function(){
checkPoint.showPoints(false);
};}(this,checkPoint);
//alert("checkPoint = "+checkPoint+" id = "+settings.id);
if(checkPoint!=null)
{
checkPoint.showPoints(true);
checkPoint.setVisibility(true);
}
}
//Вернуть объект TRoute по идентификатору
getRouteByID(id)
{
for(var i=0;i<this.routes.length;i++)
{
if(this.routes[i].id==id)
return this.routes[i];
}
return null;
}
//Вернуть объект TCheckPoint по идентификатору
getCheckPointByID(id)
{
for(var i=0;i<this.routes.length;i++)
{
for(var j=0;j<this.routes[i].checkpoints.length;j++)
{
if(this.routes[i].checkpoints[j].id==id)
return this.routes[i].checkpoints[j];
}
}
return null;
}
//Инвертировать видимость маршрутов
hide()
{
for(var i=0;i<this.routes.length;i++)
{
this.routes[i].setVisibility(!this.routes[i].getVisibility());
}
}
}
class TRoute
{
constructor(){
this.uid=getUID(); //Уникальный идентификатор
this.id='';
this.feature=null; //Объект который отображается на карте
this.featureA=null; //Начало маршрута
this.featureB=null; //Конец маршрута
this.shP=false; //Показывать ли точки для редактирования
this.visible=false; //По умолчанию всё видим
}
getVisibility()
{
return this.visible;
}
setVisibility(val)
{
var chb=document.getElementById("route_ch_"+this.id);
if(val)
{
if(!chb.checked) chb.checked=true;
if(this.feature==null)
{
this.getGeoJSON(); //Подгружаем объект с сервера
}else
{
//Проверяю чтобы заново не добавить
var exists=false;
var features=g_vectorSourceRoute.getFeatures();
for(var i=0;i<features.length;i++)
{
if(features[i]==this.feature)
{
exists=true;
break;
}
}
if(!exists)
{
g_vectorSourceRoute.addFeature(this.feature);
g_vectorSourceRoute.addFeature(this.featureA); //Начало маршрута
g_vectorSourceRoute.addFeature(this.featureB); //Конец маршрута
}
}
}else{
if(chb!=null && chb.checked) chb.checked=false;
if(this.feature!=null)
{
g_vectorSourceRoute.removeFeature(this.feature);
this.showPoints(false);
}
if(this.featureA!=null) g_vectorSourceRoute.removeFeature(this.featureA); //Начало маршрута
if(this.featureB!=null) g_vectorSourceRoute.removeFeature(this.featureB); //Конец маршрута
}
this.visible=val;
//Также присваваю видимость для контрольных точек
for(var i=0;i<this.checkpoints.length;i++)
{
this.checkpoints[i].setVisibility(val);
}
}
goToStart()
{
if(this.feature!=null)
{
var coord = this.feature.getGeometry().getCoordinates();
if(coord.length>0)
{
var point = coord[0];
if(point!=null)
{
g_map.getView().setCenter(point);
if(g_map.getView().getZoom()<9)
g_map.getView().setZoom(9);
}
}
}else
{
if(!isNaN(parseFloat(this.lon)))
{
var point = ol.proj.transform([this.lon,this.lat], 'EPSG:4326','EPSG:3857');
if(point!=null)
{
g_map.getView().setCenter(point);
if(g_map.getView().getZoom()<9)
g_map.getView().setZoom(9);
}
}
}
}
//Отобразить точки для редактирования
showPoints(val)
{
this.shP=val;
if(this.shP)
enableEditPoints(this.feature);
else
disableEditPoints(this.feature);
return true;
}
//Запросить гео данные для построения маршрута на карте
getGeoJSON()
{
if(this.feature!=null) return;
var data = {
id: this.id
};
$.ajax({
url: '/monitoring/pscripts/routes.php?fn=1',
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
type: "POST",
dataType: "json",
success: function(thiz){return function(data,status){
if(status=='success')
{
var dataC;
var featuresC;
var vectorSourceC;
dataC = data;//JSON.parse('{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type": "LineString","coordinates": [[34.32128906249999,54.67383096593114],[45.3955078125,54.44449176335762],[52.7783203125,52.61639023304539],[62.13867187499999,49.095452162534826],[76.1572265625,43.45291889355465]]}}]}');
vectorSourceC = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(dataC,{featureProjection: 'EPSG:3857'})
});
featuresC = vectorSourceC.getFeatures();
var point=null; //Коордионаты первой точки в маршруте
for(i=0;i<featuresC.length;i++)
{
featuresC[i].setStyle(new ol.style.Style({
fill: new ol.style.Fill({color: 'rgba(255, 0, 76, 0.3)'}),
stroke: new ol.style.Stroke({color: 'rgba(255, 0, 0, 0.7)', width: 4}),
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=featuresC[i]; //Должен быть один массив в объекте
thiz.feature.userData=thiz; //Ссылка на TRoute
g_vectorSourceRoute.addFeature(featuresC[i]);
}
var pointS=thiz.feature.getGeometry().getCoordinates()[0]; //Коордионаты первой точки в треке
var pointE=thiz.feature.getGeometry().getCoordinates()[thiz.feature.getGeometry().getCoordinates().length-1]; //Координаты последней точки
//Обозначаю начальную точку маршрута как A
thiz.featureA = new ol.Feature({geometry: new ol.geom.Point(pointS)});
thiz.featureA.setStyle(new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 24],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: '../resources/images/icons/19.png'
}))
}));
g_vectorSourceRoute.addFeature(thiz.featureA);
//Обозначаю конечную точку маршрутат как B
thiz.featureB = new ol.Feature({geometry: new ol.geom.Point(pointE)});
thiz.featureB.setStyle(new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 24],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: '../resources/images/icons/20.png'
}))
}));
g_vectorSourceRoute.addFeature(thiz.featureB);
//Если в режиме редактирования точек то отображаем эти точки
if(thiz.shP)
enableEditPoints(thiz.feature);
}else
{
alert(status);
}
}}(this)
});
}
};
//У каждого маршрута должно быть по крайней мере 2 контрольные точки
class TCheckPoint
{
constructor(){
this.uid=getUID(); //Уникальный идентификатор
this.id='';
this.feature=null; //Объект который отображается на карте
this.shP=false; //Показывать ли точки для редактирования
this.visible=false; //По умолчанию всё видим
}
getVisibility()
{
return this.visible;
}
setVisibility(val)
{
var chb=document.getElementById("route_ch_c_"+this.id);
if(val)
{
if(!chb.checked) chb.checked=true;
if(this.feature==null)
{
this.getGeoJSON(); //Подгружаем объект с сервера
}else
{
//Проверяю чтобы заново не добавить
var exists=false;
var features=g_vectorSourceRoute.getFeatures();
for(var i=0;i<features.length;i++)
{
if(features[i]==this.feature)
{
exists=true;
break;
}
}
if(!exists)
g_vectorSourceRoute.addFeature(this.feature);
}
}else{
if(chb!=null && chb.checked) chb.checked=false;
if(this.feature!=null)
{
//Проверяем есть ли Feature а если есть то удаляем
var exists=false;
var features=g_vectorSourceRoute.getFeatures();
for(var i=0;i<features.length;i++)
{
if(features[i]==this.feature)
{
exists=true;
break;
}
}
if(exists)
{
g_vectorSourceRoute.removeFeature(this.feature);
this.showPoints(false);
}
}
}
this.visible=val;
}
//Отобразить точки для редактирования
showPoints(val)
{
//alert("showPoints="+val);
this.shP=val;
if(this.shP)
enableEditPoints(this.feature);
else
disableEditPoints(this.feature);
return true;
}
goToCenter()
{
var point=ol.proj.transform([parseFloat(this.lon), parseFloat(this.lat)], 'EPSG:4326','EPSG:3857');
g_map.getView().setCenter(point);
if(g_map.getView().getZoom()<9)
g_map.getView().setZoom(9);
}
//Запросить гео данные для построения объекта на карте
getGeoJSON()
{
if(this.feature!=null) return;
var data = {
id: this.id
};
$.ajax({
url: '/monitoring/pscripts/routes.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')
{
var 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_vectorSourceRoute.addFeature(thiz.feature);
//Если в режиме редактирования точек то отображаем эти точки
if(thiz.shP)
enableEditPoints(thiz.feature);
}
}else
{
alert(status);
}
}}(this)
});
}
}

View File

@ -0,0 +1,475 @@
class TTrips
{
constructor(map){
//this.m_id=null; //id редактируемой записи
this.trips = []; //Список маршрутов
this.win=null;
this.iframe = createIFrame('trip_file_i', '/monitoring/pscripts/trips.php?fn=4', document.body, false); //Фрейм для закачки файла на сервер
}
//Открывается новое окно для создания нового рейса
// settings - объект(или строка) с настройками для создания маршрута
createTrip(settings)
{
if(this.win!=null && !this.win.closed) return; //Несколько одновременно нельзя создавать
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
this.win=new TWin();
this.win.pth='../metadata/dbms/form/';
this.win.BuildGUI(10,40)
this.win.getCaption().appendChild(document.createTextNode(trt("Creation_of_trip")));
//Как подгрузится содержимое выполниться данная функция для настройки по средством JS
var func=function(thiz)
{
return function()
{
setCalendar('trip_date_start','trip_date_start_s');
//кнопка выбора файла
var btn=document.getElementById('e_trip_btn_select_file');
var doc=getIframeDocument(thiz.iframe)
var inp=document.getElementById('trip_file_name');
btn.onclick=function(doc){return function(){doc.forms["form"].elements["file"].click()}}(doc);
doc.forms["form"].elements["file"].onchange = function(inp) {return function(){inp.value=this.files[0].name;/*this.value;*/};}(inp);
/*if(BeforeFirst(doc.body.innerHTML,'=')=='ok')
{
var fName=BeforeFirst(AfterFirst(doc.body.innerHTML,'='),"\n");
inp.value=BeforeLast(inp.value,'.')+'_'+fName;
if(inp.value!='')
{ thiz.sendData();
}
}*/
//Кнопка скачать файл
//Кнопка удаления файла
var btn=document.getElementById('trip_btn_delete_file');
btn.onclick=function(inp,ifr){return function(){ inp.value=''; getIframeDocument(ifr).forms["form"].reset(); }}(inp,thiz.iframe)
thiz.win.setCenter();
}
};
this.win.load("/monitoring/pscripts/trips.php?fn=2",settings,func(this));
this.win.setSize("750px","200px");
//win.setCenter();
this.win.obj=this;
//this.win.Hide(false)
this.win.setCenter();
}
editTrip(settings)
{
if(this.win!=null && !this.win.closed) //Несколько одновременно нельзя редактировать
{
alert(trt('Trip_is_already_being_edited')+'!');
return;
}
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
this.win=new TWin();
this.win.pth='../metadata/dbms/form/';
this.win.BuildGUI(10,40)
this.win.getCaption().appendChild(document.createTextNode(trt("Editing_of_trip")));
//Как подгрузится содержимое выполниться данная функция для настройки по средством JS
var func=function(thiz)
{
return function()
{
setCalendar('trip_date_start','trip_date_start_s');
//кнопка выбора файла
var btn=document.getElementById('e_trip_btn_select_file');
var doc=getIframeDocument(thiz.iframe)
var inp=document.getElementById('trip_file_name');
btn.onclick=function(doc){return function(){doc.forms["form"].elements["file"].click()}}(doc);
//Настраиваю форму
doc.forms["form"].elements["file"].onchange = function(inp) {return function(){inp.value=this.files[0].name;/*this.value;*/};}(inp);
thiz.iframe.onload=function(inp,obj){return function()
{ doc=getIframeDocument(this)
if(BeforeFirst(doc.body.innerHTML,'=')=='ok')
{
inp.value=BeforeFirst(AfterFirst(doc.body.innerHTML,'='),"\n")
if(inp.value!='') obj.sendData()
}
}}(inp,thiz);
//Кнопка скачать файл
var btn=document.getElementById('e_trip_btn_download_file');
btn.onclick=function(name){return function(){ window.open('/monitoring/pscripts/trips.php?fn=5&fname='+name, '_blank'); }}(document.getElementById('e_trip_file_name').value)
//Кнопка удаления файла
var btn=document.getElementById('e_trip_btn_delete_file');
btn.onclick=function(inp,ifr){return function(){ inp.value=''; getIframeDocument(ifr).forms["form"].reset(); }}(inp,thiz.iframe)
thiz.win.setCenter();
}
};
this.win.load("/monitoring/pscripts/trips.php?fn=2",settings,func(this));
this.win.setSize("750px","200px");
//win.setCenter();
this.win.obj=this;
//this.win.Hide(false)
this.win.setCenter();
}
//Удалить маршрут
deleteTrip(settings)
{
if (typeof settings === 'string' || settings instanceof String)
{
try {
settings = JSON.parse(settings);
} catch (e) {
alert(e.message);
return;
}
}
if (confirm(trt("Do_you_really_want_to_delete_the_record")+'?')) {
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
return;
}
if(data!=null)
{
if(data.errorMessage !== undefined && data.errorMessage!='')
{
alert(data.errorMessage);
thiz.win.hideProgressBar();
}else
{
}
}
//Фильтрую список заново
thiz.filtering();
}
};
}(this);
req.open("POST", '/monitoring/pscripts/trips.php?fn=1', true);
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(settings));
this.filtering();
}
return true;
}
saveTrip()
{
//Отправляю файлик дожидаюсь загрузки потом отправляю данные
this.win.showProgressBar();
var doc=getIframeDocument(this.iframe);
if(doc.forms["form"].elements["file"].value!='') //Отправляем файла
{
doc.forms["form"].submit();
}else //Отправляем без файла
{
this.sendData();
}
}
sendData()
{
//Считываю значения с полей и отправляю на сервер
var json='{';
if(document.getElementById('e_trip_id').value=='') json+='"id":null,';
else json+='"id":'+document.getElementById('e_trip_id').value+',';
if(document.getElementById('e_trip_type_id').value=='') json+='"trip_type_id":null,';
else json+='"trip_type_id":'+document.getElementById('e_trip_type_id').value+',';
if(document.getElementById('e_trip_route_id').value=='') json+='"route_id":null,';
else json+='"route_id":'+document.getElementById('e_trip_route_id').value+',';
if(document.getElementById('e_trip_direction').value=='') json+='"direction":null,';
else json+='"direction":'+document.getElementById('e_trip_direction').value+',';
if(document.getElementById('e_trip_carrier_id').value=='') json+='"carrier_id":null,';
else json+='"carrier_id":'+document.getElementById('e_trip_carrier_id').value+',';
if(document.getElementById('e_trip_object_id').value=='') json+='"object_id":null,';
else json+='"object_id":'+document.getElementById('e_trip_object_id').value+',';
if(document.getElementById('e_trip_date_start').value=='') json+='"date_start":null,';
else json+='"date_start":"'+document.getElementById('e_trip_date_start').value+'",';
if(document.getElementById('e_trip_passenger').value=='') json+='"passenger":null,';
else json+='"passenger":"'+document.getElementById('e_trip_passenger').value+'",';
if(document.getElementById('e_trip_file_name').value=='') json+='"file_name":null,';
else json+='"file_name":"'+document.getElementById('e_trip_file_name').value+'",';
if(document.getElementById('e_trip_description').value=='') json+='"description":null';
else json+='"description":"'+document.getElementById('e_trip_description').value+'"';
json+='}';
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
return;
}
if(data!=null)
{
if(data.errorMessage !== undefined && data.errorMessage!='')
{
alert(data.errorMessage);
thiz.win.hideProgressBar();
}else
{
thiz.win.Close();
}
}
//Фильтрую список заново
thiz.filtering();
}
};
}(this);
req.open("POST", '/monitoring/pscripts/trips.php?fn=3', true);
req.setRequestHeader("Content-type", "text/plain");
//alert(json);
req.send(json);
}
//Фильтруем объекты для заполнения в таблицу
filtering()
{
showProgressBar(document.getElementById('div_tbl_trips'));
//Выбираем рейсы текущей компании (если админ то все)
var data = {
company_id: document.getElementById('trip_company_id').value,
carrier_id: document.getElementById('trip_carrier_id').value,
route_id: document.getElementById('trip_route_id').value,
status: document.getElementById("trip_status").value
};
var req=createRequestObject();
req.onreadystatechange = function(thiz)
{
return function(){
if(req.readyState === 4){
var data=null;
try {
data = JSON.parse(req.responseText);
} catch (e) {
alert(e.message);
return;
}
if(data!=null)
{
thiz.trips = []; //Удаляю старые объекты
for(i=0;i<data.length;i++)
{
var obj = new TTrip();
obj.id=data[i].id;
obj.trip_type_name=data[i].trip_type_name;
obj.name=data[i].name;
obj.company_name=data[i].company_name;
obj.carrier_name=data[i].carrier_name;
obj.object_name=data[i].object_name;
obj.object_places=data[i].object_places;
obj.direction=data[i].direction;
obj.date_start=data[i].date_start;
obj.date_end=data[i].date_end;
obj.passenger=data[i].passenger;
obj.description=data[i].description;
obj.real_checkpoints=data[i].real_checkpoints;
obj.plan_checkpoints=data[i].plan_checkpoints;
thiz.trips.push(obj);
}
thiz.fillRezDiv(); //Обновляю отображение элементов
}
hideProgressBar(document.getElementById('div_tbl_trips'));
}
};
}(this);
req.open("POST", '/monitoring/pscripts/trips.php?fn=0', true);
req.setRequestHeader("Content-type", "text/plain");
req.send(JSON.stringify(data));
}
//Заполнить результатом выборки DIV в виде таблицы
fillRezDiv()
{
var div=document.getElementById("div_tbl_trips");
delChild(div);
div.innerHTML='<table id="thetable_trips" class="SShow"><thead><tr><th> </th><th title="">Дата/время отправления ('+trt('plan')+')</th><th title="">Дата/время прибытия ('+trt('plan')+')</th><th>'+trt('Route')+'</th><th title="">'+trt('Direction')+'</th><th title="">Автовокзал</th><th title="">Перевозчик</th><th title="">Автобус</th><th title=""></th></tr></thead><tbody></tbody></table>';
var theTable = document.getElementById('thetable_trips');
for(i=0;i<this.trips.length;i++)
{
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;
tr.onmouseover=function(){this.style.backgroundColor='var(--btn-color2)';};
tr.onmouseout=function(val1,val2){return function(){val1.style.backgroundColor=val2;}}(tr,bgColor);
var td=null;
td = document.createElement('td');
td.style.cssText="width:24px;text-align:center;vertical-align:top;";
td.innerHTML='<img id="trip_down_btn_'+this.trips[i].id+'" src="/resources/images/right.png" alt="" style="cursor: pointer;">';
tr.appendChild(td);
td = document.createElement('td');
td.innerHTML=this.trips[i].date_start;
tr.appendChild(td);
td = document.createElement('td');
td.innerHTML=this.trips[i].date_end;
tr.appendChild(td);
td = document.createElement('td');
td.innerHTML=this.trips[i].name;
tr.appendChild(td);
td = document.createElement('td');
if(this.trips[i].direction) td.innerHTML=trt('Direct'); else td.innerHTML=trt('Back');
tr.appendChild(td);
td = document.createElement('td');
td.innerHTML=this.trips[i].company_name;
tr.appendChild(td);
td = document.createElement('td');
td.innerHTML=this.trips[i].carrier_name;
tr.appendChild(td);
td = document.createElement('td');
if(this.trips[i].object_name!=null)
td.appendChild(document.createTextNode(this.trips[i].object_name));
tr.appendChild(td);
/*td = document.createElement('td');
td.style.cssText="vertical-align:top;";
td.innerHTML='<img id="trip_edit_'+this.trips[i].id+'" src="/resources/images/edit24.png" alt="'+trt('Edit')+'" style="cursor:pointer;">';
tr.appendChild(td);*/
theTable.tBodies[0].appendChild(tr);
//Формирую раскрывающийся список
tr = document.createElement('tr');
tr.id=this.trips[i].id;
tr.style.cssText="background-color:var(--back-color-3);display:none";
td = document.createElement('td');
td.colSpan=8;
var html='<table style="width:100%;"><tr><td style="width:100%;border: 0;">';
if(this.trips[i].trip_type_name!=null)
html+='<b>'+trt('Trip_type')+'</b>: '+this.trips[i].trip_type_name+'<br>';
if(this.trips[i].passenger!=null)
{
html+='<b>'+trt('Passengers')+'</b>: '+this.trips[i].passenger;
if(this.trips[i].passenger!=null) html+=' из '+this.trips[i].object_places;
html+='<br>';
}
if(this.trips[i].description!=null)
html+='<b>'+trt('Additional_Information')+'</b>: '+this.trips[i].description+'<br>';
if(this.trips[i].real_checkpoints!=null)
html+='<b>'+'Пройдено контрольных точек'+'</b>: '+this.trips[i].real_checkpoints+' из '+this.trips[i].plan_checkpoints+'<br>';
html+='</td><td valign="top" style="border: 0;"><img id="trip_del_'+this.trips[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="trip_edit_'+this.trips[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 btn=document.getElementById('trip_down_btn_'+this.trips[i].id);
btn.onclick=function(tr,thiz,id){ return function(){
var btn=document.getElementById('trip_down_btn_'+id);
if(btn.src.indexOf("right.png")!=-1)
{
btn.src = '/resources/images/down.png';
//alert('Показать = '+tr+' = '+tr.style.display);
tr.style.display = 'table-row';
}else if(btn.src.indexOf("down.png")!=-1)
{
btn.src = '/resources/images/right.png';
//alert('Скрыть = '+tr+' = '+tr.style.display);
tr.style.display = 'none';
}
}; }(tr,this,this.trips[i].id);
//Кнопка редактировать
var btn=document.getElementById('trip_edit_'+this.trips[i].id)
btn.onclick=function(thiz,id){ return function(){ thiz.editTrip({id:id}); }; }(this,this.trips[i].id);
//Кнопка удалить
btn=document.getElementById('trip_del_'+this.trips[i].id)
btn.onclick=function(thiz,id){ return function(){ thiz.deleteTrip({id:id}); }; }(this,this.trips[i].id);
}
//Количество элементов в дереве
var divCnt = document.getElementById("count_trips");
delChild(divCnt);
divCnt.appendChild(document.createTextNode(this.trips.length));
}
}
class TTrip
{
constrictor(){
this.id=null;
}
}

695
monitoring/jscripts/user.js Normal file
View File

@ -0,0 +1,695 @@
class TUser //Current user with role name and access
{
constructor() {
//this.name="TUser"; //User name
this.company_id = null;
this.win = null;
this.access = {}; //Associative array
this.isLoadedAccess=false; //Подгрузились ли уровни доступа
this.onUpdate = null; //Listener update access array
this.onLoadSettings = null;
this.timezone = ""; // +06:00:00 временая зона текущего пользователя
this.settings = {'':''}; //ассоциативный массив настроек для текущего пользователя
this.checkSession();
//Так как страница перезагружается после авторизации то пользователь уже должен быть зарегестрирован
this.loadSettings();
}
loadAccess() {
let xs = '<?xml version="1.0" encoding="utf-8"?>\n\
<metadata fn="4">\n\
<type n="SysAccessList" pp="-1">\n\
<objects-list><filter></filter></objects-list>\n\
</type>\n\
</metadata>';
let request = new TRequest(this);
if (request.callServer(ScriptName, xs)) {
//m_winPP.showProgressBar();
}
}
//Сохранить параметр настройки для текущего пользователя в базе данных.
sendSettings(name, value)
{
showProgressBarIco();
this.settings[name]=''+value;
let xs='<?xml version="1.0" encoding="utf-8"?>\n\
<metadata fn="1">\n\
<type n="SysUsersSettings">\n\
<properties><prop n="name"><![CDATA['+name+']]></prop><prop n="value"><![CDATA['+value+']]></prop></properties>\n\
</type>\n\
</metadata>';
$.ajax({
url: ScriptName,
type: "POST",
contentType: 'text/xml; charset=utf-8',
dataType: "text",
data: xs,
success: function(response) {
hideProgressBarIco();
},
error: function(xhr) {
hideProgressBarIco();
}
});
}
//Запросить загрузку параметров настроек
loadSettings()
{
//alert('call loadSettings');
let xs='<?xml version="1.0" encoding="utf-8"?>\n\
<metadata fn="4">\n\
<type n="SysUsersSettings" pp="-1">\n\
<objects-list><filter></filter></objects-list>\n\
</type>\n\
</metadata>';
let request=new TRequest(this);
if(request.callServer(ScriptName,xs))
{
//m_winPP.showProgressBar();
}
}
//Получить настройку
getSettings(name,def)
{
let rez=this.settings[name];
if(rez === undefined) {
rez=false;
if(def!==undefined) rez=def;
}
return ''+rez;
};
//Записать присланные данные в асоциативный массив
updateSettings(node)
{
this.settings={};
let nodeType=findFirstNode(node, "type");
let nodeRecord = nodeType.firstChild;
while(nodeRecord != null)
{
if(nodeRecord.nodeName=="record")
{
let key='';
let val='';
let i=0; //column number
let cdataNode = nodeRecord.firstChild;
while (cdataNode!=null)
{
if(cdataNode.nodeName=="#cdata-section")
{
if(i==0) key=cdataNode.nodeValue;
if(i==1) val=cdataNode.nodeValue;
i++;
}
cdataNode = cdataNode.nextSibling;
}
/*if(val=='f' || val==0 || val=='false') val=false;
else if(val='t' || val==1 || val=='true') val=true;
else val=null;*/
this.settings[key]=val;
}
nodeRecord = nodeRecord.nextSibling;
}
if(this.onLoadSettings!=null) this.onLoadSettings(this);
return true;
}
applyReq(req, fn, node) {
if (fn == -1) {
alert2(trt("Alert"),findFirstNode(node, '#cdata-section').nodeValue);
} else if (fn == 4) {
var nodeType = findFirstNode(node, "type");
if (nodeType != null) {
if (nodeType.getAttribute("n") == "_ChangePassword") {
if (findFirstNode(node, '#cdata-section').nodeValue == 't') {
alert2(trt("Alert"),trt('Password_changed_successfully'));
//this.win.hideProgressBar();
this.win.Close();
this.win = null;
} else {
alert2(trt("Alert"),trt('Failed_to_change_password') + '\n' + trt('Check_the_entered_data'));
this.win.hideProgressBar();
}
} else {
this.updateAccess(node);
}
}
} else if (fn == 7) {
var nCmd = findFirstNode(node, "cmd");
if (nCmd != null) {
if (findFirstNode(nCmd, '#cdata-section').nodeValue == "1") //Logout
{
location.reload();
} else if (findFirstNode(nCmd, '#cdata-section').nodeValue == "2") //Check if user not logged
{
if (findNode(node, '#cdata-section').nodeValue == "0") //if not logged
{
this.showLoginForm();
} else {
this.name = getCdataValue(findNode(node, 'name'));
this.company_id = getCdataValue(findNode(node, 'company_id'));
//alert2(trt("Alert"),'this.company_id = '+this.company_id);
configGUIbyAccessLevel();
//var shadow=document.getElementById("shadow");
//if(shadow.parentNode!=null) shadow.parentNode.removeChild(shadow);
g_trips.filtering();
g_geofences.filtering();
g_objects.filtering();
g_routes.filtering();
g_detours.filtering();
}
} else if (findFirstNode(nCmd, '#cdata-section').nodeValue == "3") //Login
{
if (findNode(node, '#cdata-section').nodeValue == "0") //if not logged
{
alert2(trt("Alert"),trt('Invalid_username_and_or_password'));
} else {
location.reload();
}
} else if (findFirstNode(nCmd, '#cdata-section').nodeValue == "4") //Register
{
if (findNode(node, '#cdata-section').nodeValue == "1") //if register
{
alert2(trt("Alert"),trt('New_user_is_registered') + '\n' + trt('The_password_has_been_sent_to_you_by_Email'));
location.reload();
}
}
}
} else {
alert2(trt("Alert"),"Unknown function! fn=\"" + fn + "\"");
}
if (this.win != null) this.win.hideProgressBar();
}
updateAccess(node) {
this.access = {};
var nodeType = findFirstNode(node, "type");
var nodeRecord = nodeType.firstChild;
while (nodeRecord != null) {
if (nodeRecord.nodeName == "record") {
var key = '';
var val = '';
i = 0; //column number
var cdataNode = nodeRecord.firstChild;
while (cdataNode != null) {
if (cdataNode.nodeName == "#cdata-section") {
if (i == 0) key = cdataNode.nodeValue;
if (i == 1) val = cdataNode.nodeValue;
i++;
}
cdataNode = cdataNode.nextSibling;
}
if (val == 'f' || val == 0 || val == 'false') val = false;
else if (val = 't' || val == 1 || val == 'true') val = true;
else val = null;
this.access[key] = val;
}
nodeRecord = nodeRecord.nextSibling;
}
if (this.onUpdate != null) this.onUpdate(this);
this.isLoadedAccess=true;
return true;
}
getAccess(name) {
let rez = this.access[name];
if (rez === undefined) {
console.error('Access key "' + name + '" not found!');
return false;
}
if (rez != true) return false;
return rez;
};
changePassword() {
this.win = new TWin();
this.win.BuildGUI(10, 10);
this.win.setCaption(trt('Change_password'));
let str = '<div style="width: 100%; height: 100%; padding: 3px; text-align: left;">\n\
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%;">\n\
<tbody>\n\
<tr><td>\n\
<table border="0" style="width: 100%; height: 100%;">\n\
<tr>\n\
<td style="padding: 2px; width: 30%; white-space: nowrap"><b>' + trt('Login') + ' (email):</b></td>\n\
<td style="padding: 2px;"><input type="text" maxlength="50" style="width: 100%; padding: 2px; display: inline;" id="id_ch_login" name="login"><br></td>\n\
</tr>\n\
<tr>\n\
<td style="padding: 2px;"><b>' + trt('Old_password') + ':</b></td>\n\
<td style="padding: 2px;"><input type="password" maxlength="33" style="width: 100%; padding: 2px; display: inline;" id="id_ch_oldpassword" name="password"><br></td>\n\
</tr>\n\
<tr>\n\
<td style="padding: 2px;"><b>' + trt('New_password') + ':</b></td>\n\
<td style="padding: 2px;"><input type="password" maxlength="33" style="width: 100%; padding: 2px; display: inline;" id="id_ch_newpassword" name="password"><br></td>\n\
</tr>\n\
<tr>\n\
<td style="padding: 2px;"><b>' + trt('Repeat_password') + ':</b></td>\n\
<td style="padding: 2px;"><input type="password" maxlength="33" style="width: 100%; padding: 2px; display: inline;" id="id_ch_newrpassword" name="password"><br></td>\n\
</tr>\n\
<tr><td colspan="2" style="text-align: right;"><input class="button-secondary" id="id_change_pass" type="button" style="display: inline;" value="' + trt('Apply') + '"><input class="button-secondary" id="exit_pass_' + this.win.uid + '" type="button" style="display: inline;" value="' + trt('Cancel') + '"></td></tr>\n\
</table>\n\
</td></tr>\n\
</tbody>\n\
</table>\n\
</div>';
this.win.setContent(str);
this.win.setSize("500px", "180px");
this.win.setCenter();
this.win.shadow = true;
this.win.hide(false);
document.getElementById('id_change_pass').onclick = function (thiz) {
return function () {
let data = {
email: document.getElementById('id_ch_login').value,
password: document.getElementById('id_ch_oldpassword').value,
new_password: document.getElementById('id_ch_newpassword').value,
repeat_new_password: document.getElementById('id_ch_newrpassword').value
};
if (data.email == '') {
document.getElementById('id_ch_login').select();
alert2(trt("Alert"),trt('Not_filled_Email_address'));
return;
}
if (!isEmail(data.email)) {
alert2(trt("Alert"),sprintf(trt('The_s_is_not_Email'), data.email));
return;
}
if (data.new_password != data.repeat_new_password) {
alert2(trt("Alert"),trt('Passwords_did_not_match'));
return;
}
thiz.win.showProgressBar();
$.ajax({
url: "/monitoring/pscripts/user.php?fn=3",
type: "POST",
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: JSON.stringify(data),
success: function (win) {
return function (response, status) {
if (status == 'success') {
if (response.errorCode == '0') {
alert2(trt("Alert"),trt('Password_changed_successfully'));
} else {
alert2(trt("Alert"),response.errorMessage);
}
} else {
alert2(trt("Alert"),status);
}
win.hideProgressBar();
}
}(thiz.win)
});
};
}(this);
document.getElementById('exit_pass_' + this.win.uid).onclick = function (win) {
return function () {
win.Close();
};
}(this.win);
}
//logout current user
Logout() {
let xs = '<?xml version="1.0" encoding="utf-8"?><metadata fn="7"><cmd><![CDATA[1]]></cmd></metadata>';
let request = new TRequest(this);
if (request.callServer(ScriptName, xs)) {
//m_winPP.showProgressBar();
}
}
//Display login and registration form
showLoginForm() {
if (this.win == null || this.win.closed) {
this.win = new TWin(true);
this.win.disableClosing = true;
this.win.BuildGUI(10, 10);
this.win.setCaption(trt('Authorization') + ' / ' + trt('Registration'));
this.win.setSize("350px", "150px");
/*let str='<div style="width: 100%; height: 100%; padding: 3px; text-align: left;">\n\
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%;">\n\
<tbody>\n\
<tr><td>\n\
<table border="0" style="width: 100%; height: 100%;">\n\
<tr>\n\
<td style="padding: 2px; width: 30%; white-space: nowrap"><b>'+trt('Login')+' (email):</b></td>\n\
<td style="padding: 2px;"><input type="text" maxlength="50" style="width: 100%; padding: 2px; display: inline;" id="login0" name="login"><br></td>\n\
</tr>\n\
<tr>\n\
<td style="padding: 2px;"><b>'+trt('Password')+':</b></td>\n\
<td style="padding: 2px;"><input type="password" maxlength="33" style="width: 100%; padding: 2px; display: inline;" id="password0" name="password"><br></td>\n\
</tr>\n\
<tr>\n\
<td style="padding: 2px;" colspan="2"><table cellspacing="0" cellpadding="0" border="0" style="width: 100%;"><tr><td><!--label for="save0" style="white-space: nowrap;"><input id="save0" type="checkbox" style="display: inline;" checked/>&nbsp;'+trt('Remember')+'&nbsp;(--><a href="#" onclick="showRestoreForm();">'+trt('Password_recovery')+'</a><!--)</label>--></td></tr></table></td>\n\
</tr>\n\
<tr><td colspan="2" style="text-align: right;"><input class="button-secondary" id="'+this.win.uid+'_login" type="button" style="display: inline;" value="'+trt('Log_in')+'"></td></tr>\n\
</table>\n\
</td></tr>\n\
</tbody>\n\
</table>\n\
</div>';
this.win.setContent(str);*/
let str;
var tab = new tcTabs(document.getElementById('TWin_Co_' + this.win.tWinId));
tb = tab.addTab({caption: trt('Authorization')});
str = '<div style="width: 100%; height: 100%; padding: 3px; text-align: left;">\n\
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%;">\n\
<tbody>\n\
<tr><td>\n\
<table border="0" style="width: 100%; height: 100%;">\n\
<tr>\n\
<td style="padding: 2px; width: 30%; white-space: nowrap"><b>' + trt('Login') + ' (' + trt('E_mail') + '):</b></td>\n\
<td style="padding: 2px;"><input type="text" maxlength="50" style="width: 100%; padding: 2px; display: inline;" id="login0" name="login"><br></td>\n\
</tr>\n\
<tr>\n\
<td style="padding: 2px;"><b>' + trt('Password') + ':</b></td>\n\
<td style="padding: 2px;"><input type="password" maxlength="33" style="width: 100%; padding: 2px; display: inline;" id="password0" name="password"><br></td>\n\
</tr>\n\
<tr>\n\
<td style="padding: 2px;" colspan="2"><table cellspacing="0" cellpadding="0" border="0" style="width: 100%;"><tr><td><label for="save0" style="white-space: nowrap;"><input id="save0" type="checkbox" style="display: inline;" checked/>&nbsp;' + trt('Remember') + '&nbsp;</label>(<a href="#" id="' + this.win.uid + '_restore">' + trt('Forgot_your_password') + '</a>)</td></tr></table></td>\n\
</tr>\n\
<tr><td colspan="2" style="text-align: right;"><input class="button-secondary" id="' + this.win.uid + '_login" type="button" style="display: inline;" value="' + trt('Log_in') + '"></td></tr>\n\
</table>\n\
</td></tr>\n\
</tbody>\n\
</table>\n\
</div>';
tb.setConText(str);
tb.setSel();
tb = tab.addTab({caption: trt('Registration')});
str = '<div style="width: 100%; height: 100%; padding: 3px; text-align: left;">\n\
<form action="./?path=f1;0;" id="create_order_form" method="post" name="create_order_form">\n\
<input type="hidden" name="fn" value="2">\n\
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%;">\n\
<tbody>\n\
<tr><td style="padding: 2px;">' + trt('Surname') + '</td><td style="padding: 2px;"><input type="text" maxlength="50" style="width: 100%; display: inline;" id="' + this.win.uid + '_lastname" value=""></td></tr>\n\
<tr><td style="padding: 2px;"><strong>' + trt('Name') + ' *</strong></td><td style="padding: 2px;"><input type="text" maxlength="50" style="width: 100%; display: inline;" id="' + this.win.uid + '_firstname" value=""></td></tr>\n\
<tr><td style="padding: 2px;">' + trt('Company') + ' </td><td style="padding: 2px;"><input type="text" maxlength="255" style="width: 100%; display: inline;" id="' + this.win.uid + '_company" value=""></td></tr>\n\
<tr><td style="padding: 2px;">' + trt('Position') + ' </td><td style="padding: 2px;"><input type="text" maxlength="255" style="width: 100%; display: inline;" id="' + this.win.uid + '_position" value=""></td></tr>\n\
<tr><td style="padding: 2px;">' + trt('Phone') + ' </td><td style="padding: 2px;"><input type="text" maxlength="50" style="width: 100%; display: inline;" id="' + this.win.uid + '_phone" value=""></td></tr>\n\
<tr><td style="padding: 2px;"><strong>' + trt('E_mail') + ' *</strong></td><td style="padding: 2px;"><input type="text" maxlength="50" style="width: 100%; display: inline;" id="' + this.win.uid + '_email" value=""></td></tr>\n\
<tr><td colspan="2" style="padding: 2px;"><b>' + trt('Enter_the_numbers_from_the_image') + ' *</b></td></tr>\n\
<tr><td style="padding: 2px;"><img id="l_img" src="/resources/metadata/include/captcha.php?id=1" alt="' + trt('Security_Code') + '" /></td><td style="padding: 2px;"><input type="text" maxlength="5" style="width: 100%; display: inline;" id="' + this.win.uid + '_captcha" name="captcha"><br><a href="#" style="white-space: nowrap" onclick="document.getElementById(\'l_img\').src = \'/resources/metadata/include/captcha.php?id=2&time=' + (new Date()).getTime() + '\'">&#x21bb; ' + trt('Another_picture') + '</a></td></tr>\n\
<tr><td colspan="2" style="text-align: right;"><input class="button-secondary" id="' + this.win.uid + '_registration" type="button" style="display: inline;" value="' + trt('Registration') + '"></td></tr>\n\
</tbody>\n\
</table>\n\
</form>\n\
</div>';
tb.setConText(str);
//tb.setSel()
//Center the window and display the shadow
this.win.setCenter();
this.win.shadow = true;
this.win.hide(false);
//Clicking on the button login
let obj = null;
obj = document.getElementById(this.win.uid + '_login');
if (obj !== null) {
obj.onclick=()=>
{
let login=document.getElementById('login0').value;
let password=document.getElementById('password0').value;
if(login==''){ alert2(trt("Alert"),trt('Please_fill_in_the_login_field')); return; }
if(password==''){ alert2(trt("Alert"),trt('Please_fill_in_the_password_field')); return; }
let xs = '<?xml version="1.0" encoding="utf-8"?>\
<metadata fn="7">\
<cmd><![CDATA[3]]></cmd>\n\
<login><![CDATA[' + login + ']]></login>\
<password><![CDATA[' + password + ']]></password>\
</metadata>';
let request = new TRequest(this);
if (request.callServer(ScriptName, xs)) {
this.win.showProgressBar();
}
};
}
//Щелчёк по нажатию Enter
obj = document.getElementById('password0');
if (obj != null) {
obj.onkeypress = function (thiz) {
return function (e) {
if (e.keyCode == 13) {
let xs = '<?xml version="1.0" encoding="utf-8"?>\
<metadata fn="7">\
<cmd><![CDATA[3]]></cmd>\n\
<login><![CDATA[' + document.getElementById('login0').value + ']]></login>\
<password><![CDATA[' + document.getElementById('password0').value + ']]></password>\
</metadata>';
let request = new TRequest(thiz);
if (request.callServer(ScriptName, xs)) {
thiz.win.showProgressBar();
}
}
};
}(this);
}
//Регистрация нового пользователя и компании
obj = document.getElementById(this.win.uid + '_registration');
if (obj !== null) {
obj.onclick = function (thiz) {
return function () {
//showProgressBar(document.getElementById('TWin_Co_'+thiz.win.tWinId),thiz.win.uid);
let data = {
lastname: document.getElementById(thiz.win.uid + '_lastname').value,
firstname: document.getElementById(thiz.win.uid + '_firstname').value,
company: document.getElementById(thiz.win.uid + '_company').value,
position: document.getElementById(thiz.win.uid + '_position').value,
phone: document.getElementById(thiz.win.uid + '_phone').value,
email: document.getElementById(thiz.win.uid + '_email').value,
captcha: document.getElementById(thiz.win.uid + '_captcha').value
};
//Check for completeness of the fields
if (data.firstname == '') {
document.getElementById(thiz.win.uid + '_firstname').select();
alert2(trt("Alert"),sprintf(trt('The_s_field_is_empty'), trt('Name')));
return;
}
if (data.email == '') {
document.getElementById(thiz.win.uid + '_email').select();
alert2(trt("Alert"),sprintf(trt('The_s_field_is_empty'), trt('Email')));
return;
}
if (!isEmail(data.email)) {
document.getElementById(thiz.win.uid + '_email').select();
alert2(trt("Alert"),trt('Please_enter_a_valid_email_address'));
return;
}
thiz.win.showProgressBar();
$.ajax({
url: "/monitoring/pscripts/user.php?fn=1",
type: "POST",
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: JSON.stringify(data),
success: function (win) {
return function (response, status) {
if (status == 'success') {
if (response.errorCode == '0') {
alert2(trt("Alert"),trt('New_user_is_registered') + '\n' + trt('The_password_has_been_sent_to_you_by_Email'));
} else {
alert2(trt("Alert"),response.errorMessage);
}
} else {
alert2(trt("Alert"),status);
}
win.hideProgressBar();
}
}(thiz.win)
});
};
}(this);
}
obj = document.getElementById(this.win.uid + '_restore');
if (obj !== null) {
obj.onclick = function (thiz) {
return function () {
thiz.showRestoreForm();
};
}(this);
}
}
/*
log.bind(this, 'Hello world')
let user = {
firstName: "Вася"
};
function func() {
alert2(trt("Alert"),this.firstName);
}
let funcUser = func.bind(user);
funcUser(); // Вася
*/
/*var field1=document.getElementById("lang_1");
if(field1!=null)
{
field1.value=getURLParam("lng");
}
var field2=document.getElementById("lang_2");
if(field2!=null)
{
field2.value=getURLParam("lng");
}*/
}
//Display password recovery form
showRestoreForm() {
let win = new TWin(true);
win.BuildGUI(10, 10);
win.setCaption(trt("Password_recovery"));
let str = '<div id="TWin_DT_' + win.tWinId + '" style="width: 100%; height: 100%; padding: 4px; text-align: left;">\n\
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%; padding: 0px;">\n\
<tr>\n\
<td style="padding: 2px; white-space: nowrap"><b>' + trt('Login') + ' (E-mail):</b></td>\n\
<td style="padding: 2px;"><input type="text" maxlength="40" style="width: 100%; display: inline;" id="' + win.uid + '_email" name="login"></td>\n\
</tr>\n\
<tr>\n\
<td colspan="2" style="padding: 2px;"><b>' + trt('Enter_the_numbers_from_the_image') + ' *</b></td>\n\
</tr>\n\
<tr>\n\
<td style="width: 10px; padding: 2px;"><img id="r_img" src="/resources/metadata/include/captcha.php?id=2" alt="' + trt('Security_Code') + '" /></td>\n\
<td style="padding: 2px;"><input type="text" maxlength="5" style="width: 100%; display: inline;" id="' + win.uid + '_captcha" name="captcha"><br><a href="#" style="white-space: nowrap" onclick="document.getElementById(\'r_img\').src = \'/resources/metadata/include/captcha.php?id=2&time=\'+(new Date()).getTime()">&#x21bb; ' + trt('Another_picture') + '</a></td>\n\
</tr>\n\
<tr><td colspan="2" style="text-align: right; padding: 2px;"><input class="button-secondary" id="' + win.uid + '_restore" type="button" style="display: inline;" value="' + trt('Restore') + '"></td></tr>\n\
</table>\n\
</td></tr>\n\
</div>';
document.getElementById('TWin_Co_' + win.tWinId).innerHTML = str;
win.setSize("300px", "170px");
//Центрируем окно и отображаем тень
if (win.tbl.offsetHeight > win.div.offsetHeight) win.div.style.height = win.tbl.offsetHeight + "px";
if (win.tbl.offsetWidth > win.div.offsetWidth) win.div.style.width = win.tbl.offsetWidth + "px";
win.setCenter();
win.shadow = true;
win.hide(false);
//Click on restore button
var obj = null;
obj = document.getElementById(win.uid + '_restore');
if (obj != null) {
obj.onclick = function (win) {
return function () {
let data = {
email: document.getElementById(win.uid + '_email').value,
captcha: document.getElementById(win.uid + '_captcha').value
};
if (data.email == '') {
document.getElementById(win.uid + '_email').select();
alert2(trt("Alert"),trt('Not_filled_Email_address'));
return;
}
if (!isEmail(data.email)) {
document.getElementById(win.uid + '_email').select();
alert2(trt("Alert"),trt('Please_enter_a_valid_email_address'));
return;
}
win.showProgressBar();
$.ajax({
url: "/monitoring/pscripts/user.php?fn=2",
type: "POST",
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: JSON.stringify(data),
success: function (win) {
return function (response, status) {
if (status == 'success') {
if (response.errorCode == '0') {
alert2(trt("Alert"),trt('A_new_password_has_been_sent_to_your_email') + '.');
} else {
alert2(trt("Alert"),response.errorMessage);
}
} else {
alert2(trt("Alert"),status);
}
win.hideProgressBar();
}
}(win)
});
};
}(win);
}
}
//Check whether the already authorized (+ attempt to log in through "hash").
isLogined() {
let xs = '<?xml version="1.0" encoding="utf-8"?><metadata fn="7"><cmd><![CDATA[2]]></cmd></metadata>';
//var xs='{"fn":7,"cmd":2}';
let request = new TRequest(this);
if (request.callServer(ScriptName, xs)) {
//m_winPP.showProgressBar();
}
};
//Если список доступов подгрузился то считается что пользователь авторизовался
isLoggedIn(){
if(this.access.length>0)
return true;
else
return false;
}
//Checking the session without its extension, if it is completed, we display the authorization window.
checkSession()
{
let jqxhr = $.getJSON('./session.php',{},(data)=>{
if(data.result=='ERROR'){
this.showLoginForm();
}else
if(data.result=='OK'){
this.id=data.user_id;
}
divsh.style.display='none';
});
jqxhr.fail(function(){divsh.style.display='block';}); //If the server is not available.
setTimeout(()=>this.checkSession(), 10000);
}
}

196
monitoring/messages.php Normal file
View File

@ -0,0 +1,196 @@
<?php
//Вернуть в JSON кол-во необработанных сообщений (не присвоенных ни одному пользователю)
//И всё другое связаное с оброботкой сообщений для пользователя
@session_start();
require_once("./config.php");
$db=connectToDB();
$db->exec('SET NAMES utf8');
$db->exec("SET time_zone = '+00:00'");
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
if($fn=='1') //Вернуть кол-во не присвоеных пользователю сообщений
{
$m_all_count=0; //Количество не присвоенных никому сообщений.
$m_user_count=0; //Количество не обработаны сообщений для текущего пользователя.
$sql = 'SELECT count(*) FROM messages m join companies c on m.company_id=c.id WHERE m.del=false and m.id NOT IN (SELECT mu.message_id FROM messagesusers mu WHERE del=false) and c.description=\'TRANSIT\';';
try {
$res = $db->query($sql);
} catch (Exception $e) {
echo $e->getMessage();
$res = null;
}
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$m_all_count = $row[0];
}
if($_SESSION['USER_ID']!='')
{
$sql = "SELECT COUNT(*) FROM monitoring.messagesusers WHERE user_id=".$_SESSION['USER_ID']." AND del=FALSE and date_read IS null";
try {
$res = $db->query($sql);
} catch (Exception $e) {
echo $e->getMessage();
$res = null;
}
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$m_user_count = $row[0];
}
}
$json ='';
header('Content-Type: application/json');
$json .='{';
$json .='"count":'.$m_all_count.",\n";
$json .='"user":'.$m_user_count."\n";
$json .='}';
echo $json;
exit;
}if($fn=='2') //Присвоить последнее сообщение пользователю и вернуть его ID
{
$id='';
$errorCode='0';
$errorMessage='';
$sql = 'SELECT m.id FROM messages m join companies c on m.company_id=c.id WHERE m.del=false and m.id NOT IN (SELECT mu.message_id FROM messagesusers mu WHERE del=false) and c.description=\'TRANSIT\' ORDER BY m.priority desc, m.date_create LIMIT 1';
try {
$res = $db->query($sql);
} catch (Exception $e) {
$errorCode='1';
$errorMessage = $e->getMessage();
$res = null;
}
if($res != null)
{
if ($row = $res->fetch(PDO::FETCH_NUM))
{
//Присваиваю текущему пользователю
$sql="insert into messagesusers(message_id,user_id,date_create)values(".$row[0].",".$_SESSION['USER_ID'].",now())";
try {
$res = $db->query($sql);
} catch (Exception $e) {
$errorCode='1';
$errorMessage = $e->getMessage();
$res = null;
}
$id=$row[0];
}
}
header('Content-Type: application/json');
echo '{"errorCode":'.$errorCode.',"errorMessage":"'.$errorMessage.'","id":"'.$id.'"}';
exit;
}if($fn=='3') //Вернуть данные пользователю в соответствии со значением фильтра
{
$status='';
if(isset($_GET['status'])) { $status=$_GET['status']; }
if($status=='0'){ //Не отработанные
$sql='SELECT mu.id,m.subject,m.text,m.date_create FROM messagesusers mu JOIN messages m ON m.id=mu.message_id WHERE mu.del=FALSE AND m.del=FALSE and mu.user_id='.$_SESSION['USER_ID'].' AND mu.date_read IS null';
}
if($status=='1'){ //Отработанные
$sql='SELECT mu.id,m.subject,m.text,m.date_create FROM messagesusers mu JOIN messages m ON m.id=mu.message_id WHERE mu.del=FALSE AND m.del=FALSE and mu.user_id='.$_SESSION['USER_ID'].' AND mu.date_read > NOW() - INTERVAL 30 DAY';
}
try {
$res = $db->query($sql);
} catch (Exception $e) {
//echo $e->getMessage();
$res = null;
}
$json ='';
$json .='[';
if($res != null)
{
while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$json .='{';
$json .='"id":'.$row['id'].',';
$json .='"subject":"'.str_replace("\n"," ",addslashes($row['subject'])).'",';
$json .='"text":"'.str_replace("\n"," ",addslashes($row['text'])).'"';
$json .="},";
}
if($json[strlen($json)-1]==','){
$json = substr($json, 0, -1);
}
}
$json .=']';
header('Content-Type: application/json');
echo $json;
exit;
}if($fn=='4') //Одна запись для подтверждения
{
//$status='';
//if(isset($_GET['status'])) { $status=$_GET['status']; }
$sql='SELECT mu.id,m.subject,m.text,m.date_create FROM messagesusers mu JOIN messages m ON m.id=mu.message_id WHERE mu.del=FALSE AND m.del=FALSE and mu.user_id='.$_SESSION['USER_ID'].' AND mu.date_read IS null';
try {
$res = $db->query($sql);
} catch (Exception $e) {
//echo $e->getMessage();
$res = null;
}
$json ='';
$json .='{';
if($res != null)
{
if($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$json .='"id":'.$row['id'].',';
$json .='"subject":"'.str_replace("\n"," ",addslashes($row['subject'])).'",';
$json .='"text":"'.str_replace("\n"," ",addslashes($row['text'])).'"';
}
//$json = substr($json, 0, -2);
}
$json .='}';
header('Content-Type: application/json');
echo $json;
exit;
}if($fn=='5') //Отмечаем сообщение как обработанное
{
$errorCode='0';
$errorMessage='';
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
//Сохраняю текст и присваиваю время чтения
$sql="update messagesusers set date_read=now(), description = :description where id = ".$object->id;
$stmt = $db->prepare($sql);
$stmt->bindParam(':description', $object->description, PDO::PARAM_STR);
try
{
$res = $stmt->execute();
} catch (Exception $e)
{
$errorCode='1';
$errorMessage = $e->getMessage();
}
header('Content-Type: application/json');
echo '{"errorCode":'.$errorCode.',"errorMessage":"'.$errorMessage.'"}';
exit;
}else
{
header('Content-Type: application/json');
echo '{"error":1}';
}

2835
monitoring/metadata.xml Normal file

File diff suppressed because it is too large Load Diff

158
monitoring/php_error.log Normal file
View File

@ -0,0 +1,158 @@
[22-Feb-2019 13:35:04 Asia/Almaty] PHP Warning: fopen(./temp/file_848.xls): failed to open stream: No such file or directory in O:\projects\Workspace_PHP\stations.istt.kz\resources\metadata\dbms\records.php on line 1251
[22-Feb-2019 13:35:04 Asia/Almaty] PHP Stack trace:
[22-Feb-2019 13:35:04 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\engine\records.php:0
[22-Feb-2019 13:35:04 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\engine\records.php:36
[22-Feb-2019 13:35:04 Asia/Almaty] PHP 3. fopen(*uninitialized*, *uninitialized*) O:\projects\Workspace_PHP\stations.istt.kz\resources\metadata\dbms\records.php:1251
[22-Feb-2019 13:40:59 Asia/Almaty] PHP Warning: fopen(./temp/file_384.xls): failed to open stream: No such file or directory in O:\projects\Workspace_PHP\stations.istt.kz\resources\metadata\dbms\records.php on line 1251
[22-Feb-2019 13:40:59 Asia/Almaty] PHP Stack trace:
[22-Feb-2019 13:40:59 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\engine\records.php:0
[22-Feb-2019 13:40:59 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\engine\records.php:36
[22-Feb-2019 13:40:59 Asia/Almaty] PHP 3. fopen(*uninitialized*, *uninitialized*) O:\projects\Workspace_PHP\stations.istt.kz\resources\metadata\dbms\records.php:1251
[11-Jul-2019 16:10:09 Asia/Almaty] PHP Notice: Undefined variable: login in O:\projects\Workspace_PHP\stations.istt.kz\resources\metadata\dbms\records.php on line 225
[11-Jul-2019 16:10:09 Asia/Almaty] PHP Stack trace:
[11-Jul-2019 16:10:09 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\engine\records.php:0
[11-Jul-2019 16:10:09 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\engine\records.php:36
[11-Jul-2019 16:10:09 Asia/Almaty] PHP Notice: Undefined variable: password in O:\projects\Workspace_PHP\stations.istt.kz\resources\metadata\dbms\records.php on line 225
[11-Jul-2019 16:10:09 Asia/Almaty] PHP Stack trace:
[11-Jul-2019 16:10:09 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\engine\records.php:0
[11-Jul-2019 16:10:09 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\engine\records.php:36
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Notice: Undefined variable: connstr in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 156
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Notice: Undefined variable: connstr in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 161
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Notice: Undefined variable: login in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 161
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Notice: Undefined variable: password in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 161
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Warning: Cannot modify header information - headers already sent by (output started at O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:161) in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 41
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 3. sendError($e = *uninitialized*) O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:165
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 4. header(*uninitialized*) O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:41
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Warning: Cannot modify header information - headers already sent by (output started at O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:161) in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 42
[05-Nov-2019 17:08:10 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 3. sendError($e = *uninitialized*) O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:165
[05-Nov-2019 17:08:10 Asia/Almaty] PHP 4. header(*uninitialized*) O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:42
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Notice: Undefined variable: connstr in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 156
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Notice: Undefined variable: connstr in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 161
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Notice: Undefined variable: login in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 161
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Notice: Undefined variable: password in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 161
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Warning: Cannot modify header information - headers already sent by (output started at O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:161) in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 41
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 3. sendError($e = *uninitialized*) O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:165
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 4. header(*uninitialized*) O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:41
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Warning: Cannot modify header information - headers already sent by (output started at O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:161) in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 42
[05-Nov-2019 17:09:40 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 3. sendError($e = *uninitialized*) O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:165
[05-Nov-2019 17:09:40 Asia/Almaty] PHP 4. header(*uninitialized*) O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php:42
[05-Nov-2019 17:27:36 Asia/Almaty] PHP Notice: Undefined variable: connstr in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 156
[05-Nov-2019 17:27:36 Asia/Almaty] PHP Stack trace:
[05-Nov-2019 17:27:36 Asia/Almaty] PHP 1. {main}() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:0
[05-Nov-2019 17:27:36 Asia/Almaty] PHP 2. require_once() O:\projects\Workspace_PHP\stations.istt.kz\monitoring\records.php:36
[05-Nov-2019 17:27:36 Asia/Almaty] PHP Notice: Undefined variable: connstr in O:\projects\Workspace_PHP\Metadata_PHP\metadata\dbms\records.php on line 161

View File

@ -0,0 +1,566 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8"/>
<title>Data Protection Agreement</title>
<meta name="keywords" content="">
<meta name="description" content="">
</head>
<body>
<div class="container">
<h1 align="center">
<strong>
<span style="font-size: 18px;">Data Protection Agreement</span>
</strong>
</h1>
<p>This Data Protection Agreement (the &ldquo;DPA&rdquo;) becomes effective on May 25, 2018.&nbsp;</p>
<p align="justify" lang="ru-RU"><span lang="en-US">The Customer shall make available to GEOVizor and the Customer authorizes GEOVizor to process information including Personal Data for the provision of the Services under the Agreement. The parties have agreed to enter into this DPA to confirm the data protection provisions relating to their relationship and so as to meet the requirements of the applicable Data Protection Law.&nbsp;</span>
</p>
<h2><strong><span style="font-size: 14px;">1. Definitions</span></strong>
</h2>
<p style="margin-left: 20px;">1.1 For the purposes of this DPA:</p>
<p align="justify" lang="ru-RU" style="margin-left: 40px;">&ldquo;<span lang="en-US"><strong>Personal Data&rdquo;</strong></span><span lang="en-US">&nbsp;means any information relating to an identified or identifiable natural person (&lsquo;data subject&rsquo;); an identifiable natural person is one who can be identified, directly or indirectly, in particular by reference to an identifier such as a name, an identification number, location data, an online identifier or to one or more factors specific to the physical, physiological, genetic, mental, economic, cultural or social identity of that natural person;&nbsp;</span>
</p>
<p align="justify" lang="ru-RU" style="margin-left: 40px;">&ldquo;<span lang="en-US"><strong
>Data Protection Law</strong></span><span lang="en-US">&rdquo; mean all applicable laws, regulations, and other legal requirements relating to (a) privacy, data security, consumer protection, marketing, promotion, and text messaging, email, and other communications; and (b) the use, collection, retention, storage, security, disclosure, transfer, disposal, and other processing of any Personal Data.;</span>
</p>
<p align="justify" lang="ru-RU" style="margin-left: 40px;">&ldquo;<span lang="en-US"><strong
>GEOVizor Affiliate</strong></span><span lang="en-US">&rdquo; means any entity that directly or indirectly controls, is controlled by, or is under common control with GEOVizor. &ldquo;</span><span
lang="en-US"><strong>Control</strong></span><span
lang="en-US">,&rdquo; for purposes of this definition, means direct or indirect ownership or control of more than 50% of the voting interests of the subject entity;</span>
</p>
<p align="justify" lang="ru-RU" style="margin-left: 40px;">&ldquo;<span lang="en-US"><strong
>Services</strong></span><span lang="en-US">&rdquo; means any of the following services provided by GEOVizor: (a) GEOVizor-branded product offerings made available via the Internet on&nbsp;</span><u
><a href="http://GEOVizor.com/" target="_blank"><span
lang="en-US">http://GEOVizor.com</span></a></u><span lang="en-US">, (b) consulting or training services provided by GEOVizor either remotely via the Internet or in person, and (c) any support services provided by GEOVizor, including access to GEOVizor&rsquo;s help desk;</span>
</p>
<p align="justify" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">the terms &ldquo;</span><span
lang="en-US"><strong>data controller</strong></span><span
lang="en-US">&rdquo;</span><span
lang="en-US">, &ldquo;</span><span
lang="en-US"><strong>data processor</strong></span><span
lang="en-US">&rdquo;, &ldquo;</span><span lang="en-US"><strong
>data subject</strong></span><span
lang="en-US">&rdquo;, &ldquo;</span><span
lang="en-US"><strong>personal data</strong></span><span
lang="en-US">&rdquo;, &ldquo;</span><span lang="en-US"><strong
>processing</strong></span><span
lang="en-US">&rdquo; and &ldquo;</span><span
lang="en-US"><strong>appropriate technical and organisational measures</strong></span><span
lang="en-US">&rdquo; shall have the meanings given to them under applicable Data Protection Law.</span>
</p>
<h2 align="justify"><strong><span style="font-size: 14px;">2. Subject Matter, Nature and Purpose of GEOVizor&rsquo;s Processing of Personal Data</span></strong>
</h2>
<p align="justify" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">2.1 The subject matter, nature and purpose of the processing of Personal Data under this DPA is GEOVizor performance of the GEOVizor Platform Services (the &ldquo;Services) as further instructed in writing by the Customer in its use of the Services, unless required to do so otherwise by the Data Protection Law, in which case to the extent permitted by the Data Protection Law, GEOVizor shall inform the Customer of this legal requirement prior to carrying out the processing. GEOVizor shall only collect or process Personal Data for the period of rendering of the Services to the extent, and in such a manner, as is necessary for provision of the Services and in accordance with the DPA and the Data Protection Law applicable to GEOVizor.</span>
</p>
<h2><strong><span style="font-size: 14px;">3. Duration</span></strong>
</h2>
<p align="justify" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">3.1 The processing of Personal Data will be carried out by GEOVizor&nbsp;</span><span
lang="en-US">while GEOVizor Account of the Customer is in existence or as needed for the performance of the obligations and rights between GEOVizor and the Customer&nbsp;</span><span
lang="en-US">unless otherwise agreed upon in writing.</span></p>
<h2><strong><span style="font-size: 14px;">4. Type of Personal Data Processed</span></strong>
</h2>
<p align="justify">4.1 The Customer may submit Customer Personal Data to the Services, the
extent of which is determined and controlled by the Customer in its sole discretion, and which may include, but
is not limited to the following categories of Personal Data:</p>
<ul style="margin-left: 40px;">
<li align="justify" lang="ru-RU"><span lang="en-US"><strong
>Account Information.</strong></span><span lang="en-US">&nbsp;When the Customer signs up for a&nbsp;</span><span
lang="en-US">GEOVizor&nbsp;</span><span lang="en-US">Account, it is required certain information such as the name and email.</span><span
lang="en-US">The Customer may update or correct its information and email preferences at any time by visiting the&nbsp;</span><span
lang="en-US">GEOVizor&nbsp;</span><span lang="en-US">Account. GEOVizor can provide the Customer with additional support to access, correct, delete, or modify the information the Customer provided to GEOVizor and associated with the Customer&rsquo;s&nbsp;</span><span
lang="en-US">GEOVizor&nbsp;</span><span lang="en-US">Account. To protect the security, GEOVizor takes reasonable steps (such as requesting any legal information) to verify the identity of the Customer before making corrections. The Customer is responsible for maintaining the secrecy of the password and information of the Customer&rsquo;s&nbsp;</span><span
lang="en-US">GEOVizor&nbsp;</span><span lang="en-US">Account at all times.&nbsp;</span>
</li>
<li align="justify" lang="ru-RU"><span lang="en-US"><strong
>Additional Profile Information.&nbsp;</strong></span><span
lang="en-US">The Customer may choose to provide additional information as part of its&nbsp;</span><span
lang="en-US">GEOVizor</span><span lang="en-US"> profile. Profile information helps the Customer to get more from the&nbsp;</span><span
lang="en-US">GEOVizor Platform</span><span lang="en-US">. It&rsquo;s the Customer&rsquo;s choice whether to include sensitive information on its&nbsp;</span><span
lang="en-US">GEOVizor</span><span lang="en-US"> profile.</span>
</li>
<li align="justify" lang="ru-RU"><span lang="en-US"><strong
>Other Information.</strong></span><span lang="en-US">&nbsp;The Customer may otherwise choose to provide GEOVizor information when the Customer fills in a form, conducts a search, updates or adds information to its GEOVizor Account, responds to surveys, posts to community forums, participates in promotions, or uses other features of the GEOVizor Platform.</span>
</li>
</ul>
<h2 align="justify"><strong><span style="font-size: 14px;">5. GEOVizor Obligations&nbsp;</span></strong>
</h2>
<p style="margin-left: 20px;"><span
lang="en-US">5.1 GEOVizor agrees and/or warrants:&nbsp;</span></p>
<p style="margin-left: 40px;">(a) to process the Personal Data only on behalf of the Customer and in compliance with
its instructions and the DPA; if it cannot provide such compliance for whatever reasons, it agrees to inform
promptly the Customer of its inability to comply, in which case the Customer is entitled to suspend the transfer
of data and/or terminate the Services;</p>
<p style="margin-left: 40px;">(b) that all Personal Data processed on behalf of the Customer remains the property of
the Customer and/or the relevant Data subjects;</p>
<p style="margin-left: 40px;">(c) that it has no reason to believe that the legislation applicable to it prevents it
from fulfilling the instructions received from the Customer and its obligations under the DPA and that in the
event of a change in this legislation which is likely to have a substantial adverse effect on the warranties and
obligations provided by the DPA, it will promptly notify the change to the Customer as soon as it is aware, in
which case the Customer is entitled to suspend the transfer of data and/or terminate the Services;</p>
<p style="margin-left: 40px;"><span lang="en-US">(d) that it has implemented the technical and organizational security measures specified in Appendix 1&nbsp;</span><span
lang="en-US">before processing the Personal Data transferred;</span></p>
<p style="margin-left: 40px;">(e) that it will promptly notify the Customer about:</p>
<p style="margin-left: 60px;">i. any legally binding request for disclosure of the Personal Data by a law
enforcement authority unless otherwise prohibited, such as a prohibition under criminal law to preserve the
confidentiality of a law enforcement investigation;</p>
<p style="margin-left: 60px;">ii. any accidental or unauthorized access; and</p>
<p style="margin-left: 60px;">iii. any request received directly from the data subjects without responding to that
request, unless it has been otherwise authorized to do so;</p>
<p align="JUSTIFY" style="margin-left: 40px;">(f) to deal promptly and properly with all inquiries from the Customer
relating to its processing of the Personal Data subject to the transfer and to abide by the advice of the
supervisory authority with regard to the processing of the data transferred;</p>
<p align="JUSTIFY" style="margin-left: 40px;">(g) at the request of the Customer to submit its data-processing
facilities for audit of the processing activities covered by the DPA;</p>
<p align="JUSTIFY" style="margin-left: 40px;">(h) that, in the event of sub-processing, it has previously informed
the Customer and obtained its prior written consent;</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(i) that the processing services by the sub-processor will be carried out in accordance with Section 8;</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(j) to appoint a data protection officer, who performs his/her duties in compliance with the Data Protection Law. The data protection officers contact details are available at GEOVizor web page.</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(k) to entrust only such employees with the data processing outlined in this DPA who have been bound to confidentiality and have previously been familiarized with the data protection provisions relevant to their work. GEOVizor and any person acting under its authority who has access to Personal Data, shall not process that data unless on instructions from the Customer, unless required to do so by the Data Protection Law;&nbsp;</span>
</p>
<p align="JUSTIFY" style="margin-left: 40px;">(l) to monitor periodically the internal processes to ensure that
processing within GEOVizor area of responsibility is in accordance with the requirements of the Data Protection
Law and the protection of the rights of the data subject.</p>
<h2 align="justify"><strong><span style="font-size: 14px;">6. Customer Obligations&nbsp;</span></strong>
</h2>
<p align="justify" style="margin-left: 20px;">6.1 The Customer agrees and/or warrants:&nbsp;</p>
<p align="JUSTIFY" style="margin-left: 40px;">(a) that the processing, including the transfer itself, of the
Personal Data has been and will continue to be carried out in accordance with the relevant provisions of the
Data Protection Law and does not violate the relevant provisions;</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(b) that it has instructed and throughout the duration of the personal data-processing services will instruct GEOVizor to process the Personal Data transferred only on the Customer&rsquo;s behalf and in accordance with the Data Protection Law and the DPA;&nbsp;</span>
&nbsp;</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(c) that GEOVizor will provide sufficient guarantees in respect of the technical and organizational security measures specified in&nbsp;</span>
Appendix 1 t<span lang="en-US">o this DPA;&nbsp;</span></p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(d) that after assessment of the requirements of the Data Protection Law, the security measures are appropriate to protect Personal Data against accidental or unlawful destruction or accidental loss, alteration, unauthorized disclosure or access, in particular where the processing involves the transmission of data over a network, and against all other unlawful forms of processing, and that these measures ensure a level of security appropriate to the risks presented by the processing and the nature of the data to be protected having regard to the state of the art and the cost of their implementation;&nbsp;</span>
&nbsp;</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(e) that it will ensure compliance with the security measures;</span>
&nbsp;</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(f) to</span>
<span lang="en-US">&nbsp;access and use the Services only for legal, authorized, and acceptab</span><span
lang="en-US">le&nbsp;</span><span lang="en-US">purposes. The Customer will not use (or assist others in using) the Services in ways that: (a) violate, misappropriate, or infringe the rights of GEOVizor, its users, or others, including privacy, publicity, intellectual property, or other proprietary rights; (b) are illegal, obscene, defamatory, threatening, intimidating, harassing, hateful, racially, or ethnically offensive, or instigate or encourage conduct that would be illegal, or otherwise inappropriate; (c) involve publishing falsehoods, misrepresentations, or misleading statements; (d) impersonate someone; (e) involve sending illegal or impermissible communications such as bulk messaging, auto-messaging, auto-dialing, and the like; or (f) involve any other use of the Services prescribed in this DPA</span><span
lang="en-US">&nbsp;</span><span lang="en-US">unless otherwise authorized by GEOVizor;</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span
lang="en-US">(g) do&nbsp;</span> <span
lang="en-US">not to (or assist others to) access, use, copy, adapt, modify, prepare derivative works based upon, distribute, license, sublicense, transfer, display, perform, or otherwise exploit the <span
lang="en-US">GEOVizor Platform</span> in impermissible or unauthorized manners, or in ways that burden, impair, or harm GEOVizor, the <span
lang="en-US">GEOVizor Platform</span>, systems, other users, or others, including that the Customer will not directly or through automated means: (a) reverse engineer, alter, modify, create derivative works from, decompile, or extract code from the <span
lang="en-US">GEOVizor Platform</span>; (b) send, store, or transmit viruses or other harmful computer code through or onto the <span
lang="en-US">GEOVizor Platform</span>; (c) gain or attempt to gain unauthorized access to the <span
lang="en-US">GEOVizor Platform</span> or systems; (d) interfere with or disrupt the integrity or performance of the <span
lang="en-US">GEOVizor Platform</span>; (e) create accounts for the <span
lang="en-US">GEOVizor Platform t</span>hrough unauthorized or automated means; (f) collect the information of or about other users in any impermissible or unauthorized manner; (g) sell, resell, rent, or charge for the <span
lang="en-US">GEOVizor Platform</span>; or (h) distribute or make the <span
lang="en-US">GEOVizor Platform&nbsp;</span>available over a network where it could be used by multiple devices at the same time;</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(h) that t</span>
<span lang="en-US">he Customer</span><span lang="en-US">&nbsp;is responsible for keeping the Customer&rsquo;s GEOVizor Account safe and secure, and the Customer will notify GEOVizor promptly of any unauthorized use or security breach of the Customer&rsquo;s Account or the <span
lang="en-US">GEOVizor Platform</span>;</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span
lang="en-US">(i) that GEOVizor</span>&nbsp; <span
lang="en-US">&nbsp;grants the Customer a limited, revocable, non-exclusive, non-sublicensable, and non-transferable license to use the <span
lang="en-US">GEOVizor Platform</span>. This license is for the sole purpose of enabling the Customer to use the <span
lang="en-US">GEOVizor Platform</span>, in the manner permitted by this DPA. No licenses or rights are granted to the Customer by implication or otherwise, except for the licenses and rights expressly granted to the Customer.&nbsp;</span>
</p>
<p align="JUSTIFY" lang="ru-RU"><strong><span style="font-size: 14px;">7. Technical and Organizational Measures</span></strong>
</p>
<p style="margin-left: 20px;"><span lang="en-US">7.1 GEOVizor shall take the appropriate technical and organizational measures to adequately protect Personal Data against accidental or unlawful destruction, loss, alteration, unauthorized disclosure of, or access to Personal Data, described under Appendix 1.</span><span
lang="en-US">&nbsp;Such measures include but not limited to physical and IT measures, and organizational measures to:</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(a) the prevention of unauthorized persons from gaining access to Personal Data processing systems (physical access control),</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(b) the prevention of Personal Data processing systems from being used without authorization (logical access control),</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(c) ensuring that persons entitled to use a Personal Data processing system gain access only to such Personal Data as they are entitled to accessing in accordance with their access rights, and that, in the course of processing or use and after storage, Personal Data cannot be read, copied, modified or deleted without authorization (data access control),</span>
</p>
<p align="JUSTIFY" style="margin-left: 40px;">(d) ensuring that Personal Data cannot be read, copied, modified or
deleted without authorization during electronic transmission, transport or storage on storage media, and that
the target entities for any transfer of Personal Data by means of data transmission facilities can be
established and verified (data transfer control),</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">(e) ensuring the establishment of an audit trail to document whether and by whom Personal Data have been entered into, modified in, or removed from Personal Data processing systems (entry control),</span>
</p>
<p align="JUSTIFY" style="margin-left: 40px;">(f) ensuring that Personal Data is protected against accidental
destruction or loss (availability control).</p>
<p style="margin-left: 20px;">7.2 The technical and organizational measures are subject to technical progress and
further development. In this respect GEOVizor may implement alternative adequate measure, however, the security
level of the defined measures must never be reduced. Major changes must be documented.</p>
<h2><strong><span
style="font-size: 14px;">8. Sub-Processors</span></strong></h2>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">8.1 The Customer agrees that GEOVizor may engage GEOVizor Affiliate or third parties to process Personal Data in order to assist GEOVizor to deliver the Services on behalf of the Customer (</span><span
lang="en-US"><strong
>&ldquo;Sub-processors&rdquo;</strong></span><span lang="en-US">). GEOVizor has or will enter into written agreement with each Sub-processor containing data protection obligations not less protective than those in this DPA to the extent applicable to the nature of the Services provided by such Sub-processor. If the Sub-processor processes the Services outside the EU/EEA, GEOVizor shall ensure that the transfer is made pursuant to European Commission approved standard contractual clauses for the transfer of Personal Data which the Customer authorizes GEOVizor to enter into on its behalf, or that other appropriate legal data transfer mechanisms are used.</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">8.2 The current Sub-processors for the Services are set out at&nbsp;</span><span
lang="en-US"><u><a href="https://GEOVizor.com/en/sub-processors/"
target="_blank">https://GEOVizor.com/en/sub-processors/</a></u></span><span
lang="en-US">&nbsp;(&ldquo;Sub-processor List&rdquo;) and the Customer agrees and approves that GEOVizor has engaged such Sub-processors to process Personal Data as set out in the list. GEOVizor shall provide notification of a new Sub-processor(s) before authorizing any new Sub-processor(s) to process Personal Data in connection with the provision of the applicable Service.</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">8.3 GEOVizor shall notify the Customer thirty (30) days&rsquo; in advance of any intended changes concerning the addition or replacement of any Sub-processor during which period the Customer may raise objections to the Sub-processor&rsquo;s appointment. Any objections must be raised promptly (and in any event no later than fourteen (14) days following GEOVizor&rsquo;s notification of the intended changes). Should GEOVizor choose to retain the objected to Sub-processor, GEOVizor will notify the customer at least fourteen (14) days before authorizing the Sub-processor to process Personal Data and then the Customer may immediately discontinue using the relevant portion of the Services and may terminate the relevant portion of the Services.</span>
</p>
<p align="JUSTIFY" style="margin-left: 20px;">8.4 For the avoidance of doubt, where any Sub-processor fails to
fulfill its obligations under any sub-processing agreement or under applicable law GEOVizor will remain fully
liable to the Customer for the fulfillment of its obligations under this DPA.</p>
<h2><strong><span style="font-size: 14px;">9. Audit</span></strong></h2>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">9.1 In order to confirm compliance with this DPA, the Customer shall be at liberty to conduct an audit by assigning an independent third party who shall be obliged to observe confidentiality in this regard. Any such audit must occur during GEOVizor&rsquo;s normal business hours and will be permitted only to the extent required for the Customer to assess GEOVizor&rsquo;s compliance with this DPA. In connection with any such audit, the Customer will ensure that the auditor will: (a) review any information on GEOVizor&rsquo;s premises; (b) observe reasonable on-site access and other restrictions reasonably imposed by GEOVizor; (c) comply with GEOVizor&rsquo;s policies and procedures, and (d) not unreasonably interfere with GEOVizor&rsquo;s business activities. GEOVizor reserves the right to restrict or suspend any audit in the event of any breach of the conditions specified in this Section 9</span><span
lang="en-US">.&nbsp;</span></p>
<p align="JUSTIFY" style="margin-left: 20px;">9.2 In the event that the Customer, a regulator or data protection
authority requires additional information or an audit related to the Services, then, GEOVizor agrees to submit
its data processing facilities, data files and documentation needed for processing Personal Data to audit by the
Customer (or any third party such as inspection agents or auditors, selected by Customer) to ascertain
compliance with this DPA, subject to being given notice and the auditor entering into a non-disclosure agreement
directly with GEOVizor. GEOVizor agrees to provide reasonable cooperation to Customer in the course of such
operations including providing all relevant information and access to all equipment, software, data, files,
information systems, etc. used for the performance of Services, including processing of Personal Data. Such
audits shall be carried out at the Customer&rsquo;s cost and expense.</p>
<p align="JUSTIFY" style="margin-left: 20px;">9.3 The audit may only be undertaken when there are specific grounds
for suspecting the misuse of Personal Data, and no earlier than two weeks after the Customer has provided
written notice to GEOVizor.</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">9.4 The findings in respect of the performed audit will be discussed and evaluated by the parties and, where applicable, implemented accordingly as the case may be by one of the parties or jointly by both parties. The costs of the audit will be borne by the Customer.</span>
</p>
<h2 align="JUSTIFY"><strong><span style="font-size: 14px;">10. Notification of A Data Breach</span></strong>
</h2>
<p align="JUSTIFY" style="margin-left: 20px;">10.1 In the event of GEOVizor aware of any breach of security that
results in the accidental, unauthorized or unlawful destruction or unauthorized disclosure of or access to
Personal Data GEOVizor shall to the best of its ability, notify the Customer thereof with undue delay, after
which the Customer shall determine whether or not to inform the Data subjects and/or the relevant regulatory
authority(ies). This duty to report applies irrespective of the impact of the leak. GEOVizor will endeavour that
the furnished information is complete, correct and accurate.</p>
<p align="JUSTIFY" style="margin-left: 20px;">10.2 If required by law and/or regulation, GEOVizor shall cooperate in
notifying the relevant authorities and/or Data subjects. The Customer remains the responsible party for any
statutory obligations in respect thereof.</p>
<p align="JUSTIFY" style="margin-left: 20px;">10.3 The duty to report includes in any event the duty to report the
fact that a leak has occurred, including details regarding:</p>
<ul style="margin-left: 40px;">
<li>the (suspected) cause of the leak;</li>
<li>the (currently known and/or anticipated) consequences thereof;</li>
<li>the (proposed) solution;</li>
<li>the measures that have already been taken.</li>
</ul>
<p><strong>11. Deletion and Return of Personal Data</strong></p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">11.1 The parties agree that on the termination of the provision of data-processing services, the GEOVizor and its subcontractors shall, at the choice of the Customer, return all the Personal Data transferred and the copies thereof to the Customer or shall destroy all the Personal Data and certify to the Customer that it has done so, unless legislation imposed upon GEOVizor prevents it from returning or destroying all or part of the Personal Data transferred. In that case, GEOVizor warrants that it will guarantee the confidentiality of the Personal Data transferred and will not actively process the Personal Data transferred anymore. GEOVizor and its subcontractors warrant that upon request of the Customer and/or of the supervisory authority, it will submit its data-processing facilities for an audit of the measures referred to in Section 9</span>
<span lang="en-US">.&nbsp;</span></p>
<h2><strong><span style="font-size: 14px;">12. Governing Law/Forum</span></strong>
</h2>
<p align="JUSTIFY" style="margin-left: 20px;">12.1 This DPA shall be governed by and interpreted in accordance with
the laws of Lithuania.</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">12.2 Any and all claims, disputes or controversies arising under, out of, or in connection with this DPA, breach, termination or validity thereof, which have not been resolved by good faith negotiations between GEOVizor and the Customer within period of thirty (30) calendar days after receipt of a notice from one party to the other requesting negotiations shall be resolved by final and binding arbitration in the Vilnius Court of Commercial Arbitration in accordance with its Rules of Arbitration as in force and effect on the date of the DPA. Disputes shall be settled by a single arbitrator. Arbitration proceedings shall be held in Vilnius, Lithuania. The place of arbitration shall be Vilnius, Lithuania. The language of arbitration shall be English. Relevant documents in other languages shall be translated into English if the arbitrators so direct. All expenses and costs of the arbitrators and the arbitration in connection therewith will be shared equally, except that GEOVizor and the Customer will each bear the costs of its own prosecution and defense, including without limitation attorney&rsquo;s fees and the production of witnesses and other evidence. Any award rendered in such arbitration shall be final and may be enforced by either party.</span>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">12.3 The parties agree to keep all details of the arbitration proceedings and arbitral award strictly confidential and shall use all reasonable efforts to take such action as may be appropriate to prevent the unauthorized disclosure of the proceedings, any information disclosed in connection therewith and the award granted.</span>
</p>
<h2><span style="font-size: 18px;">Appendix No. 1</span></h2>
<p align="JUSTIFY"><strong>Description of the technical and organizational
measures implemented by GEOVizor:</strong></p>
<p align="JUSTIFY">GEOVizor shall implement the measures described in this appendix, provided
that the measures directly or indirectly contribute or can contribute to the protection of Personal Data during
the period of GEOVizor&rsquo;s Services rendering to the Customer. If GEOVizor believes that a measure is not
necessary for the respective Service or part thereof, GEOVizor will justify this and come to an agreement with
the Customer.</p>
<p align="JUSTIFY">The technical and organizational measures are subject to technical progress
and development. In this respect GEOVizor is permitted to implement alternative adequate measures. The level of
security must align with industry security best practice and not less than, the measures set forth herein. All
major changes are to be agreed with the Customer and documented.</p>
<h2><strong><span
style="font-size: 14px;">1. Risk management</span></strong></h2>
<p style="margin-left: 20px;"><strong>1.1 Security risk management</strong></p>
<p style="margin-left: 40px;">1.1.1 GEOVizor shall identify and evaluate security risks related to confidentiality,
integrity and availability and based on such evaluation implement appropriate technical and organizational
measures to ensure a level of security which is appropriate to the risk.</p>
<p style="margin-left: 40px;">1.1.2 GEOVizor shall have documented processes and routines for handling risks within
its operations.</p>
<p style="margin-left: 40px;">1.1.3 GEOVizor shall periodically assess the risks related to information systems and
processing, storing and transmitting information.</p>
<p style="margin-left: 20px;"><strong>1.2 Security risk management for personal data</strong>
</p>
<p align="JUSTIFY" style="margin-left: 40px;">1.2.1 GEOVizor shall identify and evaluate security risks related to
confidentiality, integrity and availability and based on such evaluation implement appropriate technical and
organizational measures to ensure a level of security which is appropriate to the risk of the specific Personal
Data types and purposes being processed by GEOVizor, including inter alia as appropriate:</p>
<ul style="margin-left: 60px;">
<li><span lang="en-US">The pseudonymisation and encryption of Personal Data;</span>
</li>
<li><span lang="en-US">The ability to ensure the ongoing confidentiality, integrity, availability and resilience of processing systems and services;</span>
</li>
<li><span lang="en-US">The ability to restore the availability and access to the Customer&rsquo;s Data in a timely manner in the event of a physical or technical incident;</span>
</li>
<li><span lang="en-US">A process for regularly testing, assessing and evaluating the effectiveness of technical and organizational measures for ensuring the security of the processing.</span>
</li>
</ul>
<p align="JUSTIFY" style="margin-left: 40px;">1.2.2 GEOVizor shall have documented processes and routines for
handling risks when processing Personal Data on behalf of the Customer.</p>
<p align="JUSTIFY" style="margin-left: 40px;">1.2.3 GEOVizor shall periodically assess the risks related to
information systems and processing, storing and transmitting Personal Data.</p>
<p style="margin-left: 20px;"><strong>1.3&nbsp;</strong><strong><strong
>Information security policies</strong>&nbsp;</strong>
</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 40px;"><span lang="en-US">1.3.1 GEOVizor shall have a defined and documented information security management system including an information security policy and procedures in place, which shall be approved by GEOVizor&rsquo;s management. They shall be published within GEOVizor&acute;s organization and communicated to relevant GEOVizor personnel.</span>
</p>
<p align="JUSTIFY" style="margin-left: 40px;">1.3.2 GEOVizor shall periodically review GEOVizor&rsquo;s security
policies and procedures and update them if required to ensure their compliance with this Appendix.</p>
<h2 align="JUSTIFY"><strong><span style="font-size: 14px;">2. Organization of information security</span></strong>
</h2>
<p align="JUSTIFY" style="margin-left: 20px;">2.1 GEOVizor shall have defined and documented security roles and
responsibilities within its organization.</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">2.2 GEOVizor shall appoint at least one data protection officer who has appropriate security competence and who has an overall responsibility for implementing the security measures under this Appendix and who will be the contact person for the Customer&rsquo;s security staff.</span>
</p>
<h2 lang="ru-RU"><strong><span style="font-size: 14px;">3. Human resource security</span></strong>
</h2>
<p align="JUSTIFY" style="margin-left: 20px;">3.1 GEOVizor shall ensure that GEOVizor personnel handles information
in accordance with the level of confidentiality required under the DPA.</p>
<p align="JUSTIFY" style="margin-left: 20px;">3.2 GEOVizor shall ensure that relevant GEOVizor personnel is aware of
the approved use (including use restrictions as the case may be) of information, facilities and systems under
the DPA.</p>
<p align="JUSTIFY" style="margin-left: 20px;">3.3 GEOVizor shall ensure that any GEOVizor personnel performing
assignments under the Agreement is trustworthy, meets established security criteria and has been, and during the
term of the assignment will continue to be, subject to appropriate screening and background verification.</p>
<p align="JUSTIFY" style="margin-left: 20px;">3.4 GEOVizor shall ensure that GEOVizor personnel with security
responsibilities is adequately trained to carry out security related duties.</p>
<p align="JUSTIFY" lang="ru-RU" style="margin-left: 20px;"><span lang="en-US">3.5 GEOVizor shall provide or ensure periodical security awareness training to relevant GEOVizor personnel.&nbsp;</span>Such
GEOVizor training shall include, without limitation:</p>
<p align="JUSTIFY" style="margin-left: 40px;">(a) How to handle customer information security (i.e. the protection
of the confidentiality, integrity and availability of information);</p>
<p align="JUSTIFY" style="margin-left: 40px;">(b) Why information security is needed to protect customers
information and systems;</p>
<p align="JUSTIFY" style="margin-left: 40px;">(c) The common types of security threats (such as identity theft,
malware, hacking, information leakage and insider threat);</p>
<p align="JUSTIFY" style="margin-left: 40px;">(d) The importance of complying with information security policies and
applying associated standards/procedures;</p>
<p align="JUSTIFY" style="margin-left: 40px;">(e) Personal responsibility for information security (such as
protecting customer&rsquo;s privacy-related information and reporting actual and suspected data breaches).</p>
<p lang="ru-RU"></p>
<h2 lang="ru-RU"><strong><span
style="font-size: 14px;">4. Access control</span></strong></h2>
<p align="JUSTIFY">GEOVizor shall have a defined and documented access control policy for
facilities, sites, network, system, application and information/data access (including physical, logical and
remote access controls), an authorization process for user access and privileges, procedures for revoking access
rights and an acceptable use of access privileges for GEOVizor personnel in place.</p>
<p align="JUSTIFY">GEOVizor shall have a formal and documented user registration and
de-registration process implemented to enable assignment of access rights.</p>
<p align="JUSTIFY">GEOVizor shall assign all access privileges based on the principle of
need-to-know and principle of least privilege.</p>
<p align="JUSTIFY">GEOVizor shall use strong authentication (multi-factor) for remote access
users and users connecting from an untrusted network.</p>
<p align="JUSTIFY" lang="ru-RU"><span lang="en-US">GEOVizor shall ensure that GEOVizor personnel has a personal and unique identifier (user ID), and use an appropriate authentication technique, which confirms and ensures the identity of users.</span>
</p>
<h2><strong><span style="font-size: 14px;">5. Physical and environmental security</span></strong>
</h2>
<p align="JUSTIFY">GEOVizor shall protect information processing facilities against external
and environmental threats and hazards, including power/cabling failures and other disruptions caused by failures
in supporting utilities. This includes physical perimeter and access protection.</p>
<p></p>
<h2><strong><span
style="font-size: 14px;">6. Operations security</span></strong></h2>
<p align="JUSTIFY">GEOVizor shall have an established change management system in place for
making changes to business processes, information processing facilities and systems. The change management
system shall include tests and reviews before changes are implemented, such as procedures to handle urgent
changes, roll back procedures to recover from failed changes, logs that show, what has been changed, when and by
whom.</p>
<p align="JUSTIFY">GEOVizor shall implement malware protection to ensure that any software used
for GEOVizor&rsquo;s provision of the Services to the Customer is protected from malware.</p>
<p align="JUSTIFY">GEOVizor shall make backup copies of critical information and test back-up
copies to ensure that the information can be restored as agreed with the Customer.</p>
<p align="JUSTIFY" lang="ru-RU"><span lang="en-US">GEOVizor shall log and monitor activities, such as create, reading, copying, amendment and deletion of processed data, as well as exceptions, faults and information security events and regularly review these. Furthermore, GEOVizor shall protect and store (for at least 6 months or such period/s set by Data Protection Law) log information, and on request, deliver monitoring data to the Customer. Anomalies / incidents / indicators of compromise shall be reported according to the data breach management requirements as set out in&nbsp;</span>clause
9<span lang="en-US">, below.</span></p>
<p align="JUSTIFY">GEOVizor shall manage vulnerabilities of all relevant technologies such as
operating systems, databases, applications proactively and in a timely manner.</p>
<p align="JUSTIFY">GEOVizor shall establish security baselines (hardening) for all relevant
technologies such as operating systems, databases, applications.</p>
<p align="JUSTIFY">GEOVizor shall ensure development is segregated from test and production
environment.</p>
<h2 lang="ru-RU"><strong><span style="font-size: 14px;">7. Communications security</span></strong>
</h2>
<p align="JUSTIFY">GEOVizor shall implement network security controls such as service level,
firewalling and segregation to protect information systems.</p>
<h2><strong><span style="font-size: 14px;">8. GEOVizor relationship with sub-suppliers</span></strong>
</h2>
<p align="JUSTIFY">GEOVizor shall reflect the content of this Appendix in its agreements with
Sub-processors that perform tasks assigned under the DPA.</p>
<p align="JUSTIFY">GEOVizor shall regularly monitor, review and audit Sub-processor&rsquo;s
compliance with this Appendix.</p>
<p align="JUSTIFY">GEOVizor shall, at the request of the Customer, provide the Customer with
evidence regarding Sub-processor&rsquo;s compliance with this Appendix.</p>
<h2><strong><span
style="font-size: 14px;">9. Data breach management</span></strong></h2>
<p>GEOVizor shall have established procedures for data breach management.</p>
<p align="JUSTIFY" lang="ru-RU"><span lang="en-US">GEOVizor shall inform the Customer about any data breach (including but not limited to incidents in relation to the processing of Personal Data) as soon as possible but no later than within 36 hours after the data breach has been identified.</span>
</p>
<p align="JUSTIFY">All reporting of security-related incidents shall be treated as confidential
information and be encrypted, using industry standard encryption methods.</p>
<p align="JUSTIFY">The data breach report shall contain at least the following information:</p>
<p align="JUSTIFY" style="margin-left: 20px;">(a) The nature of the data breach,</p>
<p align="JUSTIFY" style="margin-left: 20px;">(b) The nature of the Personal Data affected,</p>
<p align="JUSTIFY" style="margin-left: 20px;">(c) The categories and number of data subjects concerned,</p>
<p align="JUSTIFY" style="margin-left: 20px;">(d) The number of Personal Data records concerned,</p>
<p align="JUSTIFY" style="margin-left: 20px;">(e) Measures taken to address the data breach,</p>
<p align="JUSTIFY" style="margin-left: 20px;">(f) The possible consequences and adverse effect of the data breach,
and</p>
<p align="JUSTIFY" style="margin-left: 20px;">(g) Any other information the Customer is required to report to the
relevant regulator or data subject.</p>
<p align="JUSTIFY" lang="ru-RU"><span lang="en-US">To the extent legally possible, GEOVizor may claim compensation for support services under this clause 9&nbsp;</span><span
lang="en-US">which are not attributable to failures on the part of GEOVizor.</span></p>
<h2><strong><span style="font-size: 14px;">10. Business continuity management</span></strong>
</h2>
<p align="JUSTIFY">GEOVizor shall identify business continuity risks and take necessary actions
to control and mitigate such risks.</p>
<p align="JUSTIFY">GEOVizor shall have documented processes and routines for handling business
continuity.</p>
<p align="JUSTIFY">GEOVizor shall ensure that information security is embedded into the
business continuity plans</p>
<p align="JUSTIFY">GEOVizor shall periodically assess the efficiency of its business continuity
management, and compliance with availability requirements (if any).</p>
</div>
</body>
</html>

View File

@ -0,0 +1,143 @@
<?php
//Выбираю объезды в GeoJSON и отправляю клиенту
require_once("../../monitoring/config.php");
function sendError($msg)
{
$json='{"errorCode":1,"errorMessage":'.json_encode($msg,JSON_UNESCAPED_UNICODE).'}';
header('Content-Type: application/json');
echo $json;
exit;
}
$db = connectToDB();
//$db->exec('SET NAMES utf8');
//$db->exec("SET time_zone = '+00:00'");
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
if($fn=='1') //Вернуть список
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if(!property_exists($object,'name') or $object->name=='') $object->name='null'; else $object->name='\'%'.$object->name.'%\'';
$sql = '
SELECT
id
,name
,date_start
,date_end
,coalesce(ST_NPoints(geom),0) as count
,ST_X(ST_Centroid(geom)) lon
,ST_Y(ST_Centroid(geom)) lat
FROM
main.detours
where
del=false
and ('.$object->name.' is null or name like '.$object->name.')
ORDER BY name;
';
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
//Массив объектов
$json ='[';
//Перебираю и последовательно отправляю не отправленные пломбы
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$json .="\n";
$json .='{';
$json .='"id":'.json_encode($row['id']).",\n";
$json .='"name":'.json_encode($row['name'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"date_start":'.json_encode($row['date_start'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"date_end":'.json_encode($row['date_end'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"lat":'.json_encode($row['lat']).",\n";
$json .='"lon":'.json_encode($row['lon']).",\n";
$json .='"count":'.json_encode($row['count'])."\n";
$json .='},';
}
if($json[strlen($json) - 1]==','){
$json=substr ( $json , 0, strlen($json)-1 );
}
$json .=']';
header('Content-Type: application/json');
echo $json;
exit;
}else if($fn=='2') //Вернуть GEOJSON по ID записи
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object->id=='') $object->id='null';
/*if($object->cnumber=='') $object->cnumber='null'; else $object->cnumber='"%'.$object->cnumber.'%"'; //Гос. номер
if($object->tnumber=='') $object->tnumber='null'; else $object->tnumber='"%'.$object->tnumber.'%"'; //Номер ТД
if($object->country_seal_begin=='') $object->country_seal_begin='null'; //Страна пломб.
if($object->country_seal_end=='') $object->country_seal_end='null'; //Страна распломб.*/
//Выбираю геометрию
$sql="select ST_AsGeoJSON(geom,6,0) as geom from main.detours where id=".$object->id.";";
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
$json="{}";
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$json=$row[0];
}
}
header('Content-Type: application/json');
echo $json;
exit;
}else if($fn=='3') //Удалить запись
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object==null) $object = (object)[];
if(!property_exists($object,'id') or $object->id=='') $object->id=null; //Поле заполнено если редактирвание записи
if($object->id!=null)
{
try
{
$sql="update main.detours set del=true where id=".$object->id;
$db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
$json='{}';
header('Content-Type: application/json');
echo $json;
exit;
}else
{
sendError("ID is not set!");
}
}else
{
sendError("Fn is null!");
}

View File

@ -0,0 +1,174 @@
<?php
header('Cache-Control: no-store, no-cache, must-revalidate');
header("Expires: 0");
header('Pragma: no-cache');
@session_start();
require_once("../../monitoring/config.php");
function sendError($msg)
{
$obj = new StdClass();
$obj->errorCode = 1;
$obj->errorMessage = $msg;
$obj->data = array();
header('Content-Type: application/json');
header("Cache-Control: no-cache, must-revalidate");
echo json_encode($obj);
exit();
}
$db = connectToDB();
//$db->exec('SET NAMES utf8');
//$db->exec("SET time_zone = '+00:00'");
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
if($fn=='1') //Вернуть список геозон
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if(!property_exists($object,'name') or $object->name=='') $object->name='null'; else $object->name='\'%'.$object->name.'%\'';
//if(!property_exists($object,'geofence_group_id') or $object->geofence_group_id=='') $object->geofence_group_id='null';
if(!property_exists($object,'geofence_type_id') or $object->geofence_type_id=='') $object->geofence_type_id='null';
$obj = new StdClass();
$obj->errorCode = 0;
$obj->errorMessage = '';
$obj->data = array();
$sql='select
id,
name
from
main.geofences_types gt
where
del=false
and gt.company_id = (select company_id from main._users where id='.$_SESSION['USER_ID'].')
and id in (select geofence_type_id from main.geofences g where g.del=false )
and (' . $object->geofence_type_id . ' is null or gt.id = ' . $object->geofence_type_id . ')
ORDER BY gt.name;';
try
{
$types = $db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
while ($type = $types->fetch(PDO::FETCH_ASSOC)) {
$type=(object)$type;
$type->geofences = array();
$sql = '
SELECT
g.id
,6 as icon_id
,g.name
,coalesce(ST_NPoints(geom),0) as count
,ST_X(ST_Centroid(geom)) lon
,ST_Y(ST_Centroid(geom)) lat
,gt.name as geofence_type_name
FROM
main.geofences g
left join main.geofences_types gt on gt.id=g.geofence_type_id
where
g.del=false
and g.company_id = (select company_id from main._users where id='.$_SESSION['USER_ID'].')
and (' . $object->name . ' is null or g.name like ' . $object->name . ')
and g.geofence_type_id = '.$type->id.'
ORDER BY g.name;
';
try {
$geofences = $db->query($sql);
} catch (Exception $e) {
sendError($e->getMessage());
}
//Перебираю и последовательно отправляю не отправленные пломбы
while ($geofence = $geofences->fetch(PDO::FETCH_ASSOC)) {
$geofence = (object)$geofence;
array_push($type->geofences, $geofence);
}
array_push($obj->data, $type);
}
header('Content-Type: application/json');
header("Cache-Control: no-cache, must-revalidate");
echo json_encode($obj);
exit;
}else if($fn=='2') //Вернуть GEOJSON по ID записи
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object->id=='') $object->id='null';
/*if($object->cnumber=='') $object->cnumber='null'; else $object->cnumber='"%'.$object->cnumber.'%"'; //Гос. номер
if($object->tnumber=='') $object->tnumber='null'; else $object->tnumber='"%'.$object->tnumber.'%"'; //Номер ТД
if($object->country_seal_begin=='') $object->country_seal_begin='null'; //Страна пломб.
if($object->country_seal_end=='') $object->country_seal_end='null'; //Страна распломб.*/
//Выбираю геометрию
$sql="select ST_AsGeoJSON(geom,6,0) as geom from main.geofences where id=".$object->id.";";
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
$json="{}";
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$json=$row[0];
}
}
header('Content-Type: application/json');
echo $json;
exit;
}else if($fn=='3') //Удалить запись
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object==null) $object = (object)[];
if(!property_exists($object,'id') or $object->id=='') $object->id=null; //Поле заполнено если редактирвание записи
if($object->id!=null)
{
try
{
$sql="update main.geofences set del=true where id=".$object->id;
$db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
$obj = new StdClass();
$obj->errorCode = 0;
$obj->errorMessage = '';
header('Content-Type: application/json');
header("Cache-Control: no-cache, must-revalidate");
echo json_encode($obj);
exit();
}else
{
sendError("ID is not set!");
}
}else
{
sendError("Fn is null!");
}

View File

@ -0,0 +1,277 @@
<?php
//Вернуть в JSON кол-во необработанных сообщений (не присвоенных ни одному пользователю)
//И всё другое связаное с оброботкой сообщений для пользователя
@session_start();
require_once("../../monitoring/config.php");
//require_once("../tools.php");
$db = connectToDB();
//$db->exec('SET NAMES utf8');
//$db->exec("SET time_zone = '+00:00'");
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
if($fn=='1') //Вернуть кол-во не присвоеных пользователю сообщений
{
$m_all_count=0; //Количество не присвоенных никому сообщений.
$m_user_count=0; //Количество не обработаны сообщений для текущего пользователя.
$sql = 'SELECT count(*) FROM main.messages m join main.companies c on m.company_id=c.id WHERE m.del=false and m.id NOT IN (SELECT mu.message_id FROM main.messages_users mu WHERE del=false) and m.company_id=(select company_id from main._users where id='.$_SESSION['USER_ID'].')';
try {
$res = $db->query($sql);
} catch (Exception $e) {
echo $e->getMessage();
$res = null;
}
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$m_all_count = $row[0];
}
if($_SESSION['USER_ID']!='')
{
$sql = "SELECT COUNT(*) FROM main.messages_users WHERE user_id=".$_SESSION['USER_ID']." AND del=FALSE and date_read IS null";
try {
$res = $db->query($sql);
} catch (Exception $e) {
echo $e->getMessage();
$res = null;
}
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$m_user_count = $row[0];
}
}
$json ='';
header('Content-Type: application/json');
$json .='{';
$json .='"count":'.$m_all_count.",\n";
$json .='"user":'.$m_user_count."\n";
$json .='}';
echo $json;
exit;
}if($fn=='2') //Присвоить последнее сообщение пользователю и вернуть его ID
{
$id='';
$errorCode='0';
$errorMessage='';
$sql = 'SELECT m.id FROM main.messages m join main.companies c on m.company_id=c.id WHERE m.del=false and m.id NOT IN (SELECT mu.message_id FROM main.messages_users mu WHERE del=false) and m.company_id=(select company_id from main._users where id='.$_SESSION['USER_ID'].') ORDER BY m.priority desc, m.date_create LIMIT 1';
try {
$res = $db->query($sql);
} catch (Exception $e) {
$errorCode='1';
$errorMessage = $e->getMessage();
$res = null;
}
if($res != null)
{
if ($row = $res->fetch(PDO::FETCH_NUM))
{
//Присваиваю текущему пользователю
$sql="insert into main.messages_users(message_id,user_id,date_create)values(".$row[0].",".$_SESSION['USER_ID'].",now())";
try {
$res = $db->query($sql);
} catch (Exception $e) {
$errorCode='1';
$errorMessage = $e->getMessage();
$res = null;
}
$id=$row[0];
}
}
header('Content-Type: application/json');
echo '{"errorCode":'.$errorCode.',"errorMessage":'.json_encode($errorMessage,JSON_UNESCAPED_UNICODE).',"id":"'.$id.'"}';
exit;
}if($fn=='3') //Вернуть данные пользователю в соответствии со значением фильтра
{
$status='';
if(isset($_GET['status'])) { $status=$_GET['status']; }
if($status=='0'){ //Не отработанные
$sql='
SELECT
mu.id,
main."_"('.$_SESSION['USER_ID'].',m.subject) as subject,
main."_"('.$_SESSION['USER_ID'].',m.text) as text,
m.text_settings,
m.date_create
FROM
main.messages_users mu
JOIN main.messages m ON m.id=mu.message_id
WHERE
mu.del=FALSE
AND m.del=FALSE
and mu.user_id='.$_SESSION['USER_ID'].'
AND mu.date_read IS null';
}
if($status=='1'){ //Отработанные
//$sql='SELECT mu.id,m.subject,m.text,m.date_create FROM main.messages_users mu JOIN main.messages m ON m.id=mu.message_id WHERE mu.del=FALSE AND m.del=FALSE and mu.user_id='.$_SESSION['USER_ID'].' AND mu.date_read > NOW() - INTERVAL 30 DAY';
$sql='
SELECT
mu.id,
main."_"('.$_SESSION['USER_ID'].',m.subject) as subject,
main."_"('.$_SESSION['USER_ID'].',m.text) as text,
m.text_settings,
m.date_create
FROM
main.messages_users mu
JOIN main.messages m ON m.id=mu.message_id
WHERE
mu.del=FALSE
AND m.del=FALSE
and mu.user_id='.$_SESSION['USER_ID'].'
AND mu.date_read IS not null';
}
try {
$res = $db->query($sql);
} catch (Exception $e) {
$json = '{"errorMessage":'.json_encode($e->getMessage(),JSON_UNESCAPED_UNICODE).'}';
header('Content-Type: application/json');
echo $json;
exit;
}
$json ='';
$json .='[';
if($res != null)
{
while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$json .='{';
$json .='"id":'.$row['id'].',';
$json .='"subject":'.json_encode($row['subject'],JSON_UNESCAPED_UNICODE).',';
$text=$row['text'];
$text_settings=$row['text_settings'];
$obj=json_decode($text_settings);
if($obj) //Перебираю параметры и пытаюсь подставить в строку
{
foreach ($obj as $name => $value) {
$text = str_replace('${'.$name.'}', trt($value), $text);
}
}
$json .='"text":'.json_encode($text,JSON_UNESCAPED_UNICODE).'';
$json .="},";
}
if($json[strlen($json)-1]==','){
$json = substr($json, 0, -1);
}
}
$json .=']';
header('Content-Type: application/json');
echo $json;
exit;
}if($fn=='4') //Одна запись для подтверждения
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if(!property_exists($object,'id') or $object->id=='') $object->id='null'; //id компании
$sql='
SELECT
mu.id,
main."_"('.$_SESSION['USER_ID'].',m.subject) as subject,
main."_"('.$_SESSION['USER_ID'].',m.text) as text,
m.text_settings,
m.date_create,
m.action_name,
m.action_settings
FROM
main.messages_users mu
JOIN main.messages m ON m.id=mu.message_id
WHERE
mu.del=FALSE
AND m.del=FALSE
and mu.user_id='.$_SESSION['USER_ID'].'
AND mu.id='.$object->id;
try {
$res = $db->query($sql);
} catch (Exception $e) {
$json = '{"errorMessage":'.json_encode($e->getMessage(),JSON_UNESCAPED_UNICODE).'}';
header('Content-Type: application/json');
echo $json;
exit;
}
$json ='';
$json .='{';
if($res != null)
{
if($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
$json .='"id":'.$row['id'].',';
$json .='"subject":'.json_encode($row['subject'],JSON_UNESCAPED_UNICODE).',';
$text=$row['text'];
$text_settings=$row['text_settings'];
$obj=json_decode($text_settings);
if($obj) //Перебираю параметры и пытаюсь подставить в строку
{
foreach ($obj as $name => $value) {
$text = str_replace('${'.$name.'}', trt($value), $text);
}
}
$json .='"text":'.json_encode($text,JSON_UNESCAPED_UNICODE).',';
$json .='"action_name":'.json_encode($row['action_name'],JSON_UNESCAPED_UNICODE).',';
if($row['action_settings']!='')
{
$json .='"action_settings":'.$row['action_settings'];
}else
{
$json .='"action_settings":{}';
}
}
}
$json .='}';
header('Content-Type: application/json');
echo $json;
exit;
}if($fn=='5') //Отмечаем сообщение как обработанное
{
$errorCode='0';
$errorMessage='';
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
//Сохраняю текст и присваиваю время чтения
$sql="update main.messages_users set date_read=now(), description = :description where id = ".$object->id;
$stmt = $db->prepare($sql);
$stmt->bindParam(':description', $object->description, PDO::PARAM_STR);
try
{
$res = $stmt->execute();
} catch (Exception $e)
{
$errorCode='1';
$errorMessage = $e->getMessage();
}
header('Content-Type: application/json');
echo '{"errorCode":'.$errorCode.',"errorMessage":"'.$errorMessage.'"}';
exit;
}else
{
header('Content-Type: application/json');
echo '{"errorCode":1,"errorMessage":"Неизвестная функция!"}';
}

View File

@ -0,0 +1,94 @@
<?php
//Вернуть данные о объекте в виде HTML
@session_start();
if(isset($_GET["object_id"])){
$object_id=$_GET["object_id"];
}else{
echo "Not set ID";
exit;
}
require_once("../config.php");
require_once("../../resources/metadata/include/tools.php");
$db=connectToDB();
//$db->exec('SET NAMES utf8');
//$db->exec("SET time_zone = '+00:00'");
//Номер пломбы
$sql = '
SELECT
o.id,
COALESCE(o.name,\'\') as name,
c.name as company_name,
COALESCE(t.serial,\'\') || \' (\' || t.imei || \')\' as terminal_name
from
main.objects o
left join main.companies_objects co on co.object_id=o.id and co.del=false
left join main.companies c on c.id=co.company_id and c.del=false
left join main.terminals t on t.id=o.terminal_id and t.del=false
where
o.del=false
and o.id='.$object_id;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res = null;
}
$html='';
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$html.='<table border="1" cellpadding="7" style="width:100%;">';
$html.='<tr><td style="font-weight: bold;white-space: nowrap;vertical-align:top;padding-right:4px;">Гос. номер:</td><td colspan="3">'.$row['name'].'</td></tr>';
if($row['company_name']!=''){
$html.='<tr><td style="font-weight: bold;white-space: nowrap;padding-right:4px;">Наименование перевозчика:</td><td colspan="3">'.$row['company_name'].'</td></tr>';
}
if($row['terminal_name']!=''){
$html.='<tr><td style="font-weight: bold;white-space: nowrap;padding-right:4px;">Терминал:</td><td colspan="3">'.$row['terminal_name'].'</td></tr>';
}
//выбираю показания всех датчиков для данного объекта (установки)
$sql="
select
obr.id,
obs.name,
round(obr.value::numeric,2) as value,
to_char(obr.date+(select timezone from main._users where id=".$_SESSION['USER_ID']."), 'yyyy.mm.dd HH24:MI:SS') as date,
obs.sensor_type_id,
trst.measurement as terminalsensortype_name
from
main.objects_sensors obs
left join main.sensors_values obr on obr.id=obs.sensor_value_id
left join main.terminals_sensors trs on trs.id=obs.terminal_sensor_id
left join main.sensors_types trst on trst.id=trs.sensor_type_id
where
obs.del=false
--and obs.sensor_type_id in (1,16,17)
and obs.object_id=".$row['id']."
order by obs.name";
try
{
$res2 = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res2 = null;
}
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
{
$html.='<tr><td style="font-weight: bold;white-space: nowrap;padding-right:4px;">'.trt($row2['name']).':</td><td>'.$row2['value'].'</td><td>'.$row2['terminalsensortype_name'].'</td><td>'.$row2['date'].'</td></tr>';
}
$html.='</table>';
}
header('Content-Type: text/html');
echo $html;

View File

@ -0,0 +1,232 @@
<?php
//Выдираю все объекты на которых установлен терминал и отправляю клиенту
@session_start();
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
//if($object->active=='') $object->active='null';
//if($object->cnumber=='') $object->cnumber='null'; else $object->cnumber='"%'.$object->cnumber.'%"'; //Гос. номер
//if($object->tnumber=='') $object->tnumber='null'; else $object->tnumber='"%'.$object->tnumber.'%"'; //Номер ТД
//if($object->country_seal_begin=='') $object->country_seal_begin='null'; //Страна пломб.
//if($object->country_seal_end=='') $object->country_seal_end='null'; //Страна распломб.
require_once("../../monitoring/config.php");
require_once("../../resources/metadata/include/tools.php");
$db=connectToDB();
$db->exec("SET TIME ZONE 'UTC';"); //Ниже в коде есть смещение временной зоны под настройки каждого пользователя
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
if($fn=='0') //Вернуть список объектов в соответствии с фильтром
{
if(!property_exists($object,'company_id') or $object->company_id=='') $object->company_id='null'; //id компании
if(!property_exists($object,'cnumber') or $object->cnumber=='') $object->cnumber='null'; else $object->cnumber='\'%'.$object->cnumber.'%\''; //Гос. номер
$sql = 'SELECT
o.id,
0 as seq,
o.name,
sl.lat,
sl.lon,
round(cast(sl.speed as numeric),1) speed,
to_char(sl.date+(select timezone from main._users where id='.$_SESSION['USER_ID'].'), \'yyyy.mm.dd HH24:MI:SS\') as date,
\'\' as declaration,
i.file_name as icon_name,
\'\' as active,
t.serial || \' (\' || t.imei || \')\' AS terminal_name,
coalesce(g.geofences,\'\') as geofences
from
main.objects o
LEFT JOIN main.terminals_locations sl ON sl.id=o.terminal_location_id
LEFT JOIN main.terminals t ON t.id = o.terminal_id
LEFT JOIN main.icons i on i.id=o.icon_id
LEFT JOIN (SELECT og.object_id, CAST(array_to_string(array_agg(gg.name), \', \') AS character varying ) AS geofences FROM main.objects_geofences og, main.geofences gg WHERE og.del = FALSE and gg.del=false AND gg.id = og.geofence_id GROUP BY og.object_id) g ON o.id = g.object_id
where
o.del=false
and ('.$object->company_id.' is null or '.$object->company_id.' in (select company_id from main.companies_objects where del=false and object_id=o.id))
and ('.$object->cnumber.' is null or o.name like '.$object->cnumber.')
order by o.name,o.id';
try
{
$res = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res = null;
}
//Массив объектов
$json ='[';
//Перебираю и последовательно отправляю не отправленные пломбы
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$json .="\n";
$json .='{';
$json .='"id":"'.$row['id']."\",\n";
$json .='"seq":"'.$row['seq']."\",\n";
$json .='"active":"'.$row['active']."\",\n";
$json .='"name":"'.$row['name']."\",\n";
$json .='"terminal_name":"'.$row['terminal_name']."\",\n";
$json .='"declaration":"'.$row['declaration']."\",\n";
$json .='"icon_name":"'.afterLast($row['icon_name'],'_')."\",\n";
//выбираю показания 3х датчиков для данного объекта (установки)
//$json .="\"bat\":\"0\",\n";
//$json .="\"bat_date\":\"0\",\n";
//$json .="\"tros\":\"0\",\n";
//$json .="\"tros_date\":\"0\",\n";
//$json .="\"box\":\"0\",\n";
//$json .="\"box_date\":\"0\",\n";
$json .='"lat":'.json_encode($row['lat']).",\n";
$json .='"lon":'.json_encode($row['lon']).",\n";
$json .='"speed":'.json_encode($row['speed']).",\n";
$json .='"date":"'.$row['date']."\",\n";
$json .="\"country\":\"KZ\",\n";
$json .='"geofences":"'.$row['geofences']."\",\n";
//Выбираю показания всех датчиков (которые видны)
$json .='"sensors":[';
$sql="
select
obs.id,
obs.name,
round(obr.value::numeric,2) as value,
to_char(obr.date+(select timezone from main._users where id=".$_SESSION['USER_ID']."), 'yyyy.mm.dd HH24:MI:SS') as date,
obs.sensor_type_id,
trst.measurement as terminalsensortype_name
from
main.objects_sensors obs
left join main.sensors_values obr on obr.id=obs.sensor_value_id
left join main.terminals_sensors trs on trs.id=obs.terminal_sensor_id
left join main.sensors_types trst on trst.id=trs.sensor_type_id
where
obs.del=false
and obs.object_id=".$row['id']."
order by obs.name";
try
{
$res2 = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res2 = null;
}
if ($res2->rowCount() > 0) {
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
{
$json .='{';
$json .='"id":"'.$row2['id']."\",\n";
$json .='"name":"'.$row2['name']."\",\n";
$json .='"value":"'.$row2['value']."\",\n";
$json .='"type_name":"'.$row2['terminalsensortype_name']."\",\n";
$json .='"date":"'.$row2['date']."\"\n";
$json .='},';
}
$json=substr($json, 0, -1);
}
$json .=']';
$json .='},';
}
if($json[strlen($json) - 1]==','){
$json=substr ( $json , 0, strlen($json)-1 );
}
$json .=']';
header('Content-Type: application/json');
echo $json;
exit;
}else
if($fn=='1') //Вернуть список объектов для обновления полей по переданным ID
{
$sql = 'SELECT
o.id,
0 as seq,
o.name,
sl.lat,
sl.lon,
to_char(sl.date+(select timezone from main._users where id='.$_SESSION['USER_ID'].'), \'yyyy.mm.dd HH24:MI:SS\') as date,
\'\' as declaration,
i.file_name as icon_name,
\'\' as active
from
main.objects o
LEFT JOIN main.terminals_locations sl ON sl.id=o.terminal_location_id
LEFT JOIN main.icons i on i.id=o.icon_id
where
o.del=false
and o.id in '.str_replace("]", ")", str_replace("[", "(", $HTTP_RAW_POST_DATA)).'
order by o.name,o.id';
try
{
$res = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res = null;
}
//Массив объектов
$json ='[';
//Перебираю и последовательно отправляю не отправленные пломбы
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$json .="\n";
$json .='{';
$json .='"id":"'.$row['id']."\",\n";
$json .='"lat":"'.$row['lat']."\",\n";
$json .='"lon":"'.$row['lon']."\",\n";
$json .='"date":"'.$row['date']."\",\n";
//Выбираю показания всех датчиков (которые видны)
$json .='"sensors":[';
$sql="
select
obs.id,
round(obr.value::numeric,2) as value,
to_char(obr.date+(select timezone from main._users where id=".$_SESSION['USER_ID']."), 'yyyy.mm.dd HH24:MI:SS') as date
from
main.objects_sensors obs
left join main.sensors_values obr on obr.id=obs.sensor_value_id
left join main.terminals_sensors trs on trs.id=obs.terminal_sensor_id
where
obs.del=false
and obs.object_id=".$row['id']."
order by obs.name";
try
{
$res2 = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res2 = null;
}
if ($res2->rowCount() > 0) {
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
{
$json .='{';
$json .='"id":"'.$row2['id']."\",\n";
$json .='"value":"'.$row2['value']."\",\n";
$json .='"date":"'.$row2['date']."\"\n";
$json .='},';
}
$json=substr($json, 0, -1);
}
$json .=']';
$json .='},';
}
if($json[strlen($json) - 1]==','){
$json=substr ( $json , 0, strlen($json)-1 );
}
$json .=']';
header('Content-Type: application/json');
echo $json;
exit;
}

View File

@ -0,0 +1,80 @@
<?php
//Скрипт по обновлению геометрии а именно точек
require_once("../../monitoring/config.php");
function sendError($msg)
{
$json='{"errorCode":1,"errorMessage":'.json_encode($msg,JSON_UNESCAPED_UNICODE).'}';
header('Content-Type: application/json');
echo $json;
exit;
}
$db = connectToDB();
//$db->exec('SET NAMES utf8');
//$db->exec("SET time_zone = '+00:00'");
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
if($fn=='1') //Перезаписать все координаты для геометрии
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object->name=="TCheckPoint")
{
$sql="update main.routes_checkpoints set geom=ST_GeomFromText('POLYGON((".$object->points."))', 4326) where id=".$object->id;
try
{
$db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
}else if($object->name=="TDetour")
{
$sql="update main.detours set geom=ST_GeomFromText('POLYGON((".$object->points."))', 4326) where id=".$object->id;
try
{
$db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
}else if($object->name=="TRoute")
{
$sql="update main.routes set geom=ST_GeomFromText('LINESTRING(".$object->points.")', 4326) where id=".$object->id;
try
{
$db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
}else if($object->name=="TGeofence")
{
$sql="update main.geofences set geom=ST_GeomFromText('POLYGON((".$object->points."))', 4326) where id=".$object->id;
try
{
$db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
}
/*json+='"id":'+feature.userFeature.userData.id+',\n';
json+='"name":"'+feature.userFeature.userData.constructor.name+'",\n';
json+='"points":"';*/
$json='{"errorCode":0}';
header('Content-Type: application/json');
echo $json;
exit;
}

View File

@ -0,0 +1,230 @@
<?php
//Выбираю маршруты в GeoJSON и отправляю клиенту
require_once("../../monitoring/config.php");
$db = connectToDB();
//$db->exec('SET NAMES utf8');
//$db->exec("SET time_zone = '+00:00'");
function sendError($msg)
{
$json='{"errorCode":1,"errorMessage":'.json_encode($msg,JSON_UNESCAPED_UNICODE).'}';
header('Content-Type: application/json');
echo $json;
exit;
}
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
if($fn=='0') //Вернуть список маршрутов
{
$sql = '
SELECT
id
,name
,coalesce((select c.name from main.companies c join main.routes_companies rc on c.id=rc.company_id where rc.del=false and c.del=false and rc.route_id=r.id and c.company_type_id=2 limit 1),\'\') as station
,coalesce((select c.name from main.companies c join main.routes_companies rc on c.id=rc.company_id where rc.del=false and c.del=false and rc.route_id=r.id and c.company_type_id=1 limit 1),\'\') as carriers
,ST_NPoints(geom) as count
,round(ST_Length_Spheroid(geom,\'SPHEROID["WGS 84",6378137,298.257223563]\')/1000) as length
,ST_y(ST_StartPoint(geom)) lat
,ST_X(ST_StartPoint(geom)) lon
FROM
main.routes r
where del=false
ORDER BY name;
';
try
{
$res = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res = null;
}
//Массив объектов
$json ='[';
//Перебираю и последовательно отправляю не отправленные пломбы
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$json .="\n";
$json .='{';
$json .='"id":"'.$row['id']."\",\n";
$json .='"name":'.json_encode($row['name'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"station":'.json_encode($row['station'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"carriers":'.json_encode($row['carriers'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"count":"'.$row['count']."\",\n";
$json .='"length":"'.$row['length']."\",\n";
$json .='"lat":'.json_encode($row['lat']).",\n";
$json .='"lon":'.json_encode($row['lon']).",\n";
//Расписание для маршрута
$sql='select
ts.id,
CASE WHEN ts.direction=true THEN \'Прямое\' WHEN ts.direction=false THEN \'Обратное\' ELSE \'Не задано\' END as direction,
ts.time,
coalesce(c.name,\'\') as carrier
from
main.trips_schedules ts
left join main.companies c on c.id=ts.company_id
where
ts.route_id='.$row['id'].'
order by
ts.direction desc,ts.time';
try
{
$res2 = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res2 = null;
}
$json .='"schedules":['."\n";
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
{
$json .="{";
$json .='"direction":'.json_encode($row2['direction'],JSON_UNESCAPED_UNICODE).',';
$json .='"time":'.json_encode($row2['time'],JSON_UNESCAPED_UNICODE).',';
$json .='"carrier":'.json_encode($row2['carrier'],JSON_UNESCAPED_UNICODE);
$json .="},";
}
if($json[strlen($json) - 1]==','){
$json=substr ( $json , 0, strlen($json)-1 );
}
$json .="],\n";
//Контрольные точки для маршрута
$sql='select
rc.id,
CASE WHEN rc.direction=true THEN \'Прямое\' WHEN rc.direction=false THEN \'Обратное\' ELSE \'Не задано\' END as direction,
rc.time,
coalesce(rc.name,\'\') as name,
ST_X(ST_Centroid(rc.geom)) lon,
ST_Y(ST_Centroid(rc.geom)) lat
from
main.routes_checkpoints rc
where
rc.route_id='.$row['id'].'
order by
rc.direction desc,rc.time';
try
{
$res2 = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res2 = null;
}
$json .='"checkpoints":['."\n";
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
{
$json .="{";
$json .='"id":'.json_encode($row2['id'],JSON_UNESCAPED_UNICODE).',';
$json .='"direction":'.json_encode($row2['direction'],JSON_UNESCAPED_UNICODE).',';
$json .='"time":'.json_encode($row2['time'],JSON_UNESCAPED_UNICODE).',';
$json .='"name":'.json_encode($row2['name'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"lat":'.json_encode($row2['lat']).",\n";
$json .='"lon":'.json_encode($row2['lon'])."\n";
$json .="},";
}
if($json[strlen($json) - 1]==','){
$json=substr ( $json , 0, strlen($json)-1 );
}
$json .="]\n";
$json .='},';
}
if($json[strlen($json) - 1]==','){
$json=substr ( $json , 0, strlen($json)-1 );
}
$json .=']';
header('Content-Type: application/json');
echo $json;
}else
if($fn=='1') //Вернуть GEOJSON по ID записи
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object->id=='') $object->id='null';
/*if($object->cnumber=='') $object->cnumber='null'; else $object->cnumber='"%'.$object->cnumber.'%"'; //Гос. номер
if($object->tnumber=='') $object->tnumber='null'; else $object->tnumber='"%'.$object->tnumber.'%"'; //Номер ТД
if($object->country_seal_begin=='') $object->country_seal_begin='null'; //Страна пломб.
if($object->country_seal_end=='') $object->country_seal_end='null'; //Страна распломб.*/
//Выбираю геометрию
$sql="select ST_AsGeoJSON(geom,6,0) as geom from main.routes where id=".$object->id.";";
try
{
$res = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res = null;
}
$json="{}";
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$json=$row[0];
}
}
header('Content-Type: application/json');
echo $json;
exit;
}else if($fn=='2') //Вернуть GEOJSON по ID записи
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if(!property_exists($object,'id') or $object->id=='') $object->id='null';
//Выбираю геометрию
$sql="select ST_AsGeoJSON(geom,6,0) as geom from main.routes_checkpoints where id=".$object->id.";";
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
$json="{}";
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$json=$row[0];
}
}
header('Content-Type: application/json');
echo $json;
exit;
}else if($fn=='3') //Удалить маршрут
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object->id=='') $object->id='null';
$sql="update main.routes r set del=true where id=".$object->id;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
$json="{}";
header('Content-Type: application/json');
echo $json;
exit;
}else
{
sendError("Неизвестная функция!");
}

View File

@ -0,0 +1,46 @@
<?php
//Выбираю точки запрошенного маршрута и отправляю в виде JSON клиенту
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object->date_start=='') $object->date_start='null';
if($object->date_end=='') $object->date_end='null';
require_once("../../monitoring/config.php");
$db = connectToDB();
$db->exec('SET TIME ZONE 0;');
$sql = 'select id,lon,lat,round(extract(epoch from date at time zone \'utc\')) udate,speed,velocity from main.terminals_locations where del=false and object_id='.$object->object_id.' and ('.$object->date_start.' is null or date > to_timestamp('.$object->date_start.')::timestamp) and ('.$object->date_end.' is null or date < to_timestamp('.$object->date_end.')::timestamp) order by date;';
try
{
$res = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res = null;
}
//Массив объектов
$json ='[';
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$json .="\n";
$json .='{';
$json .='"lat":"'.$row['lat']."\",\n";
$json .='"lon":"'.$row['lon']."\",\n";
$json .='"udate":"'.$row['udate']."\",\n";
$json .='"speed":"'.round ($row['speed'], 1)."\",\n";
$json .='"velocity":"'.round ($row['velocity'], 1)."\"\n";
$json .='},';
}
if($json!='[')
$json = substr($json,0,strlen($json)-1);
$json .=']';
header('Content-Type: application/json');
echo $json;

View File

@ -0,0 +1,499 @@
<?php
//Этот скрипт обслуживает рейсы назначение, список, и.т.д.
@session_start();
function sendError($msg)
{
$json='{"errorCode":1,"errorMessage":'.json_encode($msg,JSON_UNESCAPED_UNICODE).'}';
header('Content-Type: application/json');
echo $json;
exit;
}
require_once("../../monitoring/config.php");
require_once("../../resources/metadata/include/tools.php");
$db = connectToDB();
//$db->exec('SET NAMES utf8');
//$db->exec("SET time_zone = '+00:00'");
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
if($fn=='0') //Вернуть список объектов в соответствии с фильтром
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
try
{
$object = json_decode($HTTP_RAW_POST_DATA);
}catch (Exception $e)
{
$json='{"errorMessage":"'.$e->getMessage().'"}';
header('Content-Type: application/json');
echo $json;
exit;
}
if(!property_exists($object,'carrier_id') or $object->carrier_id=='') $object->carrier_id='null';
if(!property_exists($object,'company_id') or $object->company_id=='') $object->company_id='null';
if(!property_exists($object,'status') or $object->status=='') $object->status='null';
if(!property_exists($object,'route_id') or $object->route_id=='') $object->route_id='null';
$sql = 'SELECT
t.id,
tt.name as trip_type_name,
r.name,
c.name as company_name,
cr.name as carrier_name,
o.name as object_name,
o.places as object_places,
t.direction,
t.date_start,
t.date_start+(select max("time") from main.routes_checkpoints where del=false and route_id=t.route_id) as date_end,
t.passenger,
t.description,
COALESCE((select count(*) from main.trips_checkpoints where del=false and "time" is not null and trip_id=t.id),0) as real_checkpoints,
COALESCE((select count(1) from main.routes r0 join main.routes_checkpoints rc0 on r0.id=rc0.route_id where r0.del=false and rc0.del=false and r0.id=t.route_id and rc0.direction=t.direction group by r0.id,rc0.direction),0) as plan_checkpoints
from
main.trips t
join main.routes r on r.id=t.route_id
left join main.companies c on c.id=t.company_id
left join main.companies cr on cr.id=t.company_carrier_id
left join main.objects o on o.id=t.object_id
left join main.trips_types tt on tt.id=t.trip_type_id
where
t.del=false
and ('.$object->route_id.' is null or '.$object->route_id.'=t.route_id)
and ('.$object->carrier_id.' is null or '.$object->carrier_id.'=t.company_carrier_id)
and ('.$object->company_id.' is null or '.$object->company_id.'=t.company_id)
order by t.date_start,r.name';
//select r.id,rc.direction,count(1) from main.routes r join main.routes_checkpoints rc on r.id=rc.route_id where r.del=false and rc.del=false group by r.id,rc.direction;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
header('Content-Type: application/json');
echo "{\"error\":\"".$e->getMessage()."\"}";
exit;
}
//Массив объектов
$json ='[';
//Перебираю и последовательно отправляю не отправленные пломбы
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$json .="\n";
$json .='{';
$json .='"id":"'.$row['id']."\",\n";
$json .='"trip_type_name":'.json_encode($row['trip_type_name'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"name":'.json_encode($row['name'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"company_name":'.json_encode($row['company_name'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"carrier_name":'.json_encode($row['carrier_name'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"object_name":'.json_encode($row['object_name'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"object_places":'.json_encode($row['object_places'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"direction":'.json_encode($row['direction'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"date_start":'.json_encode($row['date_start'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"date_end":'.json_encode($row['date_end'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"passenger":'.json_encode($row['passenger'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"description":'.json_encode($row['description'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"real_checkpoints":'.json_encode($row['real_checkpoints'],JSON_UNESCAPED_UNICODE).",\n";
$json .='"plan_checkpoints":'.json_encode($row['plan_checkpoints'],JSON_UNESCAPED_UNICODE)."\n";
$json .='},';
}
if($json[strlen($json) - 1]==','){
$json=substr ( $json , 0, strlen($json)-1 );
}
$json .=']';
header('Content-Type: application/json');
echo $json;
exit;
}else if($fn=='1') //Удалить запись
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object==null) $object = (object)[];
if(!property_exists($object,'id') or $object->id=='') $object->id=null; //Поле заполнено если редактирвание записи
if($object->id!=null)
{
try
{
$sql="update main.trips set del=true where id=".$object->id;
$db->query($sql);
}catch (Exception $e)
{
sendError($e->getMessage());
}
$json='{}';
header('Content-Type: application/json');
echo $json;
exit;
}else
{
$json='{"errorMessage":"ID is not set!"}';
header('Content-Type: application/json');
echo $json;
exit;
}
}else if($fn=='2') //HTML формочка для создания/редактирования новой записи (чтобы не заморачиваться с заполнением выпадающих полей записей через javascript)
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object==null) $object = (object)[];
if(!property_exists($object,'id') or $object->id=='') $object->id=null; //Поле заполнено если редактирвание записи
if($object->id!=null)
{
$sql = 'SELECT * from main.trips t
where
t.id='.$object->id;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
header('Content-Type: application/json');
echo "{\"error\":\"".$e->getMessage()."\"}";
exit;
}
//Переписываю значения в объект
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$object->route_id=$row['route_id'];
$object->company_id=$row['company_id'];
$object->carrier_id=$row['company_carrier_id']; //Как общий так и конкретный для данного маршрута
$object->trip_type_id=$row['trip_type_id'];
$object->object_id=$row['object_id'];
$object->direction=$row['direction'];
//$object->date_start=$row['date_start'];
$object->date=$row['date_start'];
//$object->date_end=$row['date_end'];
$object->passenger=$row['passenger'];
$object->file_name=$row['file_name'];
$object->description=$row['description'];
}
}
if(!property_exists($object,'trip_type_id') or $object->trip_type_id=='') $object->trip_type_id=null;
if(!property_exists($object,'direction') or $object->direction==='') $object->direction=null; //Направление
if(!property_exists($object,'object_id')) $object->object_id=''; //Автобус
if(!property_exists($object,'date')) $object->date=''; //Дата время начала маршрута план
if(!property_exists($object,'passenger')) $object->passenger=''; //Пассажиров
if(!property_exists($object,'route_id')) $object->route_id='';
if(!property_exists($object,'carrier_id')) $object->carrier_id='';
if(!property_exists($object,'file_name')) $object->file_name=''; //Сопроводительные документы
if(!property_exists($object,'description')) $object->description=''; //Описание
$html='<input style="display:none;" id="e_trip_id" value="'.$object->id.'" type="text">';
$html.='
<table class="SEdit">
<caption></caption>
<thead>
<tr>
<th style="width:40%">'.trt('Name').'</th>
<th style="width:60%">'.trt('Value').'</th>
</tr>
</thead>
<tbody>
<tr style="background-color:#EEEEEE"><td style="font-weight: bold;">'.trt('Trip_type').'</td><td><select style="width: 100%;" id="e_trip_type_id"><option value=""></option>';
if($object->trip_type_id===1)
{
$html.='<option value="1" selected="true">'.trt('Primary').'</option>';
$html.='<option value="2">'.trt('Optional').'</option>';
}else if($object->trip_type_id===2)
{
$html.='<option value="1">'.trt('Primary').'</option>';
$html.='<option value="2" selected="true">'.trt('Optional').'</option>';
}else
{
$html.='<option value="1">'.trt('Primary').'</option>';
$html.='<option value="2">'.trt('Optional').'</option>';
}
$html.=' </select></td></tr>
<tr style="background-color:#FFFFFF"><td style="font-weight: bold;">'.trt('Route').'</td><td><select style="width: 100%;" id="e_trip_route_id"><option value=""></option>
';
//Выбираю маршруты только для текущего автовакзала
$sql="select id,name from main.routes where del=false and id in (select route_id from main.routes_companies where del=false and company_id=(select company_id from main._users where id=".$_SESSION['USER_ID'].")) order by name;";
$res = $db->query($sql);
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
if($row['id']==$object->route_id)
{
$html.='<option value="'.$row['id'].'" selected>'.$row['name'].'</option>';
}else
{
$html.='<option value="'.$row['id'].'">'.$row['name'].'</option>';
}
}
$html.='</select></td></tr>
<tr style="background-color:#EEEEEE"><td style="font-weight: bold;">'.trt('Direction').'</td><td><select style="width: 100%;" name="trip_direction" id="e_trip_direction"><option value=""></option>
';
if($object->direction===1 or $object->direction===true)
{
$html.='<option value="1" selected>Прямой</option><option value="0">Обратный</option>';
}else if($object->direction===0 or $object->direction===false)
{
$html.='<option value="1">Прямой</option><option value="0" selected>Обратный</option>';
}else
{
$html.='<option value="1">Прямой</option><option value="0">Обратный</option>';
}
$html.='</select></td></tr>
<tr style="background-color:#FFFFFF"><td style="font-weight: bold;">'.trt('Carrier').'</td><td><select style="width: 100%;" name="trip_carrier_id" id="e_trip_carrier_id"><option value=""></option>
';
//Выбираю перевозчика для заданого маршрута (и для заданого автовакзала)
$sql='
select c.* from
main.companies c
join (
select company_id from main.trips_schedules where del=false and route_id in (select route_id from main.routes_companies where del=false and company_id=(select company_id from main._users where del=false and id='.$_SESSION['USER_ID'].'))
union
select company_id from main.routes_companies where del=false and route_id in (select route_id from main.routes_companies where del=false and company_id=(select company_id from main._users where del=false and id='.$_SESSION['USER_ID'].'))
)t on c.id=t.company_id
where company_id!=(select company_id from main._users where del=false and id='.$_SESSION['USER_ID'].')
order by c.name
';
$res = $db->query($sql);
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
if($row['id']==$object->carrier_id)
{
$html.='<option value="'.$row['id'].'" selected>'.$row['name'].'</option>';
}else
{
$html.='<option value="'.$row['id'].'">'.$row['name'].'</option>';
}
}
$html.='
</select></td></tr>
<tr style="background-color:#EEEEEE"><td>'.trt('Bus').'</td><td><select style="width: 100%;" name="object_id" id="e_trip_object_id"><option value=""></option>
';
//Выбираю перевозчика для заданого маршрута
$res = $db->query("select id,name from main.objects where del=false order by name;");
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
if($row['id']==$object->object_id)
{
$html.='<option value="'.$row['id'].'" selected>'.$row['name'].'</option>';
}else
{
$html.='<option value="'.$row['id'].'">'.$row['name'].'</option>';
}
}
$html.='
</select></td></tr>
<tr style="background-color:#FFFFFF"><td style="font-weight: bold;">Дата время начала маршрута план</td><td><table><tbody><tr><td style="padding: 0px; width: 100%;"><input style="width: 100%;" name="trip_date_start" id="e_trip_date_start" value="'.$object->date.'" type="text"></td><td style="padding: 0px;"><img id="e_trip_date_start_s" src="../resources/monitoring/images/datepicker.jpg" style="cursor: pointer; padding-left:1px;"></td></tr></tbody></table></td></tr>
<tr style="background-color:#FFFFFF"><td>'.trt('Passengers').'</td><td><input style="width: 100%; height: 22px;" name="trip_passenger" id="e_trip_passenger" value="'.$object->passenger.'" type="text"></td></tr>
<tr style="background-color:#FFFFFF"><td>Сопроводительные документы</td><td><table><tbody><tr><td style="padding: 0px; width: 100%;"><input style="width: 100%;opacity:0.5;" name="trip_file_name" id="e_trip_file_name" value="'.$object->file_name.'" type="text" readonly></td><td style="padding: 0px 0px 0px 1px;"><input class="button-secondary" id="e_trip_btn_select_file" type="button" value="'.trt('Choose').'"></td><td style="padding: 0px 0px 0px 1px;"><input class="button-secondary" id="e_trip_btn_download_file" type="button" value="'.trt('Download').'"></td><td style="padding: 0px 0px 0px 1px;"><input class="button-secondary" id="e_trip_btn_delete_file" type="button" value="'.trt('Delete').'"></td></tr></tbody></table></td></tr>
<tr style="background-color:#EEEEEE"><td>'.trt('Description').'</td><td><textarea id="e_trip_description" style="width: 100%;" rows="4" name="trip_description">'.$object->description.'</textarea></td></tr>
<tr><td style="padding: 5px; vertical-align: bottom; background-color: rgb(245, 245, 245);" colspan="2" align="right"><input class="button-secondary" style="width: 90px;" value="Применить" type="button" onclick="g_trips.saveTrip();"><input class="button-secondary" style="width: 90px;" value="Отмена" type="button" onclick="alert(\'test\');"></td></tr>
</tbody>
</table>
';
header('Content-Type: text/plain');
echo $html;
exit;
}else if($fn=='3') //Создать/изменить запись в базе
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
try
{
$object = json_decode($HTTP_RAW_POST_DATA);
}catch (Exception $e)
{
$json='{"errorMessage":"'.$e->getMessage().'"}';
header('Content-Type: application/json');
echo $json;
exit;
}
//if($object==null) $object = (object)[];
if(!property_exists($object,'id') or $object->id=='') $object->id=null;
if(!property_exists($object,'trip_type_id') or $object->trip_type_id=='') $object->trip_type_id=null;
if(!property_exists($object,'route_id') or $object->route_id=='') $object->route_id=null;
if(!property_exists($object,'direction') or $object->direction==='') $object->direction=null;
if(!property_exists($object,'carrier_id') or $object->carrier_id==='') $object->carrier_id=null;
if(!property_exists($object,'date_start') or $object->date_start==='') $object->date_start=null;
if(!property_exists($object,'passenger') or $object->passenger==='') $object->passenger=null;
if(!property_exists($object,'date')) $object->date='';
if(!property_exists($object,'route_id')) $object->route_id='';
if(!property_exists($object,'file_name')) $object->file_name='';
if(!property_exists($object,'description')) $object->description='';
if($object->id==null) //Новая запись
{
$sql='insert into main.trips(trip_type_id,route_id,direction,company_carrier_id,object_id,date_start,passenger,file_name,description)values(:trip_type_id,:route_id,:direction,:company_carrier_id,:object_id,:date_start,:passenger,:file_name,:description) RETURNING id;';
$stmt = $db->prepare($sql);
if($stmt === false) sendError('Error preparing Statement');
$stmt->bindParam(':trip_type_id', $object->trip_type_id, PDO::PARAM_STR);
$stmt->bindParam(':route_id', $object->route_id, PDO::PARAM_INT);
$stmt->bindParam(':direction', $object->direction, PDO::PARAM_BOOL);
$stmt->bindParam(':company_carrier_id', $object->carrier_id, PDO::PARAM_INT); //перевозчик
$stmt->bindParam(':object_id', $object->object_id, PDO::PARAM_INT); //Автобус перевозчика
$stmt->bindParam(':date_start', $object->date_start, PDO::PARAM_STR);
$stmt->bindParam(':passenger', $object->passenger, PDO::PARAM_INT); //Пассажиров
$stmt->bindParam(':file_name', $object->file_name, PDO::PARAM_STR);
$stmt->bindParam(':description', $object->description, PDO::PARAM_STR);
try
{
$res = $stmt->execute();
} catch (Exception $e)
{
$json='{"errorCode":1,"errorMessage":'.json_encode($e->getMessage(),JSON_UNESCAPED_UNICODE).'}';
header('Content-Type: application/json');
echo $json;
exit;
}
$id='';
if($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$id=$row['id'];
}
$stmt=null;
//Если запись добавлена информируем автобусный парк, чтобы он назначил автобус на заданый рейс
if($id!='')
{
$route_name='';
$sql="select id,name from main.routes where id=".$object->route_id;
$res = $db->query($sql);
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$route_name=$row['name'];
}
$sql='insert into main.messages(subject,"text",company_carrier_id,action_name,action_settings)values(:subject,:text,:company_carrier_id,:action_name,:action_settings);';
$stmt = $db->prepare($sql);
if($stmt === false) sendError('Error preparing Statement');
//Так как bindParam принимает ссылки на переменные то создаём эти переменные
$subject='Warning';
$text='Вам был назначен рейс "'.$route_name.'" начало рейса в "'.$object->date_start.'", пожалуйста назначте автобус на это рейс!';
$action_name='Edit_trip';
$action_settings='{"trip_id":'.$id.'}';
$stmt->bindParam(':subject', $subject, PDO::PARAM_STR);
$stmt->bindParam(':text', $text, PDO::PARAM_STR);
$stmt->bindParam(':company_carrier_id', $object->carrier_id, PDO::PARAM_INT);
$stmt->bindParam(':action_name', $action_name, PDO::PARAM_STR);
$stmt->bindParam(':action_settings', $action_settings, PDO::PARAM_STR);
try
{
$res = $stmt->execute();
} catch (Exception $e)
{
$json='{"errorCode":1,"errorMessage":'.json_encode($e->getMessage(),JSON_UNESCAPED_UNICODE).'}';
header('Content-Type: application/json');
echo $json;
exit;
}
}
}else //Обновляем старую запись
{
$sql='update main.trips set trip_type_id=:trip_type_id,route_id=:route_id,direction=:direction,company_carrier_id=:company_carrier_id,object_id=:object_id,date_start=:date_start,passenger=:passenger,file_name=:file_name,description=:description where id=:id';
$stmt = $db->prepare($sql);
if($stmt === false) sendError('Error preparing Statement');
$stmt->bindParam(':trip_type_id', $object->trip_type_id, PDO::PARAM_STR);
$stmt->bindParam(':route_id', $object->route_id, PDO::PARAM_INT);
$stmt->bindParam(':direction', $object->direction, PDO::PARAM_BOOL);
$stmt->bindParam(':company_carrier_id', $object->carrier_id, PDO::PARAM_INT); //перевозчик
$stmt->bindParam(':object_id', $object->object_id, PDO::PARAM_INT); //Автобус перевозчика
$stmt->bindParam(':date_start', $object->date_start, PDO::PARAM_STR);
$stmt->bindParam(':passenger', $object->passenger, PDO::PARAM_INT); //Пассажиров
$stmt->bindParam(':file_name', $object->file_name, PDO::PARAM_STR);
$stmt->bindParam(':description', $object->description, PDO::PARAM_STR);
$stmt->bindParam(':id', $object->id, PDO::PARAM_INT);
try
{
$res = $stmt->execute();
} catch (Exception $e)
{
$json='{"errorCode":1,"errorMessage":'.json_encode($e->getMessage(),JSON_UNESCAPED_UNICODE).'}';
header('Content-Type: application/json');
echo $json;
exit;
}
}
$json='{}';
header('Content-Type: application/json');
echo $json;
exit;
}else if($fn=='4') //Загрузить файл на сервер
{
session_write_close(); //Разблокируем сессионный файл так как запросы могут быть достаточно долгими
$dir = $_SERVER['DOCUMENT_ROOT']."/temp/";
//Так как у файлов могут быть одинаковые имена считаем CRC и переименовываем файл отправля пользователю новое название файла
//В базе данных название файла будет преобразовываться так: "файл.txt" -> "файл_crc32.txt"
if(isset($_FILES['file']))
{
if(file_exists($_FILES['file']['tmp_name']))
{
$hash = hash_file( 'crc32', $_FILES['file']['tmp_name'] );
$new_name=delPHPExt($dir.$hash.'.'.getExtension($_FILES['file']['name']));
if(move_uploaded_file($_FILES['file']['tmp_name'],$new_name))
{
//Отправляем новое название файла клиенту
print "ok=".beforeLast($_FILES['file']['name'],'.').'_'.$hash.'.'.getExtension($_FILES['file']['name'])."\n";
}
}else { print "ok=\n File \"".file_exists($_FILES['file']['tmp_name'])."\" not find"; }
}
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">';
print '<html>';
print ' <head>';
print ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
print ' </head>';
print ' <body>';
print ' <form name="form" enctype="multipart/form-data" action="/monitoring/pscripts/trips.php?fn=4" method="post">';
print ' <input type="hidden" name="state" value=""/>';
print ' <input type="file" name="file"><br/>';
print ' <input type="submit" value="Send File">';
print ' <input type="reset" value="Reset">';
print ' </form>';
print ' </body>';
print '</html>';
}else if($fn=='5') //Скачать файл с сервера
{
$dir = $_SERVER['DOCUMENT_ROOT']."/temp/";
$fname='';
if(isset($_GET['fname'])) { $fname=$_GET['fname']; }
$name=beforeLast($fname,'_').'.'.afterLast($fname,'.');
$fname=$dir.afterLast($fname,'_');
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="'.$name.'"');
header('Content-Length: '.filesize($fname));
readfile($fname);
exit;
}

View File

@ -0,0 +1,180 @@
<?php
@session_start();
require_once("../../monitoring/config.php");
require_once("../../monitoring/tools.php");
require_once("../../resources/metadata/include/tools.php");
function sendError($msg)
{
$json='{"errorCode":1,"errorMessage":'.json_encode($msg,JSON_UNESCAPED_UNICODE).'}';
header('Content-Type: application/json');
echo $json;
exit;
}
$db = connectToDB();
$MainFrom = 'irigm@yandex.ru';
//$MainFrom = 'info@motion-engine.com';
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
if($fn=='1') //Зарегестрировать нового пользователя и компанию
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object==null) sendError(trt("Invalid_request")."!");
$captcha=$_SESSION['secpic1'];
if($captcha!=$object->captcha) {
sendError('The numbers from the picture do not match!');
}else{
$password = getPassword(5);
$sql = "select * from main.p__users_1(1,null,:company_name,:surname,:name,:position,:phone,:email,:password);";
$stmt = $db->prepare($sql);
$stmt->bindParam(':company_name', $object->company, PDO::PARAM_STR);
$stmt->bindParam(':surname', $object->lastname, PDO::PARAM_STR);
$stmt->bindParam(':name', $object->firstname, PDO::PARAM_STR);
$stmt->bindParam(':position', $object->position, PDO::PARAM_STR);
$stmt->bindParam(':phone', $object->phone, PDO::PARAM_STR);
$stmt->bindParam(':email', $object->email, PDO::PARAM_STR);
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
$response = new stdClass();
$response->errorCode = '0';
$response->errorMessage = '';
try
{
$res = $stmt->execute();
} catch (Exception $e)
{
sendError($e->getMessage());
}
$html='<html><head><title>Message</title></head><body>';
$html.='<h1>Поздравляю, Вы зарегистрированы!</h1>';
$html.='<b>Ваш пароль:</b> '.$password.'<br>';
$html.='</body></html>';
//Отсылаю пароль на почту
if(mail($object->email,'Motion-Engine.com',$html,"Content-type: text/html; charset=utf-8\r\nFrom: Motion-Engine Site <".$MainFrom.">"))
{
}else{
sendError('Failed to send password email to!');
}
echo json_encode($response);
exit;
}
}else if($fn=='2') //Восстановление пароля
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object==null) sendError(trt("Invalid_request")."!");
$captcha=$_SESSION['secpic2'];
if($captcha!=$object->captcha) {
sendError('The numbers from the picture do not match!');
}else{
$password = getPassword(5);
$sql = "update main._users set password='".md5($password)."' where email=lower('".$object->email."');";
$response = new stdClass();
$response->errorCode = '0';
$response->errorMessage = '';
try
{
$db->query($sql);
}catch (Exception $ex)
{
sendError($ex->getMessage());
}
$html='<html><head><title>Message</title></head><body>';
$html.='<h1>Password recovery</h1>';
$html.='<b>Your password has been changed to:</b> '.$password.'<br>';
$html.='</body></html>';
//Отсылаю пароль на почту
if(mail($object->email,'Motion-Engine.com',$html,"Content-type: text/html; charset=utf-8\r\nFrom: Motion-Engine Site <".$MainFrom.">"))
{
}else{
sendError('Failed to send password email to!');
}
echo json_encode($response);
exit;
}
}else if($fn=='3'){ //Смена пароля
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object==null) sendError(trt("Invalid_request")."!");
//Проверяю есть ли такой пользователь
$sql = "select id from main._users where del=false and password='".md5($object->password)."' and email=lower('".$object->email."');";
try
{
$res = $db->query($sql);
}catch (Exception $ex)
{
sendError($ex->getMessage());
}
if($res==NULL || $res->rowCount()==0)
{
sendError(trt("Invalid_username_and_or_password"));
}
$sql = "update main._users set password='".md5($object->new_password)."' where email=lower('".$object->email."') and password='".md5($object->password)."';";
$response = new stdClass();
$response->errorCode = '0';
$response->errorMessage = '';
try
{
$db->query($sql);
}catch (Exception $ex)
{
sendError($ex->getMessage());
}
echo json_encode($response);
exit;
}else if($fn=='10'){ //Вернуть список для заполнения компаний к которым у пользователя есть доступ
$sql="select id,name,exists(select 1 from main._users where del=false and c.id=company_id and id=".$_SESSION['USER_ID'].") as select from main.companies c where id in (select company_id from main.companies_users where del=false and user_id=".$_SESSION['USER_ID'].") order by name";
try
{
$res = $db->query($sql);
}catch (Exception $ex)
{
sendError($ex->getMessage());
}
if($res != null)
{
while ($row = $res->fetch(PDO::FETCH_ASSOC))// $row - ассоциативный массив значений, ключи - названия столбцов
{
if($row['select'])
echo '<option selected="selected" value="'.$row['id'].'">'.$row['name'].'</option>';
else
echo '<option value="'.$row['id'].'">'.$row['name'].'</option>';
}
}
}else{
sendError("Fn is null!");
}

22
monitoring/records.php Normal file
View File

@ -0,0 +1,22 @@
<?php
//Разрешаем CrossDomain запросы
header('Access-Control-Allow-Origin: *');
header('XDomainRequestAllowed: 1');
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
header('Access-Control-Allow-Credentials: true');
header("Access-Control-Allow-Headers: X-PINGARUNER");
header('Access-Control-Max-Age: 3628800');
//Чтоб не кешировало
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');
require_once("../resources/metadata/include/xmltools.php");
require_once("../resources/metadata/include/tools.php");
//require_once("../metadata/include/MPDF54/mpdf.php");
require_once("config.php");
require_once("../resources/metadata/include/session.php");
require_once("../resources/metadata/dbms/records.php");

View File

@ -0,0 +1 @@
<?php

91
monitoring/routes.php Normal file
View File

@ -0,0 +1,91 @@
<?php
//Выбираю маршруты в GeoJSON и отправляю клиенту
require_once("./config.php");
$db=connectToDB();
//$db->exec('SET NAMES utf8');
//$db->exec("SET time_zone = '+00:00'");
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
if($fn=='0') //Вернуть список маршрутов
{
$sql = '
SELECT
id
,name
,ST_NPoints(geom) as count
FROM
main.routes
ORDER BY name;
';
try
{
$res = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res = null;
}
//Массив объектов
$json ='[';
//Перебираю и последовательно отправляю не отправленные пломбы
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$json .="\n";
$json .='{';
$json .='"id":"'.$row['id']."\",\n";
$json .='"name":"'.$row['name']."\",\n";
$json .='"count":"'.$row['count']."\"\n";
$json .='},';
}
if($json[strlen($json) - 1]==','){
$json=substr ( $json , 0, strlen($json)-1 );
}
$json .=']';
header('Content-Type: application/json');
echo $json;
}else
if($fn=='1') //Вернуть GEOJSON по ID записи
{
if(!isset($HTTP_RAW_POST_DATA))
{ $HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
$object = json_decode($HTTP_RAW_POST_DATA);
if($object->id=='') $object->id='null';
/*if($object->cnumber=='') $object->cnumber='null'; else $object->cnumber='"%'.$object->cnumber.'%"'; //Гос. номер
if($object->tnumber=='') $object->tnumber='null'; else $object->tnumber='"%'.$object->tnumber.'%"'; //Номер ТД
if($object->country_seal_begin=='') $object->country_seal_begin='null'; //Страна пломб.
if($object->country_seal_end=='') $object->country_seal_end='null'; //Страна распломб.*/
//Выбираю геометрию
$sql="select ST_AsGeoJSON(geom,3,0) as geom from main.routes where id=".$object->id.";";
try
{
$res = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res = null;
}
$json="{}";
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$json=$row[0];
}
}
header('Content-Type: application/json');
echo $json;
exit;
}else
{
echo 'fn is null';
}

11
monitoring/session.php Normal file
View File

@ -0,0 +1,11 @@
<?php
session_start();
if(isset($_SESSION['USER_ID']) && $_SESSION['USER_ID']!='' && $_SESSION['USER_ID']!='null')
{
echo '{"result":"OK","user_id":'.$_SESSION['USER_ID'].'}';
}else
{
echo '{"result":"ERROR","user_id":0}';
}

36
monitoring/setup.css Normal file
View File

@ -0,0 +1,36 @@
/* https://stackoverflow.com/questions/61429260/dynamically-change-css-files */
[data-theme="1"] {
--box-shadow-color: rgba(0,0,0,0.7); /*Цвет тени окна*/
--header-color: #505050; /*Цвет заголовка таблицы #505050*/
--back-color: #3a3a3a; /*Цвет тела таблицы #3a3a3a;*/
--back-color3: #454555; /* #454555 (цвет полей ввода текста) */
--main-font-color: #ffffff; /*Основной цвет текста белый либо чёрный*/
--inactive-font-color: #656565; /* Цвет неактивного текста #afafaf*/
--row-color-1: #3c3c3c;
--row-color-2: #303030;
--text-color-1: #ffffff;
--back-color-1: #3a3a3a;
--back-color-2: #000000;
--back-color-3: #454555; /* TextEdit */
--path-grad: url('/resources/metadata/dbms/form/g_b.gif');
--path-X: url('/resources/metadata/dbms/form/x_w.gif');
}
[data-theme="2"] {
--box-shadow-color: rgba(0,0,0,0.7);
--header-color: #dadada;
--back-color: #f1f1f1;
--back-color3: #ffffff;
--main-font-color: #000000;
--inactive-font-color: #656565;
--row-color-1: white;
--row-color-2: whitesmoke;
--text-color-1: #000000;
--back-color-1: #ffffff;
--back-color-2: #ffffff;
--back-color-3: #ffffff; /* TextEdit */
--path-grad: url('/resources/metadata/dbms/form/g_w.gif');
--path-X: url('/resources/metadata/dbms/form/x_b.gif');
}

12
monitoring/setup.js Normal file
View File

@ -0,0 +1,12 @@
//var ScriptName='../metadata/dbms/records.jsp';
var ScriptName='../records.php';
var ScriptDName='../records.php';
var ScriptUName='./records.php';
//var g_rowColor1='#3c3c3c'; //white
//var g_rowColor2='#303030'; //whitesmoke
//var g_backColor1= '#3a3a3a'; //#ffffff
//var g_backColor2= '#000000'; //#ffffff
//var g_backColor3= '#454555'; //TextEdit
//var g_textColor1= '#ffffff'; //#ffffff

View File

@ -0,0 +1,59 @@
<?php
//Формирую JavaScript массив для перевода интерфейса
@session_start();
require_once("./config.php");
$db=connectToDB();
//$db->exec('SET NAMES utf8');
//$db->exec("SET time_zone = '+00:00'");
header("Content-type: text/javascript");
?>
/*function trt(key)
{
var val=g_translations[key];
if(val===undefined)
{
if(key===undefined) return '';
else return key.replace(/_/g, ' ');
}else
return val;
}*/
var g_translations = {
'':''
<?php
//$sql="select id,identifier,translation from main._translations where del=false and language_id=(select id from main._languages where short_name='".$_SESSION["LNG"]."');";
$sql='select id,identifier,translation from main._translations where del=false and language_id='.$_SESSION["LNG"];
$res = NULL;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_NUM))
{
$identifier = str_replace(" ", "_", $row[1]);
$identifier = str_replace("\"", "_", $identifier);
$identifier = str_replace("'", "_", $identifier);
$identifier = str_replace("!", "_", $identifier);
$identifier = str_replace("%", "_", $identifier);
$identifier = str_replace("(", "_", $identifier);
$identifier = str_replace(")", "_", $identifier);
$identifier = str_replace("/", "_", $identifier);
$identifier = str_replace(".", "_", $identifier);
$row[2] = str_replace("'", "\'", $row[2]);
echo " ,".$identifier.": '".trim($row[2])."'\n";
}
}
?>
};

View File

@ -0,0 +1,229 @@
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Key</title>
<script>
/*if (location.protocol != 'https:')
{
location.href = 'https:' + window.location.href.substring(window.location.protocol.length);
}*/
function getXmlHttp()
{
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch (ee) {
}
}
if (typeof XMLHttpRequest!='undefined') {
return new XMLHttpRequest();
}
}
function Request()
{
let data={
sourceLanguageCode: "ru",
targetLanguageCode: "en",
texts: ["Книга"]
};
let xmlhttp = getXmlHttp();
xmlhttp.onreadystatechange = function(xmlhttp)
{
return function()
{
if (xmlhttp.readyState == 4)
{
alert(xmlhttp.responseText);
}
}
}(xmlhttp);
xmlhttp.open("POST",'https://translate.api.cloud.yandex.net/translate/v2/translate',true);
alert(JSON.stringify(data));
xmlhttp.send(JSON.stringify(data));
}
</script>
</head>
<body>
Перевожу:<br>
<?php
//Пытаюсь перевести недостающие слова с русского на английски если перевода нет (к слову приписываю признак автоматического перевода)
require_once("./config.php");
require_once("../resources/metadata/include/tools.php");
/*
//Для того чтобы отсылать в ГУГЕЛ нужно авторизоваться! Делаю это по инструкции из: https://usefulangle.com/post/9/google-login-api-with-php-curl
$clientId = "232776754177";
$clientSecret = "AIzaSyAOtc8E9Yg0O1uuZ_0EMYgqFP7W3p_0LGI";
$clientRedirectURL = "http://127.0.0.1";
$login_url = 'https://accounts.google.com/o/oauth2/v2/auth?scope=' . urlencode('https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/cloud-translation') . '&redirect_uri=' . urlencode($clientRedirectURL) . '&response_type=code&client_id=' . $clientId . '&access_type=online';
if (!isset($_GET['code'])){
header("location: $login_url");
} else {
$code = filter_var($_GET['code'], FILTER_SANITIZE_STRING);
$curlGet = '?client_id=' . $clientId . '&redirect_uri=' . $clientRedirectURL . '&client_secret=' . $clientSecret . '&code='. $code . '&grant_type=authorization_code';
$url = 'https://www.googleapis.com/oauth2/v4/token' . $curlGet;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$data = curl_exec($ch);
$data = json_decode($data, true);
curl_close($ch);
$accessToken = $data['access_token'];
$apiKey = "AIzaSyAOtc8E9Yg0O1uuZ_0EMYgqFP7W3p_0LGI";
$projectID = "232776754177";
$target = "https://translation.googleapis.com/v3/projects/$projectID:translateText?key=$apiKey";
$headers = array(
"Content-Type: application/json; charset=utf-8",
"Authorization: Bearer " . $accessToken,
"x-goog-encode-response-if-executable: base64",
"Accept-language: en-US,en;q=0.9,es;q=0.8"
);
$requestBody = array();
$requestBody['sourceLanguageCode'] = "en";
$requestBody['targetLanguageCode'] = "pt";
$requestBody['contents'] = array("So, I guess this thing works?");
$requestBody['mimeType'] = "text/plain";
$ch = curl_init($target);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestBody));
$data = curl_exec($ch);
curl_close($ch);
echo $data;
}
*/
$db=connectToDB();
$db->exec("SET NAMES 'UTF8';");
$sql="select identifier from main._translations where del=false group by identifier";
$res = NULL;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res!=NULL && $res->rowCount()>0) {
while ($row = $res->fetch(PDO::FETCH_NUM)) {
//Выбираю перевод на русском
$type="NULL";
$translate="";
$sql="select translation,type from main._translations where identifier='".$row[0]."' and language_id=(select id from main._languages where short_name='ru');";
$res2 = NULL;
try
{
$res2 = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res2!=NULL && $res2->rowCount()>0) {
while ($row2 = $res2->fetch(PDO::FETCH_NUM)) {
$translate=$row2[0];
if($row2[1]===true) $type='true';
if($row2[1]===false) $type='false';
}
}
if($translate!=''){
$sql="select l.*,(select translation from main._translations t where t.del=false and t.language_id=l.id and identifier='".$row[0]."' limit 1) as translation from main._languages l where l.del=false;";
$res3 = NULL;
try
{
$res3 = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res3!=NULL && $res3->rowCount()>0) {
while ($row3 = $res3->fetch(PDO::FETCH_ASSOC)) {
//$translate=$row3[0];
if($row3['translation']==''){ //Если не переведён то пытаюсь перевести
echo 'short_name='.$row3['short_name'].' identifier='.$row[0].' text='.$translate.'<br>';
$myObj = new stdClass();
$myObj->target = $row3['short_name'];
$myObj->q = array($translate);
$json=json_encode($myObj);
//$json='{"q": ["Hello world", "My name is Jeff"], "target": "de"}';
echo $json."<br>";
$json=getURLText("https://translation.googleapis.com/language/translate/v2?key=AIzaSyAOtc8E9Yg0O1uuZ_0EMYgqFP7W3p_0LGI",$json);
echo $json;
echo "<br>";
/*
$myObj = new stdClass();
$myObj->sourceLanguageCode = "ru";
$myObj->targetLanguageCode = $row3['short_name'];
$myObj->contents = array($translate);
$json=json_encode($myObj);
$json='{"sourceLanguageCode": "en","targetLanguageCode": "ru","contents": ["Dr. Watson, come here!", "Bring me some coffee!"]}';
echo getURLText("https://translation.googleapis.com/v3/projects/AIzaSyAOtc8E9Yg0O1uuZ_0EMYgqFP7W3p_0LGI:translateText",$json);
*/
$myObj=json_decode($json); //{ "data": { "translations": [ { "translatedText": "km / h", "detectedSourceLanguage": "bg" } ] } }
if(!property_exists($myObj,'error')) {
echo '<br>';
$sql = "insert into main._translations(language_id,identifier,translation,type,auto)values(" . $row3['id'] . ",'" . $row[0] . "','" . addslashes($myObj->data->translations[0]->translatedText) . "',$type,true);";
echo $sql . '<br>';
try
{
$db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
exit;
}
}
}
}
}
}
}
}
//http://translate.google.com/translate_a/t?client=x&text=hello&sl=en&tl=ru
//Если есть перевод с Русского то переводим с него если нет то с Английского
?>
<h2>Генерация</h2>
<table>
<tr><td>Параметр</td><td><input id="data" type="text" size="30" value="012345678912"></td></tr>
<tr><td></td><td style="text-align: right;"><button onclick="Request();">Отправить</button></td></tr>
</table>
</body>
</html>

23
monitoring/trip.html Normal file
View File

@ -0,0 +1,23 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
Маршрут<br>
Перевозчик<br>
Тип автобуса<br>
Номер автобуса<br>
ФИО водителя<br>
Направление<br>
Время выхода на рейс<br>
Время завершения рейса (план.)<br>
Время завершения рейса (факт.)<br>
Число пасажиров<br>
Сопроводительные документы<br>
Коментарий<br>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<?php
@session_start();
require_once("./config.php");
$fn=0;
if(isset($_GET['fn'])) { $fn=$_GET['fn']; }
$db=connectToDB();
$db->exec("SET TIME ZONE 'UTC';");
if($fn==1)
{
//Добавляю кордионату в базу
$imei=0;
$lon=0;
$lat=0;
$utime=0;
if (isset($_POST['imei'])) $imei=$_POST['imei'];
if (isset($_POST['lon'])) $lon=$_POST['lon'];
if (isset($_POST['lat'])) $lat=$_POST['lat'];
if (isset($_POST['utime'])) $utime=$_POST['utime'];
$sql="select * from main.setLocation(1,'".$imei."',".$lat.",".$lon.",700,40,false,to_timestamp(".$utime.")::timestamp,NULL);";
try
{
$res = $db->query($sql);
}catch (Exception $e)
{ echo $e->getMessage();
$res = null;
}
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
}
}
?>
<html>
<head>
<meta charset="utf-8">
<title>Приём координат для виртуального терминала</title>
</head>
<body>
Параметры:
<form method="post" action="virtual_terminal.php?fn=1">
<p>
IMEI<input name="imei" type="text" value="537126354421237" size="50"><br>
Долгота (lon)<input name="lon" type="text" value="76.8648" size="50"><br>
Широта (lat)<input name="lat" type="text" value="43.2456" size="50"><br>
Unix-время<input name="utime" type="text" value="1542862269" size="50"><br>
</p>
<p>
<input type="submit" value="Отправить">
<input type="reset" value="Очистить">
</p>
</form>
</body>
</html>

442
monitoring/work.php Normal file
View File

@ -0,0 +1,442 @@
<?php
//Скрипт для выполнения всевозможных проверок. Таких как прохождение контрольных точек. назначили ли на рейс автобус.
//Данный скрипт выполняется раз в минуту добавив расписание в CRON:
// sudo crontab -e -u www-data
// */1 * * * * wget -O /dev/null -q 'http://stations.istt.kz/engine/work.php'
//Создаём рейс по расписанию
@session_start();
require_once("./config.php");
$db=connectToDB();
//$db->exec('SET TIME ZONE 0;');
/*
$sql='
select
s.id,
s.repeat,
s.route_id,
((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time") as "time",
s."day",
s."month",
CASE WHEN s.direction THEN \'1\' ELSE \'0\' END as direction,
(select rc.company_id from main.routes_companies rc join main.companies c on c.id=rc.company_id where rc.del=false and c.company_type_id=2 and route_id=r.id and rc.type=true limit 1) as company_id,
coalesce(s.company_id,(select rc.company_id from main.routes_companies rc join main.companies c on c.id=rc.company_id where rc.del=false and c.company_type_id=1 and route_id=r.id order by rc.type desc limit 1)) as carrier_id,
s.date,
s.inform,
s.auto,
r.name as route_name
from
main.trips_schedules s
join main.routes r on r.id=s.route_id
where
s.del=false
and (s.date_start is null or s.date_start>now())
and (s.date_end is null or s.date_end<now())
and position(cast(EXTRACT(DOW FROM ((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time")) as character varying) in s."day")>0
and position(case when EXTRACT(MONTH FROM ((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time"))=11 then \'a\' when EXTRACT(MONTH FROM ((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time"))=12 then \'b\' else cast(EXTRACT(DOW FROM ((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time")) as character varying) end in s."month")>0
and s.date<((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time")-s.inform
and now()>((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time")-s.inform
order by s."time"
';
$res = NULL;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$dir='';
if($row['direction']=='1') $dir='в прямом направлении'; else $dir='в обратном направлении';
$msg='Для маршрута "'.$row['route_name'].'" '.$dir.' необходимо создать рейс, время отправления "'.$row['time'].'"!';
echo '<b>'.$msg."</b><br>";
echo 'Настройки для создания рейса:<br>';
$json='{"trip_type_id":1,"route_id":'.$row['route_id'].',"direction":'.$row['direction'].',"carrier_id":'.$row['carrier_id'].',"date":"'.$row['time'].'"}';
//echo $json;
echo '<br>';
if($row['auto']) //Если автоматическое создание рейса по расписанию.
{
}else //Создание рейса доверяем пользователю в автовокзале
{
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Creation_of_trips','".$msg."',".$row['company_id'].",'Create','".$json."');";
$db->query($sql);
echo $sql.'<br>';
}
echo '<br>';
//Создал либо проинформировал, обновляю расписание
$sql="update main.trips_schedules set date=(now() AT TIME ZONE (EXTRACT(TIMEZONE FROM \"time\") * INTERVAL '1 second'))::date + \"time\" where id=".$row['id'];
$db->query($sql);
echo $sql;
echo '<br>';
echo '<br>';
}
}else
{
echo 'Нет ни одного расписания!<br>';
}
*/
//----------------------------------------------------------------------------------------------------
//Проверяем контрольные точки и если в контрольной точке нет ни одной коордионаты то считается что контрольная точка просрочена
//Выбираю те записи для которых нужна проверка выполнения расписания
//Для этого выбираю действующие рейсы (которые начались) и действующие контрольные точки которые закончались
//Исключаю из контрольных точек уже пройденные те. где time заполнено
/*
$sql='
select
t.id as trip_id,
t.object_id,
rc.id as checkpoint_id,
t.date_start+rc."time"-"interval" as start,
t.date_start+rc."time"+"interval" as stop
from
main.trips t
join main.routes_checkpoints rc on rc.route_id=t.route_id and rc.direction=t.direction
join main.routes r on r.id=rc.route_id
where
t.del=false
and rc.del=false
and r.del=false
and t.object_id is not null
and t.date_start<now()
and t.date_start+rc."time"+"interval" < now()
and rc.id not in (select route_checkpoint_id from main.trips_checkpoints where del=false and trip_id=t.id)
order by t.id;
';
$res = NULL;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
//Проверяем каждую точку за заданный промежуток времени и если в геозоне нет такой точки то считаем что автобус опоздал либо ускорился
$sql="select id,date,lon,lat from main.terminals_locations where del=false and object_id=".$row["object_id"]." and date>'".$row["start"]."' and date<'".$row["stop"]."';";
echo $sql.'<br>';
$res2=null;
try
{
$res2 = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res2!=NULL && $res2->rowCount()>0)
{
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
{
echo 'id='.$row2['id'].' date='.$row2['date'].' lat='.$row2['lon'].' lon='.$row2['lon'].'<br>';
}
}
echo '<br><br>';
}
}*/
//----------------------------------------------------------------------------------------------------
//Проверка на то что назначили ли на рейс автобус за 10 минут до начала движения по рейсу, если нет то отправляем предупреждение
echo 'Проверка назначения автобуса на рейс за 10 минут до рейса если не назначем то генерим предупреждение<br>';
$sql='
select
t.id,
t.company_id,
t.company_carrier_id,
r.name as route_name,
t.date_start
from
main.trips t
join main.routes r on r.id=t.route_id
left join main.objects o on o.id=t.object_id and o.del=false
where
t.del=false
and o.id is null
and t.date_start<now()-\'10 minutes\'::interval
and t.date_start>now()-\'10 day\'::interval --Старые рейсы не сканируем
and (t.informed is null or t.informed=false)
';
$res = NULL;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
$msg='Для рейса "'.$row['route_name'].'" с началом движения в "'.$row['date_start'].'" не был назначен автобус!';
$json='{}';
echo $msg.'<br>';
//Отправляю предупреждение перевозчику
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Attention','".$msg."',".$row['company_id'].",null,null);";
$db->query($sql);
//Отправляю предупреждение автобусному парку
if($row['company_carrier_id']!='')
{
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Attention','".$msg."',".$row['company_carrier_id'].",null,null);";
$db->query($sql);
}
//Отмечаю что по даному маршруту было отправлено предупреждение и больше его не стоит отправлять
$sql="update main.trips set informed=true where id=".$row['id'];
$db->query($sql);
}
}
echo 'OK<br>';
//----------------------------------------------------------------------------------------------------
//Проверка прохождения контрольных точек и генерация сообщения о опоздании (делаю не в момент получения координат так как точки могут придти позже)
//Есть 2 варианта генерации сообщения 1: за заданный период нет координат 2: Координаты есть но ни одной в заданой области
echo 'Проверка прохождения контрольных точек и генерация сообщения об этом<br>';
$sql='
select
tc.id,
tc.route_checkpoint_id,
t.company_id,
t.company_carrier_id,
t.object_id,
t.date_start+rc."time"-rc."interval" as start,
t.date_start+rc."time"+rc."interval" as stop,
tc.informed,
o.name as object_name,
rc.name as checkpoint_name,
t.date_start,
r.name as route_name
from
main.trips_checkpoints tc
join main.trips t on tc.trip_id=t.id
join main.routes_checkpoints rc on rc.id=tc.route_checkpoint_id
left join main.objects o on o.id=t.object_id
left join main.routes r on r.id=t.route_id
where
tc.del=false
and t.del=false
and rc.del=false
and (tc.informed is null or tc.informed=false)
and tc."time" is null
and t.object_id is not null
and t.date_start+rc."time"+rc."interval"<now()
and t.date_start+rc."time"+rc."interval">now()-\'10 day\'::interval --Старые рейсы не сканируем
';
$res = NULL;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
//Проверяю были ли точки в заданное время для автобуса
$sql='select sum(1) as cnt from main.terminals_locations where object_id='.$row['object_id'].' and date>\''.$row['start'].'\' and date<\''.$row['stop'].'\' and ST_Within(ST_SetSRID(ST_MakePoint(lon,lat),4326),(select geom from main.routes_checkpoints where id='.$row['route_checkpoint_id'].'))=true';
$res2 = NULL;
try
{
$res2 = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res2!=NULL && $res2->rowCount()>0)
{
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
{
if($row2['cnt']===0)
{
$msg='Автобус "'.$row['object_name'].'" в заданное время c "'.$row['start'].'" по "'.$row['stop'].'" не был в контрольной точке "'.$row['checkpoint_name'].'" на маршруте "'.$row['route_name'].'" с началом движения в "'.$row['date_start'].'"!';
$json='{}';
echo $msg.'<br>';
//Отправляю предупреждение перевозчику
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Passage_of_control_points','".$msg."',".$row['company_id'].",'Filtering','".$json."');";
$db->query($sql);
//Отправляю предупреждение автобусному парку
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Passage_of_control_points','".$msg."',".$row['company_carrier_id'].",'Filtering','".$json."');";
$db->query($sql);
//Отмечаю что по даному маршруту было отправлено предупреждение и больше его не стоит отправлять
$sql="update main.trips_checkpoints set informed=true where id=".$row['id'];
$db->query($sql);
}else
{
$msg='Терминал автобуса "'.$row['object_name'].'" не передавал валидные координаты заданное время с "'.$row['start'].'" по "'.$row['stop'].'" для контрольной точки "'.$row['checkpoint_name'].'" на маршруте "'.$row['route_name'].'" с началом движения в "'.$row['date_start'].'"!';
$json='{}';
echo $msg.'<br>';
//Отправляю предупреждение перевозчику
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Passage_of_control_points','".$msg."',".$row['company_id'].",'Filtering','".$json."');";
$db->query($sql);
//Отправляю предупреждение автобусному парку
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Passage_of_control_points','".$msg."',".$row['company_carrier_id'].",'Filtering','".$json."');";
$db->query($sql);
//Отмечаю что по даному маршруту было отправлено предупреждение и больше его не стоит отправлять
$sql="update main.trips_checkpoints set informed=true where id=".$row['id'];
$db->query($sql);
}
}
}
echo '<br><br>';
}
}
echo 'OK<br>';
//----------------------------------------------------------------------------------------------------
//Выбираем точки в заданный промежуток времени если эта точка не находится на маршруте то проверяем её на зоны объезда и если она находится там то не реагируем
//а если точка в не зоны объезда то нужно проверить в предыдущей или следующей были выезды то не следует генерировать новое предуреждение.
//А предыдущий определяется по времени те если +- 5 минут небыло ни одного выезда то событие не генерим, это сделано потому что координаты с терминала приходят не последовательно по возможности с начала новые а потом старые.
//Коордионаты проходящие не по маршруту выписываем в отдельную таблицу
echo 'Проверка GPS координат на то что они в нужное время на маршруте с учётом объездов, если не на маршруте то генерим предупреждение<br>';
$sql="
select
t.id,
t.date_start + mint.min_time as date_start,
t.date_start + maxt.max_time as date_stop,
t.object_id,
t.route_id,
r.name
from
main.trips t
join main.routes r on r.id=t.route_id
join (
select
rc.route_id,
rc.\"time\"+rc.\"interval\" as min_time
from
main.routes_checkpoints rc
join (select route_id,min(\"time\") as \"time\" from main.routes_checkpoints where del=false and route_id=129 group by route_id) t on t.route_id=rc.route_id and t.\"time\"=rc.\"time\"
limit 1
) mint on mint.route_id=t.route_id
join
(
select
rc.route_id,
rc.\"time\"-rc.\"interval\" as max_time
from
main.routes_checkpoints rc
join (select route_id,max(\"time\") as \"time\" from main.routes_checkpoints where del=false and route_id=129 group by route_id) t on t.route_id=rc.route_id and t.\"time\"=rc.\"time\"
limit 1
) maxt on mint.route_id=t.route_id
where
t.del=false
and r.del=false
and t.object_id is not null
and t.date_start + maxt.max_time>now()-'10 day'::interval --Старые рейсы не сканируем
order by t.date_start
";
$res = NULL;
try
{
$res = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res!=NULL && $res->rowCount()>0)
{
while ($row = $res->fetch(PDO::FETCH_ASSOC))
{
//Теперь проверяем координаты которые ещё небыли проверены
echo 'Проверяю для "'.$row['name']." c ".$row['date_start'].' по '.$row['date_stop'].'"<br>';
$sql='
select
sl.id,
ST_distance(r.geom::geography,ST_SetSRID(ST_MakePoint(sl.lon,sl.lat),4326)::geography)<width as on_route
from
main.terminals_locations sl,
main.routes r
where
sl.del=false
and r.del=false
and sl.on_trip is null
and r.id='.$row['object_id'].'
and sl.date>\''.$row['date_start'].'\'
and sl.date<\''.$row['date_stop'].'\'
';
$res2 = NULL;
try
{
$res2 = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
if($res2!=NULL && $res2->rowCount()>0)
{
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
{
if($row2['on_route']==true)
{
//Помечаем точку что она на маршруте
$sql='update main.terminals_locations set on_trip=true where id='.$row2['id'];
$db->query($sql);
}else
{
//Для точек которые не на маршруте нужно пройти ещё одну проверку не находятся ли они в объездах
$sql='select sum(1) from main.terminals_locations sl,main.detours d where ST_Within(ST_SetSRID(ST_MakePoint(sl.lon,sl.lat),4326),d.geom)=true and sl.id='.$row2['id'];
$res3 = NULL;
try
{
$res3 = $db->query($sql);
}catch (Exception $e)
{
echo $e->getMessage();
}
}
}
}
//++++++
}
}
echo 'OK<br>';