lixioayao 6 år sedan
förälder
incheckning
6487155a15
20 ändrade filer med 581 tillägg och 133 borttagningar
  1. 18 2
      Makefile
  2. 1 1
      Makefile.am
  3. 18 2
      Makefile.in
  4. 4 1
      ant.h
  5. 3 4
      area.cpp
  6. 28 19
      area.h
  7. 19 19
      autom4te.cache/requests
  8. 89 13
      card.cpp
  9. 5 32
      card.h
  10. 49 0
      common.h
  11. 6 5
      main.cpp
  12. 4 4
      monkey_car/monkeycar_area.cpp
  13. 1 1
      monkey_car/monkeycar_area.h
  14. 115 0
      special_area.cpp
  15. 31 0
      special_area.h
  16. 88 1
      websocket/jsonBuilder.cpp
  17. 36 2
      websocket/jsonBuilder.h
  18. 7 1
      websocket/wsClientMgr.cpp
  19. 22 1
      websocket/wsClientMgr.h
  20. 37 25
      websocket/ws_common.h

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 18 - 2
Makefile


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 1
Makefile.am


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 18 - 2
Makefile.in


+ 4 - 1
ant.h

@@ -122,7 +122,10 @@ struct site:point
 	point    m_position;
 	int index()const;
 	const algo_config&config()const;
-
+	int id()const
+	{
+		return m_id;
+	}
 	site(int id=-1);
 
 	mutable double m_height=1.5;

+ 3 - 4
area.cpp

@@ -138,7 +138,7 @@ void area_list::init_monkeycar_area()
 			da->m_default_speed = monkeycar_speed;
 			da->m_point = init_path(monkeycar_coor);
 		
-			std::shared_ptr<area> ap = std::make_shared<monkey_area>(da,area_id,over_count_person,over_time_person,scale,map_id);
+			std::shared_ptr<area> ap = std::make_shared<monkey_area>(da,area_id,over_count_person,over_time_person,scale,map_id,area_type_id);
 
 			ap->m_bound=init_path(path);
 			for(const auto &p : ap->m_bound)
@@ -200,7 +200,7 @@ void area_list::init_from_db()
 
 			log_info("init_area : id:%d,path:%s",area_id, path.c_str());
 			
-			std::shared_ptr<area> ap = std::make_shared<area>(area_id,over_count_person,over_time_person,scale,map_id);
+			std::shared_ptr<area> ap = std::make_shared<area>(area_id,over_count_person,over_time_person,scale,map_id,area_type_id);
 			ap->m_bound=init_path(path);
 			for(const auto &p : ap->m_bound)
 			  log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
@@ -212,8 +212,7 @@ void area_list::init_from_db()
 	area_list::instance()->add(map);
 
 	init_monkeycar_area();
-
-	}
+}
 std::vector<point> area_list::init_path(std::string &str)
 {
 	if(str.empty())

+ 28 - 19
area.h

@@ -5,7 +5,7 @@
 #include <algorithm>
 #include <iterator>
 #include <point.h>
-
+#include "common.h"
 #include <write-copy.h>
 //下午查看代码,整理了一下思路,如下
 //普通区域和考勤区域就不分开了,使用同一个具现类,至于里面的操作,是否区域告警之类的可以通过数据库配置进行控制,比如超员可以查看超员配置是否为0,0则不会进行告警
@@ -25,24 +25,13 @@
 struct area_hover;
 struct point;
 
-/**
- * @brief 区域类型
- */
-enum AREA_TYPE
-{
-    ///非考勤区域
-    AT_NOT_ATTENDANCE,
-
-    ///与考勤,卡数统计,超员,超时无关的区域
-    AT_OTHER,
-};
-
 struct area
 {
-	area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid)
+	area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type)
 		:m_id(id)
-		 ,m_limit_time_second(limit_time_person)
-		 ,m_limit_person_count(limit_count_person)
+		,m_area_type(type)
+		,m_limit_time_second(limit_time_person)
+		,m_limit_person_count(limit_count_person)
 		,m_scale(scale)
 		,m_mapid(mapid)
 	{
@@ -64,14 +53,19 @@ struct area
 	{
 		return m_scale;
 	}
+	bool special()const
+	{
+		return m_area_type == AREA_TYPE_NO_COVER;
+	}
 	virtual ~area()
 	{}
 	std::vector<point> m_bound;
 private:
 	std::atomic<int> m_card_count;
-	int    m_id;
+	int32_t    m_id;
+
     ///区域类型  AREA_TYPE
-    int m_area_type;
+    int32_t m_area_type;
 
     
     ///区域人卡数
@@ -170,7 +164,13 @@ struct area_tool
 			m_area_hover->setLandmark(pt);
 		}
 	}
-		
+	//special area or no area att.,return true;else return false.
+	bool special_area()
+	{
+		if(m_area_hover==nullptr)
+		  return true;
+		return m_area_hover->m_area->special();
+	}
 	std::tuple<time_t,time_t,int,int,int,int,double> getLandmark()
 	{
 		if(m_area_hover)
@@ -199,6 +199,15 @@ struct area_tool
 	{
 		m_area_hover->m_area->on_leave(card_id,m_area_hover,speed,type);
 	}
+
+	void change_area(int64_t card_id,double speed,int16_t type,int32_t new_areaid)
+	{
+		do_leave_biz(card_id,speed,type);
+		auto area = area_list::instance()->get(new_areaid);
+		point pt;
+		m_area_hover.reset(new area_hover(area,pt,speed));
+		do_enter_biz(card_id,speed,type);
+	}
 };
 
 #endif

+ 19 - 19
autom4te.cache/requests

@@ -81,58 +81,58 @@
                         'configure.ac'
                       ],
                       {
-                        '_LT_AC_TAGCONFIG' => 1,
                         'AM_PROG_F77_C_O' => 1,
-                        'AC_INIT' => 1,
+                        '_LT_AC_TAGCONFIG' => 1,
                         'm4_pattern_forbid' => 1,
-                        'AC_CANONICAL_TARGET' => 1,
+                        'AC_INIT' => 1,
                         '_AM_COND_IF' => 1,
-                        'AC_CONFIG_LIBOBJ_DIR' => 1,
+                        'AC_CANONICAL_TARGET' => 1,
                         'AC_SUBST' => 1,
-                        'AC_CANONICAL_HOST' => 1,
+                        'AC_CONFIG_LIBOBJ_DIR' => 1,
                         'AC_FC_SRCEXT' => 1,
+                        'AC_CANONICAL_HOST' => 1,
                         'AC_PROG_LIBTOOL' => 1,
                         'AM_PROG_MKDIR_P' => 1,
                         'AM_INIT_AUTOMAKE' => 1,
-                        'AC_CONFIG_SUBDIRS' => 1,
                         'AM_PATH_GUILE' => 1,
+                        'AC_CONFIG_SUBDIRS' => 1,
                         'AM_AUTOMAKE_VERSION' => 1,
                         'LT_CONFIG_LTDL_DIR' => 1,
-                        'AC_REQUIRE_AUX_FILE' => 1,
                         'AC_CONFIG_LINKS' => 1,
-                        'LT_SUPPORTED_TAG' => 1,
+                        'AC_REQUIRE_AUX_FILE' => 1,
                         'm4_sinclude' => 1,
+                        'LT_SUPPORTED_TAG' => 1,
                         'AM_MAINTAINER_MODE' => 1,
                         'AM_NLS' => 1,
                         'AC_FC_PP_DEFINE' => 1,
                         'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
-                        '_m4_warn' => 1,
                         'AM_MAKEFILE_INCLUDE' => 1,
+                        '_m4_warn' => 1,
                         'AM_PROG_CXX_C_O' => 1,
-                        '_AM_COND_ENDIF' => 1,
                         '_AM_MAKEFILE_INCLUDE' => 1,
+                        '_AM_COND_ENDIF' => 1,
                         'AM_ENABLE_MULTILIB' => 1,
                         'AM_PROG_MOC' => 1,
                         'AM_SILENT_RULES' => 1,
                         'AC_CONFIG_FILES' => 1,
-                        'include' => 1,
                         'LT_INIT' => 1,
-                        'AM_PROG_AR' => 1,
+                        'include' => 1,
                         'AM_GNU_GETTEXT' => 1,
+                        'AM_PROG_AR' => 1,
                         'AC_LIBSOURCE' => 1,
-                        'AC_CANONICAL_BUILD' => 1,
                         'AM_PROG_FC_C_O' => 1,
+                        'AC_CANONICAL_BUILD' => 1,
                         'AC_FC_FREEFORM' => 1,
-                        'AC_FC_PP_SRCEXT' => 1,
                         'AH_OUTPUT' => 1,
-                        '_AM_SUBST_NOTMAKE' => 1,
+                        'AC_FC_PP_SRCEXT' => 1,
                         'AC_CONFIG_AUX_DIR' => 1,
-                        'AM_PROG_CC_C_O' => 1,
-                        'sinclude' => 1,
+                        '_AM_SUBST_NOTMAKE' => 1,
                         'm4_pattern_allow' => 1,
-                        'AM_CONDITIONAL' => 1,
-                        'AC_CANONICAL_SYSTEM' => 1,
+                        'sinclude' => 1,
+                        'AM_PROG_CC_C_O' => 1,
                         'AM_XGETTEXT_OPTION' => 1,
+                        'AC_CANONICAL_SYSTEM' => 1,
+                        'AM_CONDITIONAL' => 1,
                         'AC_CONFIG_HEADERS' => 1,
                         'AC_DEFINE_TRACE_LITERAL' => 1,
                         'AM_POT_TOOLS' => 1,

+ 89 - 13
card.cpp

@@ -11,9 +11,11 @@
 #include "config_file.h"
 #include "db_api/CDBConnPool.h"
 #include "websocket/wsTimerThread.h"
+#include "websocket/wsClientMgr.h"
 #include "timestamp.h"
 #include "monkey_car/monkeycar_area.h"
 #include "monkey_car/monkeycar_person.h"
+#include "special_area.h"
 
 extern config_file config;
 //一张卡一个ct的所有不同天线的信息
@@ -153,14 +155,16 @@ struct card_message_handle
 			log_warn("%s","当前代码没有处理历史消息记录。");
 			return;
 		}
+		//
+		m_card->site_hover(loc.m_site_id);
 
         if(loc.m_batty_status == 2) 
         {
-            m_card->do_status(STA_TYPE::STATUS_LOW_POWER);
+            m_card->do_status(STA_TYPE::STATUS_LOW_POWER_);
         }
         else if(loc.m_callinfo == 0x80)
         {
-            m_card->do_status(STA_TYPE::STATUS_HELP);
+            m_card->do_status(STA_TYPE::STATUS_HELP_);
         }
 
 		m_ct_list[loc.m_card_ct&(m_ct_list.size()-1)]->on_message(loop,loc);
@@ -192,16 +196,21 @@ struct person:card_location_base,private card_area
 	{
 		m_message_handle->on_message(loop,loc,is_history);
 	}
-
+	
+	virtual void site_hover(int sid)
+	{
+		m_site_area->on_point(m_id,sid,0);
+	}
 	virtual void do_business(const point &pt)
 	{
 		//区域
 		m_area_tool->on_point(m_id,pt,m_speed,m_type);
 		//考勤
-		
+		m_site_area->on_point(m_id,0,this);
 		//
 	}
-
+	//人卡升井后该线程要停掉
+	//手动升级需要补全区域得同时,需要进区域走区域业务
 	void set(ev::dynamic_loop * loop)
 	{
 		log_info("cardid_id %d",m_id);
@@ -229,8 +238,19 @@ private:
 		cp.landmark_id = std::get<4>(lm);
 		cp.lm_direction = std::get<5>(lm);
 		cp.landmark_dis=std::get<6>(lm);
+
+		cp.biz_stat = state();
 		upt_card_pos(cp,pt);
 	}
+	int state()
+	{
+		int status = get_stat();
+		if(status == STATUS_NORMAL)
+		{
+			//超时
+		}
+		return status;
+	}
 	point getSmoothPoint()
 	{
 		point pt;
@@ -253,15 +273,23 @@ private:
 
 struct car:card_location_base,private card_area
 {
-	car(std::string type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid)
+	int m_vehicle_category_id=0;
+	car(std::string type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid,int32_t categoryid)
         :card_location_base(type,cardid,needdisplay,t,deptid)
+		,m_vehicle_category_id(categoryid)
     {
         m_message_handle=new card_message_handle(this);
     }
 
+	virtual void site_hover(int sid)
+	{
+		m_site_area->on_point(m_id,sid,0);
+	}
+
 	virtual void do_business(const point &pt)
 	{
 		m_area_tool->on_point(m_id,pt,m_speed,m_type);
+		m_site_area->on_point(m_id,0,this);
 	}
 
 	void set(ev::dynamic_loop * loop)
@@ -277,6 +305,33 @@ struct car:card_location_base,private card_area
 private:
 	void on_timer()
 	{
+		make_package();
+		
+	}
+	int statbiz(int32_t special_id)
+	{
+		int status = get_stat();
+		if(status==STATUS_NORMAL)
+		{
+			//超速
+			//超时
+			//顺序不能变
+		}
+		if(status == STATUS_LOST)
+		{
+			if(!m_area_tool->special_area())			
+			{
+				special_id = special_area_list::instance()->get_special_id(m_id,*this,m_vehicle_category_id);
+				log_info("enter_special_area:%.2f,%2.f,id:%d,special_area_id:%d",x,y,m_id,special_id);
+				if(special_id != -1)
+					m_area_tool->change_area(m_id,m_speed,m_type,special_id);//自动拖车
+			}
+		}
+		return status;
+	}
+	void make_package()
+	{
+		int32_t special_id=-1;
 		YA::_CARD_POS_ cp;
 		point pt = getSmoothPoint();
 
@@ -288,12 +343,21 @@ private:
 		cp.landmark_id = std::get<4>(lm);
 		cp.lm_direction = std::get<5>(lm);
 		cp.landmark_dis=std::get<6>(lm);
-		
+		int32_t biz_stat=statbiz(special_id);
+		cp.biz_stat=biz_stat;
+		//cp.down_time
+		//cp.work_time;
+		//cp.level_id;
 		//for now
 		cp.is_on_duty=1;
 		upt_card_pos(cp,pt);
-	}
 
+		if(biz_stat==STATUS_LOST && special_id != -1 && m_display==1)
+		{
+			cp.area_id = special_id;
+			swsClientMgr.SendSpecialAreaProcess(cp);
+		}
+	}
 	point getSmoothPoint()
 	{
 		loc_point lp = m_smo_tool->smooth_strategy();
@@ -378,9 +442,9 @@ void card_list::init_vehicle()
 			//for now
 			vehicle_id = vsid;
 
-			std::shared_ptr<card_location_base> clb = std::make_shared<car>(strategy,vehicle_id,need_display,card_type_id,dept_id);
+			std::shared_ptr<card_location_base> clb = std::make_shared<car>(strategy,vehicle_id,need_display,card_type_id,dept_id,vehicle_category_id);
 			uint64_t cardid = getId(vehicle_id,2);
-			log_info("cardId:%llu,vehicle_id:%d dept_id:%d,need_display:%d---cardid:%s",cardid,vehicle_id,dept_id,need_display,card_id.c_str());
+			log_info("cardId:%llu,vehicle_id:%d dept_id:%d,need_display:%d---cardid:%s,categoryid:%d",cardid,vehicle_id,dept_id,need_display,card_id.c_str(),vehicle_category_id);
 			map.insert({cardid,clb});
 		}
 	}
@@ -500,7 +564,7 @@ void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&lo
 	m_message_handle->on_message(loop,loc,is_history);
 }
 
-
+//前端推送位置函数
 void card_location_base::upt_card_pos(YA::_CARD_POS_ &cp,const point &pt)
 {
 	cp.x = pt.x;
@@ -512,11 +576,23 @@ void card_location_base::upt_card_pos(YA::_CARD_POS_ &cp,const point &pt)
 	cp.running_stat = m_stat;
 	cp.dept_id = m_deptid;
 	cp.display=m_display;
+	cp.rec_time=m_time;
 
 	swsTimerThrd.upt_card_pos(cp);
-
 }
-
+int  card_location_base::get_stat()
+{
+	//盲区>呼救>呼叫>超时>超速>正常
+	int status=STATUS_NORMAL;
+	if(false)
+		status = STATUS_CALL;
+	if(false)
+		status = STATUS_HELP;
+
+	uint64_t now = time(0)*1000;
+	status=(now-m_time>CARD_LOST_TIME_OUT)?STATUS_LOST:STATUS_NORMAL;
+	return status;
+}
 card_location_base::~card_location_base()
 {
 }

+ 5 - 32
card.h

@@ -7,6 +7,8 @@
 
 #include "write-copy.h"
 #include "websocket/ws_common.h"
+#include "common.h"
+#define CARD_LOST_TIME_OUT (30*1000)
 
 struct task;
 template<typename T> struct zloop;
@@ -14,37 +16,6 @@ struct select_tool;
 struct smooth_tool;
 struct monkey_person;
 struct card_message_handle;
-
-enum STA_TYPE
-{
-    STATUS_HELP=0,
-    STATUS_LOW_POWER,
-};
-
-/**
- * @brief 0初始状态 1 没在考勤 2 考勤
- */
-enum ATTENDANCE_STATUS
-{
-    ///初始状态
-    AS_INIT=0,
-    ///没在考勤
-    AS_NOT_ATTENDANCE=1,
-    ///考勤
-    AS_ATTENDANCE=2,
-};
-
-/**
- * @brief 卡类型 人卡  车卡
- */
-enum CARD_TYPE
-{
-    ///卡类型 人卡
-    CT_PERSON=1,
-    ///卡类型 车卡
-    CT_VEHICLE=2,
-};
-
 struct card:point
 {
 	card(uint32_t id,uint16_t dis,int16_t type,int32_t deptid)
@@ -81,18 +52,20 @@ struct card_location_base:card
 
 	virtual void do_business(const point &pt)=0;
 	virtual void set(ev::dynamic_loop * loop)=0;
+	virtual void site_hover(int sid)=0;
 	virtual void reset(std::shared_ptr<monkey_person> mp){}
 
     void on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history);
     void on_location(const std::vector<point>&vp,const std::vector<loc_message> &lm );
     void do_status(STA_TYPE st)
     {
-        if(STATUS_HELP==st)
+        if(STATUS_HELP_==st)
         {
             //module_call_help::ins
         }
     }
 	void upt_card_pos(YA::_CARD_POS_ &,const point &pt);
+	int get_stat();
 	virtual ~card_location_base();
 };
 

+ 49 - 0
common.h

@@ -0,0 +1,49 @@
+#ifndef COMMON_HPP__
+#define COMMON_HPP__
+
+enum STA_TYPE
+{
+	STATUS_HELP_=0,
+	STATUS_LOW_POWER_,
+};
+enum STATUS_CARD
+{
+	STATUS_NORMAL=0,
+	STATUS_OVER_SPEED=8,
+	STATUS_AREA_OVER_TIME=16,
+	STATUS_HELP=128,
+	STATUS_CALL=512,
+	STATUS_LOST=1024
+};
+/**
+ * @brief 0初始状态 1 没在考勤 2 考勤
+ */
+enum ATTENDANCE_STATUS
+{
+	///初始状态
+	AS_INIT=0,
+	///没在考勤
+	AS_NOT_ATTENDANCE=1,
+	///考勤
+	AS_ATTENDANCE=2,
+};
+
+/**
+ * @brief 卡类型 人卡  车卡
+ */
+enum CARD_TYPE
+{
+	///卡类型 人卡
+	CT_PERSON=1,
+	///卡类型 车卡
+	CT_VEHICLE=2,
+};
+
+enum AREA_TYPE
+{
+	AREA_TYPE_FORBIDDEN = 3,	// 限制区域
+	AREA_TYPE_NO_COVER = 1000,	// 非覆盖区域,车辆信号消失后,定位到附近非覆盖区域内
+	AREA_TYPE_SPECIAL = 1001	// 特殊区域,只给你前端用来标识是否显示图标,胶轮车硐室
+};
+
+#endif

+ 6 - 5
main.cpp

@@ -10,6 +10,7 @@
 #include "area.h"
 #include "card_path.h"
 #include "landmark.h"
+#include "special_area.h"
 
 #include <config_file.h>
 
@@ -51,11 +52,11 @@ struct Init_Setting
 		auto a = Landmark_list::instance()->get(5,id,pt);
 		std_info("test landmark:id:%d,dir:%d,dis:%.2f",std::get<0>(a),std::get<1>(a),std::get<2>(a));
 
-		const auto map = sit_list::instance()->m_map;
-		for(const auto & s:map)
-		{
-			std_info("id:%d",s.second->m_id);
-		}
+		special_area_list::instance()->init_from_db();
+		auto s = special_area_list::instance()->get_special_id(1013,point(4727,-254),2);
+		std_info("test special_area:%d",s);
+		
+
 	}
 
 	void _mysql_init(YADB::_DB_POOL_SETTING_ &dps)

+ 4 - 4
monkey_car/monkeycar_area.cpp

@@ -5,8 +5,9 @@
 #include "log.h"
 
 uint64_t monkey_area::m_startTime=time(NULL)*1000;
-monkey_area::monkey_area(std::shared_ptr<db_area> dap,int area_id,int over_count_person,int over_time_person,double scale,int32_t mapid)
-	:area(area_id,over_count_person,over_time_person,scale,mapid)
+
+monkey_area::monkey_area(std::shared_ptr<db_area> dap,int area_id,int over_count_person,int over_time_person,double scale,int32_t mapid,int32_t type)
+	:area(area_id,over_count_person,over_time_person,scale,mapid,type)
 	,m_path(dap->m_point.begin(),dap->m_point.end())	
 {
 	log_info("monkeycar _area init ");
@@ -46,7 +47,6 @@ void monkey_area::on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double
 }
 void monkey_area::on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
 {
-	log_info("on_enter..card_id:%d,%d",card_id,type);
 	area::on_enter(card_id,c,speed,type);
 
 	if(type != 1)
@@ -102,7 +102,7 @@ void monkey_area::on_card_move(uint32_t cardid,const st_coord & st,uint64_t type
 	auto mp=find(cardid);
 	if (!mp)
 	{
-		//if not exist create it .because may be restart the system.then area not changed.
+		//if not exist ,create it .because may be restart the system.then area has not changed.
 		on_card_enter(cardid,type); 
 		return ;
 	}

+ 1 - 1
monkey_car/monkeycar_area.h

@@ -22,7 +22,7 @@ struct monkey_person;
 struct monkey_area : area,std::enable_shared_from_this<monkey_area>
 {
 public:
-	monkey_area(std::shared_ptr<db_area> dap,int area_id,int over_count_person,int over_time_person,double scale,int32_t );
+	monkey_area(std::shared_ptr<db_area> dap,int area_id,int over_count_person,int over_time_person,double scale,int32_t ,int32_t);
 	//	:area(area_id,over_count_person,over_time_person)
 	//	,m_scale(scale)
 	//	{}

+ 115 - 0
special_area.cpp

@@ -0,0 +1,115 @@
+#include "special_area.h"
+
+#include "db_api/CDBConnPool.h"
+#include "log.h"
+
+special_area_list * special_area_list::instance()
+{
+	static special_area_list spl;
+	return &spl;
+}
+int32_t special_area_list::get_special_id(uint32_t cardid,const point p,int32_t categoryid)
+{
+	int32_t f = -1;
+	for(const auto s:m_v)	
+	{
+		if(p.x<=std::max(s.start_point.x,s.end_point.x)
+			&&p.x>=std::min(s.start_point.x,s.end_point.x)
+			&&p.y<=std::max(s.start_point.y,s.end_point.y)
+			&&p.y>=std::min(s.start_point.y,s.end_point.y))	
+			//&&p.z<=std::max(s.start_point.z,s.end_point.z)
+			//&&p.z>=std::min(s.start_point.z,s.end_point.z))	
+		{
+			if(!s.car_type.empty())
+				if(s.car_type.find(std::to_string(categoryid)) == std::string::npos)	
+					continue;
+			if(m_m.find(s.special_area_id) != m_m.end())
+			{
+				auto v=m_m[s.special_area_id];
+				if(std::find(v.begin(),v.end(),cardid)==v.end())
+					continue;
+			}
+			f=s.special_area_id;
+		}
+	}
+
+	return f;
+}
+void special_area_list::init_from_db()
+{
+	init_special_area_entry();
+	init_special_card();
+}
+void special_area_list::init_special_area_entry()
+{
+	const char * sql = "SELECT serial_num, start_point_x, start_point_y, start_point_z, end_point_x, end_point_y, \
+					  end_point_z, special_area_id,car_type FROM dat_special_area_entry;";
+	std::string Error;
+	YADB::CDBResultSet DBRes;
+	sDBConnPool.Query(sql,DBRes,Error);
+	int nCount = DBRes.GetRecordCount( Error );
+	if (nCount > 0)
+	{
+		log_info( "init_special_area. The record count=%d\n", nCount );
+
+		while ( DBRes.GetNextRecod(Error) )
+		{
+			double start_x=0;
+			DBRes.GetField( "start_point_x",start_x, Error );
+			double start_y=0;
+			DBRes.GetField( "start_point_y",start_y, Error );
+			double start_z=0;
+			DBRes.GetField( "start_point_z",start_z, Error );
+			double end_x=0;
+			DBRes.GetField( "end_point_x",end_x, Error );
+
+			double end_y=0;
+			DBRes.GetField( "end_point_y",end_y, Error );
+
+			double end_z=0;
+			DBRes.GetField( "end_point_z",end_z, Error );
+
+			int areaid = 0;
+			DBRes.GetField( "special_area_id",areaid, Error );
+			std::string categoryid;
+			DBRes.GetField( "car_type",categoryid, Error );
+			
+			m_v.emplace_back(start_x,start_y,start_z,end_x,end_y,end_z,areaid,categoryid);
+
+			log_info("special area .....areaid:%d,categoryid:%s",areaid,categoryid.c_str());
+		}
+	}
+
+}
+void special_area_list::init_special_card()
+{
+	const char * sql = "SELECT b.vehicle_id,a.special_area FROM dat_special_card a , dat_vehicle b WHERE a.card_name = b.name;";
+	std::string Error;
+	YADB::CDBResultSet DBRes;
+	sDBConnPool.Query(sql,DBRes,Error);
+	int nCount = DBRes.GetRecordCount( Error );
+	if (nCount > 0)
+	{
+		log_info( "init_special_card. The record count=%d\n", nCount );
+
+		while ( DBRes.GetNextRecod(Error) )
+		{
+			int vehicle_id = 0;
+			DBRes.GetField( "vehicle_id",vehicle_id, Error );
+			
+			int areaid=0;
+			DBRes.GetField( "special_area",areaid, Error );
+
+			auto iter = m_m.find(areaid);
+			if(iter != m_m.end())
+				iter->second.push_back(vehicle_id);
+			else
+				m_m[areaid].push_back(vehicle_id);
+
+			log_info("special card .....areaid:%d,categoryid:%d %d ..... %d",areaid,vehicle_id,m_m.size(),m_m[areaid].size());
+		}
+	}
+
+
+}
+

+ 31 - 0
special_area.h

@@ -0,0 +1,31 @@
+#ifndef __SPECIAL_AREA_HPP
+#define __SPECIAL_AREA_HPP
+#include <map>
+#include <vector>
+#include "point.h"
+struct special_area_entry
+{
+	special_area_entry(double x,double y,double z,double ex,double ey, double ez,int32_t areaid,std::string categoryid)
+		:start_point(x,y,z)
+		 ,end_point(ex,ey,ez)
+		 ,special_area_id(areaid)
+		 ,car_type(categoryid)
+	{}
+	point		start_point;
+	point		end_point;
+	int			special_area_id;
+	std::string car_type;
+};
+struct special_area_list
+{
+	std::vector<special_area_entry> m_v;
+	std::map<uint32_t,std::vector<int32_t>> m_m;
+
+	int32_t get_special_id(uint32_t cardid,const point p,int32_t categoryid);
+	void init_from_db();
+	void init_special_area_entry();
+	void init_special_card();
+	static special_area_list * instance();
+};
+#endif
+

+ 88 - 1
websocket/jsonBuilder.cpp

@@ -18,7 +18,7 @@ namespace YA
 
 	}
 
-	std::string jsonBuilder::__FmtCardID( const _CARD_POS_ & CardPos )
+	std::string jsonBuilder::__FmtCardID( const _BASE_CARD_ & CardPos )
 	{
 		std::string ID;
 
@@ -182,6 +182,70 @@ namespace YA
 		DeptItem.AddMember( JSON_ROOT_KEY_STATISTIC_SUM, Sum, Allocator );
 	}
 
+	void jsonBuilder::__BuildBaseCardItem( const _BASE_CARD_ & Card, rapidjson::Document::AllocatorType & Allocator, rapidjson::Value & CardItem )
+	{
+		rapidjson::Value TmpObj( rapidjson::kObjectType );
+		rapidjson::Value CardObj( rapidjson::kArrayType );
+
+		//0 卡号
+		TmpObj.SetString( __FmtCardID( Card ).c_str(), Allocator );
+		CardObj.PushBack( TmpObj, Allocator );
+		
+		//1 x坐标
+		TmpObj.SetDouble( Card.x );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//2 y坐标
+		TmpObj.SetDouble( Card.y );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//3 入井时间戳
+		TmpObj.SetDouble( Card.down_time );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//4 进入区域时间戳
+		TmpObj.SetDouble( Card.enter_area_time );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//5 接收时间戳
+		TmpObj.SetDouble( Card.rec_time );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//6 工作时长
+		TmpObj.SetDouble( Card.work_time );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//7 地图编号
+		TmpObj.SetInt( Card.map_id );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//8 区域编号
+		TmpObj.SetInt( Card.area_id );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//9 部门编号
+		TmpObj.SetInt( Card.dept_id );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//10 状态
+		TmpObj.SetInt( Card.stat );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//11 运行状态
+		TmpObj.SetInt( Card.running_stat );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//12 业务状态
+		TmpObj.SetInt( Card.biz_stat );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		//13 速度
+		TmpObj.SetDouble( Card.speed );
+		CardObj.PushBack( TmpObj, Allocator );
+
+		CardItem = CardObj;
+	}
+
 	void jsonBuilder::__CreateDeptMap( const _CARD_POS_ & CardPos, std::map<int, _STAT_DEPT_ITEM_>& DeptMap )
 	{
 		std::map<int, _STAT_DEPT_ITEM_>::iterator mit_dept_map;
@@ -390,6 +454,29 @@ namespace YA
 		return sb.GetString();
 	}
 
+	std::string jsonBuilder::BuildSpecialAreaProcess( const _BASE_CARD_ & stCard )
+	{
+		rapidjson::StringBuffer sb;
+		rapidjson::Writer<rapidjson::StringBuffer> writer( sb );
+		rapidjson::Document doc;
+		rapidjson::Document::AllocatorType& Allocator = doc.GetAllocator();
+
+		rapidjson::Value root( rapidjson::kObjectType );
+		__SetCmd( JSON_CMD_VALUE_SPECIAL_AREA_UP_MINE, root, Allocator );
+
+		rapidjson::Value CardItem( rapidjson::kObjectType );
+		rapidjson::Value CardList( rapidjson::kArrayType );
+
+		__BuildBaseCardItem( stCard, Allocator, CardItem );
+		CardList.PushBack( CardItem, Allocator );
+
+		root.AddMember( JSON_ROOT_KEY_DATA, CardList, Allocator );
+
+		root.Accept( writer );
+
+		return sb.GetString();
+	}
+
 	bool jsonBuilder::ParseCall_Card_Req( const std::string& JasonText, _JS_CALL_CARD_REQ_& CallCardReq, std::string& Error )
 	{
 		rapidjson::Document doc;

+ 36 - 2
websocket/jsonBuilder.h

@@ -125,6 +125,24 @@ namespace YA
 		void __BuildDeptItem( const _STAT_DEPT_ITEM_& st_dept_item, rapidjson::Document::AllocatorType& Allocator, rapidjson::Value& DeptItem );
 		/**
 		* @brief
+		构造基础卡项json对象函数。
+
+		* @param  [in] const _BASE_CARD_& Card  基础卡对象\n
+		* @param  [out] rapidjson::Document::AllocatorType& Allocator  分配器\n
+		* @param  [out] rapidjson::Value& CardItem  生成的卡json对象\n
+
+		* @return 无\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void __BuildBaseCardItem( const _BASE_CARD_& Card, rapidjson::Document::AllocatorType& Allocator, rapidjson::Value& CardItem );
+		/**
+		* @brief
 		生成Dept Map函数。
 
 		* @param  [in] const _CARD_POS_& CardPos  卡定位数据\n
@@ -180,7 +198,7 @@ namespace YA
 		* @brief
 		格式化生成卡号函数。
 
-		* @param  [in] const _CARD_POS_& CardPos  卡位置\n
+		* @param  [in] const _BASE_CARD_& CardPos  卡位置\n
 
 		* @return 格式化生成的卡号\n
 
@@ -191,7 +209,7 @@ namespace YA
 		* @bug
 
 		*/
-        std::string __FmtCardID( const _CARD_POS_& CardPos );
+        std::string __FmtCardID( const _BASE_CARD_& CardPos );
 	public:
 		jsonBuilder();
 		virtual ~jsonBuilder();
@@ -229,6 +247,22 @@ namespace YA
 		std::string BuildCardPos( const std::map<int, _CARD_POS_>& CardPosList );
 		/**
 		* @brief
+		生成车辆进入特殊区域jason函数。
+
+		* @param  [in] const _BASE_CARD_& Card  卡结构体\n
+
+		* @return 如果成功返回生成的json字符串,否则返回空字符串\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		std::string BuildSpecialAreaProcess( const _BASE_CARD_& stCard );
+		/**
+		* @brief
 		解析呼叫结构体函数。
 
 		* @param  [in] const _JS_LOGIN_& Login  登录参数\n

+ 7 - 1
websocket/wsClientMgr.cpp

@@ -154,4 +154,10 @@ namespace YA
 
 		return true;
 	}
-}
+
+	void wsClientMgr::SendSpecialAreaProcess( const _BASE_CARD_ & stCard )
+	{
+		std::string strjson = __jsBuilder.BuildSpecialAreaProcess( stCard );
+		send( JSON_CMD_VALUE_PUSH, strjson );
+	}
+}

+ 22 - 1
websocket/wsClientMgr.h

@@ -26,9 +26,13 @@ websocket客户端管理器类
 #include <string>
 #include <map>
 
-#include "wsClient.h"
 #include <boost/serialization/singleton.hpp>
 
+#include "wsClient.h"
+#include "ws_common.h"
+#include "jsonBuilder.h"
+
+
 namespace YA
 {
 	class wsClientMgr
@@ -38,6 +42,7 @@ namespace YA
 		std::map<std::string,int>  __uriIndexList;//uri和客户端下标对应表
 		std::string __LastError;//最新错误
 		std::recursive_mutex __lock;//锁
+		jsonBuilder __jsBuilder;//json生成器
 	public:
 		wsClientMgr();
 		~wsClientMgr();
@@ -223,6 +228,22 @@ namespace YA
 
 		*/
 		bool IsSktOpened();
+		/**
+		* @brief
+		发送车辆进入特殊区域函数。
+
+		* @param  [in] const _BASE_CARD_& stCard  卡结构体\n
+
+		* @return 无\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void SendSpecialAreaProcess( const _BASE_CARD_& stCard );
 	};
 }
 

+ 37 - 25
websocket/ws_common.h

@@ -46,16 +46,15 @@ namespace YA
 
 	/**
 	* @brief
-	卡位置结构体。
+	基础卡信息结构体。
 	*/
-	struct _CARD_POS_
+	struct _BASE_CARD_
 	{
 		int Type;//卡类型
 		int ID;//卡ID
 		double x;//x坐标
 		double y;//y坐标
 		double z;//z坐标
-		double speed;//速度
 		double down_time;//入井时间戳
 		double enter_area_time;//进入区域时间戳
 		double rec_time;//最后接收时间戳
@@ -63,9 +62,37 @@ namespace YA
 		int map_id;//地图编号
 		int area_id;//区域ID
 		int dept_id;//部门编号
-		int stat;//低电量告警
-		int running_stat; //运动状态
-		int biz_stat;//业务状态 呼救呼叫盲区等
+		int stat;//状态
+		int running_stat;//运行状态
+		int biz_stat;//业务状态
+		double speed;//速度
+		_BASE_CARD_()
+		{
+			Type            = 0;
+			ID              = 0;
+			x               = 0;
+			y               = 0;
+			z               = 0;
+			down_time       = 0;
+			enter_area_time = 0;
+			rec_time        = 0;
+			work_time       = 0;
+			map_id          = 0;
+			area_id         = 0;
+			dept_id         = 0;
+			stat            = 0;
+			running_stat    = 0;
+			biz_stat        = 0;
+			speed           = 0.0;
+		}
+	};
+
+	/**
+	* @brief
+	卡位置结构体。
+	*/
+	struct _CARD_POS_ : public _BASE_CARD_
+	{
 		int landmark_id;//地标编号
 		int lm_direction;//地标方向
 		int landmark_dis;//距离地标的距离
@@ -74,27 +101,12 @@ namespace YA
 		int display;//是否显示(1:显示,0:不显示)
 		void Clear()
 		{
-			Type       = 0;
-			ID         = 0;
-			x          = 0.0;
-			y          = 0.0;
-			z          = 0.0;
-			speed      = 0.0;
-			down_time  = 0.0;
-			enter_area_time = 0.0;
-			rec_time   = 0.0;
-			work_time  = 0.0;
-			map_id     = 0;
-			area_id    = 0;
-			dept_id    = 0;
-			stat = 0;
-			biz_stat = 0;
-			landmark_id = 0;
+			landmark_id  = 0;
 			lm_direction = 0;
 			landmark_dis = 0;
-			level_id = 0;
-			is_on_duty = 0;
-			display    = 1;//默认显示
+			level_id     = 0;
+			is_on_duty   = 0;
+			display      = 1;//默认显示
 		}
 		_CARD_POS_()
 		{