信号灯周期、队长标定中间数据说明
样式数据
wx4g8nj0 77 20170331235409 86049 43.7 6.0 174.0 13331194428 wx4g8nj4
wx4g8nj0 77 20170331235414 86054 37.3 0.0 0.0 13331194428 wx4g8nj1
wx4g8nj0 77 20170331235426 86066 32.2 10.0 178.0 13331194428 wx4g8nj1
wx4g8nj0 77 20170331235438 86078 15.9 6.0 180.0 13331194428 wx4g8jvp
wx4g8nj0 77 20170331235450 86090 51.1 0.0 326.0 13331194428 wx4g8jvj
wx4g8nj0 77 20170331235551 86151 179.7 56.0 168.0 13301208461 wx4g8nm1
wx4g8nj0 77 20170331235603 86163 31.6 26.0 180.0 13301208461 wx4g8nj1
wx4g8nj0 77 20170331235615 86175 14.7 0.0 178.0 13301208461 wx4g8nj0
wx4g8nj0 77 20170331235627 86187 12.0 23.0 178.0 13301208461 wx4g8jvp
wx4g8nj0 77 20170331235632 86192 49.6 34.0 178.0 13301208461 wx4g8jvj
对应字段
nid, direction, time,seconds,distance,speed,angle, vid, cargeohash
说明
- nid 红绿灯节点编号,以Geohash作为其编号
- direciton 方向,数字1-8从正北方向开始顺时针表示八个方向,两个数字表示车辆经过站点时的方向,第一个数字表示进入红绿灯时候的方向,第二个数字表示离开红绿灯时候的位置。如1表示由北向南行驶,2表示正东北向正西南行驶,3表示正东向正西行驶
- time 时间,时间格式为yyyyMMddHHmmss, 如20170217235544为“2017-02017 23:55:44”
- seconds 当日累计秒数(= 小时数 X 3600 + 分钟数 X 60 + 秒数)
- ditance 距离离红绿灯距离,单位m
- speed 车辆瞬时速度,单位km/h
- angle 车辆瞬时角度,单位°,正北方向为0,顺时针为正方向
- vid GPS数据中的车辆编号
- cargeohash 车辆位置Geohash
经纬度与Geohash转换
GeoHash核心原理说明
import java.util.BitSet;
import java.util.HashMap;
public class GeoHash {
private static int numbits = 4 * 5; //经纬度单独编码长度
//32位编码对应字符
final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
//定义编码映射关系
final static HashMap<Character, Integer> lookup = new HashMap<Character, Integer>();
//初始化编码映射内容
static {
int i = 0;
for (char c : digits)
lookup.put(c, i++);
}
//对编码后的字符串解码
public static double[] decode(String geohash) {
StringBuilder buffer = new StringBuilder();
for (char c : geohash.toCharArray()) {
int i = lookup.get(c) + 32;
buffer.append( Integer.toString(i, 2).substring(1) );
}
BitSet lonset = new BitSet();
BitSet latset = new BitSet();
//偶数位,经度
int j =0;
for (int i=0; i< numbits*2;i+=2) {
boolean isSet = false;
if ( i < buffer.length() )
isSet = buffer.charAt(i) == '1';
lonset.set(j++, isSet);
}
//奇数位,纬度
j=0;
for (int i=1; i< numbits*2;i+=2) {
boolean isSet = false;
if ( i < buffer.length() )
isSet = buffer.charAt(i) == '1';
latset.set(j++, isSet);
}
double lon = decode(lonset, -180, 180);
double lat = decode(latset, -90, 90);
return new double[] {lat, lon};
}
//根据二进制和范围解码
private static double decode(BitSet bs, double floor, double ceiling) {
double mid = 0;
for (int i=0; i<bs.length(); i++) {
mid = (floor + ceiling) / 2;
if (bs.get(i))
floor = mid;
else
ceiling = mid;
}
return mid;
}
//对经纬度进行编码
public static String encode(double lat, double lon) {
BitSet latbits = getBits(lat, -90, 90);
BitSet lonbits = getBits(lon, -180, 180);
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < numbits; i++) {
buffer.append( (lonbits.get(i))?'1':'0');
buffer.append( (latbits.get(i))?'1':'0');
}
return base32(Long.parseLong(buffer.toString(), 2));
}
//根据经纬度和范围,获取对应二进制
private static BitSet getBits(double lat, double floor, double ceiling) {
BitSet buffer = new BitSet(numbits);
for (int i = 0; i < numbits; i++) {
double mid = (floor + ceiling) / 2;
if (lat >= mid) {
buffer.set(i);
floor = mid;
} else {
ceiling = mid;
}
}
return buffer;
}
//将经纬度合并后的二进制进行指定的32位编码
private static String base32(long i) {
char[] buf = new char[65];
int charPos = 64;
boolean negative = (i < 0);
if (!negative)
i = -i;
while (i <= -32) {
buf[charPos--] = digits[(int) (-(i % 32))];
i /= 32;
}
buf[charPos] = digits[(int) (-i)];
if (negative)
buf[--charPos] = '-';
return new String(buf, charPos, (65 - charPos));
}
}