#ifndef YASERVER_CLASSDEF_H_
#define YASERVER_CLASSDEF_H_

#define MAX_DIST_CACHE 4  //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 12

#define KALMAN_OFFSET_COOR 0.01
#define KALMAN_OFFSET_MOVE 1
#define KALMAN_OFFSET_RANGING 0.01
#define KALMAN_INTERVAL 0.3

#define KALMAN_OFFSET_COOR_TRI 0.01
#define KALMAN_OFFSET_MOVE_TRI 1
#define KALMAN_OFFSET_RANGING_TRI 0.09
#define KALMAN_INTERVAL_TRI 1

#define ANTENNA_COUNT 2
#define ADHOC_COUNT 10
#define READER_TIMEOUT 20
#define CARD_LOST_TIME_OUT 30 // (30 * 60)
#define CARD_LOST_TIME_CAL 5 // 卡未收到数据后，利用缓存的数据计算间隔
#define CARD_LOST_TIME_OUT_SPECIAL_AREA 1800
#define READER_SEND_STATE_TIMEOUT 30 // (2* 60 * 60)
#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 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

#include <string>
#include <ctime>
#include <map>
#include <iostream>  
#include <string>  
#include <vector>
#include <unordered_map>
#include <deque>
#include <mutex>
#include <thread>
//#include "winsock2.h"
#include <kalman\locate.h>
#include "Filter\KalmanFilter.h"
#include "algorithm\FittingPosition.h"
#include "algorithm/cell/cell_struct.h"
#include "LocateRecord.h"

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

using namespace std;
class YaAlgorithmForCell;

//算法中使用的常量定义
const int MAX_CALC_POINTS = 30;
const int ACCELERATE_INIT_STATE = -10;
const int IDLE_CONFIRM_TIME = 4;
const int MAX_READER_TDOA_PATH_NUMS = 10;	//主要是因为拐弯处可能存在多解的原因
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 = 10.0;	 //人卡运动速度阈值，超过此阈值，定位数据被抛弃
const double NEAR_READER = 4.0;			 //定位结果在分站附近4米内
const double MIN_DIFFER_DISTANCE = 10.0; // 使用其他分站校验计算结果时，判断该结果到校验分站的距离差允许的范围
const double MIN_IDLE_THRESHOLD = 0.5;
const double VECHILE_ACCELERATE_THRESHOLD = 10; // 校验加速度阈值
const double PERSON_ACCELERATE_THRESHOLD = 10; // 校验速度阈值
const double INVALID_COORDINATE = -1000.0;
const int POS_NO_CHANGE_TIMES = 15; // lihongzhen  2017/8/19 位置连续未改变次数，每次0.5秒，约7秒
const double CHAMBER_WIDTH = 3.0;			//特指前端展现巷道的宽度，单位为像素
<<<<<<< HEAD
const double VEHICLE_WIDTH = 10.0;
const double TOF_HEIGHT_ERROR = 2;			//tof定位时的高度误差，单位为米
=======
const double VEHICLE_WIDTH = 20.0;
const int MAX_READER_TDOA_PATH_NUMS = 10;	//主要是因为拐弯处可能存在多解的原因
const int LIGHT_CTRL_DELAY = 2000;

const double TOF_HEIGHT_ERROR = 2;	//tof定位时的高度误差，单位为米
>>>>>>> newprotocal
const double READER_SYNC_INTERVAL_TIME  = 0.2;		//分站同步序号的时间差，估计值

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

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
};

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{
	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			//绿色闪烁
};

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_LOC_TYPE{
	ALGO_LOC_SUCCESSED = 0,			//算法定位成功
	ALGO_FAILED_CONDITION_1,		//同步序号相差大于5
	ALGO_FAILED_CONDITION_2,		//相同卡序列号，时间同步序号却相差大于5
	ALGO_FAILED_CONDITION_3,		//时间同步戳值存在异常
	ALGO_FAILED_CONDITION_4,		//卡的上次时间戳大于卡的本次时间戳
	ALGO_FAILED_CONDITION_5,		//人卡加速度超限
	ALGO_FAILED_CONDITION_6,		//车卡加速度超限
	ALGO_FAILED_CONDITION_7,		//车卡速度超限
	ALGO_FAILED_CONDITION_8,		//卡尔曼连续2s定位失败等
	ALGO_FAILED_CONDITION_9,		//分站时间戳的距离差值大于分站之间的距离
	ALGO_FAILED_CONDITION_10,		//分站之间无地图集
	ALGO_FAILED_CONDITION_11,		//定位无解or解的个数为0
	ALGO_FAILED_CONDITION_12,		//分站附近（小于4m），分站不是特殊分站
	ALGO_FAILED_CONDITION_13,		//解与无地图集两分站之间的距离差（大于10m）
	ALGO_FAILED_CONDITION_14,		//定位结果距离定位分站之间的距离差大于4
	ALGO_FAILED_CONDITION_15,		//参与定位的数据条数小于2
	ALGO_LOC_TOTAL
};

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;

#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_CARD_READER = 0, //读卡分站
	DT_CTRL_READER = 1, // 控制分站
	DT_LIGHT = 3, // 红绿灯
	DT_SPEAKER = 4, // 告警器
	DT_TURNOUT = 5, // 道岔
	DT_LED = 6 // 显示屏
};

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, 
	LDT_TDOA
};

enum CAL_STATUS{
	CAL_NO = 0,		//不校准
	CAL_REQUEST		//请求校准
};

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

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

// 定位坐标
struct _coordinate{
	_coordinate(){
		t = 0;
		reader_id = 0;
		tt = 0;
		d = 0.0;
		sync_num = 0;	

		x = 0.0;
		y = 0.0;
		z = 0.0;
		a = 0.0;
		v = 0.0;
		antenna_id = 0;
		d_offset = 0.0;
		special = 0;
		acceleration = 0;
		acce_state = 0;	
		acce_state_last = 0;
		ins_direction = 0;
		rangingtype = 1; // 0 tof，1 toda
		cur_time = time(NULL);
	}
	int t; // 定位时间戳
	int reader_id; // 分站编号
	unsigned long long syncRootId; // tdoa主节点
	unsigned long long tt; // 分站接收的时间，为同步及线性插值后的时间
	double d; // 距离

	double x; // x坐标
	double y; // y坐标
	double z; // z坐标
	double a; // 平面角度
	double v; // 速度
	int antenna_id;
	
	int sync_num;   //同步序号
	int acce_state;	//加速度状态
	int acce_state_last;	//加速度计上一次状态
	int ins_direction;		//惯导方向
	int special; //分站是否属于特殊分站，0属于特殊分站，1普通分站
	int rangingtype;
	int reason;

	double acceleration;	//加速度
	double d_offset; // 与显示距离的偏移，用来修正单基站的情况

	time_t cur_time;
	_coordinate& operator=(_coordinate &tmp){
		t = tmp.t;
		reader_id = tmp.reader_id;
		tt = tmp.tt;
		d = tmp.d;
		sync_num = tmp.sync_num;
		x = tmp.x;
		y = tmp.y;
		z = tmp.z;
		a = tmp.a;
		v = tmp.v;
		antenna_id = tmp.antenna_id;
		d_offset = tmp.d_offset;
		special = tmp.special;
		acceleration = tmp.acceleration;
		acce_state = tmp.acce_state;
		acce_state_last = tmp.acce_state_last;
		ins_direction = tmp.ins_direction;
		rangingtype = tmp.rangingtype;
		reason = ALGO_LOC_SUCCESSED;
		cur_time = tmp.cur_time;
		return *this;
	}
};

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;
	}
};

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;
	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;	// 分站接收时间，一个5字节的无符号数
	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;
	};
};

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

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 POS{
	double posx; // 以米为单位坐标
	double posy;
	double posz;
	//误差范围
	double pos_radius;

	//以像素为单位的坐标，米/地图比例尺 = 像素
	double cx;
	double cy;
	double cz;
	//三个方向的速度
	double cvx;
	double cvy;
	double cvz;
	//加速度
	double av;

	//保存定位结果的两个分站信息
	int nFirstReader;
	int nSecondReader;

	//精度参考
	double dDiff[MAX_READER_TDOA_PATH_NUMS];
	double dis_diff;

	//定位失败的状态
	int reason;
	int status;
	int card_count;		//卡的ct号
	bool update;		//是否需要保存到同步队列中
	bool is_back;
	bool is_fit;		//是否是拟合数据

	//当前分站同步序号与参考数据的分站同步序号时间差值
	double diff_reader_sync_num;

	double delta_time;			//时间差
	//参考数据的定位坐标
	double ref_x;
	double ref_y;
	double ref_z;
	double origin_speed;	//原始定位结果算的速度

	double sumVariance;		// 保存各定位解之间差值的和

	POS(){
		nFirstReader = 0;
		nSecondReader = 0;
		pos_radius = 999999.9;	
		posx = posy = posz = INVALID_COORDINATE;
		cx = cy = cz = cvx = cvy = cvz = 0.0;
		av = 0.0;
		status = 0;

		for (int i=0;i<MAX_READER_TDOA_PATH_NUMS;i++)
		{
			dDiff[i] = 0;
		}

		dis_diff = 999999.9;
		update = false;
		is_fit = false;
		is_back = false;
		origin_speed = 0;
		sumVariance = 0;
		diff_reader_sync_num = 0;
		delta_time = 0.0;
		ref_x = ref_y = ref_z = 0;
		reason = -1;
		reason = ALGO_LOC_SUCCESSED;
	}

	POS& operator=(POS& tmp){
		nFirstReader = tmp.nFirstReader;
		nSecondReader = tmp.nSecondReader;
		posx = tmp.posx;
		posy = tmp.posy;
		posz = tmp.posz;
		cx = tmp.cx;
		cy = tmp.cy;
		cz = tmp.cz;
		cvx = tmp.cvx;
		cvy = tmp.cvy;
		cvz = tmp.cvz;
		av = tmp.av;
		update = tmp.update;
		origin_speed = tmp.origin_speed;
		status = tmp.status;
		is_back = tmp.is_back;
		diff_reader_sync_num = tmp.diff_reader_sync_num;
		delta_time = tmp.delta_time;
		dis_diff = tmp.dis_diff;
		ref_x = tmp.ref_x;
		ref_y = tmp.ref_y;
		ref_z = tmp.ref_z;
		sumVariance = tmp.sumVariance;
		for (int i=0;i<MAX_READER_TDOA_PATH_NUMS;i++)
		{
			dDiff[i] = tmp.dDiff[i];
		}
		pos_radius = tmp.pos_radius;
		reason = ALGO_LOC_SUCCESSED;

		return *this;
	}
};

//解的结构体
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;

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

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;

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<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 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 std::map<std::string,std::list<std::shared_ptr<Cell>>> CellPathMap;
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);
	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;
	// 人员
	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;

	double rect_left;
	double rect_right;
	double rect_top;
	double rect_bottom;

	// 区域人数
	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 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;
};

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

// 工作面与卡绑定信息
class 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;
};

// 自组网预置坐标
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 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 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;
	bool bIsInitCoverage;
	int m_nIsSpecial;
	bool init_ctrl_reader_state;	//当为控制分站时，第一次需要获得此控制分站下的红绿灯状态

	INT64 m_event_list[READER_EVENT_COUNT]; // 保存事件Id
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:
	Card(void);
	~Card(void);
	Card(string cardid, int cardtype,double z_offset);

    friend class YaAlgorithmForCell;

public:
	CRITICAL_SECTION m_csCard;
	bool is_registered;
public:
	int card_type; // 卡类型 0x01人, 0x02车
	string card_id;
	int m_indexCardSpeed;
	// 人员
	int level_id;
	int worktype_id;// 工种lemon 2017/07/31 车辆为vehicle_type_id
	int vehice_type_id;
	// 人员、车辆
	int id; // 编号，人员或车辆
	int dept_id; // 部门
	int occ_id; // 职务id
	int group_id; // 班组	
	int need_display;// lemon 2071/08/01 是否在Web端显示
	int shift_type_id; // 人员或者车辆执行的班次类型

	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 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 coor_offset_x;
	double coor_offset_y;
	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 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_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 landmark_id;
	double landmark_dis;
	int landmark_direction;
	int reader_id; // 当前分站

	Reader* p_reader;
	std::shared_ptr<ReaderPathMap> pTofReaderPathMap;
	std::shared_ptr<TDOAReaderPathMap> pTdoaReaderPathMap;
	map<unsigned long long,std::shared_ptr<_coordinate>> mp_dists_locate;
	_coordinate last_locate;
	_coordinate origin_locate;

	QueStrorePos _storepostions;	
	DistQueMap _dists;
	int time_stamp_max; // 最大时间戳，即需要计算定位的时间戳
	int time_stamp_cal; // ct 值

	int m_nFilterType;
	int m_nLastLocateT;
	int m_nCalcSyncNum;	//卡在算法中的同步号，此同步号和卡的实时同步号并不一定一致
	int m_nSyncNumInList;	//从队列中取出的大于5的同步号
	int m_nStream;			//上行、下行
	int m_nLightGroupId;
	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 is_need_cal;
	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();
	string get_state_text();
	string get_acc_text();
	double get_speed();
	void set_speed(double v);
	int get_effictive_dist_count(int offset = 0);
	void set_reader_path(std::shared_ptr<ReaderPathMap> rpm, std::shared_ptr<TDOAReaderPathMap> trpm);

	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();

	INT64 m_event_list[CARD_EVENT_COUNT]; // 保存事件Id
public://lemon
	int m_warning_point_id; 
	bool m_isWarning; // 0 
	double m_minDistanceToWarningpoint; //
	double m_warning_threshold; //limit value
	bool m_CardHasBeenInDrivingfaceAlarm;
	int m_DrivingfaceAlarmFlag;

	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;

private:
	double m_drivingface_distance_cul_values;
	double m_drivingface_distance_limit_values;
public:
	//算法相关参数及函数
	bool is_algo_first_location;		//表示算法的第一次定位
	bool is_idling; // 是否为怠速状态
	int idle_count; // 连续判断为怠速状态的次数，超过次数阈值则将速度置为0

	std::shared_ptr<nspLocate::LocateRecord> locate;
	std::list<std::shared_ptr<POS>> idle_pos_list;

	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);
	int SaveTdoaData(const std::shared_ptr<POS> pos);
	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 CheckSolution(std::shared_ptr<POS>& p);					// 验证唯一解合法性，如速度、加速度
	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 CalcPositionBySpeed(std::shared_ptr<POS>& pos,double v);
	bool CheckStreamUniformity(double x1,double y1,double x2,double y2,int nStream);
	bool IsExistPath(int left,int right);
	int CopySolution(std::shared_ptr<POS> source,std::shared_ptr<POS>& dest);
	//std::shared_ptr<nspLocate::LocateRecord> locate;
	int CheckCardStatus();
	bool IsIdleStatus(std::shared_ptr<POS> pos);
	bool IsRebound(std::shared_ptr<POS> pos);		//判断是否回退
	bool CheckPositionValid(const std::shared_ptr<POS> pos);		//检查解的有效性
	double GetDeltaT();		//获取时间差值
public:
	//tof相关变量及函数
	time_t time_cur_algo;				// dist数据进缓存队列的时间
	time_t time_last_tof;				// 上次tof定位的时间
	int reader_id_algo;					// 算法计算时的分站号

	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);
	int KalmanFilterProcess(std::shared_ptr<POS>& pos);

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

	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();								//计算拟合数据
	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有效性
	double GetFittingDegree(std::list<std::shared_ptr<Cell>> ltCells);	//检查拟合度
private:
	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: 
	// 采集到的底层数据
	int time_stamp_last;		// 定位时间戳
	int accelerate_state_last;	// 上一次加速度状态
	int power_state_last;		// 电量
	int ins_direction;			// 上一次的惯导合成方向
	int reader_tickcount;		// 分站发送数据的计数次数
	int time_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;	// 车辆是否进入过路口区域

	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;

public:
	//格子算法的代码
	bool bInitalCellPath;
	bool isNeedWrited;

	std::shared_ptr<CellPathMap> mpCellPath;
	std::string curCellReaderName;		//当前格子所属分站名
	std::string originCellReaderName;	//原始定位格子所属分站名
	ULONGLONG calc_cell_time;		//保存当前定位的计时器（通过数据和通过500ms补充）
	ULONGLONG data_cell_time;		//用于区分两次通过数据进行定位的
	SYSTEMTIME cellDealTime;		//格子处理时间

	int curCellId;			//当前格子id
	int originCellId;		//原始定位格子id
	int nIncrease;			//格子是否增长，0为未识别，如果增长为1，如果下降为-1
	int nStartLocateCounts;	//启动定位计数统计，根据前5次定位计算是否怠速：如果怠速，则继续不运动；如果运动，则开始加速
	int change_cell_dir;	//改变格子方向
	int locateCounts;		//统计定位次数，用于取模计算
	int isInsertToDb;		//插入数据库
	int nOverThreCounts;	//连续大跳次数

	double fit_k;	//最新的格子拟合的斜率
	double last_k;
	double delta_ct; //ct的差值
	double fit_b;	//最新的格子拟合的截距
	double fit_r;	//求斜率时的拟合度
	double cell_a;	//格子算法中的加速度值
    int cell_id_delta_for_idling; // 格子算法: 怠速判断累计值

	bool isIdling;		//怠速状态
    int idling_count; // lyl add: for cell
	int m_reverse_direction_count; // 用于算法路径14, 统计转向数据数量
	int last_direction; // 运动方向

	std::thread* pThread;

	std::shared_ptr<Cell> last_cell;
	std::list<std::shared_ptr<Cell>> his_cell;
    std::list<std::shared_ptr<Cell>> history_cell_for_idling;
	std::list<std::shared_ptr<Cell>> locate_cells;

	int DiscreteLocate(int cnt);
	int PersonLocation(int cnt);
	bool CheckIdleStatus();
	bool CheckStartRule();
	bool isOverThreshold();
	bool isRebound(std::shared_ptr<Cell> cell);
	bool Position2Cell(std::shared_ptr<POS>& pos, std::shared_ptr<Cell>& cell);		//点转化为格子信息
	std::shared_ptr<POS> Cell2Position(std::shared_ptr<Cell>& cell);	//格子信息转化坐标输出
	std::shared_ptr<Cell> GetNextCell(std::shared_ptr<Cell> lastCell,int increase,int nIndex);
	std::shared_ptr<Cell> GetNextCell(std::shared_ptr<Cell> lastCell,int increase,int nIndex,std::shared_ptr<Cell> newCell);
	int SetCellPathMap(std::shared_ptr<CellPathMap> pCellPath);
	int ChangeSystemTime(SYSTEMTIME& st,const int condition);
	int ChangeSystemTime(SYSTEMTIME& st);				//在st基础上加500ms
	int ChangeSystemTimeBySecond(SYSTEMTIME& st);		//按1s的方式更改st时间
	int MappingCell2FitLinear(std::shared_ptr<Cell>& cell);		//将格子拟合到线上
	bool cftool(float *data_x, float *data_y, int data_n, std::vector<float> &vResult);
	int SaveCardAlgoData(std::shared_ptr<Cell>& cell);
	std::shared_ptr<Cell> FindCell(std::string strReaderName,int cellid);

	//刘思平修订的代码Part 3/Sum 3:begin
	//以下函数的声明：将当前时刻的毫秒四舍五入为0ms或者500ms
	//by lsp on 2017.07.09 @山西长治
	int ChangeMsTimeToZeroOrFive(SYSTEMTIME& st);
	int colourfulCloudsChasingTheMoon(std::shared_ptr<Cell> &cell, std::list<std::shared_ptr<Cell>> &myCellList);
	//结束：刘思平修订的代码Part 3/Sum 3
public:
	//测试参数及相关函数
	int OutputCmdLog(int n);

	double dTestDelatT;		//测试时间差
	double dTestDistance;		//测试两次的定位的距离差
};

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;
};

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 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 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,//掘进机附近人员超员
	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
};

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;
		is_count = false;
	};
	~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; // 已发送
	bool is_count;

	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);
};

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

#endif //YASERVER_CLASSDEF_H_