RtcmMessageType.java

  1. /* Copyright 2002-2022 CS GROUP
  2.  * Licensed to CS GROUP (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.gnss.metric.parser;

  18. import java.util.HashMap;
  19. import java.util.Map;
  20. import java.util.regex.Matcher;
  21. import java.util.regex.Pattern;

  22. import org.orekit.errors.OrekitException;
  23. import org.orekit.errors.OrekitMessages;
  24. import org.orekit.gnss.metric.messages.ParsedMessage;
  25. import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1019;
  26. import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1019Data;
  27. import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1020;
  28. import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1020Data;
  29. import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1042;
  30. import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1042Data;
  31. import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1044;
  32. import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1044Data;
  33. import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1045;
  34. import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1045Data;
  35. import org.orekit.gnss.metric.messages.rtcm.ephemeris.utils.AccuracyProvider;
  36. import org.orekit.gnss.metric.messages.rtcm.ephemeris.utils.GlonassUserRangeAccuracy;
  37. import org.orekit.gnss.metric.messages.rtcm.ephemeris.utils.SignalInSpaceAccuracy;
  38. import org.orekit.gnss.metric.messages.rtcm.ephemeris.utils.UserRangeAccuracy;
  39. import org.orekit.propagation.analytical.gnss.data.BeidouNavigationMessage;
  40. import org.orekit.propagation.analytical.gnss.data.GLONASSNavigationMessage;
  41. import org.orekit.propagation.analytical.gnss.data.GPSNavigationMessage;
  42. import org.orekit.propagation.analytical.gnss.data.GalileoNavigationMessage;
  43. import org.orekit.propagation.analytical.gnss.data.QZSSNavigationMessage;

  44. /** Enum containing the supported RTCM messages types.
  45. *
  46. * @author Luc Maisonobe
  47. * @author Bryan Cazabonne
  48. *
  49. * @see "RTCM STANDARD 10403.3, DIFFERENTIAL GNSS (GLOBAL NAVIGATION SATELLITE SYSTEMS) SERVICES – VERSION 3, October 2016."
  50. *
  51. * @since 11.0
  52. */
  53. public enum RtcmMessageType implements MessageType {

  54.     /** GPS Ephemeris message. */
  55.     RTCM_1019("1019") {

  56.         /** {@inheritDoc} */
  57.         @Override
  58.         public ParsedMessage parse(final EncodedMessage encodedMessage,
  59.                                    final int messageNumber) {

  60.             // Initialize data container and navigation message
  61.             final Rtcm1019Data         rtcm1019Data  = new Rtcm1019Data();
  62.             final GPSNavigationMessage gpsNavMessage = new GPSNavigationMessage();

  63.             // Set the satellite ID
  64.             final int gpsId = RtcmDataField.DF009.intValue(encodedMessage);
  65.             rtcm1019Data.setSatelliteID(gpsId);

  66.             // Week number
  67.             final int gpsWeekNumber = RtcmDataField.DF076.intValue(encodedMessage);
  68.             gpsNavMessage.setWeek(gpsWeekNumber);

  69.             // Accuracy provider
  70.             final AccuracyProvider gpsProvider = new UserRangeAccuracy(RtcmDataField.DF077.intValue(encodedMessage));
  71.             rtcm1019Data.setAccuracyProvider(gpsProvider);
  72.             gpsNavMessage.setSvAccuracy(gpsProvider.getAccuracy());

  73.             // GPS Code on L2
  74.             rtcm1019Data.setGpsCodeOnL2(RtcmDataField.DF078.intValue(encodedMessage));

  75.             // Fill navigation message
  76.             gpsNavMessage.setPRN(gpsId);
  77.             gpsNavMessage.setIDot(RtcmDataField.DF079.doubleValue(encodedMessage));
  78.             gpsNavMessage.setIODE(RtcmDataField.DF071.intValue(encodedMessage));
  79.             rtcm1019Data.setGpsToc(RtcmDataField.DF081.doubleValue(encodedMessage));
  80.             gpsNavMessage.setAf2(RtcmDataField.DF082.doubleValue(encodedMessage));
  81.             gpsNavMessage.setAf1(RtcmDataField.DF083.doubleValue(encodedMessage));
  82.             gpsNavMessage.setAf0(RtcmDataField.DF084.doubleValue(encodedMessage));
  83.             gpsNavMessage.setIODC(RtcmDataField.DF085.intValue(encodedMessage));
  84.             gpsNavMessage.setCrs(RtcmDataField.DF086.doubleValue(encodedMessage));
  85.             gpsNavMessage.setDeltaN(RtcmDataField.DF087.doubleValue(encodedMessage));
  86.             gpsNavMessage.setM0(RtcmDataField.DF088.doubleValue(encodedMessage));
  87.             gpsNavMessage.setCuc(RtcmDataField.DF089.doubleValue(encodedMessage));
  88.             gpsNavMessage.setE(RtcmDataField.DF090.doubleValue(encodedMessage));
  89.             gpsNavMessage.setCus(RtcmDataField.DF091.doubleValue(encodedMessage));
  90.             gpsNavMessage.setSqrtA(RtcmDataField.DF092.doubleValue(encodedMessage));
  91.             gpsNavMessage.setTime(RtcmDataField.DF093.doubleValue(encodedMessage));
  92.             gpsNavMessage.setCic(RtcmDataField.DF094.doubleValue(encodedMessage));
  93.             gpsNavMessage.setOmega0(RtcmDataField.DF095.doubleValue(encodedMessage));
  94.             gpsNavMessage.setCis(RtcmDataField.DF096.doubleValue(encodedMessage));
  95.             gpsNavMessage.setI0(RtcmDataField.DF097.doubleValue(encodedMessage));
  96.             gpsNavMessage.setCrc(RtcmDataField.DF098.doubleValue(encodedMessage));
  97.             gpsNavMessage.setPa(RtcmDataField.DF099.doubleValue(encodedMessage));
  98.             gpsNavMessage.setOmegaDot(RtcmDataField.DF100.doubleValue(encodedMessage));
  99.             gpsNavMessage.setTGD(RtcmDataField.DF101.doubleValue(encodedMessage));
  100.             gpsNavMessage.setSvHealth(RtcmDataField.DF102.intValue(encodedMessage));

  101.             // Set the navigation message
  102.             rtcm1019Data.setGpsNavigationMessage(gpsNavMessage);

  103.             // L2 P data flag and fit interval
  104.             rtcm1019Data.setGpsL2PDataFlag(RtcmDataField.DF103.booleanValue(encodedMessage));
  105.             rtcm1019Data.setGpsFitInterval(RtcmDataField.DF137.intValue(encodedMessage));

  106.             // Return the parsed message
  107.             return new Rtcm1019(1019, rtcm1019Data);

  108.         }

  109.     },

  110.     /** GLONASS Ephemeris message. */
  111.     RTCM_1020("1020") {

  112.         /** {@inheritDoc} */
  113.         @Override
  114.         public ParsedMessage parse(final EncodedMessage encodedMessage,
  115.                                    final int messageNumber) {

  116.             // Initialize data container and navigation message
  117.             final Rtcm1020Data             rtcm1020Data      = new Rtcm1020Data();
  118.             final GLONASSNavigationMessage glonassNavMessage = new GLONASSNavigationMessage();

  119.             // Set the satellite ID
  120.             final int glonassId = RtcmDataField.DF038.intValue(encodedMessage);
  121.             rtcm1020Data.setSatelliteID(glonassId);

  122.             // Read data
  123.             glonassNavMessage.setPRN(glonassId);
  124.             glonassNavMessage.setFrequencyNumber(RtcmDataField.DF040.intValue(encodedMessage));
  125.             glonassNavMessage.setHealth(RtcmDataField.DF104.intValue(encodedMessage));
  126.             rtcm1020Data.setHealthAvailabilityIndicator(RtcmDataField.DF105.booleanValue(encodedMessage));
  127.             rtcm1020Data.setP1(RtcmDataField.DF106.intValue(encodedMessage));
  128.             rtcm1020Data.setTk(RtcmDataField.DF107.doubleValue(encodedMessage));
  129.             rtcm1020Data.setBN(RtcmDataField.DF108.intValue(encodedMessage));
  130.             rtcm1020Data.setP2(RtcmDataField.DF109.intValue(encodedMessage));
  131.             glonassNavMessage.setTime(RtcmDataField.DF110.doubleValue(encodedMessage));
  132.             glonassNavMessage.setXDot(RtcmDataField.DF111.doubleValue(encodedMessage));
  133.             glonassNavMessage.setX(RtcmDataField.DF112.doubleValue(encodedMessage));
  134.             glonassNavMessage.setXDotDot(RtcmDataField.DF113.doubleValue(encodedMessage));
  135.             glonassNavMessage.setYDot(RtcmDataField.DF114.doubleValue(encodedMessage));
  136.             glonassNavMessage.setY(RtcmDataField.DF115.doubleValue(encodedMessage));
  137.             glonassNavMessage.setYDotDot(RtcmDataField.DF116.doubleValue(encodedMessage));
  138.             glonassNavMessage.setZDot(RtcmDataField.DF117.doubleValue(encodedMessage));
  139.             glonassNavMessage.setZ(RtcmDataField.DF118.doubleValue(encodedMessage));
  140.             glonassNavMessage.setZDotDot(RtcmDataField.DF119.doubleValue(encodedMessage));
  141.             rtcm1020Data.setP3(RtcmDataField.DF120.intValue(encodedMessage));
  142.             glonassNavMessage.setGammaN(RtcmDataField.DF121.doubleValue(encodedMessage));
  143.             rtcm1020Data.setP(RtcmDataField.DF122.intValue(encodedMessage));
  144.             rtcm1020Data.setLNThirdString(RtcmDataField.DF123.intValue(encodedMessage));
  145.             glonassNavMessage.setTauN(RtcmDataField.DF124.doubleValue(encodedMessage));
  146.             rtcm1020Data.setDeltaTN(RtcmDataField.DF125.doubleValue(encodedMessage));
  147.             rtcm1020Data.setEn(RtcmDataField.DF126.intValue(encodedMessage));
  148.             rtcm1020Data.setP4(RtcmDataField.DF127.intValue(encodedMessage));

  149.             // Glonass accuracy
  150.             final int index = RtcmDataField.DF128.intValue(encodedMessage);
  151.             rtcm1020Data.setAccuracyProvider(new GlonassUserRangeAccuracy(index));
  152.             rtcm1020Data.setFT(index);

  153.             // Read other data
  154.             rtcm1020Data.setNt(RtcmDataField.DF129.intValue(encodedMessage));
  155.             rtcm1020Data.setM(RtcmDataField.DF130.intValue(encodedMessage));
  156.             rtcm1020Data.setAreAdditionalDataAvailable(RtcmDataField.DF131.booleanValue(encodedMessage));
  157.             rtcm1020Data.setNA(RtcmDataField.DF132.intValue(encodedMessage));
  158.             rtcm1020Data.setTauC(RtcmDataField.DF133.doubleValue(encodedMessage));
  159.             rtcm1020Data.setN4(RtcmDataField.DF134.intValue(encodedMessage));
  160.             rtcm1020Data.setTauGps(RtcmDataField.DF135.doubleValue(encodedMessage));
  161.             rtcm1020Data.setLNFifthString(RtcmDataField.DF136.intValue(encodedMessage));

  162.             // Set the navigation message
  163.             rtcm1020Data.setGlonassNavigationMessage(glonassNavMessage);

  164.             // Return the parsed message
  165.             return new Rtcm1020(1020, rtcm1020Data);
  166.         }


  167.     },

  168.     /** Beidou Ephemeris message. */
  169.     RTCM_1042("1042") {

  170.         /** {@inheritDoc} */
  171.         @Override
  172.         public ParsedMessage parse(final EncodedMessage encodedMessage,
  173.                                    final int messageNumber) {

  174.             // Initialize data container and navigation message
  175.             final Rtcm1042Data            rtcm1042Data  = new Rtcm1042Data();
  176.             final BeidouNavigationMessage beidouNavMessage = new BeidouNavigationMessage();

  177.             // Set the satellite ID
  178.             final int beidouId = RtcmDataField.DF488.intValue(encodedMessage);
  179.             rtcm1042Data.setSatelliteID(beidouId);

  180.             // Week number
  181.             final int beidouWeekNumber = RtcmDataField.DF489.intValue(encodedMessage);
  182.             beidouNavMessage.setWeek(beidouWeekNumber);

  183.             // Accuracy provider
  184.             final AccuracyProvider beidouProvider = new UserRangeAccuracy(RtcmDataField.DF490.intValue(encodedMessage));
  185.             rtcm1042Data.setAccuracyProvider(beidouProvider);
  186.             beidouNavMessage.setSvAccuracy(beidouProvider.getAccuracy());

  187.             // Fill navigation message
  188.             beidouNavMessage.setPRN(beidouId);
  189.             beidouNavMessage.setIDot(RtcmDataField.DF491.doubleValue(encodedMessage));
  190.             beidouNavMessage.setAODE(RtcmDataField.DF492.intValue(encodedMessage));
  191.             rtcm1042Data.setBeidouToc(RtcmDataField.DF493.doubleValue(encodedMessage));
  192.             beidouNavMessage.setAf2(RtcmDataField.DF494.doubleValue(encodedMessage));
  193.             beidouNavMessage.setAf1(RtcmDataField.DF495.doubleValue(encodedMessage));
  194.             beidouNavMessage.setAf0(RtcmDataField.DF496.doubleValue(encodedMessage));
  195.             beidouNavMessage.setAODC(RtcmDataField.DF497.intValue(encodedMessage));
  196.             beidouNavMessage.setCrs(RtcmDataField.DF498.doubleValue(encodedMessage));
  197.             beidouNavMessage.setDeltaN(RtcmDataField.DF499.doubleValue(encodedMessage));
  198.             beidouNavMessage.setM0(RtcmDataField.DF500.doubleValue(encodedMessage));
  199.             beidouNavMessage.setCuc(RtcmDataField.DF501.doubleValue(encodedMessage));
  200.             beidouNavMessage.setE(RtcmDataField.DF502.doubleValue(encodedMessage));
  201.             beidouNavMessage.setCus(RtcmDataField.DF503.doubleValue(encodedMessage));
  202.             beidouNavMessage.setSqrtA(RtcmDataField.DF504.doubleValue(encodedMessage));
  203.             beidouNavMessage.setTime(RtcmDataField.DF505.doubleValue(encodedMessage));
  204.             beidouNavMessage.setCic(RtcmDataField.DF506.doubleValue(encodedMessage));
  205.             beidouNavMessage.setOmega0(RtcmDataField.DF507.doubleValue(encodedMessage));
  206.             beidouNavMessage.setCis(RtcmDataField.DF508.doubleValue(encodedMessage));
  207.             beidouNavMessage.setI0(RtcmDataField.DF509.doubleValue(encodedMessage));
  208.             beidouNavMessage.setCrc(RtcmDataField.DF510.doubleValue(encodedMessage));
  209.             beidouNavMessage.setPa(RtcmDataField.DF511.doubleValue(encodedMessage));
  210.             beidouNavMessage.setOmegaDot(RtcmDataField.DF512.doubleValue(encodedMessage));
  211.             beidouNavMessage.setTGD1(RtcmDataField.DF513.doubleValue(encodedMessage));
  212.             beidouNavMessage.setTGD2(RtcmDataField.DF514.doubleValue(encodedMessage));
  213.             rtcm1042Data.setSvHealth(RtcmDataField.DF515.intValue(encodedMessage));

  214.             // Set the navigation message
  215.             rtcm1042Data.setBeidouNavigationMessage(beidouNavMessage);

  216.             // Return the parsed message
  217.             return new Rtcm1042(1042, rtcm1042Data);

  218.         }

  219.     },

  220.     /** QZSS Ephemeris message. */
  221.     RTCM_1044("1044") {

  222.         /** {@inheritDoc} */
  223.         @Override
  224.         public ParsedMessage parse(final EncodedMessage encodedMessage,
  225.                                    final int messageNumber) {

  226.             // Initialize data container and navigation message
  227.             final Rtcm1044Data          rtcm1044Data   = new Rtcm1044Data();
  228.             final QZSSNavigationMessage qzssNavMessage = new QZSSNavigationMessage();

  229.             // Set the satellite ID
  230.             final int qzssId = RtcmDataField.DF429.intValue(encodedMessage);
  231.             rtcm1044Data.setSatelliteID(qzssId);

  232.             // Fill navigation message
  233.             qzssNavMessage.setPRN(qzssId);
  234.             rtcm1044Data.setQzssToc(RtcmDataField.DF430.doubleValue(encodedMessage));
  235.             qzssNavMessage.setAf2(RtcmDataField.DF431.doubleValue(encodedMessage));
  236.             qzssNavMessage.setAf1(RtcmDataField.DF432.doubleValue(encodedMessage));
  237.             qzssNavMessage.setAf0(RtcmDataField.DF433.doubleValue(encodedMessage));
  238.             qzssNavMessage.setIODE(RtcmDataField.DF434.intValue(encodedMessage));
  239.             qzssNavMessage.setCrs(RtcmDataField.DF435.doubleValue(encodedMessage));
  240.             qzssNavMessage.setDeltaN(RtcmDataField.DF436.doubleValue(encodedMessage));
  241.             qzssNavMessage.setM0(RtcmDataField.DF437.doubleValue(encodedMessage));
  242.             qzssNavMessage.setCuc(RtcmDataField.DF438.doubleValue(encodedMessage));
  243.             qzssNavMessage.setE(RtcmDataField.DF439.doubleValue(encodedMessage));
  244.             qzssNavMessage.setCus(RtcmDataField.DF440.doubleValue(encodedMessage));
  245.             qzssNavMessage.setSqrtA(RtcmDataField.DF441.doubleValue(encodedMessage));
  246.             qzssNavMessage.setTime(RtcmDataField.DF442.doubleValue(encodedMessage));
  247.             qzssNavMessage.setCic(RtcmDataField.DF443.doubleValue(encodedMessage));
  248.             qzssNavMessage.setOmega0(RtcmDataField.DF444.doubleValue(encodedMessage));
  249.             qzssNavMessage.setCis(RtcmDataField.DF445.doubleValue(encodedMessage));
  250.             qzssNavMessage.setI0(RtcmDataField.DF446.doubleValue(encodedMessage));
  251.             qzssNavMessage.setCrc(RtcmDataField.DF447.doubleValue(encodedMessage));
  252.             qzssNavMessage.setPa(RtcmDataField.DF448.doubleValue(encodedMessage));
  253.             qzssNavMessage.setOmegaDot(RtcmDataField.DF449.doubleValue(encodedMessage));
  254.             qzssNavMessage.setIDot(RtcmDataField.DF450.doubleValue(encodedMessage));

  255.             // QZSS Code on L2
  256.             rtcm1044Data.setQzssCodeOnL2(RtcmDataField.DF451.intValue(encodedMessage));

  257.             // Week number
  258.             qzssNavMessage.setWeek(RtcmDataField.DF452.intValue(encodedMessage));

  259.             // Accuracy provider
  260.             final AccuracyProvider qzssProvider = new UserRangeAccuracy(RtcmDataField.DF453.intValue(encodedMessage));
  261.             rtcm1044Data.setAccuracyProvider(qzssProvider);
  262.             qzssNavMessage.setSvAccuracy(qzssProvider.getAccuracy());

  263.             // Health
  264.             qzssNavMessage.setSvHealth(RtcmDataField.DF454.intValue(encodedMessage));

  265.             // Tgd, IODC, and fit interval
  266.             qzssNavMessage.setTGD(RtcmDataField.DF455.doubleValue(encodedMessage));
  267.             qzssNavMessage.setIODC(RtcmDataField.DF456.intValue(encodedMessage));
  268.             rtcm1044Data.setQzssFitInterval(RtcmDataField.DF457.intValue(encodedMessage));

  269.             // Set the navigation message
  270.             rtcm1044Data.setQzssNavigationMessage(qzssNavMessage);

  271.             // Return the parsed message
  272.             return new Rtcm1044(1044, rtcm1044Data);

  273.         }

  274.     },

  275.     /** Galileo F/NAV Ephemeris message. */
  276.     RTCM_1045("1045") {

  277.         /** {@inheritDoc} */
  278.         @Override
  279.         public ParsedMessage parse(final EncodedMessage encodedMessage,
  280.                                    final int messageNumber) {

  281.             // Initialize data container and navigation message
  282.             final Rtcm1045Data             rtcm1045Data      = new Rtcm1045Data();
  283.             final GalileoNavigationMessage galileoNavMessage = new GalileoNavigationMessage();

  284.             // Set the satellite ID
  285.             final int galileoId = RtcmDataField.DF252.intValue(encodedMessage);
  286.             rtcm1045Data.setSatelliteID(galileoId);

  287.             // Week number
  288.             final int galileoWeekNumber = RtcmDataField.DF289.intValue(encodedMessage);
  289.             galileoNavMessage.setWeek(galileoWeekNumber);

  290.             // IODNav
  291.             galileoNavMessage.setIODNav(RtcmDataField.DF290.intValue(encodedMessage));

  292.             // Accuracy provider
  293.             final AccuracyProvider galileoProvider = new SignalInSpaceAccuracy(RtcmDataField.DF291.intValue(encodedMessage));
  294.             rtcm1045Data.setAccuracyProvider(galileoProvider);
  295.             galileoNavMessage.setSisa(galileoProvider.getAccuracy());

  296.             // Fill navigation message
  297.             galileoNavMessage.setPRN(galileoId);
  298.             galileoNavMessage.setIDot(RtcmDataField.DF292.doubleValue(encodedMessage));
  299.             rtcm1045Data.setGalileoToc(RtcmDataField.DF293.doubleValue(encodedMessage));
  300.             galileoNavMessage.setAf2(RtcmDataField.DF294.doubleValue(encodedMessage));
  301.             galileoNavMessage.setAf1(RtcmDataField.DF295.doubleValue(encodedMessage));
  302.             galileoNavMessage.setAf0(RtcmDataField.DF296.doubleValue(encodedMessage));
  303.             galileoNavMessage.setCrs(RtcmDataField.DF297.doubleValue(encodedMessage));
  304.             galileoNavMessage.setDeltaN(RtcmDataField.DF298.doubleValue(encodedMessage));
  305.             galileoNavMessage.setM0(RtcmDataField.DF299.doubleValue(encodedMessage));
  306.             galileoNavMessage.setCuc(RtcmDataField.DF300.doubleValue(encodedMessage));
  307.             galileoNavMessage.setE(RtcmDataField.DF301.doubleValue(encodedMessage));
  308.             galileoNavMessage.setCus(RtcmDataField.DF302.doubleValue(encodedMessage));
  309.             galileoNavMessage.setSqrtA(RtcmDataField.DF303.doubleValue(encodedMessage));
  310.             galileoNavMessage.setTime(RtcmDataField.DF304.doubleValue(encodedMessage));
  311.             galileoNavMessage.setCic(RtcmDataField.DF305.doubleValue(encodedMessage));
  312.             galileoNavMessage.setOmega0(RtcmDataField.DF306.doubleValue(encodedMessage));
  313.             galileoNavMessage.setCis(RtcmDataField.DF307.doubleValue(encodedMessage));
  314.             galileoNavMessage.setI0(RtcmDataField.DF308.doubleValue(encodedMessage));
  315.             galileoNavMessage.setCrc(RtcmDataField.DF309.doubleValue(encodedMessage));
  316.             galileoNavMessage.setPa(RtcmDataField.DF310.doubleValue(encodedMessage));
  317.             galileoNavMessage.setOmegaDot(RtcmDataField.DF311.doubleValue(encodedMessage));
  318.             galileoNavMessage.setBGDE1E5a(RtcmDataField.DF312.doubleValue(encodedMessage));
  319.             galileoNavMessage.setSvHealth(RtcmDataField.DF314.intValue(encodedMessage));

  320.             // Set the navigation message
  321.             rtcm1045Data.setGalileoNavigationMessage(galileoNavMessage);

  322.             // NAV data validity status
  323.             rtcm1045Data.setGalileoDataValidityStatus(RtcmDataField.DF315.intValue(encodedMessage));

  324.             // Return the parsed message
  325.             return new Rtcm1045(1045, rtcm1045Data);

  326.         }

  327.     };

  328.     /** Codes map. */
  329.     private static final Map<Pattern, RtcmMessageType> CODES_MAP = new HashMap<>();
  330.     static {
  331.         for (final RtcmMessageType type : values()) {
  332.             CODES_MAP.put(type.getPattern(), type);
  333.         }
  334.     }

  335.     /** Message pattern (i.e. allowed message numbers). */
  336.     private final Pattern pattern;

  337.     /** Simple constructor.
  338.      * @param messageRegex message regular expression
  339.      */
  340.     RtcmMessageType(final String messageRegex) {
  341.         this.pattern = Pattern.compile(messageRegex);
  342.     }

  343.     /** Get the message number.
  344.      * @return message number
  345.      */
  346.     public Pattern getPattern() {
  347.         return pattern;
  348.     }

  349.     /** Get the message type corresponding to a message number.
  350.      * @param rtcmNumber message number
  351.      * @return the message type corresponding to the message number
  352.      */
  353.     public static RtcmMessageType getMessageType(final String rtcmNumber) {
  354.         // Try to find a match with an existing message type
  355.         for (Map.Entry<Pattern, RtcmMessageType> rtcmEntry : CODES_MAP.entrySet()) {
  356.             // Matcher
  357.             final Matcher matcher = rtcmEntry.getKey().matcher(rtcmNumber);
  358.             // Check the match !
  359.             if (matcher.matches()) {
  360.                 // return the message type
  361.                 return rtcmEntry.getValue();
  362.             }
  363.         }
  364.         // No match found
  365.         throw new OrekitException(OrekitMessages.UNKNOWN_ENCODED_MESSAGE_NUMBER, rtcmNumber);
  366.     }

  367. }