Przeglądaj źródła

his location for card

lixioayao 6 lat temu
rodzic
commit
97b8f2c6bf
7 zmienionych plików z 302 dodań i 30 usunięć
  1. 1 3
      bindmorecard.h
  2. 20 20
      card.cpp
  3. 4 1
      card.h
  4. 272 0
      his_location.h
  5. 2 1
      monkey_car/monkeycar_person.h
  6. 2 4
      select_tool.h
  7. 1 1
      worker.cpp

+ 1 - 3
bindmorecard.h

@@ -72,13 +72,11 @@ struct TcardInterface
 		assert(m_timestamp != 0||tsp != 0);
 		std::tuple<bool,std::string> stp(flag,"");
 
-
-
 		if (empty())
 		  grow(tsp);
 		uint64_t tmp_tsp_min = back(0).m_timestamp;
 		uint64_t tmp_tsp_max = back(0).m_timestamp + TIME_WIN_MILLISEC;
-		assert(tsp >= tmp_tsp_min);
+		//assert(tsp >= tmp_tsp_min);
 
 		do
 		{

+ 20 - 20
card.cpp

@@ -21,6 +21,7 @@
 #include "mine.h"
 #include "module_service/module_mgr.h"
 #include "visit.h"
+#include "his_location.h"
 
 extern config_file config;
 //一张卡一个ct的所有不同天线的信息
@@ -201,11 +202,11 @@ struct card_area
 struct person:card_location_base, card_area
 {
 	std::weak_ptr<monkey_person> m_monkeyPerson;
-
 	person(std::string type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid,int32_t level_id)
         :card_location_base(type,cardid,needdisplay,t,deptid,level_id)
 	{
-        m_message_handle = new card_message_handle(this);
+        m_message_handle.reset(new card_message_handle(this));
+		m_his_location_card.reset(new location_staff(m_id,m_type));
 	}
 
 	void on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history)
@@ -248,14 +249,9 @@ struct person:card_location_base, card_area
 
 	virtual void do_business(const point &pt)
 	{
-		//区域
 		m_area_tool->on_point(m_id,pt,m_speed,m_type);
-		//考勤
         m_site_area->on_point(m_id,0,this, m_type);
-		//
 	}
-	//人卡升井后该线程要停掉
-	//手动升级需要补全区域得同时,需要进区域走区域业务
 	void reset(std::shared_ptr<monkey_person> mp)
 	{
 		m_monkeyPerson = mp;
@@ -267,15 +263,16 @@ private:
 		if(!m_mine_tool->is_attendance())
 		  return;
 		YA::_CARD_POS_ cp;
-		point pt = getSmoothPoint();
+		uint64_t _time=0;
+		point pt = getSmoothPoint(_time);
 		const auto lm = m_area_tool->getLandmark();
 
 		cp.enter_area_time = std::get<0>(lm)*1000;
 		cp.rec_time = std::get<1>(lm);
 
-		cp.map_id = std::get<2>(lm);
-		cp.area_id = std::get<3>(lm);
-
+		int32_t map_id = std::get<2>(lm);
+		int32_t area_id = std::get<3>(lm);
+		cp.map_id=map_id;cp.area_id=area_id;
 		cp.landmark_id = std::get<4>(lm);
 		cp.lm_direction = std::get<5>(lm);
 		cp.landmark_dis=std::get<6>(lm);
@@ -284,10 +281,10 @@ private:
 		cp.down_time = m_mine_tool->get_down_time();
 		cp.work_time = m_mine_tool->get_work_time();
 		cp.is_on_duty= m_mine_tool->is_on_duty();
-		
+		m_his_location_card->push(_time,pt,area_id,map_id);
 		upt_card_pos(cp,pt);
 	}
-	point getSmoothPoint()
+	point getSmoothPoint(uint64_t t)
 	{
 		point pt;
 		loc_point lp = m_smo_tool->smooth_strategy();
@@ -295,12 +292,13 @@ private:
 		m_stat  = lp.m_stat;
 		pt.x = lp.x;
 		pt.y = -lp.y;
+		t=lp.m_time;
 		if(auto  p = m_monkeyPerson.lock() )
 		{
 			if(p->is_on_bus())
 			{
 				m_stat = 7;
-				pt = p->getPoint();	
+				pt = p->getPoint(t);	
 			}
 		}
 		return pt;
@@ -317,7 +315,8 @@ struct car:card_location_base,card_area
 		,m_vehicle_category_id(categoryid)
         ,m_vehicle_type_id(type_id)
     {
-        m_message_handle=new card_message_handle(this);
+        m_message_handle.reset(new card_message_handle(this));
+		m_his_location_card.reset(new location_vehicle(m_id,m_type));
     }
 
 	virtual void site_hover(int sid)
@@ -383,13 +382,14 @@ private:
 	{
 		int32_t special_id=-1;
 		YA::_CARD_POS_ cp;
-		point pt = getSmoothPoint();
+		loc_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);
+		uint32_t map_id = std::get<2>(lm);
+		uint32_t area_id = std::get<3>(lm);
+		cp.map_id =map_id;cp.area_id=area_id;
 		cp.landmark_id = std::get<4>(lm);
 		cp.lm_direction = std::get<5>(lm);
 		cp.landmark_dis=std::get<6>(lm);
@@ -400,14 +400,14 @@ private:
 		//for now
 		cp.is_on_duty=m_mine_tool->is_on_duty();
 		upt_card_pos(cp,pt);
-
+		m_his_location_card->push(pt.m_time,pt,area_id,map_id);
 		if(biz_stat==STATUS_LOST && special_id != -1 && m_display==1)
 		{
 			cp.area_id = special_id;
 			swsClientMgr.SendSpecialAreaProcess(cp);
 		}
 	}
-	point getSmoothPoint()
+	loc_point getSmoothPoint()
 	{
 		loc_point lp = m_smo_tool->smooth_strategy();
 		m_speed = lp.m_speed;

+ 4 - 1
card.h

@@ -20,6 +20,7 @@ struct smooth_tool;
 struct monkey_person;
 struct card_message_handle;
 struct mine_tool;
+struct location_card;
 struct card:point
 {
 	card(uint32_t id,uint16_t dis,uint64_t type,int32_t deptid,int32_t level_id)
@@ -52,7 +53,8 @@ struct card_location_base:card
 {
     std::unique_ptr<select_tool> m_sel_tool;
     std::unique_ptr<smooth_tool> m_smo_tool;
-	card_message_handle *m_message_handle=nullptr;
+	std::unique_ptr<card_message_handle> m_message_handle;
+	std::unique_ptr<location_card> m_his_location_card;
   //  ev::dynamic_loop * m_loop = nullptr;
  //   ev::timer m_timer;
 
@@ -101,6 +103,7 @@ struct card_list:single_base<card_list,uint64_t,std::shared_ptr<card_location_ba
     void load_his_card_postion_vehicle();
     void load_his_card_postion_staff();
     void load_his_card_postion_from_db();
+
 	std::unique_ptr<std::thread> m_pThread;
 	bool m_bflag=false;
 	void run()

+ 272 - 0
his_location.h

@@ -0,0 +1,272 @@
+#ifndef __INCLUDE_HIS_LOCATION_HPP
+#define __INCLUDE_HIS_LOCATION_HPP
+#include <complex>
+#include <queue>
+#include "point.h"
+#include "log.h"
+#include "db_api/CDBConnPool.h"
+//速度
+//区域 地图变换
+//运动方向
+//路径变换
+struct location_card
+{
+	location_card(uint32_t id,uint64_t type)
+		:m_cardid(id)
+		 ,m_type(type)
+	{
+		init();
+	}
+	uint32_t    m_cardid;//卡id
+	uint16_t	m_type;//卡类型
+	double		m_arg;//运动方向角度值
+	int 		m_areaid;//区域
+	int 		m_mapid;//地图
+	uint64_t	m_timestamp;//入库后的时间
+	point		m_p;//入库后的点
+	struct mini_data
+	{
+		mini_data(const point &p,uint64_t t)
+			:p(p)
+			 ,time(t)
+		{}
+		point p;
+		uint64_t time;
+	};
+	std::queue<mini_data> m_d;
+	void init()
+	{
+		m_areaid=-1;
+		m_mapid=-1;
+		m_timestamp=0;
+		m_p.set(0,0);
+		init_att();
+	}
+	void init_att()
+	{
+		m_arg=0x12345678;
+		std::queue<mini_data> tmp;
+		m_d.swap(tmp);
+	}
+	void set_invalid()
+	{
+		m_arg=0x12345678;
+	}
+	bool is_valid()
+	{
+		return m_arg!=0x12345678;
+	}
+	double make_arg(const point &pt,const point &p)
+	{
+		log_info("his_location arg[%d],(%.2f,%.2f)--->(%.2f,%.2f)---->(%.2f,%.2f)",m_cardid,m_p.x,m_p.y,p.x,p.y,pt.x,pt.y);
+		return  std::arg(std::complex<double>(pt.x,pt.y)-std::complex<double>(p.x,p.y));
+	}
+	void set(const point &pt,uint64_t time)
+	{
+		m_timestamp=time;
+		m_p.set(pt);
+	}
+	bool line_changed(const point &pt)
+	{
+		if(!is_valid())
+		  return false;
+		point p=m_d.back().p;
+		if(p==pt)p=m_p;
+		double arg = make_arg(pt,p);
+		log_info("his_location:line_changed:%d,%.2f,m_arg:%.2f",m_cardid,arg,m_arg);
+		return arg != m_arg;
+	}
+	bool is_speed_changed(const point& pt,uint64_t time)
+	{
+		bool flag = false;
+		double v=0.0;
+		if(m_d.size()>=4)
+		{
+			mini_data d1 = m_d.front();
+			double dist = d1.p.dist(pt);
+			double t = time-d1.time;
+			v = dist/t*1000;
+			m_d.pop();
+		}
+		m_d.emplace(pt,time);
+		if(v==0.0)
+		  return flag;
+		double dist = m_p.dist(pt);
+		double t	= time - m_timestamp;
+		double avge_speed= dist/t*1000;
+		log_info("his_location cardid:%d:v:%.2f,avge_v:%.2f,(%.2f--%.2f)",m_cardid,v,avge_speed,0.8*avge_speed,1.2*avge_speed);
+		if(v<(1-0.2)*avge_speed && v>(1+0.2)*avge_speed)
+		  flag=true;
+		  
+		return flag;
+	}
+	bool time_out(uint64_t time)
+	{
+		if(time-m_timestamp>=60*1000)
+			return true;
+		return false;
+	}
+	bool is_area_changed(int new_areaid)
+	{
+		bool flag =false;
+		if(m_areaid != new_areaid)
+		{
+			m_areaid = new_areaid;
+			flag=true;
+		}
+		return flag;
+	}
+	bool is_map_changed(int new_mapid)	
+	{
+		bool flag =false;
+		if(m_mapid != new_mapid)
+		{
+			m_mapid = new_mapid;
+			flag=true;
+		}
+		return flag;
+	}
+	void push(uint64_t timestamp,const point & p,int32_t areaid,int32_t mapid)
+	{
+		if(m_p.empty() || m_timestamp==0||m_areaid<=0||m_mapid<=0)	
+		{
+		  set(p,timestamp);
+		  m_areaid=areaid;m_mapid=mapid;
+		  m_d.emplace(p,timestamp);
+		  return;
+		}
+		
+		if(!is_valid())
+		{
+		  if(p==m_p)
+		  {
+			  init_att();set(p,timestamp);
+			  m_d.emplace(p,timestamp);
+			  return ;
+		  }
+		  m_arg=make_arg(p,m_p);
+		  log_info("his_location:%d arg:%f",m_cardid,m_arg);
+		  insert();
+		}
+		bool flag=false;
+		bool iflag=false;
+		flag=handle_message(p,timestamp);
+		if(time_out(timestamp))
+			if(!flag)iflag=true;
+		if(is_speed_changed(p,timestamp))
+			if(!flag)iflag=true;
+		if(is_area_changed(areaid))
+			if(!flag)iflag=true;
+		if(is_map_changed(mapid))
+			if(!flag)iflag=true;
+		if(iflag)
+		{
+			update(p,timestamp);
+			set_invalid();	
+			set(p,timestamp);
+		}
+	}
+	virtual std::string getTabName()=0;
+	void insert()
+	{
+		std::string tabName=getTabName();
+		char nsql[512]={0};
+		const char * sql = "replace into %s (card_id,begin_time,map_id,area_id,begin_pt,direction)values(%03d%010d,'%s',%d,%d,'%.2f,%.2f',%f);";
+		snprintf(nsql,512,sql,tabName.c_str(),m_type,m_cardid,tool_time::to_str_ex(m_timestamp).c_str(),m_mapid,m_areaid,m_p.x,m_p.y,m_arg);
+		log_info("his_location[%d]:%s",m_cardid,nsql);
+		sDBConnPool.PushAsync(nsql);
+	}
+	void update(const point &p,uint64_t timestamp)
+	{
+		std::string tabName=getTabName();
+		char nsql[512]={0};
+		const char * sql = "update %s set last_time='%s',speed=%.2f where card_id=%03d%010d and begin_time='%s';";
+		double dist = m_p.dist(p);
+		double t	= timestamp - m_timestamp;
+		double avge_speed= dist/t*1000;
+		snprintf(nsql,512,sql,tabName.c_str(),tool_time::to_str_ex(timestamp).c_str(),avge_speed,m_type,m_cardid,tool_time::to_str_ex(m_timestamp).c_str());
+		log_info("his_location[%d]:%s",m_cardid,nsql);
+		sDBConnPool.PushAsync(nsql);
+	}
+
+	virtual bool  handle_message(const point &p,uint64_t timestamp)=0;
+};
+struct location_staff:location_card
+{
+	location_staff(uint32_t id,uint16_t type)
+		:location_card(id,type)
+	{}
+	virtual std::string getTabName(){return std::string{"his_location_staff_"};}
+	//人员如果运行方向发生变化的话,需要求的拐点。如果有拐点,入拐点。时间大与120s则不做处理。没有拐点,则不求
+	virtual bool  handle_message(const point &p,uint64_t timestamp)
+	{
+		bool flag = false;
+		if(line_changed(p))
+		{
+			log_info("his_location:line_changed %d",m_cardid);
+			flag=true;
+			if(timestamp-m_timestamp>120*1000)
+			{
+				update(m_d.back().p,m_d.back().time);
+				set(p,timestamp);
+			}
+			else
+			{
+				std::vector<point> rc=card_path::inst().find_path(m_p,p);
+				if(rc.empty())				
+				{
+					update(m_d.back().p,m_d.back().time);
+					set(m_d.back().p,m_d.back().time);
+				}
+				else
+				{
+					if(rc.size()==1)
+					{
+						log_info("his_location:line_changed %d circle point(%.2f,%.2f)",m_cardid,rc[0].x,rc[0].y);
+						update(rc[0],m_d.back().time);
+						set(rc[0],m_d.back().time);
+					}
+					else if(rc.size()==2)
+					{
+						update(rc[0],m_d.back().time);
+						set(rc[0],m_d.back().time);
+						//
+						m_arg=make_arg(rc[1],m_p);
+						insert();
+						//
+						update(rc[1],timestamp);
+						set(rc[1],timestamp);
+					}
+					else//更多的拐点
+					{
+						update(rc[0],m_d.back().time);
+						set(rc[1],timestamp);
+					}
+				}
+			}
+			init_att();
+		}
+		return flag;
+	}
+};
+struct location_vehicle:location_card
+{
+	location_vehicle(uint32_t id,uint16_t type)
+		:location_card(id,type)
+	{}
+	virtual std::string getTabName(){return std::string{"his_location_vehicle_"};}
+	//车辆是有推送拐点的,所以不需要求拐点。如果运行方向发生变化的话,直接更新数据库即可,使用上一个点的时间。同时生成这一次的历史。
+	virtual bool  handle_message(const point &p,uint64_t timestamp)
+	{
+		bool flag =false;
+		if(line_changed(p))
+		{
+			log_info("his_location:line_changed %d ",m_cardid);
+			flag=true;
+			update(m_d.back().p,m_d.back().time);
+			set(m_d.back().p,m_d.back().time);init_att();
+		}
+		return flag;
+	}
+};
+#endif

+ 2 - 1
monkey_car/monkeycar_person.h

@@ -40,10 +40,11 @@ struct monkey_person
 	bool fit_speed(double*ret_speed);
 	bool get_num_point(int * p);
 	bool init_another_list(size_t index);
-	point getPoint()
+	point getPoint(uint64_t t)
 	{
 		point p;
 		const auto pt = get_position();
+		t=m_timeval;
 		if(point_2::is_valid(pt))
 		{
 			p.x = pt.x_;

+ 2 - 4
select_tool.h

@@ -216,7 +216,7 @@ struct person_point_filter:select_point_object
 		//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())
-		  log_error("error.here....2222");
+		  log_error("person.dstp empty()");
 
 		push_data_point dp;
 		dp.dstp.set(dstp);
@@ -468,7 +468,7 @@ struct car_point_filter:select_point_object
 		{
 			dstp = sit->get_dstp(pt);
 			if(dstp.empty())
-			  log_error("error.here....lll");
+			  log_error("dstp.empty()..");
 			//dstp.set(sit->x,sit->y);
 		}
 		else
@@ -798,7 +798,6 @@ 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))
@@ -850,7 +849,6 @@ struct smooth_tool
 		const auto & sit = sit_list::instance()->get(dpt.lp.m_sid);
 		if(dpt.valid)
 		{
-			//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);
 

+ 1 - 1
worker.cpp

@@ -91,7 +91,7 @@ struct worker_impl:worker
 
 	worker_thread& hash(uint64_t i)
 	{
-		return *m_threads[i*2003%m_threads.size()].get();
+		return *m_threads[i*2003%m_threads.size()];
 	}
 
 	virtual void request(task*t)