GPS转换16位十六进制值到经纬度
GPS conversion 16digit hexadecimal value to longitude and latitude
从设备中我得到以下类型的十六进制值 3305511C0424573C(存储在 sql 数据库中)。我需要从中获取经度和纬度。
我也得到这种格式的经度和纬度值(单精度浮点数):
- 经度 = 1083419342
- 纬度 = 1112302388
我知道结果是:
- 经度 = 4.6146
- 纬度 = 51.09688
我尝试在 C# 中编写多个转换代码,但所有结果都不正确。
来自sql服务器的数据:
StreamID = 15620,GPS0 = 3305511C0424573C,GPS1 = 0000000000000000,GPS 经度 = 1083419342,GPS 纬度 = 1112302388
label = GPS 经度,单位 = 度,DataItemType = 单精度浮点数,精度 = 0,BytePosition = 11
标签 = GPS 纬度,单位 = 度,DataItemType = 单精度浮点数,精度 = 0,BytePosition = 12
我不知道数据如何进入 sql。
我如何使用坐标:
<script> var XMarker = L.marker([51.09688, 4.6146]).addTo(mymap); </script>
这是您需要在 html 或网络应用程序中添加的内容,以便在由 leafletjs (link: leafletjs.com )
创建的地图上获得额外标记
因此我需要知道转换自:
- 3305511C0424573C -> 经度 = 4.6146,纬度 = 51.09688
- 330D262A030C1247 -> 经度 = 3.19325013523526,纬度 = 51.222186941538
C#答案
public static double GPSCoordinateConversion(string GPSCoordinate)
{
double coordinate = 0;
byte[] _byte = new byte[GPSCoordinate.Length / 2];
double value1 = 0;
double value2 = 0;
for (int i = 0; i < _byte.Length; i++)
{
string byteValue = GPSCoordinate.Substring(i * 2, 2);
_byte[i] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
value1 = Convert.ToDouble(_byte[2]) / 100;
value2 = Convert.ToDouble(_byte[3]) / 10000;
coordinate = Convert.ToDouble(_byte[0] + ((_byte[1]+value1+value2) / 60));
return coordinate;
}
public static double GetLatitude(string GPSHexCoordinate)
{
double latitude = 0;
latitude = GPSCoordinateConversion(GPSHexCoordinate.Substring(0, 8));
return latitude;
}
public static double GetLongitude(string GPSHexCoordinate)
{
double longitude = 0;
longitude = GPSCoordinateConversion(GPSHexCoordinate.Substring(8, 8));
return longitude;
}
你要求找到两个不同的解码。
第一部分(原题),是关于转换
longitude = 1083419342
latitude = 1112302388
至
longitude = 4.6146
latitude = 51.09688
该数字是现代计算机上浮点数的整数表示(因此 IEEE 754 单精度二进制表示具有普通整数表示。[注意:我们没有负数,所以我们不知道如何符号表示]
算法(第一题)
- 取每个数字(不带分隔字段的
C
)
- 将其转换为字节数组(4 个字节)
- 读取float等字节(float有标准格式)
在 C 中,uint32_t
和 float
之间的并集。在Pythonstruct.unpack('>f', bytearray.fromhex(hex(your_number)[2:])
。 C# 有 BitConverter,你可以在 bitconverter documentation 中看到一个例子。我让对方写一个正确的C#答案。注意:我们仍然需要测试负数,但他们应该没问题(几个月前我们得到了与澳大利亚类似的问题,所以负纬度)。
现在,然后你问了十六进制数表示,这与第一个问题无关(所以你的软件已经知道如何转换坐标)。
问题是我无法获得准确的坐标,但我非常精确,误差为 0.02 度。也许还有一个基准转换(你的坐标是 WGS84,正如 GPS 所期望的那样?)。或者数据库将坐标转换成不同的数据?
无论如何第二种编码的解法:
将字符串分成两个半个 8 个字符。前半部分是纬度,后半部分是经度。
第一组两个字的度数
第二组两个字符是质数(或分)。所以你应该把坐标写成 4'36"52.56, 3'11"35.70, 51'5"48.77, 51'13"19.87
那我就不知道了。也许第二组是第二个,然后是两位小数,也可能是4位小数。
再说一次:我不知道负纬度或经度是如何编码的。考虑到经度可以有 360 个值,但是在两个字符中你最多只能编码 256 个值。
几个月前我再也找不到类似的问题(未回答),澳大利亚坐标。这可能有助于证实这一点。但是您可以尝试使用更多的坐标,并检查错误(并且可能会发现是否还有基准转换 [所以两个不同的坐标约定])。但是我认为(只有4个数据)这样的方法已经足够精确了。
从3305511C0424573C到经度=4.6146和纬度=51.09688的转换如下。
将 16 个字符拆分为两个单独的 8 个字符的字符串。
将 8 个字符长的字符串拆分为 4 个字节(2 个字符长)的字节数组。
则计算如下:byte[0]+((Byte[1]+(byte[2]/100)+(byte[3]/10000))/60)
对经度和纬度执行这些步骤。
public static double GPSCoordinateConversion(string GPSCoordinate)
{
double coordinate = 0;
byte[] _byte = new byte[GPSCoordinate.Length / 2];
double value1 = 0;
double value2 = 0;
for (int i = 0; i < _byte.Length; i++)
{
string byteValue = GPSCoordinate.Substring(i * 2, 2);
_byte[i] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
value1 = Convert.ToDouble(_byte[2]) / 100;
value2 = Convert.ToDouble(_byte[3]) / 10000;
coordinate = Convert.ToDouble(_byte[0] + ((_byte[1]+value1+value2) / 60));
return coordinate;
}
public static double GetLatitude(string GPSHexCoordinate)
{
double latitude = 0;
latitude = GPSCoordinateConversion(GPSHexCoordinate.Substring(0, 8));
return latitude;
}
public static double GetLongitude(string GPSHexCoordinate)
{
double longitude = 0;
longitude = GPSCoordinateConversion(GPSHexCoordinate.Substring(8, 8));
return longitude;
}
从设备中我得到以下类型的十六进制值 3305511C0424573C(存储在 sql 数据库中)。我需要从中获取经度和纬度。
我也得到这种格式的经度和纬度值(单精度浮点数):
- 经度 = 1083419342
- 纬度 = 1112302388
我知道结果是:
- 经度 = 4.6146
- 纬度 = 51.09688
我尝试在 C# 中编写多个转换代码,但所有结果都不正确。
来自sql服务器的数据:
StreamID = 15620,GPS0 = 3305511C0424573C,GPS1 = 0000000000000000,GPS 经度 = 1083419342,GPS 纬度 = 1112302388
label = GPS 经度,单位 = 度,DataItemType = 单精度浮点数,精度 = 0,BytePosition = 11 标签 = GPS 纬度,单位 = 度,DataItemType = 单精度浮点数,精度 = 0,BytePosition = 12
我不知道数据如何进入 sql。
我如何使用坐标:
<script> var XMarker = L.marker([51.09688, 4.6146]).addTo(mymap); </script>
这是您需要在 html 或网络应用程序中添加的内容,以便在由 leafletjs (link: leafletjs.com )
因此我需要知道转换自:
- 3305511C0424573C -> 经度 = 4.6146,纬度 = 51.09688
- 330D262A030C1247 -> 经度 = 3.19325013523526,纬度 = 51.222186941538
C#答案
public static double GPSCoordinateConversion(string GPSCoordinate)
{
double coordinate = 0;
byte[] _byte = new byte[GPSCoordinate.Length / 2];
double value1 = 0;
double value2 = 0;
for (int i = 0; i < _byte.Length; i++)
{
string byteValue = GPSCoordinate.Substring(i * 2, 2);
_byte[i] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
value1 = Convert.ToDouble(_byte[2]) / 100;
value2 = Convert.ToDouble(_byte[3]) / 10000;
coordinate = Convert.ToDouble(_byte[0] + ((_byte[1]+value1+value2) / 60));
return coordinate;
}
public static double GetLatitude(string GPSHexCoordinate)
{
double latitude = 0;
latitude = GPSCoordinateConversion(GPSHexCoordinate.Substring(0, 8));
return latitude;
}
public static double GetLongitude(string GPSHexCoordinate)
{
double longitude = 0;
longitude = GPSCoordinateConversion(GPSHexCoordinate.Substring(8, 8));
return longitude;
}
你要求找到两个不同的解码。
第一部分(原题),是关于转换
longitude = 1083419342
latitude = 1112302388
至
longitude = 4.6146
latitude = 51.09688
该数字是现代计算机上浮点数的整数表示(因此 IEEE 754 单精度二进制表示具有普通整数表示。[注意:我们没有负数,所以我们不知道如何符号表示]
算法(第一题)
- 取每个数字(不带分隔字段的
C
) - 将其转换为字节数组(4 个字节)
- 读取float等字节(float有标准格式)
在 C 中,uint32_t
和 float
之间的并集。在Pythonstruct.unpack('>f', bytearray.fromhex(hex(your_number)[2:])
。 C# 有 BitConverter,你可以在 bitconverter documentation 中看到一个例子。我让对方写一个正确的C#答案。注意:我们仍然需要测试负数,但他们应该没问题(几个月前我们得到了与澳大利亚类似的问题,所以负纬度)。
现在,然后你问了十六进制数表示,这与第一个问题无关(所以你的软件已经知道如何转换坐标)。
问题是我无法获得准确的坐标,但我非常精确,误差为 0.02 度。也许还有一个基准转换(你的坐标是 WGS84,正如 GPS 所期望的那样?)。或者数据库将坐标转换成不同的数据?
无论如何第二种编码的解法:
将字符串分成两个半个 8 个字符。前半部分是纬度,后半部分是经度。
第一组两个字的度数
第二组两个字符是质数(或分)。所以你应该把坐标写成 4'36"52.56, 3'11"35.70, 51'5"48.77, 51'13"19.87
那我就不知道了。也许第二组是第二个,然后是两位小数,也可能是4位小数。
再说一次:我不知道负纬度或经度是如何编码的。考虑到经度可以有 360 个值,但是在两个字符中你最多只能编码 256 个值。
几个月前我再也找不到类似的问题(未回答),澳大利亚坐标。这可能有助于证实这一点。但是您可以尝试使用更多的坐标,并检查错误(并且可能会发现是否还有基准转换 [所以两个不同的坐标约定])。但是我认为(只有4个数据)这样的方法已经足够精确了。
从3305511C0424573C到经度=4.6146和纬度=51.09688的转换如下。
将 16 个字符拆分为两个单独的 8 个字符的字符串。
将 8 个字符长的字符串拆分为 4 个字节(2 个字符长)的字节数组。
则计算如下:
byte[0]+((Byte[1]+(byte[2]/100)+(byte[3]/10000))/60)
对经度和纬度执行这些步骤。
public static double GPSCoordinateConversion(string GPSCoordinate)
{
double coordinate = 0;
byte[] _byte = new byte[GPSCoordinate.Length / 2];
double value1 = 0;
double value2 = 0;
for (int i = 0; i < _byte.Length; i++)
{
string byteValue = GPSCoordinate.Substring(i * 2, 2);
_byte[i] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
value1 = Convert.ToDouble(_byte[2]) / 100;
value2 = Convert.ToDouble(_byte[3]) / 10000;
coordinate = Convert.ToDouble(_byte[0] + ((_byte[1]+value1+value2) / 60));
return coordinate;
}
public static double GetLatitude(string GPSHexCoordinate)
{
double latitude = 0;
latitude = GPSCoordinateConversion(GPSHexCoordinate.Substring(0, 8));
return latitude;
}
public static double GetLongitude(string GPSHexCoordinate)
{
double longitude = 0;
longitude = GPSCoordinateConversion(GPSHexCoordinate.Substring(8, 8));
return longitude;
}