Browse Source

Merge branch 'master' of http://local.beijingyongan.com:3000/linux-dev/ya-serv

chensongchao 6 years ago
parent
commit
81a9765dbd

+ 1 - 1
Makefile.am

@@ -44,7 +44,7 @@ client_SOURCES=client.cpp message_file.cpp
 client_CPPFLAGS=${AM_CPPFLAGS}
 client_LDFLAGS=${AM_LDFLAGS}  -L. -lzlog
 
-test_SOURCES=test.cpp base64.cpp
+test_SOURCES=test.cpp base64.cpp point.cpp
 test_CPPFLAGS=${AM_CPPFLAGS}
 test_LDFLAGS=${AM_LDFLAGS}  -L. -lzlog -lrt
 

+ 308 - 115
ant.cpp

@@ -6,6 +6,7 @@
 #include "event.h"
 #include "tool_time.h"
 #include "area.h"
+#include "card_path.h"
 //template<> std::shared_ptr<sit_list> single_base<sit_list, int, std::shared_ptr<site>>::m_instance=std::make_shared<sit_list>();
 
 int site::index()const
@@ -16,8 +17,8 @@ int site::index()const
 site::site(int id)
 	:m_algo(0)
 	,m_num_dims(0)
-    ,m_id(id)
-    ,m_path_empty(true)
+	,m_id(id)
+	,m_path_empty(true)
 {
 	m_time=time(0);
 }
@@ -27,143 +28,331 @@ const algo_config&site::config()const
 	return g_config[index()];
 }
 
-bool visit_site_status::visit(std::shared_ptr<site> s)
+void ant::set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator itm)
 {
-	time_t now=time(0);
-	int diff = now-s->m_time;
-	event_tool::instance()->handle_event(OT_DEVICE_READER,ET_READER_ERROR,s->m_id,READER_TIMEOUT,diff,[diff](){return diff>READER_TIMEOUT;});
-	return true;
+	auto it=itm;
+	for(int i=0;i<2 && it!=v_line.end();++it,++i)
+		m_path[0][i]=*it;
+
+	it=itm-1;
+	for(int i=0;i<2 && it>=v_line.begin();--it,++i)
+	{
+		m_path[1][i]=*it;
+		m_path[1][i].swap_point();
+	}
+
+	for(const auto&p:m_path)
+	{
+		log_info("site-path: %s",p.to_str().c_str());
+	}
 }
 
-void sit_list::read_ant_path(int id)
+void ant::set_path(const std::vector<line_v>&v_line_)
 {
-     std::string sql = "SELECT reader_id,tof_flag,b_x,b_y,b_z,e_x,e_y,e_z,spacing_ratio FROM dat_reader_path_tof_n";
+	std::vector<line_v> vl(v_line_);
+	vl.reserve(vl.size()+2);
+	//找到距离天线最近的端点
+	auto min_it=vl.begin();
+	double dist=10;
+	for(auto it=vl.begin();it!=vl.end();it++)
+	{
+		double d=it->as_line().dist(*this);
+		if(d<dist)
+		{
+			dist=d;
+			min_it=it;
+		}
+	}
+
+	if(min_it==vl.end())
+	{
+		log_error("分站路径距离分站太远site_id=%d",m_id);
+		return;
+	}
 
-     if(-1 == id)
-     {
-         sql.append(";");
-     }
-     else
-     {
-         sql.append(" AND reader_id=");
-         sql.append(std::to_string(id));
-         sql.append(";");
+	if(abs(min_it->v[0].dist(*this)-dist)<1)
+	{
+		set_path(vl,min_it);
+	}
+	else if(abs(min_it->v[1].dist(*this)-dist)<1)
+	{
+		set_path(vl,min_it+1);
+	}
+	else
+	{
+		point proj=min_it->projection(*this);
+		vl.insert(min_it+1,line_v(proj,min_it->v[1]));
+		min_it->set_point(1,proj);
+
+		if(min_it->v[0].z)//slope ..555
+		{
+			double slope=min_it->v[0].z;
+			double len_a=min_it->v[0].dist((min_it+1)->v[1]);
+			double len_0=slope*min_it->length()/len_a;
+			double len_1=slope-len_0;
+			
+			min_it->v[0].z=min_it->v[1].z=len_0;
+			(min_it+1)->v[0].z=(min_it+1)->v[1].z=len_1;
+		}
+
+		set_path(vl,min_it+1);
+	}
+}
 
-         std_debug("修改path sql=%s", sql.c_str());
-         log_info("修改path sql=%s", sql.c_str());
-     }
+void site::set_path(const std::vector<line_v>&v_line)
+{
+	if(v_line.empty())
+		return;
+
+	const auto&find_line=[](const point&pt,int first,std::vector<line_v>&vl){
+		for(auto it=vl.begin();it!=vl.end();it++)
+		{
+			if(it->v[first].dist(pt)<1)
+				return it;
+			if(it->v[first?0:1].dist(pt)<1)
+			{
+				point p=it->v[0];
+				it->v[0]=it->v[1];
+				it->v[1]=p;
+				return it;
+			}
+		}
+
+		return vl.end();
+	};
+	
+	//构造一个首尾相连的结构
+
+	std::vector<line_v> vl(v_line.begin()+1,v_line.end());
+	std::vector<line_v> target(v_line.begin(),v_line.begin()+1);
+#if 0
+	target[0][0].z=target[0][1].z=slope[0];
+	for(int i=0,c=vl.size();i<c;i++)
+		vl[i][0].z=vl[i][1].z=slope[i+1];
+#endif
 
-     std::string Error;
-     YADB::CDBResultSet DBRes;
-     sDBConnPool.Query(sql.c_str(),DBRes,Error);
-     int nCount = DBRes.GetRecordCount( Error );
-     if (nCount < 1)
-     {
-         log_error("修改path失败,数据库中找不到(dat_reader_path_tof_n): 分站id=%d", id);
-         return ;
-     }
+	for(;;)
+	{
+		auto it=find_line(target.back().v[1],0,vl);
+		if(it==vl.end())
+			break;
 
-    log_info( "read_ant_path. The record count=%ld\n", nCount );
-     while ( DBRes.GetNextRecod(Error) )
-     {
-         int reader_id  = 0;
-         DBRes.GetField( "reader_id",reader_id, Error );
+		target.insert(target.end(),it,it+1);
+		vl.erase(it);
+	}
 
-         auto site_ptr=sit_list::instance()->get(reader_id);
-         if(nullptr==site_ptr)
-             continue;
+	for(;;)
+	{
+		auto it=find_line(target.front().v[0],1,vl);
+		if(it==vl.end())
+			break;
 
-         int pid=0;
-         DBRes.GetField( "tof_flag",pid, Error );
+		target.insert(target.begin(),it,it+1);
+		vl.erase(it);
+	}
 
-         double b_x= 0;
-         DBRes.GetField( "b_x",b_x, Error );
+	log_info("初始化分站路径:site_id=%d",m_id);
 
-         double b_y= 0;
-         DBRes.GetField( "b_y",b_y, Error );
+	for(auto&a:m_ant)
+	{
+		a.set_path(target);
+	}
+	m_path_empty= !m_ant[0][0].valid() && !m_ant[0][1].valid() ;
+}
 
-         double b_z= 0;
-         DBRes.GetField( "b_z",b_z, Error );
+std::vector<point> ant::getsol(const double &dist) const
+{
+	std::vector<point> v;
+	for(const auto & p : m_path)
+	{
+		if(!p.valid())
+			continue;
+
+		point pt;
+		double d  = dist;
+
+		if(dist <= p.m_line[0].length())
+		{
+			d += d*p.m_line[0][0].z;
+			pt = point(p.m_line[0][0].x + d*p.m_line[0].cos() , p.m_line[0][0].y + d*p.m_line[0].sin());
+		}
+		else if(p.m_line[1].length()>0)
+		{
+			d -= p.m_line[0].length()*(1-d*p.m_line[0][1].z);
+			d += d*p.m_line[1][0].z;
+
+			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());
+		}
+		else
+		{
+			continue;
+		}
+		v.push_back(pt);
+	}
+	return std::move(v);
+}
 
-         double e_x= 0;
-         DBRes.GetField( "e_x",e_x, Error );
+bool visit_site_status::visit(std::shared_ptr<site> s)
+{
+	time_t now=time(0);
+	int diff = now-s->m_time;
+	event_tool::instance()->handle_event(OT_DEVICE_READER,ET_READER_ERROR,s->m_id,READER_TIMEOUT,diff,diff>READER_TIMEOUT);
+	return true;
+}
 
-         double e_y= 0;
-         DBRes.GetField( "e_y",e_y, Error );
+void sit_list::read_ant_path(int id)
+{
+	std::string sql = "SELECT reader_id,tof_flag,b_x,b_y,b_z,e_x,e_y,e_z,spacing_ratio FROM dat_reader_path_tof_n";
 
-         double e_z= 0;
-         DBRes.GetField( "e_z",e_z, Error );
+	std::map<int,std::vector<line_v>> map_path;
 
-         double spacing_ratio = 0;
-         DBRes.GetField( "spacing_ratio",spacing_ratio, Error );
-         log_info("ant_path:%d,%.2f,%.2f,%.2f,%.2f",reader_id,b_x,b_y,e_x,e_y);
-         point p1(b_x,-b_y);
-         point p2(e_x,-e_y);
-         auto &sit_ = *site_ptr;
-         if(-1!=id)//清空path
-         {
-            sit_.clear_path();
-            log_info( "修改path 清空path,分站id=%d\n", id );
-         }
+	if(-1 == id)
+	{
+		sql.append(";");
+	}
+	else
+	{
+		sql.append(" where reader_id=");
+		sql.append(std::to_string(id));
+		sql.append(";");
+
+		std_debug("修改path sql=%s", sql.c_str());
+		log_info("修改path sql=%s", sql.c_str());
+	}
+
+	std::string Error;
+	YADB::CDBResultSet DBRes;
+	sDBConnPool.Query(sql.c_str(),DBRes,Error);
+	int nCount = DBRes.GetRecordCount( Error );
+	if (nCount < 1)
+	{
+		log_error("修改path失败,数据库中找不到(dat_reader_path_tof_n): 分站id=%d", id);
+		return ;
+	}
 
-         if(pid == 0)
-         {
-             line_v l(p1,p2);
-             {
-                 point px = l.line::projection(sit_);
-                 sit_.set(px);
-                 for(int i=0;i<2;i++)
-                 {
-                     path p;
-                     p.m_slope[0] = spacing_ratio;
-                     p.m_line[0] = line_v(px,l[i]);
-                     sit_.m_ant[i].m_path.push_back(p);
-                 }
-             }
-         }
-         else
-         {
-             ant &a = pid<0?sit_.m_ant[0]:sit_.m_ant[1];
-             if(a.m_path.size()!=0)
-             {
-                 path &p = a.m_path[0];
-                 p.m_line[abs(pid)-1] = line_v(p1,p2);
-                 p.m_slope[abs(pid)-1] = spacing_ratio;
-             }
-             else
-             {
-                 path p;
-                 p.m_line[abs(pid)-1] = line_v(p1,p2);
-                 p.m_slope[abs(pid)-1] = spacing_ratio;
-                 a.m_path.push_back(p);
-             }
-             if(abs(pid)==1)
-                 sit_.set(p1);
-         }
-     }
+	log_info( "read_ant_path. The record count=%ld\n", nCount );
+	while ( DBRes.GetNextRecod(Error) )
+	{
+		int reader_id  = 0;
+		DBRes.GetField( "reader_id",reader_id, Error );
+
+		auto site_ptr=sit_list::instance()->get(reader_id);
+		if(nullptr==site_ptr)
+			continue;
+
+		int pid=0;
+		DBRes.GetField( "tof_flag",pid, Error );
+
+		double b_x= 0;
+		DBRes.GetField( "b_x",b_x, Error );
+
+		double b_y= 0;
+		DBRes.GetField( "b_y",b_y, Error );
+
+		double b_z= 0;
+		DBRes.GetField( "b_z",b_z, Error );
+
+		double e_x= 0;
+		DBRes.GetField( "e_x",e_x, Error );
+
+		double e_y= 0;
+		DBRes.GetField( "e_y",e_y, Error );
+
+		double e_z= 0;
+		DBRes.GetField( "e_z",e_z, Error );
+
+		double spacing_ratio = 0;
+		DBRes.GetField( "spacing_ratio",spacing_ratio, Error );
+		log_info("ant_path:%d,%.2f,%.2f,%.2f,%.2f",reader_id,b_x,b_y,e_x,e_y);
+		point p1(b_x,-b_y, spacing_ratio);
+		point p2(e_x,-e_y, spacing_ratio);
+
+		map_path.insert(std::make_pair(reader_id,std::vector<line_v>()));
+		map_path.find(reader_id)->second.push_back(line_v(p1,p2));
+#if 0
+
+		auto &sit_ = *site_ptr;
+		if(-1!=id)//清空path
+		{
+			sit_.clear_path();
+			log_info( "修改path 清空path,分站id=%d\n", id );
+		}
+
+		if(pid == 0)
+		{
+			line_v l(p1,p2);
+			{
+				point px = l.line::projection(sit_);
+				sit_.set(px);
+				for(int i=0;i<2;i++)
+				{
+					path p;
+					p.m_slope[0] = spacing_ratio;
+					p.m_line[0] = line_v(px,l[i]);
+					sit_.m_ant[i].m_path.push_back(p);
+				}
+			}
+		}
+		else
+		{
+			ant &a = pid<0?sit_.m_ant[0]:sit_.m_ant[1];
+			if(a.m_path.size()!=0)
+			{
+				path &p = a.m_path[0];
+				p.m_line[abs(pid)-1] = line_v(p1,p2);
+				p.m_slope[abs(pid)-1] = spacing_ratio;
+			}
+			else
+			{
+				path p;
+				p.m_line[abs(pid)-1] = line_v(p1,p2);
+				p.m_slope[abs(pid)-1] = spacing_ratio;
+				a.m_path.push_back(p);
+			}
+			if(abs(pid)==1)
+				sit_.set(p1);
+		}
+#endif
+	}
 
-     if(-1==id)
-     {
-         for(auto&_s:sit_list::instance()->m_map)
-         {
-             _s.second->deal_path();
-         }
-     }
-     else
-     {
-         auto sit_ptr=sit_list::instance()->get(id);
-         if(sit_ptr)
-         {
-             sit_ptr->deal_path();
-             log_info( "修改path成功,分站id=%d\n", id );
-         }
-     }
+#if 0
+	if(-1==id)
+	{
+		for(auto&_s:sit_list::instance()->m_map)
+		{
+			_s.second->deal_path();
+		}
+	}
+	else
+	{
+		auto sit_ptr=sit_list::instance()->get(id);
+		if(sit_ptr)
+		{
+			sit_ptr->deal_path();
+			log_info( "修改path成功,分站id=%d\n", id );
+		}
+	}
+#endif
+
+	for(auto&vl:map_path)
+	{
+		auto sit_ptr=sit_list::instance()->get(vl.first);
+		if(!sit_ptr)
+		{
+			log_error("定义了分站路径,但是没有定义分站:%d",vl.first);
+			continue;
+		}
+
+		sit_ptr->set_path(vl.second);
+	}
+
+	card_path::init();
 }
 
 void sit_list::init_site(int id)
 {
      std::string sql = "SELECT reader_id, reader_type_id, dat_reader.map_id, \
-             area_id, device_type_id, dimension, dat_map.scale\
+             area_id, device_type_id, dimension, dat_map.scale,need_power_alarm\
              FROM dat_reader, dat_map where \
              dat_reader.map_id=dat_map.map_id and state=0";
 
@@ -223,9 +412,13 @@ void sit_list::init_site(int id)
          double scale= 0;
          DBRes.GetField( "scale",scale, Error );
 
+         int power_alarm  = 0;
+         DBRes.GetField( "need_power_alarm",power_alarm, Error );
+
          site_ptr->m_reader_type_id = reader_type_id;
          site_ptr->m_map_id = map_id;
          site_ptr->m_area_id = area_id;
+         site_ptr->m_power_check_enable=power_alarm;
 
          site_ptr->m_device_type_id = device_type_id;
 

+ 19 - 78
ant.h

@@ -23,22 +23,20 @@ class area;
 struct path
 {
     std::array<line_v,2>	m_line;
-    std::array<double,2>    m_slope;
     path()
     {
-        for(auto &d:m_slope)
-            d=0;
     }
+
     std::string to_str() const
     {
         std::stringstream ss;
         for(int i=0;i<2;i++)
         {
-            ss<<"line:" <<m_line[i].to_string()<<"slope:"<<m_slope[i]<< " cos:"<<m_line[i].cos()<<" sin:"<<m_line[i].sin()<<" | ";
+            ss<<"line:" <<m_line[i].to_string()<<"slope:"<<m_line[i][0].z<< " cos:"<<m_line[i].cos()<<" sin:"<<m_line[i].sin()<<" | ";
         }
         return ss.str();
     }
-    bool vaild() const
+    bool valid() const
     {
         return !m_line[0].empty();
     }
@@ -50,7 +48,6 @@ struct path
     {
         return m_line[i];
     }
-
 };
 //?
 struct algo_config
@@ -64,49 +61,27 @@ struct algo_config
 //
 struct ant :point
 {
+    std::array<path,2> m_path;
     int m_id;
-    std::vector<path> m_path;
+
     path & operator[](int i)
     {
         return m_path[i];
     }
+
     const path & operator[](int i) const
     {
         return m_path[i];
     }
+
     size_t size() const
     {
         return m_path.size();
     }
-    std::vector<point> getsol(const double &dist) const
-    {
-        std::vector<point> v;
-        for(const auto & p : m_path)
-        {
-            double d  = dist;
-            if(p.vaild())
-            {
-                point pt;
-                if(dist <= p.m_line[0].length() || (dist > p.m_line[0].length() && p.m_line[1].empty()))
-                {
-                    d += d*p.m_slope[0];
-                    pt = point(p.m_line[0][0].x + d*p.m_line[0].cos() , p.m_line[0][0].y + d*p.m_line[0].sin());
-                }
-                else
-                {
-                    d -= p.m_line[0].length();
-                    d += d*p.m_slope[1];
-                    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);
-            }
-            //else
-             //   std_error("ant[%d]::getsol empty path..",);
-        }
-        return std::move(v);
-    }
 
+	void set_path(const std::vector<line_v>&v_line);
+	void set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator it);
+    std::vector<point> getsol(const double &dist) const;
 };
 
 struct site:point,std::enable_shared_from_this<site>
@@ -234,13 +209,7 @@ struct site:point,std::enable_shared_from_this<site>
             m_ant_dist_cnt_new = 0;
         }
     }
-    void swap()
-    {
-        auto v0 =  m_ant[0].m_path;
-        auto v1 =  m_ant[1].m_path;
-        std::copy (std::begin(v0),std::end(v0),std::back_inserter(m_ant[1].m_path));
-        std::copy (std::begin(v1),std::end(v1),std::back_inserter(m_ant[0].m_path));
-    }
+
     double ant_dist()const
     {
         return m_ant[0].dist(m_ant[1]);
@@ -260,10 +229,10 @@ struct site:point,std::enable_shared_from_this<site>
     {
         std::stringstream ss;
         ss<<"site_id:"<<m_id<<"x:"<<x<<" y: "<<y<<" scale:"<<m_scale;
-        for(const auto a:m_ant)
+        for(const auto&a:m_ant)
         {
             ss<<"<";
-            for(const auto p:a.m_path)
+            for(const auto&p:a.m_path)
             {
                 ss<<"{"<<p.to_str()<<"}";
             }
@@ -280,6 +249,7 @@ struct site:point,std::enable_shared_from_this<site>
         return m_ant[0].m_path[i].m_line[0][1];
     }
 
+	void set_path(const std::vector<line_v>&v_line);
     std::vector<point> solving(int ant_id, double dist)const
     {
         const ant &a = m_ant[ant_id];
@@ -297,11 +267,13 @@ struct site:point,std::enable_shared_from_this<site>
         }
         return std::move(a.getsol(dist));
     }
-    ant operator[](int i)
+
+    ant&operator[](int i)
     {
         return m_ant[i];
     }
-    const ant operator[](int i) const
+
+    const ant&operator[](int i) const
     {
         return m_ant[i];
     }
@@ -321,42 +293,11 @@ struct site:point,std::enable_shared_from_this<site>
         set( (m_ant[0].x+m_ant[1].x)/2,(m_ant[0].y+m_ant[1].y)/2);
     }
 
-    void deal_path()
-    {
-        if(m_id==-1)
-            return;
-        swap();
-        if((path(0).empty() && path(1).empty()))
-            return;
-        m_path_empty=false;
-
-        for(auto &a:m_ant)
-        for(auto &p:a.m_path)
-        {
-            if(!p.m_line[0].empty())
-            {
-                point px = p.m_line[0].line::projection(a);
-                p.m_line[0]=line_v(px,p.m_line[0][1]);
-            }
-        }
-        //std_info("%s",sit_ptr->to_string().c_str());
-        log_info("%s",to_string().c_str());
-        //std_info("%f----%f",sit_ptr->x,sit_ptr->y);
-    }
-
     void delete_antenna(int antidx)
     {
-        m_ant[antidx].m_path.clear();
-        m_ant[antidx].m_id=0;
-        point pt;
-        m_ant[antidx].set(pt);
+        m_ant[antidx].set(point(0,0));
     }
 
-    void clear_path()
-    {
-        m_ant[0].m_path.clear();
-        m_ant[1].m_path.clear();
-    }
 /*
 
 	处理分站供电状态,交流供电时,ac_down=false,直流供电时,ac_down=true

+ 147 - 132
area.cpp

@@ -29,8 +29,8 @@
 
 struct underground_area:area
 {
-    underground_area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type)
-        :area(id,limit_count_person,limit_time_person,scale,mapid,type)
+    underground_area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t biz_type)
+        :area(id,limit_count_person,limit_time_person,scale,mapid,biz_type)
 	{
 	}
     virtual bool in_area(const std::shared_ptr<site>&s,const std::shared_ptr<card_location_base>&c, const point & p,int &sarid)
@@ -41,8 +41,8 @@ struct underground_area:area
 
 struct special_area:area
 {
-    special_area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type)
-        :area(id,limit_count_person,limit_time_person,scale,mapid,type)
+    special_area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t biz_type)
+        :area(id,limit_count_person,limit_time_person,scale,mapid,biz_type)
 	{}
     virtual bool in_area(const std::shared_ptr<site>&s,const std::shared_ptr<card_location_base>&c, const point & p,int &sarid)
 	{
@@ -66,9 +66,9 @@ struct special_area:area
 
 };
 
-area::area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type)
+area::area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t b_type)
      :m_id(id)
-     ,m_area_type(type)
+     ,m_biz_type(b_type)
      ,m_limit_person_min(limit_time_person)
      ,m_limit_person_count(limit_count_person)
      ,m_scale(scale)
@@ -78,7 +78,7 @@ area::area(int id,int limit_count_person, int limit_time_person,double scale,int
      ,m_person_show_count(0)
      ,m_vehicle_show_count(0)
     {
-		m_area_business_list=area_business::get_instance_list(m_area_type,id);
+		m_area_business_list=area_business::get_instance_list(m_biz_type,id);
 		m_event_person_count = false;
 		m_event_vehicle_count = false;
 		m_event_person_show_count = false;
@@ -106,9 +106,10 @@ void area::change_business(uint32_t new_bits)
 {
 	worker*w=worker::instance();
 
-	uint32_t del=((m_area_type^new_bits)|m_area_type)^m_area_type;
-	uint32_t add=((m_area_type^new_bits)|new_bits)^new_bits;
-    log_info("change_area_business:%d,b_type:%d,area_type:%d [del:%d, add:%d]",m_id,new_bits,m_area_type,del,add);
+	uint32_t del=((m_biz_type^new_bits)|m_biz_type)^m_biz_type;
+	uint32_t add=((m_biz_type^new_bits)|new_bits)^new_bits;
+    log_info("change_area_business:area_id:%d,b_type:%d,area_type:%d [del:%d, add:%d]",m_id,new_bits,m_biz_type,del,add);
+
 	if(del==0 && add==0)
 		return;
 
@@ -134,6 +135,8 @@ void area::change_business(uint32_t new_bits)
 
 	add_frozen_count(w->num_thread()+1);
 
+	this->m_biz_type=new_bits;
+
 	w->broadcast(t);
 }
 
@@ -291,7 +294,7 @@ void area_list::init_monkeycar_area(int id)
             da->m_default_speed = monkeycar_speed;
             da->m_point = init_path(monkeycar_coor,area_id);
             std::shared_ptr<area> ap = std::make_shared<monkey_area>(da,area_id,over_count_person, over_time_person,scale,map_id,b_type);
-            ap->update(over_count_person, over_time_person,scale,map_id,b_type, over_count_vehicle,over_time_vehicle);
+            ap->update(over_count_person, over_time_person,scale,map_id,over_count_vehicle,over_time_vehicle);
 
             ap->m_bound=init_path(path,area_id);
             for(const auto &p : ap->m_bound)
@@ -303,22 +306,31 @@ void area_list::init_monkeycar_area(int id)
         }
         else
         {
-			//这里后续需要把猴车得信息传递过去
-            std::shared_ptr<db_area>  da = std::make_shared<db_area>();
-            da->m_default_speed = monkeycar_speed;
-            da->m_point = init_path(monkeycar_coor,area_id);
-			std::shared_ptr<area> ap = std::make_shared<monkey_area>(da,area_id,over_count_person, over_time_person,scale,map_id,b_type);
-			if(auto area_=area_list::instance()->get(id))
-				area_=ap;
-			else
-				area_list::instance()->add(area_id,ap);
 
-            ap->m_bound=init_path(path,area_id);
-            ap->update(over_count_person, over_time_person,scale,map_id,b_type, over_count_vehicle,over_time_vehicle);
-            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);
+			auto tmp_ptr = area_list::instance()->get(id);
+			bool newobj=false;
+
+			if(!tmp_ptr)
+			{
+				std::shared_ptr<db_area>  da = std::make_shared<db_area>();
+				da->m_default_speed = monkeycar_speed;
+				da->m_point = init_path(monkeycar_coor,area_id);
+				tmp_ptr=std::make_shared<monkey_area>(da,area_id,over_count_person, over_time_person,scale,map_id,b_type);
+
+				newobj=true;
+			}
+
+			tmp_ptr->m_bound=init_path(path,area_id);
+            tmp_ptr->update(over_count_person, over_time_person,scale,map_id, over_count_vehicle,over_time_vehicle);
+
+			if(newobj)
+			{
+				area_list::instance()->add(id, tmp_ptr);
+			}
+			else
+			{
+				tmp_ptr->change_business(b_type);
+			}
 
             log_info("基础数据 monkeycar area增加或修改区域成功:区域id:%d,over_count_person:%d over_time_person:%d,\
                      scale:%.2f,map_id:%d,area_type_id:%d,over_count_vehicle:%d,over_time_vehicle:%d",
@@ -352,134 +364,137 @@ std::shared_ptr<area>  area_list::create(int type,int id,int limit_count_person,
 }
 void area_list::init_from_db(int id/*=-1*/)
 {
-    std::string 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,business_type, a.is_work_area\
-            FROM dat_area a,dat_map b\
-            where a.map_id = b.map_id and  area_id not in \
-			  (select monkeycar_base_info_id from dat_monkeycar_base_info)";
-
-    if(-1 == id)
-    {
-        sql.append(";");
-    }
-    else
-    {
-        sql.append(" AND a.area_id=");
-        sql.append(std::to_string(id));
-        sql.append(";");
+	do{
+		std::string 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,business_type, a.is_work_area\
+						   FROM dat_area a,dat_map b\
+						   where a.map_id = b.map_id and  area_id not in \
+						   (select monkeycar_base_info_id from dat_monkeycar_base_info)";
+
+		if(-1 == id)
+		{
+			sql.append(";");
+		}
+		else
+		{
+			sql.append(" AND a.area_id=");
+			sql.append(std::to_string(id));
+			sql.append(";");
 
-        log_info("基础数据 增加或修改区域 sql=%s", sql.c_str());
-    }
+			log_info("基础数据 增加或修改区域 sql=%s", sql.c_str());
+		}
 
-    std::string Error;
-    YADB::CDBResultSet DBRes;
-    sDBConnPool.Query(sql.c_str(),DBRes,Error);
-    int nCount = DBRes.GetRecordCount( Error );
-    if (nCount < 1)
-    {
-        log_error("基础数据 增加或修改失败,数据库中找不到: area_id=%d:%s", id,sql.c_str());
-        return ;
-    }
+		std::string Error;
+		YADB::CDBResultSet DBRes;
+		sDBConnPool.Query(sql.c_str(),DBRes,Error);
+		int nCount = DBRes.GetRecordCount( Error );
+		if (nCount < 1)
+		{
+			log_error("基础数据 增加或修改失败,数据库中找不到: area_id=%d:%s", id,sql.c_str());
+			break;
+		}
 
-    std::unordered_map<int,std::shared_ptr<area>> map;
-    while ( DBRes.GetNextRecod(Error) )
-    {
-        int area_id  = 0;
-        DBRes.GetField( "area_id",area_id, Error );
+		std::unordered_map<int,std::shared_ptr<area>> map;
+		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 );
+			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 );
+			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_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_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_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 );
+			int over_time_vehicle = 0;
+			DBRes.GetField( "over_time_vehicle",over_time_vehicle, Error );
 
-        std::string over_speed_vehicle;
-        DBRes.GetField( "over_speed_vehicle",over_speed_vehicle, Error );
+			std::string over_speed_vehicle;
+			DBRes.GetField( "over_speed_vehicle",over_speed_vehicle, Error );
 
-        std::string path;
-        DBRes.GetField( "path",path, Error );
+			std::string path;
+			DBRes.GetField( "path",path, Error );
 
-        double scale = 0;
-        DBRes.GetField( "scale",scale, Error );
+			double scale = 0;
+			DBRes.GetField( "scale",scale, Error );
 
-		uint32_t b_type =0;
-        DBRes.GetField( "business_type",b_type, Error );
+			uint32_t b_type =0;
+			DBRes.GetField( "business_type",b_type, Error );
 
-        int is_work_area = 0;
-        DBRes.GetField( "is_work_area",is_work_area, Error );
+			int is_work_area = 0;
+			DBRes.GetField( "is_work_area",is_work_area, Error );
 
-        log_info("init_area : id:%d,path:%s..speed:%s",area_id, path.c_str(),over_speed_vehicle.c_str());
-        std::map<int,double> map_;
-        auto vp=init_path(over_speed_vehicle,area_id);
-        for(const auto &v:vp)
-            map_.insert({v.x,v.y});
-        if(-1 == id)
-        {
-            std::shared_ptr<area> ap = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type);
-            ap->m_limit_vehicle_min = over_time_vehicle;
-            ap->m_limit_vehicle_count = over_count_vehicle;
-            ap->m_speed=std::move(map_);
-            ap->m_is_work_area = is_work_area;
+			log_info("init_area : id:%d,path:%s..speed:%s",area_id, path.c_str(),over_speed_vehicle.c_str());
+			std::map<int,double> map_;
+			auto vp=init_path(over_speed_vehicle,area_id);
+			for(const auto &v:vp)
+				map_.insert({v.x,v.y});
+			if(-1 == id)
+			{
+				std::shared_ptr<area> ap = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type);
+				ap->m_limit_vehicle_min = over_time_vehicle;
+				ap->m_limit_vehicle_count = over_count_vehicle;
+				ap->m_speed=std::move(map_);
+				ap->m_is_work_area = is_work_area;
+
+				ap->m_bound=init_path(path,area_id);
+				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});
+			}
+			else
+			{
+				auto tmp_ptr = area_list::instance()->get(id);
+				bool newobj=false;
 
-            ap->m_bound=init_path(path,area_id);
-            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});
-        }
-        else
-        {
-            auto tmp_ptr = area_list::instance()->get(id);
-			bool newobj=false;
-			
-            if(!tmp_ptr)
-            {
-				tmp_ptr = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type);
-				newobj=true;
-            }
+				if(!tmp_ptr)
+				{
+					tmp_ptr = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type);
+					newobj=true;
+				}
 
-            tmp_ptr->update(over_count_person, over_time_person,scale,map_id,b_type, over_count_vehicle,over_time_vehicle);
-            tmp_ptr->m_speed=std::move(map_);
-            tmp_ptr->m_bound=init_path(path,area_id);
-            tmp_ptr->m_is_work_area = is_work_area;
+				tmp_ptr->update(over_count_person, over_time_person,scale,map_id, over_count_vehicle,over_time_vehicle);
+				tmp_ptr->m_speed=std::move(map_);
+				tmp_ptr->m_bound=init_path(path,area_id);
+				tmp_ptr->m_is_work_area = is_work_area;
 
-            for(const auto &p : tmp_ptr->m_bound)
-                log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
+				for(const auto &p : tmp_ptr->m_bound)
+					log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
 
-            log_info("基础数据 增加或修改区域成功:区域id:%d,over_count_person:%d over_time_person:%d,scale:%.2f,map_id:%d\
-                     ,area_type_id:%d,over_count_vehicle:%d,over_time_vehicle:%d,b_type:%d",
-                     id,over_count_person, over_time_person,scale,map_id,area_type_id,
-                     over_count_vehicle,over_time_vehicle,b_type);
+				log_info("基础数据 增加或修改区域成功:区域id:%d,over_count_person:%d over_time_person:%d,scale:%.2f,map_id:%d\
+						,area_type_id:%d,over_count_vehicle:%d,over_time_vehicle:%d",
+						id,over_count_person, over_time_person,scale,map_id,area_type_id,
+						over_count_vehicle,over_time_vehicle);
 
-			if(newobj)
-			{
-				area_list::instance()->add(id, tmp_ptr);
-			}
-			else
-			{
-				tmp_ptr->change_business(b_type);
+				if(newobj)
+				{
+					area_list::instance()->add(id, tmp_ptr);
+				}
+				else
+				{
+					tmp_ptr->change_business(b_type);
+				}
 			}
-        }
-    }
+		}
 
-    if(-1 == id)
-    {
-        log_info( "init_area. The record count=%d\n", nCount );
-        area_list::instance()->add(map);
-    }
-    init_monkeycar_area(id);
+		if(-1 == id)
+		{
+			log_info( "init_area. The record count=%d\n", nCount );
+			area_list::instance()->add(map);
+		}
+	}while(0);
+
+	init_monkeycar_area(id);
 }
 
 std::vector<point> area_list::init_path(std::string &str_0,int area_id)

+ 23 - 11
area.h

@@ -8,6 +8,7 @@
 #include <point.h>
 #include "common.h"
 #include <write-copy.h>
+#include <ant.h>
 #include <set>
 #include <map>
 
@@ -23,7 +24,7 @@ struct site;
 */
 struct area
 {
-    area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type);
+    area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t b_type);
 
   	virtual void on_hover(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c);
 	virtual	void on_enter(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c);
@@ -50,10 +51,8 @@ struct area
     virtual ~area()
     {}
     double get_speed(int vehicle_category_id) {return m_speed[vehicle_category_id];}
-    void  update(int limit_count_person, int limit_time_person,double scale,int32_t mapid,
-                     int32_t type,int limit_count_vehicle, int limit_time_vehicle)
+    void  update(int limit_count_person, int limit_time_person,double scale,int32_t mapid, int limit_count_vehicle, int limit_time_vehicle)
     {
-        m_area_type=type;
         m_limit_person_min=limit_time_person;
         m_limit_person_count=limit_count_person;
         m_scale=scale;
@@ -103,7 +102,7 @@ public:
 		7:禁区[进入时长]
 		8:猴车区域
 	*/
-    int m_area_type;
+    int    m_biz_type=0;
 
 	//人卡超时及超员数量(阀值)
     int m_limit_person_min;
@@ -208,24 +207,37 @@ struct area_hover
 struct site;
 struct task;
 struct area_tool
-{
+{ 
+private:
+	int m_mapid=-1;
+public:
+
+	int get_mapid()const
+	{
+		return m_mapid;
+	}
+
+	double m_scale=2.0;
 	//卡所在的所有area的列表,以id排序小->大
 	std::vector<std::shared_ptr<area_hover>> m_hover_list;
 
 	//推送卡位置时需要推送的所在区域id列表
 	std::map<int,std::tuple<int,int,int,double,uint64_t>> m_area_info;
-	int m_mapid=-1;
-	double m_scale=2.0;
     std::shared_ptr<site> m_site=nullptr;
     void clear()
     {
         m_area_info.clear();
     }
-    void set(const std::shared_ptr<site>& s)
+
+    void set_site(const std::shared_ptr<site>& s)
     {
-        if(m_site != s)
-          m_site=s;
+		if(s == nullptr || m_site == s)
+			return;
+
+        m_site=s;
+		m_mapid=m_site->m_map_id;
     }
+
 	void on_change_business(const std::shared_ptr<card_location_base>& c, const task&t);
 	void on_point(const std::shared_ptr<card_location_base>& c,const point&pt);
     void on_leave(const std::shared_ptr<card_location_base>& c);

+ 5 - 4
card.cpp

@@ -198,7 +198,7 @@ void card_list::load_his_card_postion_vehicle()
             {
                 auto area_hover_ptr = std::make_shared<area_hover>(sit_ptr->get_area(),*card_ptr);
                 area_tool->m_hover_list.push_back(area_hover_ptr);
-                area_tool->set(sit_ptr);
+                area_tool->set_site(sit_ptr);
             }
 
             //解析area_info
@@ -310,7 +310,7 @@ void card_list::load_his_card_postion_staff()
             {
                 auto area_hover_ptr = std::make_shared<area_hover>(sit_ptr->get_area(),*card_ptr);
                 area_tool->m_hover_list.push_back(area_hover_ptr);
-                area_tool->set(sit_ptr);
+                area_tool->set_site(sit_ptr);
             }
 
             //解析area_info
@@ -353,8 +353,9 @@ void card_list::on_message(zloop<task*> *loop,const message_locinfo&loc,bool is_
 		log_warn("数据库中未定义该卡的信息,card_id=%d, card_type=%d,cardid:%lld",loc.m_card_id,loc.m_card_type,cardid);
 		return;
 	}
-	logn_info(3,"card_message:site=%d,ant=%d,type=%lu,card=%d,ct=%d,tof=%lld,rav=%02X,acc=%02X,rssi=%d,stamp=%llu",
-			loc.m_site_id,loc.m_ant_id,loc.m_card_type,loc.m_card_id,loc.m_card_ct,loc.m_tof,loc.m_rav,loc.m_acc,loc.m_rssi,loc.m_time_stamp);
+	double dist_tof=loc.m_tof*15.65*2.996*1e-4;
+	logn_info(3,"card_message:site=%d,ant=%d,type=%lu,card=%d,ct=%d,tof=%lld(%.2lfm),rav=%02X,acc=%02X,rssi=%d,stamp=%llu",
+			loc.m_site_id,loc.m_ant_id,loc.m_card_type,loc.m_card_id,loc.m_card_ct,loc.m_tof,dist_tof,loc.m_rav,loc.m_acc,loc.m_rssi,loc.m_time_stamp);
 
 	c->on_message(loop,loc,is_history);
 }

+ 9 - 4
card_base.cpp

@@ -47,9 +47,13 @@ void card_location_base::on_location(const std::vector<point>&vp,const std::vect
 
 		double acc = lm[0].m_acc;
         m_acc = lm[0].m_acc;
-		log_info("useful:card_id:%d,ct:%d,timestamp:%llu, loc_point,x:%f,y:%f acc:%.2f",m_id,m_ct,m_time,x,y,acc);
+		log_info("useful:type:%d,card_id:%d,ct:%d,timestamp:%llu, loc_point,x:%f,y:%f acc:%.2f",m_type,m_id,m_ct,m_time,x,y,acc);
 		do_business(lm.front().m_sit, pt, acc);
 	}
+	else
+	{
+		log_warn("坐标不可用:type:%d,card_id:%d,ct:%d,x:%f,y:%f",m_type,m_id,m_ct,pt.x,pt.y);
+	}
 }
 
 void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history)
@@ -63,11 +67,13 @@ void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&lo
 		return;
 	}
 
+
+	auto area_tool=get_area_tool();
+	area_tool->set_site(site_ptr);
+
 	if(site_ptr->is_up_site())
 	{
         log_info("%d被井上分站[%d]收到",m_id,site_ptr->id());
-		auto area_tool=get_area_tool();
-		area_tool->set(site_ptr);
 		area_tool->on_point(shared_from_this(),point(1,1));
 
 		this->site_hover(loc.m_site_id);
@@ -149,7 +155,6 @@ void  card_location_base::clear()
 {
 //	uint16_t m_display;			//1显示0不显示,往前端推送
     m_speed=0;			//速度
-    m_is_attendance=0;	//井上井下状态  0初始状态 1 井上 2 井下
     m_stat=0;			//运动静止状态
     //m_ct;				//ct
     m_time=0;			//时间戳

+ 8 - 2
card_base.h

@@ -3,6 +3,7 @@
 
 #include <vector>
 #include <memory>
+#include <atomic>
 #include "point.h"
 #include "common.h"
 
@@ -35,7 +36,6 @@ struct card:point
 		,m_type(type)
 		,m_display(dis)
 		,m_speed(0)
-		,m_is_attendance(0)
 		,m_stat(0)
 		,m_ct(0)
 		,m_time(0)
@@ -50,7 +50,6 @@ struct card:point
 	uint64_t m_type;			//类型
 	uint16_t m_display;			//1显示0不显示,往前端推送
 	double   m_speed;			//速度
-	int      m_is_attendance;	//井上井下状态  0初始状态 1 井上 2 井下
 	int		 m_stat;			//运动静止状态
 	uint16_t m_ct;				//ct
     uint64_t m_time;			//时间戳 ms
@@ -70,6 +69,13 @@ struct card_location_base:card,std::enable_shared_from_this<card_location_base>
 	std::unique_ptr<card_message_handle> m_message_handle;
 	std::unique_ptr<location_card> m_his_location_card;
 
+	std::atomic<int> m_upmine_flag{0};
+
+	void inc_upmine_flag()
+	{
+		++m_upmine_flag;
+	}
+
     card_location_base()=default;
     card_location_base(const std::string&type,uint32_t id,uint16_t dis,int16_t t,int32_t,int32_t,uint32_t );
 

+ 2 - 3
card_car.cpp

@@ -35,7 +35,6 @@ void car::set_area_info(int mapid,double scale,int areaid,uint64_t t,int type)
 void car::do_business(const std::shared_ptr<site>&site,const point &pt,double acc)
 {
 	m_acc=acc;
-    m_area_tool->set(site);
 	m_area_tool->on_point(shared_from_this(),pt);
 	m_timeval=m_time;
 	m_mine_tool->on_point(m_id, m_type, m_vehicle_category_id);
@@ -58,7 +57,7 @@ void car::handle_three_rates(const point &pt)
 	//const auto lm = m_area_tool->getLandmark();
 //	cp.enter_time = std::get<0>(lm)*1000;
 //	cp.area_id = std::get<3>(lm);
-	cp.map_id = m_area_tool->m_mapid;
+	cp.map_id = m_area_tool->get_mapid();
 	cp.vibration=m_acc;
 	put_three_rates(cp);
 }
@@ -85,7 +84,7 @@ void car::make_package()
 	YA::_CARD_POS_ cp;
 	loc_point pt = getSmoothPoint();
 	cp.area_info=m_area_tool->m_area_info;	
-	cp.map_id =m_area_tool->m_mapid;
+	cp.map_id =m_area_tool->get_mapid();
 
 	int32_t biz_stat=m_biz_stat;
 	cp.biz_stat=biz_stat;

+ 11 - 24
card_path.cpp

@@ -822,33 +822,20 @@ struct graph
 	}
 };
 
-
-std::atomic<int> g_init_flag(0);
-graph g_graph;
-
+safe_shared_ptr<graph> g_graph(std::make_shared<graph>());
 }//namespace
 
 void card_path::init()
 {
-    //Ensure only ont thread can init path.
-	int expect=0;
-	if(g_init_flag.compare_exchange_strong(expect,1))
-	{
-		handle_path hp;
-		//std::vector<base_path> opath=init_path(sites,v_list);
-		sit_list::instance()->accept(hp);
-		std::vector<base_path> opath=init_path(hp.ret,hp.v);
-		g_graph.init(hp.v,opath);
+	std::shared_ptr<graph> local_graph=std::make_shared<graph>();
 
-		++g_init_flag;
-	}
-    //if != 2 then wait here until init over.
-	while(g_init_flag.load()!=2)
-	{
-		std::this_thread::sleep_for (std::chrono::seconds(1));
-	}
-}
+	handle_path hp;
+	sit_list::instance()->accept(hp);
+	std::vector<base_path> opath=init_path(hp.ret,hp.v);
+	local_graph->init(hp.v,opath);
 
+	g_graph.set(local_graph);
+}
 
 card_path&card_path::inst()
 {
@@ -858,17 +845,17 @@ card_path&card_path::inst()
 
 std::vector<point> card_path::find_path(const point&from,const point&to)const
 {
-	return g_graph.find(from,to);
+	return g_graph.get()->find(from,to);
 }
 
 bool card_path::is_at_path(const point&pt)const
 {
-	return g_graph.is_at_path(pt);
+	return g_graph.get()->is_at_path(pt);
 }
 
 std::vector<line_v>  card_path::find_possible_path(const point&from,double dist) const
 {
-	return std::move(g_graph.find_possible_path(from,dist));
+	return std::move(g_graph.get()->find_possible_path(from,dist));
 }
 
 #ifdef __DEBUG__

+ 7 - 2
card_person.cpp

@@ -90,7 +90,6 @@ std::shared_ptr<mine_tool> person::get_mine_tool()
 
 void person::do_business(const std::shared_ptr<site>&site,const point &pt,double acc)
 {
-    m_area_tool->set(site);
 	m_area_tool->on_point(shared_from_this(),pt);
 	m_timeval=m_time;
 	handle_three_rates(pt);
@@ -122,7 +121,7 @@ void person::on_timer()
 	point pt = getSmoothPoint(_time);
     
 	cp.area_info=m_area_tool->m_area_info;	
-	cp.map_id =m_area_tool->m_mapid;
+	cp.map_id =m_area_tool->get_mapid();
 
 	cp.biz_stat = m_biz_stat;
 	cp.down_time = m_mine_tool->get_down_time();
@@ -141,6 +140,12 @@ void person::on_timer()
 		m_area_tool->on_point(shared_from_this(),pt);
 		m_biz_stat=get_stat();
 	}
+
+	if(m_upmine_flag.load())
+	{
+		m_upmine_flag=0;
+		m_area_tool->on_leave(shared_from_this());
+	}
 }
 
 point person::getSmoothPoint(uint64_t& t)

+ 3 - 28
client.cpp

@@ -3,44 +3,19 @@
 #include "log.h"
 #include "message_file.h"
 
-time_t site_timestamp(const char*time)
-{
-	//秒、分、时、天、周、月、年, 脑残的设计
-
-	struct tm t={0};
-
-	t.tm_sec=time[0];
-	t.tm_min=time[1];
-	t.tm_hour=time[2];
-	t.tm_mday=time[3];
-	t.tm_mon=time[5]-1;
-	t.tm_year=time[6]+100;
-
-	return mktime(&t);
-}
 
 int main()
 {
+	message_file  mf(stdin);
+
 	unsigned char b[2048];
 	char m[2048];
-	message_file mf(stdin);
 	uint64_t time=0;
 	int len;
 
 	while((len=mf.get_line(&time,(char*)b,sizeof(b),m))>0)
 	{
-		if(!((b[2]==0x84) && (b[3]==0x3b)))
-			continue;
-
-		int diff=abs(time/1000-site_timestamp((const char*)&b[10]));
-		if(diff>300)
-		{
-			printf("%d:%s\n",diff,m);
-		}
-		else
-		{
-//			printf ("%d\n",diff);
-		}
+		mf.put_line(stdout,time,(char*)b,len);
 	}
 
 	return 0;

+ 1 - 1
event.cpp

@@ -218,7 +218,7 @@ std::shared_ptr<ya_event> card_event::on_message(EVENT_TYPE et,uint64_t id,bool
         {
             auto lm = area_info_map.begin()->second;
             event_ptr->m_area_id = std::get<0>(lm);
-            event_ptr->m_map_id = card_ptr->get_area_tool()->m_mapid;
+            event_ptr->m_map_id = card_ptr->get_area_tool()->get_mapid();
         }
     }
     return event_ptr;

+ 18 - 10
forbid_staff_down_mine.cpp

@@ -3,14 +3,13 @@
 #include "tool_time.h"
 #include "db_api/CDBSingletonDefine.h"
 
-void forbid_staff_down_mine::init_forbid_staff(int id /* = -1*/)
+void forbid_staff_down_mine::init_forbid_staff(int id /* = -1*/,int etype)
 {
-    std::string sql = "select id,staff_id,start_time,end_time,status,oper_time,lastupdate from rt_person_forbid_down_mine ";
+    std::string sql = "select id,staff_id,start_time,end_time,status,oper_time,lastupdate from rt_person_forbid_down_mine where ";
     if (id != -1)
-        sql += " where id = " + std::to_string(id) + ";";
+        sql += " id = " + std::to_string(id) + ";";
     else
-        sql += " where status = 1 or end_time > now() ;";
-
+        sql += "status = 1 and end_time > now();";
     std::string Error;
     YADB::CDBResultSet DBRes;
     sDBConnPool.Query(sql.c_str(),DBRes,Error);
@@ -36,6 +35,8 @@ void forbid_staff_down_mine::init_forbid_staff(int id /* = -1*/)
         DBRes.GetField("oper_time", create_time, Error);
         std::string update_time;
         DBRes.GetField("lastupdate", update_time, Error);
+        time_t stime = tool_time::to_time(start_time);
+        time_t etime = tool_time::to_time(end_time);
         std::shared_ptr<SForbidStaffList> s = forbid_staff_down_mine::instance()->get(staff_id);
         //如果存在则查找更新。查找不到则插入
         if (s)
@@ -46,9 +47,9 @@ void forbid_staff_down_mine::init_forbid_staff(int id /* = -1*/)
                 //找到记录则更新,停止.找不到,则继续往下走
                 if (info.db_id == key)
                 {
-                    f = true;
-                    info.start_time = tool_time::to_time(start_time);
-                    info.end_time = tool_time::to_time(end_time);
+                    f=true;
+                    info.start_time =stime;
+                    info.end_time =etime;
                     info.state = state;
                     log_info("Check Forbid_staff_down_mine DBID:%d Staff:%d State:%d Time:%s -> %s . "
                                 ,key,staff_id,state,start_time.c_str(),end_time.c_str());
@@ -57,6 +58,13 @@ void forbid_staff_down_mine::init_forbid_staff(int id /* = -1*/)
                 if (f) continue;
             }
             if(f)continue;
+            //ET_UPDATE
+            if(id !=-1 && etype ==2)
+            {
+                time_t now= time(0);
+                if(state!=1 || now>etime)
+                    continue;
+            }
         }
         else
         {
@@ -67,8 +75,8 @@ void forbid_staff_down_mine::init_forbid_staff(int id /* = -1*/)
         SForbidStaffInfo info ;
         info.staff_id = staff_id;
         info.db_id = key;
-        info.start_time = tool_time::to_time(start_time);
-        info.end_time = tool_time::to_time(end_time);
+        info.start_time = stime;
+        info.end_time =etime;
         info.state = state;
 
         log_info("Init Forbid_staff_down_mine DBID:%d Staff:%d State:%d Time:%s -> %s . "

+ 1 - 1
forbid_staff_down_mine.h

@@ -39,7 +39,7 @@ struct forbid_staff_down_mine
 {
 public:
     // 根据数据库中的自增长id
-    void init_forbid_staff(int id = -1);
+    void init_forbid_staff(int id = -1,int etype=-1);
     // 根据数据库中的自增长id
     void del_forbid_data(int id,int staff_id);
 

+ 24 - 6
line.h

@@ -135,9 +135,17 @@ struct line_v:line//线段
 	{
 		v[0]=p0;
 		v[1]=p1;
-        setpoint();
+        recalc();
 	}
-    void setpoint()
+	void swap_point()
+	{
+		point tmp=v[0];
+		v[0]=v[1];
+		v[1]=tmp;
+		recalc();
+	}
+
+    void recalc()
     {
         double dx = v[1].x - v[0].x;
         double dy = v[1].y - v[0].y;
@@ -146,10 +154,15 @@ struct line_v:line//线段
         double sin = dy/r;
         angle = point(cos,sin);
     }
-    double cos() const
-    {return angle.x;}
-    double sin() const
-    {return angle.y;}
+
+	void set_point(int i,const point&p)
+	{
+		v[i]=p;
+		recalc();
+	}
+
+    double cos() const {return angle.x;}
+    double sin() const {return angle.y;}
 	point&operator[](int i) { return v[i]; }
 	const point&operator[](int i)const { return v[i]; }
 
@@ -232,6 +245,11 @@ struct line_v:line//线段
 
 		return v.dist(p);
 	}
+
+	const line &as_line()const
+	{
+		return *this;
+	}
 };
 #endif
 

+ 0 - 3
main.cpp

@@ -182,9 +182,6 @@ int main(int argc ,char * argv[])
     Init_Setting is;
     is.init();
 
-	card_path::init();
-//	test_find_path(point(4600,-75),point(4727,-90));
-
     module_mgr::start();
     web_connect::start_beatheart_monitor();
     atexit(&cleanup);

+ 4 - 3
message.cpp

@@ -5,8 +5,8 @@
 
 void message_locinfo::zero_this()
 {
-	m_time_stamp=
-	m_site_id=
+//	m_time_stamp=
+//	m_site_id=
 	m_site_time=
 
 	m_card_type=
@@ -68,7 +68,8 @@ void message_locinfo::load(zistream&is,bool tdoa)
 	uint16_t sp1=0,sp2=0;
 	is>>sp1>>sp2;
 	m_rssi=10*log10(1.*sp1*(1<<17)/pow(sp2-64.,2))-121.74;
-	log_info("timestamp=%llu,type:%d,card_id:%d,site:%d,ct:%d,status:%d,acc=%d,tof=%llu,ant_id:%d,spq=%d",m_time_stamp,m_card_type,m_card_id,m_site_id,m_card_ct,m_batty_status,m_acc,m_tof,m_ant_id,m_rssi);
+	log_info("timestamp=%llu,type:%d,card_id:%d,site:%d,ct:%d,status:%d,acc=%d,tof=%llu,ant_id:%d,spq=%d",
+			m_time_stamp,m_card_type,m_card_id,m_site_id,m_card_ct,m_batty_status,m_acc,m_tof,m_ant_id,m_rssi);
 }
 
 void message_tdoasync::zero_this()

+ 1 - 1
message.h

@@ -32,7 +32,7 @@ struct message_locinfo:task
 	uint8_t  m_acc;
 	uint8_t  m_ant_id;
 	uint16_t m_sync_ct;
-	uint16_t m_rssi;
+	int16_t  m_rssi;
 
 	void zero_this();
     void load(zistream&is,bool tdoa);

+ 50 - 4
message_file.cpp

@@ -6,8 +6,9 @@
 #include <memory.h>
 #include <time.h>
 #include <stdint.h>
-#include "message_file.h"
 
+#include "message_file.h"
+#include "zstream.h"
 namespace
 {
 char decode[256];
@@ -100,19 +101,24 @@ inline const char* now(char*date_str,uint64_t time)
 	return date_str;
 }
 
-int message_file::put_line(uint64_t time,char*buf,int buflen)
+int message_file::put_line(FILE*fp,uint64_t time,char*buf,int buflen)
 {
 	char b[8192];
 
-	printf("[%s]\n",now(b,time));
+	fprintf(fp,"[%s]\n",now(b,time));
 	int n=0,t;
 	for(int i=0;i<buflen;i++)
 	{
 		t=(int)(unsigned char)buf[i];
 		n+=sprintf(&b[n],"%s ",encode[t]);
+
+		if((i+1)%32 == 0)
+		{
+			n+=sprintf(&b[n],"\n");
+		}
 	}
 
-	printf("%s\n",b);
+	fprintf(fp,"%s\n",b);
 
 	return 0;
 }
@@ -175,3 +181,43 @@ int message_file::get_line(uint64_t*time,char*buf,int buflen,char*m)
 	return o-buf;
 }
 
+int message_file::get_card_message(uint32_t card_id,char*b)
+{
+	int len;
+	char buf[2048];
+	uint64_t time=0;
+
+	int ppos=0;
+	while((len=get_line(&time,buf,sizeof(buf)))>0)
+	{
+		zistream is(buf,len-2);
+		uint16_t cmd;
+		is>>skip(2)>>cmd;
+
+		if(cmd!=0x843b && cmd!=0x753b)
+			continue;
+
+		is>>skip(16);
+
+		while(!is.eof())
+		{
+			uint32_t cid;
+			uint32_t gpos=is.pos();
+			is>>skip(1)>>cid;
+
+			if(cid!=card_id) continue;
+
+			if(ppos==0) memcpy(b,buf,ppos=20); 
+			memcpy(&b[ppos],&buf[gpos],20);
+			ppos+=20;
+		}
+
+		if(ppos==0)  continue;
+
+		ppos+=2;
+	}
+
+	return -1;
+}
+
+

+ 4 - 2
message_file.h

@@ -8,7 +8,7 @@ struct message_file
 private:
 	bool  m_owner;
 	FILE* m_file;
-	char  m_last_line[256];
+	char  m_last_line[1024];
 	message_file(const message_file&);
 public:
 
@@ -19,7 +19,9 @@ public:
 	
 	int get_line(uint64_t*time,char*buf,int buflen,char*msg);
 	int get_line(uint64_t*time,char*buf,int buflen);
-	int put_line(uint64_t time,char*buf,int buflen);
+	int put_line(FILE*fp,uint64_t time,char*buf,int buflen);
+	int get_card_message(uint32_t card_id,char*b);
+
 };
 
 #endif

+ 14 - 4
module_service/area_business_count_checker.cpp

@@ -50,13 +50,18 @@ void area_business_count_checker::on_enter(const std::shared_ptr<area_hover>&a,
 		return ;
 	if (c->is_person())
 	{
+        int limit_val=a->m_area->m_limit_person_count;
+        int aid=a->m_area->id();
+        if(limit_val<=0)
+        {
+            log_warn("on_enter_area_id:%d,limit_person_count is 0.so should not run area_business_count_checker...",aid);
+            return;
+        }
 		a->m_area->m_person_count ++ ;
         if(c->m_display)
 		    a->m_area->m_person_show_count ++ ;
         int pc=a->m_area->m_person_count.load();
         int pc_=a->m_area->m_person_show_count.load();
-        int limit_val=a->m_area->m_limit_person_count;
-        int aid=a->m_area->id();
 	    EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_PERSON : EVENT_TYPE::ET_AREA_OVER_COUNT_PERSON ;
         if(pc>limit_val){
             lock();
@@ -73,13 +78,18 @@ void area_business_count_checker::on_enter(const std::shared_ptr<area_hover>&a,
 	}
 	else if (c->is_vehicle())
 	{
+        int limit_val=a->m_area->m_limit_vehicle_count;
+        int aid=a->m_area->id();
+        if(limit_val<=0)
+        {
+            log_warn("on_enter_area_id:%d,limit_vehicle_count is 0.so should not run area_business_count_checker...",aid);
+            return;
+        }
 		a->m_area->m_vehicle_count ++ ;
         if(c->m_display)
 		    a->m_area->m_vehicle_show_count ++ ;
         int vc=a->m_area->m_vehicle_count.load();
         int vc_=a->m_area->m_vehicle_show_count.load();
-        int limit_val=a->m_area->m_limit_vehicle_count;
-        int aid=a->m_area->id();
 		EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_VEHICLE : EVENT_TYPE::ET_AREA_OVER_COUNT_VEHICLE ;
         if(vc>limit_val){
             lock();

+ 1 - 1
module_service/area_business_person_attendance.cpp

@@ -110,7 +110,7 @@ void area_business_person_attendance::handle_up_mine(sio::message::ptr const& da
         if(card_ptr && STATUS_LOST == card_ptr->m_biz_stat)
         {
             log_info("handle_up_card:%s 手工升井,处理",s_card_id.c_str());
-            module_meta_date_changed::clear_card(card_ptr);
+            card_ptr->inc_upmine_flag();
         }
         else
             log_warn("handle_up_card:%s,手动升井的卡找不到,或者该卡不在盲区",s_card_id.c_str());

+ 9 - 2
module_service/area_business_person_dwell_checker.cpp

@@ -22,17 +22,23 @@ void area_business_person_dwell_checker::on_enter(const std::shared_ptr<area_hov
 							const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr)
 {
     log_info("area_business_person_dwell_checker::on_enter : In Area=%d Card = %d  ",a->m_area->id(),c->m_id);
+
+	if( a->m_area->m_limit_person_min == 0 )
+	{
+		log_warn("区域area_id=%d超时值设置为0,不会检查超时。",a->m_area->m_id);
+	}
 }
 
 //判断是否超时
 void area_business_person_dwell_checker::on_hover(const std::shared_ptr<area_hover>&a,
 							const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr)
 {
-    if(!c->is_person()||a->m_enter_time==0)
+    if(!c->is_person()||a->m_enter_time==0||a->m_area->m_limit_person_min==0)
       return;
 
 	int limit_val = a->m_area->m_limit_person_min*60;
 	int cur_val = ( tool_time::now_to_seconds() - a->m_enter_time / 1000);
+
 	EVENT_TYPE evType = a->m_area->is_mine() ? EVENT_TYPE::ET_CARD_OVER_TIME_PERSON : EVENT_TYPE::ET_CARD_AREA_OVER_TIME_PERSON;
 	if (limit_val < cur_val)
     {
@@ -48,8 +54,9 @@ void area_business_person_dwell_checker::on_hover(const std::shared_ptr<area_hov
 void area_business_person_dwell_checker::on_leave(const std::shared_ptr<area_hover>&a,
 							const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr)
 {
-    if(!c->is_person())
+    if(!c->is_person()||a->m_enter_time==0||a->m_area->m_limit_person_min==0)
       return;
+
     EVENT_TYPE evType = a->m_area->is_mine() ? EVENT_TYPE::ET_CARD_OVER_TIME_PERSON:EVENT_TYPE::ET_CARD_AREA_OVER_TIME_PERSON;
     if(c->get_event_flag(evType))
     {

+ 9 - 11
module_service/module_meta_date_changed.cpp

@@ -26,14 +26,13 @@ void module_meta_date_changed::accept(sio::message::ptr const& data)
         return;
     }
 
-
     std::string szParam = "0";
     tool_map::try_get_value(szParam,JSON_KEY_ID,data);
-    int id = std::stoi(szParam);
 
     std::string op_type="";
     tool_map::try_get_value(op_type, JSON_KEY_OP_TYPE, data);
 
+    log_info("web发来数据:JSON_CMD_VALUE_META_DATA_CHANGED,%s---%s",szParam.c_str(),op_type.c_str());
     if(!szParam.empty() && !op_type.empty())
     {
         EDIT_TYPE_ID edit_type_id;
@@ -63,26 +62,32 @@ void module_meta_date_changed::accept(sio::message::ptr const& data)
         }
         else if(JSON_KEY_NAME_READER == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_reader(id, edit_type_id);
         }
         else if ("antenna" == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_antenna(id,edit_type_id);
         }
         else if(JSON_KEY_NAME_PATH == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_path(id, edit_type_id);
         }
         else if(JSON_KEY_NAME_MAP == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_map(id, edit_type_id);
         }
         else if (JSON_KEY_NAME_LIGHT == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_light(id,edit_type_id);///待实现
         }
         else if ("lights_group" == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_lights_group(id,edit_type_id);///待实现
         }
         else if (JSON_KEY_NAME_FORBID_PERSON_DOWN_MINE == name)
@@ -231,14 +236,7 @@ void module_meta_date_changed::deal_call_edit_path(int id, EDIT_TYPE_ID edit_typ
     }
     else if(ET_DELETE == edit_type_id)
     {
-        auto sit_ptr = sit_list::instance()->get(id);
-        if(sit_ptr)
-        {
-            sit_ptr->clear_path();
-        }
-
-        log_info("path删除成功,分站id=%d", id);
-        std_debug("path删除成功,分站id=%d", id);
+        sit_list::instance()->read_ant_path(id);
     }
 }
 
@@ -299,7 +297,7 @@ void module_meta_date_changed::deal_call_edit_forbid_person_down_mine(const std:
 
     if(ET_INSERT == edit_type_id || ET_UPDATE == edit_type_id)
     {
-        forbid_staff_down_mine::instance()->init_forbid_staff(db_id);
+        forbid_staff_down_mine::instance()->init_forbid_staff(db_id,edit_type_id);
     }
     else if(ET_DELETE == edit_type_id)
     {

+ 2 - 2
net-service.cpp

@@ -80,7 +80,7 @@ void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t
 						char timebuf[64];
 						unsigned char*t=(unsigned char*)data+10;
 						sprintf(timebuf,"%d-%d %d:%d:%d",*(t+4)+1,*(t+3),*(t+2),*(t+1),*(t+0));
-						logn_info(1,"分站数据信息: net=%s,sid=%d,tm=%s,sct=%d",clt->name().c_str(),site_id,timebuf,((*t-2)<<8)|*(t-1));
+						logn_info(1,"分站数据信息:%s net=%s,sid=%d,tm=%s,sct=%d",(power&1)==0?"true":"false",clt->name().c_str(),site_id,timebuf,((*t-2)<<8)|*(t-1));
 					}
 
 					site_ptr->set_client(clt);
@@ -96,9 +96,9 @@ void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t
 						index++;
 						task*t=task::alloc<message_locinfo>();
 						message_locinfo&m=t->body<message_locinfo>();
-						m.load(is,false);
 						m.m_site_id=site_id;
 						m.m_time_stamp=tstamp;
+						m.load(is,false);
 						//t_site->m_site_data = 0;
 
 						t->m_cmd_code=cmd;

+ 2 - 5
select_tool.cpp

@@ -158,7 +158,7 @@ bool select_point_object::select_solution(const std::vector<point> &vp,const sit
        std::array<solpoint,4> res;
        for(int i=0;i<2;i++)
 	   {
-           int x = i==0?3:2;
+           int x = i+2;
 			double d=vp[i].dist(vp[x]);
 			if(d<sit->ant_dist()*3)
 			{
@@ -198,10 +198,7 @@ bool select_point_object::select_solution(const std::vector<point> &vp,const sit
 	{
 		m_d(0).set_cl(0);
 
-		//printf("out of path:t=%ld,sit=%d,ct=%d,"
-		//"tof1=%d,tof2=%d,pt=(%f,%f)\n",
-		//m_d(0).m_time, m_d(0).m_sid,m_d(0).m_ct,
-		//m_d(0).m_tof[0], m_d(0).m_tof[1], pt.x, pt.y);
+		log_info("out of path:t=%ld,sit=%d,card_id=%d,ct=%d,tof1=%d,tof2=%d,pt=(%f,%f)\n", m_d(0).m_time, m_d(0).m_sid,m_d(0).m_cid,m_d(0).m_ct, m_d(0).m_tof[0], m_d(0).m_tof[1], pt.x, pt.y);
 		return false;
 	}
 

+ 158 - 290
test.cpp

@@ -1,366 +1,234 @@
 #include <unistd.h>
 #include <limits.h>
 #include <stdlib.h>
-#include <stdint.h>
 
-#include <clock.h>
-#include <zio.h>
-#include <log.h>
-#include <zloop.h>
+#include <stdint.h>
 
-#include "base64.h"
-#include "io_buf.h"
+#include <sstream>
+#include <vector>
+#include <line.h>
 
-struct web_client_http:ev::io
+#define log_error printf
+#define log_info printf
+struct path
 {
-	in_buff m_buff;
-	int m_data_len=-1;
-	int m_mask_pos=-1;
-	int m_data_pos=-1;
-	int m_fd,m_status;
-
-	web_client_http()
-		:m_buff(8192)
-	{
-		m_fd=-1;
-	}
-
-	int connect_tcp(const char*ip,int port)
-	{
-		int fd=zio::build_stream();
-		if(zio::connect(fd,ip,port))
-		{
-			zio::close(fd);
-			return m_fd=-1;
-		}
-
-		zio::setiobuf(fd,16<<10,16<<10);
-		zio::setblocking(fd,false);
-
-		return m_fd=fd;
-	}
+    std::array<line_v,2>	m_line;
+    path()
+    {
+    }
+
+    std::string to_str() const
+    {
+        std::stringstream ss;
+        for(int i=0;i<2;i++)
+        {
+            ss<<"line:" <<m_line[i].to_string()<<"slope:"<<m_line[i][0].z<< " cos:"<<m_line[i].cos()<<" sin:"<<m_line[i].sin()<<" | ";
+        }
+        return ss.str();
+    }
+    bool vaild() const
+    {
+        return !m_line[0].empty();
+    }
+    line_v & operator[](int i)
+    {
+        return m_line[i];
+    }
+    const line_v & operator[](int i) const
+    {
+        return m_line[i];
+    }
+};
 
-	void ws_reset()
-	{
-		if(m_data_pos+m_data_len>0)
-		{
-			m_buff.free(m_data_len+m_data_pos);
-		}
+struct tant:point
+{
+int m_id;
 
-		m_data_len=-1;
-		m_mask_pos=-1;
-		m_data_pos=-1;
-	}
+void set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator itm)
+{
+	std::array<path,2> m_path;
 
-	bool ws_fin()const
-	{
-		return (m_buff[0]&0x80) != 0;
-	}
+	auto 
 
-	bool ws_more()const
-	{
-		return (m_buff[0]&0xF) ==0 ;
-	}
+	it=itm;
+	for(int i=0;i<2 && it!=v_line.end();++it,++i)
+		m_path[0][i]=*it;
 
-	bool ws_text()const
+	it=itm-1;
+	for(int i=0;i<2 && it>=v_line.begin();--it,++i)
 	{
-		return (m_buff[0]&0xF) ==1 ;
+		m_path[1][i]=*it;
+		m_path[1][i].swap_point();
 	}
 
-	bool ws_bin()const
+	for(auto&p:m_path)
 	{
-		return (m_buff[0]&0xF) ==2 ;
+		log_info("%s\n",p.to_str().c_str());
 	}
+}
 
-	bool ws_ping()const
+void set_path2(const std::vector<line_v>&v_line_)
+{
+	std::vector<line_v> vl(v_line_);
+	vl.reserve(vl.size()+2);
+	//找到距离天线最近的端点
+	auto min_it=vl.begin();
+	double dist=10;
+	for(auto it=vl.begin();it!=vl.end();it++)
 	{
-		return (m_buff[0]&0xF) ==9 ;
+		double d=it->as_line().dist(*this);
+		if(d<dist)
+		{
+			dist=d;
+			min_it=it;
+		}
 	}
 
-	bool ws_pong()const
+	if(min_it==vl.end())
 	{
-		return (m_buff[0]&0xF) ==10 ;
+		log_error("分站路径距离分站太远site_id=%d",m_id);
+		return;
 	}
 
-	bool ws_close()const
+	if(abs(min_it->v[0].dist(*this)-dist)<1)
 	{
-		return (m_buff[0]&0xF) ==8 ;
+		set_path(vl,min_it);
 	}
-
-	bool ws_mask()const
+	else if(abs(min_it->v[1].dist(*this)-dist)<1)
 	{
-		return (m_buff[1]&0x80) !=0 ;
+		set_path(vl,min_it+1);
 	}
-
-	int parse_length()
+	else
 	{
-		if(m_buff.len_data()<2)
-			return -1;
-
-		if(m_data_pos>0)
-			return 0;
-
-		if((m_buff[1]&0x7F)<=125)
-		{
-			m_mask_pos=ws_mask()?2:-1;
-			m_data_pos=ws_mask()?6:2;
+		point proj=min_it->projection(*this);
+		vl.insert(min_it+1,line_v(proj,min_it->v[1]));
+		min_it->set_point(1,proj);
 
-			m_data_len=m_buff[1]&0x7F;
-		}
-		else
-		if((m_buff[1]&0x7F)==126)
+		if(min_it->v[0].z)//slope ..555
 		{
-			if(m_buff.len_data()<4)
-				return -1;
-
-			m_mask_pos=ws_mask()?4:-1;
-			m_data_pos=ws_mask()?8:4;
-
-			m_data_len=(m_buff[2]<<8) | m_buff[3];
+			double slope=min_it->v[0].z;
+			double len_a=min_it->v[0].dist((min_it+1)->v[1]);
+			double len_0=slope*min_it->length()/len_a;
+			double len_1=slope-len_0;
+			
+			min_it->v[0].z=min_it->v[1].z=len_0;
+			(min_it+1)->v[0].z=(min_it+1)->v[1].z=len_1;
 		}
-		else
-		{
-			if(m_buff.len_data()<9)
-				return -1;
-
-			m_mask_pos=ws_mask()?9:-1;
-			m_data_pos=ws_mask()?13:9;
 
-			//不考虑大于20G的数据
-			m_data_len=(m_buff[6]<<24)|(m_buff[7]<<16)|(m_buff[8]<<8)|(m_buff[9]);
-		}
-		
-		int i=0;
-		for(i=0;i<m_data_len;i++)
-		{
-			uint8_t b=m_buff[m_data_pos+i];
-			if(b>=0x30 && b<=0x39)
-				continue;
-			break;
-		}
-
-		m_data_len-=i;
-		m_data_pos+=i;
-
-		return 0;
+		set_path(vl,min_it+1);
 	}
+}
+};
 
-	void mask(const uint8_t*m,uint8_t*d,int len)
+void print_vl(const std::vector<line_v>&vl)
+{
+	printf("-----------------------------------\n");
+	for(auto&v:vl)
 	{
-		for(int i=0;i<len;i++)
-			d[i]=d[i]^m[i&3];
+		printf("%s\n",v.to_string().c_str());
 	}
 
-	int ws_parse()
-	{
-		if(parse_length()<0)
-			return -1;
-
-		if(m_buff.len_data()<m_data_pos+m_data_len)
-			return -1;
+}
 
-		if(ws_mask())
-		{
-			mask(&m_buff[m_mask_pos],&m_buff[m_data_pos],m_data_len);
-		}
+void set_path(const std::vector<line_v>&v_line,const std::vector<double>&slope)
+{
+	if(v_line.empty())
+		return;
 
-		for(int i=0;i<m_data_len;i++)
+	const auto&find_line=[](const point&pt,int first,std::vector<line_v>&vl){
+		for(auto it=vl.begin();it!=vl.end();it++)
 		{
-			printf("%c",m_buff[m_data_pos+i]);
+			if(it->v[first].dist(pt)<1)
+				return it;
+			if(it->v[first?0:1].dist(pt)<1)
+			{
+				point p=it->v[0];
+				it->v[0]=it->v[1];
+				it->v[1]=p;
+				return it;
+			}
 		}
 
-		printf("\n\n");
+		return vl.end();
+	};
+	
+	//构造一个首尾相连的结构
 
-		return 0;
-	}
+	print_vl(v_line);
+	std::vector<line_v> vl(v_line.begin()+1,v_line.end());
+	std::vector<line_v> target(v_line.begin(),v_line.begin()+1);
 
+	target[0][0].z=target[0][1].z=slope[0];
+	for(int i=0,c=vl.size();i<c;i++)
+		vl[i][0].z=vl[i][1].z=slope[i+1];
 
-	int connect_ws(const char*ip,int port)
+	for(;;)
 	{
-		unsigned char k[16], k6[128];
-
-		for(size_t i=0;i<sizeof(k);i++)
-			k[i]=rand();
-
-		base64::encode(k,sizeof(k),k6);
-
-		const char*fmt=
-			"GET /socket.io/?EIO=3&transport=websocket HTTP/1.1\r\n"
-			"Host: %s:%d\r\n"
-			"Connection: Upgrade\r\n"
-			"Pragma: no-cache\r\n"
-			"Cache-Control: no-cache\r\n"
-			"Upgrade: websocket\r\n"
-			"Origin: http://%s:%d\r\n"
-			"Sec-WebSocket-Version: 13\r\n"
-			"Accept-Encoding: gzip, deflate\r\n"
-			"Accept-Language: zh-CN,zh;q=0.9\r\n"
-			"Sec-WebSocket-Key: %s\r\n"
-			"Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n";
-
-		if(connect_tcp(ip,port)<0)	
-			return -1;
-
-		char buf[512];
-		int len=sprintf(buf,fmt,ip,port,ip,port,k6);
-
-		if(len!=zio::writev(m_fd, buf, len))
-		{
-			close();
-			return -1;
-		}
-
-		sleep(1);
-		if(read_until("\r\n\r\n")<=0)
-		{
-			close();
-			return -1;
-		}
-
-		if(m_buff.find("101 Switching Protocols\r\n"))
-		{
-			m_buff.skip(m_buff.find("\r\n\r\n"));
-			return 0;
-		}
+		auto it=find_line(target.back().v[1],0,vl);
+		if(it==vl.end())
+			break;
 
-		close();
-		return -1;
+		target.insert(target.end(),it,it+1);
+		vl.erase(it);
 	}
 
-	int request(const char*what)
+	for(;;)
 	{
-		int len=strlen(what);
-
-        if(len!=zio::writev(m_fd, what, len))
-		{
-			close();
-			return -1;
-		}
+		auto it=find_line(target.front().v[0],1,vl);
+		if(it==vl.end())
+			break;
 
-		return 0;
+		target.insert(target.begin(),it,it+1);
+		vl.erase(it);
 	}
 
-	int read_until(const char*what,int timeout=10*1000)
-	{
-		int rc=0;
-		zclock c;
-		for(;;)
-		{
-			buff_t b=m_buff.alloc();
-			if(b.empty())
-			{
-				m_buff.grow(1024);
-				b=m_buff.alloc();
-			}
-
-			int len=zio::read(m_fd,b.ptr(),b.len());
-
-			if((int)c.count_ms()>timeout)
-			{
-				log_error("websocket read timeout in %dms",timeout);
-				return -1;
-			}
-
-			if(len==-1)
-			{
-				return -1;
-			}
+	print_vl(target);
 
-			if(len==-2)
-				continue;
+	tant ta;
 
-			if(len==0)
-			{
-				log_info("remote close the socket");
-				return 0;
-			}
+	ta.set(100,100);
+	ta.set_path2(target);
+}
 
-			m_buff.commit(len);
-			rc+=len;
 
-			if(m_buff.find(what))
-				return rc;
-		}
-	}
 
+int main()
+{
+{
+	std::vector<line_v> vl;
 
-	void close()
-	{
-		zio::close(m_fd);
-	}
-
-	~web_client_http()
-	{
-		close();
-	}
-};
+	vl.push_back(line_v(point(-10,0),point(0,0)));
+	vl.push_back(line_v(point(0,0),point(100,100.1)));
 
-int realpath_test()
+	print_vl(vl);
+	set_path(vl,{10,20});
+}
 {
-	char buf[4096];
+	std::vector<line_v> vl;
 
-	realpath(".",buf);
-	log_info("curpath=%s",buf);
+	vl.push_back(line_v(point(200,200),point(100,100.1)));
+	vl.push_back(line_v(point(200,200),point(200,220)));
 
-	return 0;
-}
 
-#if 0
-std::string test_json()
+	set_path(vl,{10,20});
+}
 {
-	struct json
-	{
-		json&put(const char*k,const json&n)
-		{
-		
-			return *this;
-		}
-	
-		json&put(const char*k,int v)
-		{
-		
-			return *this;
-		}
-		json&put(const char*k,const char*v)
-		{
-		
-			return *this;
-		}
+	std::vector<line_v> vl;
 
-		std::string to_string()const
-		{
-			return std::string();
-		}
-	};
+	vl.push_back(line_v(point(-10,0),point(0,0)));
+	vl.push_back(line_v(point(0,0),point(200,200)));
 
-	return json().put("cmd","login")
-				 .put("data",json()
-				 	 .put("uname","wyj")
-					 .put("passwd",111111)
-				  ).to_string();
-}
-#endif
 
-int main()
+	set_path(vl,{10,20});
+}
 {
-	unsigned char buf[32];
-	const char*s64="puVOuWb7rel6z2AVZBKnfw==";
-	const char*login="{\"cmd\":\"login\",\"data\":{\"user_name\":\"zzj\",\"user_pass\":\"111111\"}}\n";
+	std::vector<line_v> vl;
 
-	int blen=32;
-	base64::decode((char*)s64,strlen(s64),buf,blen);
+	vl.push_back(line_v(point(0,0),point(200,200)));
 
-	web_client_http client;
-	client.connect_ws("127.0.0.1",9001);
 
-	for(;;)
-	{
-		while(client.ws_parse()==0)
-			client.ws_reset();
-
-		client.request(login);
-		client.read_until("\n");
-	}
+	set_path(vl,{10});
+}
 
 	return 0;
 }

+ 1 - 1
websocket/constdef.h

@@ -53,7 +53,7 @@
 #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_PATH "reader_path_tof_n"
 #define JSON_KEY_NAME_READER "reader"
 #define JSON_KEY_NAME_CARD "card"
 #define JSON_KEY_NAME_STAFF "staff"

+ 3 - 0
websocket/wsClient.cpp

@@ -3,6 +3,7 @@
 #include <thread>
 #include <chrono>
 #include <boost/locale.hpp>
+#include"log.h"
 
 
 namespace YA
@@ -166,11 +167,13 @@ namespace YA
 
 	void wsClient::_on_close( sio::client::close_reason const & reason )
 	{
+        log_info("websocket %d close()",__ID);
 		_reset();
 	}
 
 	void wsClient::_on_reconnect( unsigned p1, unsigned p2 )
 	{
+        log_info("websocket %d reconnect()",__ID);
 		_reset();
 	}
 

+ 21 - 4
znet.cpp

@@ -55,7 +55,7 @@ public:
 
 	void boardcast(const std::vector<char>&msg)
 	{
-		for(auto i:m_thread_clts)
+		for(const auto&i:m_thread_clts)
 		{
 			std::vector<char> tmp(msg);
 			i->send(std::move(tmp));
@@ -99,7 +99,7 @@ public:
 
 	void close_all()
 	{
-		for(auto clt:m_thread_clts)
+		for(const auto&clt:m_thread_clts)
 		{
 			if(!clt)
 				continue;
@@ -110,7 +110,7 @@ public:
 
 	void on_async(const std::list<std::shared_ptr<client>>&notify_clts)
 	{
-		for(auto&clt:notify_clts)
+		for(const auto&clt:notify_clts)
 		{
 			((client_ex*)clt.get())->on_notify();
 		}
@@ -626,7 +626,24 @@ struct main_loop:io_context
 
 		block_sig(SIGPIPE);
 		signal_w sint(*this,SIGINT),term(*this,SIGTERM);
-		ev::dynamic_loop::run(0);
+
+
+		while(!check_stop_flag())
+		{
+			try
+			{
+			ev::dynamic_loop::run(0);
+			}
+			catch(const std::exception&e)
+			{
+				log_error("捕获到异常:%s",e.what());
+			}
+			catch(...)
+			{
+				log_error("捕获到未知异常");
+			}
+		}
+
 		_1.stop();
 		close_all();