diff --git a/scwx-qt/gl/geo_texture2d.vert b/scwx-qt/gl/geo_texture2d.vert
index 6ac512c7..10d10af7 100644
--- a/scwx-qt/gl/geo_texture2d.vert
+++ b/scwx-qt/gl/geo_texture2d.vert
@@ -14,6 +14,7 @@ layout (location = 3) in vec4  aModulate;
 layout (location = 4) in float aAngleDeg;
 layout (location = 5) in int   aThreshold;
 layout (location = 6) in ivec2 aTimeRange;
+layout (location = 7) in int   aDisplayed;
 
 uniform mat4 uMVPMatrix;
 uniform mat4 uMapMatrix;
@@ -42,8 +43,8 @@ vec2 latLngToScreenCoordinate(in vec2 latLng)
 
 void main()
 {
-   // Always set displayed to true
-   vsOut.displayed = 1;
+   // Pass displayed to the geometry shader
+   vsOut.displayed = aDisplayed;
 
    // Pass the threshold and time range to the geometry shader
    vsOut.threshold = aThreshold;
diff --git a/scwx-qt/res/textures/images/cursor-17.png b/scwx-qt/res/textures/images/cursor-17.png
new file mode 100644
index 00000000..8f6c6dd9
Binary files /dev/null and b/scwx-qt/res/textures/images/cursor-17.png differ
diff --git a/scwx-qt/res/textures/images/dot-3.png b/scwx-qt/res/textures/images/dot-3.png
new file mode 100644
index 00000000..14c3f4bc
Binary files /dev/null and b/scwx-qt/res/textures/images/dot-3.png differ
diff --git a/scwx-qt/scwx-qt.qrc b/scwx-qt/scwx-qt.qrc
index 79d50f23..285594a1 100644
--- a/scwx-qt/scwx-qt.qrc
+++ b/scwx-qt/scwx-qt.qrc
@@ -70,7 +70,9 @@
         res/palettes/wct/ZDR.pal
         res/textures/lines/default-1x7.png
         res/textures/lines/test-pattern.png
+        res/textures/images/cursor-17.png
         res/textures/images/crosshairs-24.png
+        res/textures/images/dot-3.png
         res/textures/images/mapbox-logo.svg
         res/textures/images/maptiler-logo.svg
     
diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp
index 503960fb..622718e3 100644
--- a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp
+++ b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp
@@ -8,6 +8,7 @@
 #include 
 
 #include 
+#include 
 
 namespace scwx
 {
@@ -32,8 +33,10 @@ static constexpr std::size_t kIconBufferLength =
 static constexpr std::size_t kTextureBufferLength =
    kNumTriangles * kVerticesPerTriangle * kPointsPerTexCoord;
 
-// Threshold, start time, end time
-static constexpr std::size_t kIntegersPerVertex_ = 3;
+// Threshold, start time, end time, displayed
+static constexpr std::size_t kIntegersPerVertex_ = 4;
+static constexpr std::size_t kIntegerBufferLength_ =
+   kNumTriangles * kVerticesPerTriangle * kIntegersPerVertex_;
 
 struct GeoIconDrawItem
 {
@@ -42,6 +45,7 @@ struct GeoIconDrawItem
    std::chrono::sys_time endTime_ {};
 
    boost::gil::rgba32f_pixel_t modulate_ {1.0f, 1.0f, 1.0f, 1.0f};
+   bool                        visible_ {true};
    double                      latitude_ {};
    double                      longitude_ {};
    double                      x_ {};
@@ -50,6 +54,8 @@ struct GeoIconDrawItem
    std::string                 iconSheet_ {};
    std::size_t                 iconIndex_ {};
    std::string                 hoverText_ {};
+
+   std::shared_ptr iconInfo_ {};
 };
 
 class GeoIcons::Impl
@@ -82,9 +88,15 @@ public:
 
    ~Impl() {}
 
-   void UpdateBuffers();
-   void UpdateTextureBuffer();
-   void Update(bool textureAtlasChanged);
+   void        UpdateBuffers();
+   static void UpdateSingleBuffer(const std::shared_ptr& di,
+                                  std::size_t                  iconIndex,
+                                  std::vector&          iconBuffer,
+                                  std::vector&          integerBuffer,
+                                  std::vector& hoverIcons);
+   void        UpdateTextureBuffer();
+   void        UpdateModifiedIconBuffers();
+   void        Update(bool textureAtlasChanged);
 
    std::shared_ptr context_;
 
@@ -93,13 +105,16 @@ public:
    bool thresholded_ {false};
    bool lastTextureAtlasChanged_ {false};
 
+   boost::unordered_flat_set> dirtyIcons_ {};
+
    std::chrono::system_clock::time_point selectedTime_ {};
 
    std::mutex iconMutex_;
 
-   boost::unordered_flat_map
+   boost::unordered_flat_map>
       currentIconSheets_ {};
-   boost::unordered_flat_map newIconSheets_ {};
+   boost::unordered_flat_map>
+      newIconSheets_ {};
 
    std::vector> currentIconList_ {};
    std::vector> newIconList_ {};
@@ -240,6 +255,15 @@ void GeoIcons::Initialize()
                              reinterpret_cast(1 * sizeof(GLint)));
    gl.glEnableVertexAttribArray(6);
 
+   // aDisplayed
+   gl.glVertexAttribPointer(7,
+                            1,
+                            GL_INT,
+                            GL_FALSE,
+                            kIntegersPerVertex_ * sizeof(GLint),
+                            reinterpret_cast(3 * sizeof(float)));
+   gl.glEnableVertexAttribArray(7);
+
    p->dirty_ = true;
 }
 
@@ -338,10 +362,11 @@ void GeoIcons::AddIconSheet(const std::string& name,
                             std::int32_t       hotY)
 {
    // Populate icon sheet map
-   p->newIconSheets_.emplace(std::piecewise_construct,
-                             std::tuple {name},
-                             std::forward_as_tuple(types::IconInfo {
-                                name, iconWidth, iconHeight, hotX, hotY}));
+   p->newIconSheets_.emplace(
+      std::piecewise_construct,
+      std::tuple {name},
+      std::forward_as_tuple(std::make_shared(
+         name, iconWidth, iconHeight, hotX, hotY)));
 }
 
 void GeoIcons::FinishIconSheets()
@@ -349,7 +374,7 @@ void GeoIcons::FinishIconSheets()
    // Update icon sheets
    for (auto& iconSheet : p->newIconSheets_)
    {
-      iconSheet.second.UpdateTextureInfo();
+      iconSheet.second->UpdateTextureInfo();
    }
 
    std::unique_lock lock {p->iconMutex_};
@@ -379,12 +404,26 @@ std::shared_ptr GeoIcons::AddIcon()
    return p->newIconList_.emplace_back(std::make_shared());
 }
 
+void GeoIcons::SetIconVisible(const std::shared_ptr& di,
+                              bool                                    visible)
+{
+   if (di->visible_ != visible)
+   {
+      di->visible_ = visible;
+      p->dirtyIcons_.insert(di);
+   }
+}
+
 void GeoIcons::SetIconTexture(const std::shared_ptr& di,
                               const std::string&                      iconSheet,
                               std::size_t                             iconIndex)
 {
-   di->iconSheet_ = iconSheet;
-   di->iconIndex_ = iconIndex;
+   if (di->iconSheet_ != iconSheet || di->iconIndex_ != iconIndex)
+   {
+      di->iconSheet_ = iconSheet;
+      di->iconIndex_ = iconIndex;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void GeoIcons::SetIconLocation(const std::shared_ptr& di,
@@ -393,10 +432,16 @@ void GeoIcons::SetIconLocation(const std::shared_ptr& di,
                                double                        xOffset,
                                double                        yOffset)
 {
-   di->latitude_  = latitude.value();
-   di->longitude_ = longitude.value();
-   di->x_         = xOffset;
-   di->y_         = yOffset;
+   if (di->latitude_ != latitude.value() ||
+       di->longitude_ != longitude.value() || di->x_ != xOffset ||
+       di->y_ != yOffset)
+   {
+      di->latitude_  = latitude.value();
+      di->longitude_ = longitude.value();
+      di->x_         = xOffset;
+      di->y_         = yOffset;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void GeoIcons::SetIconLocation(const std::shared_ptr& di,
@@ -405,37 +450,63 @@ void GeoIcons::SetIconLocation(const std::shared_ptr& di,
                                double xOffset,
                                double yOffset)
 {
-   di->latitude_  = latitude;
-   di->longitude_ = longitude;
-   di->x_         = xOffset;
-   di->y_         = yOffset;
+   if (di->latitude_ != latitude || di->longitude_ != longitude ||
+       di->x_ != xOffset || di->y_ != yOffset)
+   {
+      di->latitude_  = latitude;
+      di->longitude_ = longitude;
+      di->x_         = xOffset;
+      di->y_         = yOffset;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void GeoIcons::SetIconAngle(const std::shared_ptr& di,
                             units::angle::degrees           angle)
 {
-   di->angle_ = angle;
+   if (di->angle_ != angle)
+   {
+      di->angle_ = angle;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void GeoIcons::SetIconModulate(const std::shared_ptr& di,
                                boost::gil::rgba8_pixel_t               modulate)
 {
-   di->modulate_ = {modulate[0] / 255.0f,
-                    modulate[1] / 255.0f,
-                    modulate[2] / 255.0f,
-                    modulate[3] / 255.0f};
+   boost::gil::rgba32f_pixel_t newModulate = {modulate[0] / 255.0f,
+                                              modulate[1] / 255.0f,
+                                              modulate[2] / 255.0f,
+                                              modulate[3] / 255.0f};
+
+   if (di->modulate_ != newModulate)
+   {
+      di->modulate_ = {modulate[0] / 255.0f,
+                       modulate[1] / 255.0f,
+                       modulate[2] / 255.0f,
+                       modulate[3] / 255.0f};
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void GeoIcons::SetIconModulate(const std::shared_ptr& di,
                                boost::gil::rgba32f_pixel_t             modulate)
 {
-   di->modulate_ = modulate;
+   if (di->modulate_ != modulate)
+   {
+      di->modulate_ = modulate;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void GeoIcons::SetIconHoverText(const std::shared_ptr& di,
                                 const std::string&                      text)
 {
-   di->hoverText_ = text;
+   if (di->hoverText_ != text)
+   {
+      di->hoverText_ = text;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void GeoIcons::FinishIcons()
@@ -482,10 +553,11 @@ void GeoIcons::Impl::UpdateBuffers()
          continue;
       }
 
-      auto& icon = it->second;
+      auto& icon    = it->second;
+      di->iconInfo_ = icon;
 
       // Validate icon
-      if (di->iconIndex_ >= icon.numIcons_)
+      if (di->iconIndex_ >= icon->numIcons_)
       {
          // No icon found
          logger_->warn("Invalid icon index: {}", di->iconIndex_);
@@ -495,101 +567,162 @@ void GeoIcons::Impl::UpdateBuffers()
       // Icon is valid, add to valid icon list
       newValidIconList_.push_back(di);
 
-      // Threshold value
-      units::length::nautical_miles threshold = di->threshold_;
-      GLint thresholdValue = static_cast(std::round(threshold.value()));
+      // Update icon buffer
+      UpdateSingleBuffer(di,
+                         newValidIconList_.size() - 1,
+                         newIconBuffer_,
+                         newIntegerBuffer_,
+                         newHoverIcons_);
+   }
 
-      // Start and end time
-      GLint startTime =
-         static_cast(std::chrono::duration_cast(
-                               di->startTime_.time_since_epoch())
-                               .count());
-      GLint endTime =
-         static_cast(std::chrono::duration_cast(
-                               di->endTime_.time_since_epoch())
-                               .count());
+   // All icons have been updated
+   dirtyIcons_.clear();
+}
 
-      // Latitude and longitude coordinates in degrees
-      const float lat = static_cast(di->latitude_);
-      const float lon = static_cast(di->longitude_);
+void GeoIcons::Impl::UpdateSingleBuffer(
+   const std::shared_ptr& di,
+   std::size_t                             iconIndex,
+   std::vector&                     iconBuffer,
+   std::vector&                     integerBuffer,
+   std::vector&            hoverIcons)
+{
+   auto& icon = di->iconInfo_;
 
-      // Base X/Y offsets in pixels
-      const float x = static_cast(di->x_);
-      const float y = static_cast(di->y_);
+   // Threshold value
+   units::length::nautical_miles threshold = di->threshold_;
+   GLint thresholdValue = static_cast(std::round(threshold.value()));
 
-      // Icon size
-      const float iw = static_cast(icon.iconWidth_);
-      const float ih = static_cast(icon.iconHeight_);
+   // Start and end time
+   GLint startTime =
+      static_cast(std::chrono::duration_cast(
+                            di->startTime_.time_since_epoch())
+                            .count());
+   GLint endTime =
+      static_cast(std::chrono::duration_cast(
+                            di->endTime_.time_since_epoch())
+                            .count());
 
-      // Hot X/Y (zero-based icon center)
-      const float hx = static_cast(icon.hotX_);
-      const float hy = static_cast(icon.hotY_);
+   // Latitude and longitude coordinates in degrees
+   const float lat = static_cast(di->latitude_);
+   const float lon = static_cast(di->longitude_);
 
-      // Final X/Y offsets in pixels
-      const float lx = std::roundf(x - hx);
-      const float rx = std::roundf(lx + iw);
-      const float ty = std::roundf(y + hy);
-      const float by = std::roundf(ty - ih);
+   // Base X/Y offsets in pixels
+   const float x = static_cast(di->x_);
+   const float y = static_cast(di->y_);
 
-      // Angle in degrees
-      units::angle::degrees angle = di->angle_;
-      const float                  a     = angle.value();
+   // Icon size
+   const float iw = static_cast(icon->iconWidth_);
+   const float ih = static_cast(icon->iconHeight_);
 
-      // Modulate color
-      const float mc0 = di->modulate_[0];
-      const float mc1 = di->modulate_[1];
-      const float mc2 = di->modulate_[2];
-      const float mc3 = di->modulate_[3];
+   // Hot X/Y (zero-based icon center)
+   const float hx = static_cast(icon->hotX_);
+   const float hy = static_cast(icon->hotY_);
 
-      newIconBuffer_.insert(newIconBuffer_.end(),
-                            {
-                               // Icon
-                               lat, lon, lx, by, mc0, mc1, mc2, mc3, a, // BL
-                               lat, lon, lx, ty, mc0, mc1, mc2, mc3, a, // TL
-                               lat, lon, rx, by, mc0, mc1, mc2, mc3, a, // BR
-                               lat, lon, rx, by, mc0, mc1, mc2, mc3, a, // BR
-                               lat, lon, rx, ty, mc0, mc1, mc2, mc3, a, // TR
-                               lat, lon, lx, ty, mc0, mc1, mc2, mc3, a  // TL
-                            });
-      newIntegerBuffer_.insert(newIntegerBuffer_.end(),
-                               {thresholdValue,
-                                startTime,
-                                endTime,
-                                thresholdValue,
-                                startTime,
-                                endTime,
-                                thresholdValue,
-                                startTime,
-                                endTime,
-                                thresholdValue,
-                                startTime,
-                                endTime,
-                                thresholdValue,
-                                startTime,
-                                endTime,
-                                thresholdValue,
-                                startTime,
-                                endTime});
+   // Final X/Y offsets in pixels
+   const float lx = std::roundf(x - hx);
+   const float rx = std::roundf(lx + iw);
+   const float ty = std::roundf(y + hy);
+   const float by = std::roundf(ty - ih);
 
-      if (!di->hoverText_.empty())
+   // Angle in degrees
+   units::angle::degrees angle = di->angle_;
+   const float                  a     = angle.value();
+
+   // Modulate color
+   const float mc0 = di->modulate_[0];
+   const float mc1 = di->modulate_[1];
+   const float mc2 = di->modulate_[2];
+   const float mc3 = di->modulate_[3];
+
+   // Visibility
+   const GLint v = static_cast(di->visible_);
+
+   // Icon initialize list data
+   const auto iconData = {
+      // Icon
+      lat, lon, lx, by, mc0, mc1, mc2, mc3, a, // BL
+      lat, lon, lx, ty, mc0, mc1, mc2, mc3, a, // TL
+      lat, lon, rx, by, mc0, mc1, mc2, mc3, a, // BR
+      lat, lon, rx, by, mc0, mc1, mc2, mc3, a, // BR
+      lat, lon, rx, ty, mc0, mc1, mc2, mc3, a, // TR
+      lat, lon, lx, ty, mc0, mc1, mc2, mc3, a  // TL
+   };
+   const auto integerData = {thresholdValue, startTime, endTime, v,
+                             thresholdValue, startTime, endTime, v,
+                             thresholdValue, startTime, endTime, v,
+                             thresholdValue, startTime, endTime, v,
+                             thresholdValue, startTime, endTime, v,
+                             thresholdValue, startTime, endTime, v};
+
+   // Buffer position data
+   auto iconBufferPosition = iconBuffer.end();
+   auto iconBufferOffset   = iconIndex * kIconBufferLength;
+
+   auto integerBufferPosition = integerBuffer.end();
+   auto integerBufferOffset   = iconIndex * kIntegerBufferLength_;
+
+   if (iconBufferOffset < iconBuffer.size())
+   {
+      iconBufferPosition = iconBuffer.begin() + iconBufferOffset;
+   }
+   if (integerBufferOffset < integerBuffer.size())
+   {
+      integerBufferPosition = integerBuffer.begin() + integerBufferOffset;
+   }
+
+   if (iconBufferPosition == iconBuffer.cend())
+   {
+      iconBuffer.insert(iconBufferPosition, iconData);
+   }
+   else
+   {
+      std::copy(iconData.begin(), iconData.end(), iconBufferPosition);
+   }
+
+   if (integerBufferPosition == integerBuffer.cend())
+   {
+      integerBuffer.insert(integerBufferPosition, integerData);
+   }
+   else
+   {
+      std::copy(integerData.begin(), integerData.end(), integerBufferPosition);
+   }
+
+   auto hoverIt = std::find_if(hoverIcons.begin(),
+                               hoverIcons.end(),
+                               [&di](auto& entry) { return entry.di_ == di; });
+
+   if (di->visible_ && !di->hoverText_.empty())
+   {
+      const units::angle::radians radians = angle;
+
+      const auto sc = util::maplibre::LatLongToScreenCoordinate({lat, lon});
+
+      const float cosAngle = cosf(static_cast(radians.value()));
+      const float sinAngle = sinf(static_cast(radians.value()));
+
+      const glm::mat2 rotate {cosAngle, -sinAngle, sinAngle, cosAngle};
+
+      const glm::vec2 otl = rotate * glm::vec2 {lx, ty};
+      const glm::vec2 otr = rotate * glm::vec2 {rx, ty};
+      const glm::vec2 obl = rotate * glm::vec2 {lx, by};
+      const glm::vec2 obr = rotate * glm::vec2 {rx, by};
+
+      if (hoverIt == hoverIcons.end())
       {
-         const units::angle::radians radians = angle;
-
-         const auto sc = util::maplibre::LatLongToScreenCoordinate({lat, lon});
-
-         const float cosAngle = cosf(static_cast(radians.value()));
-         const float sinAngle = sinf(static_cast(radians.value()));
-
-         const glm::mat2 rotate {cosAngle, -sinAngle, sinAngle, cosAngle};
-
-         const glm::vec2 otl = rotate * glm::vec2 {lx, ty};
-         const glm::vec2 otr = rotate * glm::vec2 {rx, ty};
-         const glm::vec2 obl = rotate * glm::vec2 {lx, by};
-         const glm::vec2 obr = rotate * glm::vec2 {rx, by};
-
-         newHoverIcons_.emplace_back(
-            IconHoverEntry {di, sc, otl, otr, obl, obr});
+         hoverIcons.emplace_back(IconHoverEntry {di, sc, otl, otr, obl, obr});
       }
+      else
+      {
+         hoverIt->otl_ = otl;
+         hoverIt->otr_ = otr;
+         hoverIt->obl_ = obl;
+         hoverIt->obr_ = obr;
+      }
+   }
+   else if (hoverIt != hoverIcons.end())
+   {
+      hoverIcons.erase(hoverIt);
    }
 }
 
@@ -627,7 +760,7 @@ void GeoIcons::Impl::UpdateTextureBuffer()
       auto& icon = it->second;
 
       // Validate icon
-      if (di->iconIndex_ >= icon.numIcons_)
+      if (di->iconIndex_ >= icon->numIcons_)
       {
          // No icon found
          logger_->error("Invalid icon index: {}", di->iconIndex_);
@@ -653,17 +786,17 @@ void GeoIcons::Impl::UpdateTextureBuffer()
       }
 
       // Texture coordinates
-      const std::size_t iconRow    = (di->iconIndex_) / icon.columns_;
-      const std::size_t iconColumn = (di->iconIndex_) % icon.columns_;
+      const std::size_t iconRow    = (di->iconIndex_) / icon->columns_;
+      const std::size_t iconColumn = (di->iconIndex_) % icon->columns_;
 
-      const float iconX = iconColumn * icon.scaledWidth_;
-      const float iconY = iconRow * icon.scaledHeight_;
+      const float iconX = iconColumn * icon->scaledWidth_;
+      const float iconY = iconRow * icon->scaledHeight_;
 
-      const float ls = icon.texture_.sLeft_ + iconX;
-      const float rs = ls + icon.scaledWidth_;
-      const float tt = icon.texture_.tTop_ + iconY;
-      const float bt = tt + icon.scaledHeight_;
-      const float r  = static_cast(icon.texture_.layerId_);
+      const float ls = icon->texture_.sLeft_ + iconX;
+      const float rs = ls + icon->scaledWidth_;
+      const float tt = icon->texture_.tTop_ + iconY;
+      const float bt = tt + icon->scaledHeight_;
+      const float r  = static_cast(icon->texture_.layerId_);
 
       // clang-format off
       textureBuffer_.insert(
@@ -681,17 +814,51 @@ void GeoIcons::Impl::UpdateTextureBuffer()
    }
 }
 
+void GeoIcons::Impl::UpdateModifiedIconBuffers()
+{
+   // Update buffers for modified icons
+   for (auto& di : dirtyIcons_)
+   {
+      // Find modified icon in the current list
+      auto it =
+         std::find(currentIconList_.cbegin(), currentIconList_.cend(), di);
+
+      // Ignore invalid icons
+      if (it == currentIconList_.cend())
+      {
+         continue;
+      }
+
+      auto iconIndex = std::distance(currentIconList_.cbegin(), it);
+
+      UpdateSingleBuffer(di,
+                         iconIndex,
+                         currentIconBuffer_,
+                         currentIntegerBuffer_,
+                         currentHoverIcons_);
+   }
+
+   // Clear list of modified icons
+   if (!dirtyIcons_.empty())
+   {
+      dirtyIcons_.clear();
+      dirty_ = true;
+   }
+}
+
 void GeoIcons::Impl::Update(bool textureAtlasChanged)
 {
    gl::OpenGLFunctions& gl = context_->gl();
 
+   UpdateModifiedIconBuffers();
+
    // If the texture atlas has changed
    if (dirty_ || textureAtlasChanged || lastTextureAtlasChanged_)
    {
       // Update texture coordinates
       for (auto& iconSheet : currentIconSheets_)
       {
-         iconSheet.second.UpdateTextureInfo();
+         iconSheet.second->UpdateTextureInfo();
       }
 
       // Update OpenGL texture buffer data
diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp
index 455f4bd5..4d819681 100644
--- a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp
+++ b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp
@@ -94,6 +94,13 @@ public:
     */
    std::shared_ptr AddIcon();
 
+   /**
+    * @param [in] di Geo icon draw item
+    * @param [in] visible Visibility of the icon
+    */
+   void SetIconVisible(const std::shared_ptr& di,
+                       bool                                    visible);
+
    /**
     * Sets the texture of a geo icon.
     *
@@ -101,9 +108,9 @@ public:
     * @param [in] iconSheet The name of the icon sheet in the texture atlas
     * @param [in] iconIndex The zero-based index of the icon in the icon sheet
     */
-   static void SetIconTexture(const std::shared_ptr& di,
-                              const std::string&                      iconSheet,
-                              std::size_t iconIndex);
+   void SetIconTexture(const std::shared_ptr& di,
+                       const std::string&                      iconSheet,
+                       std::size_t                             iconIndex);
 
    /**
     * Sets the location of a geo icon.
@@ -114,11 +121,11 @@ public:
     * @param [in] xOffset The x-offset of the geo icon in pixels. Default is 0.
     * @param [in] yOffset The y-offset of the geo icon in pixels. Default is 0.
     */
-   static void SetIconLocation(const std::shared_ptr& di,
-                               units::angle::degrees           latitude,
-                               units::angle::degrees longitude,
-                               double                        xOffset = 0.0,
-                               double                        yOffset = 0.0);
+   void SetIconLocation(const std::shared_ptr& di,
+                        units::angle::degrees           latitude,
+                        units::angle::degrees           longitude,
+                        double                                  xOffset = 0.0,
+                        double                                  yOffset = 0.0);
 
    /**
     * Sets the location of a geo icon.
@@ -129,11 +136,11 @@ public:
     * @param [in] xOffset The x-offset of the geo icon in pixels. Default is 0.
     * @param [in] yOffset The y-offset of the geo icon in pixels. Default is 0.
     */
-   static void SetIconLocation(const std::shared_ptr& di,
-                               double                                  latitude,
-                               double longitude,
-                               double xOffset = 0.0,
-                               double yOffset = 0.0);
+   void SetIconLocation(const std::shared_ptr& di,
+                        double                                  latitude,
+                        double                                  longitude,
+                        double                                  xOffset = 0.0,
+                        double                                  yOffset = 0.0);
 
    /**
     * Sets the angle of a geo icon.
@@ -141,8 +148,8 @@ public:
     * @param [in] di Geo icon draw item
     * @param [in] angle Angle in degrees
     */
-   static void SetIconAngle(const std::shared_ptr& di,
-                            units::angle::degrees           angle);
+   void SetIconAngle(const std::shared_ptr& di,
+                     units::angle::degrees           angle);
 
    /**
     * Sets the modulate color of a geo icon.
@@ -150,8 +157,8 @@ public:
     * @param [in] di Geo icon draw item
     * @param [in] modulate Modulate color
     */
-   static void SetIconModulate(const std::shared_ptr& di,
-                               boost::gil::rgba8_pixel_t modulate);
+   void SetIconModulate(const std::shared_ptr& di,
+                        boost::gil::rgba8_pixel_t               modulate);
 
    /**
     * Sets the modulate color of a geo icon.
@@ -159,8 +166,8 @@ public:
     * @param [in] di Geo icon draw item
     * @param [in] modulate Modulate color
     */
-   static void SetIconModulate(const std::shared_ptr& di,
-                               boost::gil::rgba32f_pixel_t modulate);
+   void SetIconModulate(const std::shared_ptr& di,
+                        boost::gil::rgba32f_pixel_t             modulate);
 
    /**
     * Sets the hover text of a geo icon.
@@ -168,8 +175,8 @@ public:
     * @param [in] di Geo icon draw item
     * @param [in] text Hover text
     */
-   static void SetIconHoverText(const std::shared_ptr& di,
-                                const std::string&                      text);
+   void SetIconHoverText(const std::shared_ptr& di,
+                         const std::string&                      text);
 
    /**
     * Finalizes the draw item after adding new icons.
diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp b/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp
index 0f9dd191..e415d24e 100644
--- a/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp
+++ b/scwx-qt/source/scwx/qt/gl/draw/geo_lines.cpp
@@ -136,7 +136,8 @@ void GeoLines::set_thresholded(bool thresholded)
 
 void GeoLines::Initialize()
 {
-   gl::OpenGLFunctions& gl = p->context_->gl();
+   gl::OpenGLFunctions& gl   = p->context_->gl();
+   auto&                gl30 = p->context_->gl30();
 
    p->shaderProgram_ = p->context_->GetShaderProgram(
       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
@@ -215,6 +216,9 @@ void GeoLines::Initialize()
                              reinterpret_cast(1 * sizeof(GLint)));
    gl.glEnableVertexAttribArray(6);
 
+   // aDisplayed
+   gl30.glVertexAttribI1i(7, 1);
+
    p->dirty_ = true;
 }
 
diff --git a/scwx-qt/source/scwx/qt/gl/draw/icons.cpp b/scwx-qt/source/scwx/qt/gl/draw/icons.cpp
index 39dbd9ad..55d8f8f2 100644
--- a/scwx-qt/source/scwx/qt/gl/draw/icons.cpp
+++ b/scwx-qt/source/scwx/qt/gl/draw/icons.cpp
@@ -179,7 +179,7 @@ void Icons::Initialize()
                             reinterpret_cast(8 * sizeof(float)));
    gl.glEnableVertexAttribArray(4);
 
-   // aAngle
+   // aDisplayed
    gl.glVertexAttribPointer(5,
                             1,
                             GL_FLOAT,
@@ -316,57 +316,80 @@ std::shared_ptr Icons::AddIcon()
 void Icons::SetIconVisible(const std::shared_ptr& di,
                            bool                                 visible)
 {
-   di->visible_ = visible;
-   p->dirtyIcons_.insert(di);
+   if (di->visible_ != visible)
+   {
+      di->visible_ = visible;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void Icons::SetIconTexture(const std::shared_ptr& di,
                            const std::string&                   iconSheet,
                            std::size_t                          iconIndex)
 {
-   di->iconSheet_ = iconSheet;
-   di->iconIndex_ = iconIndex;
-   p->dirtyIcons_.insert(di);
+   if (di->iconSheet_ != iconSheet || di->iconIndex_ != iconIndex)
+   {
+      di->iconSheet_ = iconSheet;
+      di->iconIndex_ = iconIndex;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void Icons::SetIconLocation(const std::shared_ptr& di,
                             double                               x,
                             double                               y)
 {
-   di->x_ = x;
-   di->y_ = y;
-   p->dirtyIcons_.insert(di);
+   if (di->x_ != x || di->y_ != y)
+   {
+      di->x_ = x;
+      di->y_ = y;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void Icons::SetIconAngle(const std::shared_ptr& di,
                          units::angle::degrees        angle)
 {
-   di->angle_ = angle;
-   p->dirtyIcons_.insert(di);
+   if (di->angle_ != angle)
+   {
+      di->angle_ = angle;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void Icons::SetIconModulate(const std::shared_ptr& di,
                             boost::gil::rgba8_pixel_t            modulate)
 {
-   di->modulate_ = {modulate[0] / 255.0f,
-                    modulate[1] / 255.0f,
-                    modulate[2] / 255.0f,
-                    modulate[3] / 255.0f};
-   p->dirtyIcons_.insert(di);
+   boost::gil::rgba32f_pixel_t newModulate = {modulate[0] / 255.0f,
+                                              modulate[1] / 255.0f,
+                                              modulate[2] / 255.0f,
+                                              modulate[3] / 255.0f};
+
+   if (di->modulate_ != newModulate)
+   {
+      di->modulate_ = newModulate;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void Icons::SetIconModulate(const std::shared_ptr& di,
                             boost::gil::rgba32f_pixel_t          modulate)
 {
-   di->modulate_ = modulate;
-   p->dirtyIcons_.insert(di);
+   if (di->modulate_ != modulate)
+   {
+      di->modulate_ = modulate;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void Icons::SetIconHoverText(const std::shared_ptr& di,
                              const std::string&                   text)
 {
-   di->hoverText_ = text;
-   p->dirtyIcons_.insert(di);
+   if (di->hoverText_ != text)
+   {
+      di->hoverText_ = text;
+      p->dirtyIcons_.insert(di);
+   }
 }
 
 void Icons::FinishIcons()
diff --git a/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp b/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp
index d343acf3..abc852f8 100644
--- a/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp
+++ b/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp
@@ -161,7 +161,8 @@ void PlacefileIcons::set_thresholded(bool thresholded)
 
 void PlacefileIcons::Initialize()
 {
-   gl::OpenGLFunctions& gl = p->context_->gl();
+   gl::OpenGLFunctions& gl   = p->context_->gl();
+   auto&                gl30 = p->context_->gl30();
 
    p->shaderProgram_ = p->context_->GetShaderProgram(
       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
@@ -251,6 +252,9 @@ void PlacefileIcons::Initialize()
                              reinterpret_cast(1 * sizeof(GLint)));
    gl.glEnableVertexAttribArray(6);
 
+   // aDisplayed
+   gl30.glVertexAttribI1i(7, 1);
+
    p->dirty_ = true;
 }
 
diff --git a/scwx-qt/source/scwx/qt/gl/draw/placefile_images.cpp b/scwx-qt/source/scwx/qt/gl/draw/placefile_images.cpp
index a1fbe032..aafaef8d 100644
--- a/scwx-qt/source/scwx/qt/gl/draw/placefile_images.cpp
+++ b/scwx-qt/source/scwx/qt/gl/draw/placefile_images.cpp
@@ -139,7 +139,8 @@ void PlacefileImages::set_thresholded(bool thresholded)
 
 void PlacefileImages::Initialize()
 {
-   gl::OpenGLFunctions& gl = p->context_->gl();
+   gl::OpenGLFunctions& gl   = p->context_->gl();
+   auto&                gl30 = p->context_->gl30();
 
    p->shaderProgram_ = p->context_->GetShaderProgram(
       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
@@ -220,6 +221,9 @@ void PlacefileImages::Initialize()
                              reinterpret_cast(1 * sizeof(GLint)));
    gl.glEnableVertexAttribArray(6);
 
+   // aDisplayed
+   gl30.glVertexAttribI1i(7, 1);
+
    p->dirty_ = true;
 }
 
diff --git a/scwx-qt/source/scwx/qt/gl/draw/placefile_lines.cpp b/scwx-qt/source/scwx/qt/gl/draw/placefile_lines.cpp
index ced0a41a..8fdce9f1 100644
--- a/scwx-qt/source/scwx/qt/gl/draw/placefile_lines.cpp
+++ b/scwx-qt/source/scwx/qt/gl/draw/placefile_lines.cpp
@@ -131,7 +131,8 @@ void PlacefileLines::set_thresholded(bool thresholded)
 
 void PlacefileLines::Initialize()
 {
-   gl::OpenGLFunctions& gl = p->context_->gl();
+   gl::OpenGLFunctions& gl   = p->context_->gl();
+   auto&                gl30 = p->context_->gl30();
 
    p->shaderProgram_ = p->context_->GetShaderProgram(
       {{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
@@ -209,6 +210,9 @@ void PlacefileLines::Initialize()
                              reinterpret_cast(1 * sizeof(GLint)));
    gl.glEnableVertexAttribArray(6);
 
+   // aDisplayed
+   gl30.glVertexAttribI1i(7, 1);
+
    p->dirty_ = true;
 }
 
diff --git a/scwx-qt/source/scwx/qt/gl/gl_context.cpp b/scwx-qt/source/scwx/qt/gl/gl_context.cpp
index 592d12cb..813225e1 100644
--- a/scwx-qt/source/scwx/qt/gl/gl_context.cpp
+++ b/scwx-qt/source/scwx/qt/gl/gl_context.cpp
@@ -31,7 +31,8 @@ public:
    static std::size_t
    GetShaderKey(std::initializer_list> shaders);
 
-   gl::OpenGLFunctions gl_;
+   gl::OpenGLFunctions  gl_;
+   QOpenGLFunctions_3_0 gl30_;
 
    bool glInitialized_ {false};
 
@@ -56,6 +57,11 @@ gl::OpenGLFunctions& GlContext::gl()
    return p->gl_;
 }
 
+QOpenGLFunctions_3_0& GlContext::gl30()
+{
+   return p->gl30_;
+}
+
 std::uint64_t GlContext::texture_buffer_count() const
 {
    return p->textureBufferCount_;
@@ -68,6 +74,9 @@ void GlContext::Impl::InitializeGL()
       return;
    }
 
+   gl_.initializeOpenGLFunctions();
+   gl30_.initializeOpenGLFunctions();
+
    gl_.glGenTextures(1, &textureAtlas_);
 
    glInitialized_ = true;
@@ -122,6 +131,11 @@ GLuint GlContext::GetTextureAtlas()
    return p->textureAtlas_;
 }
 
+void GlContext::Initialize()
+{
+   p->InitializeGL();
+}
+
 std::size_t GlContext::Impl::GetShaderKey(
    std::initializer_list> shaders)
 {
diff --git a/scwx-qt/source/scwx/qt/gl/gl_context.hpp b/scwx-qt/source/scwx/qt/gl/gl_context.hpp
index b09ff403..1ba74fb8 100644
--- a/scwx-qt/source/scwx/qt/gl/gl_context.hpp
+++ b/scwx-qt/source/scwx/qt/gl/gl_context.hpp
@@ -3,6 +3,8 @@
 #include 
 #include 
 
+#include 
+
 namespace scwx
 {
 namespace qt
@@ -22,7 +24,8 @@ public:
    GlContext(GlContext&&) noexcept;
    GlContext& operator=(GlContext&&) noexcept;
 
-   gl::OpenGLFunctions& gl();
+   gl::OpenGLFunctions&  gl();
+   QOpenGLFunctions_3_0& gl30();
 
    std::uint64_t texture_buffer_count() const;
 
@@ -34,6 +37,8 @@ public:
 
    GLuint GetTextureAtlas();
 
+   void Initialize();
+
 private:
    class Impl;
 
diff --git a/scwx-qt/source/scwx/qt/main/main_window.cpp b/scwx-qt/source/scwx/qt/main/main_window.cpp
index 93ee8f4b..3cedcf98 100644
--- a/scwx-qt/source/scwx/qt/main/main_window.cpp
+++ b/scwx-qt/source/scwx/qt/main/main_window.cpp
@@ -824,6 +824,11 @@ void MainWindowImpl::ConnectMapSignals()
             coordinateLabel_->setText(
                QString("%1, %2").arg(latitude).arg(longitude));
             coordinateLabel_->setVisible(true);
+
+            for (auto& map : maps_)
+            {
+               map->UpdateMouseCoordinate(coordinate);
+            }
          },
          Qt::QueuedConnection);
 
diff --git a/scwx-qt/source/scwx/qt/map/map_context.cpp b/scwx-qt/source/scwx/qt/map/map_context.cpp
index d7e4f224..c659c432 100644
--- a/scwx-qt/source/scwx/qt/map/map_context.cpp
+++ b/scwx-qt/source/scwx/qt/map/map_context.cpp
@@ -32,7 +32,8 @@ public:
    MapProvider mapProvider_ {MapProvider::Unknown};
    std::string mapCopyrights_ {};
 
-   QMargins colorTableMargins_ {};
+   QMargins           colorTableMargins_ {};
+   common::Coordinate mouseCoordinate_ {};
 
    std::shared_ptr overlayProductView_ {nullptr};
    std::shared_ptr   radarProductView_;
@@ -78,6 +79,11 @@ float MapContext::pixel_ratio() const
    return p->pixelRatio_;
 }
 
+common::Coordinate MapContext::mouse_coordinate() const
+{
+   return p->mouseCoordinate_;
+}
+
 std::shared_ptr
 MapContext::overlay_product_view() const
 {
@@ -129,6 +135,11 @@ void MapContext::set_color_table_margins(const QMargins& margins)
    p->colorTableMargins_ = margins;
 }
 
+void MapContext::set_mouse_coordinate(const common::Coordinate& coordinate)
+{
+   p->mouseCoordinate_ = coordinate;
+}
+
 void MapContext::set_overlay_product_view(
    const std::shared_ptr& overlayProductView)
 {
diff --git a/scwx-qt/source/scwx/qt/map/map_context.hpp b/scwx-qt/source/scwx/qt/map/map_context.hpp
index 55136886..86f49b8f 100644
--- a/scwx-qt/source/scwx/qt/map/map_context.hpp
+++ b/scwx-qt/source/scwx/qt/map/map_context.hpp
@@ -2,6 +2,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -43,6 +44,7 @@ public:
    MapSettings&                              settings();
    QMargins                                  color_table_margins() const;
    float                                     pixel_ratio() const;
+   common::Coordinate                        mouse_coordinate() const;
    std::shared_ptr overlay_product_view() const;
    std::shared_ptr   radar_product_view() const;
    common::RadarProductGroup                 radar_product_group() const;
@@ -54,6 +56,7 @@ public:
    void set_map_copyrights(const std::string& copyrights);
    void set_map_provider(MapProvider provider);
    void set_color_table_margins(const QMargins& margins);
+   void set_mouse_coordinate(const common::Coordinate& coordinate);
    void set_overlay_product_view(
       const std::shared_ptr& overlayProductView);
    void set_pixel_ratio(float pixelRatio);
diff --git a/scwx-qt/source/scwx/qt/map/map_widget.cpp b/scwx-qt/source/scwx/qt/map/map_widget.cpp
index 9fb5c253..07b4937d 100644
--- a/scwx-qt/source/scwx/qt/map/map_widget.cpp
+++ b/scwx-qt/source/scwx/qt/map/map_widget.cpp
@@ -224,6 +224,9 @@ public:
    const MapStyle* currentStyle_;
    std::string     initialStyleName_ {};
 
+   Qt::KeyboardModifiers lastKeyboardModifiers_ {
+      Qt::KeyboardModifier::NoModifier};
+
    std::shared_ptr pickedEventHandler_ {nullptr};
 
    uint64_t frameDraws_;
@@ -940,6 +943,24 @@ void MapWidget::SetMapStyle(const std::string& styleName)
    }
 }
 
+void MapWidget::UpdateMouseCoordinate(const common::Coordinate& coordinate)
+{
+   if (p->context_->mouse_coordinate() != coordinate)
+   {
+      p->context_->set_mouse_coordinate(coordinate);
+
+      auto keyboardModifiers = QGuiApplication::keyboardModifiers();
+
+      if (keyboardModifiers != Qt::KeyboardModifier::NoModifier ||
+          keyboardModifiers != p->lastKeyboardModifiers_)
+      {
+         update();
+      }
+
+      p->lastKeyboardModifiers_ = keyboardModifiers;
+   }
+}
+
 qreal MapWidget::pixelRatio()
 {
    return devicePixelRatioF();
@@ -1311,7 +1332,7 @@ void MapWidget::initializeGL()
    logger_->debug("initializeGL()");
 
    makeCurrent();
-   p->context_->gl().initializeOpenGLFunctions();
+   p->context_->Initialize();
 
    // Lock ImGui font atlas prior to new ImGui frame
    std::shared_lock imguiFontAtlasLock {
diff --git a/scwx-qt/source/scwx/qt/map/map_widget.hpp b/scwx-qt/source/scwx/qt/map/map_widget.hpp
index 1b2c1220..76856e83 100644
--- a/scwx-qt/source/scwx/qt/map/map_widget.hpp
+++ b/scwx-qt/source/scwx/qt/map/map_widget.hpp
@@ -117,6 +117,13 @@ public:
    void SetInitialMapStyle(const std::string& styleName);
    void SetMapStyle(const std::string& styleName);
 
+   /**
+    * Updates the coordinates associated with mouse movement from another map.
+    *
+    * @param [in] coordinate Coordinate of the mouse
+    */
+   void UpdateMouseCoordinate(const common::Coordinate& coordinate);
+
 private:
    void  changeStyle();
    qreal pixelRatio();
diff --git a/scwx-qt/source/scwx/qt/map/overlay_layer.cpp b/scwx-qt/source/scwx/qt/map/overlay_layer.cpp
index a088b4dc..4d47eca6 100644
--- a/scwx-qt/source/scwx/qt/map/overlay_layer.cpp
+++ b/scwx-qt/source/scwx/qt/map/overlay_layer.cpp
@@ -19,6 +19,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 #if !defined(_MSC_VER)
@@ -69,6 +70,9 @@ public:
       showMapAttributionCallbackUuid_ =
          generalSettings.show_map_attribution().RegisterValueChangedCallback(
             [this](const bool&) { Q_EMIT self_->NeedsRendering(); });
+      showMapCenterCallbackUuid_ =
+         generalSettings.show_map_center().RegisterValueChangedCallback(
+            [this](const bool&) { Q_EMIT self_->NeedsRendering(); });
       showMapLogoCallbackUuid_ =
          generalSettings.show_map_logo().RegisterValueChangedCallback(
             [this](const bool&) { Q_EMIT self_->NeedsRendering(); });
@@ -84,6 +88,8 @@ public:
          defaultTimeZoneCallbackUuid_);
       generalSettings.show_map_attribution().UnregisterValueChangedCallback(
          showMapAttributionCallbackUuid_);
+      generalSettings.show_map_center().UnregisterValueChangedCallback(
+         showMapCenterCallbackUuid_);
       generalSettings.show_map_logo().UnregisterValueChangedCallback(
          showMapLogoCallbackUuid_);
    }
@@ -93,6 +99,7 @@ public:
    boost::uuids::uuid clockFormatCallbackUuid_;
    boost::uuids::uuid defaultTimeZoneCallbackUuid_;
    boost::uuids::uuid showMapAttributionCallbackUuid_;
+   boost::uuids::uuid showMapCenterCallbackUuid_;
    boost::uuids::uuid showMapLogoCallbackUuid_;
 
    std::shared_ptr positionManager_ {
@@ -108,10 +115,16 @@ public:
       types::GetTextureName(types::ImageTexture::Crosshairs24)};
    std::shared_ptr locationIcon_ {};
 
+   std::shared_ptr cursorIcon_ {};
+
    const std::string& cardinalPointIconName_ {
       types::GetTextureName(types::ImageTexture::CardinalPoint24)};
    const std::string& compassIconName_ {
       types::GetTextureName(types::ImageTexture::Compass24)};
+   const std::string& cursorIconName_ {
+      types::GetTextureName(types::ImageTexture::Dot3)};
+   const std::string& mapCenterIconName_ {
+      types::GetTextureName(types::ImageTexture::Cursor17)};
 
    const std::string& mapboxLogoImageName_ {
       types::GetTextureName(types::ImageTexture::MapboxLogo)};
@@ -119,6 +132,7 @@ public:
       types::GetTextureName(types::ImageTexture::MapTilerLogo)};
 
    std::shared_ptr compassIcon_ {};
+   std::shared_ptr mapCenterIcon_ {};
    double                                  lastBearing_ {0.0};
 
    std::shared_ptr mapLogoIcon_ {};
@@ -168,23 +182,29 @@ void OverlayLayer::Initialize()
 
    // Geo Icons
    p->geoIcons_->StartIconSheets();
+   p->geoIcons_->AddIconSheet(p->cursorIconName_);
    p->geoIcons_->AddIconSheet(p->locationIconName_);
    p->geoIcons_->FinishIconSheets();
 
    p->geoIcons_->StartIcons();
+
+   p->cursorIcon_ = p->geoIcons_->AddIcon();
+   p->geoIcons_->SetIconTexture(p->cursorIcon_, p->cursorIconName_, 0);
+
    p->locationIcon_ = p->geoIcons_->AddIcon();
-   gl::draw::GeoIcons::SetIconTexture(
-      p->locationIcon_, p->locationIconName_, 0);
-   gl::draw::GeoIcons::SetIconAngle(p->locationIcon_,
-                                    units::angle::degrees {45.0});
-   gl::draw::GeoIcons::SetIconLocation(
+   p->geoIcons_->SetIconTexture(p->locationIcon_, p->locationIconName_, 0);
+   p->geoIcons_->SetIconAngle(p->locationIcon_,
+                              units::angle::degrees {45.0});
+   p->geoIcons_->SetIconLocation(
       p->locationIcon_, coordinate.latitude(), coordinate.longitude());
+
    p->geoIcons_->FinishIcons();
 
    // Icons
    p->icons_->StartIconSheets();
    p->icons_->AddIconSheet(p->cardinalPointIconName_);
    p->icons_->AddIconSheet(p->compassIconName_);
+   p->icons_->AddIconSheet(p->mapCenterIconName_);
    p->icons_->AddIconSheet(p->mapboxLogoImageName_)->SetAnchor(0.0f, 1.0f);
    p->icons_->AddIconSheet(p->mapTilerLogoImageName_)->SetAnchor(0.0f, 1.0f);
    p->icons_->FinishIconSheets();
@@ -234,6 +254,9 @@ void OverlayLayer::Initialize()
          }
       });
 
+   p->mapCenterIcon_ = p->icons_->AddIcon();
+   p->icons_->SetIconTexture(p->mapCenterIcon_, p->mapCenterIconName_, 0);
+
    p->mapLogoIcon_ = p->icons_->AddIcon();
    if (context()->map_provider() == MapProvider::Mapbox)
    {
@@ -259,10 +282,9 @@ void OverlayLayer::Initialize()
               if (position.isValid() &&
                   p->currentPosition_.coordinate() != coordinate)
               {
-                 gl::draw::GeoIcons::SetIconLocation(p->locationIcon_,
-                                                     coordinate.latitude(),
-                                                     coordinate.longitude());
-                 p->geoIcons_->FinishIcons();
+                 p->geoIcons_->SetIconLocation(p->locationIcon_,
+                                               coordinate.latitude(),
+                                               coordinate.longitude());
                  Q_EMIT NeedsRendering();
               }
               p->currentPosition_ = position;
@@ -315,9 +337,21 @@ void OverlayLayer::Render(const QMapLibre::CustomLayerRenderParameters& params)
       p->activeBoxInner_->SetBorder(1.0f * pixelRatio, {255, 255, 255, 255});
    }
 
+   // Cursor Icon
+   bool cursorIconVisible = QGuiApplication::keyboardModifiers() &
+                            Qt::KeyboardModifier::ControlModifier;
+   p->geoIcons_->SetIconVisible(p->cursorIcon_, cursorIconVisible);
+   if (cursorIconVisible)
+   {
+      common::Coordinate mouseCoordinate = context()->mouse_coordinate();
+      p->geoIcons_->SetIconLocation(
+         p->cursorIcon_, mouseCoordinate.latitude_, mouseCoordinate.longitude_);
+   }
+
    // Location Icon
-   p->geoIcons_->SetVisible(p->currentPosition_.isValid() &&
-                            p->positionManager_->IsLocationTracked());
+   p->geoIcons_->SetIconVisible(p->locationIcon_,
+                                p->currentPosition_.isValid() &&
+                                   p->positionManager_->IsLocationTracked());
 
    // Compass Icon
    if (params.width != p->lastWidth_ || params.height != p->lastHeight_ ||
@@ -411,6 +445,16 @@ void OverlayLayer::Render(const QMapLibre::CustomLayerRenderParameters& params)
 
    auto& generalSettings = settings::GeneralSettings::Instance();
 
+   // Map Center Icon
+   if (params.width != p->lastWidth_ || params.height != p->lastHeight_)
+   {
+      // Draw the icon in the center of the widget
+      p->icons_->SetIconLocation(
+         p->mapCenterIcon_, params.width / 2.0, params.height / 2.0);
+   }
+   p->icons_->SetIconVisible(p->mapCenterIcon_,
+                             generalSettings.show_map_center().GetValue());
+
    QMargins colorTableMargins = context()->color_table_margins();
    if (colorTableMargins != p->lastColorTableMargins_ || p->firstRender_)
    {
@@ -418,7 +462,6 @@ void OverlayLayer::Render(const QMapLibre::CustomLayerRenderParameters& params)
       p->icons_->SetIconLocation(p->mapLogoIcon_,
                                  10 + colorTableMargins.left(),
                                  10 + colorTableMargins.bottom());
-      p->icons_->FinishIcons();
    }
    p->icons_->SetIconVisible(p->mapLogoIcon_,
                              generalSettings.show_map_logo().GetValue());
diff --git a/scwx-qt/source/scwx/qt/settings/general_settings.cpp b/scwx-qt/source/scwx/qt/settings/general_settings.cpp
index 86544a1e..1a670b9f 100644
--- a/scwx-qt/source/scwx/qt/settings/general_settings.cpp
+++ b/scwx-qt/source/scwx/qt/settings/general_settings.cpp
@@ -58,6 +58,7 @@ public:
       mapboxApiKey_.SetDefault("?");
       maptilerApiKey_.SetDefault("?");
       showMapAttribution_.SetDefault(true);
+      showMapCenter_.SetDefault(false);
       showMapLogo_.SetDefault(true);
       theme_.SetDefault(defaultThemeValue);
       trackLocation_.SetDefault(false);
@@ -122,6 +123,7 @@ public:
    SettingsVariable mapboxApiKey_ {"mapbox_api_key"};
    SettingsVariable maptilerApiKey_ {"maptiler_api_key"};
    SettingsVariable        showMapAttribution_ {"show_map_attribution"};
+   SettingsVariable        showMapCenter_ {"show_map_center"};
    SettingsVariable        showMapLogo_ {"show_map_logo"};
    SettingsVariable theme_ {"theme"};
    SettingsVariable        trackLocation_ {"track_location"};
@@ -147,6 +149,7 @@ GeneralSettings::GeneralSettings() :
                       &p->mapboxApiKey_,
                       &p->maptilerApiKey_,
                       &p->showMapAttribution_,
+                      &p->showMapCenter_,
                       &p->showMapLogo_,
                       &p->theme_,
                       &p->trackLocation_,
@@ -240,6 +243,11 @@ SettingsVariable& GeneralSettings::show_map_attribution() const
    return p->showMapAttribution_;
 }
 
+SettingsVariable& GeneralSettings::show_map_center() const
+{
+   return p->showMapCenter_;
+}
+
 SettingsVariable& GeneralSettings::show_map_logo() const
 {
    return p->showMapLogo_;
@@ -297,6 +305,7 @@ bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs)
            lhs.p->mapboxApiKey_ == rhs.p->mapboxApiKey_ &&
            lhs.p->maptilerApiKey_ == rhs.p->maptilerApiKey_ &&
            lhs.p->showMapAttribution_ == rhs.p->showMapAttribution_ &&
+           lhs.p->showMapCenter_ == rhs.p->showMapCenter_ &&
            lhs.p->showMapLogo_ == rhs.p->showMapLogo_ &&
            lhs.p->theme_ == rhs.p->theme_ &&
            lhs.p->trackLocation_ == rhs.p->trackLocation_ &&
diff --git a/scwx-qt/source/scwx/qt/settings/general_settings.hpp b/scwx-qt/source/scwx/qt/settings/general_settings.hpp
index e11597c7..73d2963e 100644
--- a/scwx-qt/source/scwx/qt/settings/general_settings.hpp
+++ b/scwx-qt/source/scwx/qt/settings/general_settings.hpp
@@ -41,6 +41,7 @@ public:
    SettingsVariable&                mapbox_api_key() const;
    SettingsVariable&                maptiler_api_key() const;
    SettingsVariable&                       show_map_attribution() const;
+   SettingsVariable&                       show_map_center() const;
    SettingsVariable&                       show_map_logo() const;
    SettingsVariable&                theme() const;
    SettingsVariable&                       track_location() const;
diff --git a/scwx-qt/source/scwx/qt/types/texture_types.cpp b/scwx-qt/source/scwx/qt/types/texture_types.cpp
index f38038a7..5f7da52b 100644
--- a/scwx-qt/source/scwx/qt/types/texture_types.cpp
+++ b/scwx-qt/source/scwx/qt/types/texture_types.cpp
@@ -22,6 +22,9 @@ static const std::unordered_map imageTextureInfo_ {
     {"images/compass-24", ":/res/icons/flaticon/compass-24.png"}},
    {ImageTexture::Crosshairs24,
     {"images/crosshairs-24", ":/res/textures/images/crosshairs-24.png"}},
+   {ImageTexture::Cursor17,
+    {"images/cursor-17", ":/res/textures/images/cursor-17.png"}},
+   {ImageTexture::Dot3, {"images/dot-3", ":/res/textures/images/dot-3.png"}},
    {ImageTexture::MapboxLogo,
     {"images/mapbox-logo", ":/res/textures/images/mapbox-logo.svg"}},
    {ImageTexture::MapTilerLogo,
diff --git a/scwx-qt/source/scwx/qt/types/texture_types.hpp b/scwx-qt/source/scwx/qt/types/texture_types.hpp
index be3839ec..593d574d 100644
--- a/scwx-qt/source/scwx/qt/types/texture_types.hpp
+++ b/scwx-qt/source/scwx/qt/types/texture_types.hpp
@@ -16,6 +16,8 @@ enum class ImageTexture
    CardinalPoint24,
    Compass24,
    Crosshairs24,
+   Cursor17,
+   Dot3,
    MapboxLogo,
    MapTilerLogo
 };
diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp
index 04d9331a..30cd4bcb 100644
--- a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp
+++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp
@@ -135,6 +135,7 @@ public:
           &defaultTimeZone_,
           &antiAliasingEnabled_,
           &showMapAttribution_,
+          &showMapCenter_,
           &showMapLogo_,
           &updateNotificationsEnabled_,
           &debugEnabled_,
@@ -233,6 +234,7 @@ public:
    settings::SettingsInterface  theme_ {};
    settings::SettingsInterface         antiAliasingEnabled_ {};
    settings::SettingsInterface         showMapAttribution_ {};
+   settings::SettingsInterface         showMapCenter_ {};
    settings::SettingsInterface         showMapLogo_ {};
    settings::SettingsInterface         updateNotificationsEnabled_ {};
    settings::SettingsInterface         debugEnabled_ {};
@@ -666,6 +668,9 @@ void SettingsDialogImpl::SetupGeneralTab()
       generalSettings.show_map_attribution());
    showMapAttribution_.SetEditWidget(self_->ui->showMapAttributionCheckBox);
 
+   showMapCenter_.SetSettingsVariable(generalSettings.show_map_center());
+   showMapCenter_.SetEditWidget(self_->ui->showMapCenterCheckBox);
+
    showMapLogo_.SetSettingsVariable(generalSettings.show_map_logo());
    showMapLogo_.SetEditWidget(self_->ui->showMapLogoCheckBox);
 
diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui
index 6790b659..a6cf6804 100644
--- a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui
+++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui
@@ -118,302 +118,325 @@
          
           
            - 
-            
-             
-              QFrame::StyledPanel
+            
+             
+              true
              
-             
-              QFrame::Raised
-             
-             
-              
-               0
+             
+              
+               
+                0
+                0
+                513
+                454
+               
               
-              
-               0
-              
-              
-               0
-              
-              
-               0
-              
-              - 
-               
-                
-                 Default Alert Action
-                
-               
-              -
- 
-               
-              -
- 
-               
-                
-                 ...
-                
-                
-                 
-                  :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
-                
-               
-              -
- 
-               
-              -
- 
-               
-                
-                 QLineEdit::Password
-                
-               
-              -
- 
-               
-                
-                 Default Time Zone
-                
-               
-              -
- 
-               
-                
-                 Grid Width
-                
-               
-              -
- 
-               
-                
-                 Theme
-                
-               
-              -
- 
-               
-                
-                 Map Provider
-                
-               
-              -
- 
-               
-                
-                 MapTiler API Key
-                
-               
-              -
- 
-               
-                
-                 ...
-                
-                
-                 
-                  :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
-                
-               
-              -
- 
-               
-              -
- 
-               
-              -
- 
-               
-                
-                 ...
-                
-                
-                 
-                  :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
-                
-               
-              -
- 
-               
-                
-                 ...
-                
-                
-                 
-                  :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
-                
-               
-              -
- 
-               
-                
-                 ...
-                
-                
-                 
-                  :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
-                
-               
-              -
- 
-               
-                
-                 Clock Format
-                
-               
-              -
- 
-               
-                
-                 ...
-                
-                
-                 
-                  :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
-                
-               
-              -
- 
-               
-              -
- 
-               
-              -
- 
-               
-                
-                 ...
-                
-                
-                 
-                  :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
-                
-               
-              -
- 
-               
-              -
- 
-               
-                
-                 Default Radar Site
-                
-               
-              -
- 
-               
-                
-                 Mapbox API Key
-                
-               
-              -
- 
-               
-                
-                 ...
-                
-                
-                 
-                  :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
-                
-               
-              -
- 
-               
-                
-                 Grid Height
-                
-               
-              -
- 
-               
-                
-                 ...
-                
-                
-                 
-                  :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
-                
-               
-              -
- 
-               
-                
-                 ...
-                
-               
-              -
- 
-               
-                
-                 QLineEdit::Password
-                
-               
-              -
- 
-               
-              -
- 
-               
-                
-                 ...
-                
-                
-                 
-                  :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
-                
-               
-              -             
+              
+
- 
+                
+                 
+                  QFrame::NoFrame
+                 
+                 
+                  
+                   0
+                  
+                  
+                   0
+                  
+                  
+                   0
+                  
+                  
+                   0
+                  
+                  - 
+                   
+                    
+                     Default Radar Site
+                    
+                   
+                  +
- 
+                   
+                    
+                     Default Time Zone
+                    
+                   
+                  +
- 
+                   
+                    
+                     Map Provider
+                    
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                    
+                     
+                      :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+                    
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                    
+                     
+                      :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+                    
+                   
+                  +
- 
+                   
+                  +
- 
+                   
+                    
+                     Mapbox API Key
+                    
+                   
+                  +
- 
+                   
+                    
+                     Grid Width
+                    
+                   
+                  +
- 
+                   
+                    
+                     MapTiler API Key
+                    
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                    
+                     
+                      :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+                    
+                   
+                  +
- 
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                    
+                     
+                      :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+                    
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                    
+                     
+                      :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+                    
+                   
+                  +
- 
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                    
+                     
+                      :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+                    
+                   
+                  +
- 
+                   
+                    
+                     QLineEdit::Password
+                    
+                   
+                  +
- 
+                   
+                    
+                     Theme
+                    
+                   
+                  +
- 
+                   
+                  +
- 
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                   
+                  +
- 
+                   
+                    
+                     QLineEdit::Password
+                    
+                   
+                  +
- 
+                   
+                    
+                     Default Alert Action
+                    
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                    
+                     
+                      :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+                    
+                   
+                  +
- 
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                    
+                     
+                      :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+                    
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                    
+                     
+                      :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+                    
+                   
+                  +
- 
+                   
+                    
+                     ...
+                    
+                    
+                     
+                      :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg
+                    
+                   
+                  +
- 
+                   
+                  +
- 
+                   
+                  +
- 
+                   
+                    
+                     Clock Format
+                    
+                   
+                  +
- 
+                   
+                    
+                     Grid Height
+                    
+                   
+                  +                 
+                
+
+- 
+                
+                 
+                  Anti-Aliasing Enabled
+                 
+                
+               +
- 
+                
+                 
+                  Show Map Attribution
+                 
+                
+               +
- 
+                
+                 
+                  Show Map Center
+                 
+                
+               +
- 
+                
+                 
+                  Show Map Logo
+                 
+                
+               +
- 
+                
+                 
+                  Update Notifications Enabled
+                 
+                
+               +
- 
+                
+                 
+                  Debug Enabled
+                 
+                
+               +
- 
+                
+                 
+                  Qt::Vertical
+                 
+                 
+                  
+                   20
+                   40
+                  
+                 
+                
+               +              
+
-- 
-            
-             
-              Anti-Aliasing Enabled
-             
-            
-           -
- 
-            
-             
-              Show Map Attribution
-             
-            
-           -
- 
-            
-             
-              Show Map Logo
-             
-            
-           -
- 
-            
-             
-              Update Notifications Enabled
-             
-            
-           -
- 
-            
-             
-              Debug Enabled
-             
-            
-           -
- 
-            
-             
-              Qt::Vertical
-             
-             
-              
-               20
-               40
-              
-             
-            
-           @@ -438,8 +461,8 @@
                    
                     0
                     0
-                    498
-                    383
+                    63
+                    18
                    
                   
                   
diff --git a/test/data b/test/data
index 260b3400..ab32df5b 160000
--- a/test/data
+++ b/test/data
@@ -1 +1 @@
-Subproject commit 260b340030487b01ce9aa37135d949008c972f27
+Subproject commit ab32df5b0731d70aa5b977453c9aa4786eb0bd3f