private DefaultFeatureCollection createFeaturesFromSpacing(
      final MapfishMapContext mapContext,
      final SimpleFeatureBuilder featureBuilder,
      final GridParam layerData,
      final LabelPositionCollector labels) {
    GeometryFactory geometryFactory = new GeometryFactory();
    ReferencedEnvelope bounds = mapContext.toReferencedEnvelope();

    CoordinateReferenceSystem mapCrs = bounds.getCoordinateReferenceSystem();
    String unit = layerData.calculateLabelUnit(mapCrs);
    MathTransform labelTransform = layerData.calculateLabelTransform(mapCrs);

    final double incrementX = layerData.spacing[0];
    final double incrementY = layerData.spacing[1];
    double minX = GridUtils.calculateFirstLine(bounds, layerData, 0);
    double minY = GridUtils.calculateFirstLine(bounds, layerData, 1);

    MapfishMapContext rootContext = mapContext.getRootContext();
    Polygon rotatedBounds = GridUtils.calculateBounds(rootContext);
    AffineTransform worldToScreenTransform = GridUtils.getWorldToScreenTransform(mapContext);

    DefaultFeatureCollection features = new DefaultFeatureCollection();
    int i = 0;
    int j;

    boolean addBorderFeatures = true;
    for (double x = minX; x < bounds.getMaxX(); x += incrementX) {
      i++;
      j = 0;

      if (!onRightBorder(bounds, x)) { // don't add the border features twice.
        GridUtils.bottomBorderLabel(
            labels,
            geometryFactory,
            rotatedBounds,
            unit,
            x,
            worldToScreenTransform,
            labelTransform,
            layerData.getGridLabelFormat());
        GridUtils.topBorderLabel(
            labels,
            geometryFactory,
            rotatedBounds,
            unit,
            x,
            worldToScreenTransform,
            labelTransform,
            layerData.getGridLabelFormat());
      }
      for (double y = minY; y < bounds.getMaxY(); y += incrementY) {
        j++;

        if (addBorderFeatures && !onRightBorder(bounds, x) && !onTopBorder(bounds, y)) {
          GridUtils.leftBorderLabel(
              labels,
              geometryFactory,
              rotatedBounds,
              unit,
              y,
              worldToScreenTransform,
              labelTransform,
              layerData.getGridLabelFormat());
          GridUtils.rightBorderLabel(
              labels,
              geometryFactory,
              rotatedBounds,
              unit,
              y,
              worldToScreenTransform,
              labelTransform,
              layerData.getGridLabelFormat());
        }
        if (!onTopBorder(bounds, y)
            && !onBottomBorder(bounds, y)
            && !onLeftBorder(bounds, x)
            && !onRightBorder(bounds, x)) { // don't add the border features twice.
          featureBuilder.reset();
          Point geom = geometryFactory.createPoint(new Coordinate(x, y));
          featureBuilder.set(Grid.ATT_GEOM, geom);
          features.add(featureBuilder.buildFeature("grid." + i + "." + j));
        }
      }
      addBorderFeatures = false;
    }
    return features;
  }
  private DefaultFeatureCollection createFeaturesFromNumberOfLines(
      final MapfishMapContext mapContext,
      final SimpleFeatureBuilder featureBuilder,
      final GridParam layerData,
      final LabelPositionCollector labels) {
    GeometryFactory geometryFactory = new GeometryFactory();
    ReferencedEnvelope bounds = mapContext.toReferencedEnvelope();

    MapfishMapContext rootContext = mapContext.getRootContext();
    Polygon rotatedBounds = GridUtils.calculateBounds(rootContext);
    AffineTransform worldToScreenTransform = GridUtils.getWorldToScreenTransform(mapContext);

    CoordinateReferenceSystem mapCrs = bounds.getCoordinateReferenceSystem();
    String unit = layerData.calculateLabelUnit(mapCrs);
    MathTransform labelTransform = layerData.calculateLabelTransform(mapCrs);

    double incrementX = bounds.getWidth() / (layerData.numberOfLines[0] + 1);
    double incrementY = bounds.getHeight() / (layerData.numberOfLines[1] + 1);

    double x = bounds.getMinX();
    DefaultFeatureCollection features = new DefaultFeatureCollection();
    for (int i = 0; i < layerData.numberOfLines[0] + 2; i++) {
      double y = bounds.getMinY();
      for (int j = 0; j < layerData.numberOfLines[1] + 2; j++) {
        String fid = "grid." + i + "." + j;
        if ((i != 0 || j != 0)
            && (i != layerData.numberOfLines[0] + 1 || j != layerData.numberOfLines[1] + 1)
            && (i != 0 || j != layerData.numberOfLines[1] + 1)
            && (i != layerData.numberOfLines[0] + 1 || j != 0)) {

          if (i == 0) {
            GridUtils.leftBorderLabel(
                labels,
                geometryFactory,
                rotatedBounds,
                unit,
                y,
                worldToScreenTransform,
                labelTransform,
                layerData.getGridLabelFormat());
          } else if (i == layerData.numberOfLines[0] + 1) {
            GridUtils.rightBorderLabel(
                labels,
                geometryFactory,
                rotatedBounds,
                unit,
                y,
                worldToScreenTransform,
                labelTransform,
                layerData.getGridLabelFormat());
          } else if (j == 0) {
            GridUtils.bottomBorderLabel(
                labels,
                geometryFactory,
                rotatedBounds,
                unit,
                x,
                worldToScreenTransform,
                labelTransform,
                layerData.getGridLabelFormat());
          } else if (j == layerData.numberOfLines[1] + 1) {
            GridUtils.topBorderLabel(
                labels,
                geometryFactory,
                rotatedBounds,
                unit,
                x,
                worldToScreenTransform,
                labelTransform,
                layerData.getGridLabelFormat());
          } else {
            featureBuilder.reset();
            Point geom = geometryFactory.createPoint(new Coordinate(x, y));
            featureBuilder.set(Grid.ATT_GEOM, geom);
            features.add(featureBuilder.buildFeature(fid));
          }
        }
        y += incrementY;
      }
      x += incrementX;
    }
    return features;
  }