⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gis.c

📁 基于STC51通过GPS自主定位导航FAT文件系统程序
💻 C
字号:
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& gis系统 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//*文件名称:gis.c

//*文件作用:gis系统函数

//*文件作者:翟  鹏

//*创建日期:2005年5月
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&



#include <include.h>



//县级表
static uchar code *xian_table_beijing[]=
{
"4E1C57CE533A",//东城区
"897F57CE533A",//西城区
"5D076587533A",//崇文区
"5BA36B66533A",//宣武区
"671D9633533A",//朝阳区
"4E3053F0533A",//丰台区
"77F3666F5C71533A",//石景山区
"6D776DC0533A",//海淀区
"95E859346C9F533A",//门头沟区
"623F5C71533A",//房山区
"901A5DDE533A",//通州区
"987A4E49533A",//顺义区
"660C5E73533A",//昌平区
"59275174533A",//大兴区
"600067D4533A",//怀柔区
"5E738C37533A",//平谷区
"5BC64E9153BF",//密云县
"5EF65E8653BF",//延庆县
"",
};
static uchar code *xian_table_tianjin[]=
{
"548C5E73533A",//和平区
"6CB34E1C533A",//河东区
"6CB3897F533A",//河西区
"53575F00533A",//南开区
"6CB35317533A",//河北区
"7EA26865533A",//红桥区
"58586CBD533A",//塘沽区
"6C496CBD533A",//汉沽区
"59276E2F533A",//大港区
"4E1C4E3D533A",//东丽区
"897F9752533A",//西青区
"6D255357533A",//津南区
"53178FB0533A",//北辰区
"6B666E05533A",//武清区
"5B9D577B533A",//宝坻区
"5B816CB353BF",//宁河县
"97596D7753BF",//静海县
"84DF53BF",//蓟县
"",
};



//处理GPS速度和方向--转化为文字描述
static uchar code dir_hz1[][9]={"6B635317","6B634E1C","6B635357","6B63897F","6B635317"};//"正北","正东","正南","正西","正北"
static uchar code dir_hz2[][9]={"4E1C5317","4E1C5357","897F5357","897F5317","4E1C5317"};//"东北","东南","西南","西北","东北"
static uchar code dir_hz3[][9]={"504F5317","504F4E1C","504F5357","504F897F","504F5317"};//"偏北","偏东","偏南","偏西","偏北"



static uint  xdata fp=0xFFFF;



//求两点之间的距离  经纬度单位是----度
long GetDistance(float lng1, float lat1, float lng2, float lat2)
{
	float xdata radLat1=lat1*PI/180.0;
	float xdata radLat2=lat2*PI/180.0;
	float xdata a=radLat1-radLat2;
	float xdata b=lng1*PI/180.0-lng2*PI/180.0;
	float xdata s;
	
	a/=2;b/=2;
	a=sin(a);b=sin(b);
	s=2*asin(sqrt(a*a + cos(radLat1)*cos(radLat2)*b*b));
	s*=EARTH_RADIUS;
   
	return (long)s;
}

//*******************************************************************************************
//函数作用:gis查找  先查找距离最近的点,得到政区代码,然后查找距离这个点最近的路 然后查找附近小区
//参数说明:
//注意事项:
//返回说明:无
//*******************************************************************************************
uchar gis_search(uchar *result_buf, float longti, float lati)
{
	uchar xdata file_name[]=MAP_FILE;
	map_header_t xdata map_header;

	long xdata obj_x,obj_y;
	int xdata obj_col,obj_row;
	int xdata helix_col,helix_row;//螺旋线搜索
	uchar xdata helix_depth;//螺旋线深度
	uchar xdata helix_start_flag;//螺旋线起点标志
	long xdata distance;
	uchar xdata name[64];
	ulong xdata area_code;
	
	long xdata min_cross1_distance=100000000;
	long xdata min_cross1_offset=0;
	long xdata min_cross1_x,min_cross1_y;
	uchar xdata min_cross1_length=0;
	uchar xdata min_cross1_type=0;

	long xdata min_main1_distance=100000000;
	long xdata min_main1_offset=0;
	long xdata min_main1_x,min_main1_y;
	uchar xdata min_main1_length=0;
	uchar xdata min_main1_type=0;
				
	long xdata min_point1_distance=100000000;
	long xdata min_point1_offset=0;
	long xdata min_point1_x,min_point1_y;
	uchar xdata min_point1_length=0;
	uchar xdata min_point1_type=0;

	
	//打开地图文件
	if(fp==0xFFFF)
	{
	if((fp=fopen(file_name,"r"))==0xFFFF)
	{
		//初始化SD卡上的FAT文件系统
		if(fat_init())
		{
			print_line("fat_init failed");
			return 1;
		}
		if((fp=fopen(file_name,"r"))==0xFFFF)
		{
			print_line("fopen "MAP_FILE" failed");
			return 2;
		}			
	}
	}
	//读取地图头信息
	fseek(0);
	if(fread((uchar *)&map_header,sizeof(map_header_t),fp))return 3;
	//计算目标所在区块的行列
	obj_x=(long)(longti*map_header.zoom);
	obj_y=(long)(lati*map_header.zoom);
	obj_col=(obj_x-map_header.startx)/map_header.rect_size;
	obj_row=(obj_y-map_header.starty)/map_header.rect_size;

	//以螺旋线的方式遍历所有区块 查找距离目标点最近的点
	helix_start_flag=1;
	helix_depth=0;
	while(helix_depth<=10)
	{
		long xdata rect_no;//当前的区块号
		long xdata rect_offset;//当前区块地址偏移量
		long xdata rect_startx,rect_starty;//当前区块边界坐标
		
		dog();
		
		//螺旋形计算下一个区块所在的行列
		if(helix_start_flag)//螺旋线起点不参与计算
		{
			helix_start_flag=0;
			helix_col=obj_col;
			helix_row=obj_row;
		}
		else if(abs(helix_col-obj_col)>=helix_depth && abs(helix_row-obj_row)<helix_depth)
		{
			if(helix_col>obj_col)helix_row++;
			else if(helix_col<obj_col)helix_row--;
		}
		else if(abs(helix_row-obj_row)>=helix_depth && abs(helix_col-obj_col)<helix_depth)
		{
			if(helix_row>obj_row)helix_col--;
			else if(helix_row<obj_row)helix_col++;
		}
		else if(abs(helix_col-obj_col)>=helix_depth && abs(helix_row-obj_row)>=helix_depth)
		{
			if(helix_col>obj_col && helix_row>obj_row)helix_col--;
			else if(helix_col<obj_col && helix_row>obj_row)helix_row--;
			else if(helix_col<obj_col && helix_row<obj_row)helix_col++;
			//起点
			else if(helix_col>=obj_col && helix_row<=obj_row)
			{
				helix_depth++;
				helix_col++;
			}
		}
				
		//计算区块号 并判断区块号是否超范围
		rect_no=(long)helix_row*map_header.rect_xnum+helix_col;
		if(helix_row<0 || helix_col<0 || helix_col>=map_header.rect_xnum || helix_row>=map_header.rect_ynum)
		{
			print_line("this rect is out of range");
			continue;
		}
		//读取区块地址
		fseek(sizeof(map_header_t)+rect_no*4);
		if(fread((uchar *)&rect_offset,4,fp))return 4;
		if(rect_offset==0)
		{
			//cprint_line("this rect has no data");
			continue;
		}
		//当前区块边界坐标
		rect_startx=map_header.startx+helix_col*map_header.rect_size;
		rect_starty=map_header.starty+helix_row*map_header.rect_size;
		//遍历当前区块所有数据
		while(1)
		{
			//当前纪录的头
			record_header_t xdata record_header;
			long xdata longti,lati;
					
			dog();
					
			//读取当前记录的头			
			fseek(rect_offset);
			if(fread((uchar *)&record_header,sizeof(record_header_t),fp))return 5;
			if(record_header.type_code==0xFF)
			{
				//cprint_line("end of rect and goto next");
				break;
			}
			rect_offset+=sizeof(record_header_t);
			//计算当前点坐标
			longti=rect_startx+record_header.longti;
			lati=rect_starty+record_header.lati;
			//计算两点距离
			distance=sqrt((longti-obj_x)*(longti-obj_x)+(lati-obj_y)*(lati-obj_y));
			//寻找 县级市,乡镇,村庄,交叉路口名
			if(record_header.type_code<=7)
			{
				if(distance<min_cross1_distance)
				{	
					min_cross1_distance=distance;
					min_cross1_offset=rect_offset;
					min_cross1_x=longti;min_cross1_y=lati;
					min_cross1_length=record_header.name_length;
					min_cross1_type=record_header.type_code;
				}
			}
			//主参考点
			else if(record_header.type_code<=35)
			{
				if(distance<min_main1_distance)
				{	
					min_main1_distance=distance;
					min_main1_offset=rect_offset;
					min_main1_x=longti;min_main1_y=lati;
					min_main1_length=record_header.name_length;
					min_main1_type=record_header.type_code;
					area_code=record_header.area_code;
				}
			}							
			//寻找距离最近的点
			if(distance<min_point1_distance)
			{								
				min_point1_distance=distance;
				min_point1_offset=rect_offset;
				min_point1_x=longti;min_point1_y=lati;
				min_point1_length=record_header.name_length;
				min_point1_type=record_header.type_code;
			}
			//读取名称
			//fseek(rect_offset);
			//if(fread(name,record_header.name_length,fp))return 8;
			//buf_to_hex(result_buf,name,record_header.name_length);
			//print_line(result_buf);
			rect_offset+=record_header.name_length;
		}
		//转一圈以后 判断是否找到了 并退出循环
		if(helix_depth>=2)if(min_cross1_offset && min_main1_offset && min_point1_offset)break;
	}
	
	//判断是否找到了
	if(!min_cross1_offset || !min_main1_offset || !min_point1_offset)return 10;

	result_buf[0]=0;
	//解析行政区划
	strcat(result_buf,xian_table_tianjin[area_code]);
	//交叉口或者政府所在地
	fseek(min_cross1_offset);
	if(fread(name,min_cross1_length,fp))return 8;
	buf_to_hex(&result_buf[strlen(result_buf)],name,min_cross1_length);
	min_cross1_distance=GetDistance(((float)min_cross1_x)/map_header.zoom,((float)min_cross1_y)/map_header.zoom,((float)min_point1_x)/map_header.zoom,((float)min_point1_y)/map_header.zoom);
	if(min_cross1_distance<20)
	{
		strcat(result_buf,"96448FD1FF0C");//附近,
	}
	else
	{
		//计算方向
		long xdata dx,dy;
		dx=min_point1_x-min_cross1_x;
		dy=min_point1_y-min_cross1_y;
		if(abs(dx)>=abs(dy))
		{
			if(abs(dx/dy)>=3)
			{
				strcat(result_buf,"6B63");//正
				if(dx>=0)strcat(result_buf,"4E1C");//东
				else if(dx<0)strcat(result_buf,"897F");//西
			}
			else
			{
				if(dx>=0)strcat(result_buf,"4E1C");//东
				else if(dx<0)strcat(result_buf,"897F");//西
				if(dy>=0)strcat(result_buf,"5317");//北
				else if(dy<0)strcat(result_buf,"5357");//南
			}
		}
		else if(abs(dx)<abs(dy))
		{
			if(abs(dy/dx)>=3)
			{
				strcat(result_buf,"6B63");//正
				if(dy>=0)strcat(result_buf,"5317");//北
				else if(dy<0)strcat(result_buf,"5357");//南
			}
			else
			{
				if(dx>=0)strcat(result_buf,"4E1C");//东
				else if(dx<0)strcat(result_buf,"897F");//西
				if(dy>=0)strcat(result_buf,"5317");//北
				else if(dy<0)strcat(result_buf,"5357");//南
			} 
		}
		strcat(result_buf,"65B95411");//方向
		long_to_dec(name,min_cross1_distance);//121(0x79)---313231
		str_unicode_copy((uint *)&name[32],name);//313231---003100320031
		buf_to_hex(&result_buf[strlen(result_buf)],&name[32],strlen(name)*2);//003100320031---303033313030333230303331
		strcat(result_buf,"7C73FF0C");//米,
	}
	//主参考点--大型固定建筑或者著名小区
	fseek(min_main1_offset);
	if(fread(name,min_main1_length,fp))return 8;
	buf_to_hex(&result_buf[strlen(result_buf)],name,min_main1_length);
	strcat(result_buf,"96448FD1FF0C");//附近,
	
	//距离最近的参考点
	fseek(min_point1_offset);
	if(fread(name,min_point1_length,fp))return 8;
	buf_to_hex(&result_buf[strlen(result_buf)],name,min_point1_length);
	min_point1_distance=GetDistance(((float)min_point1_x)/map_header.zoom,((float)min_point1_y)/map_header.zoom,((float)obj_x)/map_header.zoom,((float)obj_y)/map_header.zoom);
	if(min_point1_distance<20)
	{
		if(min_point1_type==7 || min_point1_type==14 || min_point1_type==15)strcat(result_buf,"4E2D95F4FF0C");//中间,
		else strcat(result_buf,"95E853E3FF0C");//门口,
	}
	else
	{
		//计算方向
		long xdata dx,dy;
		dx=obj_x-min_point1_x;
		dy=obj_y-min_point1_y;
		if(abs(dx)>=abs(dy))
		{
			if(abs(dx/dy)>=3)
			{
				strcat(result_buf,"6B63");//正
				if(dx>=0)strcat(result_buf,"4E1C");//东
				else if(dx<0)strcat(result_buf,"897F");//西
			}
			else
			{
				if(dx>=0)strcat(result_buf,"4E1C");//东
				else if(dx<0)strcat(result_buf,"897F");//西
				if(dy>=0)strcat(result_buf,"5317");//北
				else if(dy<0)strcat(result_buf,"5357");//南
			}
		}
		else if(abs(dx)<abs(dy))
		{
			if(abs(dy/dx)>=3)
			{
				strcat(result_buf,"6B63");//正
				if(dy>=0)strcat(result_buf,"5317");//北
				else if(dy<0)strcat(result_buf,"5357");//南
			}
			else
			{
				if(dx>=0)strcat(result_buf,"4E1C");//东
				else if(dx<0)strcat(result_buf,"897F");//西
				if(dy>=0)strcat(result_buf,"5317");//北
				else if(dy<0)strcat(result_buf,"5357");//南
			} 
		}
		long_to_dec(name,min_point1_distance);//121(0x79)---313231
		str_unicode_copy((uint *)&name[32],name);//313231---003100320031
		buf_to_hex(&result_buf[strlen(result_buf)],&name[32],strlen(name)*2);//003100320031---303033313030333230303331
		strcat(result_buf,"7C735904FF0C");//米处,
	}
	//移动的速度和方向-----只有定位并且速度达到一定数值才能显示
	if(gps_get_3D()>=3)
	{
		uchar xdata quadrant=gps_dir()/90;//象限
		uchar xdata slope=gps_dir()%90;//偏角
		ulong xdata vec_km=(ulong)gps_speed()*1852/1000;//速度---公里/小时
		
		if(gps_speed()>=2)
		{
			//速度
			strcat(result_buf,"65F6901F");//时速
			int_to_dec(name,(uint)vec_km);
			str_unicode_copy((uint *)&name[32],name);
			buf_to_hex(&result_buf[strlen(result_buf)],&name[32],strlen(name)*2);
			strcat(result_buf,"516C91CCFF0C");//公里
			//方向
			strcat(result_buf,"65B95411");//方向
			if(slope<=10)
			{
				strcat(result_buf,dir_hz1[quadrant]);
			}	
			else if(slope>=80)
			{
				strcat(result_buf,dir_hz1[quadrant+1]);
			}
			else
			{
				strcat(result_buf,dir_hz2[quadrant]);
				if(slope<30)strcat(result_buf,dir_hz3[quadrant]);
				else if(slope>60)strcat(result_buf,dir_hz3[quadrant+1]);
			}
		}
		else
		{
			strcat(result_buf,"59044E8E97596B6272B66001");//静止状态
		}
	}
	else
	{
		strcat(result_buf,"5F53524D4E0D5B9A4F4D");//当前不定位
	}
	//经纬度
	//cstrcat(result_buf,"FF0C");//,
	//strcpy(name,ftoa(longti,&status));
	//str_unicode_copy((uint *)&name[32],name);
	//buf_to_hex(&result_buf[strlen(result_buf)],&name[32],strlen(name)*2);
	//cstrcat(result_buf,"FF0C");//,
	//strcpy(name,ftoa(lati,&status));
	//str_unicode_copy((uint *)&name[32],name);
	//buf_to_hex(&result_buf[strlen(result_buf)],&name[32],strlen(name)*2);	
	
	return 0;
}


			/*
			//计算方向
			long dx,dy;
			dx=min_point_x-min_cross_x;
			dy=min_point_y-min_cross_y;
			if(abs(dx)>=abs(dy))
			{
				if(abs(dx/dy)>=3)
				{
					cstrcat(result_buf,"6B63");//正
					if(dx>=0)cstrcat(result_buf,"4E1C");//东
					else if(dx<0)cstrcat(result_buf,"897F");//西
				}
				else
				{
					if(dx>=0)cstrcat(result_buf,"4E1C");//东
					else if(dx<0)cstrcat(result_buf,"897F");//西
					if(dy>=0)cstrcat(result_buf,"5317");//北
					else if(dy<0)cstrcat(result_buf,"5357");//南
				}
			}
			else if(abs(dx)<abs(dy))
			{
				if(abs(dy/dx)>=3)
				{
					cstrcat(result_buf,"6B63");//正
					if(dy>=0)cstrcat(result_buf,"5317");//北
					else if(dy<0)cstrcat(result_buf,"5357");//南
				}
				else
				{
					if(dx>=0)cstrcat(result_buf,"4E1C");//东
					else if(dx<0)cstrcat(result_buf,"897F");//西
					if(dy>=0)cstrcat(result_buf,"5317");//北
					else if(dy<0)cstrcat(result_buf,"5357");//南
				} 
			}
			*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -