cdm/src/main/java/ucar/nc2/ft2/coverage/HorizCoordSys.java
public Optional<HorizCoordSys> subset(SubsetParams params) {
    LatLonRect llbb = (LatLonRect) params.get(SubsetParams.latlonBB);
    ProjectionRect projbb = (ProjectionRect) params.get(SubsetParams.projBB);
    LatLonPoint latlon = (LatLonPoint) params.get(SubsetParams.latlonPoint);
    Integer horizStride = (Integer) params.get(SubsetParams.horizStride);
    if (horizStride == null || horizStride < 1) horizStride = 1;

    CoverageCoordAxis1D xaxisSubset = null, yaxisSubset = null;
    CoverageCoordAxis lataxisSubset = null, lonaxisSubset = null;
    Optional<CoverageCoordAxis> opt;
    Optional<CoverageCoordAxisBuilder> optb;

    Formatter errMessages = new Formatter();
    try {
      if (latlon != null) { // overrides other horiz subset params
        if (isProjection) {
          CoordAxisHelper xhelper = new CoordAxisHelper(xAxis);
          CoordAxisHelper yhelper = new CoordAxisHelper(yAxis);

          // we have to transform latlon to projection coordinates
          ProjectionImpl proj = transform.getProjection();
          ProjectionPoint pp = proj.latLonToProj(latlon);
          optb = xhelper.subsetContaining(pp.getX());
          if (optb.isPresent()) xaxisSubset = new CoverageCoordAxis1D(optb.get());
          else errMessages.format("xaxis: %s;%n", optb.getErrorMessage());

          optb = yhelper.subsetContaining(pp.getY());
          if (optb.isPresent()) yaxisSubset = new CoverageCoordAxis1D(optb.get());
          else errMessages.format("yaxis: %s;%n", optb.getErrorMessage());

        } else {
          CoordAxisHelper xhelper = new CoordAxisHelper(lonAxis);
          CoordAxisHelper yhelper = new CoordAxisHelper(latAxis);

          double lonNormal = LatLonPointImpl.lonNormalFrom(latlon.getLongitude(), lonAxis.getStartValue());
          optb = xhelper.subsetContaining(lonNormal);
          if (optb.isPresent()) lonaxisSubset = new CoverageCoordAxis1D(optb.get());
          else errMessages.format("lonaxis: %s;%n", optb.getErrorMessage());

          optb = yhelper.subsetContaining(latlon.getLatitude());
          if (optb.isPresent()) lataxisSubset = new CoverageCoordAxis1D(optb.get());
          else errMessages.format("lataxis: %s;%n", optb.getErrorMessage());
        }

      } else if (projbb != null) {
        if (isProjection) {
          opt = xAxis.subset(projbb.getMinX(), projbb.getMaxX(), horizStride);
          if (opt.isPresent()) xaxisSubset = (CoverageCoordAxis1D) opt.get();
          else errMessages.format("xaxis: %s;%n", opt.getErrorMessage());

          opt = yAxis.subset(projbb.getMinY(), projbb.getMaxY(), horizStride);
          if (opt.isPresent()) yaxisSubset = (CoverageCoordAxis1D) opt.get();
          else errMessages.format("yaxis: %s;%n", opt.getErrorMessage());

        } /* else {  // WTF projbb on non Projection ?
          ProjectionImpl proj = transform.getProjection();
          LatLonRect llrect = proj.projToLatLonBB(projbb);
          opt = lonaxis.subset(llrect.getLonMin(), llrect.getLonMax(), horizStride);
          if (opt.isPresent()) lonaxisSubset = opt.get();
          else errMessages.format("lonaxis: %s;%n", opt.getErrorMessage());

          opt = lataxis.subset(llrect.getLatMin(), llrect.getLatMax(), horizStride);
          if (opt.isPresent()) lataxisSubset = opt.get();
          else errMessages.format("lataxis: %s;%n", opt.getErrorMessage());
        } */

      } else if (llbb != null) {
        LatLonRect full = calcLatLonBoundingBox();
        assert full != null;

        if (!full.containedIn(llbb)) { // if request contains entire bb, then no subsetting needed

          if (isProjection) {
            // we have to transform latlon to projection coordinates
            ProjectionImpl proj = transform.getProjection();
            ProjectionRect prect = proj.latLonToProjBB(llbb); // allow projection to override
            opt = xAxis.subset(prect.getMinX(), prect.getMaxX(), horizStride);
            if (opt.isPresent()) xaxisSubset = (CoverageCoordAxis1D) opt.get();
            else errMessages.format("xaxis: %s;%n", opt.getErrorMessage());

            opt = yAxis.subset(prect.getMinY(), prect.getMaxY(), horizStride);
            if (opt.isPresent()) yaxisSubset = (CoverageCoordAxis1D) opt.get();
            else errMessages.format("yaxis: %s;%n", opt.getErrorMessage());

          } else {
            opt = subsetLon(llbb, horizStride);
            if (opt.isPresent()) lonaxisSubset = opt.get();
            else errMessages.format("lonaxis: %s;%n", opt.getErrorMessage());

            opt = latAxis.subset(llbb.getLatMin(), llbb.getLatMax(), horizStride);
            if (opt.isPresent()) lataxisSubset = opt.get();
            else errMessages.format("lataxis: %s;%n", opt.getErrorMessage());
          }
        }

      } else if (horizStride > 1) { // no bounding box, just horiz stride
        if (isProjection) {
          opt = xAxis.subsetByIndex(xAxis.getRange().setStride(horizStride));
          if (opt.isPresent()) xaxisSubset = (CoverageCoordAxis1D) opt.get();
          else errMessages.format("xaxis: %s;%n", opt.getErrorMessage());

          opt = yAxis.subsetByIndex(yAxis.getRange().setStride(horizStride));
          if (opt.isPresent()) yaxisSubset = (CoverageCoordAxis1D) opt.get();
          else errMessages.format("yaxis: %s;%n", opt.getErrorMessage());

        } else {
          opt = lonAxis.subsetByIndex(lonAxis.getRange().setStride(horizStride));
          if (opt.isPresent()) lonaxisSubset = opt.get();
          else errMessages.format("lonaxis: %s;%n", opt.getErrorMessage());

          opt = latAxis.subsetByIndex(latAxis.getRange().setStride(horizStride));
          if (opt.isPresent()) lataxisSubset = opt.get();
          else errMessages.format("lataxis: %s;%n", opt.getErrorMessage());
        }
      }
    } catch (InvalidRangeException e) {
      errMessages.format("%s;%n", e.getMessage());
    }

    String errs = errMessages.toString();
    if (errs.length() > 0)
      return Optional.empty(errs);

    // makes a copy of the axis
    if (xaxisSubset == null && xAxis != null) xaxisSubset = (CoverageCoordAxis1D) xAxis.copy();
    if (yaxisSubset == null && yAxis != null) yaxisSubset = (CoverageCoordAxis1D) yAxis.copy();
    if (lataxisSubset == null && latAxis != null) lataxisSubset = latAxis.copy();
    if (lonaxisSubset == null && lonAxis != null) lonaxisSubset = lonAxis.copy();

    return Optional.of(new HorizCoordSys(xaxisSubset, yaxisSubset, lataxisSubset, lonaxisSubset, transform));
  }
public Optional<HorizCoordSys> subset(SubsetParams params) {
    LatLonRect llbb = (LatLonRect) params.get(SubsetParams.latlonBB);
    ProjectionRect projbb = (ProjectionRect) params.get(SubsetParams.projBB);
    LatLonPoint latlon = (LatLonPoint) params.get(SubsetParams.latlonPoint);
    Integer horizStride = (Integer) params.get(SubsetParams.horizStride);
    if (horizStride == null || horizStride < 1) horizStride = 1;

    CoverageCoordAxis1D xaxisSubset = null, yaxisSubset = null;
    CoverageCoordAxis lataxisSubset = null, lonaxisSubset = null;
    Optional<CoverageCoordAxis> opt;
    Optional<CoverageCoordAxisBuilder> optb;

    Formatter errMessages = new Formatter();
    try {
      if (latlon != null) { // overrides other horiz subset params
        if (isProjection) {
          CoordAxisHelper xhelper = new CoordAxisHelper(xAxis);
          CoordAxisHelper yhelper = new CoordAxisHelper(yAxis);

          // we have to transform latlon to projection coordinates
          ProjectionImpl proj = transform.getProjection();
          ProjectionPoint pp = proj.latLonToProj(latlon);
          optb = xhelper.subsetContaining(pp.getX());
          if (optb.isPresent()) xaxisSubset = new CoverageCoordAxis1D(optb.get());
          else errMessages.format("xaxis: %s;%n", optb.getErrorMessage());

          optb = yhelper.subsetContaining(pp.getY());
          if (optb.isPresent()) yaxisSubset = new CoverageCoordAxis1D(optb.get());
          else errMessages.format("yaxis: %s;%n", optb.getErrorMessage());

        } else {
          CoordAxisHelper xhelper = new CoordAxisHelper(lonAxis);
          CoordAxisHelper yhelper = new CoordAxisHelper(latAxis);

          double lonNormal = LatLonPointImpl.lonNormalFrom(latlon.getLongitude(), lonAxis.getStartValue());
          optb = xhelper.subsetContaining(lonNormal);
          if (optb.isPresent()) lonaxisSubset = new CoverageCoordAxis1D(optb.get());
          else errMessages.format("lonaxis: %s;%n", optb.getErrorMessage());

          optb = yhelper.subsetContaining(latlon.getLatitude());
          if (optb.isPresent()) lataxisSubset = new CoverageCoordAxis1D(optb.get());
          else errMessages.format("lataxis: %s;%n", optb.getErrorMessage());
        }

      } else if (projbb != null) {
        if (isProjection) {
          opt = xAxis.subset(projbb.getMinX(), projbb.getMaxX(), horizStride);
          if (opt.isPresent()) xaxisSubset = (CoverageCoordAxis1D) opt.get();
          else errMessages.format("xaxis: %s;%n", opt.getErrorMessage());

          opt = yAxis.subset(projbb.getMinY(), projbb.getMaxY(), horizStride);
          if (opt.isPresent()) yaxisSubset = (CoverageCoordAxis1D) opt.get();
          else errMessages.format("yaxis: %s;%n", opt.getErrorMessage());

        } /* else {  // WTF projbb on non Projection ?
          ProjectionImpl proj = transform.getProjection();
          LatLonRect llrect = proj.projToLatLonBB(projbb);
          opt = lonaxis.subset(llrect.getLonMin(), llrect.getLonMax(), horizStride);
          if (opt.isPresent()) lonaxisSubset = opt.get();
          else errMessages.format("lonaxis: %s;%n", opt.getErrorMessage());

          opt = lataxis.subset(llrect.getLatMin(), llrect.getLatMax(), horizStride);
          if (opt.isPresent()) lataxisSubset = opt.get();
          else errMessages.format("lataxis: %s;%n", opt.getErrorMessage());
        } */

      } else if (llbb != null) {
        LatLonRect full = calcLatLonBoundingBox();
        assert full != null;

        if (!full.containedIn(llbb)) { // if request contains entire bb, then no subsetting needed

          if (isProjection) {
            // we have to transform latlon to projection coordinates
            ProjectionImpl proj = transform.getProjection();
            ProjectionRect prect = proj.latLonToProjBB(llbb); // allow projection to override
            opt = xAxis.subset(prect.getMinX(), prect.getMaxX(), horizStride);
            if (opt.isPresent()) xaxisSubset = (CoverageCoordAxis1D) opt.get();
            else errMessages.format("xaxis: %s;%n", opt.getErrorMessage());

            opt = yAxis.subset(prect.getMinY(), prect.getMaxY(), horizStride);
            if (opt.isPresent()) yaxisSubset = (CoverageCoordAxis1D) opt.get();
            else errMessages.format("yaxis: %s;%n", opt.getErrorMessage());

          } else {
            opt = subsetLon(llbb, horizStride);
            if (opt.isPresent()) lonaxisSubset = opt.get();
            else errMessages.format("lonaxis: %s;%n", opt.getErrorMessage());

            opt = latAxis.subset(llbb.getLatMin(), llbb.getLatMax(), horizStride);
            if (opt.isPresent()) lataxisSubset = opt.get();
            else errMessages.format("lataxis: %s;%n", opt.getErrorMessage());
          }
        }

      } else if (horizStride > 1) { // no bounding box, just horiz stride
        if (isProjection) {
          opt = xAxis.subsetByIndex(xAxis.getRange().setStride(horizStride));
          if (opt.isPresent()) xaxisSubset = (CoverageCoordAxis1D) opt.get();
          else errMessages.format("xaxis: %s;%n", opt.getErrorMessage());

          opt = yAxis.subsetByIndex(yAxis.getRange().setStride(horizStride));
          if (opt.isPresent()) yaxisSubset = (CoverageCoordAxis1D) opt.get();
          else errMessages.format("yaxis: %s;%n", opt.getErrorMessage());

        } else {
          opt = lonAxis.subsetByIndex(lonAxis.getRange().setStride(horizStride));
          if (opt.isPresent()) lonaxisSubset = opt.get();
          else errMessages.format("lonaxis: %s;%n", opt.getErrorMessage());

          opt = latAxis.subsetByIndex(latAxis.getRange().setStride(horizStride));
          if (opt.isPresent()) lataxisSubset = opt.get();
          else errMessages.format("lataxis: %s;%n", opt.getErrorMessage());
        }
      }
    } catch (InvalidRangeException e) {
      errMessages.format("%s;%n", e.getMessage());
    }

    String errs = errMessages.toString();
    if (errs.length() > 0)
      return Optional.empty(errs);

    // makes a copy of the axis
    if (xaxisSubset == null && xAxis != null) xaxisSubset = (CoverageCoordAxis1D) xAxis.copy();
    if (yaxisSubset == null && yAxis != null) yaxisSubset = (CoverageCoordAxis1D) yAxis.copy();
    if (lataxisSubset == null && latAxis != null) lataxisSubset = latAxis.copy();
    if (lonaxisSubset == null && lonAxis != null) lonaxisSubset = lonAxis.copy();

    return Optional.of(new HorizCoordSys(xaxisSubset, yaxisSubset, lataxisSubset, lonaxisSubset, transform));
  }
///////////////////////////////////////////////////////////////////////////////////