#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 30
#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_OUT_SPECIAL_AREA 1800
#define READER_SEND_STATE_TIMEOUT 30 // (2* 60 * 60)
#define OVER_TIME (480 * 60)

//#define CARD_TYPE_ADHOC 3
#define MAX_SEMACOUNT 64
//#define INVALID_COORDINATE -1

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

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

//算法中使用的常量定义
const int MAX_CALC_POINTS = 30;
const double INS_WEIGHT = 9.0;	//惯导权重
const double UWB_WEIGHT = 1.0;  //UWB权重
const double MAX_VECHILE_SPEED = 30.0;	//25
const double NEAR_READER = 4.0;
const double MIN_DIFFER_DISTANCE = 10.0;
const double VECHILE_ACCELERATE_THRESHOLD = 10;
const double PERSON_ACCELERATE_THRESHOLD = 10;
const int ACCELERATE_INIT_STATE = -10;
const double INVALID_COORDINATE = -1000.0;
const double CHAMBER_WIDTH = 10.0;			//特指前端展现巷道的宽度，单位为像素
const double VEHICLE_WIDTH = 10.0;
const int MAX_READER_TDOA_PATH_NUMS = 10;	//主要是因为拐弯处可能存在多解的原因
const int LIGHT_CTRL_DELAY = 1000;
const int MAX_REBOUND_COUNTS = 5;

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

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 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_MOVING
{
	STATUS_MOVING_MOTIONLESS = 0,
	STATUS_MOVING_MOTION,
	STATUS_MOVING_IDLING
};

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{
	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,

	ALGO_CALC_SOLUTION = 30001,
	ALGO_CALC_NO_SOLUTION_WITH_TWO_DATA,
	ALGO_CALC_ONE_DATA,

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

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

extern unsigned int g_nAlgoFailedCounts[ALGO_LOC_TOTAL];	//全局的统计所有次数
extern unsigned int g_nAlgoFailedCycleCounts[ALGO_LOC_TOTAL];	//指定周期内的所有统计次数
extern ULONGLONG 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,		//呼叫失败
	
};

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;
	}
	int t; // 定位时间戳
	int reader_id;
	unsigned long long syncRootId;
	unsigned long long tt;
	double d; // 距离

	double x; // x坐标
	double y; // y坐标
	double z; // z坐标
	double a; // 平面角度
	double v; // 速度
	int antenna_id;
	double d_offset; // 与显示距离的偏移，用来修正单基站的情况

	int sync_num;   //同步序号
	double acceleration;	//加速度
	int acce_state;	//加速度状态
	int acce_state_last;	//加速度计上一次状态
	int ins_direction;		//惯导方向
	int special; //分站是否属于特殊分站，0属于特殊分站，1普通分站

	int reason;

	_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;
		reason = ALGO_LOC_SUCCESSED;
		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 vx;
	double vy;

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

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

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

	sync_data& operator=(sync_data&tmp){
		x = tmp.x;
		y = tmp.y;
		vx = tmp.vx;
		vy = tmp.vy;
		sync_num = tmp.sync_num;
		update = tmp.update;
		locate = tmp.locate;
		return *this;
	}
};

struct _call_info_card
{
	int card_id;
	int card_type;
	int call_type;
	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_type;
	int cards_count;
	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 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 ref_x;
	double ref_y;
	double ref_z;
	double origin_speed;	//原始定位结果算的速度

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

	POS(){
		nFirstReader = 0;
		nSecondReader = 0;
		pos_radius = 0;	
		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;
		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;
		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;
		}
	}
};

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

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::shared_ptr<SpecialAreaEntry>> SpecilaAreaEntryMap;
typedef map<int, std::shared_ptr<DrivingfaceRender>> DrivingfaceRenderMap;
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 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 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;
};
typedef deque<DistQueMapItem> DistQueMap;

// 地图
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;
	double x;
	double y;
	double z;
};

class 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);
	int 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 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, double offset_x = 12.0, double offset_y =12.0);

public:
	CRITICAL_SECTION m_csCard;
public:
	int card_type; // 卡类型 0x01人, 0x02车
	//int64_t card_id; // 卡唯一标识， 高位为卡号，低位为卡类型， ((card_id << 8) | card_type)
	string card_id;
	
	// 人员
	string level; // 级别
	string occupation; // 职务
	// 人员、车辆
	string id; // 编号，人员或车辆
	string name; // 姓名、车辆名称
	string number; // 身份证号码，车牌号码
	//string photo; // 照片
	//string company; // 单位
	string department; // 部门
	string group; // 班组 
	string worktype; // 工种、车辆类型
	int dept_id;
	int occlevel_id; // 职务id
	int group_id;
	
	string driver_id;	//如果是车辆，则有司机id
	int light_id;

	//time_t deal_time; // 最后处理卡逻辑时间
	SYSTEMTIME deal_time;
	SYSTEMTIME enter_area_time;

	//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 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;
	
	//double driving_face_x;  //cur shift start point
	//double driving_face_y;
	//double driving_face_z;

	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 z_offset;
	bool init_postion;
	bool is_first_location;
	int is_driving_face_start;
	double v; //速度
	double mileage;

	double xx;
	double yy;
	double zz;

	double x1, x2, x3, x4;
	double y1, y2, y3, y4;
	double z1, z2, z3, z4;
	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 启动

	// 电量低、 呼叫、呼救
	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 未进入盲区，1 盲区状态
	
	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> pReaderPathMap;
	std::shared_ptr<TDOAReaderPathMap> pTdoaReaderPathMap;
	_coordinate** p_dists_locate;
	map<unsigned long long,std::shared_ptr<_coordinate>> mp_dists_locate;
	_coordinate last_locate;
	_coordinate origin_locate;
	_coordinate kalman_locate;
	double m_dFirstDiff;
	double m_dSecondDiff;

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

	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 issent;		// true 已发送至客户端，false 新数据，需要发送至客户端
	bool issaved;		//true 已保存到数据库，false 生成新的考勤记录，需要保存到数据库
	bool isdealed;		// 已经处理
	bool isreceive;		// 接收到
	bool is_pos_changed;
	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 set_reader(std::shared_ptr<Reader> preader);
	//void set_reader(std::weak_ptr<Reader> preader);
	void add_dist(_coordinate* dist);
	void add_dist(std::shared_ptr<_coordinate> dist);
	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_tof(std::shared_ptr<ReaderPathMap> rpm);
	void set_reader_path_tdoa(std::shared_ptr<TDOAReaderPathMap> trpm);
	void inspect_coordinate(int acce_state);
	bool checkStream(double x1,double y1,double x2,double y2,int nStream);

	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:
	std::shared_ptr<nspLocate::LocateRecord> locate;

	void algo_tof(int cnt);
	void algo_tdoa(int cnt);
	int  algo_tdoa_1d(int cnt);		//一维定位
	int  algo_tdoa_2d(int cnt);		//二维定位
	int  algo_tdoa_3d(int cnt);		//三维定位

	void algo_calc_offset();		//计算偏移坐标
	bool algo_is_same_direction(double x,double y,double z);	//检查此次方向

	int CheckDistData(int cnt);
	int AssembleDistData(std::shared_ptr<ReceiveDataMap> pRdm);
	int SaveCardAlgoData(std::shared_ptr<POS>& pos);
	int SaveCardAlgoData(std::shared_ptr<Cell>& cell);
	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 CheckSolution(std::shared_ptr<POS>& p); // 验证唯一解合法性，如速度、加速度
	int CheckSulutionByStream(std::shared_ptr<POS> p);	//参数使用非引用，即不可修改其值
	bool IsExistPath(int left,int right);
	int CopySolution(std::shared_ptr<POS> source,std::shared_ptr<POS>& dest);
	int CalcPositionBySpeed(std::shared_ptr<POS>& pos,double v);

	//std::shared_ptr<nspLocate::LocateRecord> locate;
	int GetDeltaT(map<unsigned long long,std::shared_ptr<_coordinate>> dl);
	int CheckCardStatus();

public:
	// 滤波算法相关
	std::unique_ptr<CKalmanFilter> m_pKalmanFilter;
	list<sync_data> m_syncNumList;
	std::list<std::shared_ptr<POS>> his_idle_pos;

	int last_s_locate_reader[2];	//上一次定位成功的分站信息

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

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

	std::list<double> vt_his_speed;
	void get_coordinate();
	void get_coordinate(int cnt);
	void get_coordinate_3d(int cnt);
	void set_anchors(int cnt);

	void EnableFilter(int nType);
	int FindDistMap(int cardstamp);
	int KalmanFilterProcess(std::shared_ptr<POS>& pos);
	int InitAlgoParam();
	bool CheckCrossCycle();
	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();								//计算拟合数据
	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);
private:
	bool b_long_interval;	//上一次定位的间隔时间差大于10s

	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:
	AlgoFailedMsg m_afmData;
public:
	bool b_pos_change;		//位置发生了改变
	bool b_enter_intersection;	//车辆是否进入过路口区域
public: // 采集到的底层数据
	int reader_tickcount; 
	int time_stamp; // 定位时间戳
	int ranging_type; // 报文类型 tof，tdoa
	int accelerate_state; // 加速度
	int antenna_id; // 天线号
	double antenna_angle; // 天线角度
	double distance; // 距离
	int64_t flying_time; // 飞行时间
	int power_state; // 电量
	int sync_num;

	int time_stamp_last; // 定位时间戳
	int context_type_last; // 报文类型 tof，tdoa
	int accelerate_state_last; // 上一次加速度状态
	int antenna_id_last; // 天线号
	double antenna_angle_last; // 天线角度
	double distance_last; // 距离	
	int64_t flying_time_last; // 飞行时间
	int power_state_last; // 电量

	int ins_direction;	//上一次的惯导合成方向
	int direction;		//上下行概念

	int reader_id_last;	//上一次定位时间戳的分站id

	string str_his_time;
	string str_rec_time;

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;		//插入数据库

	bool isIdling;		//怠速状态

	std::thread* pThread;

	std::shared_ptr<Cell> last_cell;
	std::list<std::shared_ptr<Cell>> his_cell;
	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);
	std::shared_ptr<Cell> Position2Cell(std::shared_ptr<POS> pos);		//点转化为格子信息
	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

	//void handle_data_thread(LPVOID pContext);
	//HANDLE hEvent;
	HWND pMainWnd;

	int SetMainHwnd(HWND hWnd){
		pMainWnd = hWnd;
		return 0;
	}
public:
	//测试函数
	int OutputCmdLog(int n);

	//呼叫信息
	int call_type;
	std::vector<int> vt_deal_call_reader_id;
	time_t recv_call_time;	//卡接收到呼叫的时间戳
};

class BanShift
{
public: 
	BanShift();
	~BanShift();
	BanShift(int id, std::string s, std::string e);
	int shift_id;
	std::string start_time;
	std::string end_time;
};

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, // 井下人员超员
	ET_OVER_COUNT_VEHICLE = 2,    // 井下车辆超员

	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, // 人员井下超时
	ET_CARD_OVER_TIME_VEHICLE = 14, // 车辆井下超时
	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,  //掘进面靠近预警区域告警
	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 // 标识卡，包括人员、车辆、自组网等
};

enum EVENT_STATUS{ // 事件状态
	ES_START = 0, // 事件开始
	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
};

#endif //YASERVER_CLASSDEF_H_