Browse Source

monkeycar , and push card point to web

lixioayao 6 years ago
parent
commit
f40cd71b08
51 changed files with 4847 additions and 2087 deletions
  1. 1 0
      .gitignore
  2. 0 0
      In file included from area.cpp
  3. 71 8
      Makefile
  4. 2 2
      Makefile.am
  5. 71 8
      Makefile.in
  6. 5 8
      ant.cpp
  7. 2 2
      ant.h
  8. 253 56
      area.cpp
  9. 97 29
      area.h
  10. 19 19
      autom4te.cache/requests
  11. 163 41
      card.cpp
  12. 20 5
      card.h
  13. 2 1
      card_path.cpp
  14. 0 2
      data_reader_antenna.txt
  15. 169 0
      landmark.cpp
  16. 58 0
      landmark.h
  17. 22 3
      main.cpp
  18. 84 0
      monkey_car/base_data.h
  19. 152 0
      monkey_car/fp_path.h
  20. 170 0
      monkey_car/linear_fit.h
  21. 218 0
      monkey_car/monkey_fit.h
  22. 140 0
      monkey_car/monkeycar_area.cpp
  23. 65 0
      monkey_car/monkeycar_area.h
  24. 109 0
      monkey_car/monkeycar_bus.cpp
  25. 67 0
      monkey_car/monkeycar_bus.h
  26. 244 0
      monkey_car/monkeycar_person.cpp
  27. 78 0
      monkey_car/monkeycar_person.h
  28. BIN
      path
  29. 0 1
      path_tof.txt
  30. 2 1
      point.cpp
  31. 2 1
      point.h
  32. 10 10
      select_tool.cpp
  33. 31 17
      select_tool.h
  34. BIN
      sio.tar.gz
  35. 21 0
      timestamp.h
  36. 192 192
      websocket/constdef.h
  37. 350 23
      websocket/jsonBuilder.cpp
  38. 184 2
      websocket/jsonBuilder.h
  39. 5 21
      websocket/jsonCommon.h
  40. 35 35
      websocket/singleton_test_class1.cpp
  41. 8 8
      websocket/singleton_test_class1.h
  42. BIN
      websocket/socket.io-client-cpp_test.cpp
  43. 256 225
      websocket/thread_safe_map.h
  44. 254 253
      websocket/wsClient.cpp
  45. 380 380
      websocket/wsClient.h
  46. 156 141
      websocket/wsClientMgr.cpp
  47. 232 232
      websocket/wsClientMgr.h
  48. 115 81
      websocket/wsTimerThread.cpp
  49. 207 202
      websocket/wsTimerThread.h
  50. 124 77
      websocket/ws_common.h
  51. 1 1
      write-copy.h

+ 1 - 0
.gitignore

@@ -5,6 +5,7 @@
 *.out
 *.raw
 /.deps/
+/bak/
 /autom4te.cache/
 Makefile
 config.log

+ 0 - 0
In file included from area.cpp


File diff suppressed because it is too large
+ 71 - 8
Makefile


File diff suppressed because it is too large
+ 2 - 2
Makefile.am


File diff suppressed because it is too large
+ 71 - 8
Makefile.in


+ 5 - 8
ant.cpp

@@ -58,18 +58,15 @@ void sit_list::read_sit_list(const char*fname)
 			continue;
 		auto tmp = m_instance->get(id);
 		if(tmp==nullptr)
-		{
-			tmp = std::make_shared<site>();
-			tmp->m_id=id;
-		}
+			tmp = std::make_shared<site>(id);
 		tmp->m_ant[antid].set(atof(s[4]),-atof(s[5]));
-		instance()->add(id,tmp);
+		sit_list::instance()->add(id,tmp);
 		//std_info("211111 id=%dsize = %d",id,instance()->m_map.size());
 		//m_list[id].m_id=id;
 		//m_list[id].m_ant[antid].set(atof(s[4]),-atof(s[5]));
 	}
 	
-	for(auto&sit_:m_instance->m_map)
+	for(auto&sit_:sit_list::instance()->m_map)
 	{
 		auto & sit = *(sit_.second);
 		if(sit.m_id==-1)
@@ -98,7 +95,7 @@ void sit_list::read_ant_path(const char*fname)
 			continue;
 
 		id=atoi(s[0]);
-		auto s_ = m_instance->get(id);
+		auto s_ = sit_list::instance()->get(id);
 		if(s_==nullptr)
 			continue;
 
@@ -145,7 +142,7 @@ void sit_list::read_ant_path(const char*fname)
 	}
 	fclose(fp);
 
-	for(auto&_s:m_instance->m_map)
+	for(auto&_s:sit_list::instance()->m_map)
 	{
 		auto & s = *(_s.second);
 		if(s.m_id==-1)

+ 2 - 2
ant.h

@@ -91,7 +91,7 @@ struct ant :point
                     pt = point(p.m_line[1][0].x+d*p.m_line[1].cos(),p.m_line[1][0].y+d*p.m_line[1].sin());
                 }
                 v.push_back(pt);
-                std_info("get_sol:x:%.2f,y:%.2f",pt.x,pt.y);
+                //std_info("get_sol:x:%.2f,y:%.2f",pt.x,pt.y);
             }
             else
                 std_error("%s","ant::getsol empty path..");
@@ -187,7 +187,7 @@ struct site:point
 	std::string to_string()const
 	{
         std::stringstream ss;
-        ss<<"site_id:"<<m_id<<"x:"<<x<<" y: "<<y;
+        ss<<"site_id:"<<m_id<<"x:"<<x<<" y: "<<y<<" scale:"<<m_scale;
         for(const auto a:m_ant)
         {  
             ss<<"<";

+ 253 - 56
area.cpp

@@ -1,96 +1,293 @@
 #include <memory>
 #include <write-copy.h>
+#include "db_api/CDBConnPool.h"
+#include "log.h"
 
 #include <area.h>
+#include "point.h"
+#include "monkey_car/monkeycar_area.h"
+#include "landmark.h"
+
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
 
 template<> std::shared_ptr<area_list> 
 single_base<area_list, int, std::shared_ptr<area>>::m_instance=std::make_shared<area_list>();
 
-struct area_impl
-{
-	area_impl()
-	{
-	}
-
+void area::on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
+ {
+ 	//check超时
+	log_info("on_hover..%d  areaId:%d",card_id,m_id);
+ 	time_t now = time(NULL);
+ 	if(now-c->m_enter_time>m_limit_time_second && !c->m_is_over_time)
+ 	{
+ 		c->m_is_over_time=true;
+ 		//产生告警
+ 	}
+ }
 
-    void on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double speed)
-	{
-
-	}
+void area::on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
+{
+	log_info("on_enter..%d  areaId:%d",card_id,m_id);
+	//入库 : 进入区域
+	int cu = m_card_count.load();
+	cu++;
+	m_card_count.store(cu);
+	//check超员
+}
 
-    void on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed)
+void area::on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
+{
+	log_info("on_leave..%d  areaId:%d",card_id,m_id);
+	//入库 : 出 区域
+	int cu = m_card_count.load();
+	m_card_count.store(cu--);
+	//check 超员
+	if(c->m_is_over_time)
 	{
-	
+		//取消告警
 	}
+}
+bool area::in_area(const point & p)
+{
+	if(m_bound.empty())
+	  return false;
+	int counter = 0;
+	double xinters;
+	point p1,p2;
 
-    void on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed)
-	{
-	
-	
+	p1 = m_bound[0];
+	int size = m_bound.size();
+	for (int i=1;i<= size;i++) {
+		p2 = m_bound[i%size];
+		if (p.y > std::min(p1.y,p2.y)) {
+			if (p.y <= std::max(p1.y,p2.y)) {
+				if (p.x <= std::max(p1.x,p2.x)) {
+					if (p1.y != p2.y) {
+						xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
+						if (p1.x == p2.x || p.x <= xinters)
+						  counter++;
+					}
+				}
+			}
+		}
+		p1 = p2;
 	}
-};
+	return (counter % 2 == 0) ? false : true;
+}
 
 area_list::area_list()
 {
 }
-
-std::vector<std::shared_ptr<area>> area_list::get_area(const point&pt)
+void area_list::init_monkeycar_area()
 {
-	std::vector<std::shared_ptr<area>> ret;
-	//需要添加根据点查找区域的算法
+	std::unordered_map<int,std::shared_ptr<area>> map;
+	const char *sql = "SELECT a.area_id, a.name, a.map_id, a.area_type_id, a.path, c.scale,\
+						over_count_person, over_count_vehicle, over_time_person, over_time_vehicle, over_speed_vehicle, is_attendance ,b.monkeycar_coordinate,b.monkeycar_speed \
+						FROM dat_area a ,dat_monkeycar_base_info b ,dat_map c\
+						where a.area_id = b.monkeycar_areaid and a.map_id = c.map_id;";
+	std::string Error;
+	YADB::CDBResultSet DBRes;
+	sDBConnPool.Query(sql,DBRes,Error);
+	if(!Error.empty())
+		log_error("monkeycar area init Error,%s",Error.c_str());
+	int nCount = DBRes.GetRecordCount( Error );
+	if (nCount > 0)
+	{
+		log_info( "init_monkey area. The record count=%d", nCount );
 
+		while ( DBRes.GetNextRecod(Error) )
+		{
+			int area_id  = 0;
+			DBRes.GetField( "area_id",area_id, Error );
 
+			int map_id  = 0;
+			DBRes.GetField( "map_id",map_id, Error );
 
-	return std::move(ret);
-}
+			unsigned int area_type_id  = 0;
+			DBRes.GetField( "area_type_id",area_type_id, Error );
+			
+			int over_count_person = 0;
+			DBRes.GetField( "over_count_person",over_count_person, Error );
 
+			int over_count_vehicle = 0;
+			DBRes.GetField( "over_count_vehicle",over_count_vehicle, Error );
 
-void area_tool::on_point(int64_t card_id,const point&pt,double speed)
-{
-	std::vector<std::shared_ptr<area>> areas=area_list::instance()->get_area(pt);//找出所有的区域
-	std::sort(areas.begin(),areas.end(),[](std::shared_ptr<area>&l,std::shared_ptr<area>&r){
-			return l->id()<r->id();
-			});
+			int over_time_person = 0;
+			DBRes.GetField( "over_time_person",over_time_person, Error );
 
-	auto c1=m_clist.begin(),ce=m_clist.end();
-	auto a1=areas.begin() ,ae=areas.end();
+			int over_time_vehicle = 0;
+			DBRes.GetField( "over_time_vehicle",over_time_vehicle, Error );
 
-	std::vector<std::shared_ptr<area_hover>> nlist;
+			std::string path;
+			DBRes.GetField( "path",path, Error );
+			
+			float monkeycar_speed = 0;
+			DBRes.GetField( "monkeycar_speed",monkeycar_speed, Error );
 
-	while (c1!=ce && a1!=ae)
-	{
-		if ((*c1)->id()<(*a1)->id()) 
-		{ 
-			do_leave_biz(card_id,*c1,speed);
-			++c1;
+			std::string monkeycar_coor;
+			DBRes.GetField( "monkeycar_coordinate",monkeycar_coor, Error );
+
+			float scale=0;
+			DBRes.GetField( "scale",scale, Error );
+
+
+			log_info("init_area : id:%d,path:%s",area_id, path.c_str());
+
+			std::shared_ptr<db_area>  da = std::make_shared<db_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);
+
+			ap->m_bound=init_path(path);
+			for(const auto &p : ap->m_bound)
+			  log_info("point:monkey:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
+			for(const auto &p : da->m_point)
+			  log_info("point:monkey_coor:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
+
+			map.insert({area_id,ap});
 		}
-		else if ((*a1)->id()<(*c1)->id()) 
+	}
+	
+	area_list::instance()->add(map);
+}
+void area_list::init_from_db()
+{
+	std::unordered_map<int,std::shared_ptr<area>> map;
+	const char *sql = "SELECT a.area_id, a.name, a.map_id, a.area_type_id, a.path,b.scale, \
+						over_count_person, over_count_vehicle, over_time_person, over_time_vehicle, over_speed_vehicle, is_attendance \
+						FROM dat_area a,dat_map b\
+						where a.map_id = b.map_id and  area_id not in (select monkeycar_areaid from dat_monkeycar_base_info);";
+	std::string Error;
+	YADB::CDBResultSet DBRes;
+	sDBConnPool.Query(sql,DBRes,Error);
+	if(!Error.empty())
+		log_error("monkeycar area init Error,%s",Error.c_str());
+	int nCount = DBRes.GetRecordCount( Error );
+	if (nCount > 0)
+	{
+		log_info( "init_area. The record count=%d\n", nCount );
+
+		while ( DBRes.GetNextRecod(Error) )
 		{
-			nlist.push_back(std::make_shared<area_hover>(*a1,pt,speed));
-			do_enter_biz(card_id,nlist.back(),speed);
-			++a1;
-		}
-		else 
-		{ 
-			nlist.push_back(*c1);
-			do_hover_biz(card_id,nlist.back(),speed);
-			++c1,++a1;
+			int area_id  = 0;
+			DBRes.GetField( "area_id",area_id, Error );
+
+			int map_id  = 0;
+			DBRes.GetField( "map_id",map_id, Error );
+
+			unsigned int area_type_id  = 0;
+			DBRes.GetField( "area_type_id",area_type_id, Error );
+			
+			int over_count_person = 0;
+			DBRes.GetField( "over_count_person",over_count_person, Error );
+
+			int over_count_vehicle = 0;
+			DBRes.GetField( "over_count_vehicle",over_count_vehicle, Error );
+
+			int over_time_person = 0;
+			DBRes.GetField( "over_time_person",over_time_person, Error );
+
+			int over_time_vehicle = 0;
+			DBRes.GetField( "over_time_vehicle",over_time_vehicle, Error );
+
+			std::string path;
+			DBRes.GetField( "path",path, Error );
+		
+			double scale = 0;
+			DBRes.GetField( "scale",scale, Error );
+
+			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);
+			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);
+
+			map.insert({area_id,ap});
 		}
 	}
+	
+	area_list::instance()->add(map);
+
+	init_monkeycar_area();
+
+	}
+std::vector<point> area_list::init_path(std::string &str)
+{
+	if(str.empty())
+	  log_error("area path empty()...");
+	std::vector<point> vp;
+	std::vector<std::string> vs;
+	std::vector<std::string> vs1;
+	boost::split(vs,str,boost::is_any_of("ML ;"));
+	for(auto & s:vs)
+	{
+		if(s.empty())
+		  continue;
+		boost::split(vs1,s,boost::is_any_of(","));
+		if(vs1.size()!=2)
+		  log_error("area path data Error.pls check data table.");
+		vp.emplace_back(atof(vs1[0].c_str()),atof(vs1[1].c_str()));
+	}
+	return std::move(vp);
+}
+std::shared_ptr<area> area_list::get_area(const point&pt)
+{
+	std::shared_ptr<area> ret=nullptr;
+		
+	auto map = area_list::instance()->m_map;
 
-	while(c1!=ce)
+	for(const auto &a:map)
 	{
-		do_leave_biz(card_id,*c1,speed);
-		++c1;
+		if(a.second->in_area(pt))
+		  ret = a.second;
 	}
+	//区域覆盖不完全地图,很多车辆人行驶在地图外,如何确认.
+	return ret;
+}
 
-	while(a1!=ae)
+
+void area_tool::on_point(int64_t card_id,const point&pt,double speed,int16_t type)
+{
+	log_info("on_point...cardid:%d,type:%d",card_id,type);
+	//获取地标信息
+	setLandmark(pt);
+	if(m_area_hover != nullptr && m_area_hover->m_area->in_area(pt))
 	{
-		nlist.push_back(std::make_shared<area_hover>(*a1,pt,speed));
-		do_enter_biz(card_id,nlist.back(),speed);
-		++a1;
+		do_hover_biz(card_id,speed,type);
 	}
+	else
+	{
+		auto area = area_list::instance()->get_area(pt);
+		if(area == nullptr)
+		{
+			//这里使用分站区域比较合理
+			log_error("Cardid:%d can not find area..[x:%.2f,y:%.2f]",card_id,pt.x,pt.y);
+			return;
+		}
+		if(m_area_hover==nullptr)
+		{
+			m_area_hover = std::make_shared<area_hover>(area,pt,speed);
+			do_enter_biz(card_id,speed,type);
+		}
+		else
+		{
+			do_leave_biz(card_id,speed,type);
 
-	m_clist=std::move(nlist);
+			m_area_hover.reset(new area_hover(area,pt,speed));
+			do_enter_biz(card_id,speed,type);
+		}
+	}
+}
+void area_hover::setLandmark(const point &pt)
+{
+	set(pt);
+	auto lm = Landmark_list::instance()->get(mapid(),id(),pt);
+	landmark_id = std::get<0>(lm);
+	landmark_dir = std::get<1>(lm);
+	landmark_dis = std::get<2>(lm)*scale();
+	log_info("landmark:%d %d %.2f",landmark_id,landmark_dir,landmark_dis);
 }
 

+ 97 - 29
area.h

@@ -7,45 +7,73 @@
 #include <point.h>
 
 #include <write-copy.h>
+//下午查看代码,整理了一下思路,如下
+//普通区域和考勤区域就不分开了,使用同一个具现类,至于里面的操作,是否区域告警之类的可以通过数据库配置进行控制,比如超员可以查看超员配置是否为0,0则不会进行告警
+//其他区域 井上和井下 考勤区域则不在区域模块进行考虑
+//猴车区域拥有一般区域的行为,所以打算通过继承方式
+//区域超速win版本有实现,没有应用,统一是井下超速,这里待讨论
+//区域超员win版本是通过一个线程循环来进行判断的。这里我觉着可以不采用
+//区域超时win版本的确是当有点过来的时候才会进行判断。这里需讨论是否满足需求,即丢失信号,是否进行告警判断
+//告警对象:分井下 卡  分站 区域 ,不同的告警对象下分不同的告警类型,告警类型分人和车(win版本设计)。
+//考虑到业务需要,以及重叠区域,之前(志军哥)的代码设计可能不使用。至于以后是否考虑重叠区域,后续可以有需求再处理。
+//代码中有对通过坐标点找不到区域的逻辑,使用的是分站注册时候的区域id,这块是否沿用之前思路。
+//益俊那边的json组装需尽快提供
+//月腾那边的区域代码逻辑尽快完善,这边可能需要在你代码实现的基础上进行操作,框架可以先给我
+//区域超员,超时,人车阈值win版本不同,这里需讨论
+//区域进出,插入的数据库表,人车分离。
 
 struct area_hover;
 struct point;
 struct area
 {
-	area()
+	area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid)
+		:m_id(id)
+		 ,m_limit_time_second(limit_time_person)
+		 ,m_limit_person_count(limit_count_person)
+		,m_scale(scale)
+		,m_mapid(mapid)
 	{
 	}
 
-    virtual void on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double speed)=0;
-    virtual void on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed)=0;
-    virtual void on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed)=0;
+    virtual void on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
+    virtual void on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
+    virtual void on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
 
+	bool in_area(const point & p);
 	int id()const
 	{
 		return m_id;
 	}
-
+	int mapid()const
+	{
+		return m_mapid;
+	}
+	double scale()const
+	{
+		return m_scale;
+	}
+	virtual ~area()
+	{}
+	std::vector<point> m_bound;
+private:
 	std::atomic<int> m_card_count;
-
 	int    m_id;
 	double m_limit_speed;
 
-//	std::string m_name;
-//	int m_limit_time_second;
-//	int m_limit_person_count;
-//	int m_area_type;
-
-	std::vector<point> m_bound;
+	int m_limit_time_second;
+	int m_limit_person_count;
+	double m_scale;
+	int32_t m_mapid;
 };
 
 struct area_list:single_base<area_list,int,std::shared_ptr<area>>
 {
 	area_list();
 
-	std::vector<std::shared_ptr<area>> get_area(const point&pt);
-	void init_from_db()
-	{
-	}
+	std::shared_ptr<area> get_area(const point&pt);
+	std::vector<point> init_path(std::string  &str);
+	void init_from_db();
+	void init_monkeycar_area();
 };
 
 struct area_hover
@@ -54,22 +82,36 @@ struct area_hover
 	time_t m_enter_time,m_last_time;
 	point  m_enter_point,m_last_point;
 	int    m_num_speeding;
+	bool   m_is_over_time;
+
+	int landmark_id;
+	int landmark_dir;
+	double landmark_dis;
 
+	area_hover()=default;
 	area_hover(std::shared_ptr<area>&area,const point&pt,double speed)
 		:m_area(area)
 	{
 		m_enter_time=m_last_time=time(0);
 		m_enter_point=m_last_point=pt;
 		m_num_speeding=0;
-		if(speed>m_area->m_limit_speed)
-			m_num_speeding++;
+		landmark_id=0;
+		landmark_dir=0;
+		landmark_dis=0;
 	}
 
 	int id()const
 	{
 		return m_area->id();
 	}
-
+	int mapid()const
+	{
+		return m_area->mapid();
+	}
+	double scale()const
+	{
+		return m_area->scale();
+	}
 	bool operator == (const area_hover&o)const
 	{
 		return m_area->id()==o.m_area->id();
@@ -79,34 +121,60 @@ struct area_hover
 	{
 		return m_area->id()<o.m_area->id();
 	}
+	std::tuple<time_t,time_t,int,int,int,int,double> getLandmark()
+	{
+		return std::make_tuple(m_enter_time,m_last_time,mapid(),id(),landmark_id,landmark_dir,landmark_dis);
+	}
+	void setLandmark(const point &pt);
+	void set(const point&pt)
+	{
+		m_last_time=time(0);
+		m_last_point = pt;
+	}
 };
 
 //每张卡包含一个对象
 //在解析出数据点时,调用on_point
 struct area_tool
 {
-	std::vector<std::shared_ptr<area_hover>> m_clist;
-	void on_point(int64_t card_id,const point&pt,double speed);
+	std::shared_ptr<area_hover> m_area_hover=nullptr;
+	void on_point(int64_t card_id,const point&pt,double speed,int16_t type);
 
+	void setLandmark(const point &pt)
+	{
+		if(m_area_hover)
+		{
+			m_area_hover->setLandmark(pt);
+		}
+	}
+		
+	std::tuple<time_t,time_t,int,int,int,int,double> getLandmark()
+	{
+		if(m_area_hover)
+			return m_area_hover->getLandmark();
+		else
+		  return std::make_tuple(0,0,0,0,0,0,0);
+		
+	}
 	//检测是否超时
-    void on_timer(int64_t card_id)
+	void on_timer(int64_t card_id)
 	{
-	
+
 	}
 
-    void do_hover_biz(int64_t card_id,std::shared_ptr<area_hover>&a,double speed)
+	void do_hover_biz(int64_t card_id,double speed,int16_t type)
 	{
-		a->m_area->on_hover(card_id,a,speed);
+		m_area_hover->m_area->on_hover(card_id,m_area_hover,speed,type);
 	}
 
-    void do_enter_biz(int64_t card_id,std::shared_ptr<area_hover>&a,double speed)
+	void do_enter_biz(int64_t card_id,double speed,int16_t type)
 	{
-		a->m_area->on_enter(card_id,a,speed);
+		m_area_hover->m_area->on_enter(card_id,m_area_hover,speed,type);
 	}
 
-    void do_leave_biz(int64_t card_id,std::shared_ptr<area_hover>&a,double speed)
+	void do_leave_biz(int64_t card_id,double speed,int16_t type)
 	{
-		a->m_area->on_leave(card_id,a,speed);
+		m_area_hover->m_area->on_leave(card_id,m_area_hover,speed,type);
 	}
 };
 

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

+ 163 - 41
card.cpp

@@ -11,6 +11,9 @@
 #include "config_file.h"
 #include "db_api/CDBConnPool.h"
 #include "websocket/wsTimerThread.h"
+#include "timestamp.h"
+#include "monkey_car/monkeycar_area.h"
+#include "monkey_car/monkeycar_person.h"
 
 extern config_file config;
 //一张卡一个ct的所有不同天线的信息
@@ -77,7 +80,10 @@ struct one_ct_message_handle
 		}
 		auto sitPtr = sit_list::instance()->get(loc.m_site_id);
 		if(sitPtr==nullptr)
-		  return;
+		{
+			log_warn("分站信息缺失,SitId:%d",loc.m_site_id);
+			return;
+		}
 		const site &s=*(sit_list::instance()->get(loc.m_site_id));
 		if(m_msg_list.empty())
 		{
@@ -163,28 +169,135 @@ struct card_message_handle
 
 struct card_area
 {
-	std::shared_ptr<site_area_hover> m_site_area;
-	std::shared_ptr<area_tool> m_area_tool;
+	card_area()
+	{
+		m_site_area.reset(new site_area_hover);
+		m_area_tool.reset(new area_tool);
+	}
+	std::shared_ptr<site_area_hover> m_site_area=nullptr;
+	std::shared_ptr<area_tool> m_area_tool=nullptr;
 };
 
-struct person:card_location_base,card_area
+struct person:card_location_base,private card_area
 {
-	person(std::string type,uint32_t cardid,uint16_t needdisplay,int16_t t)
-        :card_location_base(type,cardid,needdisplay,t)
+	std::weak_ptr<monkey_person> m_monkeyPerson;
+
+	person(std::string type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid)
+        :card_location_base(type,cardid,needdisplay,t,deptid)
 	{
         m_message_handle=new  card_message_handle(this);
 	}
+
+	virtual void do_business(const point &pt)
+	{
+		//区域
+		m_area_tool->on_point(m_id,pt,m_speed,m_type);
+		//考勤
+		
+		//
+	}
+
+	void set(ev::dynamic_loop * loop)
+	{
+		log_info("cardid_id %d",m_id);
+	    m_loop = loop;
+	
+	    m_timer.set(*m_loop);
+	    m_timer.set<person,&person::on_timer>(this);
+		m_timer.start(1,1);
+	}
+	void reset(std::shared_ptr<monkey_person> mp)
+	{
+		m_monkeyPerson = mp;
+	}
 	~person(){}
+private:
+	void on_timer()
+	{    
+		YA::_CARD_POS_ cp;
+		point pt = getSmoothPoint();
+		const auto lm = m_area_tool->getLandmark();
+		cp.enter_area_time = std::get<0>(lm);
+		cp.rec_time = std::get<1>(lm);
+		cp.map_id = std::get<2>(lm);
+		cp.area_id = std::get<3>(lm);
+		cp.landmark_id = std::get<4>(lm);
+		cp.lm_direction = std::get<5>(lm);
+		cp.landmark_dis=std::get<6>(lm);
+		upt_card_pos(cp,pt);
+	}
+	point getSmoothPoint()
+	{
+		point pt;
+		loc_point lp = m_smo_tool->smooth_strategy();
+		m_speed = lp.m_speed;
+		m_stat  = lp.m_stat;
+		pt.x = lp.x;
+		pt.y = -lp.y;
+		if(auto  p = m_monkeyPerson.lock() )
+		{
+			if(p->is_on_bus())
+			{
+				m_stat = 7;
+				pt = p->getPoint();	
+			}
+		}
+		return pt;
+	}
 };
 
-struct car:card_location_base,card_area
+struct car:card_location_base,private card_area
 {
-	car(std::string type,uint32_t cardid,uint16_t needdisplay,int16_t t)
-        :card_location_base(type,cardid,needdisplay,t)
+	car(std::string type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid)
+        :card_location_base(type,cardid,needdisplay,t,deptid)
     {
         m_message_handle=new  card_message_handle(this);
     }
+
+	virtual void do_business(const point &pt)
+	{
+		m_area_tool->on_point(m_id,pt,m_speed,m_type);
+	}
+
+	void set(ev::dynamic_loop * loop)
+	{
+		log_info("cardid_id %d",m_id);
+	    m_loop = loop;
+	
+	    m_timer.set(*m_loop);
+	    m_timer.set<car,&car::on_timer>(this);
+		m_timer.start(1,1);
+	}
 	~car(){}
+private:
+	void on_timer()
+	{
+		YA::_CARD_POS_ cp;
+		point pt = getSmoothPoint();
+
+		const auto lm = m_area_tool->getLandmark();
+		cp.enter_area_time = std::get<0>(lm);
+		cp.rec_time = std::get<1>(lm);
+		cp.map_id = std::get<2>(lm);
+		cp.area_id = std::get<3>(lm);
+		cp.landmark_id = std::get<4>(lm);
+		cp.lm_direction = std::get<5>(lm);
+		cp.landmark_dis=std::get<6>(lm);
+		
+		//for now
+		cp.is_on_duty=1;
+		upt_card_pos(cp,pt);
+	}
+
+	point getSmoothPoint()
+	{
+		loc_point lp = m_smo_tool->smooth_strategy();
+		m_speed = lp.m_speed;
+		m_stat  = lp.m_stat;
+		lp.y = -lp.y;
+		return lp;
+	}
+
 };
 
 loc_tool_main one_ct_message_handle::m_loc_tool;
@@ -210,7 +323,6 @@ void card_list::init_vehicle()
 						LEFT JOIN dat_vehicle_category vc ON vc.vehicle_category_id = vt.vehicle_category_id \
 						WHERE c.card_type_id = 2 AND c.state_id = 0;";
 	std::string Error;
-	YADB::CDBHelper DBHelper;
 	YADB::CDBResultSet DBRes;
 	sDBConnPool.Query(sql,DBRes,Error);
 	int nCount = DBRes.GetRecordCount( Error );
@@ -222,6 +334,11 @@ void card_list::init_vehicle()
 		{
 			unsigned int vehicle_id  = 0;
 			DBRes.GetField( "vehicle_id",vehicle_id, Error );
+
+			std::string card_id;
+			DBRes.GetField( "card_id",card_id, Error );
+
+			uint32_t vsid = atoi(card_id.substr(3).c_str());
 			
 			unsigned int card_type_id  = 0;
 			DBRes.GetField( "card_type_id",card_type_id, Error );
@@ -252,11 +369,13 @@ void card_list::init_vehicle()
 
 			double over_speed= 0;
 			DBRes.GetField( "over_speed",over_speed, Error );
+			
+			//for now
+			vehicle_id = vsid;
 
-
-			std::shared_ptr<card_location_base> clb = std::make_shared<car>(strategy,vehicle_id,need_display,card_type_id);
+			std::shared_ptr<card_location_base> clb = std::make_shared<car>(strategy,vehicle_id,need_display,card_type_id,dept_id);
 			uint64_t cardid = getId(vehicle_id,2);
-			log_info("cardId:%llu,vehicle_id:%d dept_id:%d,need_display:%d",cardid,vehicle_id,dept_id,need_display);
+			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());
 			map.insert({cardid,clb});
 		}
 	}
@@ -276,7 +395,6 @@ void card_list::init_staffer()
 						LEFT JOIN dat_occupation_level ol ON ol.occupation_level_id = o.occupation_level_id \
 						WHERE c.card_type_id = 1 AND s.duty_id = 0 AND c.state_id = 0;";
 	std::string Error;
-	YADB::CDBHelper DBHelper;
 	YADB::CDBResultSet DBRes;
 	sDBConnPool.Query(sql,DBRes,Error);
 	int nCount = DBRes.GetRecordCount( Error );
@@ -289,6 +407,11 @@ void card_list::init_staffer()
 			unsigned int staff_id  = 0;
 			DBRes.GetField( "staff_id",staff_id, Error );
 
+			std::string card_id;
+			DBRes.GetField( "card_id",card_id, Error );
+
+			uint32_t vsid = atoi(card_id.substr(3).c_str());
+			
 			unsigned int card_type_id  = 0;
 			DBRes.GetField( "card_type_id",card_type_id, Error );
 			
@@ -307,10 +430,12 @@ void card_list::init_staffer()
 			int need_display = 0;
 			DBRes.GetField( "need_display",need_display, Error );
 
+			//for now;
+			staff_id = vsid;
 
-			std::shared_ptr<card_location_base> clb = std::make_shared<person>(strategy,staff_id,need_display,card_type_id);
+			std::shared_ptr<card_location_base> clb = std::make_shared<person>(strategy,staff_id,need_display,card_type_id,dept_id);
 			uint64_t cardid = getId(staff_id,1);
-			log_info("cardId:%llu,staff_id:%d dept_id:%d,need_display:%d",cardid,staff_id,dept_id,need_display);
+			log_info("cardId:%llu,staff_id:%d dept_id:%d,need_display:%d--c-ard:%s",cardid,staff_id,dept_id,need_display,card_id.c_str());
 			map.insert({cardid,clb});
 		}
 	}
@@ -340,17 +465,27 @@ void card_list::on_message(zloop<task*> *loop,const message_locinfo&loc,bool is_
 	c->on_message(loop,loc,is_history);
 }
 //-----------------card_location_base..
-card_location_base::card_location_base(std::string type,uint32_t id,uint16_t dis,int16_t t)
-	:card(id,dis,t)
+card_location_base::card_location_base(std::string type,uint32_t id,uint16_t dis,int16_t t,int32_t deptid)
+	:card(id,dis,t,deptid)
 {
     select_tool_manage::instance()->create_tool(type,m_sel_tool,m_smo_tool);
 }
 void card_location_base::on_location(const std::vector<point>&vp,const std::vector<loc_message> &lm )
 {
+	//ct timestamp;
+	m_ct = lm[0].m_card_ct;
+	m_time = lm[0].m_loc_time;
+
     loc_point pt = m_sel_tool->select_solution(vp,lm);
+	pt.y=-pt.y;
 	if(pt.m_useless)
-		log_info("loc_point,x:%.2f,y:%.2f",pt.x,pt.y);
+	{
+		x = pt.x;
+		y = pt.y;
 
+		log_info("card_id:%d,ct:%d,timestamp:%llu, loc_point,x:%.2f,y:%.2f ",m_id,m_ct,m_time,pt.x,pt.y);
+		do_business(pt);
+	}
 }
 
 void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history)
@@ -360,35 +495,22 @@ 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::set(ev::dynamic_loop * loop)
-{
-    m_loop = loop;
-
-    m_timer.set(*m_loop);
-    m_timer.set<card_location_base,&card_location_base::on_timer>(this);
-	m_timer.start(1,1);
-}
 
-void card_location_base::on_timer()
+void card_location_base::upt_card_pos(YA::_CARD_POS_ &cp,const point &pt)
 {
-	//push_point..
-    loc_point lp = m_smo_tool->smooth_strategy();
-	m_speed = lp.m_speed;
-	m_stat  = lp.m_stat;
-
-	YA::_CARD_POS_ cp;
-	cp.x = x;
-	cp.y = y;
-	cp.z = z;
+	cp.x = pt.x;
+	cp.y = pt.y;
+	cp.z = pt.z;
 	cp.Type=m_type;
 	cp.ID = m_id;
-	cp.speed = m_speed;
-	cp.stat = m_stat;
+	cp.speed = abs(ceil(m_speed));
+	cp.running_stat = m_stat;
+	cp.dept_id = m_deptid;
+	cp.display=m_display;
 
 	swsTimerThrd.upt_card_pos(cp);
-	//log_info("one seconds............later..............");
-}
 
+}
 
 card_location_base::~card_location_base()
 {

+ 20 - 5
card.h

@@ -6,26 +6,33 @@
 #include "ant.h"
 
 #include "write-copy.h"
+#include "websocket/ws_common.h"
 
 struct task;
 template<typename T> struct zloop;
 struct select_tool;
 struct smooth_tool;
+struct monkey_person;
+struct card_message_handle;
+
 enum STA_TYPE
 {
     STATUS_HELP=0,
     STATUS_LOW_POWER, 
 };
-struct card_message_handle;
+
 struct card:point
 {
-	card(uint32_t id,uint16_t dis,int16_t type)
+	card(uint32_t id,uint16_t dis,int16_t type,int32_t deptid)
 		:m_id(id)
 		,m_type(type)
 		,m_display(dis)
 		,m_speed(0)
 		,m_is_attendance(0)
 		,m_stat(0)
+		,m_ct(0)
+		,m_time(0)
+		,m_deptid(deptid)
 	{}
 	uint32_t m_id;				//卡号
 	int16_t  m_type;			//类型
@@ -33,25 +40,33 @@ struct card:point
 	double   m_speed;			//速度
 	int      m_is_attendance;	//井上井下状态  0初始状态 1 井上 2 井下
 	int		 m_stat;			//运动静止状态
+	uint16_t m_ct;				//ct
+	uint64_t m_time;			//时间戳
+	int32_t  m_deptid;			//部门编号
 };
 struct card_location_base:card
 {
     std::shared_ptr<select_tool> m_sel_tool=nullptr;
     std::shared_ptr<smooth_tool> m_smo_tool=nullptr;
 	card_message_handle *m_message_handle=nullptr;
+
     ev::dynamic_loop * m_loop = nullptr;
 	ev::timer m_timer;
 
     card_location_base()=default;
-    card_location_base(std::string type,uint32_t id,uint16_t dis,int16_t t);
-	void set(ev::dynamic_loop * loop);
-	void on_timer();
+    card_location_base(std::string type,uint32_t id,uint16_t dis,int16_t t,int32_t );
+
+	virtual void do_business(const point &pt)=0;
+	virtual void set(ev::dynamic_loop * loop)=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)
     {
     }
+	void upt_card_pos(YA::_CARD_POS_ &,const point &pt);
 	virtual ~card_location_base();
 };
 

+ 2 - 1
card_path.cpp

@@ -899,7 +899,8 @@ void test_find_poss_path(const card_path&cp ,const point&from)
 int main()
 {
 //	std::unique_ptr<sit_list> sites(new sit_list());
-	sit_list::instance()->load("data_reader_antenna.txt","path_tof.txt");
+	//sit_list::instance()->load("data_reader_antenna.txt","path_tof.txt");
+	sit_list::instance()->load("1.txt","2.txt");
 
 	card_path cp;
 

+ 0 - 2
data_reader_antenna.txt

@@ -128,8 +128,6 @@
 510, 605, 2, '605-2', 3003.15, 100, 0, 0, '2017-11-22 15:55:49'
 511, 606, 1, '606-1', 3005.85, 75, 0, 0, '2017-11-22 11:10:23'
 512, 606, 2, '606-2', 3006.35, 75, 0, 0, '2017-11-22 11:10:41'
-513, 607, 1, '607-1', 3640.8, -37.15, 0, 0, '2017-08-29 10:55:01'
-514, 607, 2, '607-2', 3640.8, -37.65, 0, 0, '2017-08-29 10:55:04'
 515, 608, 1, '608-1', 3640.8, -152.15, 0, 0, '2017-08-29 10:55:09'
 516, 608, 2, '608-2', 3640.8, -151.65, 0, 0, '2017-08-29 10:55:11'
 517, 609, 1, '609-1', 3479, -87.3, 0, 0, '2017-08-29 10:55:14'

+ 169 - 0
landmark.cpp

@@ -0,0 +1,169 @@
+#include "landmark.h"
+#include <cfloat>
+#include "db_api/CDBConnPool.h"
+#include "log.h"
+
+
+Landmark_list * Landmark_list::instance()
+{
+	static Landmark_list  lm_list;
+	return &lm_list;
+}
+void Landmark_list::init_mapDirection()
+{
+	const char * sql = "select map_direction_id, map_id, north_angle from dat_map_direction;";
+	std::string Error;
+	YADB::CDBResultSet DBRes;
+	sDBConnPool.Query(sql,DBRes,Error);
+	int nCount = DBRes.GetRecordCount( Error );
+	if (nCount > 0)
+	{
+		log_info( "init_map_direction. The record count=%d\n", nCount );
+
+		while ( DBRes.GetNextRecod(Error) )
+		{
+			int map_id  = 0;
+			DBRes.GetField( "map_id",map_id, Error );
+
+			int north_angle = 0;
+			DBRes.GetField( "north_angle",north_angle, Error );
+
+			std::shared_ptr<map_direction> md = std::make_shared<map_direction>(map_id,north_angle);
+			m_map.insert({map_id,md});
+			log_info("map_direction.....mapid:%d,north:%d",map_id,north_angle);
+		}
+	}
+}
+void Landmark_list::init_from_db()
+{
+	init_landmarkInfo();
+	init_mapDirection();
+}
+
+void Landmark_list::init_landmarkInfo()
+{
+	const char * sql = "select landmark_id, name, map_id, area_id, x, y, z from dat_landmark;";
+	std::string Error;
+	YADB::CDBResultSet DBRes;
+	sDBConnPool.Query(sql,DBRes,Error);
+	int nCount = DBRes.GetRecordCount( Error );
+	if (nCount > 0)
+	{
+		log_info( "init_landmark_info. The record count=%d\n", nCount );
+
+		while ( DBRes.GetNextRecod(Error) )
+		{
+			int landmark_id  = 0;
+			DBRes.GetField( "landmark_id",landmark_id, Error );
+
+			std::string name;
+			DBRes.GetField( "name",name, Error );
+
+			int map_id  = 0;
+			DBRes.GetField( "map_id",map_id, Error );
+
+			int area_id = 0;
+			DBRes.GetField( "area_id",area_id, Error );
+
+			double x = 0;
+			DBRes.GetField( "x",x, Error );
+
+			double y = 0;
+			DBRes.GetField( "y",y, Error );
+
+			double z = 0;
+			DBRes.GetField( "z",z, Error );
+			point p(x,y,z);
+			std::shared_ptr<LandmarkInfo> landmark = std::make_shared<LandmarkInfo>(p,landmark_id,name,map_id,area_id);
+			m_v.push_back(landmark);
+			log_info("landmark ......id:%d,name:%s,mapid:%d,area_id:%d,x:%.2f,y:%.2f,z:%.2f",landmark_id,name.c_str(),map_id,area_id,x,y,z);
+		}
+	}
+
+}
+
+std::tuple<int,int,double> Landmark_list::get(int mapid ,int areaid,const point &pt)
+{
+	int32_t id = -1;
+	double dis = DBL_MAX;
+	point p;
+	for(const auto &lm : m_v)	
+	{
+		if(lm->area_id == areaid)
+		{
+			double tmp = pt.dist(*lm);
+			if(tmp < dis)
+			{
+				id = lm->landmark_id;
+				dis=tmp;
+				p=*lm;
+			}
+		}
+	}
+	if(id==-1)
+	  return std::make_tuple(0,0,0);
+	int dir = GetDirectionType(pt,p,mapid);
+	return std::make_tuple(id,dir,dis);
+}
+DIRECTION_TYPE Landmark_list::GetDirectionType(point card_point, point landmark_point, int map_id)
+{
+	DIRECTION_TYPE direction = NODIRECTORY;
+	int x_offset = 0;
+	int y_offset = 0;
+	int angle = 0;
+	x_offset = card_point.x - landmark_point.x;
+	y_offset = card_point.y - landmark_point.y;
+
+	if(abs(x_offset) < 1)
+		x_offset = 0;
+	if(abs(y_offset) < 1)
+		y_offset = 0;
+
+	std::shared_ptr<map_direction> pMapDirectoryInfo = nullptr;
+	auto it = m_map.find(map_id);		
+	if(it == m_map.end())
+	{
+		return NODIRECTORY;
+	}
+	else
+	{ 
+		pMapDirectoryInfo = it->second;
+	}
+
+	if(0 == y_offset)
+	{
+		if(x_offset > 0)
+			angle = pMapDirectoryInfo->north_angle + 0;
+		if(x_offset < 0)
+			angle = pMapDirectoryInfo->north_angle - 180;
+	}
+	else if(0 == x_offset)
+	{
+		if(y_offset < 0)
+			angle = pMapDirectoryInfo->north_angle - 90;
+		if(y_offset > 0)
+			angle = pMapDirectoryInfo->north_angle + 90;
+	}
+	else if(abs(x_offset) >= abs(y_offset))
+	{
+		if(x_offset > 0)
+			angle = pMapDirectoryInfo->north_angle + 0;
+		if(x_offset < 0)
+			angle = pMapDirectoryInfo->north_angle - 180;
+	}
+	else
+	{
+		if(y_offset < 0)
+			angle = pMapDirectoryInfo->north_angle - 90;
+		if(y_offset > 0)
+			angle = pMapDirectoryInfo->north_angle + 90;
+	}
+
+	direction = (DIRECTION_TYPE)((angle % 360) / 90);
+	if(angle % 360 == 0)
+		direction = NORTH;
+	if((0 == y_offset) && (0 == x_offset))
+		direction = NODIRECTORY;
+
+	return direction;
+}

+ 58 - 0
landmark.h

@@ -0,0 +1,58 @@
+#ifndef __LAND_MARK_HPP__
+#define __LAND_MARK_HPP__
+#include <string>
+#include <vector>
+#include <map>
+#include <memory>
+#include <tuple>
+#include "point.h"
+enum DIRECTION_TYPE{
+	NODIRECTORY = 0,
+	EAST        = 1,
+	SOURTH      = 2,
+	WEST		= 3,
+	NORTH		= 4
+};
+struct LandmarkInfo:point
+{
+	LandmarkInfo()
+		:landmark_id(0)
+		 ,landmark_name("")
+		 ,map_id(0)
+		 ,area_id(0)
+	{}
+	LandmarkInfo(point &p,int id,std::string & n,int mapid, int areaid)
+		:point(p)
+		 ,landmark_id(id)
+		 ,landmark_name(n)
+		 ,map_id(mapid)
+		 ,area_id(areaid)
+	{}
+	int landmark_id;
+	std::string landmark_name;
+	int map_id;
+	int area_id;
+};
+struct map_direction
+{
+	map_direction(int mapid,int angle)
+		:map_id(mapid)
+		 ,north_angle(angle)
+	{}
+	int map_id;
+	int north_angle;
+};
+struct Landmark_list
+{
+	std::vector<std::shared_ptr<LandmarkInfo>> m_v;
+	std::map<int,std::shared_ptr<map_direction>> m_map;
+	static Landmark_list * instance();
+	void init_from_db();
+	void init_landmarkInfo();
+	void init_mapDirection();
+	//landmarkId landmark_direction  landmark_dis
+	std::tuple<int,int,double> get(int mapid,int areaid,const point &pt);
+	DIRECTION_TYPE GetDirectionType(point card_point, point landmark_point, int map_id);
+};
+#endif
+

+ 22 - 3
main.cpp

@@ -7,7 +7,9 @@
 
 #include "card.h"
 #include "ant.h"
+#include "area.h"
 #include "card_path.h"
+#include "landmark.h"
 
 #include <config_file.h>
 
@@ -17,11 +19,11 @@ struct Init_Setting
 	void init()
 	{
 		std::string url=config.get("service.websocket_url","ws://127.0.0.1:8086");
-		int32_t send_interval =config.get("service.interval_send_json_postion",1000);
+		int32_t send_interval =config.get("service.interval_send_json_postion",1);
 		std_info("json_interval:%d",send_interval);
 		std::vector<std::string> url_list;
 		url_list.push_back(url);
-		wsClientMgr_init(url_list,send_interval);//init websocket
+//		wsClientMgr_init(url_list,send_interval);//init websocket
 
 		YADB::_DB_POOL_SETTING_ DBSetting;
 
@@ -29,7 +31,7 @@ struct Init_Setting
 		DBSetting.User = config.get("db.user","root");
 		DBSetting.PWD = config.get("db.passwd","");
 		DBSetting.DBName = config.get("db.dbname","yaxt");
-		DBSetting.CharSet = config.get("db.charset","utf-8");
+		DBSetting.CharSet = config.get("db.charset","utf8");
 		DBSetting.TimeOut = config.get("db.conn_timeout",5);
 		DBSetting.PoolSize = config.get("db.conn_timeout",30);
 		_mysql_init(DBSetting);
@@ -37,6 +39,23 @@ struct Init_Setting
 		sit_list::instance()->load_from_db();
 
 		card_list::instance()->init_card_from_db();
+
+		area_list::instance()->init_from_db();
+		std_info("here....");
+		//test
+		point pt(3348,100);
+		int id = area_list::instance()->get_area(pt)->id();
+		std_info("test area:%d",id);
+
+		Landmark_list::instance()->init_from_db();
+		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);
+		}
 	}
 
 	void _mysql_init(YADB::_DB_POOL_SETTING_ &dps)

+ 84 - 0
monkey_car/base_data.h

@@ -0,0 +1,84 @@
+#ifndef __BASE_DATA__
+#define __BASE_DATA__
+#include <map>
+#include <list>
+#include <deque> 
+#include <vector>
+#include <cmath>
+
+struct point_2
+{
+	double x_;
+	double y_;
+
+	point_2()
+		:x_(0x12345678)
+		,y_(0x87654321)
+	{
+	}
+
+	point_2(double x,double y)
+		:x_(x),y_(y)
+	{}
+
+
+	void setX(double x)
+	{
+		x_ = x;
+	}
+	void setY(double y)
+	{
+		y_ = y;
+	}
+	static inline bool is_valid(const point_2&p)
+	{
+		const point_2 &pt=invalid_point();
+		return pt.x_!=p.x_ || pt.y_!=p.y_;
+	}
+
+	static inline const point_2& invalid_point()
+	{
+		static const point_2 pt;
+		return pt;
+	}
+
+	static inline double sqr(double x) 
+	{
+		return x*x;
+	}
+
+	double dist_to(double x,double y)
+	{
+		return std::sqrt(sqr(x-x_)+sqr(y-y_));
+	}
+
+	double dist_to(const point_2&pt)
+	{
+		return dist_to(pt.x_,pt.y_);
+	}
+};
+
+
+struct st_coord :point_2
+{
+	uint64_t	gen_time_;
+	uint16_t    m_ct;//ct
+	void clear()
+	{
+		gen_time_ = 0;
+		m_ct = 0;
+		x_ = 0;
+		y_ = 0;
+	}
+	void setTime(uint64_t t)
+	{
+		gen_time_ = t;
+	}
+	void setCT(uint16_t t)
+	{
+		m_ct = t;
+	}
+
+
+};
+#endif

+ 152 - 0
monkey_car/fp_path.h

@@ -0,0 +1,152 @@
+#ifndef _FP_PATH_HPP_
+#define _FP_PATH_HPP_
+
+#include <math.h>
+#include <assert.h>
+#include <vector>
+#include "base_data.h"
+#include "../point.h"
+
+struct fixed_point:point_2
+{
+	fixed_point(double x,double y)
+		:point_2(x,y)
+		,cos_(0),sin_(0)
+		,dist_(0)
+	{}
+
+	fixed_point(const point_2&pt)
+		:point_2(pt)
+		,cos_(0),sin_(0)
+		,dist_(0)
+		{}
+
+	fixed_point(const fixed_point&pt)
+		:point_2(pt)
+		,cos_(pt.cos_),sin_(pt.sin_)
+		,dist_(pt.dist_)
+		{}
+	double cos_;
+	double sin_;
+	double dist_;
+	double set_next_point(const point_2&p)
+	{
+		dist_ = dist_to(p);
+
+		assert(dist_>0);
+
+		double deta_x = p.x_-x_;
+		cos_ = deta_x/dist_;
+
+		double deta_y = p.y_-y_;
+		sin_ = deta_y/dist_;
+		return dist_;
+	}
+};
+struct fp_path
+{
+private:
+	std::vector<fixed_point> path_;
+	fp_path(const fp_path&);
+	double m_total_length;
+private:
+	static inline bool eq(double x1,double x2)
+	{
+		return fabs(x1-x2)<0.1;
+	}
+public:
+	fp_path()
+		:m_total_length(0)
+	{
+		path_.reserve(8);
+	}
+
+	template<typename iterator>
+	fp_path(iterator begin,iterator end)
+		:m_total_length(0)
+	{
+		for (;begin != end; ++ begin)
+		{
+			add_point(*begin);
+		}
+	}
+	void add_point(double x,double y)
+	{
+		add_point(point_2(x,y));
+	}
+	void add_point(const point &pt)
+	{
+		point_2 p(pt.x,pt.y);
+		add_point(p);
+	}
+	void add_point(const point_2&pt)
+	{
+		if(!path_.empty()) 
+		{
+			 double d = path_.back().set_next_point(pt); 
+			 m_total_length += d;
+		}
+
+		path_.push_back(pt);
+	}
+	double map(double x,double y)
+	{
+		
+		if(path_.size()<2)
+			return -1.;
+
+		double rc=0.;
+
+		auto it1=path_.begin(); 
+		double l1=it1->dist_to(x,y);
+		
+		auto it2=path_.begin(); ++it2;
+		for(; it2!=path_.end();++it2)
+		{
+			double l2=it2->dist_to(x,y);
+
+			if(eq(l1+l2, it1->dist_))
+			{
+				return rc+l1;
+			}
+
+			rc+=it1->dist_;
+
+			it1=it2;
+			l1=l2;
+		}
+
+		return -1.;
+	}
+
+	double  map(const point_2& p)
+	{
+		return map(p.x_, p.y_);
+	}
+
+	point_2  map(double dist)
+	{
+		if(path_.size()>1)
+		{
+			for(auto it=path_.begin(), _e=path_.end()-1; it!=_e;++it)
+			{
+				if(dist<=it->dist_)
+				{
+					return point_2(it->x_+it->cos_*dist,it->y_+it->sin_*dist);
+				}
+
+				dist-=it->dist_;
+
+				if(dist<0) 
+					break;
+			}
+		}
+
+		return point_2::invalid_point();
+	}
+	double get_total_length()
+	{
+		return m_total_length;
+	}
+};
+#endif

+ 170 - 0
monkey_car/linear_fit.h

@@ -0,0 +1,170 @@
+#ifndef _LINEAR_FIT_STUB_
+#define _LINEAR_FIT_STUB_
+
+#include <deque>
+#include <algorithm>
+#include <string.h>
+#include <map>
+#include <float.h>
+#include "base_data.h"
+
+
+struct linear_fit
+{
+private:
+	const size_t count_;
+	double a_,b_,t_[4];
+	std::deque<double> x_,y_;
+	//²»ÊÊÓÃ
+	//linear_fit(const linear_fit&)=delete;
+	//linear_fit(const linear_fit&);
+	void start_fit()
+	{
+		for(auto ix=x_.begin(), iy=y_.begin();  ix!=x_.end();  ++ix,++iy)
+		{  
+			t_[0] += *ix * *ix;
+			t_[1] += *ix;
+			t_[2] += *ix * *iy;
+			t_[3] += *iy;
+		}  
+
+		double t1=t_[0]*count_ - t_[1]*t_[1];
+
+		a_ = (t_[2]*count_ - t_[1]*t_[3]) / t1 ;
+		b_ = (t_[0]*t_[3] - t_[1]*t_[2]) / t1 ;
+		//debug_print_syslog(0,"[framework push]count:%d,k:%f,b:%f",count_,a_,b_);
+	}
+public:
+
+	linear_fit(int count)
+		:count_(count)
+	{
+		reset();
+	}
+
+	void reset()
+	{
+		a_=b_=0;
+		memset(&t_[0],0,sizeof(t_));
+		x_.resize(0);
+		y_.resize(0);
+	}
+
+	template<typename iteratorx,typename iteratory>
+	bool start(iteratorx xi,iteratory yi,size_t count)
+	{
+		reset();
+		std::copy_n(xi,count,std::back_inserter(x_));
+		std::copy_n(yi,count,std::back_inserter(y_));
+
+		if(count<count_)
+			return false;
+
+		while(count-- > count_)
+		{
+			x_.pop_front();
+			y_.pop_front();
+		}
+
+		start_fit();
+
+		return true;
+	}
+
+	bool push(double x,double y)
+	{
+		//debug_print_syslog(0,"[framework push]count:%d,  x:%.2f,y:%.2f",count_,x,y);
+		x_.push_back(x);
+		y_.push_back(y);
+
+		if(x_.size() < count_)
+		{
+			return false; //throw logic_exception(...)
+		}
+		else if(x_.size()==count_)
+		{
+			start_fit();
+			return true;
+		}
+		
+		t_[0] += x * x - x_.front()*x_.front();
+		t_[1] += x - x_.front();
+		t_[2] += x * y - x_.front() * y_.front();
+		t_[3] += y - y_.front();
+
+		x_.pop_front();
+		y_.pop_front();
+
+		double t1=t_[0]*count_ - t_[1]*t_[1];
+
+		a_ = (t_[2]*count_ - t_[1]*t_[3]) / t1 ;
+		b_ = (t_[0]*t_[3] - t_[1]*t_[2]) / t1 ;
+		//debug_print_syslog(0,"[framework push]count:%d,k:%f,b:%f",count_,a_,b_);
+
+
+		return true;
+	}
+
+	double getY(double x)const
+	{
+		return a_ * x + b_;
+	}
+	double getY(uint64_t x) const
+	{
+		return a_ * x + b_;
+	}
+	double getK()const
+	{
+		return a_;
+	}
+};
+
+
+struct comp_linear_fit
+{
+	std::map<int,linear_fit*> m_fit;
+	comp_linear_fit(const int* begin,const int* end)
+	{
+		for(;begin!=end;++begin)
+		{
+			m_fit.insert(std::make_pair(*begin,new linear_fit(*begin)));
+		}
+	}
+
+	~comp_linear_fit()
+	{
+		for_each(m_fit.begin(),m_fit.end(),[&](std::pair<int,linear_fit*> it){delete it.second;});
+	}
+
+	double getY(int num_point,uint64_t time)const
+	{
+		auto it=m_fit.find(num_point);
+		if(it==m_fit.end())
+		{
+			//throw 
+			return 0.0;
+		}
+
+		return it->second->getY(time);
+	}
+
+	double getK(int num_point)const
+	{
+		auto it=m_fit.find(num_point);
+		if(it==m_fit.end())
+		{
+			//throw 
+			return DBL_MAX;
+		}
+
+		return it->second->getK();
+	}
+
+	void push(uint64_t time, double x)
+	{
+		for_each(m_fit.begin(),m_fit.end(),[&](std::pair<int,linear_fit*> it){it.second->push(time,x);});
+	}
+};
+
+#endif
+

+ 218 - 0
monkey_car/monkey_fit.h

@@ -0,0 +1,218 @@
+#ifndef __MONKEY_FIT__
+#define __MONKEY_FIT__
+
+#include <cmath>
+#include <iterator>
+#include <map>
+#include <deque>
+#include <algorithm>
+#include "base_data.h"
+
+struct monkey_fit
+{	
+	virtual ~monkey_fit(){}
+	template<typename T> static double get_probab_max(T it,T ite,int sum,int N=3)
+	{
+		sum/=5;
+		sum=std::max(3,sum);
+
+		std::vector<std::tuple<T,T,float>> p;
+
+
+		if(N==0)
+		{
+			auto it0=it;
+			for(int i=0;it0!=ite;++it0,++i)
+			{
+				if(i%10==0) printf("\n");
+
+				printf("%5d:%2d,",it0->first,it0->second);
+			}
+			printf("\n");
+		}
+
+		int s=0;
+		for(auto i1=it;it!=ite;)
+		{
+			for(;s<sum && i1!=ite;++i1)
+				s+=i1->second;
+
+			if(s<sum) break;
+
+			p.push_back(std::make_tuple(it,i1,1.*s/(std::prev(i1)->first-it->first+1)));
+
+			s-=it->second; ++it;
+		}
+
+		std::sort(p.begin(),p.end(),[](const std::tuple<T,T,int>&l,const std::tuple<T,T,int>&r){
+			return 1.*std::get<2>(l) > 1.*std::get<2>(r);
+		});
+
+		int i=1;
+
+		auto it1=std::get<0>(p[0]);
+		auto it2=std::prev(std::get<1>(p[0]));
+
+		for(;i<(int)p.size();++i)
+		{
+			if(std::get<2>(p[i])!=std::get<2>(p[i-1]))
+				break;
+
+			if(std::get<0>(p[i])->first < it1->first)
+				it1=std::get<0>(p[i]);
+
+			if(std::prev(std::get<1>(p[i]))->second > it2->second)
+				it2=std::prev(std::get<1>(p[i]));
+		}
+
+		++it2;
+
+		double rc=0;
+		int    cc=0;
+		int    x=0;
+		for(;it1!=it2;++it1)
+		{
+			rc+=it1->first*it1->second;
+			cc+=it1->second;
+
+			if(N==0)
+			{
+				if(x++%10==0) printf("\n");
+				printf("%5d:%2d,",it1->first,it1->second);
+			}
+		}
+
+		if(N==0)
+			printf("\n");
+
+		return rc/cc;
+	}
+
+	int round(double value)
+	{
+		return (value > 0.0)?floor(value + 0.5):ceil(value - 0.5);
+	}
+	virtual void reset(double monkey_speed = 0){}
+	virtual void push(double time_second,double dist_meter) {}
+	virtual double get_K() = 0;
+};
+
+struct monkey_fit_b :monkey_fit
+{
+	static const int min_points = 60;
+	static const int BN = 20;
+	double k_init_;
+	int    count_;
+
+	std::map<int,int> probab_b;
+
+	monkey_fit_b()
+		:k_init_(0)
+		,count_(0)
+	{}
+	monkey_fit_b(double s)
+		:k_init_(s)
+		,count_(0)
+	{}
+
+	virtual void reset(double monkey_speed/*=0*/)
+	{
+		k_init_=monkey_speed;
+
+		count_=0;
+		probab_b.clear();
+	}
+
+	virtual void push(double time_second,double dist_meter)
+	{
+		double k=k_init_;
+
+		++count_;
+		double b=(dist_meter-k*time_second)*BN;
+		++probab_b[round(b)];
+	}
+
+	double get_dist(double time_second)const
+	{
+		return k_init_*time_second + get_B();
+	}
+
+	double get_K()
+	{
+		return k_init_;
+	}
+
+	double get_B()const
+	{
+		if(count_<min_points)
+			return 0;
+
+		if(probab_b.size()<3)
+			return 0;
+
+		return 1.*get_probab_max(probab_b.begin(),probab_b.end(),count_)/BN;
+	}
+};
+
+struct monkey_fit_k:monkey_fit
+{
+	static const int min_points=60;
+	static const int KN=50;
+	int			step_;
+	uint32_t    count_;
+	std::map<int,int> probab_k;
+	std::deque<point_2> m_points;
+
+	monkey_fit_k()
+		:step_(0)
+		,count_(0)
+	{}
+
+	virtual void reset(double speed /*=0*/)
+	{
+		probab_k.clear();
+		m_points.clear();
+		step_=0;
+		count_ = 0;
+	}
+
+	virtual void push(double time_second,double dist_meter)
+	{
+		int cc=m_points.size();
+
+		if(cc<60)
+		{
+			m_points.push_back(point_2(time_second,dist_meter));
+		}
+		else if(step_++>2)
+		{
+			m_points.push_back(point_2(time_second,dist_meter));
+			step_=0;
+		}
+
+		if(cc<10)
+			return;
+
+		cc*=9./10;
+		for(int i=0;i<3;i++)
+		{
+			int index=rand()%cc;
+			double k=(dist_meter-m_points[index].y_)/(time_second-m_points[index].x_);
+			if((1<k && k<3) || (-3<k && k<-1))
+			{
+				count_++;
+				++probab_k[round(k*KN)];
+			}
+		}
+	}
+
+	double get_K()
+	{
+		if(m_points.size()<min_points)
+			return 0;
+		return round(get_probab_max(probab_k.begin(),probab_k.end(),count_)/KN*10000)/10000.;
+	}
+
+};
+
+#endif

+ 140 - 0
monkey_car/monkeycar_area.cpp

@@ -0,0 +1,140 @@
+#include "monkeycar_area.h"
+#include "monkeycar_bus.h"
+#include "monkeycar_person.h"
+#include "card.h"
+#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)
+	,m_path(dap->m_point.begin(),dap->m_point.end())	
+{
+	log_info("monkeycar _area init ");
+	std::shared_ptr<monkey_bus> bus = std::make_shared<monkey_bus>(dap->m_default_speed,NEGTIVE_DIRECTION);
+	bus_.push_back(bus);
+
+	bus = std::make_shared<monkey_bus>(dap->m_default_speed * -1.0,POSTIVE_DIRECTION);
+	bus_.push_back(bus);
+}
+
+
+std::shared_ptr<monkey_person> monkey_area::find(uint32_t cardid)
+{
+	std::lock_guard<std::mutex> lk(m_mtx);
+	auto it =  card_map_.find(cardid);
+	if(it == card_map_.end())
+		return nullptr;
+	return it->second;
+}
+
+void monkey_area::on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
+{
+	area::on_hover(card_id,c,speed,type);
+	//人卡走下面的业务
+	if(type != 1)
+	  return;
+	uint64_t cid = type<<32|card_id;
+	const std::shared_ptr<card_location_base> card = card_list::instance()->get(cid);
+
+	st_coord pt;
+	pt.x_=card->x;
+	pt.y_=card->y;
+	pt.m_ct = card->m_ct;
+	pt.gen_time_ = card->m_time-m_startTime;
+
+	on_card_move(card_id,pt,type);
+}
+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)
+	  return;
+	on_card_enter(card_id,type);
+}
+void monkey_area::on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
+{
+	area::on_leave(card_id,c,speed,type);
+	if(type != 1)
+	  return;
+	on_card_leave(card_id);
+}
+
+
+void monkey_area::on_card_leave(uint32_t cardid)
+{
+	log_info("[monkeycar on_card_leave]cardId:%d",cardid);
+	std::lock_guard<std::mutex> lk(m_mtx);
+	auto it = card_map_.find(cardid);
+	if (it != card_map_.end())
+	{
+		if(auto tbus = it->second->getBus())
+			tbus->getOffTheBus(it->second);
+		card_map_.erase(it);
+	}
+	
+}
+void monkey_area::on_card_enter(uint32_t cardid,uint64_t type)
+{
+	//log_info("[framework on_card_enter]cardId:%d",card_id);
+	log_info("[monkeycar on_card_enter]cardId:%d",cardid);
+	auto me = shared_from_this();
+
+	std::shared_ptr<monkey_person> mp = std::make_shared<monkey_person>(me);
+
+	uint64_t c = type<<32|cardid;
+	const std::shared_ptr<card_location_base> card = card_list::instance()->get(c);
+	if(card==nullptr)
+	{
+		log_error("[monkeycar ----on_card_enter 卡未找到。]cardId:%d",cardid);
+		return;
+	}
+	card->reset(mp);
+
+	std::lock_guard<std::mutex> lk(m_mtx);
+	card_map_.insert(std::make_pair(cardid,mp));
+}
+void monkey_area::on_card_move(uint32_t cardid,const st_coord & st,uint64_t type)
+{
+	log_info("[monkeycar on_card_move]cardId:%d",cardid);
+	auto me = shared_from_this();
+	auto mp=find(cardid);
+	if (!mp)
+	{
+		//if not exist create it .because may be restart the system.then area not changed.
+		on_card_enter(cardid,type); 
+		return ;
+	}
+	bool ret = mp->on_step_map(st);
+	if (!ret)
+	{
+		return;
+	}
+	double speed=0;
+	bool b=mp->fit_speed(&speed);
+	if (!b || speed == DBL_MAX)
+	{
+		return ;
+	}
+	//on bus
+	speed *= 1000;
+	log_info("monkeycar speed :cardid:%d,speed:%.2f",cardid,speed);
+	if(auto tbus = mp->getBus())
+	{
+		if(!tbus->test_get_off(mp,speed))
+		{
+			log_info("monkeycar get off id:%d",cardid);
+			tbus->getOffTheBus(mp);	
+		}
+	}
+	else
+	{
+		std::shared_ptr<monkey_bus> bus=bus_[speed>0?0:1];
+		if(bus->test_get_on(mp,speed))
+		{
+			log_info("monkeycar get onid:%d",cardid);
+			bus->getOnTheBus(mp,bus);	
+		}
+	}
+}

+ 65 - 0
monkey_car/monkeycar_area.h

@@ -0,0 +1,65 @@
+#ifndef __MONKEYCAR_AREA__
+#define __MONKEYCAR_AREA__
+
+
+//#include "monkeycar_person.h"
+//#include "monkeycar_bus.h"
+#include <mutex>
+#include <memory>
+#include "area.h"
+#include "fp_path.h"
+
+struct db_area 
+{
+	std::vector<point> m_point;
+	double m_default_speed;
+};
+
+
+struct monkey_bus;
+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 );
+	//	:area(area_id,over_count_person,over_time_person)
+	//	,m_scale(scale)
+	//	{}
+	~monkey_area()
+	{}
+	std::shared_ptr<monkey_person> find(uint32_t cardid);
+
+    virtual void on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
+    virtual void on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
+    virtual void on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
+	void on_card_leave(uint32_t cardid);
+	void on_card_enter(uint32_t cardid,uint64_t type);
+	void on_card_move(uint32_t cardid,const st_coord & st,uint64_t);
+	
+	inline  double map(double x, double y)
+	{
+		return m_path.map(x,y);
+	}
+	inline point_2 map(double d)
+	{
+		return m_path.map(d);
+	}
+	inline double get_total_length()
+	{
+		return m_path.get_total_length();
+	}
+	double getScale()
+	{
+		return scale();
+	}
+
+	static  uint64_t m_startTime;
+private:
+	std::map<uint32_t ,std::shared_ptr<monkey_person>> card_map_;
+	std::vector<std::shared_ptr<monkey_bus>> bus_;
+	fp_path m_path;
+	std::mutex  m_mtx;
+};
+
+#endif

+ 109 - 0
monkey_car/monkeycar_bus.cpp

@@ -0,0 +1,109 @@
+#include "monkeycar_bus.h"
+#include "monkeycar_area.h"
+#include "monkeycar_person.h"
+#include "timestamp.h"
+#include "log.h"
+#ifndef WIN32
+#include <unistd.h>
+#endif
+monkey_bus::monkey_bus(double speed, int direct)
+	:m_speed(speed)
+	,m_direct(direct)
+	,m_stop(false)
+{
+	m_thread.reset(new std::thread(std::bind(&monkey_bus::adjust_monkeyperson_distance,this)));
+}
+void monkey_bus::adjust_monkeyperson_distance()
+{
+	bool cflag = false;
+	std::vector<std::shared_ptr<monkey_person>> v;
+	while (!m_stop)
+	{
+		v.clear();
+		uint64_t nowTime = TIME::getMilliseconds();
+		{
+			std::lock_guard<std::mutex> lk(m_mtx);
+			std::for_each(person_list_.begin(),person_list_.end(),[&](const std::shared_ptr<monkey_person> mp){
+				if (nowTime - mp->m_adjustDis_timeval >= ADJUST_DISTANCE_TIMEVAL/2 && !cflag)
+				{
+					mp->setCompensationSpeed(0);
+					cflag = true;
+				}
+				if (nowTime - mp->m_adjustDis_timeval >= ADJUST_DISTANCE_TIMEVAL)
+				{
+					mp->m_adjustDis_timeval = nowTime;
+					mp->handle_monkeycar_fit(1.*(nowTime-monkey_area::m_startTime)/1000.0);
+					cflag = false;
+				}
+			});
+			std::for_each(person_list_.begin(),person_list_.end(),[&](const std::shared_ptr<monkey_person> mp){
+				if (nowTime-mp->m_timestamp > LONG_TIME_NO_DATA)
+					v.push_back(mp);
+			});
+		}
+
+		std::for_each(v.begin(),v.end(),[&](const std::shared_ptr<monkey_person>& mp){
+			getOffTheBus(mp);
+		});
+		std::this_thread::sleep_for(std::chrono::milliseconds(100));
+	}
+}
+
+bool monkey_bus::test_get_on(std::shared_ptr<monkey_person> mp,double speed)
+{
+	//debug_print_syslog(0,"[lemon the second choice false]cardId:%s,v:%f",mp->getCardId().c_str(),speed);
+	if (abs(speed) >= abs(m_speed) * ON_BUS_SPEED_LIMIT && abs(speed) < abs(m_speed) * ON_BUS_SPEED_MAX_LIMIT)
+	{
+		//debug_print_syslog(0,"[lemon the second choice GetOn]cardId:%s",mp->getCardId().c_str());
+		return true;
+	}
+	return false;
+}
+
+bool monkey_bus::test_get_off(std::shared_ptr<monkey_person> mp,double speed)
+{
+	bool ret = false;
+	ret = (speed > ZERO_ ? NEGTIVE_DIRECTION:POSTIVE_DIRECTION) == m_direct ;
+	if (ret)
+	{
+		if (abs(speed) < abs(m_speed) * OFF_BUS_SPEED_LIMIT)
+		{
+			//debug_print_syslog(0,"[lemon the second choice true]cardId:%s,v:%f",mp->getCardId().c_str(),speed);
+
+			if(mp->Judge_OffIndex())
+			{
+				ret = false;
+			}
+		}
+		else
+		{
+			mp->resetOffIndex();
+		}
+	}
+	//debug_print_syslog(0,"[lemon the second choice true___]cardId:%s,v:%f,state:%s",mp->getCardId().c_str(),speed,ret?"ON":"OFF");
+
+	return ret;
+}
+void monkey_bus::Set_AverageSpeed(double speed)
+{
+	m_speed = m_speed * 0.99 + speed * 0.01;
+}
+void monkey_bus::getOffTheBus(std::shared_ptr<monkey_person> mp)
+{
+	//can not free here .
+	mp->GetOffTheBus();
+	std::lock_guard<std::mutex> lk(m_mtx);
+	auto it = std::find(person_list_.begin(),person_list_.end(),mp);
+	if (it != person_list_.end())
+	{
+		person_list_.erase(it);
+
+	}
+}
+void monkey_bus::getOnTheBus(std::shared_ptr<monkey_person> mp,std::shared_ptr<monkey_bus> bus)
+{
+	log_info("monkeycar getOn");
+	mp->GetOnTheBus(bus,m_speed);
+	std::lock_guard<std::mutex> lk(m_mtx);
+	person_list_.push_back(mp);
+}

+ 67 - 0
monkey_car/monkeycar_bus.h

@@ -0,0 +1,67 @@
+#ifndef __MONKEYCAR_BUS__
+#define __MONKEYCAR_BUS__
+
+#include <numeric>
+#include "base_data.h"
+#include <thread>
+#include <mutex>
+
+#define K_MEANS_X1 0.5
+#define K_MEANS_X2 1.8
+#define K_MEANS_x3 3.0
+
+#define ON_BUS_SPEED_LIMIT 0.95
+#define ON_BUS_SPEED_MAX_LIMIT 2
+#define OFF_BUS_SPEED_LIMIT 0.67
+
+#define ADJUST_DISTANCE_TIMEVAL (5 * 60 * 1000)
+
+#define PERSON_SEND_TIME_INTERVAL (2 * 1000) // 2s intervel
+#define GROUPING_PERSON_DISTANCE 20   // 60/map_scale  now is 60m
+#define GROUPING_PERSON_NUMBER   5
+#define FIT_COUNT_LIMIT (ADJUST_DISTANCE_TIMEVAL/PERSON_SEND_TIME_INTERVAL)*6.0/10
+
+#define LONG_TIME_NO_DATA (1*60*1000)  //1 min no data recv. 
+enum DIRECTION{
+	NO_DIRECTION = 0,
+	POSTIVE_DIRECTION,
+	NEGTIVE_DIRECTION
+};
+struct monkey_person;
+struct monkey_bus
+{
+	monkey_bus(double speed, int direct);
+	~monkey_bus()
+	{
+		m_stop = true;
+		m_thread->join();
+	}
+
+	bool test_get_on(std::shared_ptr<monkey_person> mp,double speed);
+	
+	/********************************/
+	/*Decide whether to get off or not*/
+	/******************************/
+	bool test_get_off(std::shared_ptr<monkey_person> mp,double speed);
+	//get the average speed 
+	void Set_AverageSpeed(double speed);
+	//get off the bus 
+	void getOffTheBus(std::shared_ptr<monkey_person> mp);
+	//get on the bus
+	void getOnTheBus(std::shared_ptr<monkey_person> mp,std::shared_ptr<monkey_bus> bus);
+
+	//get step length
+	inline double getNextStep_Distance(double time_val)
+	{
+		return m_speed * time_val;
+	}
+private:
+	std::vector<std::shared_ptr<monkey_person>> person_list_;
+	double m_speed;
+	int    m_direct;
+	std::unique_ptr<std::thread> m_thread;
+	std::mutex m_mtx;
+	void adjust_monkeyperson_distance();
+	bool m_stop;
+};
+#endif

+ 244 - 0
monkey_car/monkeycar_person.cpp

@@ -0,0 +1,244 @@
+#include "monkeycar_person.h"
+#include "monkeycar_area.h"
+#include "monkeycar_bus.h"
+#include "timestamp.h"
+#include <climits>
+#include "log.h"
+
+const int num_fit_point[4]={5,10,20,30};
+
+monkey_person::monkey_person(std::shared_ptr<monkey_area> area)
+	:m_area(area)
+	,m_getOffIndex(0)
+	,m_cur_distance(0x12345678)
+	,m_compensation_speed(0)
+	,m_timeval(0)
+	,m_adjustDis_timeval(0)
+	,m_timestamp(0)
+{
+	m_timestamp = time(NULL) * 1000;
+	
+	m_linear_fit=new comp_linear_fit(&num_fit_point[0],&num_fit_point[0]+sizeof(num_fit_point)/sizeof(num_fit_point[0]));
+
+	mp_monkey_fit.front() = new monkey_fit_k; //k
+	mp_monkey_fit.back() = new monkey_fit_b;  //b
+}
+
+monkey_person::~monkey_person()
+{
+	delete m_linear_fit;
+	for(auto & mp:mp_monkey_fit)
+		delete mp;
+}
+void monkey_person::GetOnTheBus(std::shared_ptr<monkey_bus> bus,double speed)
+{
+	//assignment the monkeycar_bus value
+	m_bus = bus;
+
+	m_cur_distance = m_fit_point.back().x_;
+	m_timeval = TIME::getMilliseconds();
+	m_adjustDis_timeval = m_timeval;
+
+	m_fit_point.clear();
+	m_compensation_speed = 0;
+
+	//when get on the bus, init monkey_fit
+	reset(speed);
+}
+void monkey_person::GetOffTheBus()
+{
+	Set_AverageSpeed();
+
+	m_bus.reset();
+
+	resetOffIndex();
+	m_fit_point.clear();
+	m_compensation_speed = 0;
+
+
+}
+void monkey_person::Set_AverageSpeed()
+{
+	//set average speed.
+	//monkey_fit_k* fit_k  = dynamic_cast<monkey_fit_k*>(mp_monkey_fit.front());
+	//double k = fit_k->get_K();
+	double k = mp_monkey_fit.front()->get_K();
+	if (!m_bus.expired()&& k != 0)
+	{
+		//debug_print_syslog(0,"[framework_2 Set_AverageSpeed_getoff]%s,v:%f",getCardId().c_str(),k);
+		m_bus.lock()->Set_AverageSpeed(k);
+	}
+
+}
+void monkey_person::reset(double speed)
+{
+	for (auto & mp:mp_monkey_fit)
+	{
+		mp->reset(speed);
+	}
+}
+bool monkey_person::Judge_OffIndex()
+{
+	m_getOffIndex++;
+	if (m_getOffIndex == MAX_GETOFF_NUM)
+	{
+		return true;
+	}
+	return false;
+}
+void monkey_person::resetOffIndex()
+{
+	m_getOffIndex = 0;
+}
+bool monkey_person::is_on_bus() const
+{
+	return !m_bus.expired();
+}
+std::shared_ptr<monkey_bus> monkey_person::getBus()
+{
+	return m_bus.lock();
+}
+point_2 monkey_person::get_position()
+{
+	uint64_t timeval = TIME::getMilliseconds();
+	if (m_bus.expired() || m_cur_distance == 0x12345678)
+	{
+		//debug_print_syslog(0,"[framework m_bus.expired()]cardId:%s",getCardId().c_str());
+		m_timeval = timeval;
+		return point_2::invalid_point();
+	}
+
+	//get shared_ptr 
+	//debug_print_syslog(0,"[framework get_positon]cardId:%s  x:%.2f,time:%lld",getCardId().c_str(),m_cur_distance,m_timeval);
+	//here should lock ...take care
+	std::shared_ptr<monkey_bus> tbus = nullptr;
+	if (!m_bus.expired())
+	{
+		tbus = m_bus.lock();
+	}
+	else
+	{
+		return point_2::invalid_point();
+	}
+	//get time val
+	double val = 1.*(timeval - m_timeval)/1000;
+	//get Distance
+	double ds = tbus->getNextStep_Distance(val)/m_area.lock()->getScale();
+	m_cur_distance += ds;
+	//compensation speed...
+	m_cur_distance += m_compensation_speed * val;
+	double total_length = m_area.lock()->get_total_length();
+	if (m_cur_distance < ZERO_)
+	{
+		m_cur_distance = 0;
+	}
+	else if (m_cur_distance >=total_length)
+	{
+		m_cur_distance = total_length;
+	}
+	//get point
+	point_2 tmp = m_area.lock()->map(m_cur_distance);
+	//debug_print_syslog(0,"[framework get_position]cardId:%s,d:%f",getCardId().c_str(),m_cur_distance);
+	if (point_2::is_valid(tmp))
+	{
+		//debug_print_syslog(0,"[framework get_position__]cardId:%s,d:%f",getCardId().c_str(),m_cur_distance);
+		m_timeval = timeval;
+		return tmp;
+	}
+	m_timeval = timeval;
+	return point_2::invalid_point();
+}
+
+bool monkey_person::on_step_map(const st_coord & pt_)
+{
+	st_coord pt(pt_);
+	if (!point_2::is_valid(pt))
+	{
+		return false;
+	}
+	m_timestamp = time(NULL)*1000;
+	double d = m_area.lock()->map(pt.x_,pt.y_);
+	if (d < ZERO_)
+	{
+		//debug_print_syslog(0,"[framework d<0]cardId:%s,orix:%.2f,oriy:%.2f dis:%.2f  ct:%d  time:%ld",getCardId().c_str(),pt.x_,pt.y_,d,pt.m_ct,pt.gen_time_);
+		return false;
+	}
+	pt.x_ = d;
+	if (!m_bus.expired())
+	{
+		for (auto & mp:mp_monkey_fit)
+		{
+			mp->push(1.*pt.gen_time_/1000.0,pt.x_*m_area.lock()->getScale());
+		}
+	}
+
+	m_linear_fit->push(pt.gen_time_,pt.x_);
+	if (m_fit_point.size() >= MAX_POINT_V)
+	{
+		m_fit_point.pop_front();
+	}
+	m_fit_point.push_back(pt);
+
+	return true;
+}
+
+bool monkey_person::fit_speed(double*ret_speed)
+{
+	int num_point=0;
+	if(!get_num_point(&num_point))
+		return false;
+	//here multiply map_scale
+	*ret_speed=m_linear_fit->getK(num_point)*m_area.lock()->getScale();
+	//debug_print_syslog(0,"[framework fit_speed]cardId:%s,speed:%f",getCardId().c_str(),*ret_speed);
+	return true;
+}
+bool monkey_person::get_num_point(int * p)
+{
+	int index = 5;
+	int i = 0;
+	while (index <= 30)
+	{
+		if (init_another_list(index))
+		{
+			*p = index;
+			return true;
+		}
+
+		i += 2;
+		index = 5 * i;
+	}
+	return false;
+}
+bool monkey_person::init_another_list(size_t index)
+{
+	if (m_fit_point.size() < index)
+	{
+		return false;
+	}
+	if (index < 5)
+	{
+		return false;
+	}
+	size_t begin_count = (*std::prev(m_fit_point.end(),index)).m_ct;
+	size_t end_count = (*std::prev(m_fit_point.end())).m_ct;
+	end_count = end_count>begin_count?end_count:end_count+USHRT_MAX;
+	if (end_count - begin_count <= (index-5)*1/5+index)
+	{
+		return true;
+	}
+	return false;
+}
+
+
+void monkey_person::handle_monkeycar_fit(double time_second)
+{
+	monkey_fit_b * fit_b = dynamic_cast<monkey_fit_b*>(mp_monkey_fit.back());
+	if (!fit_b->get_B())
+	{
+		return;
+	}
+	double ori_d = fit_b->get_dist(time_second)/m_area.lock()->getScale();
+	double compensation_speed = (ori_d-m_cur_distance)/(ADJUST_DISTANCE_TIMEVAL/2)*1000;
+	setCompensationSpeed(compensation_speed);
+	log_info("monkeycar framework_2 compensationSpeed]k:%f,b:%f,ori_dis:%f,cur_dis:%f,s:%f",fit_b->get_K(),fit_b->get_B(),ori_d,m_cur_distance,compensation_speed);
+}

+ 78 - 0
monkey_car/monkeycar_person.h

@@ -0,0 +1,78 @@
+#ifndef __MONKEYCAR_PERSON__	
+#define __MONKEYCAR_PERSON__
+#include <memory>
+#include "base_data.h"
+#include "linear_fit.h"
+#include "fp_path.h"
+#include "monkey_fit.h"
+#include "../point.h"
+
+struct monkey_bus;
+struct monkey_area;
+
+#define MAX_POINT_V 30
+#define MAX_GETOFF_NUM 5
+#define ZERO_  1E-5
+extern const int num_fit_point[4];
+
+struct monkey_person
+{
+	std::weak_ptr<monkey_bus>  m_bus;
+	std::weak_ptr<monkey_area> m_area;
+	
+	std::deque<st_coord> m_fit_point;
+
+
+	monkey_person(std::shared_ptr<monkey_area> area);
+
+	~monkey_person();
+
+	void GetOnTheBus(std::shared_ptr<monkey_bus> bus,double speed);
+	void GetOffTheBus();
+	bool Judge_OffIndex();
+	void resetOffIndex();
+
+	bool is_on_bus() const;
+	std::shared_ptr<monkey_bus> getBus();
+
+	bool on_step_map(const st_coord & pt);
+
+	bool fit_speed(double*ret_speed);
+	bool get_num_point(int * p);
+	bool init_another_list(size_t index);
+	point getPoint()
+	{
+		point p;
+		const auto pt = get_position();
+		if(point_2::is_valid(pt))
+		{
+			p.x = pt.x_;
+			p.y = pt.y_;
+		}
+		return p;
+	}
+	
+	inline void setCompensationSpeed(double v)
+	{
+		//debug_print_syslog(0,"[framework adjust speed] :%s,v:%f",getCardId().c_str(),v);
+		m_compensation_speed = v;
+	}
+
+	void reset(double speed);
+	void Set_AverageSpeed();
+	void handle_monkeycar_fit(double);
+private:
+	point_2 get_position();
+public:
+	int				m_getOffIndex;
+	double			m_cur_distance;   //curTime distance
+	double			m_compensation_speed;
+	uint64_t		m_timeval;
+	uint64_t		m_adjustDis_timeval;
+	uint64_t		m_timestamp;
+
+	comp_linear_fit* m_linear_fit;
+	std::array<monkey_fit*,2> mp_monkey_fit;
+};
+
+#endif

BIN
path


+ 0 - 1
path_tof.txt

@@ -46,7 +46,6 @@
 604, 0, 4625, 100, 0,  2700, 100, 0, 0,NULL, -1
 605, 0, 4625, 100, 0,  2700, 100, 0, 0,NULL, -1
 606, 0, 4727, 75, 0,  2732.2, 75, 0, 0,NULL, -1
-607, 0, 3640.8, -10, 0, 3640.8, -151.9, 0, 0,NULL, -1
 608, 0, 3640.8, -37.4, 0,3640.8, -400, 0, 0,NULL, -1
 609, 0, 3479, 1, 0,  3479, -400, 0, 0,NULL, -1
 610, 0, 2700, 100, 0,4625, 100, 0, 0,NULL, -1

+ 2 - 1
point.cpp

@@ -5,10 +5,11 @@ point::point()
 {
 }
 
-void point::set(double x_,double y_) 
+void point::set(double x_,double y_,double z_) 
 {
 	x=x_;
 	y=y_;
+	z=z_;
 }
 
 void point::swap(point&p)

+ 2 - 1
point.h

@@ -35,9 +35,10 @@ struct point
 	{
 		x=p.x;
 		y=p.y;
+		z=p.z;
 	}
 
-	void set(double,double);
+	void set(double,double,double z=0);
 	void swap(point&p);
 
 	bool operator<(const point&p)const

+ 10 - 10
select_tool.cpp

@@ -1,6 +1,7 @@
 #include "select_tool.h"
 #include "ant.h"
 #include "card_path.h"
+#include "log.h"
 void select_point_object::att_initiate()
 {
 	m_fitk.add_tool(30,5,5);
@@ -129,6 +130,7 @@ void select_point_object::select_one_ant(loc_point &c,const std::vector<point> &
  
 point select_point_object::select_solution0(std::vector<point> &tvp,const double scale)
 {
+   //log_info("lemon test 2 :cardid:%d sit:%f sitid:%d",m_d(0).m_cid,scale,m_d(0).m_sid);
     loc_point&c=m_d(0);
 	if(m_d.size()==1)
 	{
@@ -147,6 +149,7 @@ point select_point_object::select_solution0(std::vector<point> &tvp,const double
 }
 bool select_point_object::select_solution(const std::vector<point> &vp,const site*sit,loc_point &p)
 {
+   //log_info("lemon test 1 :cardid:%d sit:%d sitid:%d",m_d(0).m_cid,sit->m_id,m_d(0).m_sid);
    remove_history(); 
    std::vector<point> tvp(vp.begin(),vp.end());
    if(vp.size()==4)
@@ -177,10 +180,9 @@ bool select_point_object::select_solution(const std::vector<point> &vp,const sit
 		m_d(0).inc_cl(10);
    }
    point pt = select_solution0(tvp,sit->m_scale);
-   std_info("-----select_solution0:x:%.2f,y:%.2f",pt.x,pt.y);
-	m_d(0).set(pt);
-	if(pt.empty())
+	if(pt.empty() || m_d.empty())
 		return false;
+	m_d(0).set(pt);
     if(!m_d(0).empty())
 		m_d(0).m_dist=sit->dist_direct(pt);
 	else
@@ -189,9 +191,8 @@ bool select_point_object::select_solution(const std::vector<point> &vp,const sit
 		if(m_last) m_d(0).m_dist=0.01*m_last->m_dist>0?1:-1;
 	}
 
-    //revise_by
     //
-	std_info("revise_by_history:::%llu",m_d(0).m_time);
+	//std_info("revise_by_history:::%llu",m_d(0).m_time);
     bool fg=revise_by_history(pt,sit,m_d(0).m_time);
     if(!card_path::inst().is_at_path(pt))
 	{
@@ -263,7 +264,7 @@ bool select_point_object::select_solution(const std::vector<point> &vp,const sit
 				double tk=(d0-d1)/(t0-t1), tb=d1-tk*t1;		//d1+(d0-d1)/(t0-t1)*(t-t1)
 				for(double ti=tbegin;ti<t0;ti=ti+1)
 				{
-					std_info("add ..seelct");
+					//std_info("add ..seelct");
 					m_fitk.add(ti, tk*ti+tb);
 				}
 			}
@@ -344,14 +345,14 @@ void select_point_object::remove_history()
 					double tk=(d0-d1)/(t0-t1), tb=d1-tk*t1;		//d1+(d0-d1)/(t0-t1)*(t-t1)
 					for(double ti=tbegin;ti<t0;ti=ti+1)
 					{
-						std_info("add remove..");
+						//std_info("add remove..");
 						m_fitk.add(ti, tk*ti+tb);
 					}
 				}
 			}
 
 			dist=m_begin->loc_dist(m_d(i)[0]);
-						std_info("add remove..");
+						//std_info("add remove..");
 			m_fitk.add(m_d(i).m_time/1000.,dist);
 
 			if(i==len)
@@ -366,7 +367,6 @@ void select_point_object::remove_history()
 }
 void select_point_object::save_k()
 {
-	std_info("save_k()...............");
 	const fit_result*fk=best_fit_raw(0,4);
 	if(!fk)
 	{
@@ -400,7 +400,7 @@ fit_result* select_point_object::best_fit_raw(int num_point,int start,int last)
 	last  =std::min(last,m_fitk.tool_size());
 	if(last==-1)
 		last=m_fitk.tool_size();
-	std_info("best_fit_raw :%d:%d",start,last);
+	//std_info("best_fit_raw :%d:%d",start,last);
 	for(int i=start;i<last;i++)
 	{
 		if(!m_fitk[i].is_valid())

+ 31 - 17
select_tool.h

@@ -35,7 +35,13 @@ struct solpoint:point
 };
 struct push_data_point:point
 {
-	const site *sit;
+	push_data_point()
+		:ct(0)
+		,valid(false)
+		,stop_cnt(0)
+	{
+
+	}
 	point dstp;
 	int ct;
 	bool valid;	// if valid
@@ -208,12 +214,12 @@ struct person_point_filter:select_point_object
 
 	virtual bool revise_by_history(point & pt, const site*sit, int64_t timestamp)
 	{
+		//log_info("lemon test revise preson:cardid:%d sit:%d sitid:%d  %0X",m_d(0).m_cid,sit->m_id,m_d(0).m_sid,sit);
 		point dstp = sit->get_dstp(pt);
 		if(dstp.empty())
-		  std_error("error.here....");
+		  log_error("error.here....2222");
 
 		push_data_point dp;
-		dp.sit=sit;
 		dp.dstp.set(dstp);
 		dp.ct=m_d(0).m_ct;
 		dp.valid=true;
@@ -325,6 +331,8 @@ struct car_point_filter:select_point_object
 	}
 	void generate_list(point &pt, const site*sit, bool is_whole_list)
 	{
+		
+		//log_info("lemon test 4 :cardid:%d sit:%d sitid:%d",m_d(0).m_cid,sit->m_id,m_d(0).m_sid);
 		if(is_whole_list)
 		{
 			put_loc_point(pt, sit, m_d(0).m_ct, m_d(0));
@@ -372,6 +380,7 @@ struct car_point_filter:select_point_object
 
 	void put_single_loc_point(point &pt, const site*sit, int ct, loc_point &lp)
 	{
+		//log_info("lemon test 6 :cardid:%d sit:%d sitid:%d",m_d(0).m_cid,sit->m_id,m_d(0).m_sid);
 		point rpt;
 		rpt.set(pt);
 		turning_mapping(rpt,sit);
@@ -392,7 +401,7 @@ struct car_point_filter:select_point_object
 			//dstp.set(sit->x,sit->y);
 			dstp = sit->get_dstp(pt);
 			if(dstp.empty())
-			  std_error("error.here....");
+			  log_error("error.here....here.");
 		}
 		else
 		{
@@ -400,7 +409,6 @@ struct car_point_filter:select_point_object
 		}
 
 		push_data_point dp;
-		dp.sit=sit;
 		dp.dstp.set(dstp);
 		dp.ct=ct;
 		dp.valid=true;
@@ -441,6 +449,7 @@ struct car_point_filter:select_point_object
 
 	void put_loc_point(point &pt, const site*sit, int ct, loc_point &lp)
 	{
+		//log_info("lemon test 5 :cardid:%d sit:%d sitid:%d",m_d(0).m_cid,sit->m_id,m_d(0).m_sid);
 		point rpt;
 		rpt.set(pt);
 		turning_mapping(rpt,sit);
@@ -460,7 +469,7 @@ struct car_point_filter:select_point_object
 		{
 			dstp = sit->get_dstp(pt);
 			if(dstp.empty())
-			  std_error("error.here....");
+			  log_error("error.here....lll");
 			//dstp.set(sit->x,sit->y);
 		}
 		else
@@ -470,7 +479,6 @@ struct car_point_filter:select_point_object
 
 		int size = 0;
 		push_data_point dp[13];
-		dp[size].sit=sit;
 		dp[size].dstp.set(dstp);
 		dp[size].ct=ct;
 		dp[size].valid=true;
@@ -481,7 +489,6 @@ struct car_point_filter:select_point_object
 		size++;
 		for(;size<13;size++)
 		{
-			dp[size].sit=sit;
 			dp[size].dstp.set(dstp);
 			dp[size].ct = ct;
 			dp[size].valid=true;
@@ -519,7 +526,8 @@ struct car_point_filter:select_point_object
 		int fidx=find_first(0);
 		if(fidx>=0)
 		{
-			loc_point&f=m_d[fidx];		printf("find_first:(%.2f,%.2f)(%.2f,%.2f)\n",f.m_sol[0].x,f.m_sol[0].y,pt.x,pt.y);
+			loc_point&f=m_d[fidx];		
+			//printf("find_first:(%.2f,%.2f)(%.2f,%.2f)\n",f.m_sol[0].x,f.m_sol[0].y,pt.x,pt.y);
 			//dist = f.dist(pt) * (pt<f?-1:1);
 			dist = f.loc_dist(pt);
 			if(dist!=0)
@@ -543,6 +551,8 @@ struct car_point_filter:select_point_object
 
 	virtual bool revise_by_history(point & pt, const site*sit, int64_t timestamp)
 	{
+
+		//log_info("lemon test 3 :cardid:%d sit:%d sitid:%d",m_d(0).m_cid,sit->m_id,m_d(0).m_sid);
 		bool flag =false;
 		if(m_line.empty() || !m_line.contain(m_d(0),0.1))
 		{
@@ -621,7 +631,7 @@ struct car_point_filter:select_point_object
 			// update acc
 			//m_accumulate_acc=0
 
-			printf("change line------------, k=%f,ke=%f\n",fit->k,fit->ke);
+			//printf("change line------------, k=%f,ke=%f\n",fit->k,fit->ke);
 		}
 
 		// revise
@@ -789,6 +799,7 @@ struct smooth_tool
 		else
 		{
 			lp->m_speed=smooth_speed_presentation * (3.6*sit->m_scale) ; //(m/s) to (km/h)
+			log_info("m_speed:%.2f   %.2f    %.2f ,id %d",lp->m_speed,smooth_speed_presentation,sit->m_scale, sit->m_id);
 			if(smooth_speed<0)
 			  lp->m_speed = -lp->m_speed;
 			if(std::isnan(lp->m_speed))
@@ -832,28 +843,30 @@ struct smooth_tool
 	{
 		loc_point lp;
 		push_data_point dpt = m_st->getDpt();
+		if(dpt.empty())	
+		  return lp;
 		point pt;
 		pt.set(dpt);
-		if(pt.empty())	
-		  return lp;
 		double current_t=time(NULL);
+		const auto & sit = sit_list::instance()->get(dpt.lp.m_sid);
 		if(dpt.valid)
 		{
-			smooth_dist(pt, current_t, dpt.ct, dpt.sit, dpt.dstp, &lp);
+			//log_info("lemon ......card_id:%d,sitId:%d,---lpid:%d",dpt.lp.m_cid,sit->m_id,dpt.lp.m_sid);
+			smooth_dist(pt, current_t, dpt.ct, sit.get(), dpt.dstp, &lp);
 			set(pt,lp);
 
 			dpt.lp.m_dist2=lp.m_dist2;
 			dpt.lp.m_time=lp.m_time;
 			dpt.lp.m_ct=lp.m_ct;	
 			dpt.lp.set(lp);
-			dpt.lp.m_dist=dpt.sit->dist_direct(dpt);
+			dpt.lp.m_dist=sit->dist_direct(dpt);
 			dpt.lp.m_speed=lp.m_speed;
 			dpt.lp.m_stat=lp.m_stat;
 			dpt.lp.debug_out("get_point");
 		}
 		else
 		{
-			smooth_set_loc_point(current_t, dpt.ct, dpt.sit, &lp);
+			smooth_set_loc_point(current_t, dpt.ct, sit.get(), &lp);
 			if(dpt.stop_cnt<=0)
 			{
 				lp.m_speed=0;
@@ -909,17 +922,17 @@ struct smooth_tool_person_1:smooth_tool
 		}
 		else
 		{
-            printf("lemon2");
 			double current_dist = dstp.dist_direct(pt);
 			double last_true_position = dstp.dist_direct(smooth_last_true_position);
 			double max_span = 100;
 			if(fabs(current_dist-last_true_position)<max_span && t - smooth_last_time_sec < 10)
 			{
 				double new_speed = (current_dist-last_true_position) / (t - smooth_last_time_sec);
-
+				log_info("person....new_speed:%.2f",new_speed);
 				double speed_differ = fabs(new_speed-smooth_speed);
 				if(speed_differ>1)new_speed=smooth_speed +1*(new_speed>smooth_speed?1:-1);
 				smooth_speed = smooth_speed * 0.4 + new_speed * 0.6;
+				log_info("person....new_speed_smooth:%.2f",smooth_speed);
 				smooth_last_true_position = pt;
 				smooth_last_position = pt;
 				smooth_last_time_sec = t;
@@ -930,6 +943,7 @@ struct smooth_tool_person_1:smooth_tool
 				else
 					smooth_speed_presentation = smooth_speed_presentation * 0.4 + fabs(smooth_speed) * 0.6;
 				if(fabs(smooth_speed)<0.1)smooth_speed_presentation=0;
+				log_info("person...persentation.new_speed_smooth:%.2f",smooth_speed_presentation);
 			}
 			else
 			{

BIN
sio.tar.gz


+ 21 - 0
timestamp.h

@@ -0,0 +1,21 @@
+#ifndef _INCLUDE_TIME_STAMP_HPP
+#define _INCLUDE_TIME_STAMP_HPP
+#include <sys/timeb.h>
+#ifndef WIN32
+#include <sys/time.h>
+#endif
+struct  TIME{
+	static uint64_t getMilliseconds()
+	{
+#ifndef WIN32
+		struct timeval tv;
+		::gettimeofday(&tv, 0);
+		return tv.tv_sec*1000+tv.tv_usec/1000;
+#else
+		struct timeb tb;
+		::ftime(&tb);
+		return tb.time*1000+tb.millitm;
+#endif
+	}
+};
+#endif

+ 192 - 192
websocket/constdef.h

@@ -1,193 +1,193 @@
-#ifndef _SERVER_CONST_DEF_H_
-#define _SERVER_CONST_DEF_H_
-
-#define MAXCRITICALSECTIONSPINCOUNT 4000
-#define INTERFACE_VERSION "1.0.0.2"
-#define INTERFACE_VERSION_1_1 "1.0.0.1"
-#define INTERFACE_VERSION_1_3 "1.0.0.3"
-#define INTERFACE_VERSION_1_4 "1.0.0.4"
-
-#define TEST_WS_URL  "ws://182.92.224.191:8086"
-#define JSON_ROOT_KEY_CMD "cmd"
-#define JSON_ROOT_KEY_VERSION "version"
-#define JSON_ROOT_KEY_DATA "data"
-#define JSON_ROOT_KEY_TOTAL "total"
-#define JSON_ROOT_KEY_STATISTIC_VEHICLE_DATA "v"
-#define JSON_ROOT_KEY_STATISTIC_STAFF_DATA "s"
-#define JSON_ROOT_KEY_STATISTIC_STAT "stat"
-#define JSON_ROOT_KEY_STATISTIC_DETAIL "detail"
-#define JSON_ROOT_KEY_STATISTIC_GLOBAL "glbl"
-#define JSON_ROOT_KEY_STATISTIC_DEPT "dept"
-#define JSON_ROOT_KEY_STATISTIC_SUM "sum"
-#define JSON_ROOT_KEY_STATISTIC_AREA "area"
-#define JSON_ROOT_KEY_STATISTIC_LEVEL "occupation_level"
-
-// 采集端接收接口
-#define JSON_CMD_VALUE_CLEAR_CARD "clear_card"
-#define JSON_CMD_VALUE_DEAL_HELP "helpme_done"   //deal_help
-#define JSON_CMD_VALUE_DEAL_HELP_RESPONSE "helpme_done_rsp"   //deal_help
-#define JSON_CMD_VALUE_REQUEST_ALL_POSTION "request_all_postion"
-#define JSON_CMD_VALUE_REQUEST_ALL_DATA "req_all_data"
-#define JSON_CMD_VALUE_RESPONSE_ALL_DATA "resp_all_data"
-#define JSON_CMD_VALUE_CALL_CARD_START "call_card_start"
-#define JSON_CMD_VALUE_CALL_CARD_CANCEL "call_card_cancel"
-#define  JSON_CMD_VALUE_LEADER_ARRANGE "leader_arrange"
-//呼叫命令
-#define JSON_CMD_VALUE_CALL_CARD_REQUEST "call_card_req"
-#define JSON_CMD_VALUE_CALL_CARD_RESPONSE "call_card_resp"
-#define JSON_CMD_VALUE_CALL_CARD_CANCEL_REQUEST "call_card_cancel_req"
-#define JSON_CMD_VALUE_CALL_CARD_CANCEL_RESPONSE "call_card_cancel_resp"
-#define JSON_CMD_VALUE_CALL_CARD_LIST "callcardlist"
-
-#define JSON_CMD_VALUE_META_DATA_CHANGED "meta_data_changed"
-#define JSON_CMD_VALUE_LIGHTS_CTRL_REQUEST "light_control"
-#define JSON_CMD_VALUE_LIGHTS_CTRL_RESPONSE "lights_ctrl_res"
-#define JSON_CMD_VALUE_HAND_UP_RESPONSE "deal_hand_up_res"
-
-#define JSON_KEY_ID "id"
-#define JSON_KEY_OP_TYPE "op_type"
-#define JSON_KEY_OP_TYPE_INSERT "INSERT"
-#define JSON_KEY_OP_TYPE_UPDATE "UPDATE"
-#define JSON_KEY_OP_TYPE_DELETE "DELETE"
-
-#define JSON_KEY_NAME "name"
-#define JSON_KEY_NAME_MAP "map"
-#define JSON_KEY_NAME_AREA "area"
-#define JSON_KEY_NAME_PATH "path"
-#define JSON_KEY_NAME_READER "reader"
-#define JSON_KEY_NAME_CARD "card"
-#define JSON_KEY_NAME_STAFF "staff"
-#define JSON_KEY_NAME_STAFF_EXTEND "staff_extend"
-#define JSON_KEY_NAME_VEHICLE "vehicle"
-
-#define JSON_KEY_NAME_VEHICLE_EXTEND "vehicle_extend"
-#define JSON_KEY_NAME_SECTION "section"
-#define JSON_KEY_NAME_LIGHT   "light"
-#define JSON_KEY_NAME_CHAMBER "chamber"
-#define JSON_KEY_NAME_SHIFT "shift"
-#define JSON_KEY_NAME_PATROL_TASK "patrol_task"
-#define JSON_KEY_NAME_RULES "rules"
-#define JSON_KEY_NAME_SETTING "setting"
-#define JSON_KEY_NAME_DRIVINGFACE "drivingface_vehicle"
-#define JSON_KEY_NAME_DRIVINGFACE_WARNING_POINT "dat_drivingface_warning_point"
-#define JSON_KEY_NAME_HAND_UP "dat_handup_vehicle"
-
-#define JSON_KEY_CALL_CARD_CALL_TYPE "call_type_id"
-#define JSON_KEY_CALL_CARD_CALL_TIME_OUT "call_time_out"
-#define JSON_KEY_CALL_CARD_CALL_TIME "call_time"
-#define JSON_KEY_CALL_CARD_CALL_LEVEL "call_level_id"
-#define JSON_KEY_CALL_CARD_USER_NAME "user_name"
-#define JSON_KEY_CALL_CARD_STATIONS "stations"
-#define JSON_KEY_CALL_CARD_STATION_ID "stationid"
-#define JSON_KEY_CALL_CARD_CARDS "cards"
-#define JSON_KEY_CALL_CARD_CARD_ID "cardid"
-#define JSON_KEY_CALL_CARD_CARD_TYPE_ID "cardtype"
-
-#define JSON_KEY_CALL_LIGHT_TASK_ID "task_id"
-#define JSON_KEY_CALL_LIGHT_OBJ_TYPE "obj_type"
-#define JSON_KEY_CALL_LIGHT_CTRL_TYPE "ctrl_type"
-#define JSON_KEY_CALL_LIGHT_LIGHT_STATE "light_state"
-#define JSON_KEY_CALL_LIGHT_USER_ID "user_id"
-#define JSON_KEY_CALL_LIGHT_LIGHTS "lights"
-#define JSON_KEY_CALL_LIGHT_ID "id"
-
-#define JSON_KEY_EDIT_CARD_ID "cardid"
-#define JSON_KEY_EDIT_EDIT_TYPE_ID "edittype"
-
-// 采集端调用接口
-#define JSON_CMD_VALUE_LOGIN "login"
-#define JSON_CMD_VALUE_LOGOUT "logout"
-#define JSON_KEY_USERNAME "user_name"
-#define JSON_KEY_PASSWORD "user_pass"
-#define JSON_VALUE_USERNAME "COLLECTOR"
-#define JSON_VALUE_PASSWORD "666666"  //"666666"
-#define JSON_KEY_CARD_ID "card_id" //"卡号"
-#define JSON_KEY_CARD_TYPE_ID "card_type_id"
-#define JSON_KEY_REC_TIME "rec_time" // "接收时间"
-#define JSON_KEY_DOWN_TIME "down_time" // "入井时间"
-#define JSON_KEY_WORK_TIME "work_time" // "工作时间"
-#define JSON_KEY_ENTER_AREA_TIME "enter_area_time" // "进入区域时间"
-#define JSON_KEY_CORDINATE_X "x"
-#define JSON_KEY_CORDINATE_Y "y"
-#define JSON_KEY_CORDINATE_Z "z"
-#define JSON_KEY_STATE "state" // "状态"
-#define JSON_KEY_STATE_MOVING "state_moving" // 运动状态
-#define JSON_KEY_STATE_BIZ "state_biz" // 业务状态
-#define JSON_KEY_MAP_ID "map_id" // "地图编号"
-#define JSON_KEY_DEPT_ID "dept_id"
-#define JSON_KEY_SPEED "speed"	//速度
-#define JSON_KEY_LANDMARK_ID "landmark_id"
-#define JSON_KEY_DIRECTORY_ID "landmark_direction_id"
-#define JSON_KEY_LANDMARK_DIS "landmark_distance"
-
-// id, name, type, map_id
-#define JSON_KEY_AREA_ID "area_id" // "区域编号"
-#define JSON_KEY_AREA_IS_SPECIAL "is_special_area" // "区域名称"
-// down_mine,up_mine
-#define JSON_CMD_VALUE_DOWN_MINE "down_mine"
-#define JSON_CMD_VALUE_UP_MINE "up_mine"
-#define JSON_CMD_VALUE_SPECIAL_AREA_UP_MINE "special_area_up_mine"
-#define JSON_CMD_VALUE_DEV_STATE "device_state"
-#define JSON_CMD_VALUE_EVENT "event"
-#define JSON_CMD_VALUE_CALL "CALL"
-#define JSON_CMD_VALUE_PUSH "PUSH"
-#define JSON_CMD_VALUE_USER "USER"
-#define JSON_CMD_DRIVING_FACE_STATE "tunneller_stat"
-// pos_map
-#define JSON_CMD_VALUE_POS_MAP "pos_map"
-
-// 告警事件
-#define JSON_KEY_EVENT_EVENT_ID "event_id"
-#define JSON_KEY_EVENT_STATUS "status"
-#define JSON_KEY_EVENT_TYPE_ID "type_id"
-#define JSON_KEY_EVENT_OBJ_TYPE_ID "obj_type_id"
-#define JSON_KEY_EVENT_OBJ_ID "obj_id"
-#define JSON_KEY_EVENT_MAP_ID "map_id"
-#define JSON_KEY_EVENT_AREA_ID "area_id"
-#define JSON_KEY_EVENT_X "x"
-#define JSON_KEY_EVENT_Y "y"
-#define JSON_KEY_EVENT_LIMIT_VALUE "limit_value"
-#define JSON_KEY_EVENT_CUR_VALUE "cur_value"
-#define JSON_KEY_EVENT_CUR_TIME "cur_time"
-#define JSON_KEY_EVENT_LANDMARK_ID "lmid"
-#define JSON_KEY_EVENT_LANDMARK_DIRECTION "lmdirect"
-#define JSON_KEY_EVENT_LANDMARK_DISTANCE "lmdistance"
-#define JSON_KEY_EVENT_READER_POS_CHANGE    "reader_pos_change"
-
-// alarm
-#define JSON_KEY_ALARM_OVER_COUNT_PERSON "over_count_person"
-#define JSON_KEY_ALARM_OVER_COUNT_VEHICLE "over_count_vehicle"
-#define JSON_KEY_ALARM_OVER_TIME_PERSON "over_time_person"
-#define JSON_KEY_ALARM_OVER_TIME_VEHICLE "over_time_vehicle"
-#define JSON_KEY_ALARM_OVER_SPEED_VEHICLE "over_speed_vehicle"
-
-#define JSON_KEY_ALARM_START_TIME "alarm_start_time"
-
-#define JSON_KEY_ALARM_STAFFER_ID "staffer_id"
-#define JSON_KEY_ALARM_VEHICLE_ID "vehicle_id"
-
-#define JSON_KEY_ALARM_SECTION "section_info"
-#define JSON_KEY_ALARM_SECTION_ID "section_id"
-#define JSON_KEY_ALARM_SECTION_VEHICLE_COUNTS "vehicle_counts"
-#define JSON_KEY_ALARM_SECTION_STAFFER_COUNTS "staffer_counts"
-#define JSON_KEY_ALARM_SECTION_STATE "state"
-
-#define JSON_KEY_ALARM_LIGHT "light_info"
-#define JSON_KEY_ALARM_LIGHT_ID "light_id"
-#define JSON_KEY_ALARM_LIGHT_GROUP_ID "light_group_id"
-#define JSON_KEY_ALARM_LIGHT_GROUP_NAME	"light_group_name"
-
-#define JSON_KEY_ALARM_TRAFFIC_RED_LIGHT "traffic_red_light"
-// 掘进面
-#define JSON_KEY_DRIVINGFACE_DIS "driving_face_moving_dis"
-#define JSON_KEY_DRIVINGFACE_WARNING_POINT_ID "driving_face_warning_point_id"
-#define JSON_KEY_DRIVINGFACE_WARNING_POINT_DIS "driving_face_warning_point_dis"
-
-#define JSON_KEY_DRIVINGFACE_CURSHIFT_LENGTH "drivingface_curshift_length"
-
-//人上车状态
-#define JSON_KEY_PERSON_ON_CAR "person_on_car"
-#define JSON_CMD_REQ_ALL_PERSON_ON_CAR "req_all_person_on_car"
-#define JSON_CMD_RESP_ALL_PERSON_ON_CAR "resp_all_person_on_car"
-
+#ifndef _SERVER_CONST_DEF_H_
+#define _SERVER_CONST_DEF_H_
+
+#define MAXCRITICALSECTIONSPINCOUNT 4000
+#define INTERFACE_VERSION "1.0.0.2"
+#define INTERFACE_VERSION_1_1 "1.0.0.1"
+#define INTERFACE_VERSION_1_3 "1.0.0.3"
+#define INTERFACE_VERSION_1_4 "1.0.0.4"
+
+#define TEST_WS_URL  "ws://182.92.224.191:8086"
+#define JSON_ROOT_KEY_CMD "cmd"
+#define JSON_ROOT_KEY_VERSION "version"
+#define JSON_ROOT_KEY_DATA "data"
+#define JSON_ROOT_KEY_TOTAL "total"
+#define JSON_ROOT_KEY_STATISTIC_VEHICLE_DATA "v"
+#define JSON_ROOT_KEY_STATISTIC_STAFF_DATA "s"
+#define JSON_ROOT_KEY_STATISTIC_STAT "stat"
+#define JSON_ROOT_KEY_STATISTIC_DETAIL "detail"
+#define JSON_ROOT_KEY_STATISTIC_GLOBAL "glbl"
+#define JSON_ROOT_KEY_STATISTIC_DEPT "dept"
+#define JSON_ROOT_KEY_STATISTIC_SUM "sum"
+#define JSON_ROOT_KEY_STATISTIC_AREA "area"
+#define JSON_ROOT_KEY_STATISTIC_LEVEL "occupation_level"
+
+// 采集端接收接口
+#define JSON_CMD_VALUE_CLEAR_CARD "clear_card"
+#define JSON_CMD_VALUE_DEAL_HELP "helpme_done"   //deal_help
+#define JSON_CMD_VALUE_DEAL_HELP_RESPONSE "helpme_done_rsp"   //deal_help
+#define JSON_CMD_VALUE_REQUEST_ALL_POSTION "request_all_postion"
+#define JSON_CMD_VALUE_REQUEST_ALL_DATA "req_all_data"
+#define JSON_CMD_VALUE_RESPONSE_ALL_DATA "resp_all_data"
+#define JSON_CMD_VALUE_CALL_CARD_START "call_card_start"
+#define JSON_CMD_VALUE_CALL_CARD_CANCEL "call_card_cancel"
+#define  JSON_CMD_VALUE_LEADER_ARRANGE "leader_arrange"
+//呼叫命令
+#define JSON_CMD_VALUE_CALL_CARD_REQUEST "call_card_req"
+#define JSON_CMD_VALUE_CALL_CARD_RESPONSE "call_card_resp"
+#define JSON_CMD_VALUE_CALL_CARD_CANCEL_REQUEST "call_card_cancel_req"
+#define JSON_CMD_VALUE_CALL_CARD_CANCEL_RESPONSE "call_card_cancel_resp"
+#define JSON_CMD_VALUE_CALL_CARD_LIST "callcardlist"
+
+#define JSON_CMD_VALUE_META_DATA_CHANGED "meta_data_changed"
+#define JSON_CMD_VALUE_LIGHTS_CTRL_REQUEST "light_control"
+#define JSON_CMD_VALUE_LIGHTS_CTRL_RESPONSE "lights_ctrl_res"
+#define JSON_CMD_VALUE_HAND_UP_RESPONSE "deal_hand_up_res"
+
+#define JSON_KEY_ID "id"
+#define JSON_KEY_OP_TYPE "op_type"
+#define JSON_KEY_OP_TYPE_INSERT "INSERT"
+#define JSON_KEY_OP_TYPE_UPDATE "UPDATE"
+#define JSON_KEY_OP_TYPE_DELETE "DELETE"
+
+#define JSON_KEY_NAME "name"
+#define JSON_KEY_NAME_MAP "map"
+#define JSON_KEY_NAME_AREA "area"
+#define JSON_KEY_NAME_PATH "path"
+#define JSON_KEY_NAME_READER "reader"
+#define JSON_KEY_NAME_CARD "card"
+#define JSON_KEY_NAME_STAFF "staff"
+#define JSON_KEY_NAME_STAFF_EXTEND "staff_extend"
+#define JSON_KEY_NAME_VEHICLE "vehicle"
+
+#define JSON_KEY_NAME_VEHICLE_EXTEND "vehicle_extend"
+#define JSON_KEY_NAME_SECTION "section"
+#define JSON_KEY_NAME_LIGHT   "light"
+#define JSON_KEY_NAME_CHAMBER "chamber"
+#define JSON_KEY_NAME_SHIFT "shift"
+#define JSON_KEY_NAME_PATROL_TASK "patrol_task"
+#define JSON_KEY_NAME_RULES "rules"
+#define JSON_KEY_NAME_SETTING "setting"
+#define JSON_KEY_NAME_DRIVINGFACE "drivingface_vehicle"
+#define JSON_KEY_NAME_DRIVINGFACE_WARNING_POINT "dat_drivingface_warning_point"
+#define JSON_KEY_NAME_HAND_UP "dat_handup_vehicle"
+
+#define JSON_KEY_CALL_CARD_CALL_TYPE "call_type_id"
+#define JSON_KEY_CALL_CARD_CALL_TIME_OUT "call_time_out"
+#define JSON_KEY_CALL_CARD_CALL_TIME "call_time"
+#define JSON_KEY_CALL_CARD_CALL_LEVEL "call_level_id"
+#define JSON_KEY_CALL_CARD_USER_NAME "user_name"
+#define JSON_KEY_CALL_CARD_STATIONS "stations"
+#define JSON_KEY_CALL_CARD_STATION_ID "stationid"
+#define JSON_KEY_CALL_CARD_CARDS "cards"
+#define JSON_KEY_CALL_CARD_CARD_ID "cardid"
+#define JSON_KEY_CALL_CARD_CARD_TYPE_ID "cardtype"
+
+#define JSON_KEY_CALL_LIGHT_TASK_ID "task_id"
+#define JSON_KEY_CALL_LIGHT_OBJ_TYPE "obj_type"
+#define JSON_KEY_CALL_LIGHT_CTRL_TYPE "ctrl_type"
+#define JSON_KEY_CALL_LIGHT_LIGHT_STATE "light_state"
+#define JSON_KEY_CALL_LIGHT_USER_ID "user_id"
+#define JSON_KEY_CALL_LIGHT_LIGHTS "lights"
+#define JSON_KEY_CALL_LIGHT_ID "id"
+
+#define JSON_KEY_EDIT_CARD_ID "cardid"
+#define JSON_KEY_EDIT_EDIT_TYPE_ID "edittype"
+
+// 采集端调用接口
+#define JSON_CMD_VALUE_LOGIN "login"
+#define JSON_CMD_VALUE_LOGOUT "logout"
+#define JSON_KEY_USERNAME "user_name"
+#define JSON_KEY_PASSWORD "user_pass"
+#define JSON_VALUE_USERNAME "COLLECTOR"
+#define JSON_VALUE_PASSWORD "666666"  //"666666"
+#define JSON_KEY_CARD_ID "card_id" //"卡号"
+#define JSON_KEY_CARD_TYPE_ID "card_type_id"
+#define JSON_KEY_REC_TIME "rec_time" // "接收时间"
+#define JSON_KEY_DOWN_TIME "down_time" // "入井时间"
+#define JSON_KEY_WORK_TIME "work_time" // "工作时间"
+#define JSON_KEY_ENTER_AREA_TIME "enter_area_time" // "进入区域时间"
+#define JSON_KEY_CORDINATE_X "x"
+#define JSON_KEY_CORDINATE_Y "y"
+#define JSON_KEY_CORDINATE_Z "z"
+#define JSON_KEY_STATE "state" // "状态"
+#define JSON_KEY_STATE_MOVING "state_moving" // 运动状态
+#define JSON_KEY_STATE_BIZ "state_biz" // 业务状态
+#define JSON_KEY_MAP_ID "map_id" // "地图编号"
+#define JSON_KEY_DEPT_ID "dept_id"
+#define JSON_KEY_SPEED "speed"	//速度
+#define JSON_KEY_LANDMARK_ID "landmark_id"
+#define JSON_KEY_DIRECTORY_ID "landmark_direction_id"
+#define JSON_KEY_LANDMARK_DIS "landmark_distance"
+
+// id, name, type, map_id
+#define JSON_KEY_AREA_ID "area_id" // "区域编号"
+#define JSON_KEY_AREA_IS_SPECIAL "is_special_area" // "区域名称"
+// down_mine,up_mine
+#define JSON_CMD_VALUE_DOWN_MINE "down_mine"
+#define JSON_CMD_VALUE_UP_MINE "up_mine"
+#define JSON_CMD_VALUE_SPECIAL_AREA_UP_MINE "special_area_up_mine"
+#define JSON_CMD_VALUE_DEV_STATE "device_state"
+#define JSON_CMD_VALUE_EVENT "event"
+#define JSON_CMD_VALUE_CALL "CALL"
+#define JSON_CMD_VALUE_PUSH "PUSH"
+#define JSON_CMD_VALUE_USER "USER"
+#define JSON_CMD_DRIVING_FACE_STATE "tunneller_stat"
+// pos_map
+#define JSON_CMD_VALUE_POS_MAP "pos_map"
+
+// 告警事件
+#define JSON_KEY_EVENT_EVENT_ID "event_id"
+#define JSON_KEY_EVENT_STATUS "status"
+#define JSON_KEY_EVENT_TYPE_ID "type_id"
+#define JSON_KEY_EVENT_OBJ_TYPE_ID "obj_type_id"
+#define JSON_KEY_EVENT_OBJ_ID "obj_id"
+#define JSON_KEY_EVENT_MAP_ID "map_id"
+#define JSON_KEY_EVENT_AREA_ID "area_id"
+#define JSON_KEY_EVENT_X "x"
+#define JSON_KEY_EVENT_Y "y"
+#define JSON_KEY_EVENT_LIMIT_VALUE "limit_value"
+#define JSON_KEY_EVENT_CUR_VALUE "cur_value"
+#define JSON_KEY_EVENT_CUR_TIME "cur_time"
+#define JSON_KEY_EVENT_LANDMARK_ID "lmid"
+#define JSON_KEY_EVENT_LANDMARK_DIRECTION "lmdirect"
+#define JSON_KEY_EVENT_LANDMARK_DISTANCE "lmdistance"
+#define JSON_KEY_EVENT_READER_POS_CHANGE    "reader_pos_change"
+
+// alarm
+#define JSON_KEY_ALARM_OVER_COUNT_PERSON "over_count_person"
+#define JSON_KEY_ALARM_OVER_COUNT_VEHICLE "over_count_vehicle"
+#define JSON_KEY_ALARM_OVER_TIME_PERSON "over_time_person"
+#define JSON_KEY_ALARM_OVER_TIME_VEHICLE "over_time_vehicle"
+#define JSON_KEY_ALARM_OVER_SPEED_VEHICLE "over_speed_vehicle"
+
+#define JSON_KEY_ALARM_START_TIME "alarm_start_time"
+
+#define JSON_KEY_ALARM_STAFFER_ID "staffer_id"
+#define JSON_KEY_ALARM_VEHICLE_ID "vehicle_id"
+
+#define JSON_KEY_ALARM_SECTION "section_info"
+#define JSON_KEY_ALARM_SECTION_ID "section_id"
+#define JSON_KEY_ALARM_SECTION_VEHICLE_COUNTS "vehicle_counts"
+#define JSON_KEY_ALARM_SECTION_STAFFER_COUNTS "staffer_counts"
+#define JSON_KEY_ALARM_SECTION_STATE "state"
+
+#define JSON_KEY_ALARM_LIGHT "light_info"
+#define JSON_KEY_ALARM_LIGHT_ID "light_id"
+#define JSON_KEY_ALARM_LIGHT_GROUP_ID "light_group_id"
+#define JSON_KEY_ALARM_LIGHT_GROUP_NAME	"light_group_name"
+
+#define JSON_KEY_ALARM_TRAFFIC_RED_LIGHT "traffic_red_light"
+// 掘进面
+#define JSON_KEY_DRIVINGFACE_DIS "driving_face_moving_dis"
+#define JSON_KEY_DRIVINGFACE_WARNING_POINT_ID "driving_face_warning_point_id"
+#define JSON_KEY_DRIVINGFACE_WARNING_POINT_DIS "driving_face_warning_point_dis"
+
+#define JSON_KEY_DRIVINGFACE_CURSHIFT_LENGTH "drivingface_curshift_length"
+
+//人上车状态
+#define JSON_KEY_PERSON_ON_CAR "person_on_car"
+#define JSON_CMD_REQ_ALL_PERSON_ON_CAR "req_all_person_on_car"
+#define JSON_CMD_RESP_ALL_PERSON_ON_CAR "resp_all_person_on_car"
+
 #endif // !_SERVER_CONST_DEF_H_

+ 350 - 23
websocket/jsonBuilder.cpp

@@ -1,5 +1,5 @@
 #include "jsonBuilder.h"
-
+#include <cstdlib>
 
 #include <rapidjson/writer.h>
 #include <rapidjson/stringbuffer.h>
@@ -8,11 +8,9 @@
 
 namespace YA
 {
-
 	jsonBuilder::jsonBuilder()
 	{
 
-
 	}
 
 	jsonBuilder::~jsonBuilder()
@@ -20,44 +18,373 @@ namespace YA
 
 	}
 
-	void jsonBuilder::__AddVersion( rapidjson::Value& root, rapidjson::Document::AllocatorType& allocator )
+	std::string jsonBuilder::__FmtCardID( const _CARD_POS_ & CardPos )
+	{
+		std::string ID;
+
+		char szID[32] = { 0 };
+
+		switch ( CardPos.Type )
+		{
+			case 1://人卡
+			{
+				sprintf( szID, "001%.10d", CardPos.ID );
+			}
+			break;
+			case 2://车卡
+			{
+				sprintf( szID, "002%.10d", CardPos.ID );
+			}
+			break;
+		}
+
+		ID = szID;
+
+		return ID;
+	}
+
+	void jsonBuilder::__AddVersion( rapidjson::Value& root, rapidjson::Document::AllocatorType& Allocator )
+	{
+		rapidjson::Value value( rapidjson::kStringType );
+
+		value.SetString( INTERFACE_VERSION_1_4, Allocator );
+		root.AddMember( JSON_ROOT_KEY_VERSION, value, Allocator );
+	}
+
+	void jsonBuilder::__SetCmd( const char* szCmd, rapidjson::Value & root, rapidjson::Document::AllocatorType & Allocator )
 	{
-		rapidjson::Value key( rapidjson::kStringType );
 		rapidjson::Value value( rapidjson::kStringType );
 
-		key.SetString( JSON_ROOT_KEY_VERSION, allocator );
-		value.SetString( JASON_CURRENT_VERSION, allocator );
-		root.AddMember( key, value, allocator );
+		value.SetString( szCmd, Allocator );
+		root.AddMember( JSON_ROOT_KEY_CMD, value, Allocator );
+	}
+
+	bool jsonBuilder::__BuildDetail( const _CARD_POS_ & CardPos, rapidjson::Document::AllocatorType& Allocator, rapidjson::Value & DetailItem )
+	{
+		rapidjson::Value Array( rapidjson::kArrayType );
+		rapidjson::Value tmp_object( rapidjson::kObjectType );
+
+		//0 ID
+		tmp_object.SetString( __FmtCardID( CardPos ).c_str(), Allocator );
+		Array.PushBack( tmp_object, Allocator );
+
+		//1 x
+		tmp_object.SetDouble( CardPos.x );
+		Array.PushBack( tmp_object, Allocator );
+
+		//2 y
+		tmp_object.SetDouble( CardPos.y );
+		Array.PushBack( tmp_object, Allocator );
+
+		//3 入井时间戳
+		tmp_object.SetDouble( CardPos.down_time );
+		Array.PushBack( tmp_object, Allocator );
+
+		//4 进入区域时间戳
+		tmp_object.SetDouble( CardPos.enter_area_time );
+		Array.PushBack( tmp_object, Allocator );
+
+		//5 最后接收时间戳
+		tmp_object.SetDouble( CardPos.rec_time );
+		Array.PushBack( tmp_object, Allocator );
+
+		//6 工作时长
+		tmp_object.SetDouble( CardPos.work_time );
+		Array.PushBack( tmp_object, Allocator );
+
+		//7 地图编号
+		tmp_object.SetInt( CardPos.map_id );
+		Array.PushBack( tmp_object, Allocator );
+
+		//8 区域编号
+		tmp_object.SetInt( CardPos.area_id );
+		Array.PushBack( tmp_object, Allocator );
+
+		//9 部门编号
+		tmp_object.SetInt( CardPos.dept_id );
+		Array.PushBack( tmp_object, Allocator );
+
+		//10 状态
+		tmp_object.SetInt( CardPos.stat );
+		Array.PushBack( tmp_object, Allocator );
+
+		//11 运行状态
+		tmp_object.SetInt( CardPos.running_stat );
+		Array.PushBack( tmp_object, Allocator );
+
+		//12 业务状态
+		tmp_object.SetInt( CardPos.biz_stat );
+		Array.PushBack( tmp_object, Allocator );
+
+		//13 速度
+		tmp_object.SetDouble( CardPos.speed );
+		Array.PushBack( tmp_object, Allocator );
+
+		//14 地标编号
+		tmp_object.SetInt( CardPos.landmark_id );
+		Array.PushBack( tmp_object, Allocator );
+
+		//15 地标方向
+		tmp_object.SetInt( CardPos.lm_direction );
+		Array.PushBack( tmp_object, Allocator );
+
+		//16 距离地标的距离
+		tmp_object.SetDouble( CardPos.landmark_dis );
+		Array.PushBack( tmp_object, Allocator );
+
+		//17 级别编号
+		tmp_object.SetInt( CardPos.level_id );
+		Array.PushBack( tmp_object, Allocator );
+
+		//18 车辆当天出勤的标识
+		tmp_object.SetInt( CardPos.is_on_duty );
+		Array.PushBack( tmp_object, Allocator );
+
+		DetailItem = Array;
+		return true;
+	}
+
+	bool jsonBuilder::__BuildDept( const std::map<int, _STAT_DEPT_ITEM_>& dept_map, rapidjson::Document::AllocatorType & Allocator, rapidjson::Value & Dept )
+	{
+		std::map<int, _STAT_DEPT_ITEM_>::const_iterator mit_dept;
+		for ( mit_dept = dept_map.begin(); mit_dept != dept_map.end(); mit_dept++ )
+		{
+			rapidjson::Value DeptItem( rapidjson::kObjectType );
+
+			__BuildDeptItem( mit_dept->second, Allocator, DeptItem );
+
+			rapidjson::Value dept_id( rapidjson::kObjectType );
+			char szNum[20] = { 0 };
+			//itoa( mit_dept->second.DeptID, szNum, 10 );
+			sprintf(szNum,"%d",mit_dept->second.DeptID);
+
+			dept_id.SetString( szNum, strlen( szNum ), Allocator );
+			Dept.AddMember( dept_id, DeptItem, Allocator );
+		}
+
+		return true;
+	}
+
+	void jsonBuilder::__BuildDeptItem( const _STAT_DEPT_ITEM_ & st_dept_item, rapidjson::Document::AllocatorType & Allocator, rapidjson::Value & DeptItem )
+	{
+		//Area
+		__BuildIDSumMap( st_dept_item.Area, JSON_ROOT_KEY_STATISTIC_AREA, Allocator, DeptItem );
+
+		//Dept
+		__BuildIDSumMap( st_dept_item.Dept, JSON_ROOT_KEY_STATISTIC_DEPT, Allocator, DeptItem );
+
+		//occupation_level
+		__BuildIDSumMap( st_dept_item.OcptLvl, JSON_ROOT_KEY_STATISTIC_LEVEL, Allocator, DeptItem );
+
+		//sum
+		rapidjson::Value Sum( rapidjson::kObjectType );
+		Sum.SetInt( st_dept_item.Sum );
+		DeptItem.AddMember( JSON_ROOT_KEY_STATISTIC_SUM, Sum, Allocator );
+	}
+
+	void jsonBuilder::__CreateDeptMap( const _CARD_POS_ & CardPos, std::map<int, _STAT_DEPT_ITEM_>& DeptMap )
+	{
+		std::map<int, _STAT_DEPT_ITEM_>::iterator mit_dept_map;
+
+		mit_dept_map = DeptMap.find( CardPos.dept_id );
+		if ( mit_dept_map == DeptMap.end() )
+		{
+			_STAT_DEPT_ITEM_ sdItem;
+			sdItem.DeptID = CardPos.dept_id;
+			sdItem.Area.insert( std::make_pair( CardPos.area_id, 1 ) );
+			sdItem.Dept.insert( std::make_pair( CardPos.dept_id, 1 ) );
+			sdItem.OcptLvl.insert( std::make_pair( CardPos.level_id, 1 ) );
+			sdItem.Sum = 1;
+			DeptMap.insert( std::make_pair( sdItem.DeptID, sdItem ) );
+		}
+		else
+		{
+			__CreateDeptItem( CardPos, mit_dept_map->second );
+			
+		}
+	}
+
+	void jsonBuilder::__CreateDeptItem( const _CARD_POS_ & CardPos, _STAT_DEPT_ITEM_ & DeptItem )
+	{
+		std::map<int, int>::iterator mit_id_sum;
+
+		//area
+		mit_id_sum = DeptItem.Area.find( CardPos.area_id );
+		if ( mit_id_sum == DeptItem.Area.end() )
+		{
+			DeptItem.Area.insert( std::make_pair( CardPos.area_id, 1 ) );
+		}
+		else
+		{
+			mit_id_sum->second++;
+		}
+
+		//Dept
+		mit_id_sum = DeptItem.Dept.find( CardPos.dept_id );
+		if ( mit_id_sum == DeptItem.Dept.end() )
+		{
+			DeptItem.Dept.insert( std::make_pair( CardPos.dept_id, 1 ) );
+		}
+		else
+		{
+			mit_id_sum->second++;
+		}
+
+		//occupation_level
+		mit_id_sum = DeptItem.OcptLvl.find( CardPos.level_id );
+		if ( mit_id_sum == DeptItem.OcptLvl.end() )
+		{
+			DeptItem.OcptLvl.insert( std::make_pair( CardPos.level_id, 1 ) );
+		}
+		else
+		{
+			mit_id_sum->second++;
+		}
+
+		//Sum
+		DeptItem.Sum++;
+	}
+
+	void jsonBuilder::__BuildIDSumMap( const std::map<int, int>& id_sum_map, const char* szName, rapidjson::Document::AllocatorType & Allocator, rapidjson::Value & Parent )
+	{
+		rapidjson::Value Array( rapidjson::kArrayType );
+		std::map<int, int>::const_iterator mit_id_sum;
+
+		for ( mit_id_sum = id_sum_map.begin(); mit_id_sum != id_sum_map.end(); mit_id_sum++ )
+		{
+			rapidjson::Value Item( rapidjson::kArrayType );
+			rapidjson::Value tmpobj( rapidjson::kObjectType );
+
+			tmpobj.SetInt( mit_id_sum->first );
+			Item.PushBack( tmpobj, Allocator );
+
+			tmpobj.SetInt( mit_id_sum->second );
+			Item.PushBack( tmpobj, Allocator );
+
+			Array.PushBack( Item, Allocator );
+		}
+
+		Parent.AddMember( rapidjson::StringRef( szName ), Array, Allocator );
 	}
 
 	std::string jsonBuilder::BuildLogin( const _JS_LOGIN_& Login )
 	{
 		rapidjson::StringBuffer sb;
 		rapidjson::Writer<rapidjson::StringBuffer> writer( sb );
-
 		rapidjson::Document doc;
+		rapidjson::Document::AllocatorType& Allocator = doc.GetAllocator();
 
-		rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
 		rapidjson::Value root( rapidjson::kObjectType );
 		rapidjson::Value child( rapidjson::kObjectType );
-		rapidjson::Value key( rapidjson::kStringType );
 		rapidjson::Value value( rapidjson::kStringType );
 
-		key.SetString( JSON_ROOT_KEY_CMD, allocator );
-		value.SetString( JASON_CMD_LOGIN, allocator );
-		root.AddMember( key, value, allocator );
+		__SetCmd( JSON_CMD_VALUE_LOGIN, root, Allocator );
+
+		value.SetString( Login.user_name.c_str(), Allocator );
+		child.AddMember( JSON_KEY_USERNAME, value, Allocator );
+
+		value.SetString( Login.user_password.c_str(), Allocator );
+		child.AddMember( JSON_KEY_PASSWORD, value, Allocator );
+
+		root.AddMember( JSON_ROOT_KEY_DATA, child, Allocator );
+
+		root.Accept( writer );
+
+		return sb.GetString();
+	}
+
+	std::string jsonBuilder::BuildCardPos( const std::map<int, _CARD_POS_>& CardPosList )
+	{
+		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_POS_MAP, root, Allocator );
+
+		rapidjson::Value s( rapidjson::kObjectType );
+		rapidjson::Value v( rapidjson::kObjectType );
+		rapidjson::Value s_Detail( rapidjson::kArrayType );
+		rapidjson::Value v_Detail( rapidjson::kArrayType );
+		rapidjson::Value s_dept( rapidjson::kObjectType );
+		rapidjson::Value v_dept( rapidjson::kObjectType );
+		std::map<int, _STAT_DEPT_ITEM_> s_dept_map;
+		std::map<int, _STAT_DEPT_ITEM_> v_dept_map;
+		_STAT_DEPT_ITEM_ s_glbl_item;
+		_STAT_DEPT_ITEM_ v_glbl_item;
+		std::map<int, _CARD_POS_>::const_iterator mit_card;
+		for ( mit_card = CardPosList.begin(); mit_card != CardPosList.end(); mit_card++ )
+		{
+			//不显示的卡不往前端推送
+			if ( !mit_card->second.display )
+			{
+				continue;
+			}
+
+			rapidjson::Value DetailItem;
+			if ( !__BuildDetail( mit_card->second, Allocator, DetailItem ) )
+			{
+				continue;
+			}
+			
+			switch ( mit_card->second.Type )
+			{
+				case 1://人卡
+				{
+					s_Detail.PushBack( DetailItem, Allocator );
+					__CreateDeptMap( mit_card->second, s_dept_map );
+					__CreateDeptItem(  mit_card->second, s_glbl_item );
+				}
+				break;
+				case 2://车卡
+				{
+					v_Detail.PushBack( DetailItem, Allocator );
+					__CreateDeptMap( mit_card->second, v_dept_map );
+					__CreateDeptItem(  mit_card->second, v_glbl_item );
+				}
+				break;
+			}
+		}
+
+		s.AddMember( JSON_ROOT_KEY_STATISTIC_DETAIL, s_Detail, Allocator );
+		v.AddMember( JSON_ROOT_KEY_STATISTIC_DETAIL, v_Detail, Allocator );
+
+		//stat
+		rapidjson::Value s_stat( rapidjson::kObjectType );
+		rapidjson::Value v_stat( rapidjson::kObjectType );
+
+		if ( __BuildDept( s_dept_map, Allocator, s_dept ) )
+		{
+			s_stat.AddMember( JSON_ROOT_KEY_STATISTIC_DEPT, s_dept, Allocator );
+		}
+
+		if ( __BuildDept( v_dept_map, Allocator, v_dept ) )
+		{
+			v_stat.AddMember( JSON_ROOT_KEY_STATISTIC_DEPT, v_dept, Allocator );
+		}
+			
+		s.AddMember( JSON_ROOT_KEY_STATISTIC_STAT, s_stat, Allocator );
+		v.AddMember( JSON_ROOT_KEY_STATISTIC_STAT, v_stat, Allocator );
+
+		//glbl
+		rapidjson::Value s_glbl( rapidjson::kObjectType );
+		rapidjson::Value v_glbl( rapidjson::kObjectType );
+
+		__BuildDeptItem( s_glbl_item, Allocator, s_glbl );
+		__BuildDeptItem( v_glbl_item, Allocator, v_glbl );
 
-		key.SetString( JSON_KEY_USERNAME, allocator );
-		value.SetString( Login.user_name.c_str(), allocator );
-		child.AddMember( key, value, allocator );
+		s.AddMember( JSON_ROOT_KEY_STATISTIC_GLOBAL, s_glbl, Allocator );
+		v.AddMember( JSON_ROOT_KEY_STATISTIC_GLOBAL, v_glbl, Allocator );
 
-		key.SetString( JSON_KEY_PASSWORD, allocator );
-		value.SetString( Login.user_password.c_str(), allocator );
-		child.AddMember( key, value, allocator );
+		rapidjson::Value Data( rapidjson::kObjectType );
+		Data.AddMember( JSON_ROOT_KEY_STATISTIC_STAFF_DATA, s, Allocator );
+		Data.AddMember( JSON_ROOT_KEY_STATISTIC_VEHICLE_DATA, v, Allocator );
 
-		key.SetString( JSON_ROOT_KEY_DATA, allocator );
-		root.AddMember( key, child, allocator );
+		root.AddMember( JSON_ROOT_KEY_DATA, Data, Allocator );
 
+		__AddVersion( root, Allocator );
 		root.Accept( writer );
 
 		return sb.GetString();
@@ -129,7 +456,7 @@ namespace YA
 			Error = "data::stations is not a valid array!";
 			return false;
 		}
-		for ( int i = 0; i <(int) stations.Size(); ++i )
+		for ( int i = 0; i < (int)stations.Size(); ++i )
 		{
 			rapidjson::Value & v = stations[i];
 			if ( !v.IsObject() )

+ 184 - 2
websocket/jsonBuilder.h

@@ -1,8 +1,33 @@
+/**
+* @brief
+json构造器类
+
+* @version
+  V 1.0.0
+
+* @author
+  王益俊
+
+* @date
+  创建时间:  2018-08-17\n
+
+* @note
+  2018-08-17  创建类。\n
+
+* @warning
+
+* @bug
+  
+*/
+
 #ifndef _JSONBUILDER_H_
 #define _JSONBUILDER_H_
 
+#include <map>
 #include <rapidjson/document.h>
+
 #include "jsonCommon.h"
+#include "ws_common.h"
 
 namespace YA
 {
@@ -14,7 +39,79 @@ namespace YA
 		加上版本信息函数。
 
 		* @param  [out] rapidjson::Value& root  根jason对象\n
-		* @param  [out] rapidjson::Document::AllocatorType& allocator  分配器\n
+		* @param  [out] rapidjson::Document::AllocatorType& Allocator  分配器\n
+
+		* @return 无\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+        void __AddVersion( rapidjson::Value& root, rapidjson::Document::AllocatorType& Allocator );
+		/**
+		* @brief
+		设置命令信息函数。
+
+		* @param  [in] const char* szCmd  命令\n
+		* @param  [out] rapidjson::Value& root  根jason对象\n
+		* @param  [out] rapidjson::Document::AllocatorType& Allocator  分配器\n
+
+		* @return 无\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void __SetCmd( const char* szCmd, rapidjson::Value& root, rapidjson::Document::AllocatorType& Allocator );
+		/**
+		* @brief
+		构造卡明细函数。
+
+		* @param  [in] const _CARD_POS_& CardPos  卡位置\n
+		* @param  [out] rapidjson::Document::AllocatorType& Allocator  分配器\n
+		* @param  [out] rapidjson::Value& DetailItem  生成的单个人卡明细\n
+
+		* @return 构造是否成功\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		bool __BuildDetail( const _CARD_POS_& CardPos, rapidjson::Document::AllocatorType& Allocator, rapidjson::Value& DetailItem );
+		/**
+		* @brief
+		构造部门列表json对象函数。
+
+		* @param  [in] const std::map<int, _STAT_DEPT_ITEM_>& dept_map  部门统计列表\n
+		* @param  [out] rapidjson::Document::AllocatorType& Allocator  分配器\n
+		* @param  [out] rapidjson::Value& Dept  生成的部门json对象\n
+
+		* @return 构造是否成功\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		bool __BuildDept( const std::map<int, _STAT_DEPT_ITEM_>& dept_map, rapidjson::Document::AllocatorType& Allocator, rapidjson::Value& Dept );
+		/**
+		* @brief
+		构造部门项json对象函数。
+
+		* @param  [in] const _STAT_DEPT_ITEM_& st_dept_item  部门项\n
+		* @param  [out] rapidjson::Document::AllocatorType& Allocator  分配器\n
+		* @param  [out] rapidjson::Value& DeptItem  生成的部门项json对象\n
 
 		* @return 无\n
 
@@ -25,7 +122,76 @@ namespace YA
 		* @bug
 
 		*/
-        void __AddVersion( rapidjson::Value& root, rapidjson::Document::AllocatorType& allocator );
+		void __BuildDeptItem( const _STAT_DEPT_ITEM_& st_dept_item, rapidjson::Document::AllocatorType& Allocator, rapidjson::Value& DeptItem );
+		/**
+		* @brief
+		生成Dept Map函数。
+
+		* @param  [in] const _CARD_POS_& CardPos  卡定位数据\n
+		* @param  [out] std::map<int, _STAT_DEPT_ITEM_>& DeptMap  生成的Dept Map\n
+
+		* @return 无\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void __CreateDeptMap( const _CARD_POS_& CardPos, std::map<int, _STAT_DEPT_ITEM_>& DeptMap );
+		/**
+		* @brief
+		生成_STAT_DEPT_ITEM_结构体函数。
+
+		* @param  [in] const _CARD_POS_& CardPos  卡定位数据\n
+		* @param  [out] _STAT_DEPT_ITEM_& DeptItem  生成的DeptItem\n
+
+		* @return 无\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void __CreateDeptItem( const _CARD_POS_& CardPos, _STAT_DEPT_ITEM_& DeptItem );
+		/**
+		* @brief
+		构造id sum map对象函数。
+
+		* @param  [in] const std::map<int,int>& id_sum_map  id sum 列表\n
+		* @param  [in] const char* szName  名称\n
+		* @param  [out] rapidjson::Document::AllocatorType& Allocator  分配器\n
+		* @param  [out] rapidjson::Value& Dept  生成的部门json对象\n
+
+		* @return 无\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void __BuildIDSumMap( const std::map<int,int>& id_sum_map, const char* szName, rapidjson::Document::AllocatorType & Allocator, rapidjson::Value & Parent );
+		/**
+		* @brief
+		格式化生成卡号函数。
+
+		* @param  [in] const _CARD_POS_& CardPos  卡位置\n
+
+		* @return 格式化生成的卡号\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+        std::string __FmtCardID( const _CARD_POS_& CardPos );
 	public:
 		jsonBuilder();
 		virtual ~jsonBuilder();
@@ -47,6 +213,22 @@ namespace YA
 		std::string BuildLogin( const _JS_LOGIN_& Login );
 		/**
 		* @brief
+		生成卡位置jason函数。
+
+		* @param  [in] const std::map<int, _CARD_POS_>& CardPosList  卡位置列表\n
+
+		* @return 如果成功返回生成的json字符串,否则返回空字符串\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		std::string BuildCardPos( const std::map<int, _CARD_POS_>& CardPosList );
+		/**
+		* @brief
 		解析呼叫结构体函数。
 
 		* @param  [in] const _JS_LOGIN_& Login  登录参数\n

+ 5 - 21
websocket/jsonCommon.h

@@ -1,4 +1,4 @@
-/**
+/**
 * @brief
 jason公共头文件
 
@@ -28,27 +28,11 @@ V 1.0.0
 
 #include <rapidjson/document.h>
 #include <rapidjson/pointer.h>
+#include "constdef.h"
 
 namespace YA
 {
 
-//----------------------------------------------------------------------------
-//                                 命令
-//----------------------------------------------------------------------------
-const char JASON_CMD_LOGIN[]              = "login";
-
-
-//----------------------------------------------------------------------------
-//                                 字段
-//----------------------------------------------------------------------------
-const char JASON_FIELD_CMD[]              = "cmd";
-
-//----------------------------------------------------------------------------
-//                                 版本
-//----------------------------------------------------------------------------
-const char JASON_CURRENT_VERSION[]        = "1.0.0.4";
-
-
 /**
  * @brief
  通用jason包结构体
@@ -80,15 +64,15 @@ public:
     std::string GetCmd( std::string& Error )
     {
     	rapidjson::Value::MemberIterator itMember;
-    	itMember = m_Doc.FindMember( JASON_FIELD_CMD );
+    	itMember = m_Doc.FindMember( JSON_ROOT_KEY_CMD );
 		if ( itMember == m_Doc.MemberEnd() )
 		{
 			Error = "Error,Failed to find member: ";
-			Error += JASON_FIELD_CMD;
+			Error += JSON_ROOT_KEY_CMD;
 			return "";
 		}
 
-    	return m_Doc[JASON_FIELD_CMD].GetString();
+    	return m_Doc[JSON_ROOT_KEY_CMD].GetString();
     }
     /**
 	* @brief

+ 35 - 35
websocket/singleton_test_class1.cpp

@@ -1,36 +1,36 @@
-#include "singleton_test_class1.h"
-#include "wsClientMgr.h"
-#include <iostream>
-
-singleton_test_class1::singleton_test_class1()
-{
-	
-}
-
-singleton_test_class1::~singleton_test_class1()
-{
-
-}
-
-void singleton_test_class1::DoSome()
-{
-	std::cout << "-- singleton_test_class1::DoSome() --" << std::endl;
-
-	if ( swsClientMgr.IsConnected() )
-	{
-		std::cout << "swsClientMgr Is Connected!" << std::endl;
-	}
-	else
-	{
-		std::cout << "swsClientMgr Is not Connected!" << std::endl;
-	}
-
-	if ( swsClientMgr.IsLogined() )
-	{
-		std::cout << "swsClientMgr Is Logined!" << std::endl;
-	}
-	else
-	{
-		std::cout << "swsClientMgr Is not Logined!" << std::endl;
-	}
+#include "singleton_test_class1.h"
+#include "wsClientMgr.h"
+#include <iostream>
+
+singleton_test_class1::singleton_test_class1()
+{
+	
+}
+
+singleton_test_class1::~singleton_test_class1()
+{
+
+}
+
+void singleton_test_class1::DoSome()
+{
+	std::cout << "-- singleton_test_class1::DoSome() --" << std::endl;
+
+	if ( swsClientMgr.IsConnected() )
+	{
+		std::cout << "swsClientMgr Is Connected!" << std::endl;
+	}
+	else
+	{
+		std::cout << "swsClientMgr Is not Connected!" << std::endl;
+	}
+
+	if ( swsClientMgr.IsLogined() )
+	{
+		std::cout << "swsClientMgr Is Logined!" << std::endl;
+	}
+	else
+	{
+		std::cout << "swsClientMgr Is not Logined!" << std::endl;
+	}
 }

+ 8 - 8
websocket/singleton_test_class1.h

@@ -1,9 +1,9 @@
-#pragma once
-
-class singleton_test_class1
-{
-public:
-	singleton_test_class1();
-	~singleton_test_class1();
-	void DoSome();
+#pragma once
+
+class singleton_test_class1
+{
+public:
+	singleton_test_class1();
+	~singleton_test_class1();
+	void DoSome();
 };

BIN
websocket/socket.io-client-cpp_test.cpp


+ 256 - 225
websocket/thread_safe_map.h

@@ -1,226 +1,257 @@
-/**
-* @brief
-线程安全模板类
-
-* @version
-  V 1.0.0
-
-* @author
-  王益俊
-
-* @date
-  创建时间:  2018-08-20\n
-
-* @note
-  2018-08-20  创建类。\n
-
-* @warning
-
-* @bug
-  
-*/
-
-#pragma once
-
-#include <map>
-#include <stdint.h>
-#include <boost/thread/mutex.hpp>
-
-template<class Key, class T>
-class thread_safe_map
-{
-private:
-	std::map<Key, T> __map;
-	mutable boost::mutex the_mutex;
-public:
-	/**
-	* @brief
-	重置函数。
-
-	* @param  [in] const Key &inputKey  key\n
-	* @param  [in] const T &inputValue  value\n
-
-	* @return 无\n
-
-	* @note
-
-	* @warning
-
-	* @bug
-
-	*/
-	void insert( const Key &inputKey, const T &inputValue )
-	{
-		boost::mutex::scoped_lock lock( the_mutex );
-		__map.insert( std::pair<Key, T>( inputKey, inputValue ) );
-		lock.unlock();
-	}
-	/**
-	* @brief
-	返回map是否为空函数。
-
-	* @param  无\n
-
-	* @return 是否为空\n
-	* @retval  true  为空\n
-    * @retval  false  不为空\n
-
-	* @note
-
-	* @warning
-
-	* @bug
-
-	*/
-	bool empty() const 
-	{
-		boost::mutex::scoped_lock lock( the_mutex );
-		return __map.empty();
-	}
-	/**
-	* @brief
-	用某个key获取值的函数。
-
-	* @param  [in] const Key &inputKey  指定的key\n
-	* @param  [out] T &outputValue  获得的值\n
-
-	* @return 是否获取成功\n
-	* @retval  true  成功\n
-    * @retval  false  失败\n
-
-	* @note
-
-	* @warning
-
-	* @bug
-
-	*/
-	bool get( const Key &inputKey, T &outputValue ) 
-	{
-		boost::mutex::scoped_lock lock( the_mutex );
-
-		typename std::map<Key, T>::iterator it;
-		it = __map.find( inputKey );
-
-		if ( __map.end() == it ) 
-		{
-			return false;
-		}
-
-		outputValue = it->second;
-		return true;
-	}
-	/**
-	* @brief
-	更新某个key对应值的函数。
-
-	* @param  [in] const Key &inputKey  指定的key\n
-	* @param  [out] T &outputValue  获得的值\n
-
-	* @return 是否获取成功\n
-	* @retval  true  成功\n
-    * @retval  false  失败\n
-
-	* @note
-
-	* @warning
-
-	* @bug
-
-	*/
-	bool update( const Key &inputKey, const T &inputValue )
-	{
-		boost::mutex::scoped_lock lock( the_mutex );
-
-		typename std::map<Key, T>::iterator it;
-		it = __map.find( inputKey );
-
-		if ( __map.end() == it ) 
-		{
-			return false;
-		}
-
-		it->second = inputValue;
-		return true;
-	}
-	/**
-	* @brief
-	根据某个key删除值的函数。
-
-	* @param  [in] const Key &inputKey  指定的key\n
-
-	* @return 无\n
-
-	* @note
-
-	* @warning
-
-	* @bug
-
-	*/
-	void erase( const Key &inputKey )
-	{
-		boost::mutex::scoped_lock lock( the_mutex );
-		__map.erase( inputKey );
-	}
-	/**
-	* @brief
-	获得大小的函数。
-
-	* @param  无\n
-
-	* @return 无\n
-
-	* @note
-
-	* @warning
-
-	* @bug
-
-	*/
-	size_t size() const
-	{
-		boost::mutex::scoped_lock lock( the_mutex );
-		return __map.size();
-	}
-	/**
-	* @brief
-	清除map的函数。
-
-	* @param  无\n
-
-	* @return 无\n
-
-	* @note
-
-	* @warning
-
-	* @bug
-
-	*/
-	void clear()
-	{
-		boost::mutex::scoped_lock lock( the_mutex );
-		__map.clear();
-	}
-	/**
-	* @brief
-	拷贝map的函数。
-
-	* @param  无\n
-
-	* @return 无\n
-
-	* @note
-
-	* @warning
-
-	* @bug
-
-	*/
-	void copy( std::map<Key, T>& dest_map )
-	{
-		boost::mutex::scoped_lock lock( the_mutex );
-		dest_map = __map;
-	}
+/**
+* @brief
+线程安全模板类
+
+* @version
+  V 1.0.0
+
+* @author
+  王益俊
+
+* @date
+  创建时间:  2018-08-20\n
+
+* @note
+  2018-08-20  创建类。\n
+
+* @warning
+
+* @bug
+  
+*/
+
+#pragma once
+
+#include <map>
+#include <stdint.h>
+#include <boost/thread/mutex.hpp>
+
+template<class Key, class T>
+class thread_safe_map
+{
+private:
+	std::map<Key, T> __map;
+	mutable boost::mutex the_mutex;
+public:
+	/**
+	* @brief
+	重置函数。
+
+	* @param  [in] const Key &inputKey  key\n
+	* @param  [in] const T &inputValue  value\n
+
+	* @return 无\n
+
+	* @note
+
+	* @warning
+
+	* @bug
+
+	*/
+	void insert( const Key &inputKey, const T &inputValue )
+	{
+		boost::mutex::scoped_lock lock( the_mutex );
+		__map.insert( std::pair<Key, T>( inputKey, inputValue ) );
+		lock.unlock();
+	}
+	/**
+	* @brief
+	返回map是否为空函数。
+
+	* @param  无\n
+
+	* @return 是否为空\n
+	* @retval  true  为空\n
+    * @retval  false  不为空\n
+
+	* @note
+
+	* @warning
+
+	* @bug
+
+	*/
+	bool empty() const 
+	{
+		boost::mutex::scoped_lock lock( the_mutex );
+		return __map.empty();
+	}
+	/**
+	* @brief
+	用某个key获取值的函数。
+
+	* @param  [in] const Key &inputKey  指定的key\n
+	* @param  [out] T &outputValue  获得的值\n
+
+	* @return 是否获取成功\n
+	* @retval  true  成功\n
+    * @retval  false  失败\n
+
+	* @note
+
+	* @warning
+
+	* @bug
+
+	*/
+	bool get( const Key &inputKey, T &outputValue ) 
+	{
+		boost::mutex::scoped_lock lock( the_mutex );
+
+		typename std::map<Key, T>::iterator it;
+		it = __map.find( inputKey );
+
+		if ( __map.end() == it ) 
+		{
+			return false;
+		}
+
+		outputValue = it->second;
+		return true;
+	}
+	/**
+	* @brief
+	用查找某个key是否存在的函数。
+
+	* @param  [in] const Key &inputKey  指定的key\n
+
+	* @return 是否存在\n
+	* @retval  true  存在\n
+    * @retval  false  不存在\n
+
+	* @note
+
+	* @warning
+
+	* @bug
+
+	*/
+	bool seek( const Key &inputKey ) 
+	{
+		boost::mutex::scoped_lock lock( the_mutex );
+
+		typename std::map<Key, T>::iterator it;
+		it = __map.find( inputKey );
+
+		if ( __map.end() == it ) 
+		{
+			return false;
+		}
+
+		return true;
+	}
+	/**
+	* @brief
+	更新某个key对应值的函数。
+
+	* @param  [in] const Key &inputKey  指定的key\n
+	* @param  [out] T &outputValue  获得的值\n
+
+	* @return 是否获取成功\n
+	* @retval  true  成功\n
+    * @retval  false  失败\n
+
+	* @note
+
+	* @warning
+
+	* @bug
+
+	*/
+	bool update( const Key &inputKey, const T &inputValue )
+	{
+		boost::mutex::scoped_lock lock( the_mutex );
+
+		typename std::map<Key, T>::iterator it;
+		it = __map.find( inputKey );
+
+		if ( __map.end() == it ) 
+		{
+			return false;
+		}
+
+		it->second = inputValue;
+		return true;
+	}
+	/**
+	* @brief
+	根据某个key删除值的函数。
+
+	* @param  [in] const Key &inputKey  指定的key\n
+
+	* @return 无\n
+
+	* @note
+
+	* @warning
+
+	* @bug
+
+	*/
+	void erase( const Key &inputKey )
+	{
+		boost::mutex::scoped_lock lock( the_mutex );
+		__map.erase( inputKey );
+	}
+	/**
+	* @brief
+	获得大小的函数。
+
+	* @param  无\n
+
+	* @return 无\n
+
+	* @note
+
+	* @warning
+
+	* @bug
+
+	*/
+	size_t size() const
+	{
+		boost::mutex::scoped_lock lock( the_mutex );
+		return __map.size();
+	}
+	/**
+	* @brief
+	清除map的函数。
+
+	* @param  无\n
+
+	* @return 无\n
+
+	* @note
+
+	* @warning
+
+	* @bug
+
+	*/
+	void clear()
+	{
+		boost::mutex::scoped_lock lock( the_mutex );
+		__map.clear();
+	}
+	/**
+	* @brief
+	拷贝map的函数。
+
+	* @param  无\n
+
+	* @return 无\n
+
+	* @note
+
+	* @warning
+
+	* @bug
+
+	*/
+	void copy( std::map<Key, T>& dest_map )
+	{
+		boost::mutex::scoped_lock lock( the_mutex );
+		dest_map = __map;
+	}
 };

+ 254 - 253
websocket/wsClient.cpp

@@ -1,253 +1,254 @@
-#include "wsClient.h"
-#include "constdef.h"
-#include <thread>
-#include <chrono>
-#include <boost/locale.hpp>
-
-
-namespace YA
-{
-	const int _LOGIN_SLEEP_TIME_      = 500;//登录前的等待时间(单位:毫秒)
-	const int _OPEN_SOCKET_WAIT_TIME_ = 100;//等待打开socket时间(单位:毫秒)
-
-	wsClient::wsClient()
-	{
-		__ID = 0;
-		_reset();
-	}
-
-	wsClient::~wsClient()
-	{
-
-	}
-
-	
-
-	void wsClient::_reset()
-	{
-		__Connected = false;
-		__SktOpened = false;
-		__Logined = false;
-	}
-
-	void wsClient::init( int ID, const std::string & uri, const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList )
-	{
-		__ID          = ID;
-		__uri         = uri;
-		__MsgFuncList = MsgFuncList;
-		__wsclient.set_reconnect_attempts( 0 );
-		using std::placeholders::_1;
-		using std::placeholders::_2;
-		using std::placeholders::_3;
-		using std::placeholders::_4;
-		sio::socket::ptr sock = __wsclient.socket();
-
-		__wsclient.set_open_listener( std::bind( &wsClient::_on_connected, this ) );
-		__wsclient.set_close_listener( std::bind( &wsClient::_on_close, this, std::placeholders::_1 ) );
-		__wsclient.set_reconnect_listener( std::bind( &wsClient::_on_reconnect, this, std::placeholders::_1, std::placeholders::_2 ) );
-		__wsclient.set_fail_listener( std::bind( &wsClient::_on_fail, this ) );
-		__wsclient.set_socket_open_listener( std::bind( &wsClient::_on_socket_opened, this ) );
-
-		sock->on( JSON_CMD_VALUE_CALL, sio::socket::event_listener_aux( std::bind( &wsClient::_OnCallMessage, this, _1, _2, _3, _4 ) ) );
-		sock->on( "code", sio::socket::event_listener_aux( std::bind( &wsClient::_OnLoginResponse, this, _1, _2, _3, _4 ) ) );
-	}
-
-	std::string wsClient::get_uri()
-	{
-		return __uri;
-	}
-
-	int wsClient::connect( int time_out )
-	{
-		if ( __uri.empty() )
-		{
-			__LastError = "Error, uri is empty.";
-			return -1;
-		}
-
-		__wsclient.connect( __uri );
-
-		std::cv_status status = std::cv_status::timeout;
-
-		int nRet = -1;
-		__lock.lock();
-		if ( !IsConnected() )
-		{
-			status = __cond.wait_for( __lock, std::chrono::seconds( time_out ) );
-
-			if ( std::cv_status::timeout == status )
-			{
-				__LastError = "Failed to connect server.";
-				nRet = -1;
-			}
-			else
-			{
-				nRet = 0;
-			}
-		}
-		else
-		{
-			nRet = 0;
-		}
-		__lock.unlock();
-
-		return nRet;
-	}
-
-	void wsClient::login()
-	{
-		char szError[512] = { 0 };
-
-		if ( !IsConnected() )
-		{
-			__LastError = "please connect server before login!";
-			return;
-		}
-
-		std::cv_status status = std::cv_status::timeout;
-		__lock.lock();
-		if ( !IsSktOpened() )
-		{
-			status = __cond.wait_for( __lock, std::chrono::milliseconds( _OPEN_SOCKET_WAIT_TIME_ ) );
-		}
-		__lock.unlock();
-
-		if ( !IsSktOpened() )
-		{
-			__LastError = "socket is not opened before login!";
-			return;
-		}
-
-		std::this_thread::sleep_for( std::chrono::milliseconds( _LOGIN_SLEEP_TIME_ ) );
-		
-		int nRet = 0;
-		YA::_JS_LOGIN_ Login;
-		Login.user_name = JSON_VALUE_USERNAME;
-		Login.user_password = JSON_VALUE_PASSWORD;
-
-		std::string strLogin = __jsBuilder.BuildLogin( Login );
-		strLogin += "\n";
-		sio::socket::ptr skt_ptr;
-		skt_ptr = __wsclient.socket();
-		skt_ptr->emit( JSON_CMD_VALUE_USER, strLogin, [&]( sio::message::list const& msglist )
-		{
-			sio::message::ptr msg_ptr = msglist[0];
-			nRet = ( int ) msg_ptr->get_map()["code"]->get_int();
-			if ( 0 == nRet )
-			{
-				__Logined = true;
-			}
-			else
-			{
-				__Logined = false;
-				sprintf( szError, "Login failed,code=%d", nRet );
-				__LastError = szError;
-			}
-		} );
-	}
-
-	void wsClient::_on_connected()
-	{
-		__lock.lock();
-		__cond.notify_all();
-		__Connected = true;
-		__lock.unlock();
-	}
-
-	void wsClient::send( const std::string & Cmd, const std::string & Data )
-	{
-		std::lock_guard<std::recursive_mutex> lock( __send_lock );
-
-		sio::socket::ptr skt_ptr;
-		skt_ptr = __wsclient.socket();
-		skt_ptr->emit( Cmd, Data );
-	}
-
-	void wsClient::_on_close( sio::client::close_reason const & reason )
-	{
-		_reset();
-	}
-
-	void wsClient::_on_reconnect( unsigned p1, unsigned p2 )
-	{
-		_reset();
-	}
-
-	void wsClient::_on_fail()
-	{
-		_reset();
-	}
-
-	void wsClient::_on_socket_opened()
-	{
-		__SktOpened = true;
-	}
-
-	void wsClient::_OnCallMessage( std::string const& name, sio::message::ptr const& data, bool need_ack, sio::message::list &ack_resp )
-	{
-		if ( data->get_flag() == sio::message::flag_object ) 
-		{
-			std::string cmd = data->get_map()[JSON_ROOT_KEY_CMD]->get_string();
-
-			std::map<std::string, MSG_HANDLE_FUNC_TYPE>::iterator mit_func;
-			mit_func = __MsgFuncList.find( cmd );
-			if ( mit_func != __MsgFuncList.end() )
-			{
-				mit_func->second( GetID(), name, data, need_ack, ack_resp );
-			}
-		}
-	}
-
-	void wsClient::_OnLoginResponse( std::string const & name, sio::message::ptr const & data, bool need_ack, sio::message::list & ack_resp )
-	{
-		char szError[512] = { 0 };
-		int res_code = ( int ) data->get_map()["code"]->get_int();
-		switch ( res_code )
-		{
-			case -1:
-			{
-				__Logined = false;
-				sprintf( szError, "Login failed,code=%d", res_code );
-				__LastError = szError;
-				break;
-			}
-			case 0:
-			{
-				__Logined = true;
-				break;
-			}
-			default:
-				break;
-		}
-	}
-
-	int wsClient::GetID()
-	{
-		return __ID;
-	}
-
-	bool wsClient::IsConnected()
-	{
-		return __Connected;
-	}
-
-	bool wsClient::IsSktOpened()
-	{
-		return __SktOpened;
-	}
-
-	bool wsClient::IsLogined()
-	{
-		return __Logined;
-	}
-
-	void wsClient::close()
-	{
-		__wsclient.sync_close();
-	}
-
-	std::string wsClient::GetLastError()
-	{
-		return __LastError;
-	}
-}
+#include "wsClient.h"
+#include "constdef.h"
+#include <thread>
+#include <chrono>
+#include <boost/locale.hpp>
+
+
+namespace YA
+{
+	const int _LOGIN_SLEEP_TIME_      = 500;//鐧诲綍鍓嶇殑绛夊緟鏃堕棿(鍗曚綅锛氭�绉�)
+	const int _OPEN_SOCKET_WAIT_TIME_ = 100;//绛夊緟鎵撳紑socket鏃堕棿(鍗曚綅锛氭�绉�)
+
+	wsClient::wsClient()
+	{
+		__ID = 0;
+		_reset();
+	}
+
+	wsClient::~wsClient()
+	{
+
+	}
+
+	
+
+	void wsClient::_reset()
+	{
+		__Connected = false;
+		__SktOpened = false;
+		__Logined = false;
+	}
+
+	void wsClient::init( int ID, const std::string & uri, const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList )
+	{
+		__ID          = ID;
+		__uri         = uri;
+		__MsgFuncList = MsgFuncList;
+		__wsclient.set_reconnect_attempts( 0 );
+		using std::placeholders::_1;
+		using std::placeholders::_2;
+		using std::placeholders::_3;
+		using std::placeholders::_4;
+		sio::socket::ptr sock = __wsclient.socket();
+
+		__wsclient.set_open_listener( std::bind( &wsClient::_on_connected, this ) );
+		__wsclient.set_close_listener( std::bind( &wsClient::_on_close, this, std::placeholders::_1 ) );
+		__wsclient.set_reconnect_listener( std::bind( &wsClient::_on_reconnect, this, std::placeholders::_1, std::placeholders::_2 ) );
+		__wsclient.set_fail_listener( std::bind( &wsClient::_on_fail, this ) );
+		__wsclient.set_socket_open_listener( std::bind( &wsClient::_on_socket_opened, this ) );
+
+		sock->on( JSON_CMD_VALUE_CALL, sio::socket::event_listener_aux( std::bind( &wsClient::_OnCallMessage, this, _1, _2, _3, _4 ) ) );
+		sock->on( "code", sio::socket::event_listener_aux( std::bind( &wsClient::_OnLoginResponse, this, _1, _2, _3, _4 ) ) );
+	}
+
+	std::string wsClient::get_uri()
+	{
+		return __uri;
+	}
+
+	int wsClient::connect( int time_out )
+	{
+		if ( __uri.empty() )
+		{
+			__LastError = "Error, uri is empty.";
+			return -1;
+		}
+
+		__wsclient.connect( __uri );
+
+		std::cv_status status = std::cv_status::timeout;
+
+		int nRet = -1;
+		__lock.lock();
+		if ( !IsConnected() )
+		{
+			status = __cond.wait_for( __lock, std::chrono::seconds( time_out ) );
+
+			if ( std::cv_status::timeout == status )
+			{
+				__LastError = "Failed to connect server.";
+				nRet = -1;
+			}
+			else
+			{
+				nRet = 0;
+			}
+		}
+		else
+		{
+			nRet = 0;
+		}
+		__lock.unlock();
+
+		return nRet;
+	}
+
+	void wsClient::login()
+	{
+		char szError[512] = { 0 };
+
+		if ( !IsConnected() )
+		{
+			__LastError = "please connect server before login!";
+			return;
+		}
+
+		//std::cv_status status = std::cv_status::timeout;
+		__lock.lock();
+		if ( !IsSktOpened() )
+		{
+		//	status = 
+			__cond.wait_for( __lock, std::chrono::milliseconds( _OPEN_SOCKET_WAIT_TIME_ ) );
+		}
+		__lock.unlock();
+
+		if ( !IsSktOpened() )
+		{
+			__LastError = "socket is not opened before login!";
+			return;
+		}
+
+		std::this_thread::sleep_for( std::chrono::milliseconds( _LOGIN_SLEEP_TIME_ ) );
+		
+		int nRet = 0;
+		YA::_JS_LOGIN_ Login;
+		Login.user_name = JSON_VALUE_USERNAME;
+		Login.user_password = JSON_VALUE_PASSWORD;
+
+		std::string strLogin = __jsBuilder.BuildLogin( Login );
+		strLogin += "\n";
+		sio::socket::ptr skt_ptr;
+		skt_ptr = __wsclient.socket();
+		skt_ptr->emit( JSON_CMD_VALUE_USER, strLogin, [&]( sio::message::list const& msglist )
+		{
+			sio::message::ptr msg_ptr = msglist[0];
+			nRet = ( int ) msg_ptr->get_map()["code"]->get_int();
+			if ( 0 == nRet )
+			{
+				__Logined = true;
+			}
+			else
+			{
+				__Logined = false;
+				sprintf( szError, "Login failed,code=%d", nRet );
+				__LastError = szError;
+			}
+		} );
+	}
+
+	void wsClient::_on_connected()
+	{
+		__lock.lock();
+		__cond.notify_all();
+		__Connected = true;
+		__lock.unlock();
+	}
+
+	void wsClient::send( const std::string & Cmd, const std::string & Data )
+	{
+		std::lock_guard<std::recursive_mutex> lock( __send_lock );
+
+		sio::socket::ptr skt_ptr;
+		skt_ptr = __wsclient.socket();
+		skt_ptr->emit( Cmd, Data );
+	}
+
+	void wsClient::_on_close( sio::client::close_reason const & reason )
+	{
+		_reset();
+	}
+
+	void wsClient::_on_reconnect( unsigned p1, unsigned p2 )
+	{
+		_reset();
+	}
+
+	void wsClient::_on_fail()
+	{
+		_reset();
+	}
+
+	void wsClient::_on_socket_opened()
+	{
+		__SktOpened = true;
+	}
+
+	void wsClient::_OnCallMessage( std::string const& name, sio::message::ptr const& data, bool need_ack, sio::message::list &ack_resp )
+	{
+		if ( data->get_flag() == sio::message::flag_object ) 
+		{
+			std::string cmd = data->get_map()[JSON_ROOT_KEY_CMD]->get_string();
+
+			std::map<std::string, MSG_HANDLE_FUNC_TYPE>::iterator mit_func;
+			mit_func = __MsgFuncList.find( cmd );
+			if ( mit_func != __MsgFuncList.end() )
+			{
+				mit_func->second( GetID(), name, data, need_ack, ack_resp );
+			}
+		}
+	}
+
+	void wsClient::_OnLoginResponse( std::string const & name, sio::message::ptr const & data, bool need_ack, sio::message::list & ack_resp )
+	{
+		char szError[512] = { 0 };
+		int res_code = ( int ) data->get_map()["code"]->get_int();
+		switch ( res_code )
+		{
+			case -1:
+			{
+				__Logined = false;
+				sprintf( szError, "Login failed,code=%d", res_code );
+				__LastError = szError;
+				break;
+			}
+			case 0:
+			{
+				__Logined = true;
+				break;
+			}
+			default:
+				break;
+		}
+	}
+
+	int wsClient::GetID()
+	{
+		return __ID;
+	}
+
+	bool wsClient::IsConnected()
+	{
+		return __Connected;
+	}
+
+	bool wsClient::IsSktOpened()
+	{
+		return __SktOpened;
+	}
+
+	bool wsClient::IsLogined()
+	{
+		return __Logined;
+	}
+
+	void wsClient::close()
+	{
+		__wsclient.sync_close();
+	}
+
+	std::string wsClient::GetLastError()
+	{
+		return __LastError;
+	}
+}

+ 380 - 380
websocket/wsClient.h

@@ -1,381 +1,381 @@
-/**
-* @brief
-websocket客户端类
-
-* @version
-  V 1.0.0
-
-* @author
-  王益俊
-
-* @date
-  创建时间:  2018-08-14\n
-
-* @note
-  2018-08-14  创建类。\n
-
-* @warning
-
-* @bug
-  
-*/
-
-#pragma once
-
-#include <string>
-#include <mutex>
-#include <condition_variable>
-#include <map>
-
-#include <rapidjson/writer.h>
-#include <rapidjson/stringbuffer.h>
-#include <rapidjson/prettywriter.h>
-
-#include <boost/function.hpp>
-#include <boost/bind.hpp>
-
-#include "sio_client.h"
-#include "jsonBuilder.h"
-
-namespace YA
-{
-	//消息处理函数类型
-	typedef boost::function<void( int, std::string const&, sio::message::ptr const&, bool, sio::message::list & )> MSG_HANDLE_FUNC_TYPE;
-
-	class wsClient
-	{
-	private:
-		sio::client __wsclient;//websocket客户端
-		int __ID;//唯一标识
-		std::string __uri;//连接字符串
-		bool __Connected;//是否连接上服务器端
-		bool __SktOpened;//Socket是否已打开
-		bool __Logined;//是否已登录成功
-		std::condition_variable_any __cond;//条件变量
-		std::mutex __lock;//锁(配合__cond)
-		std::string __LastError;//最新错误
-		std::map<std::string, MSG_HANDLE_FUNC_TYPE> __MsgFuncList;//消息处理函数列表(key是命令,value是处理函数)
-		std::recursive_mutex __send_lock;//发送锁
-		jsonBuilder __jsBuilder;//json构造器
-	protected:
-		/**
-		* @brief
-		重置状态函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void _reset();
-		/**
-		* @brief
-		连接成功回调函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void _on_connected();
-		/**
-		* @brief
-		连接关闭回调函数。
-
-		* @param  [in] sio::client::close_reason const& reason 关闭的原因\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void _on_close( sio::client::close_reason const& reason );
-		/**
-		* @brief
-		重连回调函数。
-
-		* @param  [in] unsigned p1 ???\n
-		* @param  [in] unsigned p2 ???\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void _on_reconnect( unsigned p1, unsigned p2 );
-		/**
-		* @brief
-		失败回调函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void _on_fail();
-		/**
-		* @brief
-		socket打开成功回调函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void _on_socket_opened();
-		/**
-		* @brief
-		收到服务器端CALL命令回调函数。
-
-		* @param  [in] std::string const& name  触发的名字\n
-		* @param  [in] sio::message::ptr const& data  收到的消息数据\n
-		* @param  [in] bool need_ack  是否需要应答\n
-		* @param  [in] sio::message::list &ack_resp  应答消息数据\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void _OnCallMessage( std::string const& name, sio::message::ptr const& data, bool need_ack, sio::message::list &ack_resp );
-		/**
-		* @brief
-		收到服务器端登录应答命令回调函数。
-
-		* @param  [in] std::string const& name  触发的名字\n
-		* @param  [in] sio::message::ptr const& data  收到的消息数据\n
-		* @param  [in] bool need_ack  是否需要应答\n
-		* @param  [in] sio::message::list &ack_resp  应答消息数据\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void _OnLoginResponse( std::string const& name, sio::message::ptr const& data, bool need_ack, sio::message::list &ack_resp );
-	public:
-		wsClient();
-		~wsClient();
-		/**
-		* @brief
-		初始化函数。
-
-		* @param  [in] int ID  当前客户端的唯一标识\n
-		* @param  [in] const std::string & uri  连接串\n
-		* @param  [in] const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList  消息处理函数\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void init( int ID, const std::string & uri, const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList );
-		/**
-		* @brief
-		获得连接字符串函数。
-
-		* @param  无\n
-
-		* @return 获得的连接字符串\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		std::string get_uri();
-		/**
-		* @brief
-		;连接函数。
-
-		* @param  [in] int time_out  超时(单位:秒),默认是3秒\n
-
-		* @return 连接服务器是否成功\n
-		* @retval  0  成功\n
-        * @retval  -1  失败\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		int connect( int time_out = 3 );
-		/**
-		* @brief
-		;登录函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void login();
-		/**
-		* @brief
-		发送数据函数。
-
-		* @param  [in] const std::string & Cmd  要发送的命令\n
-		* @param  [in] const std::string& Data  要发送的数据\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void send( const std::string & Cmd, const std::string & Data );
-		/**
-		* @brief
-		获得ID函数。
-
-		* @param  无\n
-
-		* @return 获得的ID\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		int GetID();
-		/**
-		* @brief
-		获得是否已连接服务器端函数。
-
-		* @param  无\n
-
-		* @return 是否已连接服务器\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		bool IsConnected();
-		/**
-		* @brief
-		获得Socket是否已打开函数。
-
-		* @param  无\n
-
-		* @return Socket是否已打开\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		bool IsSktOpened();
-		/**
-		* @brief
-		获得是否已登录成功函数。
-
-		* @param  无\n
-
-		* @return 是否已登录成功\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		bool IsLogined();
-		/**
-		* @brief
-		关闭函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void close();
-		/**
-		* @brief
-		获得最新错误函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		std::string GetLastError();
-	};
+/**
+* @brief
+websocket瀹㈡埛绔�被
+
+* @version
+  V 1.0.0
+
+* @author
+  鐜嬬泭淇�
+
+* @date
+  鍒涘缓鏃堕棿:  2018-08-14\n
+
+* @note
+  2018-08-14  鍒涘缓绫汇€俓n
+
+* @warning
+
+* @bug
+  
+*/
+
+#pragma once
+
+#include <string>
+#include <mutex>
+#include <condition_variable>
+#include <map>
+
+#include <rapidjson/writer.h>
+#include <rapidjson/stringbuffer.h>
+#include <rapidjson/prettywriter.h>
+
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+
+#include "sio_client.h"
+#include "jsonBuilder.h"
+
+namespace YA
+{
+	//娑堟伅澶勭悊鍑芥暟绫诲瀷
+	typedef boost::function<void( int, std::string const&, sio::message::ptr const&, bool, sio::message::list & )> MSG_HANDLE_FUNC_TYPE;
+
+	class wsClient
+	{
+	private:
+		sio::client __wsclient;//websocket瀹㈡埛绔�
+		int __ID;//鍞�竴鏍囪瘑
+		std::string __uri;//杩炴帴瀛楃�涓�
+		bool __Connected;//鏄�惁杩炴帴涓婃湇鍔″櫒绔�
+		bool __SktOpened;//Socket鏄�惁宸叉墦寮€
+		bool __Logined;//鏄�惁宸茬櫥褰曟垚鍔�
+		std::condition_variable_any __cond;//鏉′欢鍙橀噺
+		std::mutex __lock;//閿�(閰嶅悎__cond)
+		std::string __LastError;//鏈€鏂伴敊璇�
+		std::map<std::string, MSG_HANDLE_FUNC_TYPE> __MsgFuncList;//娑堟伅澶勭悊鍑芥暟鍒楄〃(key鏄�懡浠�,value鏄��鐞嗗嚱鏁�)
+		std::recursive_mutex __send_lock;//鍙戦€侀攣
+		jsonBuilder __jsBuilder;//json鏋勯€犲櫒
+	protected:
+		/**
+		* @brief
+		閲嶇疆鐘舵€佸嚱鏁般€�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void _reset();
+		/**
+		* @brief
+		杩炴帴鎴愬姛鍥炶皟鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void _on_connected();
+		/**
+		* @brief
+		杩炴帴鍏抽棴鍥炶皟鍑芥暟銆�
+
+		* @param  [in] sio::client::close_reason const& reason 鍏抽棴鐨勫師鍥燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void _on_close( sio::client::close_reason const& reason );
+		/**
+		* @brief
+		閲嶈繛鍥炶皟鍑芥暟銆�
+
+		* @param  [in] unsigned p1 ???\n
+		* @param  [in] unsigned p2 ???\n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void _on_reconnect( unsigned p1, unsigned p2 );
+		/**
+		* @brief
+		澶辫触鍥炶皟鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void _on_fail();
+		/**
+		* @brief
+		socket鎵撳紑鎴愬姛鍥炶皟鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void _on_socket_opened();
+		/**
+		* @brief
+		鏀跺埌鏈嶅姟鍣ㄧ�CALL鍛戒护鍥炶皟鍑芥暟銆�
+
+		* @param  [in] std::string const& name  瑙﹀彂鐨勫悕瀛梊n
+		* @param  [in] sio::message::ptr const& data  鏀跺埌鐨勬秷鎭�暟鎹甛n
+		* @param  [in] bool need_ack  鏄�惁闇€瑕佸簲绛擻n
+		* @param  [in] sio::message::list &ack_resp  搴旂瓟娑堟伅鏁版嵁\n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void _OnCallMessage( std::string const& name, sio::message::ptr const& data, bool need_ack, sio::message::list &ack_resp );
+		/**
+		* @brief
+		鏀跺埌鏈嶅姟鍣ㄧ�鐧诲綍搴旂瓟鍛戒护鍥炶皟鍑芥暟銆�
+
+		* @param  [in] std::string const& name  瑙﹀彂鐨勫悕瀛梊n
+		* @param  [in] sio::message::ptr const& data  鏀跺埌鐨勬秷鎭�暟鎹甛n
+		* @param  [in] bool need_ack  鏄�惁闇€瑕佸簲绛擻n
+		* @param  [in] sio::message::list &ack_resp  搴旂瓟娑堟伅鏁版嵁\n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void _OnLoginResponse( std::string const& name, sio::message::ptr const& data, bool need_ack, sio::message::list &ack_resp );
+	public:
+		wsClient();
+		~wsClient();
+		/**
+		* @brief
+		鍒濆�鍖栧嚱鏁般€�
+
+		* @param  [in] int ID  褰撳墠瀹㈡埛绔�殑鍞�竴鏍囪瘑\n
+		* @param  [in] const std::string & uri  杩炴帴涓瞈n
+		* @param  [in] const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList  娑堟伅澶勭悊鍑芥暟\n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void init( int ID, const std::string & uri, const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList );
+		/**
+		* @brief
+		鑾峰緱杩炴帴瀛楃�涓插嚱鏁般€�
+
+		* @param  鏃燶n
+
+		* @return 鑾峰緱鐨勮繛鎺ュ瓧绗︿覆\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		std::string get_uri();
+		/**
+		* @brief
+		锛涜繛鎺ュ嚱鏁般€�
+
+		* @param  [in] int time_out  瓒呮椂(鍗曚綅锛氱�),榛樿�鏄�3绉抃n
+
+		* @return 杩炴帴鏈嶅姟鍣ㄦ槸鍚︽垚鍔焅n
+		* @retval  0  鎴愬姛\n
+        * @retval  -1  澶辫触\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		int connect( int time_out = 3 );
+		/**
+		* @brief
+		锛涚櫥褰曞嚱鏁般€�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void login();
+		/**
+		* @brief
+		鍙戦€佹暟鎹�嚱鏁般€�
+
+		* @param  [in] const std::string & Cmd  瑕佸彂閫佺殑鍛戒护\n
+		* @param  [in] const std::string& Data  瑕佸彂閫佺殑鏁版嵁\n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void send( const std::string & Cmd, const std::string & Data );
+		/**
+		* @brief
+		鑾峰緱ID鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return 鑾峰緱鐨処D\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		int GetID();
+		/**
+		* @brief
+		鑾峰緱鏄�惁宸茶繛鎺ユ湇鍔″櫒绔�嚱鏁般€�
+
+		* @param  鏃燶n
+
+		* @return 鏄�惁宸茶繛鎺ユ湇鍔″櫒\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		bool IsConnected();
+		/**
+		* @brief
+		鑾峰緱Socket鏄�惁宸叉墦寮€鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return Socket鏄�惁宸叉墦寮€\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		bool IsSktOpened();
+		/**
+		* @brief
+		鑾峰緱鏄�惁宸茬櫥褰曟垚鍔熷嚱鏁般€�
+
+		* @param  鏃燶n
+
+		* @return 鏄�惁宸茬櫥褰曟垚鍔焅n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		bool IsLogined();
+		/**
+		* @brief
+		鍏抽棴鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void close();
+		/**
+		* @brief
+		鑾峰緱鏈€鏂伴敊璇�嚱鏁般€�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		std::string GetLastError();
+	};
 }

+ 156 - 141
websocket/wsClientMgr.cpp

@@ -1,142 +1,157 @@
-#include "wsClientMgr.h"
-
-namespace YA
-{
-	wsClientMgr::wsClientMgr()
-	{
-
-	}
-
-	wsClientMgr::~wsClientMgr()
-	{
-
-	}
-
-	void wsClientMgr::Build( const std::vector<std::string> uri_list, const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList )
-	{
-		std::lock_guard<std::recursive_mutex> lock( __lock );
-
-		std::vector<std::string>::const_iterator vit_uri;
-
-		int ID = 1;
-		int Index = 0;
-		for ( vit_uri = uri_list.begin(); vit_uri != uri_list.end(); vit_uri++ )
-		{
-			std::shared_ptr<wsClient> pClient = std::make_shared<wsClient>();
-			pClient->init( ID, *vit_uri, MsgFuncList );
-			__wsClientList.push_back( pClient );
-			__uriIndexList.insert( std::make_pair( *vit_uri, Index ) );
-			ID++;
-			Index++;
-		}
-	}
-
-	int wsClientMgr::connect( int time_out )
-	{
-		std::lock_guard<std::recursive_mutex> lock( __lock );
-
-		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
-		{
-			if ( __wsClientList[i]->connect( time_out ) != 0 )
-			{
-				char szError[1024] = { 0 };
-				sprintf( szError, "[%d] websocket client failed to connect: %s.", __wsClientList[i]->GetID(), __wsClientList[i]->get_uri().c_str() );
-				__LastError = szError;
-				return -1;
-			}
-		}
-
-		return 0;
-	}
-
-	void wsClientMgr::login()
-	{
-		std::lock_guard<std::recursive_mutex> lock( __lock );
-
-		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
-		{
-			__wsClientList[i]->login();
-		}
-	}
-
-	void wsClientMgr::send( const std::string & Cmd, const std::string & Data )
-	{
-		std::lock_guard<std::recursive_mutex> lock( __lock );
-
-		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
-		{
-			__wsClientList[i]->send( Cmd, Data );
-		}
-	}
-
-	std::shared_ptr<wsClient> wsClientMgr::GetClientByURI( const std::string & URI )
-	{
-		std::lock_guard<std::recursive_mutex> lock( __lock );
-
-		std::shared_ptr<wsClient> pClient;
-
-		std::map<std::string, int>::iterator mit_uri;
-		mit_uri = __uriIndexList.find( URI );
-		if ( mit_uri != __uriIndexList.end() )
-		{
-			pClient = __wsClientList[mit_uri->second];
-		}
-
-		return pClient;
-	}
-
-	void wsClientMgr::close()
-	{
-		std::lock_guard<std::recursive_mutex> lock( __lock );
-
-		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
-		{
-			__wsClientList[i]->close();
-		}
-	}
-
-	bool wsClientMgr::IsConnected()
-	{
-		std::lock_guard<std::recursive_mutex> lock( __lock );
-
-		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
-		{
-			if ( !__wsClientList[i]->IsConnected() )
-			{
-				return false;
-			}
-		}
-
-		return true;
-	}
-
-	bool wsClientMgr::IsLogined()
-	{
-		std::lock_guard<std::recursive_mutex> lock( __lock );
-
-		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
-		{
-			if ( !__wsClientList[i]->IsLogined() )
-			{
-				return false;
-			}
-		}
-
-		return true;
-	}
-
-	bool wsClientMgr::IsSktOpened()
-	{
-		std::lock_guard<std::recursive_mutex> lock( __lock );
-
-		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
-		{
-			if ( !__wsClientList[i]->IsSktOpened() )
-			{
-				return false;
-			}
-		}
-
-		return true;
-	}
+#include "wsClientMgr.h"
+
+namespace YA
+{
+	wsClientMgr::wsClientMgr()
+	{
+
+	}
+
+	wsClientMgr::~wsClientMgr()
+	{
+
+	}
+
+	void wsClientMgr::Build( const std::vector<std::string> uri_list, const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList )
+	{
+		std::lock_guard<std::recursive_mutex> lock( __lock );
+
+		std::vector<std::string>::const_iterator vit_uri;
+
+		int ID = 1;
+		int Index = 0;
+		for ( vit_uri = uri_list.begin(); vit_uri != uri_list.end(); vit_uri++ )
+		{
+			std::shared_ptr<wsClient> pClient = std::make_shared<wsClient>();
+			pClient->init( ID, *vit_uri, MsgFuncList );
+			__wsClientList.push_back( pClient );
+			__uriIndexList.insert( std::make_pair( *vit_uri, Index ) );
+			ID++;
+			Index++;
+		}
+	}
+
+	int wsClientMgr::connect( int time_out )
+	{
+		std::lock_guard<std::recursive_mutex> lock( __lock );
+
+		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
+		{
+			if ( __wsClientList[i]->connect( time_out ) != 0 )
+			{
+				char szError[1024] = { 0 };
+				sprintf( szError, "[%d] websocket client failed to connect: %s.", __wsClientList[i]->GetID(), __wsClientList[i]->get_uri().c_str() );
+				__LastError = szError;
+				return -1;
+			}
+		}
+
+		return 0;
+	}
+
+	void wsClientMgr::login()
+	{
+		std::lock_guard<std::recursive_mutex> lock( __lock );
+
+		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
+		{
+			__wsClientList[i]->login();
+		}
+	}
+
+	void wsClientMgr::send( const std::string & Cmd, const std::string & Data )
+	{
+		std::lock_guard<std::recursive_mutex> lock( __lock );
+
+		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
+		{
+			__wsClientList[i]->send( Cmd, Data );
+		}
+	}
+
+	std::shared_ptr<wsClient> wsClientMgr::GetClientByURI( const std::string & URI )
+	{
+		std::lock_guard<std::recursive_mutex> lock( __lock );
+
+		std::shared_ptr<wsClient> pClient;
+
+		std::map<std::string, int>::iterator mit_uri;
+		mit_uri = __uriIndexList.find( URI );
+		if ( mit_uri != __uriIndexList.end() )
+		{
+			pClient = __wsClientList[mit_uri->second];
+		}
+
+		return pClient;
+	}
+
+	void wsClientMgr::close()
+	{
+		std::lock_guard<std::recursive_mutex> lock( __lock );
+
+		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
+		{
+			__wsClientList[i]->close();
+		}
+	}
+
+	bool wsClientMgr::IsConnected()
+	{
+		std::lock_guard<std::recursive_mutex> lock( __lock );
+
+		if ( __wsClientList.empty() )
+		{
+			return false;
+		}
+
+		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
+		{
+			if ( !__wsClientList[i]->IsConnected() )
+			{
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	bool wsClientMgr::IsLogined()
+	{
+		std::lock_guard<std::recursive_mutex> lock( __lock );
+
+		if ( __wsClientList.empty() )
+		{
+			return false;
+		}
+
+		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
+		{
+			if ( !__wsClientList[i]->IsLogined() )
+			{
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	bool wsClientMgr::IsSktOpened()
+	{
+		std::lock_guard<std::recursive_mutex> lock( __lock );
+
+		if ( __wsClientList.empty() )
+		{
+			return false;
+		}
+
+		for ( size_t i = 0; i < __wsClientList.size() ; i++ )
+		{
+			if ( !__wsClientList[i]->IsSktOpened() )
+			{
+				return false;
+			}
+		}
+
+		return true;
+	}
 }

+ 232 - 232
websocket/wsClientMgr.h

@@ -1,232 +1,232 @@
-/**
-* @brief
-websocket客户端管理器类
-
-* @version
-  V 1.0.0
-
-* @author
-  王益俊
-
-* @date
-  创建时间:  2018-08-17\n
-
-* @note
-  2018-08-17  创建类。\n
-
-* @warning
-
-* @bug
-  
-*/
-
-#pragma once
-
-#include <vector>
-#include <string>
-#include <map>
-
-#include "wsClient.h"
-#include <boost/serialization/singleton.hpp>
-
-namespace YA
-{
-	class wsClientMgr
-	{
-	private:
-		std::vector<std::shared_ptr<wsClient>> __wsClientList;//ws客户端列表
-		std::map<std::string,int>  __uriIndexList;//uri和客户端下标对应表
-		std::string __LastError;//最新错误
-		std::recursive_mutex __lock;//
-	public:
-		wsClientMgr();
-		~wsClientMgr();
-		/**
-		* @brief
-		  重载[]运算符。
-
-		* @param  [in] int index  下标\n
-
-		* @return 下标对应的客户端\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		std::shared_ptr<wsClient> operator[]( int index )
-		{
-			std::lock_guard<std::recursive_mutex> lock( __lock );
-			std::shared_ptr<wsClient> pClient;
-
-			if ( index < 0 )
-			{
-				return pClient;
-			}
-
-			if ( index <(int) __wsClientList.size() )
-			{
-				pClient = __wsClientList[index];
-			}
-
-			return pClient;
-		}
-		/**
-		* @brief
-		;构造函数。
-
-		* @param  [in] const std::vector<std::string> uri_list  服务器uri列表\n
-		* @param  [in] const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList  处理函数列表\n
-
-		* @return 连接服务器是否成功\n
-		* @retval  0  成功\n
-        * @retval  -1  失败\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void Build( const std::vector<std::string> uri_list, const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList );
-		/**
-		* @brief
-		;连接函数。
-
-		* @param  [in] int time_out  超时(单位:秒),默认是3秒\n
-
-		* @return 连接服务器是否成功\n
-		* @retval  0  成功\n
-        * @retval  -1  失败\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		int connect( int time_out = 3 );
-		/**
-		* @brief
-		;登录函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void login();
-		/**
-		* @brief
-		发送数据函数。
-
-		* @param  [in] const std::string & Cmd  要发送的命令\n
-		* @param  [in] const std::string& Data  要发送的数据\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void send( const std::string & Cmd, const std::string & Data );
-		/**
-		* @brief
-		根据URI(连接串)获得对应的客户端函数。
-
-		* @param  [in] const std::string& URI  \n
-
-		* @return 获得的客户端\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		std::shared_ptr<wsClient> GetClientByURI( const std::string& URI );
-		/**
-		* @brief
-		关闭函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void close();
-		/**
-		* @brief
-		获得是否已连接服务器端函数。
-
-		* @param  无\n
-
-		* @return 是否已连接服务器\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		bool IsConnected();
-		/**
-		* @brief
-		获得是否已登录成功函数。
-
-		* @param  无\n
-
-		* @return 是否已登录成功\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		bool IsLogined();
-		/**
-		* @brief
-		获得Socket是否已打开函数。
-
-		* @param  无\n
-
-		* @return Socket是否已打开\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		bool IsSktOpened();
-	};
-}
-
-//单件相关定义
-typedef boost::serialization::singleton<YA::wsClientMgr> singleton_wsClientMgr;
-#define swsClientMgr singleton_wsClientMgr::get_mutable_instance()
-#define swsClientMgr_const singleton_wsClientMgr::get_const_instance()
+/**
+* @brief
+websocket瀹㈡埛绔��鐞嗗櫒绫�
+
+* @version
+  V 1.0.0
+
+* @author
+  鐜嬬泭淇�
+
+* @date
+  鍒涘缓鏃堕棿:  2018-08-17\n
+
+* @note
+  2018-08-17  鍒涘缓绫汇€俓n
+
+* @warning
+
+* @bug
+  
+*/
+
+#pragma once
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include "wsClient.h"
+#include <boost/serialization/singleton.hpp>
+
+namespace YA
+{
+	class wsClientMgr
+	{
+	private:
+		std::vector<std::shared_ptr<wsClient>> __wsClientList;//ws瀹㈡埛绔�垪琛�
+		std::map<std::string,int>  __uriIndexList;//uri鍜屽�鎴风�涓嬫爣瀵瑰簲琛�
+		std::string __LastError;//鏈€鏂伴敊璇�
+		std::recursive_mutex __lock;//閿�
+	public:
+		wsClientMgr();
+		~wsClientMgr();
+		/**
+		* @brief
+		  閲嶈浇[]杩愮畻绗︺€�
+
+		* @param  [in] int index  涓嬫爣\n
+
+		* @return 涓嬫爣瀵瑰簲鐨勫�鎴风�\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		std::shared_ptr<wsClient> operator[]( int index )
+		{
+			std::lock_guard<std::recursive_mutex> lock( __lock );
+			std::shared_ptr<wsClient> pClient;
+
+			if ( index < 0 )
+			{
+				return pClient;
+			}
+
+			if ( index < (int)__wsClientList.size() )
+			{
+				pClient = __wsClientList[index];
+			}
+
+			return pClient;
+		}
+		/**
+		* @brief
+		锛涙瀯閫犲嚱鏁般€�
+
+		* @param  [in] const std::vector<std::string> uri_list  鏈嶅姟鍣╱ri鍒楄〃\n
+		* @param  [in] const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList  澶勭悊鍑芥暟鍒楄〃\n
+
+		* @return 杩炴帴鏈嶅姟鍣ㄦ槸鍚︽垚鍔焅n
+		* @retval  0  鎴愬姛\n
+        * @retval  -1  澶辫触\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void Build( const std::vector<std::string> uri_list, const std::map<std::string, MSG_HANDLE_FUNC_TYPE>& MsgFuncList );
+		/**
+		* @brief
+		锛涜繛鎺ュ嚱鏁般€�
+
+		* @param  [in] int time_out  瓒呮椂(鍗曚綅锛氱�),榛樿�鏄�3绉抃n
+
+		* @return 杩炴帴鏈嶅姟鍣ㄦ槸鍚︽垚鍔焅n
+		* @retval  0  鎴愬姛\n
+        * @retval  -1  澶辫触\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		int connect( int time_out = 3 );
+		/**
+		* @brief
+		锛涚櫥褰曞嚱鏁般€�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void login();
+		/**
+		* @brief
+		鍙戦€佹暟鎹�嚱鏁般€�
+
+		* @param  [in] const std::string & Cmd  瑕佸彂閫佺殑鍛戒护\n
+		* @param  [in] const std::string& Data  瑕佸彂閫佺殑鏁版嵁\n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void send( const std::string & Cmd, const std::string & Data );
+		/**
+		* @brief
+		鏍规嵁URI(杩炴帴涓�)鑾峰緱瀵瑰簲鐨勫�鎴风�鍑芥暟銆�
+
+		* @param  [in] const std::string& URI  \n
+
+		* @return 鑾峰緱鐨勫�鎴风�\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		std::shared_ptr<wsClient> GetClientByURI( const std::string& URI );
+		/**
+		* @brief
+		鍏抽棴鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void close();
+		/**
+		* @brief
+		鑾峰緱鏄�惁宸茶繛鎺ユ湇鍔″櫒绔�嚱鏁般€�
+
+		* @param  鏃燶n
+
+		* @return 鏄�惁宸茶繛鎺ユ湇鍔″櫒\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		bool IsConnected();
+		/**
+		* @brief
+		鑾峰緱鏄�惁宸茬櫥褰曟垚鍔熷嚱鏁般€�
+
+		* @param  鏃燶n
+
+		* @return 鏄�惁宸茬櫥褰曟垚鍔焅n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		bool IsLogined();
+		/**
+		* @brief
+		鑾峰緱Socket鏄�惁宸叉墦寮€鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return Socket鏄�惁宸叉墦寮€\n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		bool IsSktOpened();
+	};
+}
+
+//鍗曚欢鐩稿叧瀹氫箟
+typedef boost::serialization::singleton<YA::wsClientMgr> singleton_wsClientMgr;
+#define swsClientMgr singleton_wsClientMgr::get_mutable_instance()
+#define swsClientMgr_const singleton_wsClientMgr::get_const_instance()

+ 115 - 81
websocket/wsTimerThread.cpp

@@ -1,81 +1,115 @@
-#include "wsTimerThread.h"
-#include <iostream>
-
-namespace YA
-{
-	wsTimerThread::wsTimerThread()
-	{
-		__Reset();
-	}
-
-
-	wsTimerThread::~wsTimerThread()
-	{
-		Stop();
-	}
-
-	void wsTimerThread::Start()
-	{
-		__Running = true;
-		__Thread.reset( new boost::thread( boost::bind( &wsTimerThread::_ThreadFunc, this, this ) ) );
-		__Thread->detach();
-	}
-
-	void wsTimerThread::Stop()
-	{
-		__Enable = false;
-
-		boost::unique_lock<boost::mutex> lock( __ExitMutex );
-		__ExitCond.wait( lock );
-
-		__Running = false;
-	}
-
-	void wsTimerThread::__Reset()
-	{
-		__Enable  = true;
-		__Running = false;
-	}
-
-	void wsTimerThread::__ChkConfig()
-	{
-		if ( __Config.SendInterval < MIN_SEND_INTERVAL )
-		{
-			__Config.SendInterval = MIN_SEND_INTERVAL;
-		}
-	}
-	void wsTimerThread::_ThreadFunc( wsTimerThread * pOwner )
-	{
-		while ( pOwner->__Enable )
-		{
-			//do something...
-			printf("doing ....timer thread .......\n");
-			boost::this_thread::sleep( boost::posix_time::millisec( 1000 ) );
-		}
-
-		pOwner->__ExitCond.notify_one();
-	}
-
-
-
-	void wsTimerThread::Init( const _THREAD_CONFIG_ & Config )
-	{
-		__Config = Config;
-		__ChkConfig();
-	}
-
-	void wsTimerThread::add_card_pos( const _CARD_POS_ & pos )
-	{
-		__CardPosList.insert( pos.ID, pos );
-	}
-
-	void wsTimerThread::upt_card_pos( const _CARD_POS_ & pos )
-	{
-		__CardPosList.update( pos.ID, pos );
-	}
-
-	void wsTimerThread::del_card_pos( const _CARD_POS_ & pos )
-	{
-		__CardPosList.erase( pos.ID );
-	}
-}
+#include "wsTimerThread.h"
+#include <iostream>
+
+#include "wsClientMgr.h"
+#include "constdef.h"
+
+namespace YA
+{
+	wsTimerThread::wsTimerThread()
+	{
+		__Reset();
+
+		__LastSendTime = { 0 };
+		__LastSendTime.tm_year = 1970 - 1900;
+		__LastSendTime.tm_mon  = 1;
+		__LastSendTime.tm_mday = 1;
+	}
+
+	wsTimerThread::~wsTimerThread()
+	{
+		Stop();
+	}
+
+	void wsTimerThread::Start()
+	{
+		__Running = true;
+		__Thread.reset( new boost::thread( boost::bind( &wsTimerThread::_ThreadFunc, this, this ) ) );
+		__Thread->detach();
+	}
+
+	void wsTimerThread::Stop()
+	{
+		std::cout << "::Stop() begin" << std::endl;
+
+		__Enable = false;
+
+		if ( __Running )
+		{
+			boost::unique_lock<boost::mutex> lock( __ExitMutex );
+			__ExitCond.wait( lock );
+		}
+
+		__Reset();
+
+		std::cout << "::Stop() end" << std::endl;
+	}
+
+	void wsTimerThread::__Reset()
+	{
+		__Enable  = true;
+		__Running = false;
+	}
+
+	void wsTimerThread::__ChkConfig()
+	{
+		if ( __Config.SendInterval < MIN_SEND_INTERVAL )
+		{
+			__Config.SendInterval = MIN_SEND_INTERVAL;
+		}
+	}
+
+	void wsTimerThread::__SendCardPos()
+	{
+		std::map<int, _CARD_POS_> CardPosList;
+		__CardPosList.copy( CardPosList );
+		std::string jsCardPos = __jsBuilder.BuildCardPos( CardPosList );
+		swsClientMgr.send( JSON_CMD_VALUE_PUSH, jsCardPos );
+	}
+
+	void wsTimerThread::_ThreadFunc( wsTimerThread * pOwner )
+	{
+		while ( pOwner->__Enable )
+		{
+			std::tm *Now;
+			std::time_t t;
+			t = time( 0 );
+			Now = localtime( &t );
+			int seconds = (int)std::difftime( mktime( Now ), mktime( &__LastSendTime ) );
+
+			if ( seconds >= pOwner->__Config.SendInterval )
+			{
+				pOwner->__SendCardPos();
+				__LastSendTime = *Now;
+			}
+
+			boost::this_thread::sleep( boost::posix_time::millisec( 1 ) );
+		}
+
+		pOwner->__ExitCond.notify_one();
+	}
+
+	void wsTimerThread::Init( const _THREAD_CONFIG_ & Config )
+	{
+		__Config = Config;
+		__ChkConfig();
+	}
+
+	void wsTimerThread::upt_card_pos( const _CARD_POS_ & pos )
+	{
+		//如果已存在就更新,否则插入
+		if ( __CardPosList.seek( pos.ID ) )
+		{
+			__CardPosList.update( pos.ID, pos );
+		}
+		else
+		{
+			__CardPosList.insert( pos.ID, pos );
+		}
+	}
+
+	void wsTimerThread::del_card_pos( const _CARD_POS_ & pos )
+	{
+		__CardPosList.erase( pos.ID );
+	}
+}

+ 207 - 202
websocket/wsTimerThread.h

@@ -1,202 +1,207 @@
-/**
-* @brief
-websocket定时发送线程类
-
-* @version
-  V 1.0.0
-
-* @author
-  王益俊
-
-* @date
-  创建时间:  2018-08-17\n
-
-* @note
-  2018-08-17  创建类。\n
-
-* @warning
-
-* @bug
-  
-*/
-
-#pragma once
-
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
-#include <boost/atomic.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/thread/condition.hpp>
-#include <boost/serialization/singleton.hpp>
-
-#include "thread_safe_map.h"
-#include "ws_common.h"
-
-namespace YA
-{
-	class wsTimerThread
-	{
-	private:
-		boost::shared_ptr<boost::thread> __Thread;//线程
-		boost::atomic<bool> __Enable;//线程是否继续运行的标志
-		boost::atomic<bool> __Running;//线程是否正在运行的标志
-		boost::condition_variable_any __ExitCond;//条件变量
-		boost::mutex __ExitMutex;//锁(配合__ExitCond)
-		_THREAD_CONFIG_ __Config;//线程配置
-		thread_safe_map<int, _CARD_POS_> __CardPosList;//卡位置列表
-	private:
-		/**
-		* @brief
-		  重置函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void __Reset();
-		/**
-		* @brief
-		  检查线程配置是否合法函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void __ChkConfig();
-	protected:
-		/**
-		* @brief
-		  线程函数。
-
-		* @param  [in] wsTimerThread* pOwner  线程所属者\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void _ThreadFunc( wsTimerThread* pOwner );
-	public:
-		wsTimerThread();
-		~wsTimerThread();
-		/**
-		* @brief
-		  启动线程函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void Start();
-		/**
-		* @brief
-		  停止线程函数。
-
-		* @param  无\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void Stop();
-		/**
-		* @brief
-		  初始化函数。
-
-		* @param  [in] const _THREAD_CONFIG_& Config  线程配置\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void Init( const _THREAD_CONFIG_& Config );
-		/**
-		* @brief
-		  添加卡位置函数。
-
-		* @param  [in] const _CARD_POS_& pos  卡位置结构体\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void add_card_pos( const _CARD_POS_& pos );
-		/**
-		* @brief
-		  更新卡位置函数。
-
-		* @param  [in] const _CARD_POS_& pos  卡位置结构体\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void upt_card_pos( const _CARD_POS_& pos );
-		/**
-		* @brief
-		  删除卡位置函数。
-
-		* @param  [in] const _CARD_POS_& pos  卡位置结构体\n
-
-		* @return 无\n
-
-		* @note
-
-		* @warning
-
-		* @bug
-
-		*/
-		void del_card_pos( const _CARD_POS_& pos );
-	};
-}
-
-//单件定义
-typedef boost::serialization::singleton<YA::wsTimerThread> singleton_wsTimerThread;
-#define swsTimerThrd singleton_wsTimerThread::get_mutable_instance()
-#define swsTimerThrd_const singleton_wsTimerThread::get_const_instance()
+/**
+* @brief
+websocket瀹氭椂鍙戦€佺嚎绋嬬被
+
+* @version
+  V 1.0.0
+
+* @author
+  鐜嬬泭淇�
+
+* @date
+  鍒涘缓鏃堕棿:  2018-08-17\n
+
+* @note
+  2018-08-17  鍒涘缓绫汇€俓n
+
+* @warning
+
+* @bug
+  
+*/
+
+#pragma once
+
+#include <boost/thread.hpp>
+#include <boost/bind.hpp>
+#include <boost/atomic.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/serialization/singleton.hpp>
+
+#include <ctime>
+
+#include "thread_safe_map.h"
+#include "ws_common.h"
+#include "jsonBuilder.h"
+
+namespace YA
+{
+	class wsTimerThread
+	{
+	private:
+		boost::shared_ptr<boost::thread> __Thread;//绾跨▼
+		boost::atomic<bool> __Enable;//绾跨▼鏄�惁缁х画杩愯�鐨勬爣蹇�
+		boost::atomic<bool> __Running;//绾跨▼鏄�惁姝e湪杩愯�鐨勬爣蹇�
+		boost::condition_variable_any __ExitCond;//鏉′欢鍙橀噺
+		boost::mutex __ExitMutex;//閿�(閰嶅悎__ExitCond)
+		_THREAD_CONFIG_ __Config;//绾跨▼閰嶇疆
+		thread_safe_map<int, _CARD_POS_> __CardPosList;//鍗′綅缃�垪琛�
+		std::tm __LastSendTime;//涓婁竴娆″彂閫佺殑鏃堕棿
+		jsonBuilder __jsBuilder;//json鏋勯€犲櫒绫�
+	private:
+		/**
+		* @brief
+		  閲嶇疆鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void __Reset();
+		/**
+		* @brief
+		  妫€鏌ョ嚎绋嬮厤缃�槸鍚﹀悎娉曞嚱鏁般€�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void __ChkConfig();
+		/**
+		* @brief
+		  鍙戦€佸崱浣嶇疆鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void __SendCardPos();
+	protected:
+		/**
+		* @brief
+		  绾跨▼鍑芥暟銆�
+
+		* @param  [in] wsTimerThread* pOwner  绾跨▼鎵€灞炶€匼n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void _ThreadFunc( wsTimerThread* pOwner );
+	public:
+		wsTimerThread();
+		~wsTimerThread();
+		/**
+		* @brief
+		  鍚�姩绾跨▼鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void Start();
+		/**
+		* @brief
+		  鍋滄�绾跨▼鍑芥暟銆�
+
+		* @param  鏃燶n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void Stop();
+		/**
+		* @brief
+		  鍒濆�鍖栧嚱鏁般€�
+
+		* @param  [in] const _THREAD_CONFIG_& Config  绾跨▼閰嶇疆\n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void Init( const _THREAD_CONFIG_& Config );
+		/**
+		* @brief
+		  鏇存柊鍗′綅缃�嚱鏁般€�
+
+		* @param  [in] const _CARD_POS_& pos  鍗′綅缃�粨鏋勪綋\n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void upt_card_pos( const _CARD_POS_& pos );
+		/**
+		* @brief
+		  鍒犻櫎鍗′綅缃�嚱鏁般€�
+
+		* @param  [in] const _CARD_POS_& pos  鍗′綅缃�粨鏋勪綋\n
+
+		* @return 鏃燶n
+
+		* @note
+
+		* @warning
+
+		* @bug
+
+		*/
+		void del_card_pos( const _CARD_POS_& pos );
+	};
+}
+
+//鍗曚欢瀹氫箟
+typedef boost::serialization::singleton<YA::wsTimerThread> singleton_wsTimerThread;
+#define swsTimerThrd singleton_wsTimerThread::get_mutable_instance()
+#define swsTimerThrd_const singleton_wsTimerThread::get_const_instance()

+ 124 - 77
websocket/ws_common.h

@@ -1,77 +1,124 @@
-/**
-* @brief
-  websocket¹«¹²Í·Îļþ
-
-* @version
-  V 1.0.0
-
-* @author
-  ÍõÒæ¿¡
-
-* @date
-  ´´½¨Ê±¼ä:  2018-08-17\n
-
-* @note
-  2018-08-17  ³õ´Î´´½¨¡£\n
-
-* @warning
-
-* @bug
-  
-*/
-
-#ifndef _WS_COMMON_INC_H_
-#define _WS_COMMON_INC_H_
-
-namespace YA
-{
-	const int MIN_SEND_INTERVAL = 2;
-
-	/**
-	* @brief
-	Ïß³ÌÅäÖýṹÌå¡£
-	*/
-	struct _THREAD_CONFIG_
-	{
-		int SendInterval;//·¢Ëͼä¸ô(µ¥Î»:Ãë)
-		void Clear()
-		{
-			SendInterval = 0;
-		}
-		_THREAD_CONFIG_()
-		{
-			Clear();
-		}
-	};
-
-	/**
-	* @brief
-	¿¨Î»ÖýṹÌå¡£
-	*/
-	struct _CARD_POS_
-	{
-		int Type;//¿¨ÀàÐÍ
-		int ID;//¿¨ID
-		double x;//x×ø±ê
-		double y;//y×ø±ê
-		double z;//z×ø±ê
-		double speed;
-		int    stat;
-		void Clear()
-		{
-			Type = 0;
-			ID   = 0;
-			x    = 0.0;
-			y    = 0.0;
-			z    = 0.0;
-			speed = 0;
-			stat = 0;
-		}
-		_CARD_POS_()
-		{
-			Clear();
-		}
-	};
-}
-
-#endif
+/**
+* @brief
+  websocket公共头文件
+
+* @version
+  V 1.0.0
+
+* @author
+  王益俊
+
+* @date
+  创建时间:  2018-08-17\n
+
+* @note
+  2018-08-17  �次创建。\n
+
+* @warning
+
+* @bug
+  
+*/
+
+#ifndef _WS_COMMON_INC_H_
+#define _WS_COMMON_INC_H_
+#include <map>
+namespace YA
+{
+	const int MIN_SEND_INTERVAL = 1;//最���时间间隔
+
+	/**
+	* @brief
+	线程�置结构体。
+	*/
+	struct _THREAD_CONFIG_
+	{
+		int SendInterval;//��间隔(��:秒)
+		void Clear()
+		{
+			SendInterval = 0;
+		}
+		_THREAD_CONFIG_()
+		{
+			Clear();
+		}
+	};
+
+	/**
+	* @brief
+	��置结构体。
+	*/
+	struct _CARD_POS_
+	{
+		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;//最�接收时间戳
+		double work_time;//工作时长
+		int map_id;//地图编�
+		int area_id;//区域ID
+		int dept_id;//部门编�
+		int stat;//低电�告警
+		int running_stat; //�动状�
+		int biz_stat;//业务状� 呼救呼�盲区等
+		int landmark_id;//地标编�
+		int lm_direction;//地标方�
+		int landmark_dis;//�离地标的�离
+		int level_id;//级别编�
+		int is_on_duty;//车辆是�是当天出勤的标识(1:出勤,0:�出勤)
+		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;
+			lm_direction = 0;
+			landmark_dis = 0;
+			level_id = 0;
+			is_on_duty = 0;
+			display    = 1;//默认显示
+		}
+		_CARD_POS_()
+		{
+			Clear();
+		}
+	};
+
+	/**
+	* @brief
+	统计部门结构体。
+	*/
+	struct _STAT_DEPT_ITEM_
+	{
+		int DeptID;//部门ID
+		std::map<int, int> Area;//区域数�列表(key是区域ID,value是区域里的�数)
+		std::map<int, int> Dept;//部门数�列表(key是区域ID,value是部门里的�数)
+		std::map<int, int> OcptLvl;//�务级别数�列表(key是区域ID,value是�务级别里的�数)
+		int Sum;//�总数
+		_STAT_DEPT_ITEM_()
+		{
+			DeptID = 0;
+			Sum    = 0;
+		}
+	};
+}
+
+#endif

+ 1 - 1
write-copy.h

@@ -1,6 +1,6 @@
 #ifndef _WRITE_COPY_HPP_
 #define  _WRITE_COPY_HPP_
-
+//add之前如果有数据,需要把运行中更改的数据进行保存。
 #include <unordered_map>
 #include <algorithm>
 #include <memory>