The Military Grid Reference System (MGRS) is the geo-coordinate standard used by NATO militaries for locating points on Earth. The MGRS is derived from the Universal Transverse Mercator (UTM) grid system and the Universal Polar Stereographic (UPS) grid system, but uses a different labeling convention.

mgrs grid
Figure 1. The MGRS grid is included in the Symbology sample

Formatting and parsing points to/from MGRS

To format and parse a PointPointPoint to/from MGRS strings, use an MgrsFormatMgrsFormatMgrsFormat.

Program: Use an MgrsFormatMgrsFormatMgrsFormat to format points to MGRS strings
MgrsFormat mgrsFormat = MgrsFormat::newBuilder()
    .precision(MgrsFormatPrecision::Precision1M)
    .formatType(MgrsFormatType::Mgrs)
    .zoneSeparator(" ")
    .coordinateSeparator(" ")
    .build();
auto wgs84 = CoordinateReferenceProvider::create("EPSG:4326");
auto point = Point(wgs84.value(), {5, 45, 0});
auto stringResult = mgrsFormat.format(point);

auto parsed = mgrsFormat.parse(stringResult.value());
MgrsFormat mgrsFormat = MgrsFormat.NewBuilder()
                                      .Precision(MgrsFormatPrecision.Precision1M)
                                      .FormatType(MgrsFormatType.Mgrs)
                                      .ZoneSeparator(" ")
                                      .CoordinateSeparator(" ")
                                      .Build();
CoordinateReference wgs84 = CoordinateReferenceProvider.Create("EPSG:4326");
Point point = GeometryFactory.CreatePoint(wgs84, 5, 45, 0);
string stringResult = mgrsFormat.Format(point);

Point parsed = mgrsFormat.Parse(stringResult);
MgrsFormat mgrsFormat = MgrsFormat.newBuilder()
                                  .precision(MgrsFormatPrecision.Precision1M)
                                  .formatType(MgrsFormatType.Mgrs)
                                  .zoneSeparator(" ")
                                  .coordinateSeparator(" ")
                                  .build();
CoordinateReference wgs84 = CoordinateReferenceProvider.create("EPSG:4326");
Point point = GeometryFactory.createPoint(wgs84, 5, 45, 0);
String stringResult = mgrsFormat.format(point);

Point parsed = mgrsFormat.parse(stringResult);

For example, you can use this to show MGRS coordinates at the mouse location. See the Symbology sample for a demonstration.

Visualizing an MGRS grid

You can visualize the MGRS grid by using MgrsGridMgrsGridMgrsGrid and MgrsGridLayerMgrsGridLayerMgrsGridLayer.

In order of increasing complexity, you can:

  • Use the default, out-of-the-box grid styling:

Program: Use the default MgrsGridMgrsGridMgrsGrid with an MgrsGridLayerMgrsGridLayerMgrsGridLayer to show an MGRS grid on the map
auto mgrsGridLayer = MgrsGridLayer::newBuilder().build();
map->getLayerList()->add(mgrsGridLayer);
MgrsGridLayer mgrsGridLayer = MgrsGridLayer.NewBuilder().Build();
map.LayerList.Add(mgrsGridLayer);
MgrsGridLayer mgrsGridLayer = MgrsGridLayer.newBuilder().build();
map.getLayerList().add(mgrsGridLayer);
  • Do some basic tweaks to the default styling, like changing line colors.

Program: Basic tweaks to the default MgrsGridMgrsGridMgrsGrid
Color primaryColor = Color::white();
Color secondaryColor = Color::green();
Color tertiaryColor = Color::yellow();
auto primaryLabelStyle = TextStyle::newBuilder() //
                             .fontSize(12)
                             .fontName("monospace")
                             .textColor(primaryColor)
                             .haloWidth(1.0)
                             .haloColor(Color::black())
                             .build();
auto secondaryLabelStyle = TextStyle::newBuilder() //
                               .fontSize(14)
                               .fontName("monospace")
                               .textColor(secondaryColor)
                               .haloWidth(1.0)
                               .haloColor(Color::black())
                               .build();
auto tertiaryLabelStyle = TextStyle::newBuilder() //
                              .fontSize(16)
                              .fontName("monospace")
                              .textColor(tertiaryColor)
                              .haloWidth(1.0)
                              .haloColor(Color::black())
                              .build();
MgrsGrid mgrsGrid = MgrsGrid::newBuilder()
                        .primaryLineStyle(LineStyle::newBuilder().color(primaryColor).width(1.0).build())
                        .primaryLabelStyle(primaryLabelStyle)
                        .secondaryLineStyle(LineStyle::newBuilder().color(secondaryColor).width(2.0).build())
                        .secondaryLabelStyle(secondaryLabelStyle)
                        .tertiaryLineStyle(LineStyle::newBuilder().color(tertiaryColor).width(3.0).build())
                        .tertiaryLabelStyle(tertiaryLabelStyle)
                        .scaleMultiplier(1.5) // make the grid more coarse
                        .build();
auto mgrsGridLayer = MgrsGridLayer::newBuilder().grid(mgrsGrid).build();
map->getLayerList()->add(mgrsGridLayer);
Color primaryColor = Color.White;
Color secondaryColor = Color.Green;
Color tertiaryColor = Color.Blue;
TextStyle primaryLabelStyle = TextStyle.NewBuilder()
    .FontName("monospace")
    .FontSize(12)
    .TextColor(primaryColor)
    .HaloWidth(1)
    .HaloColor(Color.Black)
    .Build();
TextStyle secondaryLabelStyle = TextStyle.NewBuilder()
    .FontName("monospace")
    .FontSize(14)
    .TextColor(secondaryColor)
    .HaloWidth(1)
    .HaloColor(Color.Black)
    .Build();
TextStyle tertiaryLabelStyle = TextStyle.NewBuilder()
    .FontName("monospace")
    .FontSize(16)
    .TextColor(tertiaryColor)
    .HaloWidth(1)
    .HaloColor(Color.Black)
    .Build();
MgrsGrid mgrsGrid = MgrsGrid.NewBuilder()
              .PrimaryLineStyle(LineStyle.NewBuilder().Color(primaryColor).Width(1.0).Build())
              .PrimaryLabelStyle(primaryLabelStyle)
              .SecondaryLineStyle(LineStyle.NewBuilder().Color(secondaryColor).Width(2.0).Build())
              .SecondaryLabelStyle(secondaryLabelStyle)
              .TertiaryLineStyle(LineStyle.NewBuilder().Color(tertiaryColor).Width(3.0).Build())
              .TertiaryLabelStyle(tertiaryLabelStyle)
              .ScaleMultiplier(1.5) // make the grid more coarse
              .Build();

MgrsGridLayer mgrsGridLayer = MgrsGridLayer.NewBuilder().Grid(mgrsGrid).Build();
map.LayerList.Add(mgrsGridLayer);
Color primaryColor = Color.valueOf(Color.WHITE);
Color secondaryColor = Color.valueOf(Color.GREEN);
Color tertiaryColor = Color.valueOf(Color.BLUE);
TextStyle primaryLabelStyle = TextStyle.newBuilder()
                                       .fontSize(12)
                                       .fontName("monospace")
                                       .textColor(primaryColor)
                                       .haloWidth(1)
                                       .haloColor(Color.valueOf(Color.BLACK))
                                       .build();
TextStyle secondaryLabelStyle = TextStyle.newBuilder()
                                         .fontSize(14)
                                         .fontName("monospace")
                                         .textColor(secondaryColor)
                                         .haloWidth(1)
                                         .haloColor(Color.valueOf(Color.BLACK))
                                         .build();
TextStyle tertiaryLabelStyle = TextStyle.newBuilder()
                                        .fontSize(16)
                                        .fontName("monospace")
                                        .textColor(tertiaryColor)
                                        .haloWidth(1)
                                        .haloColor(Color.valueOf(Color.BLACK))
                                        .build();
MgrsGrid mgrsGrid = MgrsGrid.newBuilder()
                            .primaryLineStyle(LineStyle.newBuilder()
                                                       .color(primaryColor)
                                                       .width(1.0)
                                                       .build())
                            .primaryLabelStyle(primaryLabelStyle)
                            .secondaryLineStyle(LineStyle.newBuilder()
                                                         .color(secondaryColor)
                                                         .width(2.0)
                                                         .build())
                            .secondaryLabelStyle(secondaryLabelStyle)
                            .tertiaryLineStyle(LineStyle.newBuilder()
                                                        .color(tertiaryColor)
                                                        .width(3.0)
                                                        .build())
                            .tertiaryLabelStyle(tertiaryLabelStyle)
                            .scaleMultiplier(1.5) // make the grid more coarse
                            .build();
MgrsGridLayer mgrsGridLayer = MgrsGridLayer.newBuilder().grid(mgrsGrid).build();
map.getLayerList().add(mgrsGridLayer);
  • Completely customize the styling of the MGRS grid.

Program: Completely custom MgrsGridMgrsGridMgrsGrid styling
// Styling with completely custom scale ranges and styles

auto labelStyle = TextStyle::newBuilder() // Label style used on all levels
                      .fontSize(20)
                      .fontName("monospace")
                      .textColor(Color::white())
                      .haloColor(Color::black())
                      .haloWidth(1)
                      .build();

// Always show grid zones with thick red lines, regardless of the zoom level
MgrsGridSetting gridZoneSetting = MgrsGridSetting::newBuilder()
                                      .level(MgrsLevel::GridZones)
                                      .scaleRange(MapScale::maxZoomedOut(), MapScale::maxZoomedIn())
                                      .lineStyle(LineStyle::newBuilder() // Thick red line
                                                     .color(Color::red())
                                                     .width(5.0)
                                                     .build())
                                      .labelStyle(labelStyle)
                                      .build();

// When zoomed in far enough, show 100km grid squares in yellow.
// Hide them when zoomed in beyond the 10km grid square scale range start
MapScale startScale100Km = MapScale::fromDenominator(3'000'000.0);
MapScale startScale10Km = MapScale::fromDenominator(750'000.0);
MgrsGridSetting square100KmSetting = MgrsGridSetting::newBuilder()
                                         .level(MgrsLevel::Squares100Km)
                                         .scaleRange(startScale100Km, startScale10Km)
                                         .lineStyle(LineStyle::newBuilder() // Yellow line
                                                        .color(Color::yellow())
                                                        .width(3.0)
                                                        .build())
                                         .labelStyle(labelStyle)
                                         .build();

// When zoomed in beyond the 100km squares, show 10km squares in green
MgrsGridSetting square10KmSetting = MgrsGridSetting::newBuilder()
                                        .level(MgrsLevel::Squares10Km)
                                        .scaleRange(startScale10Km, MapScale::maxZoomedIn())
                                        .lineStyle(LineStyle::newBuilder() // Green line
                                                       .color(Color::green())
                                                       .width(2.0)
                                                       .build())
                                        .labelStyle(labelStyle)
                                        .build();

// Don't show any lower MGRS levels (Squares1Km, Squares100M, Squares10M and Squares1M)

MgrsGrid mgrsGrid = MgrsGrid::newAdvancedBuilder()
                        .setting(gridZoneSetting)    // grid zones
                        .setting(square100KmSetting) // 100km squares
                        .setting(square10KmSetting)  // 10km squares
                        .build();

auto mgrsGridLayer = MgrsGridLayer::newBuilder().grid(mgrsGrid).build();
map->getLayerList()->add(mgrsGridLayer);
// Styling with completely custom scale ranges and styles

TextStyle labelStyle = TextStyle.NewBuilder() // Label style used on all levels
    .FontSize(20)
    .FontName("monospace")
    .TextColor(Color.White)
    .HaloColor(Color.Black)
    .HaloWidth(1)
    .Build();

// Always show grid zones with thick red lines, regardless of the zoom level
MgrsGridSetting gridZoneSetting = MgrsGridSetting.NewBuilder()
                                      .Level(MgrsLevel.GridZones)
                                      .ScaleRange(MapScale.MaxZoomedOut, MapScale.MaxZoomedIn)
                                      .LineStyle(LineStyle.NewBuilder().Color(Color.Red).Width(5.0).Build())
                                      .LabelStyle(labelStyle)
                                      .Build();

// When zoomed in far enough, show 100km grid squares in yellow.
// Hide them when zoomed in beyond the 10km grid square scale range start
MapScale startScale100Km = MapScale.FromDenominator(3_000_000.0);
MapScale startScale10Km = MapScale.FromDenominator(750_000.0);

MgrsGridSetting square100KmSetting = MgrsGridSetting.NewBuilder()
                                         .Level(MgrsLevel.Squares100Km)
                                         .ScaleRange(startScale100Km, startScale10Km)
                                         .LineStyle(LineStyle.NewBuilder().Color(Color.Yellow).Width(3.0).Build())
                                         .LabelStyle(labelStyle)
                                         .Build();

// When zoomed in beyond the 100km squares, show 10km squares in green
MgrsGridSetting square10KmSetting = MgrsGridSetting.NewBuilder()
                                        .Level(MgrsLevel.Squares10Km)
                                        .ScaleRange(startScale10Km, MapScale.MaxZoomedIn)
                                        .LineStyle(LineStyle.NewBuilder().Color(Color.Green).Width(2.0).Build())
                                        .LabelStyle(labelStyle)
                                        .Build();

// Don't show any lower MGRS levels (Squares1Km, Squares100M, Squares10M and Squares1M)

MgrsGrid mgrsGrid = MgrsGrid.NewAdvancedBuilder()
                        .Setting(gridZoneSetting)    // grid zones
                        .Setting(square100KmSetting) // 100km squares
                        .Setting(square10KmSetting)  // 10km squares
                        .Build();

MgrsGridLayer mgrsGridLayer = MgrsGridLayer.NewBuilder().Grid(mgrsGrid).Build();
map.LayerList.Add(mgrsGridLayer);
// Styling with completely custom scale ranges and styles

TextStyle labelStyle = TextStyle.newBuilder() // Label style used on all levels
                                .fontSize(20)
                                .fontName("monospace")
                                .textColor(Color.valueOf(Color.WHITE))
                                .haloColor(Color.valueOf(Color.BLACK))
                                .haloWidth(1)
                                .build();

// Always show grid zones with thick red lines, regardless of the zoom level
MgrsGridSetting gridZoneSetting = MgrsGridSetting.newBuilder()
                                                 .level(MgrsLevel.GridZones)
                                                 .scaleRange(MapScale.MaxZoomedOut, MapScale.MaxZoomedIn)
                                                 .lineStyle(LineStyle.newBuilder()
                                                                     .color(Color.valueOf(Color.RED))
                                                                     .width(5.0)
                                                                     .build())
                                                 .labelStyle(labelStyle)
                                                 .build();

// When zoomed in far enough, show 100km grid squares in yellow.
// Hide them when zoomed in beyond the 10km grid square scale range start
MapScale startScale100Km = MapScale.fromDenominator(3_000_000.0);
MapScale startScale10Km = MapScale.fromDenominator(750_000.0);
MgrsGridSetting square100KmSetting = MgrsGridSetting.newBuilder()
                                                    .level(MgrsLevel.Squares100Km)
                                                    .scaleRange(startScale100Km, startScale10Km)
                                                    .lineStyle(LineStyle.newBuilder()
                                                                        .color(Color.valueOf(Color.YELLOW))
                                                                        .width(3.0)
                                                                        .build())
                                                    .labelStyle(labelStyle)
                                                    .build();

// When zoomed in beyond the 100km squares, show 10km squares in green
MgrsGridSetting square10KmSetting = MgrsGridSetting.newBuilder()
                                                   .level(MgrsLevel.Squares10Km)
                                                   .scaleRange(startScale10Km, MapScale.MaxZoomedIn)
                                                   .lineStyle(LineStyle.newBuilder()
                                                                       .color(Color.valueOf(Color.GREEN))
                                                                       .width(2.0)
                                                                       .build())
                                                   .labelStyle(labelStyle)
                                                   .build();

// Don't show any lower MGRS levels (Squares1Km, Squares100M, Squares10M and Squares1M)

MgrsGrid mgrsGrid = MgrsGrid.newAdvancedBuilder()
                            .setting(gridZoneSetting)    // grid zones
                            .setting(square100KmSetting) // 100km squares
                            .setting(square10KmSetting)  // 10km squares
                            .build();

MgrsGridLayer mgrsGridLayer = MgrsGridLayer.newBuilder().grid(mgrsGrid).build();
map.getLayerList().add(mgrsGridLayer);

Adding an MGRS overview label to the map

When users zoom in far on the map, it’s easy for them to lose track of the grid zone or square that they’re in. To prevent that, you can show an overview label on the map. This label shows the users which grid zone and square they have reached by zooming in on the map. When you use the overview label combined with the grid labels and the mouse coordinate readout, you give the users more than one option for determining their current MGRS location.

mgrs grid overview
Figure 2. The Symbology sample shows an overview label at the top when users zoom in. It informs the users that they zoomed in on the 19T grid zone, in the CG square. The grid lines tell them the northing — 83-85 — and easting — 31-37 . The mouse coordinate readout at the bottom also shows them the exact MGRS coordinates under the mouse cursor.

The LuciadCPillar API gives you a utility class to generate the text for the MGRS overview label: MgrsGridTextProviderMgrsGridTextProviderMgrsGridTextProvider. It fires events whenever the overview label should change its text with a new formatted location string. You can use this utility in a UI framework of your choice.

Program: Add an MgrsGridTextProviderMgrsGridTextProviderMgrsGridTextProvider to the map and start listening to it.
auto textProvider = MgrsGridTextProvider(map);

textProvider.addCallback(
    MgrsGridTextProvider::ICallback::create([](const std::string& text) {
      std::cout << "New MGRS location text = " << text << "\n";
    }));
// Implement ICallback
private class MyCallback : MgrsGridTextProvider.ICallback
{
    public void OnTextChanged(string text)
    {
        Console.WriteLine("New MGRS location text = " + text);
    }
}

// Create a MgrsGridTextProvider and register the callback
var textProvider = new MgrsGridTextProvider(map);
var callback = new MyCallback();
textProvider.AddCallback(callback);
MgrsGridTextProvider textProvider = new MgrsGridTextProvider(map);

textProvider.addCallback(new MgrsGridTextProvider.ICallback() {
    @Override
    public void onTextChanged(@NotNull String text) {
        Log.d("MGRS", "New MGRS location text = " + text);
    }
});