protected Position computePositionFromUTM(
     int zone, String hemisphere, double easting, double northing) {
   try {
     UTMCoord UTM = UTMCoord.fromUTM(zone, hemisphere, easting, northing, globe);
     return new Position(
         Angle.fromRadiansLatitude(UTM.getLatitude().radians),
         Angle.fromRadiansLongitude(UTM.getLongitude().radians),
         10e3);
   } catch (IllegalArgumentException e) {
     return null;
   }
 }
 public void computeZone(DrawContext dc) {
   try {
     Position centerPos = ((OrbitView) dc.getView()).getCenterPosition();
     if (centerPos != null) {
       if (centerPos.latitude.degrees <= UTM_MAX_LATITUDE
           && centerPos.latitude.degrees >= UTM_MIN_LATITUDE) {
         UTMCoord UTM =
             UTMCoord.fromLatLon(
                 centerPos.getLatitude(), centerPos.getLongitude(), dc.getGlobe());
         this.zone = UTM.getZone();
       } else this.zone = 0;
     }
   } catch (Exception ex) {
     this.zone = 0;
   }
 }
  /**
   * Returns a geographic Sector which bounds the specified UTM rectangle. The UTM rectangle is
   * located in specified UTM zone and hemisphere.
   *
   * @param zone the UTM zone.
   * @param hemisphere the UTM hemisphere, either {@link gov.nasa.worldwind.avlist.AVKey#NORTH} or
   *     {@link gov.nasa.worldwind.avlist.AVKey#SOUTH}.
   * @param minEasting the minimum UTM easting, in meters.
   * @param maxEasting the maximum UTM easting, in meters.
   * @param minNorthing the minimum UTM northing, in meters.
   * @param maxNorthing the maximum UTM northing, in meters.
   * @return a Sector that bounds the specified UTM rectangle.
   * @throws IllegalArgumentException if <code>zone</code> is outside the range 1-60, if <code>
   *     hemisphere</code> is null, or if <code>hemisphere</code> is not one of {@link
   *     gov.nasa.worldwind.avlist.AVKey#NORTH} or {@link gov.nasa.worldwind.avlist.AVKey#SOUTH}.
   */
  public static Sector fromUTMRectangle(
      int zone,
      String hemisphere,
      double minEasting,
      double maxEasting,
      double minNorthing,
      double maxNorthing) {
    if (zone < 1 || zone > 60) {
      throw new IllegalArgumentException("ZoneIsInvalid");
    }

    if (!AVKey.NORTH.equals(hemisphere) && !AVKey.SOUTH.equals(hemisphere)) {
      throw new IllegalArgumentException("HemisphereIsInvalid");
    }

    LatLon ll = UTMCoord.locationFromUTMCoord(zone, hemisphere, minEasting, minNorthing);
    LatLon lr = UTMCoord.locationFromUTMCoord(zone, hemisphere, maxEasting, minNorthing);
    LatLon ur = UTMCoord.locationFromUTMCoord(zone, hemisphere, maxEasting, maxNorthing);
    LatLon ul = UTMCoord.locationFromUTMCoord(zone, hemisphere, minEasting, maxNorthing);

    return boundingSector(Arrays.asList(ll, lr, ur, ul));
  }
    public void selectRenderables(DrawContext dc) {
      try {
        OrbitView view = (OrbitView) dc.getView();
        // Compute easting and northing label offsets
        Double pixelSize = view.computePixelSizeAtDistance(view.getZoom());
        Double eastingOffset = view.getViewport().width * pixelSize * offsetFactorX / 2;
        Double northingOffset = view.getViewport().height * pixelSize * offsetFactorY / 2;
        // Derive labels center pos from the view center
        Position centerPos = view.getCenterPosition();
        double labelEasting;
        double labelNorthing;
        String labelHemisphere;
        if (this.zone > 0) {
          UTMCoord UTM =
              UTMCoord.fromLatLon(centerPos.getLatitude(), centerPos.getLongitude(), dc.getGlobe());
          labelEasting = UTM.getEasting() + eastingOffset;
          labelNorthing = UTM.getNorthing() + northingOffset;
          labelHemisphere = UTM.getHemisphere();
          if (labelNorthing < 0) {
            labelNorthing = 10e6 + labelNorthing;
            labelHemisphere = AVKey.SOUTH;
          }
        } else {
          UPSCoord UPS =
              UPSCoord.fromLatLon(centerPos.getLatitude(), centerPos.getLongitude(), dc.getGlobe());
          labelEasting = UPS.getEasting() + eastingOffset;
          labelNorthing = UPS.getNorthing() + northingOffset;
          labelHemisphere = UPS.getHemisphere();
        }

        Position labelPos;
        for (int i = 0; i < this.extremes.length; i++) {
          UTMExtremes levelExtremes = this.extremes[i];
          double gridStep = Math.pow(10, i);
          double gridStepTimesTen = gridStep * 10;
          String graticuleType = getTypeFor((int) gridStep);
          if (levelExtremes.minX <= levelExtremes.maxX) {
            // Process easting scale labels for this level
            for (double easting = levelExtremes.minX;
                easting <= levelExtremes.maxX;
                easting += gridStep) {
              // Skip multiples of ten grid steps except for last (higher) level
              if (i == this.extremes.length - 1 || easting % gridStepTimesTen != 0) {
                try {
                  labelPos = computePosition(this.zone, labelHemisphere, easting, labelNorthing);
                  if (labelPos == null) continue;
                  Angle lat = labelPos.getLatitude();
                  Angle lon = labelPos.getLongitude();
                  Vec4 surfacePoint = getSurfacePoint(dc, lat, lon);
                  if (viewFrustum.contains(surfacePoint) && isPointInRange(dc, surfacePoint)) {
                    String text = String.valueOf((int) (easting % this.scaleModulo));
                    GeographicText gt = new UserFacingText(text, new Position(lat, lon, 0));
                    gt.setPriority(gridStepTimesTen);
                    addRenderable(gt, graticuleType);
                  }
                } catch (IllegalArgumentException ignore) {
                }
              }
            }
          }
          if (!(levelExtremes.maxYHemisphere.equals(AVKey.SOUTH) && levelExtremes.maxY == 0)) {
            // Process northing scale labels for this level
            String currentHemisphere = levelExtremes.minYHemisphere;
            for (double northing = levelExtremes.minY;
                (northing <= levelExtremes.maxY)
                    || !currentHemisphere.equals(levelExtremes.maxYHemisphere);
                northing += gridStep) {
              // Skip multiples of ten grid steps except for last (higher) level
              if (i == this.extremes.length - 1 || northing % gridStepTimesTen != 0) {
                try {
                  labelPos = computePosition(this.zone, currentHemisphere, labelEasting, northing);
                  if (labelPos == null) continue;
                  Angle lat = labelPos.getLatitude();
                  Angle lon = labelPos.getLongitude();
                  Vec4 surfacePoint = getSurfacePoint(dc, lat, lon);
                  if (viewFrustum.contains(surfacePoint) && isPointInRange(dc, surfacePoint)) {
                    String text = String.valueOf((int) (northing % this.scaleModulo));
                    GeographicText gt = new UserFacingText(text, new Position(lat, lon, 0));
                    gt.setPriority(gridStepTimesTen);
                    addRenderable(gt, graticuleType);
                  }
                } catch (IllegalArgumentException ignore) {
                }

                if (!currentHemisphere.equals(levelExtremes.maxYHemisphere)
                    && northing >= 10e6 - gridStep) {
                  // Switch hemisphere
                  currentHemisphere = levelExtremes.maxYHemisphere;
                  northing = -gridStep;
                }
              }
            }
          } // end northing
        } // for levels
      } catch (IllegalArgumentException ignore) {
      }
    }