lixioayao 6 سال پیش
والد
کامیت
9271dd8f34
20فایلهای تغییر یافته به همراه1121 افزوده شده و 36 حذف شده
  1. 48 2
      Makefile
  2. 1 1
      Makefile.am
  3. 48 2
      Makefile.in
  4. 4 0
      ant.cpp
  5. 3 1
      ant.h
  6. 1 6
      area.cpp
  7. 17 0
      bindmorecard.cpp
  8. 388 0
      bindmorecard.h
  9. 14 3
      card.cpp
  10. 5 3
      card.h
  11. 94 0
      cardMgr.cpp
  12. 105 0
      cardMgr.h
  13. 96 0
      geo_hash.cpp
  14. 124 0
      geo_hash.h
  15. 2 5
      monkey_car/monkeycar_area.cpp
  16. 10 7
      monkey_car/monkeycar_bus.cpp
  17. 1 1
      monkey_car/monkeycar_bus.h
  18. 8 1
      net-service.cpp
  19. 1 4
      select_tool.h
  20. 151 0
      tqueue.h

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 48 - 2
Makefile


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
Makefile.am


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 48 - 2
Makefile.in


+ 4 - 0
ant.cpp

@@ -18,6 +18,10 @@ site::site(int id)
     ,m_path_empty(true)
 {
 
+}
+void site::set_client(std::shared_ptr<client>& clt)
+{
+	m_clt=clt;
 }
 const algo_config&site::config()const
 {

+ 3 - 1
ant.h

@@ -12,7 +12,7 @@
 #include "line.h"
 #include "point.h"
 #include "write-copy.h"
-
+class client;
 struct path
 {
     std::array<line_v,2>	m_line; 
@@ -139,6 +139,8 @@ struct site:point
 
     ///分站位置 UP_DOWN_SITE
     int m_up_down;
+	std::shared_ptr<client> m_clt=nullptr;
+	void set_client(std::shared_ptr<client>& clt);
 
     point get_dstp(const point pt) const 
     {

+ 1 - 6
area.cpp

@@ -30,9 +30,6 @@ void area::on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,u
 {
 	log_info("on_enter..%d  areaId:%d",card_id,m_id);
 	//入库 : 进入区域
-	int cu = m_card_count.load();
-	cu++;
-	m_card_count.store(cu);
 	//check超员
 }
 
@@ -40,8 +37,6 @@ void area::on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,u
 {
 	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)
 	{
@@ -287,6 +282,6 @@ void area_hover::setLandmark(const point &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);
+	log_info("landmark:%d %d %.2f,(%.2f,%.2f),%f",landmark_id,landmark_dir,landmark_dis,pt.x,pt.y,scale());
 }
 

+ 17 - 0
bindmorecard.cpp

@@ -0,0 +1,17 @@
+#include "bindmorecard.h"
+#include <config_file.h>
+extern config_file config;
+
+RemoteCardFactory::RemoteCardFactory(cardMgr * owner)
+		:CardFactory(owner)
+{
+	int remote_hours = config.get("BindMoreCard.timeAlarm_remote",1);
+	m_remote_slot =(int)((remote_hours*60*1000)/TIME_WIN_MILLISEC);
+}
+
+CloserCardFactory::CloserCardFactory(cardMgr * owner)
+		:CardFactory(owner)
+{
+	int closer_hours = config.get("BindMoreCard.timeAlarm_closer",3);
+	m_closer_slot =(int)((closer_hours*60*1000)/TIME_WIN_MILLISEC);
+}

+ 388 - 0
bindmorecard.h

@@ -0,0 +1,388 @@
+#ifndef BIND_MORE_CARD_HPP__
+#define BIND_MORE_CARD_HPP__
+
+#include <time.h>
+#include <thread>
+#include <chrono>
+#include <functional>
+#include <unordered_map>
+#include <mutex>
+#include <sstream>
+#include <map>
+#include "card.h"
+#include "zlist.h"
+#include "cardMgr.h"
+#include "log.h"
+#define TIME_WIN_MILLISEC (15*60*1000)
+#define TIME_LIM_SEC	  (3*1000)
+struct Data
+{
+    Data(uint64_t ct)
+    {
+		reset();
+		m_timestamp = ct;
+    }
+    void reset()
+    {
+        m_index = 0;
+        m_ct.fill(0);
+        m_totaldistance = 0;
+		m_flag = false;
+    }
+    void increase(const int index)
+    {
+        m_ct[index]++;
+    }
+    uint32_t m_index;
+    std::array<uint16_t,2> m_ct;
+    double   m_totaldistance;
+	uint64_t m_timestamp;
+	bool m_flag;
+};
+
+struct TcardInterface
+{
+   // TcardInterface()=default;
+    TcardInterface(std::pair<uint64_t,uint64_t> sp,uint64_t ct,uint64_t owner,int size)
+        :m_cardid(sp)
+        ,m_timestamp(ct)
+		,m_owner(owner)
+		,SIZE(size)
+    {}
+
+	std::tuple<bool,std::string> setindex(uint64_t tsp,const uint64_t cid,const double d=0,bool ctflag =false)
+	{
+		bool flag = false;
+		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);
+
+		do
+		{
+			if(tsp>=tmp_tsp_min && tsp < tmp_tsp_max)
+			{
+				if(!ctflag)
+				{
+					back(0).m_index++;
+					back(0).m_totaldistance+=d;
+				}
+				else
+				{
+					int arrindex = getstrindex(cid);
+					if(arrindex == -1)
+					{
+						log_error("bindmorecard error.not match the cardid");
+						return stp;
+					}
+					back(0).increase(arrindex);
+				}
+				break;
+			}
+			else
+			{
+				if(timeout())
+				{
+					auto tp = get();
+					stp = check(std::get<0>(tp),std::get<1>(tp));
+					skip(1);
+				}
+				grow(tsp);
+				tmp_tsp_min = back(0).m_timestamp;
+				tmp_tsp_max = back(0).m_timestamp + TIME_WIN_MILLISEC;
+			}
+
+		}while(1);
+		return stp;
+	}
+
+	std::tuple<bool,std::string> checkLast()
+	{
+//		std::tuple<bool,std::string> stp(false,std::string(""));
+//		if (!timeout() && size()>=ConfStruct::getCs().remote_slot)
+//		{
+//			auto tp = get();
+//			stp = check(std::get<0>(tp),std::get<1>(tp));
+//		}
+//		return stp;
+		return std::make_tuple(false,"");
+	}
+	void skip(int count)
+	{
+		for(int i =0;i<count&&i<size();i++)
+			m_arr.pop_front();
+	}
+	bool empty()
+	{
+		return m_arr.empty();
+	}
+	int size() 
+	{
+		return m_arr.size();
+	}
+	void  grow(uint64_t ct)
+	{
+		Data d(ct);
+		d.reset();
+		m_arr.push_back(d);
+	}
+	Data &back(int index)
+	{
+		assert(index<(int)size() && index >= 0);
+		return m_arr.at(size()-index-1);
+	}
+	std::tuple<int,int,double> get()
+	{
+		int total_ix=0,total_ct=0;
+		double dis = 0;
+		std::for_each(m_arr.begin(),m_arr.end(),[&total_ix,&total_ct,&dis](const Data &d){total_ix += d.m_index;total_ct+=(d.m_ct[0]+d.m_ct[1]);dis+=d.m_totaldistance;});
+		return std::make_tuple(total_ix,total_ct,dis);
+	}
+	bool timeout()
+	{
+		return size() == SIZE-1;
+	}
+	std::string getInfo_1()
+	{
+		std::stringstream ss;
+		ss<<m_cardid.first<<"&"<<m_cardid.second<<","<<m_arr[0].m_timestamp/1000<<","<<(back(0).m_timestamp+TIME_WIN_MILLISEC)/1000 <<",";
+		std::for_each(m_arr.begin(),m_arr.end(),[&ss](Data& d){
+			if (!d.m_flag)
+			{
+				ss<<d.m_timestamp/1000<<"&"<<d.m_totaldistance<<"&"<<d.m_index<<",";
+				d.m_flag = true;
+			}
+			
+		});
+		return ss.str();
+	}
+	std::string getInfo()
+	{
+		auto tp = get();
+		std::stringstream ss;
+		ss<<"{T:"<<std::get<0>(tp)<<","<<std::get<1>(tp)<<","<<std::get<2>(tp)<<"}";
+		//ss<<"{Total index:"<<std::get<0>(tp)<<","<<std::get<1>(tp)<<"},";
+		//m_arr.for_each([&ss](const Data&x){
+		//	ss<<"["<<x.m_index<<","<<x.m_ct[0]+x.m_ct[1]<<"]";
+		//});
+		return std::move(ss.str());
+	}
+	inline std::tuple<bool,std::string> check(int index,int ct)
+	{
+		if(index*1.0/ct>=0.72)
+		{
+			std::string s = getInfo_1();
+			return std::make_tuple(true,s);
+		}
+		return std::make_tuple(false,std::string(""));
+	}
+    inline int getstrindex(const uint64_t cardid)
+    {
+        if(m_cardid.first == cardid)
+          return 0;
+        else
+          return 1;
+        return -1;
+    }
+public:
+    std::pair<uint64_t,uint64_t> m_cardid;
+    uint64_t m_timestamp;
+	uint64_t m_owner;
+	std::deque<Data> m_arr;
+	int SIZE;
+    virtual ~TcardInterface(){} 
+};
+
+struct CardFactory
+{
+	CardFactory(cardMgr*owner)
+		:m_owner(owner)
+	{}
+	std::map<uint64_t,std::string> setCT(uint64_t cid)
+	{
+		std::map<uint64_t,std::string> tmpvec;
+		auto opcard=card_list::instance()->get(cid);
+		uint64_t cttime = opcard->time_();
+		auto vec = m_owner->getcard(cid);
+		for(const auto cardid:vec)
+		{
+
+			uint64_t id = cardid+cid;
+			auto iter = m_map.find(id);
+			if(iter != m_map.end())
+			{
+				std::shared_ptr<TcardInterface> ptr = iter->second;
+				auto sp = ptr->setindex(cttime,cid,0,true);
+				if (std::get<0>(sp))
+				{
+					tmpvec.insert(std::make_pair(id,std::get<1>(sp)));
+				}
+
+			}
+		}
+		return std::move(tmpvec);
+	}
+
+
+	std::map<uint64_t,std::string> handlecard(const std::vector<uint64_t>& vec,uint64_t cid)
+	{
+		std::map<uint64_t,std::string> tempvec;
+		auto opcard = card_list::instance()->get(cid);
+		uint64_t cttime = opcard->time_();
+		std::shared_ptr<TcardInterface> ptr = nullptr;
+		for(const auto cardid:vec)
+		{
+			uint64_t id = cid+cardid;
+			auto iter = m_map.find(id);
+			if(iter != m_map.end())
+				ptr = iter->second;
+			else
+			{
+				ptr = make_shared_(cardid,cid,cttime,id);
+				m_map.insert({id,ptr});
+				backup(cid,cardid);
+			}
+			auto npcard=card_list::instance()->get(cardid);
+			double dis = opcard->dist(*npcard);
+			auto sp=ptr->setindex(cttime,cid,dis);
+			if (std::get<0>(sp))
+			{
+				tempvec.insert(std::make_pair(id,std::get<1>(sp)));
+			}
+		}
+		return std::move(tempvec);
+	}
+	void erase(uint64_t id)
+	{
+		auto it = m_map.find(id);
+		if(it != m_map.end())
+		{
+			std::pair<uint64_t,uint64_t> p = it->second->m_cardid;
+			m_owner->remove_edge(p.first,p.second);
+			reset(id);
+			m_map.erase(it);
+		}
+	}
+    inline std::string InfoMessage()
+    {
+		std::stringstream ss;
+		ss<<"S: "<<m_map.size();
+		for(auto it : m_map)
+		{
+			//ss<< " hash info["<<it.first <<"]first cardid:["<<it.second->m_cardid.first<<"]second cardid:["<<it.second->m_cardid.second<<"]Info:{total_size:"<<it.second->size()<<","<<it.second->getInfo()<<"}";
+			ss<< "["<<(uint32_t)(it.second->m_cardid.first)<<"]["<<(uint32_t)(it.second->m_cardid.second)<<"]{s:"<<it.second->size()<<","<<it.second->getInfo()<<"}";
+		}
+		return std::move(ss.str());
+
+    }
+    virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &v,uint64_t cid) = 0;
+    virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key) = 0;
+    virtual void backup (uint64_t cid1,uint64_t cid2){}
+    virtual void reset (uint64_t cid){}
+    virtual std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)=0;
+	virtual ~CardFactory(){}
+public:
+    std::unordered_map<uint64_t,std::shared_ptr<TcardInterface>>     m_map;
+	cardMgr * m_owner;
+};
+struct CloserCardFactory : CardFactory
+{
+	CloserCardFactory(cardMgr*);
+	int m_closer_slot=0;
+	std::map<uint64_t,int>					 m_count;
+	bool getAccess(uint64_t cid1,uint64_t cid2)
+	{
+		uint64_t cid = cid1+cid2;
+		if(m_count[cid] < 30)
+		{
+			m_count[cid]++;
+			return false;
+		}
+		else
+			return true;
+	}
+	void reset(uint64_t id)
+	{
+		auto it = m_count.find(id);
+		if(it != m_count.end())
+		  m_count.erase(it);
+	}
+    virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &v,uint64_t cid)
+	{
+		std::map<uint64_t,std::string> vec;
+		if(v.empty()) return vec;
+		std::vector<uint64_t> rc(v.begin(),v.end());
+		auto opcard=card_list::instance()->get(cid);
+		rc.erase(std::remove_if(rc.begin(),rc.end(),[&](uint64_t cardid){
+			if(!getAccess(cid,cardid))
+				return true;
+			if(cardid == cid)
+				return true;
+			auto npcard = card_list::instance()->get(cardid);
+			if(npcard->type_()!=opcard->type_())
+				return true;
+			uint64_t ct1 = npcard->time_();
+			uint64_t ct2 = opcard->time_();
+			uint64_t ct3 = ct1>ct2?ct1-ct2:ct2-ct1;
+			return ct3 > TIME_LIM_SEC; 
+		}),rc.end());
+
+		vec = handlecard(rc,cid);
+		return std::move(vec);
+	}
+    virtual void backup (uint64_t cid1,uint64_t cid2)
+    {
+		m_owner->addVertex(cid1,cid2);
+    }
+    virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key)
+    {
+        return std::make_shared<TcardInterface>(std::make_pair(cid1,cid2),ctime,key,m_closer_slot);
+    }
+	std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)
+	{
+		return ti->checkLast();
+	}
+};
+
+struct RemoteCardFactory : CardFactory
+{
+	RemoteCardFactory(cardMgr*);
+	int m_remote_slot=0;
+    virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &ov,uint64_t cid)
+	{
+		auto vcard=m_owner->getcard(cid);
+		log_info("%d....remote%d",vcard.size(),(vcard.empty()?0:vcard[0]));
+		std::sort(vcard.begin(),vcard.end());
+		std::sort(ov.begin(),ov.end());
+		std::vector<uint64_t> v(ov.size()+vcard.size());
+
+		auto it = std::set_difference(vcard.begin(),vcard.end(),ov.begin(),ov.end(),v.begin());
+		v.resize(it-v.begin());
+		auto opcard = card_list::instance()->get(cid);
+		v.erase(std::remove_if(v.begin(),v.end(),[&](uint64_t cardid){
+			auto npcard = card_list::instance()->get(cardid);
+			uint64_t ct1 = opcard->time_();
+			uint64_t ct2 = npcard->time_();
+			uint64_t ct3 = ct1>ct2?ct1-ct2:ct2-ct1;
+			return ct3 > TIME_LIM_SEC; 
+		}),v.end());
+
+		auto vec = handlecard(v,cid);
+		return std::move(vec);
+	}
+    virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key)
+    {
+        return std::make_shared<TcardInterface>(std::make_pair(cid1,cid2),ctime,key,m_remote_slot);
+    }
+	std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)
+	{
+		return std::make_tuple(false,std::string(""));
+	}
+};
+#endif

+ 14 - 3
card.cpp

@@ -16,6 +16,8 @@
 #include "monkey_car/monkeycar_area.h"
 #include "monkey_car/monkeycar_person.h"
 #include "special_area.h"
+#include "cardMgr.h"
+#include "ant.h"
 
 extern config_file config;
 //一张卡一个ct的所有不同天线的信息
@@ -231,10 +233,13 @@ private:
 		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);
@@ -542,8 +547,8 @@ card_location_base::card_location_base(std::string type,uint32_t id,uint16_t dis
 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;
+	//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;
@@ -552,7 +557,11 @@ void card_location_base::on_location(const std::vector<point>&vp,const std::vect
 		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);
+		Msg m;
+		m.x=(int)x;m.y=(int)y;m.cmd=CMD_HANDLE;m.cardid=m_type<<32|m_id;
+		cardMgr::instance()->tryPut(m);
+
+		log_info("useful: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);
 	}
 }
@@ -561,6 +570,8 @@ void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&lo
 {
 	if(m_loop == nullptr && loop != nullptr)
 		set(loop);
+	m_ct = loc.m_card_ct;
+	m_time = loc.m_time_stamp;
 	m_message_handle->on_message(loop,loc,is_history);
 }
 

+ 5 - 3
card.h

@@ -3,11 +3,11 @@
 #include <message.h>
 #include <ev++.h>
 #include "point.h"
-#include "ant.h"
 
 #include "write-copy.h"
 #include "websocket/ws_common.h"
 #include "common.h"
+#include "ant.h"
 #define CARD_LOST_TIME_OUT (30*1000)
 
 struct task;
@@ -18,7 +18,7 @@ struct monkey_person;
 struct card_message_handle;
 struct card:point
 {
-	card(uint32_t id,uint16_t dis,int16_t type,int32_t deptid)
+	card(uint32_t id,uint16_t dis,uint64_t type,int32_t deptid)
 		:m_id(id)
 		,m_type(type)
 		,m_display(dis)
@@ -29,8 +29,10 @@ struct card:point
 		,m_time(0)
 		,m_deptid(deptid)
 	{}
+	uint64_t type_(){return m_type;}
+	uint64_t time_(){return m_time;}
 	uint32_t m_id;				//卡号
-	int16_t  m_type;			//类型
+	uint64_t  m_type;			//类型
 	uint16_t m_display;			//1显示0不显示,往前端推送
 	double   m_speed;			//速度
 	int      m_is_attendance;	//井上井下状态  0初始状态 1 井上 2 井下

+ 94 - 0
cardMgr.cpp

@@ -0,0 +1,94 @@
+#include "cardMgr.h" 
+#include "bindmorecard.h"
+
+cardMgr::cardMgr()
+:m_queue(2048)
+	,m_bstop(false)
+{
+	m_pThread.reset(new std::thread(std::bind(&cardMgr::run,this)));
+	m_cf[0] = std::make_shared<CloserCardFactory>(this);
+	m_cf[1] = std::make_shared<RemoteCardFactory>(this);
+}
+void cardMgr::run()
+{
+	while(!m_bstop)	
+	{
+		Msg m;
+		m_queue.get(m);
+		onMessage(m);
+	}
+}
+void cardMgr::onMessage(const Msg &m)
+{
+	switch(m.cmd)
+	{
+		case CMD_CLEAR:
+			clear(m.cardid);
+			break;
+		case CMD_HANDLE:
+			handleMessage(m);
+			break;
+		default:
+			break;
+	}
+}
+void cardMgr::clear(uint64_t cardid)
+{
+	auto v = m_cgraph.getcard(cardid);
+	for(const auto & cid:v)
+	{
+		uint64_t id=cid+cardid;
+		erase(id);
+		m_cgraph.remove_edge(cardid,cid);
+	}
+}
+void cardMgr::handleMessage(const Msg &m)
+{
+	m_glist.update(m.x,m.y,m.cardid);
+	std::vector<uint64_t> rc=m_glist.find_near(m.cardid,1);
+
+	log_info("LemonHash+..%d,size:%d,(%d,%d)",m.cardid,rc.size(),m.x,m.y);
+	std::map<uint64_t,std::string> map1;
+	std::map<uint64_t,std::string> map2;
+	for(int i = m_cf.size()-1;i>=0;i--)
+	{
+		map1.clear();map2.clear();
+		map1=m_cf[i]->selectcard(rc,m.cardid);
+		map2=m_cf[i]->setCT(m.cardid);
+		std::copy(map1.begin(),map1.end(),std::inserter(map2,map2.end()));
+
+		if (i == 1 && !map2.empty())
+		  erase(map2);
+
+		if (!map2.empty())
+		{
+			//m_owner->uwb_alarm(map2,i,c);
+		}
+		if (!rc.empty())
+		{
+			std::string s ;
+			s = m_cf[i]->InfoMessage();
+			log_info("---LemonHash----[%s]%s",i?"Remote":"Closer",s.c_str());
+		}
+	}
+}
+void cardMgr::erase(const std::map<uint64_t,std::string> &m)
+{
+	for(auto &p:m)
+	  erase(p.first);
+}
+void cardMgr::erase(uint64_t id)
+{
+	for(const auto & t:m_cf)
+	  t->erase(id);
+}
+cardMgr::~cardMgr()
+{
+	m_bstop = true;
+	m_pThread->join();
+}
+cardMgr* cardMgr::instance()
+{
+	static cardMgr cd;
+	return &cd;
+}

+ 105 - 0
cardMgr.h

@@ -0,0 +1,105 @@
+#ifndef __INCLUDE_CARD_MGR__
+#define __INCLUDE_CARD_MGR__
+#include <memory>
+#include <thread>
+#include <boost/config.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/graph/vector_as_graph.hpp>
+#include "tqueue.h"
+#include "log.h"
+#include "geo_hash.h"
+
+struct card_graph
+{
+	typedef boost::adjacency_list<boost::vecS,boost::vecS,boost::bidirectionalS> myGraph_vv;
+	myGraph_vv m_g;
+
+	void add_edge(uint32_t c1,uint32_t c2)
+	{
+		boost::add_edge(c1,c2,m_g);
+		boost::add_edge(c2,c1,m_g);
+	}
+
+	void clear_vertex(uint32_t c)
+	{
+		if(c>boost::num_vertices(m_g)) return;
+		boost::clear_vertex(c,m_g);
+	}
+	void remove_edge(uint32_t c1,uint32_t c2)
+	{
+		uint64_t count = boost::num_vertices(m_g);
+		if(c1>count || c2>count) return;
+		boost::remove_edge(c1,c2,m_g);
+		boost::remove_edge(c2,c1,m_g);
+	}
+	std::vector<uint32_t> getcard(uint32_t c)
+	{
+		std::vector<uint32_t> tmp;
+		if(c>boost::num_vertices(m_g))return tmp;
+		boost::graph_traits<myGraph_vv>::adjacency_iterator ai_it, ai_it_end;
+		boost::tie(ai_it, ai_it_end) = boost::adjacent_vertices(c, m_g);
+		while(ai_it != ai_it_end)
+		{
+			tmp.push_back(*ai_it);
+			ai_it++;
+		}
+		return std::move(tmp);
+	}
+};
+
+
+enum{
+	CMD_CLEAR,
+	CMD_HANDLE
+};
+struct Msg
+{
+	int				cmd;
+	int				x;
+	int				y;
+	uint64_t        cardid;
+};
+
+class CardFactory;
+struct cardMgr
+{
+	cardMgr();
+	static cardMgr* instance();
+	void run();
+	void onMessage(const Msg &m);
+	void clear(uint64_t);
+	void handleMessage(const Msg &m);
+	void erase(const std::map<uint64_t ,std::string>&);
+	void erase(uint64_t);
+	void tryPut(Msg &m)
+	{
+		if(!m_queue.tryPut(m))
+		  log_error("m_queue tryPut makes error.");
+	}
+	void addVertex(uint64_t c1,uint64_t c2)
+	{
+		m_cgraph.add_edge(c1,c2);
+	}
+	std::vector<uint64_t> getcard(uint64_t cid)
+	{
+		std::vector<uint64_t> tmpv;
+		auto v= m_cgraph.getcard(cid);
+		std::for_each(v.begin(),v.end(),[cid,&tmpv](uint32_t cardid){uint64_t id=(cid>>32<<32)|cardid;tmpv.push_back(id);});
+		return std::move(tmpv);
+	}
+	void remove_edge(uint64_t c1, uint64_t c2)
+	{
+		m_cgraph.remove_edge(c1,c2);
+	}
+	~cardMgr();
+private:
+	BoundedQueue<Msg>				m_queue;
+	bool							m_bstop;
+	geo_list						m_glist;
+	card_graph						m_cgraph;
+	std::unique_ptr<std::thread>	m_pThread;
+	std::array<std::shared_ptr<CardFactory>,2> m_cf;
+};
+#endif
+

+ 96 - 0
geo_hash.cpp

@@ -0,0 +1,96 @@
+#include "geo_hash.h"
+
+void geo_list::find_near(std::vector<uint64_t>&ret,int x,int y,unsigned h,uint32_t dist2,unsigned mask,uint64_t card_no)
+{
+	for(auto it=geo2card.lower_bound(h);it!=geo2card.end();++it)
+	{
+		if((it->first&mask)!=h)
+			break;
+
+		auto pos=ghash::decode(it->first);
+
+		int xi=std::get<0>(pos);
+		int yi=std::get<1>(pos);
+		unsigned sn = (xi-x)*(xi-x)+(yi-y)*(yi-y);
+		if(sn > dist2)
+			continue;
+		if (card_no==it->second)
+			continue;
+		//std::stringstream ss;
+		//ss<<"-----LemonHash---findnear---cardid"<<card_no<<"x:"<<x<<"y:"<<y<<"dist2:"<<dist2<<" cardid:"<<it->second<<"x:"<<xi<<"y:"<<yi<<"sn"<<sn;
+		//debug_print_syslog(0,"%s",ss.str().c_str());
+		ret.push_back(it->second);
+	}
+}
+std::vector<uint64_t> geo_list::find_near(int x,int y,int dist,uint64_t card_no)
+{
+	int t=1;
+	while(t<dist) t<<=1;
+
+	int x0=x&~(t-1) , y0=y&~(t-1);
+
+	std::vector<uint64_t> r;
+	const int dist2=dist*dist;
+
+	unsigned mask=~(t*t-1);
+
+	find_near(r,x,y,ghash::encode(x0-t,y0-t),dist2,mask,card_no);
+	find_near(r,x,y,ghash::encode(x0,y0-t),dist2,mask,card_no);
+	find_near(r,x,y,ghash::encode(x0+t,y0-t),dist2,mask,card_no);
+	find_near(r,x,y,ghash::encode(x0-t,y0),dist2,mask,card_no);
+	find_near(r,x,y,ghash::encode(x0,y0),dist2,mask,card_no);
+	find_near(r,x,y,ghash::encode(x0+t,y0),dist2,mask,card_no);
+	find_near(r,x,y,ghash::encode(x0-t,y0+t),dist2,mask,card_no);
+	find_near(r,x,y,ghash::encode(x0,y0+t),dist2,mask,card_no);
+	find_near(r,x,y,ghash::encode(x0+t,y0+t),dist2,mask,card_no);
+
+	return std::move(r);
+}
+
+//std::vector<std::string> find_near(const char*card_no,int dist)
+std::vector<uint64_t> geo_list::find_near(uint64_t card_no,int dist)
+{
+	std::vector<uint64_t> r;
+	auto it=card2geo.find(card_no);
+
+	if(it==card2geo.end())
+		return std::move(r);
+
+	auto h=ghash::decode(it->second);
+
+	return find_near(std::get<0>(h),std::get<1>(h),dist,card_no);
+}
+
+//void update(int x,int y,const char*card_no)
+void geo_list::update(int x,int y,uint64_t card_no)
+{
+	//std::stringstream ss;
+	unsigned h=ghash::encode(x,y);
+	//ss<<"-----LemonHash--update--"<<card_no<<"x:"<<x<<"y:"<<y<<"h:"<<h;
+	//debug_print_syslog(0,"%s",ss.str().c_str());
+
+	auto it=card2geo.find(card_no);
+	if(it==card2geo.end())
+	{
+		card2geo.insert(std::make_pair(card_no,h));
+		geo2card.insert(std::make_pair(h,card_no));
+	}
+	else
+	{
+		it->second=h;
+
+		for(auto it1=geo2card.begin();it1!=geo2card.end();++it1)
+		{
+			if(it1->second==card_no)
+			{
+				geo2card.erase(it1);
+				break;
+			}
+
+		}
+
+
+
+		geo2card.insert(std::make_pair(h,card_no));
+	}
+}

+ 124 - 0
geo_hash.h

@@ -0,0 +1,124 @@
+#ifndef _GEO_HASH__
+#define _GEO_HASH__
+
+#include "point.h"
+#include <iostream>
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <tuple>
+#include <boost/container/flat_set.hpp>
+#include <string>
+
+struct ghash
+{
+	static std::tuple<int,int> decode(unsigned h)
+	{
+		const unsigned S=0x80000000;
+
+		int x=0,y=0;
+		for(int i=0;i<16;i++)
+		{
+			x<<=1;
+			y<<=1;
+
+			if(h&S) 
+				x|=1;
+			h<<=1;
+
+			if(h&S) 
+				y|=1;
+			h<<=1;
+		}
+
+		return std::make_tuple(x-32768,y-32768);
+	}
+
+	static unsigned encode(int x, int y)
+	{
+		return encode_(x+32768,y+32768);
+	}
+
+public: //test
+	static void test_code(int x,int y)
+	{
+		unsigned h=ghash::encode(x,y);
+		auto t=ghash::decode(h);
+
+		printf("src x=%X,y=%X hash=%X,check x=%X,y=%X\n",x,y,h,std::get<0>(t),std::get<1>(t));
+	}
+
+	static void test()
+	{
+		for(int i=0;i<10;i++)
+		{
+			test_code((4<<i)-1,(4<<i)-1);
+			test_code((4<<i)-1,(4<<i));
+			test_code((4<<i)-1,(4<<i)-1);
+			test_code((4<<i),(4<<i)-1);
+		}
+	}
+private:
+	static unsigned encode_(unsigned short x, unsigned short y)
+	{
+		const unsigned S=0x8000;
+		unsigned r=0;
+		for(int i=0;i<16;i++)
+		{
+			r<<=2;
+			if(x&S)
+			{
+				r|=(y&S)?3:2;
+			}
+			else
+			{
+				if(y&S) r|=1;
+			}
+
+			x<<=1;
+			y<<=1;
+		}
+
+		return r;
+	}
+};
+
+struct geo_list
+{
+private:
+	std::multimap<unsigned int,uint64_t> geo2card;
+	std::map<uint64_t,unsigned int> card2geo;
+
+	inline void find_near(std::vector<uint64_t>&ret,int x,int y,unsigned h,uint32_t dist2,unsigned mask,uint64_t card_no);
+
+public:
+
+	std::vector<uint64_t> find_near(int x,int y,int dist,uint64_t card_no);
+
+	//std::vector<std::string> find_near(const char*card_no,int dist)
+	std::vector<uint64_t> find_near(uint64_t card_no,int dist);
+	//void update(int x,int y,const char*card_no)
+	void update(int x,int y,uint64_t card_no);
+
+	size_t size()
+	{
+		return card2geo.size();
+	}
+
+	void print()
+	{
+		for(auto it=card2geo.begin();it!=card2geo.end();++it)
+		{
+			std::cout<<it->first<<"\n";
+		}
+	}
+
+	geo_list()
+	{
+	}
+
+	~geo_list()
+	{
+	}
+};
+#endif

+ 2 - 5
monkey_car/monkeycar_area.cpp

@@ -34,6 +34,7 @@ void monkey_area::on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double
 	//人卡走下面的业务
 	if(type != 1)
 	  return;
+
 	uint64_t cid = type<<32|card_id;
 	const std::shared_ptr<card_location_base> card = card_list::instance()->get(cid);
 
@@ -108,15 +109,11 @@ void monkey_area::on_card_move(uint32_t cardid,const st_coord & st,uint64_t type
 	}
 	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);
@@ -131,7 +128,7 @@ void monkey_area::on_card_move(uint32_t cardid,const st_coord & st,uint64_t type
 	else
 	{
 		std::shared_ptr<monkey_bus> bus=bus_[speed>0?0:1];
-		if(bus->test_get_on(mp,speed))
+		if(bus->test_get_on(speed))
 		{
 			log_info("monkeycar get onid:%d",cardid);
 			bus->getOnTheBus(mp,bus);	

+ 10 - 7
monkey_car/monkeycar_bus.cpp

@@ -49,12 +49,15 @@ void monkey_bus::adjust_monkeyperson_distance()
 	}
 }
 
-bool monkey_bus::test_get_on(std::shared_ptr<monkey_person> mp,double speed)
+bool monkey_bus::test_get_on(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)
+	double s=speed>0?speed:-speed;
+	double ms=m_speed>0?m_speed:-m_speed;
+	log_info("monkeycar test_get_on:%.2f,%.2f",s,ms);
+	log_info("monkeycar ...........:%.2f,%.2f",ms*ON_BUS_SPEED_LIMIT,ms*ON_BUS_SPEED_MAX_LIMIT);
+	if (s >= ms*ON_BUS_SPEED_LIMIT && s < ms*ON_BUS_SPEED_MAX_LIMIT)
 	{
-		//debug_print_syslog(0,"[lemon the second choice GetOn]cardId:%s",mp->getCardId().c_str());
+		log_info("monkeycar test_get_on_true:%.2f,%.2f",speed,m_speed);
 		return true;
 	}
 	return false;
@@ -63,13 +66,13 @@ bool monkey_bus::test_get_on(std::shared_ptr<monkey_person> mp,double speed)
 bool monkey_bus::test_get_off(std::shared_ptr<monkey_person> mp,double speed)
 {
 	bool ret = false;
+	double s=speed>0?speed:-speed;
+	double ms=m_speed>0?m_speed:-m_speed;
 	ret = (speed > ZERO_ ? NEGTIVE_DIRECTION:POSTIVE_DIRECTION) == m_direct ;
 	if (ret)
 	{
-		if (abs(speed) < abs(m_speed) * OFF_BUS_SPEED_LIMIT)
+		if (s < ms*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;

+ 1 - 1
monkey_car/monkeycar_bus.h

@@ -37,7 +37,7 @@ struct monkey_bus
 		m_thread->join();
 	}
 
-	bool test_get_on(std::shared_ptr<monkey_person> mp,double speed);
+	bool test_get_on(double speed);
 	
 	/********************************/
 	/*Decide whether to get off or not*/

+ 8 - 1
net-service.cpp

@@ -14,7 +14,7 @@
 #include "worker.h"
 #include "tdoa_sync.h"
 #include "net-service.h"
-
+#include "ant.h"
 net_service::net_service()
 {
 	m_loc_worker=nullptr;
@@ -43,6 +43,13 @@ void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t
 			{
 				uint32_t site_id;
 				is>>site_id>>skip(12);
+				const auto sit_=sit_list::instance()->get(site_id);
+				if(sit_==nullptr)
+				{
+				  log_error("site is not exist...");
+				  break;
+				}
+				sit_->set_client(clt);
 				struct timeval tv;
 				gettimeofday(&tv,NULL);
 				uint64_t t = tv.tv_sec*1000 + tv.tv_usec/1000;

+ 1 - 4
select_tool.h

@@ -799,7 +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);
+			//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))
@@ -928,11 +928,9 @@ struct smooth_tool_person_1:smooth_tool
 			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;
@@ -943,7 +941,6 @@ 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
 			{

+ 151 - 0
tqueue.h

@@ -0,0 +1,151 @@
+#ifndef INCLUDED_QUEUE_H
+#define INCLUDED_QUEUE_H
+
+
+#include <mutex>
+#include <condition_variable>
+#include <vector>
+#include <iostream>
+template<class T>
+class BoundedQueue 
+{
+	public:
+		BoundedQueue(int max) 
+			: m_begin(0)
+			  , m_end(0)
+			  , m_buffered(0)
+			  , m_circularBuf(max) 
+	{
+	}
+	BoundedQueue(const BoundedQueue & rhs)=delete;
+	BoundedQueue& operator=(const BoundedQueue & rhs)=delete;
+	void put(const T &m) 
+	{
+		std::unique_lock<std::mutex> lk(m_monitor);
+		m_notFull.wait(lk,[this]{return m_buffered<m_circularBuf.size();});
+
+		purePut(m);
+		lk.unlock();
+		m_notEmpty.notify_one();
+	}
+
+	void putHead(const T& m)
+	{
+		std::unique_lock<std::mutex> lk(m_monitor);
+		m_notFull.wait(lk,[this]{return m_buffered<m_circularBuf.size();});
+
+		purePutHead(m);
+		lk.unlock();
+		m_notEmpty.notify_one();
+	}
+
+	bool tryPut(const T &m)
+	{
+		std::unique_lock<std::mutex> lk(m_monitor);
+		if(m_buffered >= m_circularBuf.size())
+		{
+			return false;
+		}
+		else
+		{
+			purePut(m);
+			lk.unlock();
+			m_notEmpty.notify_one();
+			return true;
+		}
+	}
+
+	bool tryPutHead(const T &m)
+	{
+		std::unique_lock<std::mutex> lk(m_monitor);
+		if(m_buffered >= m_circularBuf.size())
+		{
+			return false;
+		}
+		else
+		{
+			purePutHead(m);
+			lk.unlock();
+			m_notEmpty.notify_one();
+			return true;
+		}
+	}
+
+	void get(T &m) 
+	{
+		std::unique_lock<std::mutex> lk(m_monitor);
+		m_notEmpty.wait(lk,[this]{return m_buffered>0;});
+		pureGet(m);
+		lk.unlock();
+		m_notFull.notify_all();
+	}
+
+	bool get(T &m, int wait)
+	{
+		bool signaled = false;
+		std::unique_lock<std::mutex> lk(m_monitor);
+		signaled = m_notEmpty.wait_for(lk,std::chrono::seconds(wait),[this]{return m_buffered>0;});
+		if(!signaled)
+		  return false;
+
+		pureGet(m);
+		lk.unlock();
+		m_notFull.notify_all();
+		return true;
+	}
+
+	bool tryGet(T &m)
+	{
+		std::unique_lock<std::mutex> lk(m_monitor);
+		if(m_buffered <= 0)
+		{
+			return false;
+		}
+		else
+		{
+			pureGet(m);
+			lk.unlock();
+			m_notFull.notify_all();
+			return true;
+		}
+	}
+
+	size_t size() 
+	{
+		return m_buffered;
+	}
+private:
+	inline void purePut(const T& m)
+	{
+		m_circularBuf[m_end] = m;
+		m_end = (m_end+1) % m_circularBuf.size();
+		++m_buffered;
+	}
+	inline void purePutHead(const T& m)
+	{
+		if(m_begin == 0)
+		  m_begin = m_circularBuf.size();
+		m_begin--;
+		m_circularBuf[m_begin] = m;
+		++m_buffered;
+	}
+	inline void pureGet(T& m)
+	{
+		m = m_circularBuf[m_begin];
+		// clear the memory
+		T t;
+		std::swap(m_circularBuf[m_begin], t);
+		m_begin = (m_begin+1) % m_circularBuf.size();
+		--m_buffered;
+	}
+private:
+	size_t m_begin;
+	size_t m_end;
+	size_t m_buffered;
+	std::vector<T> m_circularBuf;
+	std::condition_variable m_notFull;
+	std::condition_variable m_notEmpty;
+	std::mutex m_monitor;
+};
+#endif // INCLUDED_QUEUE_H
+