#ifndef YASERVER_CLASSDEF_H_
#define YASERVER_CLASSDEF_H_

#define MAX_LOG_LENGTH 500
#define MAX_DIST_CACHE 2  //5
#define DIST_COUNT 4
#define ANCHOR_COUNT 4

#define MINE_EVENT_COUNT 3
#define SECTION_EVENT_COUNT 6
#define AREA_EVENT_COUNT 5
#define CARD_EVENT_COUNT 88
#define READER_EVENT_COUNT 88

#define KALMAN_OFFSET_COOR 0.01
#define KALMAN_OFFSET_MOVE 1

#define KALMAN_OFFSET_RANGING 0.01
#define KALMAN_INTERVAL 1.0 // 以秒为单位

#define KALMAN_OFFSET_COOR_TRI 0.01
#define KALMAN_OFFSET_MOVE_TRI 1
#define KALMAN_OFFSET_RANGING_TRI 0.09
#define KALMAN_INTERVAL_TRI 2.0 //以秒为单位

#define ANTENNA_COUNT 4
#define ADHOC_COUNT 10
#define READER_TIMEOUT 20
#define CARD_LOST_TIME_OUT 30 // (30)
#define CARD_ATTENDANCE_TIMEOUT (60*60)
#define CARD_LOST_TIME_CAL 5 // 卡未收到数据后，利用缓存的数据计算间隔
#define CARD_LOST_TIME_OUT_SPECIAL_AREA 1800
#define READER_SEND_STATE_TIMEOUT 30 
#define LIGHT_SEND_STATE_TIMEOUT 30 
#define OVER_TIME (480 * 60)
#define MAX_SEMACOUNT 64

//算法类型
//#define ALGORITHM_TYPE_TOF
//#define ALGORITHM_TYPE_TDOA
//#define ALGORITHM_TYPE_INS		//使用惯导判断
#define ENABLE_MY_LOG
#define ENABLE_DEBUG_PERSON_IN_CAR_LOG 1
#define ENABLE_DEBUG_2D_TEST_LOG 0

#define NEED_DISPLAY_RULES 1  // lemon 2017/08/01
#define NEED_DISPLAY_VALID 0
#define NEED_DISPLAY_INVALID 1
#define PATROL_LEVEL_ID 3

#define INDEXFORRECONEREADER 10 //如果持续10次都只被一个分站接收，则速度为0

#define SUSTAINEDOVERSPEED 5 // 如果连续5次都是超速，则告警.

#define WRITE_DRIVINGFACE_REAL_PER_TIME 20000

#define STR_LEN_TIME 50

//lemon 2017/10/14
#define DRIVINGFACE_X_CONST 1   //X 不变
#define DRIVINGFACE_Y_CONST 2   // Y 不变
#define DRIVINGFACE_XY_CONST 3

#define STARTUP_STATE_COUNT 10
#define SHUTDOWN_STATE_COUNT 5
#define SEC_TO_HOUR 3600.0   

//area
#define AREA_WORK_AREA      1 //工作区域
#define AREA_NON_WORK_AREA  0 //非工作区域

//card
#define CARD_FRONT_LINE_WORKERS		1 //一线工人
#define CARD_SECONT_LINE_WORKERS	2 //二线工人

#include <string>
#include <ctime>
#include <map>
#include <iostream>  
#include <string>  
#include <vector>
#include <unordered_map>
#include <deque>
#include <mutex>
#include <thread>
#include <boost/shared_ptr.hpp>
#include <kalman\locate.h>
#include "Filter\KalmanFilter.h"
#include "algorithm\FittingPosition.h"
#include "algorithm\Fit.h"
#include "LocateRecord.h"
#include "algorithm/tdoa/taylor_wls_tdoa.h"
#include "algorithm/base/sensor_manager.h"
//#include "algorithm/AjustPosition.h"
#include <boost/circular_buffer.hpp>
#include "car.h"

struct card;

#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)

using namespace std;
using namespace algorithm;

//算法中使用的常量定义
const int MAX_CALC_POINTS = 30;
const int ACCELERATE_INIT_STATE = -10;
const int IDLE_CONFIRM_TIME = 4;
const int LIGHT_CTRL_DELAY = 1000;
const int MAX_REBOUND_COUNTS = 5;
const double INS_WEIGHT = 9.0;			 //惯导权重
const double UWB_WEIGHT = 1.0;			 //UWB权重

const double MAX_VECHILE_SPEED = 30.0;	 //车卡运动速度阈值，超过此阈值，定位数据被抛弃
const double MAX_PERSON_SPEED = 15.0;	 //人卡运动速度阈值，超过此阈值，定位数据被抛弃

const double NEAR_READER = 4.0;
const double MIN_DIFFER_DISTANCE = 10.0; // 使用其他分站校验计算结果时，判断该结果到校验分站的距离差允许的范围
const double MIN_IDLE_THRESHOLD = 0.5;
const double VECHILE_ACCELERATE_THRESHOLD = 3; // 校验加速度阈值
const double PERSON_ACCELERATE_THRESHOLD = 1.5; // 校验速度阈值
const int POS_NO_CHANGE_TIMES = 15; // lihongzhen  2017/8/19 位置连续未改变次数，每次0.5秒，约7秒
const double CHAMBER_WIDTH = 4.0;			//特指前端展现巷道的宽度，单位为像素
const double VEHICLE_WIDTH = 10.0;
const double TOF_HEIGHT_ERROR = 2;					//tof定位时的高度误差，单位为米
const double READER_SYNC_INTERVAL_TIME  = 0.2;		//分站同步序号的时间差，估计值
const int CONFIRM_ON_VEHICLE_COUNTS = 3;			//人上车条件确认次数
const int CONFIRM_OFF_VEHICLE_COUNTS = 3;			//人下车条件确认次数
const double THRE_MOVING_READER_DISTANCE = 3.0;		//人卡与移动分站的距离阈值，上下车通用
const double THRE_RELATIVE_SPEED = 3.6;				//人卡与从移动分站对应的车卡的相对速度阈值，单位为3.6km/h

#define OFFSET_THRE_IN_LINE 1	//判断是否在线段上，允许的误差为1米，用于isinline
#define ZERO_PRECISION 1E-3		//为零的精度
#define HIGH_ZERO_PRECISION 1E-6		//高精度零判断

//added by zhuyf 2018/07/06
const double MAX_SPEED = 1.87;		//井下人/车移动的最大速度，1.67m/s 约合 6km/h，考虑到0.2米的误差，还要+0.2。
const int IGNORE_H_DISTANCE = 10;	//可忽略高差的距离，大于此距离时，高差可以忽略不计
const double ABSOLUTE0 = 0.00001;
const int H = 2;					//卡与天线的高差，是个概值
const double E = 0.2;				//测距精度
const int SIMULATOR_CARD_START_NO = 60000;
const uint64_t MAX_SMALL_READER_SIZES = 10;

enum ALARM_FLAG{
	//AF_CARD_OVER_COUNT = 1,
	//AF_CARD_AREA_OVER_COUNT,
	AF_CARD_OVER_TIME,
	AF_CARD_OVER_SPEED,
	AF_CARD_AREA_OVER_SPEED,
	AF_CARD_AREA_OVER_TIME,
	AF_CARD_LOW_POWER,
	AF_CARD_LOW_POWER_SERIOUS,
	AF_CARD_AREA_FORBIDDEN,
	AF_AREA_OVER_COUNT,
	AF_AREA_OVER_TIME,
	AF_AREA_FORBIDDEN,
	AF_CARD_OVER_COUNT,
	AF_CARD_NEAR_WARNING_POINT,//lemon	
	AF_CARD_NEAR_DRRIVINGFACE_VEHICLE, //lemon 2017/08/01
	AF_CARD_NEAR_GEOFAULT,
	AF_CARD_MOTIONLESS
};

enum AREA_TYPE
{
	AREA_TYPE_FORBIDDEN = 3,	// 限制区域
	AREA_TYPE_NO_COVER = 1000,	// 非覆盖区域，车辆信号消失后，定位到附近非覆盖区域内
	AREA_TYPE_SPECIAL = 1001	// 特殊区域，只给你前端用来标识是否显示图标,胶轮车硐室
};

enum EDIT_TYPE_ID{
	ET_INSERT = 0, // 新增
	ET_UPDATE,	   // 修改
	ET_DELETE      // 删除
};
//车辆烈性
enum VECHILE_TYPE_ID
{
	VT_DIGGINGCOAL_MACHINE=25,
	VT_DRIVINGFACE_MACHINE=26
};
enum ALARM_TYPE_ID
{
	ATID_OVER_COUNT_PERSON = 1,
	ATID_POWER,
	ATID_OVER_COUNT_VEHICLE
};

enum STATUS_DEVICE{
	STATUS_DEVICE_NORMAL = 0,
	STATUS_DEVICE_ERROR
};

enum STATUS_CARD
{
	STATUS_NORMAL = 0,				//正常
	STATUS_ERROR = 1, 
	STATUS_ERROR_SERIOUS = 2,

	STATUS_POWER_LOWER = 1,			//电量低
	STATUS_POWER_LOWER_SERIOUS = 2, //电量极低
	STATUS_OVER_TIME = 4,			//超时
	//STATUS_OVER_COUNT = 1,
	STATUS_OVER_SPEED = 8,			//超速
	STATUS_AREA_OVER_TIME = 16,		//区域超时
	//STATUS_AREA_OVER_COUNT = 1,
	STATUS_AREA_OVER_SPEED = 32,	//区域超速
	STATUS_AREA_FORBIDDEN = 64,		//进入限制区域
	STATUS_HELP = 128,				//呼救
	STATUS_HELP_DEALED = 256,		//呼救已处理
	STATUS_CALL = 512,				//呼叫
	STATUS_LOST = 1024				//进入盲区
	//STATUS_ERROR_DEALED,
};

enum STORE_CARD_DATA_FLAG{
	HIS_LOCATION = 0,
	HIS_RAW_DATA,
	HIS_AREA_LOCATION_ENTER,
	HIS_AREA_LOCATION_LEAVE,
	RPT_ATTEND_DOWN,
	RPT_ATTEND_UP
};

enum STORE_MINE_DATA_FLAG{
	ALARM_MINE_OVER_COUNT_PERSON_START = 0,
	ALARM_MINE_OVER_COUNT_PERSON_END,
	ALARM_MINE_OVER_COUNT_VEHICLE_START,
	ALARM_MINE_OVER_COUNT_VEHICLE_END
};

enum STORE_LIGHT_DATA_FLAG{
	ALARM_LIGHT_FAULT_START= 0, 	//故障开始
	ALARM_LIGHT_FAULT_END,			//故障结束
	ALARM_LIGHT_NETWORK_START,		//网络故障开始
	ALARM_LIGHT_NETWORK_END,		//网络故障结束
	ALARM_LIGHT_CONTROL_FAILE		//控制失败
};

enum STORE_SECTION_DATA_FLAG{
	ALARM_SECTION_START = 0, // 区段告警开始
	ALARM_SECTION_END // 区段告警结束
};

enum LIGHT_STATE{
	LIGHT_NORMAL = 0, // 正常
	LIGHT_FAULT, // 异常
	LIGHT_NETWORK_ERROR,  // 网络故障
	LIGHT_CONTROL_ERROR   // 控制失败
};

enum LOCATE_TYPE
{
	LT_COORDINATE = 0, // 使用坐标定位
	LT_READER // 使用分站定位
};

enum FILTER_TYPE{
	NO_FILTER = 0,		// 不使用滤波
	FILTER_KALMAN = 1	// 使用kalman滤波
};

enum SECTION_STATE{
	SECTION_STATE_NORMAL = 0,		//正常
	SECTION_STATE_BUSY = 1,			//繁忙
	SECTION_STATE_CONGESTION = 2	//拥堵
};

enum LIGHT_SHAPE{
	INIT_SHAPE=0,
	RED_CIRCLE_SOLID = 1,	//红色实心圆
	RED_CIRCLE = 2,			//红色空心圆
	RED_CROSS = 3,			//红色叉形
	GREEN_UP = 4,			//绿色上箭头
	GREEN_DOWN = 5,			//绿色下箭头
	GREEN_LEFT = 6,			//绿色左箭头
	GREEN_RIGHT = 7,		//绿色右箭头
	RED_SPARK = 8,			//红色闪烁
	GREEN_SPARK = 9,		//绿色闪烁
	GREEN_ALL_ON=10,		//绿色全亮
	GREEN_ALL_OFF=11,		//绿色全灭
	RED_ALL_ON=12,			//红色全亮
	RED_ALL_OFF=13			//红色全灭
};

enum LIGHT_STREAM{
	INIT_STREAM = 0,
	UP_STREAM = 1,		//上行
	DOWN_STREAM = 2	//下行
};

enum LIGHT_COLOR{
	COLOR_RED = 1, // 红色
	COLOR_GREEN = 2 // 绿色
};

enum LIGHT_CTRL_STATE{
	CTRL_STATE_AUTO = 1, //  自动控制
	CTRL_STATE_MANUAL = 2 // 手动控制
};

enum LIGHTS_SELECT_TYPE
{
	LST_ALL_LIGHTS = 0, // 所有灯
	LST_ALL_UP_LIGHTS = 1, // 所有上行
	LST_ALL_DWON_LIGHTS = 2,// 所有下行
	LST_SOME_LIGHTS = 3 // 指定灯
};

enum AREA_PROPERTY{
	MAIN_TUNNEL = 0, // 主巷道
	BRANCH_TUNNEL = 1 // 分支巷道
};

enum OUTPUT_POS{
	CENTRAL_POS = 0, // 居中
	LEFT_POS,  // 靠左
	RIGHT_POS  // 靠右
};

enum PATROL_STATE
{
	PS_NORMAL = 0, // 正常
	PS_EARLY, // 早到
	PS_LATE,  // 迟到
	PS_NON_ARRIVAL // 未到
};

enum PATROL_STAY_STATE
{
	PSS_NORMAL = 0, // 正常
	PSS_TOO_LONG,   // 停留过长
	PSS_TOO_SHORT   // 停留太短
};

enum ALGO_RETURN_VALUE{
	DIST_COUNT_LESS_THAN_TWO = 10001,
	DIST_COUNT_LESS_FOR_TIMESTAMP_ERROR,
	DIST_COUNT_LESS_FOR_SYNC_NUM_DIFFER_FIVE,
	DIST_COUNT_CARD_CUR_CT_LESS_LAST,

	ALGO_CALC_SOLUTION = 30001,
	ALGO_CALC_NO_SOLUTION_WITH_TWO_DATA,
	ALGO_CALC_ONE_DATA,

	SOLUTION_NO_SOLUTION = 40001,
	SOLUTION_NOT_EXIST_READRE,
	SOLUTION_NEAR_READER,
	SOLUTION_TWO_SOLUTION,
	SOLUTION_ERROR_STREAM,
	POSITION_INVALID,
	SOLUTION_IDLE_STATUS,

	CHECK_PERSON_ACCE_OVER_SPEED = 50001,
	CHECK_VEHICLE_ACCE_OVER_SPEED,
	CHECK_VEHICLE_OVER_SPEED,

	KALMAN_FILTER_LONG_INTERVAL = 60001,

	ALGO_USE_KALMAN_FILTER = 70001,
	ALGO_DIVIDE_ZERO = 80001,
};

extern unsigned int g_nAlgoFailedCounts[ALGO_LOC_TOTAL];	//全局的统计所有次数
extern unsigned int g_nAlgoFailedCycleCounts[ALGO_LOC_TOTAL];	//指定周期内的所有统计次数
extern DWORD g_ullCurTime;
extern unsigned long long m_Start_time;
#define ALGORITHM_FAILED(nType) { \
	g_nAlgoFailedCounts[nType]++; \
}

struct AlgoFailedMsg{
	std::string strCardId;
	int nCardStamp;
	int nType;
	SYSTEMTIME st;
	bool bStatus;

	AlgoFailedMsg(){
		strCardId = "";
		nCardStamp = 0;
		nType = 0;
		bStatus = false;
	}
};

enum DEVICE_TYPE{
	DT_BIG_READER		= 1,	// 大分站
	DT_SMALL_READER		= 2,	// 小分站
	DT_CARD_READER		= 3,	// 读卡分站
	DT_CTRL_READER		= 4,	// 通信分站
	DT_LIGHT			= 5,	// 红绿灯
	DT_SPEAKER			= 6,	// 告警器
	DT_TURNOUT			= 7,	// 道岔
	DT_LED				= 8,	// 显示屏
};

enum CALL_STATE{
	CALL_NONE = 0,			//无呼叫信息
	CALL_SUCCESSED = 1,		//呼叫成功
	CALL_ING = 2,			//呼叫中
	CALL_FAILED = 3,		//呼叫失败
};

enum CALL_CARD_TYPE
{
	CCT_CALL_ALL = 0, // 全员呼叫
	CCT_CALL_APOINT, // 定员
};

enum LOCATEDATATYPE // 定位数据类型
{
	LDT_TOF = 0,		//TOF 
	LDT_TDOA,			//TDOA
	LDT_BROAD,			//Braodcast
	LDT_TOF_INS,
	LDT_TDOA_INS
};

enum LOCATE_DATA_NUMS{
	ONE = 1,
	TWO,
	THREE,
	FOUR
};

enum Orientation{
	LEFT = 0,
	UP,
	RIGHT,
	DOWN,
	LEFT_UP,
	LEFT_DOWN,
	RIGHT_UP,
	RIGHT_DOWN,
};

enum INS_REQUEST_STATUS{
	NO_INS_REQUEST = 0,		//不校准
	YES_INS_REQUEST		//请求校准
};

enum SEND_CAL_DATA_STATUS{
	CAL_DATA_ALL = 0,		//所有校准数据
	CAL_DATA_POS,			//校准坐标
	CAL_DATA_ANGLE			//校准角度
};

enum PERSON_ON_VEHICLE_STATUS{
	PERSON_OFF_VEHICLE = 0,
	PERSON_ON_VEHICLE
};

struct OnVehicleData{
	int counts;
	std::map<string,int> person_cards;

	OnVehicleData(){
		counts = 0;
	}
};

struct SQLTHREAD_DATA//写数据库线程传递的参数
{
	char* pText;//数据库语句地址指针
	int nRepeatTimes;//已经重试几次
};

struct _point{ // 坐标
	double x;
	double y;
	double z;

	_point(){
		x = y = z = 0;
	}

	_point(double a,double b,double c){
		x = a;
		y = b;
		z = c;
	}

	_point(double a,double b){
		x = a;
		y = b;
		z = 0;
	}
};

struct TimePosition{
	time_t cur_time;
	_point p;

	TimePosition(){
		cur_time = time(NULL);
		p.x = p.y = p.z = 0;
	}

	TimePosition(double x_,double y_){
		cur_time = time(NULL);
		p.x = x_;
		p.y = y_;
	}
};

struct AlgoParamData{
	_point ant[2];		//双天线坐标
	uint16_t ct;		//当前双天线测距信息
	double distance[2];	//双天线的测距距离
	uint32_t anchor_id;	//分站号

	AlgoParamData(){
		ant[0].x=ant[0].y=ant[1].x=ant[1].y = 0;
		ct = 0;
		distance[0] = distance[1] = 0;
	}
};

struct sync_data{
	double x;
	double y;
	double z;

	double vx;
	double vy;
	double vz;

	int sync_num;	//本次同步号
	bool update;

	std::shared_ptr<nspLocate::LocateRecord> locate;

	sync_data(){
		x = 0.0;
		y = 0.0;
		z = 0.0;
		vx = 0.0;
		vy = 0.0;
		vz = 0.0;
		sync_num = 0;
		update = false;
		locate = nullptr;
	}

	sync_data& operator=(sync_data&tmp){
		x = tmp.x;
		y = tmp.y;
		z = tmp.z;
		vx = tmp.vx;
		vy = tmp.vy;
		vz = tmp.vz;
		sync_num = tmp.sync_num;
		update = tmp.update;
		locate = tmp.locate;
		return *this;
	}
    inline bool operator == (const sync_data& rhs) const
    {
        return x == rhs.x &&
            y == rhs.y &&
            vx == rhs.vx &&
            vy == rhs.vy &&
            sync_num == rhs.sync_num &&
            update == rhs.update;
    }
};

struct _call_info_card
{
	int card_id;        // 呼叫卡号
	int card_type;      // 呼叫类型，全员、定员
	int call_level;     // 呼叫级别，一般、紧急
	string str_card_id;  // 呼叫卡号，带卡类型
	time_t start_time;   // 开始呼叫时间
	int time_out;        // 呼叫时长，单位分钟
	//bool is_success;
	int call_state;      // 呼叫状态，正在呼叫、呼叫成功
};
//typedef map<std::string, _call_info_card*> CallInfoCardMap;
typedef map<std::string, std::shared_ptr<_call_info_card>> CallInfoCardMap;

struct _call_info_reader
{
	bool is_call_all;       // 呼叫类型， 全员、定员
	bool is_start_call;		//true,开始呼叫;false,取消呼叫
	BYTE call_level; // 一般，紧急
	//int call_type; 
	int cards_count;        // 呼叫的卡数，0为全员呼叫
	int time_out;           // 呼叫时长
	time_t start_time;      // 开始呼叫时间
	CallInfoCardMap mpCard;  // 呼叫卡列表
};

typedef map<int, std::shared_ptr<_call_info_reader>> CallInfoReaderMap;

struct _call_info_user
{
	std::string user_name; // 发出呼叫指令的用户
	CallInfoReaderMap mpReader; // 呼叫分站列表
};
typedef map<string, std::shared_ptr<_call_info_user>> CallInfoUserMap;

// 分站接收时间定义
struct ReceiveData{
	unsigned int reader_id;		// 分站号
	unsigned short antenna_id;  // 天线号
	long long rec_time_stamp;	// 分站接收时间，一个7字节的无符号数
	int special;
	double x;	//分站的x坐标
	double y;   //分站的y坐标
	double z;   //分站的z坐标
	ReceiveData(){
		reader_id = -1;
		antenna_id = -1;
		rec_time_stamp = 0;
		x = y = z = 0.0;
		special = -1;
	};
};

// 分站接收tof数据
struct ReceiveDataTof:public ReceiveData{
	double distance;
	ReceiveDataTof(){
		distance = 0.0;
	};
};

struct INFO_PRE{
	int t;
	long long detaT;
	double dist;
	int ant;
	int sta_num;
};

//TOF定位时参考的数据结构
struct TOF_REFER_DATA{
	unsigned int nCardTimeStamp;	// 卡的ct号
	long long llDeltaTime;			// 
	double dDistance;				// 距离
	unsigned int nAntennaIndex;		// 分站天线索引号
	unsigned int nReaderId;			// 分站id
	double x;						// 参考点x坐标
	double y;						// 参考点y坐标
	double z;						// 参考点z坐标
	int a;							// 加速度状态

	TOF_REFER_DATA(){
		nCardTimeStamp = 0;
		llDeltaTime = 0;
		dDistance = 0.0;
		nAntennaIndex = nReaderId = 0;
		x = y = z = 0.0;
		a = 0;
	}
};

//解的结构体
struct SOLUTION{
	double x[3];
	double y[3];
	double z[3];
	int nCount;

	SOLUTION(){
		for (int i =0;i<3;i++)
		{
			x[i] = y[i] = z[i] = INVALID_COORDINATE;
			nCount = 0;
		}
	}
};

//惯导数据校准的数据结构：坐标(x,y),角度angle
struct CAL_DATA{
	float x;
	float y;
	float angle;
	int status;
	int card_type;			//卡类型
	std::string card_id;	//卡id

	CAL_DATA(){
		x = y = angle = 0.0f;
		status = 0;
		card_type = 0;
		card_id = "";
	}
};

// 采煤机起始位置
struct CoalFaceStartPos
{
	float x;          // 起始位置x坐标
	float y;          // 起始位置y坐标
	time_t rec_time;  // 起始坐标接收时间
};

//综采面信息
class CoalMiningArea
{
public:
	//区域编号
	INT coalface_id;
	//综采面端点1
	double x1;
	double y1;
	//综采面端点2
	double x2;
	double y2;
	//认为到达端点的距离范围
	double distance;

	//采煤机的坐标偏移量，单位是像素
	double m_x_offset;
	double m_y_offset;

	CoalMiningArea():m_x_offset(0.0),m_y_offset(0.0){}
};

//挖煤机正规循环率的中间参数
class CoalMiningRegularCycle
{
public:
	//卡Id
	INT vehicle_id;
	//区域编号
	INT coalface_id;
	//是否开始计算
	bool IsWorking;
	// 未达机头/机尾标记
	bool bNoTarget;
	//半刀计数标记
	bool bHalfKnife;
	//目标序号
	INT tgPointNum;
	//运动方向 true-机头《-》机尾，false-机尾《-》机头
	INT bDirection;
	//上次发送位置时间
	time_t  last_time;
	//开始时间;
	time_t start_time;
	//记录最小距离的时间
	time_t  mindis_time;
	//离目标点的最小距离
	double mindistance;
	//计划刀数
	double schedule_times;
	//开始位置
	double start_x;
	double start_y;
	//结束位置
	double end_x;
	double end_y;
	//时间和位置记录
	string pos_record;
};

//挖煤机每刀详细参数
class CoalminingRegularCycleDetail
{
public:
	INT vehicle_id;// 卡号;
	//区域编号
	INT coalface_id;
	time_t start_time;//开始时间;
	time_t end_time;//结束时间;
	int dept_id;//对应队组ID;	
	double start_x;//开始x坐标;
	double start_y;//开始y坐标;
	double end_x;//结束x坐标;
	double end_y;//结束y坐标;
	int move_direction;
};

//掘进面用于定位的分站拓扑关系
struct DrivinfaceReaderTopology{
	uint64_t m_big_reader_id;		//大分站id
	uint64_t m_small_reader_id[MAX_SMALL_READER_SIZES];	//其中0为小分站id，1为中继分站id
	uint64_t m_counts;		//记录有效可使用的小分站数据（即m_small_reader_id）大小

	DrivinfaceReaderTopology():m_big_reader_id(0),m_counts(0){
		for (uint64_t i = 0;i<MAX_SMALL_READER_SIZES;++i)
		{
			m_small_reader_id[i] = 0;
		}
	}
};

//采煤机、挖掘机、司机的求和坐标
struct VehicleDriverPos
{
	VehicleDriverPos()
		:PointNum(0)
		,Sum_x(0.)
		,Sum_y(0.)
		,isOn(false)
	{

	}
	//开始时间
	time_t starttime;
	//车或者对应的车是否开机
	bool isOn;
	//定位点个数
	int PointNum;
	//x坐标和
	double Sum_x;
	//y坐标和
	double Sum_y;
};

//部门与采煤机及司机的对应关系
struct DeptVehicleDriver
{
	//部门ID
	int Dept_id;

	//采煤机和司机的对应关系
	std::map<int ,std::vector<int>> CoalMiningDriver;

	//掘进机与司机的对应关系
	std::map<int ,std::vector<int>> DrivingDriver;
};

//工作面司机和机器告警参数
struct WorkfaceDriverAlarm
{
	//车辆ID
	int Vehicle_id;
	//告警距离
	double dist;
	//告警时间
	int dist_time;
};

class Mine;
class Area;
class SpecialAreaEntry;
class DrivingfaceRender;
class DrivingfaceCard;
class DrivingfaceWarningPoint;
class VehicleTypeAttRule;
class Reader;
class Card;
class MapInfo;
class Dept;
class BanShift;
class OccLevel;
class ReaderPath;
class PatrolPoint;
class PatrolTask;
class LeaderArrange;

class Section;
class Chamber;
class Light;
class LightsGroup;
class LightCallInfo;
class StorePostion;

class LandmarkInfo;
class MapDirectionInfo;
class HandUpVehicle;
class MovingReader;
class WarningPoint;

typedef map<string, std::shared_ptr<Card>> CardMap;
typedef map<int, std::shared_ptr<Area>> AreaMap;
typedef map<int, std::shared_ptr<DrivingfaceWarningPoint>>DrivingfaceWarningPointMap;
typedef map<int,std::vector<std::shared_ptr<DrivingfaceWarningPoint>>> DrivingfaceWarningPointMapAll;
typedef map<uint64_t,std::list<std::shared_ptr<WarningPoint>>> WarningPoint_Map;
typedef map<int, std::shared_ptr<SpecialAreaEntry>> SpecilaAreaEntryMap;
typedef map<int, std::shared_ptr<DrivingfaceRender>> DrivingfaceRenderMap;
typedef map<string,std::shared_ptr<DrivingfaceCard>> DrivingfaceCardMap;
typedef map<int, std::shared_ptr<Reader>> ReaderMap;
typedef map<int, std::shared_ptr<MapInfo>> MapInfoMap;
typedef map<int, std::shared_ptr<MapDirectionInfo>>MapDirectionInfoMap;
typedef map<int, std::shared_ptr<LandmarkInfo>>LandmarkInfoMap;
typedef map<int, std::shared_ptr<Dept>> DeptMap;
typedef map<int, std::shared_ptr<BanShift>> BanShiftMap;
typedef map<int, std::shared_ptr<OccLevel>> OccLevelMap;
typedef map<int, string> AlarmTypeMap;
typedef map<int,std::shared_ptr<ReaderPath>> ReaderPathMap;
typedef map<int,std::shared_ptr<ReaderPath>> TOFReaderPathMap;
typedef unordered_map<int,std::shared_ptr<ReaderPathMap>> TDOAReaderPathMap;
typedef unordered_map<std::string, std::shared_ptr<_coordinate>> DistMap;
typedef map<unsigned long long ,std::shared_ptr<ReceiveData>> ReceiveDataMap;
typedef vector<std::shared_ptr<ReceiveDataTof>> ReceiveDataTofVector;
typedef unordered_map<unsigned long long ,std::shared_ptr<ReceiveData>> ReceiveDataUnorderedMap;
typedef map<int,std::shared_ptr<Section>> SectionMap;	//路段信息
typedef map<int,std::shared_ptr<Chamber>> ChamberMap;	//硐室信息
typedef map<int,std::shared_ptr<Light>> LightMap;		//红绿灯信息
typedef map<int,std::shared_ptr<LightsGroup>> LightGroupMap;	//红绿灯组信息
typedef map<unsigned int, std::shared_ptr<PatrolPoint>> PatrolPointMap;
typedef map<unsigned int, std::shared_ptr<PatrolTask>> PatrolTaskMap;
typedef map<std::string, std::shared_ptr<PatrolTask>> PatrolTaskCheckMap;
typedef map<unsigned int, std::shared_ptr<PatrolPoint>> PatrolPointMap;
typedef map<unsigned int, std::shared_ptr<PatrolTask>> PatrolTaskMap;
typedef map<std::string, std::shared_ptr<PatrolTask>> PatrolTaskCheckMap;
typedef deque<std::shared_ptr<StorePostion>> QueStrorePos;
typedef map<std::string, std::shared_ptr<LeaderArrange>> LeaderArrangeMap;
typedef map<int,string> WorkTypePermissionMap;
typedef map<int,int> RulesMap; //lemon 2017/08/01
typedef map<int, std::shared_ptr<VehicleTypeAttRule>> VehicleTypeAttRuleMap;
typedef map<std::string,std::shared_ptr<CAL_DATA>> CardCalData;	//第一个元素string是卡号，第二个元素是此卡的校准数据
typedef map<int,std::shared_ptr<CardCalData>> CalDataMap;	//所有的校准数据，int为分站号，第二个元素是通过此分站要下发的所有卡的校准数据
typedef map<int,std::map<int,std::shared_ptr<Reader>>> BigSmallReaderMap;	//key为大分站信息，vector为此大分站下的所有大小分站信息

//typedef std::map<int,std::shared_ptr<MonkeyCarInfo>>  MonkeyCarInfoMap;
typedef std::map<std::string,std::shared_ptr<HandUpVehicle>> HandUpVehicleMap;
typedef std::map<int,std::shared_ptr<MovingReader>> MovingReaderMap;

typedef map<int,std::shared_ptr<CoalMiningArea> >  CoalMiningAreaMap;  //综采面区域信息
typedef map<int,std::shared_ptr<CoalMiningRegularCycle>> CoalMiningRegularCycleMap;//采煤机正规循环率计算参数，编号和参数
typedef map<int, int> CoalWorkfaceVehicleMap; // 采煤机工作面与车卡绑定表

typedef map<string, std::shared_ptr<Card>> CoalDrvingfaceCardMap;      // 采煤机/掘进机卡
typedef map<string, int> CardVehicleMap;  // 车卡和卡号对应表
typedef map<string, int> CardWorkfaceMap; // 车卡和工作面对应表

typedef map<int,std::shared_ptr<VehicleDriverPos>> VehicleDriverPosMap;
typedef map<int,std::shared_ptr<DeptVehicleDriver>> DeptVehicleDriverMap;
typedef map<int,std::shared_ptr<WorkfaceDriverAlarm>> WorkfaceDriverAlarmMap;

typedef struct key_value_pair
{
	int key;
	int value;
	struct key_value_pair* next;
}KeyValuePair;

typedef struct statistic_data_str
{
	int index;
	KeyValuePair* data_info; 
	struct statistic_data_str* next;
}StatisticDataStr;

struct DistQueMapItem
{
	WORD cardstamp;
	DistMap distmap;
};

struct MeetingInfo
{
	std::string keyValue; // 卡号组合，小号在前，0020000001011 0020000001022 - > 1011-1022
	std::string card_id_first; // 第一个卡号
	std::string card_id_second; // 第二个卡号
	double distance; // 两车之间的距离
	int reduce_counter; // 两车靠近计数器
};

typedef deque<DistQueMapItem> DistQueMap;
typedef map<std::string, MeetingInfo> MeetingInfoMap;
// 地图
class MapInfo{
public:
	MapInfo(void);
	~MapInfo(void);
public:
	int map_id;
	string map_path; // 地图文件路径
	string map_name; // 地图名称
	double map_width; // 地图宽度
	double map_height; // 地图高度
	double map_scale; // 地图比例尺
	int map_type; // 地图文件类型，弃用

	AreaMap map_area_list; // 本地图上的区域列表
	ReaderMap map_reader_list; // 本地图上的分站列表
	ReaderMap map_ctrl_reader_list; // 本地图上的控制分站列表
	CardMap map_card_list_person; // 本地图上的人员列表
	CardMap map_card_list_vehicle; // 本地图上的车辆
	ChamberMap map_chamber_list; // 本地图上的硐室
	SectionMap map_section_list; // 本地图上的路段
	LightMap map_light_list; // 本地图上的交通灯
	LightGroupMap map_light_group_list; // 本地图上的交通灯灯组
};

class LandmarkInfo
{
public:
	int landmark_id; // 地标编号
	string landmark_name; // 地标名称
	int map_id; // 所属地图
	int area_id; // 所属区域
	double x;
	double y;
	double z;
};

class MapDirectionInfo
{
public:
	MapDirectionInfo(){};
	~MapDirectionInfo(){};
public:
	int map_direction_id; // 地图方向
	int map_id; // 地图编号
	int north_angle; // 当前地图向上方向与北方的夹角，用来判断当前地图哪个方向是北
};
// 区域
class Area  // 矩形
{
private:
	std::vector<std::string> split(std::string str,std::string pattern); // 将path分割成点集数组
	double get_vertex(std::string src); // 顶点
public:
	Area(void);
	~Area(void);
	void init_border(string sz_path); // 初始化边界
	bool is_in_polygon(_point p); // 判断点是否在多边形内
	bool is_special(); // 是否为特殊区域
public:
	int map_id;  // 所在地图
	int area_id; // 区域编号
	string area_name; // 区域名称
	string area_type_name; // 区域类型名称
	string path; // 多边形
	int area_type_id; // 所属区域类型
	/*
	*@brief
	是否为工作区域标识
	#define AREA_WORK_AREA      1 //工作区域
	#define AREA_NON_WORK_AREA  0 //非工作区域
	*/
	bool m_is_work_area;
	// 人员
	int over_count_person; // 最大人数
	int over_time_person; // 最大时长
	int under_count_person; // 最小人数
	int under_time_person; // 最小时长
	// 车辆
	int over_count_vehicle; 
	int over_time_vehicle;
	int under_count_vehicle;
	int under_time_vehicle;
	double over_speed_vehicle;		//区域车辆速度阈值

	int polygon_count; // 顶点个数
	_point* polygon; // 顶点数组

	// 区域人数
	int count_person; // 当前区域人数
	int count_vehicle; // 当前区域车数
	int count_card; // 当前区域卡数

	// 是否写考勤
	int is_att; // 0 停车场外，1 停车场内
	bool is_area_over_time_person; // 车辆超时
	bool is_area_over_time_vehicle; // 人员超时
	int count_area_over_time_person; // 超时人数
	int count_area_over_time_vehicle; // 超时车数
	time_t time_over_time_person; // 开始超时时间
	time_t time_over_time_vehicle; // 开始超时时间

	bool is_area_over_count_person; // 人员超员
	bool is_area_over_count_vehicle; // 车辆超员
	int count_area_over_count_person; // 人员超员数量
	int count_area_over_count_vehicle; // 车辆超员数量
	time_t time_over_count_person; // 开始时间
	time_t time_over_count_vehicle; // 开始时间

	// 区域为限制区域时有效
	bool is_area_forbidden_person; // 是否有人进入禁区
	bool is_area_forbidden_vehicle; // 是否有车进入禁区
	int count_area_forbidden_person; // 进入进入人数
	int count_area_forbidden_vehicle; // 进入进入车数
	time_t time_forbidden_person; // 开始时间
	time_t time_forbidden_vehicle; // 开始时间

	std::shared_ptr<CardMap> area_card_list_person; // 区域内的人员
	std::shared_ptr<CardMap> area_card_list_vehicle; // 区域内的车
	std::shared_ptr<CardMap> area_card_list_over_speed; // 区域内超速的车

	INT64 m_event_list[AREA_EVENT_COUNT]; // 保存事件Id
};


class WarningPoint
{
public:
	int warning_point_id;
	std::string warning_point_name;
	std::vector<NAMESPACE_POINT::point> vp;
	std::string to_string()
	{
		std::stringstream ss;
		ss<<"point_id:"<<warning_point_id<<" name:"<<warning_point_name;
		for (const auto &p:vp)
			ss<<"("<<p.x<<","<<p.y<<")";
		ss<<"-----";
		return ss.str();
	}
};

// 危险点定义
class DrivingfaceWarningPoint
{
public:
	int warning_point_id;  // 危险点编号
	string warning_point_name;
	int driving_face_id; // 掘进面编号
	float point_x; // 危险点位置
	float point_y;
	float point_z;
	float warning_threshold; // 报警门限（距离）
	int is_valid; // 危险点是否有效
};

class SpecialAreaEntry
{
public:
	SpecialAreaEntry(){}
public:
	double start_point_x;  // 特殊区域入口，对角线两顶点
	double start_point_y;
	double start_point_z;
	double end_point_x;
	double end_point_y;
	double end_point_z;
	int    special_area_id; // 特殊区域编号
	std::string car_type;
	int	   union_area_id;
};

class DrivingfaceRender
{
public:
	DrivingfaceRender(){}
public:
	INT    drivingface_id;
	INT    reader_id;
	double vertical_distance;
	double x;
	double y;
	double z;
};

// 工作面与卡绑定信息
class DrivingfaceCard
{
public:
	DrivingfaceCard():m_total_ref_point_dist(0.0){
		x = y = z = m_schedule_work_times = m_schedule_tunnelling_times = m_drifting_footage_unit = m_fOffset=0.0;
		drivingface_id = area_id = m_overcount = m_mapId = m_drivingface_type = m_relay_small_reader_id = m_small_reader_id = m_big_reader_id = 0;
		m_old_state = m_cur_state = false;m_sensor_id.clear();
		m_vt_ref_point_list.resize(0);
	}
	~DrivingfaceCard(){}
public:
	double x;
	double y;
	double z;
	INT drivingface_id;
	string card_id;
	INT area_id;
	float warning_threshold;
	int m_overcount;
	int m_mapId;
	int m_drivingface_type;
	int m_relay_small_reader_id;		//中继小分站
	int m_small_reader_id;				//小分站
	int m_big_reader_id;				//大分站
	int m_dept_id;						//部门
	double m_schedule_work_times;		//计划工作时长
	double m_schedule_tunnelling_times;	//计划排数
	double m_drifting_footage_unit;		//排数的间距
	bool m_old_state;					//之前的掘进机状态
	bool m_cur_state;					//当前的掘进机状态
	double m_driver_dist;   //工作面车和司机告警距离，米
	int  m_driver_dist_time;//工作面车司机的告警间隔。秒

	std::vector<op::point> m_vt_ref_point_list;
	double m_total_ref_point_dist;	//基准点之间的累计距离
	double m_fOffset;

	std::vector<int> m_sensor_id;
	struct TAirSensor{
		TAirSensor()
			:bigger(-1),count(0),sum(0),ct(-1),stime(0),flag(false),rid(0)
		{}
		void clear()
		{
			count=sum=0;stime=0;flag=false;
		}
		std::array<op::point,2> ant;
		std::array<double,2> dist;
		int8_t bigger;
		uint32_t count,sum;
		uint16_t ct;
		uint64_t stime;
		bool flag;
		uint16_t rid;
		std::list<double> his_data;
	};
	TAirSensor m_tas;
	bool timeout()
	{
		time_t t=time(NULL);
		return m_tas.flag && t-m_tas.stime>10*60;
	}
	bool check_location_reversal(std::string & str)
	{
		time_t t=time(NULL);
		time_t tval= t-m_tas.stime;
		bool f=false;
		if (tval !=0 && m_tas.sum*1.0/tval > 0.8 && m_tas.count*1.0/m_tas.sum <0.2)
			f=true;
		char buf[1024]={0};
		sprintf(buf,"[reverse_alarm_checking]%s,count:%d,sum:%d,val:%d,s:%.2f,v:%.2f,alarm:%d",
			card_id.c_str(),m_tas.count,m_tas.sum,tval,(m_tas.sum*1.0/tval),(m_tas.count*1.0/m_tas.sum),f);
		str=buf;
		return f;
	}
	void make_reverse_condition(int16_t antid,uint16_t ct,double d)
	{
		m_tas.dist[antid]=d;
		if(m_tas.ct == ct){
			m_tas.sum++;
			int b=-1;
			if (m_tas.dist[0]>m_tas.dist[1]) b=0 ;else b =1;
			if(b==m_tas.bigger) m_tas.count++; //合格的点
		}
		m_tas.ct = ct;
	}
	void set(const op::point &p0,const op::point &p1,int id)
	{
		int8_t b=0;
		m_tas.ant[0].set(p0);m_tas.ant[1].set(p1);
		op::point bp(x,y);
		double d0=bp.dist(p0);double d1=bp.dist(p1);
		if(d0>d1)b=1;else b=0;
		if (m_tas.bigger!=-1 && b!=m_tas.bigger){
			m_tas.count=m_tas.sum=0;m_tas.stime=time(0);
		}
		m_tas.bigger=b;m_tas.rid=id;
	}
	bool push(double d){
		bool f=true;
		m_tas.his_data.push_back(d);
		if (m_tas.his_data.size()==3){
			double da=0;
			for (const auto &d:m_tas.his_data){
				if(da>d || d-da<0.004){f=false;break;}
				da=d;
			}
			m_tas.his_data.pop_front();
		}
		else f=false;
		return f;
	}
	op::point &operator[](int i){return m_tas.ant[i];}
	const op::point &operator[](int i)const {return m_tas.ant[i];}
	void set_true(){m_tas.flag=true;m_tas.stime=time(NULL);}
	bool warning(){return m_tas.flag;}
	bool empty(){return m_tas.his_data.empty();}
	double back(){return m_tas.his_data.back();}
	void clear_sensor(){m_tas.clear();}
	int reader_id(){return m_tas.rid;}

};

// 自组网预置坐标
class Adhoc
{
public:
	Adhoc();
	~Adhoc();
public:
	int adhoc_id; 
	double x;
	double y;
	double z;
	int idx; // 节点级别
};

// 天线
class Antenna
{
public:
	Antenna(void);
	~Antenna(void);
public:
	int antenna_id;
	double antenna_x;
	double antenna_y;
	double antenna_z;
	double antenna_angle;
};

class BaseArea{
public:
	BaseArea(){
		m_nPolygonCount = 0;
		m_pPolygon = NULL;
	}
	~BaseArea(){
		if (m_pPolygon)
		{
			delete[] m_pPolygon;
			m_pPolygon = NULL;
		}
	}
public:
	int init_border(string path);
	bool IsInPolygon(_point p);
private:
	double GetVertex(std::string src); // 顶点
	std::vector<std::string> Split(std::string str,std::string pattern);
public:
	int m_nProperty;
	int m_nPolygonCount;
	_point* m_pPolygon;
};
// 区域边界定义
class BoundaryArea:public BaseArea{
public:
	BoundaryArea(){
		boundary_area_id = map_id = reader_id = 0;
		name = path = "";
	};
	~BoundaryArea(){};
public:
	int boundary_area_id; 
	int map_id;
	int reader_id;
	string name;
	string path;
};

// 分站
class Reader
{
public:
	Reader(void);
	~Reader(void);
public:
	int reader_id; // 分站号
	string reader_name; // 分站名称
	int device_type_id; // 设备类型，分站、通信分站、交通灯等
	int pos_state; // 位置状态 1井上，2井下
	string ip;
	double reader_x; 
	double reader_y;
	double reader_z;
	double reader_angle;

	double reader_interval_time; // 分站接收数据间隔，单位秒

	int map_id; // 所在地图
	int area_id; // 所属区域
	double map_scale; // 比例尺

	time_t rec_time; 
	time_t reader_time;		// 分站时间
	time_t lost_time;		// 丢失时间
	time_t last_send_time;	// 最后向前端发送时间
	int temperature;		// 温度
	int tick_count;			// 计数器
	int reader_state;		// 状态 0 正常, 1 故障
	int reader_state_old; 
	int dimension;			// 指定分站定位类型：一维定位，二维定位，三维定位
	int sync_level;         // 时间同步级别
	unsigned long long sync_rootId; // 时间同步主分站编号，用来区分同时存在多个主节点的情况

	std::shared_ptr<Antenna> ant[ANTENNA_COUNT]; // 天线数组
	std::shared_ptr<Adhoc>   adhoc[ADHOC_COUNT]; // 自组网设备数组
	map<int,_point> readerCoveragePath; // 分站覆盖范围，tof使用
	bool bIsInitCoverage;
	int m_nIsSpecial; // 是否为特殊分站，定位结果与分站间距4米以内，如果是特殊分站就将定位点定位在分站附近，否则抛弃计算结果
	bool init_ctrl_reader_state;	//当为控制分站时，第一次需要获得此控制分站下的红绿灯状态

	INT64 m_event_list[READER_EVENT_COUNT]; // 保存事件Id

	unsigned int reader_package_end_pos;				// 分站数据包结束位置
	std::string	last_parse_card_id;						// 解析的上一个卡号

	std::shared_ptr<BoundaryArea> pBoundaryArea; // 定位分站边界，用于二维定位分站

	bool is_parent;					// 是否为带ip的大分站
	unsigned int parent_anchor_id;  // 如果为不带ip的大分站或者挂载在大分站下的小分站，指出其所属大分站的id

	std::vector<TimePosition> m_vt_his_position;
	int is_simulation_card;			// 表示此分站是否可以模拟成车卡,1表示可以模拟车卡，0表示无法模拟车卡
	bool b_simulation_status;		// 分站模拟车卡的状态，为true，表示开始模拟，false表示分站结束模拟车卡
	time_t m_start_simulation_time;	// 小分站开始模拟车卡的时间
	uint8_t reader_dir;				// 分站方向，对于大小分站适用
	uint8_t relay_counts;			// 大小分站经过中继数

	bool m_bNeedPowerAlarm;			//是否需要分站电池供电告警功能
public:
	string get_state_text();		// 获取状态信息
};

class StorePostion
{
public:
	StorePostion(){
		x = y = z = 0;
		GetLocalTime(&save_time);
	};
	~StorePostion();

	double x, y, z;
	SYSTEMTIME save_time;
};


// 卡
class Card : public NAMESPACE_POINT::card_interface
{
public:
	//Card(void);
	~Card(void);
	Card(string cardid, int cardtype,double z_offset);

public:
	CRITICAL_SECTION m_csCard;
	bool m_bigCarFlag;
	double m_overSpeed;
	double m_overAreaSpeed;
	bool is_registered; // 是否注册，即是否录入数据库，没录入当误码判断，不处理
	virtual int push_optimized_data(NAMESPACE_POINT::loc_point&lp);
	virtual int getCardType();
	virtual bool smoothFlag();
	virtual bool getBigCarFlag();
	virtual const std::string& cardId();
	virtual const uint64_t CtTime();
	virtual const int getX();
	virtual const int getY();
	virtual double getv();
	virtual int getAreaId();
	virtual int getAcc();
	virtual void do_alarm(const std::size_t ow);
	virtual void PrintString(const std::string &&str);
	virtual const uint64_t  get_last_recv_time();
public:
	Fit fit_x; // 拟合的位置
	Fit fit_y;
	int card_type; // 卡类型 0x01人, 0x02车
	string card_id;
	int m_indexCardSpeed;//超速计数，超过一定次数报超速告警
	int m_indexCardSpeed_normal;//速度正常计数，超过一定次数再取消超速告警
	int m_indexMineOverSpeed;//超速计数，超过一定次数报超速告警
	int m_indexMineOverSpeed_normal;//速度正常计数，超过一定次数再取消超速告警
	// 人员
	int level_id; // 级别
	int worktype_id;// 工种lemon 2017/07/31 车辆为vehicle_type_id
	int vehice_type_id; // 几级别类型

	// 开机率相关
	boost::circular_buffer<int> m_cb_state;         // 存储硬件上传的开关机惯导标记
	bool m_bOpen;                                   // 采煤机/掘进机开机状态 
	time_t m_startup_time;                          // 采煤机/掘进机开机时间
	int m_nCardId;                                  // 卡号
	time_t m_lastrecv_time;                         // 上次收到的时间
	double m_fScheduleStartupTime;                  // 采煤机/掘进机计划开机时长
	std::vector<CoalFaceStartPos> m_vecLoc;         // 采煤机起刀位置历史轨迹

	/*
	*@brief
	一线工人或二线工人标识
	#define CARD_FRONT_LINE_WORKERS		1 //一线工人
	#define CARD_SECONT_LINE_WORKERS	2 //二线工人
	*/
	BYTE m_staff_type;

	// 人员、车辆
	int id; // 编号，人员或车辆
	int dept_id; // 部门
	int occ_id; // 职务id
	int group_id; // 班组	
	int need_display;// lemon 2071/08/01 是否在Web端显示
	int power_alarm_display;//lemon 2018/01/15 低电量告警标识，1推送 0不推送
	std::string vehicle_category_id;//lemon 2018/04/11 车辆的类型，人车料车特种车
	bool power_change_flag;//
	int shift_type_id; // 人员或者车辆执行的班次类型
	std::string m_staffName;
	std::string m_deptName;
	time_t		m_dbTimeInterval;
	string driver_id;	//如果是车辆，则有司机id
	int light_id; // 闯红灯的灯编号
	int shift_id; // 本次出勤所属班次
	SYSTEMTIME deal_time; // 最后处理卡逻辑时间
	SYSTEMTIME enter_area_time; // 进入区域时间
	//
	int m_indexForRcvOneReader;
	//driving face write database time
	ULONGLONG drive_face_location_write_time;
	ULONGLONG drive_face_location_end_time;
	//SYSTEMTIME down_time;
	time_t rec_time; // 最后接收时间
    time_t last_correct_position_info_time; // lyl temp add: 上一次解析位置信息成功的时间
    int data_source_al_route13; // lyl temp: 路径13连续累计次数
	time_t down_time; // 入井时间
	time_t att_start_time_latest; // 最近一次从无信号转为有信号的时间，有可能在考勤区域，有可能在非考勤区域 lihongzhen  2017/8/17 17:20
	time_t att_end_time_latest; // 最后一次从非考勤区域进入考勤区域的时间 lihongzhen  2017/8/17 17:23

	time_t up_time; // 升井时间
	time_t enter_reader_time; // 进入分站时间
	time_t low_power_time; // 电量低开始时间
	double x; // 定位坐标
	double y;
	double z;
	//查看掘进机变量是否为初始化值，如果是不进行插入库操作
	bool is_drivingface_Initialization;

	// 只有掘进机上的卡有效
	int driving_face_id; // 所属掘进面
	double driving_face_cur_shift_start_x; //cur shift start position
	double driving_face_cur_shift_start_y;
	double driving_face_cur_shift_start_z;

	double driving_face_cur_shift_x; //cur shift real point
	double driving_face_cur_shift_y;
	double driving_face_cur_shift_z;

	double drving_face_cur_shift_max_speed;

	double a; // 上次定位时的角度
	int t; // 上次定位时的时间戳
	double m_oldv;// lemon 2017/10/26
	double v; //速度
    double final_v; // 尽量做线程安全, 防止 v 中间计算值输出
	double mileage; // 里程，距离上次保存数据时的距离
	double z_offset; // 标识卡与分站天线的高度差
	bool init_postion; // 是否初始化了位置信息，算法中用到
	bool is_first_location; // 是否为第一次定位，算法中用到
	int is_driving_face_start; // 作为掘进机时，判读是否已启动

	double right_x,right_y,right_z;		//分别指卡位置右边偏移的x,y,z坐标
	double left_x,left_y,left_z;		//分别指卡位置左边偏移的x,y,z坐标

	double last_x; // 上次的定位位置
	double last_y;
	double last_z;

	double stored_x; // 存储到数据库中的位置
	double stored_y;
	double stored_z;

	double output_x; // 算法输出的位置
	double output_y;

	double last_vx; // 上次的速度
	double last_vy;

	int state;	// 0 正常， 共32bit,每个bit代表一个状态，从右起:
	// 第一位 0x01 井下超时, 第二位 0x02 区域超时, 第三位 0x04 超速, 第四位 0x08, 进入限制区域
	// 状态，故障、电量低等
	int state_moving; // 运动状态， 0 静止，1 运动, 2怠速
	int state_meeting; // 会车状态，与movingstate合并来表示 3会车，4结束会车，5超车

	// 电量低、 呼叫、呼救
	int status_over_time; // 0 未超时，1 超时
	int status_over_speed; // 0 未超速，1 超速
	int status_area_over_time; // 0 未区域超时， 1 区域超时
	int status_area_over_speed; // 0 未区域超速， 1 区域超速
	int status_area_forbidden; // 0 未进入限制区域， 1 进入限制区域
	int status_help; // 0 未呼救， 1 呼救， 2 已处理呼救
	int status_help_cancel; //cancle help request
	int status_call; // 0 未呼叫 1 呼叫
	int status_power; // 0 电量正常，1 电量低
	int status_lost; // 0 未进入盲区，1024 盲区状态

	int map_id; // 当前地图
	double map_scale; // 地图比例尺
	int map_id_old; // 上次测距所在地图
	int area_id; // 当前区域	
	int pre_area_id;

	bool m_area_changed; // 区域切换
	int landmark_id; // 地标信息
	double landmark_dis; // 与地标的距离
	int landmark_direction; // 所处地标的方向
	int reader_id; // 当前分站

	Reader* p_reader; // 最后一个接收本卡数据的分站，以程序处理的数据为准
	std::shared_ptr<ReaderPathMap> pTofReaderPathMap; // tof分站地图集
	std::shared_ptr<TDOAReaderPathMap> pTdoaReaderPathMap; // tdoa分站地图集
	map<unsigned long long,std::shared_ptr<_coordinate>> mp_dists_locate; // 参与算法计算的dist记录（解析得到的数据）
	_coordinate last_locate; // 上一次计算得到的位置
	_coordinate origin_locate; // 根据原始数据求出的定位解
	_coordinate error_locate; // 错误的定位解

	QueStrorePos _storepostions; // 算法存储的定位解
	DistQueMap _dists; // 算法所需的dist缓存队列
	unsigned short time_stamp_max; // 最大时间戳，即需要计算定位的时间戳
	unsigned short time_stamp_cal; // ct 值，计算位置坐标的ct值
	unsigned short time_stamp_cal_last; // 算法定位时间戳

	int m_nFilterType; // 滤波类型
	int m_nLastLocateT; // 最后定位的时间同步序号
	int m_nCalcSyncNum;	//卡在算法中的同步号，此同步号和卡的实时同步号并不一定一致
	int m_nSyncNumInList;	//从队列中取出的大于5的同步号
	int m_nStream;			//上行、下行
	int m_direction;    //正向 负向

	int m_nLightGroupId; // 灯组id

	int m_nMoveDirection;		//1为正向运动，-1为负向运动
	int m_nIsRailroad;			//是否为有轨车，0为无轨车，1为有轨车
	int m_nOutputPosState;		//0为正常输出中间坐标，1为输出靠左偏移坐标，2为输出靠右偏移坐标
	bool bIsBack; // 是否为后退

	bool bInSpecailArea; // 是否在特殊区域
	bool issent;		// true 已发送至客户端，false 新数据，需要发送至客户端
	bool issaved;		// true 已保存到数据库，false 生成新的考勤记录，需要保存到数据库
	bool isdealed;		// 已经处理
	bool isreceive;		// 接收到
	bool is_deal_by_algo;		//是否经过算法处理
	bool is_hist; // 是否为从历史数据中加载的数据
	bool m_bUseFilter; // 是否使用滤波
	bool isoutput;				//是否输出到json
	bool is_red_light; // 是否闯红灯
	bool is_mine_over_time;		// 是否井下超时
	bool is_mine_over_speed;    // 是否井下超速
	bool is_area_over_time;		// 是否区域超时, 区域超时分车辆超时、人员超时
	bool is_area_over_speed;	// 是否区域超速

	time_t time_area_over_time; // 区域超时开始时间
	time_t time_over_time;		// 井下超时开始时间
	time_t time_area_forbidden; // 进入限制区域时间
	time_t time_over_speed;		// 超速开始时间
	time_t time_area_over_speed; // 区域超速开始时间
	time_t time_low_power; // 低电量开始时间
	time_t time_red_light;		//闯红灯时间
	time_t last_locate_time;	// 最后定位时间

	void reset();				// 重置所有状态
	void resetAllBaseInfo();   //重置基本信息

	void set_reader(std::shared_ptr<Reader> preader);
	void add_dist(std::shared_ptr<_coordinate> dist);
	void cal_pos_by_cache(); // 利用缓存的数据计算位置
	int dist_cache_size(); // 获取缓存数据个数
	void remove_dist_head(); // 删除缓存队列中第一个元素
	string concat(int reader_id, int ant_id); // 把分站号和天线号拼成唯一标识
	time_t get_working_time(); // 获取工作时长
	int get_state(); // 设置电量状态
	int get_state_moving(); // 设置运动状态
	double get_speed(); // 获取速度
	void set_speed(double v); // 设置速度
	int get_effictive_dist_count(int offset = 0); // 获取参与算法的dist个数
	void set_reader_path(std::shared_ptr<ReaderPathMap> rpm, std::shared_ptr<TDOAReaderPathMap> trpm); // 设置地图集
	//int get_direction(double x1,double y1,double x2,double y2);
	void get_coordinate(); // 计算位置坐标，含算法
	void get_coordinate(int cnt);

	int const PosState(); // 井下井上状态
	void PosState(int val); // 设置井下井上状态
	void PosStateOld(int val); // 上一个井下井上状态，用来判断是否状态改变时比较
	bool is_pos_state_changed(); // 入\升井状态变化
	int const StateBiz(); // 设置业务状态

	int new_algo_tof_1d(int cnt);
	double CalculateX(int L1, int L2, int last_ct, int ct, double last_x, double dis1, double dis2, double last_dis1, double last_dis2, double next_dis1, double next_dis2);
	double Card::CalculateX(double L1, double L2, int last_ct, int ct, double last_x0, double dis1, double dis2, double last_dis1, double last_dis2, double next_dis1, double next_dis2);
	_point CalculateX(const AlgoParamData* pData,_coordinate& lc);
	int Sign(double x);
	DistQueMap::iterator get_iterator(DistQueMap::iterator it);

	INT64 m_event_list[CARD_EVENT_COUNT]; // 保存事件Id
public://lemon
	int m_warning_point_id;  // 最近的危险点
	bool m_isWarning; // 测距分站距离告警使用
	double m_minDistanceToWarningpoint; // 距离最近危险点距离
	double m_warning_threshold; //
	bool m_CardHasBeenInDrivingfaceAlarm; // 是否已发出靠近危险点告警
	int m_DrivingfaceAlarmFlag; // 非记录人员靠近掘进机告警
	int m_drivingface_index;    //与测距分站之间得距离统计参数
	int m_drivingface_index_del;
//由于目前告警模块限制，所以需要使用下面参数
	bool m_warning_point_alarm;
	double m_disToWarningPoint;
	int	   m_wp_id;
	int m_workface_index;    //与测距分站之间得距离统计参数
	int m_workface_index_del;
public:
	//add by zhuyf 2017/10/18
	int recevie_by_moving_reader;			// 针对人而言，统计被移动分站接收的次数
	int person_on_card;						// 人上车状态，0为下车，1为上车
	int satisfy_on_vehicle_counts;			// 人卡满足上车状态条件统计次数
	int satisfy_off_vehicle_counts;			// 人卡满足下车状态条件统计次数
	double relative_speed;					// 相对速度
	double min_distance;					// 最小距离，
	std::string possible_vehicle_id;			// 可能的车
	std::string vehicle_id;					// 针对人卡而言，目前人卡在哪辆车上

	std::shared_ptr<CardMap> mp_person_in_vechicle_list;	// 针对车而言，统计已上车的人员列表

	bool package_is_over;		//分站内此卡的数据包解析完，解析完即可调用算法进行计算		
	bool no_need_add_dist;		//不需要加入到_dists队列中

	double recv_signal_power; // 接收的信号强度
	
public:
	//线性拟合使用
	unsigned long long  m_ct_time; // 接收时间，用来计算时间间隔，求速度
	
	int m_positon; 
	ULONGLONG m_getOnTime;

public:
	CardMap mp_list_over_count; 
	//lemon 2017/08/01
	inline double getDrivingfaceCulValue(){return m_drivingface_distance_cul_values;}
	inline double getDrivingfaceLimitValue(){return m_drivingface_distance_limit_values;}
	inline void	 setDrivingfaceCulValue(double cvalue){m_drivingface_distance_cul_values = cvalue;}
	inline void  setDrivingfaceLimitValue(double lvalue){m_drivingface_distance_limit_values = lvalue;}

	//lemon 2017/08/16
	double m_drivingface_start_x;
	double m_drivingface_start_y;
	double m_drivingface_start_z;
	std::string m_drivingface_start_time;

	double m_curshift_finish_length;
	double m_cur_total_finish_length;
	//lemon 2017/09/22  出井补全区域信息
	string store_data_card( int tag,double x =0,double y =0);

	//zhuyf 2018/08/30
	double m_max_distance;	//与小分站或大分站的最远测距距离
	op::point m_max_p;		//最远距离的定位点坐标
	time_t m_record_cycle_start_time;	// 记录周期的开始时间
	double m_record_avg_dist;		//周期内距离信息的平均值
	double m_record_min_dist;		//周期内最小距离值
	double m_record_max_dist;		//周期内最大距离值
	unsigned int m_record_totals;	//总记录条数
	bool m_b_first_record;	//
	std::string m_str_record;	//
	std::vector<TimePosition> m_cb_position;	//存储一分钟内点的坐标；
	op::point m_base_position;
	bool m_b_first_calc;
private:
	double m_drivingface_distance_cul_values;
	double m_drivingface_distance_limit_values;
public:
	//算法相关参数及函数
	bool is_algo_first_location;		//表示算法的第一次定位
	bool is_idling; // 是否为怠速状态
	bool is_del_data; //是否删除数据
	int idle_count; // 连续判断为怠速状态的次数，超过次数阈值则将速度置为0
	int ins_req_status_algo;	//算法惯导状态

	DistMap dist_1d; // 不同计算方式的缓存dist
	DistMap dist_2d;
	DistMap dist_3d;
	DistMap distmap;

	std::shared_ptr<nspLocate::LocateRecord> locate;
	std::list<std::shared_ptr<POS>> idle_pos_list; // 怠速判断位置列表

	//2017/11/28 add by zhuyf
	std::shared_ptr<Tdoa::TaylorWls> pTaylorWls;
	std::vector<std::shared_ptr<HostServer::Position>> avg_coordinate;	// 在tdoa二维定位时：统计前5个点的坐标用于算平均坐标，当第六个点开始才使用加速度或速度过滤
	bool is_use_acc_filter;

	std::shared_ptr<algorithm::base::SensorManager> pSensorManager;
	algorithm::base::Sensor<double>* pAcceSensor;
	algorithm::base::Sensor<double>* pGyroscopeSensor;

	void algo_tof(int cnt);
	int  algo_tof_1d(int cnt);		// tof一维定位
	int  algo_tof_2d(int cnt);		// tof二维定位
	int  algo_tof_3d(int cnt);      // tof三维定位

	//tdoa算法
	void  algo_tdoa(int cnt);
	int  algo_tdoa_1d(int cnt);		// tdoa一维定位
	int  algo_tdoa_2d(int cnt);		// tdoa二维定位
	int  algo_tdoa_3d(int cnt);		// tdoa三维定位
	
	int inspect_coordinate(int acce_state); // 拟合位置

	int save_card_data(); // 为标识卡变量赋值
	void algo_calc_offset();		//计算偏移坐标

	double x_offset_after();        //返回偏移后的X坐标
	double y_offset_after();        //返回偏移后的Y坐标
	double z_offset_after();        //返回偏移后的Z坐标
	bool algo_is_same_direction(double x,double y,double z);	//检查此次方向

	int CheckDistData(int cnt);
	int AssembleDistData(std::shared_ptr<ReceiveDataMap> pRdm);		//tdoa组装数据
	int AssembleDistData(map<unsigned long long, std::shared_ptr<_coordinate>>& p_dist_locate);	//tof组装数据
	int GetDeltaT(map<unsigned long long,std::shared_ptr<_coordinate>> dl); // 获取两次定位之间的时间差
	int SaveCardAlgoData(std::shared_ptr<POS>& pos); // 保存算法计算结果变量
	int SaveTofData(const std::shared_ptr<POS> pos);  // 保存tof算法计算结果变量
	int SaveTdoaData(const std::shared_ptr<POS> pos);  // 保存tdoa算法计算结果变量
	int SaveOriginDataBeforeFilter(std::shared_ptr<POS> pos); // 保存算法滤波前的计算的结果变量
	int ChooseOneSolution(std::shared_ptr<ReceiveDataMap> pRdm, std::vector<std::shared_ptr<POS>> udm_pos, std::shared_ptr<POS>& pos);// 输出唯一解
	int calibration_pos_data(std::shared_ptr<POS> pos);			//校验坐标数据，并将结果保存到pos中

	int optimization_pos(std::shared_ptr<POS> pos);				//优化定位坐标
	int kalman_filter_process_tdoa(std::shared_ptr<POS> pos); // tdoa滤波
	int kalman_filter_process_tof(std::shared_ptr<POS> pos);  // tof滤波
	int position_data_filter_by_direction(std::shared_ptr<POS> pos,map<unsigned long long, std::shared_ptr<_coordinate>>& p_dist_locate);	//通过与同一分站两天线原测距方向进行比较判断结果是否符合预期

	int CheckSolution(std::shared_ptr<POS>& p);					// tdoa 一维定位使用：验证唯一解合法性，如速度、加速度
	void saveToSyncNumDataList(int sync_num, double pixelX, double pixelY, double speedX, double speedY, bool updated); // 通过校验后的数据, 保存到 m_syncNumList 容器
	int CheckSulutionByStream(std::shared_ptr<POS> p);			// 参数使用非引用，即不可修改其值
	int GetStream(double x1,double y1,double x2,double y2);		// 获得上下行方向

	int get_direction(double x1,double y1,double x2,double y2); //获得正向，方向
	int CalcPositionBySpeed(std::shared_ptr<POS>& pos,double v); // 通过速度计算位置
	bool CheckStreamUniformity(double x1,double y1,double x2,double y2,int nStream); // 检查当前定位坐标和nStream方向是否一致
	bool IsExistPath(int left,int right); // 判断两个分站之间是否存在地图集，用于tdoa算法
	int CopySolution(std::shared_ptr<POS> source,std::shared_ptr<POS>& dest); // 拷贝解

	//std::shared_ptr<nspLocate::LocateRecord> locate;
	bool IsIdleStatus(std::shared_ptr<POS> pos); // 判断是否为怠速状态
	bool IsRebound(std::shared_ptr<POS> pos);		//判断是否回退
	virtual bool CheckPositionValid(const std::shared_ptr<POS> pos);		//检查解的有效性
	bool CheckPositionValid(const double& x,const double& y);
	double GetDeltaT();		//获取时间差值

	int get_dimension(); // 获取定位类型，是一维、二维、三维
	int split_dist_data(); // 分割dist记录
	int deal_position_boundary(_point& p);		//处理二维边界处理问题
	bool position_is_in_boundary(_point p);		//检查点p是否在边界e
	_point mapping_position_to_boundary(_point p); //映射此点到边界上的点

	int check_solution_tdoa_2d(std::shared_ptr<POS>& p);
	int save_tdoa_data_2d(std::shared_ptr<POS>& p);		//tdoa二维定位保存数据
public:
	//tof相关变量及函数
	time_t time_cur_algo;				// dist数据进缓存队列的时间
	time_t time_last_tof;				// 上次tof定位的时间
	int reader_id_algo;					// 算法计算时的分站号
	bool is_send_ins_check;

	int  get_position_by_one_distance(std::shared_ptr<TOFReaderPathMap> trpm,std::shared_ptr<POS>& pos,const TOF_REFER_DATA refer_data);
	bool CheckSolutionTof(std::shared_ptr<POS>& pos);		//通过速度及加速度检查定位结果是否正确
	int  get_ref_data_from_dists(map<unsigned long long, std::shared_ptr<_coordinate>> tmp_dists_locate,const int& key,TOF_REFER_DATA& refer_data);

private:
	void set_reader_path_tof(std::shared_ptr<ReaderPathMap> rpm);			// 设置tof路径集
	void set_reader_path_tdoa(std::shared_ptr<TDOAReaderPathMap> trpm);		// 设置tdoa路径集
public:
	list<sync_data> m_syncNumList;
	std::list<std::shared_ptr<POS>> his_idle_pos;

	bool b_long_interval;	//上一次定位的间隔时间差大于10s
	int diff_direction_counts; // 连续反向运行次数
	int maxSyncTimes; // 分站时间同步最大时间戳
public:
	// 滤波算法相关
	std::unique_ptr<CKalmanFilter> m_pKalmanFilter;

	int acce_cur_state;		//在算法中保存当前加速度状态，保存这两个值的原因是在多线程情况下accelerate_state和accelerate_state_last状态可能变化
	int acce_last_state;	//在算法中保存上一次加速度状态

	double ins_weight;	//加速度计状态权重
	double uwb_weight;	//uwb状态权重

	std::list<double> vt_his_speed;

	int FindDistMap(int cardstamp); // 查看dist缓存中是否有此相同ct的数据
	int KalmanFilterProcess(std::shared_ptr<POS>& pos); // 滤波过程

	void EnableFilter(int nType); // 启动滤波
	
	bool isRebound(std::shared_ptr<POS> pos);			//判断是否回跳
public:
	bool b_save_pos;
	//在长时间无法定位的情况下使用拟合算法输出点
	std::list<std::shared_ptr<POS>> his_pos;	//保存之前5个点的信息

	bool is_ref_pos;		//判断是否作为参考点
	bool is_fit_pos;
	bool have_fit_pos;
	bool have_long_fit_pos;
	bool is_over_interval;		//用于保存modify_card_speed中当前时间和卡的最后接收时间的是否超过指定时间的状态

	int count_idle;			//统计坐标连续有多少次没变化了，用于判断车辆是否怠速，统计5次
	int cur_fit_nums;		//当前拟合次数，当有新数据放入his_pos即重置它
	int cur_ref_totals;
	int count_change_direction; // 统计方向改变后的的连续定位次数，大于3次，改变行驶方向。

	double fitting_v[REF_POSITION_NUM];
	double fitting_ct[REF_POSITION_NUM];
	double fitting_x[REF_POSITION_NUM];
	double fitting_y[REF_POSITION_NUM];

	double fit_new_x[FIT_POSITION_NUM];
	double fit_new_y[FIT_POSITION_NUM];

	//第二种拟合
	std::list<std::shared_ptr<POS>> long_his_pos;	//保存之前20个点的信息，此信息必须是UWB定位信息
	double long_fitting_ct[REF_POSITION_NUM];
	double long_fitting_x[REF_POSITION_NUM];
	double long_fitting_y[REF_POSITION_NUM];
	double long_fit_new_x[FIT_POSITION_NUM*4];
	double long_fit_new_y[FIT_POSITION_NUM*4];

	int UpdateFittingData(std::shared_ptr<POS> pos);	//更新拟合基础数据
	int CalcFittingData(list<std::shared_ptr<POS>> & list_pos);								//计算拟合数据
	//double CalcFittingData_ForMonkeyCar(list<std::shared_ptr<POS>> & list_pos);
	//int GetStream_Monkeycar(double x1,double y1,double x2,double y2);
	int CalcLongFittingData();
	int CalcFittingData(int ret,std::shared_ptr<POS>& pos);	
	int CalcLongFittingData(int ret,std::shared_ptr<POS>& pos);	
	int GetPosFromFittingData(std::shared_ptr<POS>& pos); 
	std::shared_ptr<POS> GetPosFromFittingData();						//从拟合数据获取定位坐标
	int CheckSolutionByFit(int ret,std::shared_ptr<POS>& pos); // 利用拟合数据验证解的合法性
	int CheckSolutionBySpeed(std::shared_ptr<POS>& pos); // 利用速度验证解的合法性
    bool need_reset;// temp add by lyl: 算法是否需要重置
    int cell_station_error_num; // temp add by lyl: 跨基站处理异常
    int speed_limit_after_reset;  // temp add by lyl: 重置后, 对拟合算法计算出的速度值做管控

	bool CheckCardCtValid();	//检查卡的ct有效性
public:
	int state_biz;					//业务状态，呼叫/超时/进入禁区等
	int pos_state;					// 位置状态，0初始化，1井下，2井上，3车场分站
	int pos_state_old;
	int pos_state_count;			// 当前位置状态确认次数
	int pos_state_confirm_times;	// 井下、井上状态确认次数，默认为1

public: 
	// 采集到的底层数据
	unsigned short time_stamp_last;		// 定位时间戳
	
	int accelerate_state_last;	// 上一次加速度状态
	int power_state_last;		// 电量
	int ins_direction;			// 上一次的惯导合成方向
	int reader_tickcount;		// 分站发送数据的计数次数
	unsigned short time_stamp;	// 定位时间戳
	unsigned short time_center_stamp;	// 定位时间戳
	int ranging_type;			// 报文类型 tof，tdoa
	int accelerate_state;		// 加速度
	int antenna_id;				// 天线号
	int power_state;			// 电量
	int sync_num;				// 分站同步序号
	int n_pos_no_change_times;  // lihongzhen  2017/8/19 位置连续未变化次数
	bool b_pos_change;			// 位置发生了改变
	bool b_enter_intersection;	// 车辆是否进入过路口区域
	int strength;				// 信号强度

	double antenna_angle;		// 天线角度
	double distance;			// 距离
	int64_t flying_time;		// 飞行时间
	
	string str_his_time; // 分站接收到卡时的时间
	string str_rec_time; // 采集程序接收到数据的时间
public:
	//呼叫信息
	int call_type_id; // 呼叫类型，全员、定员
    int call_type; // 呼叫级别 一般、紧急
	std::vector<int> vt_deal_call_reader_id; // 呼叫到卡的分站列表
	time_t recv_call_time;	//卡接收到呼叫的时间戳

public:
	//惯导数据
	//tof中惯导数据
	int ins_request_check;							//uwb带惯导数据的协议中惯导请求校准状态值，0为正常，1为请求校准
	int ins_cal_type;								//下发校准类型：0下发校准角度和坐标，1下发校准坐标，2下发校准角度
	bool is_check_ins;								//是否已校准惯导数据
	double ins_gyp_angle;							//校准后的陀螺仪角度
	std::shared_ptr<POS> cur_ins_pos;				//惯导上传的坐标
	std::shared_ptr<POS> ins_gyp_pos;				//校准后的惯导初始坐标
	std::list<std::shared_ptr<POS>> lt_uwb_pos;		//存储校准两时刻的uwb定位数据
	std::list<std::shared_ptr<POS>> lt_ins_pos;		//存储校准两时刻的ins定位数据


	int deal_ins_cal_data();				//处理惯导数据校准
	int calc_slope(std::shared_ptr<POS> start,std::shared_ptr<POS> end,double & slope);
public:
	//测试及统计功能
	AlgoFailedMsg m_afmData;
	//add by zhuyf 2018/06/28
	//由于测试卡会发呼救，针对600以上卡不许其发送呼救
	bool is_no_send_help;			

public:
	//测试参数及相关函数
	int OutputCmdLog(int n);

	double dTestDelatT;		//测试时间差
	double dTestDistance;		//测试两次的定位的距离差
    //position_optimizer
 //   virtual std::string get_id();
//	virtual unsigned long long get_m_ct_time();
public: 
	// lihongzhen  2017/9/25 原滤波算法
	CalLocation* cal_location; // 二维定位算法
	Point2* p2_anchors; // 二维定位解

	CalLocation3* cal_location3; // 三维定位算法
	Point3* p3_anchors; // 三维定位解

	std::shared_ptr<_coordinate>* p_dists;
	std::shared_ptr<_coordinate>* p_dists_locate;
	bool is_init_kalman; // 是否已初花滤波状态

	void add_dist_ex(std::shared_ptr<_coordinate> dist);
	void resetKalmanInfo(); // 重置旧版kalman滤波定位相关信息


	bool is_anchor_changed; // 定位的分站有没有变化，如果变化了，需要重置状态矩阵
	void get_coordinate_old(int cnt); 
	void get_coordinate_2d(int cnt); // 二维定位算法,带滤波
	void get_coordinate_2d_nofilter(int cnt); // 二维定位投影算法求解
	void get_coordinate_3d(int cnt); // 三维算法求解，带滤波
	void set_anchors(int cnt); // 设置参与定位的分站位置
	int get_effictive_dist_count_ex(); // 获取有效参与定位算法的dist记录数

	virtual int algo_tof_raw_1d(const DistMap& dm);
	virtual const std::vector<std::shared_ptr<_coordinate>> calc_locate_tof_raw_1d(map<unsigned long long, std::shared_ptr<_coordinate>> p_dists_locate) const;
	virtual int get_antenna_xyz(int reader_id, int antenna_id,double& x,double& y, double& z);
	virtual int get_key(double x, double y, double& key);

public:
	std::weak_ptr<card> m_card_ptr;
	inline void set_card_Ptr(std::shared_ptr<card>  ptr)
	{
		m_card_ptr = ptr;
	}

	inline void resetPtr(){m_card_ptr.reset();}
	//防追尾
	double m_arg;//0x12345678
	void make_arg();
	uint64_t m_last_time;
	NAMESPACE_POINT::line_v m_line;
public:
	//三率开发
	double m_schedule_work_time;	//采煤机计划工作时长
	double m_schedule_mine_times;	//采煤机计划刀数
	double m_work_face_width;		//采煤机所在工作面的宽度

	void calc_tunnel_boring_machine_pos(const op::point& p);
};

// 班次
class BanShift
{
public: 
	BanShift();
	~BanShift();
	BanShift(int id, std::string s, std::string e, int tid);
	int shift_id; // 班次编号
	int shift_type_id; // 班制编号
	std::string start_time; // 班次开始时间
	std::string end_time; // 班次结束时间
};

// 领导带班
class LeaderArrange
{
public:
	LeaderArrange( string cardid);
	~ LeaderArrange();

	int staff_id; // 员工编号
	string card_id; // 标识卡号
	int shift_id; // 班次
	int shift_type_id; // 班制
	time_t starttime; // 班次开始时间
	time_t endtime; // 班次结束时间
};

// 部门
class Dept
{
public:
	Dept(){};
	~Dept(){};
	Dept(int id, string name);
private:
public:
	int dept_id;
	string dept_name;

	CardMap dept_card_list_person;
	CardMap dept_card_list_vehicle;
};

// 职务级别
class OccLevel
{
public:
	OccLevel(){};
	~OccLevel(){};
	OccLevel(int id);
private:
public:
	int occlevel_id;

	CardMap level_card_list_person;
	CardMap level_card_list_vehicle;
};

/*
* 地图集路径描述
*/
class ReaderPath{
public:
	ReaderPath(){
		bIsInit = false;
		nRealCalcPoints = 0;
		x[0] = x[1] = y[0] = y[1] = 0;
		for(int i = 0;i < MAX_CALC_POINTS;i++){
			px[i] = py[i] = pz[i] = 0;
		}
	}
public:
	//对于TOF而言，x,y表示1,2天线对应的坐标
	//对于TDOA而言，x,y表示焦点F1,F2（等同于分站i,i+1）的坐标
	int nRealCalcPoints;
	double x[2];
	double y[2];
	double z[2];
	double px[MAX_CALC_POINTS];
	double py[MAX_CALC_POINTS];
	double pz[MAX_CALC_POINTS];

	bool bIsInit;
};

//红绿灯
class Light{
public:
	int m_nID;			//红绿灯id
	int m_nMapID;		//地图id
	int m_nReaderID;	//传输分站id
	int m_nAreaID;		//区域id
	int m_nSectionID;	//路段id
	int m_nLightsGroupID;		//红绿灯组id
	int m_nPort;		//与分站之间通信的路数
	int m_nState;		//红绿灯是否可用状态，0可用，1不可用
	int m_nOldState;
	int device_type_id;	//设备类型

	double x;	//x坐标
	double y;	//y坐标
	double z;	//z坐标

	std::string m_strIP;	//红绿灯ip
	std::string m_strName;	//红绿灯名字
	std::string m_strLabel;

	time_t rec_time;
	time_t last_send_time;
public:
	Light();
	~Light(){}
public:
	int get_light_state();

public:
	int m_nStream;		//0为上行，1为下行
	
	int m_nColor;		//0x01 红色, 0x02 绿色
	int m_nShape;		// 形状 0x01 实心圆形，0x02 空心圆形，0x03 叉形，0x04 - 0x07 上下左右箭头，0xFF 警告闪烁
	int m_nStateBiz;	//0为正常，1为网络故障，2为控制失败，3为灯故障
	int m_nIsCtrl;		// 设备控制状态 0x01 自动控制，0x02手动控制

	time_t alarm_start_time;
};

//闯红灯参数
struct RunRedLight
{
	//当前灯组亮绿灯的灯号，
	int32_t m_group_id;
	//当前灯组亮绿灯的灯号，
	int m_light_id;
	//车辆id，
	int m_vehicle_id;
	//区域id，
	int32_t m_area_id;
	//闯红灯时间
	std::string m_time;
};
// 灯组
class LightsGroup{
public:
	int m_nID;
	int m_nState;

	bool m_bIsUsed;

	std::string m_strName;
	std::string m_strLabel;
public:
	int m_nSectionId;		//灯组所在的路口区域
	std::string m_strVechileId;		//控制此灯组的车辆id
	map<int,std::shared_ptr<Light>> mp_lights_list;
public:
	LightsGroup();
	~LightsGroup(){};

public:
	bool isExist(std::shared_ptr<Light> pLight);
	bool isAllLightColor(int nColor);
};

//硐室
class Chamber:public BaseArea{
public:
	int m_nID;	//硐室编号
	int m_nState;		//使用状态，特指此硐室是否处于可用
	int m_nIsUsed;		//硐室内是否有车
	int m_nSectionID;	//硐室所属路段ID
	int m_nMapID;		//硐室所属地图ID

	std::string m_strPath;	//硐室区域
	std::string m_strName;	//硐室名称
	std::string m_strLabel;	//硐室描述

public:
	Chamber();
	~Chamber();
};

//路段
class Section:public BaseArea{
public:
	int m_nID;
	int m_nMapId;

	std::string m_strPath;
	std::string m_strName;
	std::string m_strLabel;
public:
	int m_nState;	//0---正常，1---繁忙，2---拥堵

	time_t alarm_start_time;

	ChamberMap mp_champer_list;
	LightMap mp_light_list;
	CardMap mp_vehicle_list;
	CardMap mp_staffer_list;

	INT64 m_event_list[SECTION_EVENT_COUNT];
public:
	Section();
	~Section(){}

public:
	bool is_has_chamber();		//是否有未使用的躲避硐室
	int get_section_state();	//路段状态
	int get_section_vehicle_counts();	//路段内车辆总数
	int get_section_staffer_counts();	//路段内人员总数
};

// 巡检任务
class PatrolTask
{
public:
	PatrolTask();
	~PatrolTask();

private:
public:
	int patrol_task_id; // 巡检任务编号
	int patrol_path_id;  // 巡检路径编号
	string card_id; // 卡号
	string starffer_id; // 员工号
	time_t start_time; // 开始时间
	time_t end_time;  // 结束时间
	PatrolPointMap mpPoint; // 巡检点列表

	bool is_in_cur_point; // 是否处在当前点位置
	int cur_point_idx; // 当前巡检点索引
	int state; // 巡检状态
	int stay_state; // 停留时长状态
	int duration_stay; //停留时长
	time_t enter_time; // 进入该节点时间
	time_t leave_time; // 离开当前节点时间
};

// 巡检点
class PatrolPoint
{
public:
	PatrolPoint();
	~PatrolPoint();
private:
public:
	int idx; // 在路径中的索引
	int patrol_point_id;
	int map_id;
	double x; // 区域范围圆心
	double y;
	double z;
	double ranging; // 距离范围

	int duration_last;  // 距离上个节点时长
	int duration_stay_min; // 本节点最小时长
	int duration_stay_max;  // 本节点最大时长
	int duration_ranging; // 距离上个节点时长最大偏差，含正负
};

enum EVENT_TYPE{ // 事件类型
	ET_UNKNOWN = 0,
	ET_OVER_COUNT_PERSON = 1, // 井下人员超员mp_card_list_over_count_person
	ET_OVER_COUNT_VEHICLE = 2,    // 井下车辆超员mp_card_list_over_count_person

	ET_AREA_OVER_COUNT_PERSON = 3,	// 区域人员超员
	ET_AREA_OVER_COUNT_VEHICLE = 4,	// 区域车辆超员

	ET_SECTION_OVER_COUNT = 5, // 路段拥堵

	ET_READER_ERROR = 6, // 分站通信异常
	ET_CTRL_READER_ERROR = 7, // 控制分站异常
	ET_LIGHT_ERROR = 8, // 交通灯异常
	ET_READER_CALL = 9, // 分站呼叫标识卡
	ET_READER_CALL_CANCEL = 10, // 取消呼叫分站

	ET_CARD_LOW_POWER = 11, // 电量低
	ET_CARD_LOW_POWER_SERIOUS = 12, // 电量极低

	ET_CARD_OVER_TIME_PERSON = 13, // 人员井下超时mp_card_list_over_time_person
	ET_CARD_OVER_TIME_VEHICLE = 14, // 车辆井下超时mp_card_list_over_time_vehicle
	ET_CARD_AREA_OVER_TIME_PERSON = 15, // 人员区域超时
	ET_CARD_AREA_OVER_TIME_VEHICLE = 16, // 车辆区域超时
	ET_CARD_AREA_LIMIT_PERSON = 17, // 人员进入限制区域
	ET_CARD_AREA_LIMIT_VEHICLE = 18, // 车辆进入限制区域
	ET_CARD_AREA_FORBIDDEN_PERSON = 19,  // 人员进入禁止区域
	ET_CARD_AREA_FORBIDDEN_VEHICLE = 20, // 车辆进入禁止区域
	ET_CARD_OVER_SPEED = 21, // 车辆超速
	ET_CARD_AREA_OVER_SPEED = 22, // 车辆区域超速
	ET_CARD_RUN_THE_RED_LIGHT = 23, // 车辆闯红灯
	ET_CARD_HELP = 24, // 人员呼救
	ET_CARD_CALLED = 25, // 人员已被呼叫
	ET_CARD_PATROL_ERROR = 26, // 人员巡检异常
	ET_CARD_LOST = 27, // 标识卡信号丢失
	ET_CARD_DRIVINGFACE_WARNING_AREA = 28,  // 掘进面靠近预警区域告警
	ET_CARD_NEAR_DRIVINGFACE_VEHICLE=29,// 人员靠近掘进机告警
	ET_CARD_NEAR_DRIVINGFACE_OVERCOUNT=30,//掘进机附近人员超员
	ET_UWB_MORE_CARD = 31,
	ET_CARD_MOTIONLESS=32,
	ET_READER_POWER_BY_BATTERY=33,		//分站电池：1为电池供电，0为交流电供电，当电池供电需要告警
	ET_VEHICLE_REAR_END=36,				//车辆追尾告警
	ET_COALING_DRIVING_DRIVER=37,		//工作面(采煤面和掘进面)司机与车卡告警
	ET_VEHICLE_NEAR_GEOFAULT=38,		//靠近断层告警
	ET_READER_LOCATION_REVERSAL=39,     //天线定位反向告警
	ET_RUN_RED_LIGHT=40,     //天线定位反向告警
	CARD_EVENT_COUNT_MAX,
};

enum OBJECT_TYPE // 对象类型
{
	OT_MINE = 1, // 矿井
	OT_AREA = 2,  // 区域
	OT_SECTION = 3, // 路段
	OT_DEVICE_READER = 4, // 分站
	OT_DEVICE_LIGHT = 5, // 交通灯
	OT_DEVICE_ctrl_reader = 6, // 控制分站
	OT_DEVICE_LED = 7, // led屏
	OT_DEVICE_SPEAKER = 8, // 防爆音箱
	OT_CARD = 9, // 标识卡，包括人员、车辆、自组网等
	OT_DRIVINGFACE_AREA=10,
	OT_UWB_MORE_CARD=11,
};

enum EVENT_STATUS{ // 事件状态
	ES_START = 0, // 事件开始
	ES_DEAL_HELP = 1, // lihongzhen  2017/8/19 呼救已处理状态 
	ES_END = 100 // 事件结束
};

enum REQUEST_COUNTS_TYPE{
	REQUEST_ALL = 0,
	REQUEST_ALL_OVER_TIME_PERSON,
	REQUEST_AREA_OVER_TIME_PERSON,
	REQUEST_SPECIAL_ERROR_PERSON,
	REQUEST_ALL_OVER_TIME_VEHICLE,
	REQUEST_AREA_OVER_TIME_VEHICLE,
	REQUEST_ALL_OVER_PERSON,
	REQUEST_AREA_OVER_PERSON,
	REQUEST_ALL_OVER_VEHICLE,
	REQUEST_AREA_OVER_VEHICLE
};

// 告警事件
class YaEvent
{
private:
	INT64 ev_id;
public:

	YaEvent(){};
	YaEvent(INT64 e_id){
		ev_id = e_id;

		obj_id = "";
		cur_time = time(NULL);
		map_id = 0;
		area_id = 0;
		x = 0;
		y = 0;
		limit_value = 0;
		cur_value = 0;
		desc = "";
		landmarkid = 0;
		landmarkdirect = 0;
		landmarkdist = 0;
	};
	~YaEvent(){};
public:
	EVENT_STATUS status; // 告警状态，开始、结束

	EVENT_TYPE ev_type; // 告警类型
	OBJECT_TYPE obj_type; // 告警对象类型
	std::string obj_id; // 告警对象编号，与告警对象类型对应，如告警对象类型为分站，此字段为分站编号
	time_t cur_time; // 当前时间，为告警事件的触发时间，如果状态为开始，则表示开始时间，否则为结束时间

	int map_id; // 告警所在地图
	int area_id; // 告警所在区域
	double x; // 位置
	double y;	
	double limit_value; // 告警阈值
	double cur_value; // 当前值
	std::string desc; // 描述
	int landmarkid; // 告警地标位置描述
	int landmarkdirect;
	int landmarkdist;

	bool is_sent; // 已发送

	INT64 get_id(){return ev_id;};
};

// 控制灯信息
class LightCallInfo{
public:
	LightCallInfo(){
		light_id = 0;
		ctrl_type = 0;
		ctrl_color = 0;
		light_state = 0;
		task_id = "";
	}
public:
	int light_id; // 灯编号
	int ctrl_type; // 控制类型，自动、手动
	int ctrl_color; // 显示颜色
	int light_state; // 灯状态
	std::string task_id;
};

enum DIRECTION_TYPE{
	NODIRECTORY = 0,
	EAST = 1,
	SOURTH = 2,
	WEST = 3,
	NORTH = 4
};

// 车辆考勤规则
class VehicleTypeAttRule
{
public:
	VehicleTypeAttRule(int vtid, int pre, int back);
	~VehicleTypeAttRule();

	int vehicle_type_id; // 车辆类型编号
	int offset_pre; // 考勤向前偏移时间
	int offset_back; // 考勤向后偏移时间
	std::vector<int> vecArea; // 考勤区域

	void Clear();
	void AddArea(int area_id);
};

// 手动移动车辆图标
class HandUpVehicle
{
public:
	std::string card_id;
	double point_x;
	double point_y;
	int area_id;
};

//移动分站
class MovingReader{
public:
	MovingReader(std::shared_ptr<Card> pCard,int reader_id){
		this->pVehicleCard = pCard;
		this->moving_reader_id = reader_id;
	};
	MovingReader(){
		this->pVehicleCard = nullptr;
		this->moving_reader_id = 0;
	};
	~MovingReader(){};
public:
	int moving_reader_id;					// 移动分站id
	std::shared_ptr<Card> pVehicleCard;		// 关联车卡信息
	CardMap mp_person_card;					// 统计移动分站收到的人卡列表

public:
	std::shared_ptr<Card> get_card(){return pVehicleCard;};
	void set_card(std::shared_ptr<Card> pCard){this->pVehicleCard = pCard;};
};

enum HAND_UP_STATUS{ // 手动挪车状态
	NOT_IN_HANDUP_LIST = 0, // 不在handup list中
	IN_HANDUP_LIST_AREA_IN = 1, // 在handup list中，在半径距离内 
	IN_HANDUP_LIST_AREA_OUT = 2 // 在handup list中，在半径距离外
};

#ifdef DEBUG
#define TEST_FROM_FILE 1
#else
#endif // DEBUG

#endif //YASERVER_CLASSDEF_H_
