?? gis.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 + -