/**
  * Ajusta el tamaño de la ventana al envelope pasado como parámetro
  *
  * @param ctx
  * @param newWrapperEnvelope
  * @param viewport
  */
 public static void resizeViewToEnvelope(
     PlugInContext ctx, Envelope newWrapperEnvelope, IViewport viewport) {
   // ajustamos las proporciones de la ventana a las de la feature
   JInternalFrame activeInternalFrame = ctx.getActiveInternalFrame();
   Dimension dimView = ((Dimension) ctx.getLayerViewPanel()).getSize();
   Double widthView = dimView.getWidth();
   Double heightView = dimView.getHeight();
   int widthDiff = (int) (activeInternalFrame.getWidth() - widthView);
   int heightDiff = (int) (activeInternalFrame.getHeight() - heightView);
   Integer newWidth =
       (int)
           ((newWrapperEnvelope.getWidth() / viewport.getEnvelopeInModelCoordinates().getWidth())
               * widthView);
   Integer newHeight =
       (int)
           ((newWrapperEnvelope.getHeight() / viewport.getEnvelopeInModelCoordinates().getHeight())
               * heightView);
   Dimension newDimensionView = new Dimension(newWidth + widthDiff, newHeight + heightDiff);
   activeInternalFrame.setSize(newDimensionView);
   // zoom al envelope actual
   try {
     viewport.zoom(newWrapperEnvelope);
   } catch (NoninvertibleTransformException e) {
     log.warn("No se ha podido alcanzar el zoom " + newWrapperEnvelope);
   }
 }
  private JButton getGraticuleButton() {
    jButtonGraticule =
        new JButton(
            I18N.get(
                MobileExtractPlugin.PluginMobileExtracti18n,
                MobilePluginI18NResource.MobileExtractPanel03_crearCuadricula));

    LayerManager layerManager = context.getLayerManager();
    Layer graticuleLayer = layerManager.getLayer(GraticuleCreatorEngine.getGraticuleName());

    // si ya existe una capa cuadrícula significa que se trata de un fichero importado previamente a
    // ejecutar el asistente
    if (graticuleLayer != null) {
      jButtonGraticule.setEnabled(false);

      if (bCuadriculaCreada == true) {
        // solo ejecutamos este código una vez
        return jButtonGraticule;
      }

      FeatureCollectionWrapper graticuleCollectionWrapper =
          graticuleLayer.getFeatureCollectionWrapper();
      FeatureSchema featureSchema = graticuleCollectionWrapper.getFeatureSchema();

      // cuadriculas visionadas
      IViewport viewport = (IViewport) context.getLayerViewPanel().getViewport();
      Envelope viewEnvelope = viewport.getEnvelopeInModelCoordinates();
      List<Feature> graticuleFeatures = graticuleCollectionWrapper.query(viewEnvelope);
      // ordenamos por distancia al origen las features
      List<SortedFeature> sortedGraticuleFeatures = new ArrayList<SortedFeature>();
      Feature feature = null;
      SortedFeature sortFeat = null;
      for (Iterator iterator = graticuleFeatures.iterator(); iterator.hasNext(); ) {
        feature = (Feature) iterator.next();
        sortFeat = new SortedFeature(feature);
        sortedGraticuleFeatures.add(sortFeat);
      }
      Collections.sort(sortedGraticuleFeatures);

      // borramos el resto de cuadrículas
      graticuleCollectionWrapper.clear();
      graticuleCollectionWrapper.addAll(graticuleFeatures);
      Envelope newWrapperEnvelope = graticuleCollectionWrapper.getEnvelope();

      // zoom al envelope actual
      try {
        viewport.zoom(newWrapperEnvelope);
      } catch (NoninvertibleTransformException e) {
        log.warn("No se ha podido alcanzar el zoom " + newWrapperEnvelope);
      }

      // ajustamos la ventana al envelope de la cuadrícula
      resizeViewToEnvelope(context, newWrapperEnvelope, viewport);

      // guardamos las propiedades gráficas de la extracción
      Envelope featEnvelope =
          sortedGraticuleFeatures.get(0).getFeature().getGeometry().getEnvelopeInternal();
      Double featWidth = featEnvelope.getWidth();
      Double featHeight = featEnvelope.getHeight();
      Double minX = newWrapperEnvelope.getMinX();
      Double minY = newWrapperEnvelope.getMinY();
      Coordinate coordCorner = new Coordinate(minX, minY);
      blackboard.put(GraticuleCreatorPlugIn.SOUTHWEST_CORNER_OF_LEFT_LAYER, coordCorner);
      blackboard.put(GraticuleCreatorPlugIn.CELL_SIDE_LENGTH_X, featWidth);
      blackboard.put(GraticuleCreatorPlugIn.CELL_SIDE_LENGTH_Y, featHeight);
      Integer numCeldasAncho = (int) (newWrapperEnvelope.getWidth() / featWidth);
      Integer numCeldasAlto = (int) (newWrapperEnvelope.getHeight() / featHeight);
      blackboard.put(GraticuleCreatorPlugIn.LAYER_WIDTH_IN_CELLS, numCeldasAncho);
      blackboard.put(GraticuleCreatorPlugIn.LAYER_HEIGHT_IN_CELLS, numCeldasAlto);

      // creamos celdas para los espacios en blanco
      if (sortedGraticuleFeatures.size() < numCeldasAncho * numCeldasAlto) {
        Double curMinX = minX;
        Double curMinY = minY;
        Double fMinX = 0.0;
        GeometryFactory geoFact = new GeometryFactory();
        Feature newFeature = null;
        for (int i = 0; i < sortedGraticuleFeatures.size(); i++) {
          sortFeat = sortedGraticuleFeatures.get(i);
          feature = sortFeat.getFeature();
          fMinX = feature.getGeometry().getEnvelopeInternal().getMinX();
          if (curMinX.doubleValue() != fMinX.doubleValue()) {
            // creamos la feature
            newFeature = (Feature) feature.clone();
            Coordinate[] coordArray = {
              new Coordinate(curMinX, curMinY),
              new Coordinate(curMinX + featWidth, curMinY),
              new Coordinate(curMinX + featWidth, curMinY + featHeight),
              new Coordinate(curMinX, curMinY + featHeight),
              new Coordinate(curMinX, curMinY)
            };

            newFeature.setGeometry(
                geoFact.createPolygon(geoFact.createLinearRing(coordArray), null));
            sortedGraticuleFeatures.add(i, new SortedFeature(newFeature));
            graticuleCollectionWrapper.add(newFeature);
          }
          // para lo último
          else if ((i == sortedGraticuleFeatures.size() - 1)
              && ((minX + (featWidth * numCeldasAncho)) != (fMinX + featWidth))) {
            curMinX = fMinX + featWidth;
            newFeature = (Feature) feature.clone();
            Coordinate[] coordArray = {
              new Coordinate(curMinX, curMinY),
              new Coordinate(curMinX + featWidth, curMinY),
              new Coordinate(curMinX + featWidth, curMinY + featHeight),
              new Coordinate(curMinX, curMinY + featHeight),
              new Coordinate(curMinX, curMinY)
            };

            newFeature.setGeometry(
                geoFact.createPolygon(geoFact.createLinearRing(coordArray), null));
            sortedGraticuleFeatures.add(
                sortedGraticuleFeatures.size(), new SortedFeature(newFeature));
            graticuleCollectionWrapper.add(newFeature);
            continue;
          }

          if (((i + 1) % numCeldasAncho) != 0) {
            curMinX = curMinX + featWidth;
          } else { // ultima celda de cada fila
            curMinX = minX;
            curMinY += featHeight;
          }
        }
      }

      // añadimos el atributo cellid
      featureSchema.addAttribute(GraticuleCreatorEngine.ATR_CELL_ID, AttributeType.INTEGER);
      int k = 1;
      Object[] featAttribs = null;
      Object[] newFeatAttribs = null;
      for (Iterator iterator = sortedGraticuleFeatures.iterator(); iterator.hasNext(); k++) {
        feature = ((SortedFeature) iterator.next()).getFeature();
        featAttribs = feature.getAttributes();
        newFeatAttribs = new Object[featAttribs.length + 1];
        for (int i = 0; i < featAttribs.length; i++) {
          newFeatAttribs[i] = featAttribs[i];
        }
        newFeatAttribs[newFeatAttribs.length - 1] = k;
        feature.setAttributes(newFeatAttribs);
      }
      // pintamos el atributo en la capa
      LabelStyle labelStyle = graticuleLayer.getLabelStyle();
      labelStyle.setColor(Color.RED);
      labelStyle.setHeight(labelStyle.getHeight() * 4);
      labelStyle.setAttribute(GraticuleCreatorEngine.ATR_CELL_ID);
      labelStyle.setEnabled(true);

      // evitamos que se modifiquen las cuadrículas
      graticuleLayer.setEditable(false);
      graticuleLayer.fireAppearanceChanged();

      bCuadriculaCreada = true;
    }
    // llamada al graticulePlugin
    else {
      jButtonGraticule.addActionListener(
          new ActionListener() {

            public void actionPerformed(ActionEvent e) {
              GraticuleCreatorPlugIn graticulePlugin = new GraticuleCreatorPlugIn();
              try {
                graticulePlugin.execute(context);
              } catch (Exception e1) {
                e1.printStackTrace();
              }
              wizardContext.inputChanged(); // indicamos que ya se puede habilitar el boton
            }
          });
    }

    return jButtonGraticule;
  }