From 5b597e29eb1ea7a5ff96b28cd5e8fe019cc65948 Mon Sep 17 00:00:00 2001 From: Denny Sheirer Date: Fri, 21 Nov 2025 10:22:35 -0500 Subject: [PATCH] #2300 Fixes Motorola unit GPS parsing, fixes P25P1 message viewer issue, and restores map center on selected coordinate in track history. (#2307) Co-authored-by: denny --- .../dsheirer/gui/viewer/P25P1Viewer.java | 1 + .../java/io/github/dsheirer/map/MapPanel.java | 34 ++++++++--------- .../lc/motorola/LCMotorolaUnitGPS.java | 37 +++++++++---------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/main/java/io/github/dsheirer/gui/viewer/P25P1Viewer.java b/src/main/java/io/github/dsheirer/gui/viewer/P25P1Viewer.java index 22257bde..061d5aa4 100644 --- a/src/main/java/io/github/dsheirer/gui/viewer/P25P1Viewer.java +++ b/src/main/java/io/github/dsheirer/gui/viewer/P25P1Viewer.java @@ -170,6 +170,7 @@ public class P25P1Viewer extends VBox Broadcaster messageBroadcaster = new Broadcaster<>(); messageFramer.setListener(messageBroadcaster); + messageFramer.start(); messageBroadcaster.addListener(messageProcessor); Channel empty = new Channel("Empty"); diff --git a/src/main/java/io/github/dsheirer/map/MapPanel.java b/src/main/java/io/github/dsheirer/map/MapPanel.java index f79fa930..65eb2dcc 100644 --- a/src/main/java/io/github/dsheirer/map/MapPanel.java +++ b/src/main/java/io/github/dsheirer/map/MapPanel.java @@ -1,6 +1,6 @@ /* * ***************************************************************************** - * Copyright (C) 2014-2024 Dennis Sheirer + * Copyright (C) 2014-2025 Dennis Sheirer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +26,9 @@ import io.github.dsheirer.identifier.IdentifierClass; import io.github.dsheirer.identifier.Role; import io.github.dsheirer.settings.MapViewSetting; import io.github.dsheirer.settings.SettingsManager; +import java.awt.EventQueue; +import java.util.ArrayList; +import java.util.List; import net.miginfocom.swing.MigLayout; import org.jdesktop.swingx.JXMapViewer; import org.jdesktop.swingx.OSMTileFactoryInfo; @@ -49,9 +52,6 @@ import javax.swing.SpinnerNumberModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.TableModelEvent; -import java.awt.EventQueue; -import java.util.ArrayList; -import java.util.List; /** * Swing map panel. @@ -218,19 +218,19 @@ public class MapPanel extends JPanel implements IPlottableUpdateListener if(mTrackHistoryTable == null) { mTrackHistoryTable = new JTable(mTrackHistoryModel); -// mTrackHistoryTable.getSelectionModel().addListSelectionListener(e -> -// { -// if(getCenterOnSelectedCheckBox().isSelected()) -// { -// int modelIndex = getTrackHistoryTable().convertRowIndexToModel(getTrackHistoryTable().getSelectedRow()); -// TimestampedGeoPosition geo = mTrackHistoryModel.get(modelIndex); -// -// if(geo != null) -// { -// mMapViewer.setCenterPosition(geo); -// } -// } -// }); + mTrackHistoryTable.getSelectionModel().addListSelectionListener(e -> + { + if(getCenterOnSelectedCheckBox().isSelected()) + { + int modelIndex = getTrackHistoryTable().convertRowIndexToModel(getTrackHistoryTable().getSelectedRow()); + TimestampedGeoPosition geo = mTrackHistoryModel.get(modelIndex); + + if(geo != null) + { + mMapViewer.setCenterPosition(geo); + } + } + }); } return mTrackHistoryTable; diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/motorola/LCMotorolaUnitGPS.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/motorola/LCMotorolaUnitGPS.java index 61b2abf8..8c0da7b6 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/motorola/LCMotorolaUnitGPS.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase1/message/lc/motorola/LCMotorolaUnitGPS.java @@ -19,8 +19,9 @@ package io.github.dsheirer.module.decode.p25.phase1.message.lc.motorola; +import io.github.dsheirer.bits.BinaryMessage; import io.github.dsheirer.bits.CorrectedBinaryMessage; -import io.github.dsheirer.bits.FragmentedIntField; +import io.github.dsheirer.bits.IntField; import io.github.dsheirer.identifier.Identifier; import io.github.dsheirer.module.decode.dmr.identifier.P25Location; import io.github.dsheirer.module.decode.p25.phase1.message.lc.LinkControlWord; @@ -35,10 +36,11 @@ public class LCMotorolaUnitGPS extends LinkControlWord { private static final double LATITUDE_MULTIPLIER = 90.0 / 0x7FFFFF; private static final double LONGITUDE_MULTIPLIER = 180.0 / 0x7FFFFF; - private static final FragmentedIntField LATITUDE_TWOS_COMPLEMENT = FragmentedIntField.of(24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47); - private static final FragmentedIntField LONGITUDE_TWOS_COMPLEMENT = FragmentedIntField.of(48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71); + + private static final int LATITUDE_SIGN = 24; + private static final IntField LATITUDE = IntField.range(25, 47); + private static final int LONGITUDE_SIGN = 48; + private static final IntField LONGITUDE = IntField.range(49, 71); private P25Location mLocation; private GeoPosition mGeoPosition; private List mIdentifiers; @@ -57,6 +59,7 @@ public class LCMotorolaUnitGPS extends LinkControlWord { StringBuilder sb = new StringBuilder(); sb.append("MOTOROLA UNIT GPS LOCATION: ").append(getLatitude()).append(" ").append(getLongitude()); + sb.append(" MSG:").append(getMessage()); return sb.toString(); } @@ -94,7 +97,7 @@ public class LCMotorolaUnitGPS extends LinkControlWord */ public double getLatitude() { - return parse24BitInteger(getInt(LATITUDE_TWOS_COMPLEMENT)) * LATITUDE_MULTIPLIER; + return getInt(LATITUDE) * LATITUDE_MULTIPLIER * (getMessage().get(LATITUDE_SIGN) ? -1 : 1); } /** @@ -103,7 +106,7 @@ public class LCMotorolaUnitGPS extends LinkControlWord */ public double getLongitude() { - return parse24BitInteger(getInt(LONGITUDE_TWOS_COMPLEMENT)) * LONGITUDE_MULTIPLIER; + return getInt(LONGITUDE) * LONGITUDE_MULTIPLIER + (getMessage().get(LONGITUDE_SIGN) ? -180 : 0); } /** @@ -121,19 +124,15 @@ public class LCMotorolaUnitGPS extends LinkControlWord return mIdentifiers; } - /** - * Parses a 24-bit two-complement number to a signed integer. - * @param value with 24 bits - * @return signed integer value. - */ - public static int parse24BitInteger(int value) + static void main() { - //If high-order bit is set, perform sign extension setting the 8x high order bits as a signed 32-bit integer - if((value & 0x800000) == 0x800000) - { - value |= 0xFF000000; - } + BinaryMessage mick = BinaryMessage.load("000001101001000000000000101100011010110101010011011000101001000001000010"); + BinaryMessage newj = BinaryMessage.load("000001101001000000000000001110010000011010111110110010110011100011000010"); - return value; + LCMotorolaUnitGPS motoMick = new LCMotorolaUnitGPS(new CorrectedBinaryMessage(mick)); + LCMotorolaUnitGPS motoNewJ = new LCMotorolaUnitGPS(new CorrectedBinaryMessage(newj)); + + System.out.println("MICK: " + motoMick); + System.out.println("NEWJ: " + motoNewJ); } }