GPS将16位十六进制值转换为经度和纬度



从设备中,我得到以下类型的十六进制值3305511C0424573C(存储在sql数据库中(。我需要把经度和纬度计算出来。

我还得到了这种格式的经度和纬度值(单精度浮点(:

  • 经度=1083419342
  • 纬度=1112302388

我知道结果是:

  • 经度=4.6146
  • 纬度=51.09688

我试图用C#编写几个转换代码,但所有结果都不正确。

来自sql server的数据:

流ID=15620,GPS0=3305511C0424573C,GPS1=0000000000000000,GPS经度=1083419342,GPS纬度=1112302388

label=GPS经度,单位=度,DataItemType=单精度浮点,精度=0,字节位置=11label=GPS纬度,单位=度,DataItemType=单精度浮点,精度=0,字节位置=12

数据如何进入sql对我来说是个未知数

我如何使用坐标:
<script> var XMarker = L.marker([51.09688, 4.6146]).addTo(mymap); </script>
这是您需要在html或Web应用程序中添加的内容,以便在由leafletjs创建的地图上获得额外的标记(链接: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_tfloat之间的并集。在Pythonstruct.unpack('>f', bytearray.fromhex(hex(your_number)[2:])。C#有BitConverter,您可以在BitConverter文档中看到一个示例。我让对方写一个正确的C#答案。注意:我们仍然需要测试负数,但它们应该是可以的(几个月前,我们在澳大利亚遇到了一个类似的问题,所以是负纬度(。

现在,你问了关于十六进制数字表示的问题,这与第一个问题无关(所以你的软件已经做了如何转换坐标(。

问题是我不能得到精确的坐标,但我的精度高达0.02度。也许还有一个基准转换(你的坐标是WGS84吗,正如GPS所期望的那样?(。或者数据库将坐标转换为不同的基准?

在任何情况下,第二种编码的解决方案:

  • 将字符串分成8个字符的两半。前半部分是纬度,后半部分是经度。

  • 第一组两个字符是度数

  • 第二组两个字符是素数(或分钟(。所以你应该把坐标写成4’36";52.56,3′11〃;35.70;48.77;19.87

  • 那我就不知道了。也许第二组是第二组,然后是两个小数,或者可能是4个小数。

再次:我不知道负纬度或经度是如何编码的。考虑一下,经度可以有360个值,但在两个字符中,最多只能编码256个值。

几个月前,我再也找不到类似的问题了(没有答案(,澳大利亚坐标。这可能有助于证实这一点。但你可以尝试使用更多的坐标,并检查误差(也许可以找出是否也有基准转换[因此有两种不同的坐标约定](。但我认为(只有4个数据(这样的方法已经足够精确了。

从3305511C0424573C到经度=4.6146和纬度=51.09688的转换如下。

  1. 将中的16个字符拆分为两个单独的8个字符的字符串。

  2. 将8个字符长的字符串拆分为4个字节(2个字符长(的字节数组。

  3. 计算如下: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;
}

最新更新