private GridStyle getStyle(ILayer layer) {
   GridStyle gridStyle = (GridStyle) layer.getStyleBlackboard().get(GridStyle.ID);
   if (gridStyle == null) {
     return GridStyle.DEFAULT_STYLE;
   }
   return gridStyle;
 }
  /**
   * This example shows how to obtain a color.
   *
   * @param g
   * @param monitor
   * @throws RenderException
   */
  public void render(Graphics2D g, IProgressMonitor monitor) throws RenderException {
    if (monitor == null) monitor = new NullProgressMonitor();

    CsvReader reader = null;
    try {
      ILayer layer = getContext().getLayer();
      IGeoResource resource = layer.findGeoResource(CSV.class);
      if (resource == null) return;
      ReferencedEnvelope bounds = getRenderBounds();
      monitor.subTask("connecting");
      CSV csv = resource.resolve(CSV.class, null);
      // LOOK UP STYLE
      IStyleBlackboard style = layer.getStyleBlackboard();
      Color color = (Color) style.get(ColorStyle.ID);

      // DATA TO WORLD
      CoordinateReferenceSystem dataCRS = layer.getCRS();
      CoordinateReferenceSystem worldCRS = context.getCRS();
      MathTransform dataToWorld = CRS.findMathTransform(dataCRS, worldCRS, false);

      // DRAW FILE
      monitor.beginTask("csv render", csv.getSize());
      reader = csv.reader();
      reader.readHeaders();
      int nameIndex = reader.getIndex("name");
      Coordinate worldLocation = new Coordinate();
      while (reader.readRecord()) {
        Point point = CSV.getPoint(reader);
        Coordinate dataLocation = point.getCoordinate();
        try {
          JTS.transform(dataLocation, worldLocation, dataToWorld);
        } catch (TransformException e) {
          continue;
        }
        if (bounds != null && !bounds.contains(worldLocation)) {
          continue; // optimize!
        }
        java.awt.Point p = getContext().worldToPixel(worldLocation);

        g.setColor(color);
        g.fillRect(p.x - 2, p.y - 2, 6, 6);

        g.setColor(Color.BLACK);
        String name = reader.get(nameIndex);
        g.drawString(name, p.x + 15, p.y + 15);
        monitor.worked(1);
        if (monitor.isCanceled()) break;
      }
    } catch (IOException e) {
      throw new RenderException(e); // rethrow any exceptions encountered
    } catch (FactoryException e) {
      throw new RenderException(e); // rethrow any exceptions encountered
    } finally {
      if (reader != null) reader.close();
      monitor.done();
    }
  }
  @SuppressWarnings("unchecked")
  private void setFilter(WebMapServer wms, GetMapRequest request) {
    Filter mapFilter = null;

    Map<ILayer, Filter> filters = new HashMap<ILayer, Filter>();
    List<ILayer> layers = getContext().getLayers();
    for (ILayer layer : layers) {
      Object layerFilter =
          layer.getStyleBlackboard().get(ProjectBlackboardConstants.LAYER__DATA_QUERY);
      Filter filter;
      if (layerFilter instanceof Query) {
        filter = (Filter) ((Query) layerFilter).getFilter();
      } else if (layerFilter instanceof Filter) {
        filter = (Filter) layerFilter;
      } else {
        filter = mapFilter;
      }
      if (filter != null && filter != Filter.INCLUDE) {
        filters.put(layer, filter);
      }
    }

    if (filters.isEmpty()) return;

    StringBuilder builder = new StringBuilder();
    HashMap hashMap = new HashMap();
    for (Map.Entry<ILayer, Filter> entry : filters.entrySet()) {
      if (entry.getValue() == null) builder.append('(');
      try {
        StringWriter writer = new StringWriter();
        DocumentWriter.writeDocument(entry.getValue(), FilterSchema.getInstance(), writer, hashMap);
        builder.append(writer.toString());
      } catch (OperationNotSupportedException e) {
        WMSPlugin.log(
            "Error writing filter for layer: " + entry.getKey().getID(), e); // $NON-NLS-1$
        builder.append("<Filter/>"); // $NON-NLS-1$
      } catch (IOException e) {
        // SHOULDN'T Happen I don't think...
        assert false;
        WMSPlugin.log(
            "Error writing filter for layer: " + entry.getKey().getID(), e); // $NON-NLS-1$
        builder.append("<Filter/>"); // $NON-NLS-1$
      }
      builder.append(')');
    }

    try {
      String encode = URLEncoder.encode(builder.toString(), "UTF-8"); // $NON-NLS-1$
      request.setVendorSpecificParameter("filter", encode); // $NON-NLS-1$
    } catch (UnsupportedEncodingException e) {
      // better not happen!
      throw (RuntimeException) new RuntimeException().initCause(e);
    }
  }
 @Override
 public ReferencedEnvelope getExtent() {
   ILayer processingRegionLayer = OmsBoxPlugin.getDefault().getProcessingRegionMapGraphic();
   if (processingRegionLayer != null) {
     IStyleBlackboard blackboard = processingRegionLayer.getStyleBlackboard();
     ProcessingRegionStyle style =
         (ProcessingRegionStyle) blackboard.get(ProcessingRegionStyleContent.ID);
     if (style == null) {
       style = ProcessingRegionStyleContent.createDefault();
     }
     ProcessingRegion processinRegion =
         new ProcessingRegion(
             style.west, style.east, style.south, style.north, style.rows, style.cols);
     ReferencedEnvelope envelope = new ReferencedEnvelope(processinRegion.getEnvelope(), getCrs());
     return envelope;
   }
   return null;
 }
  public synchronized void render(
      Graphics2D destination, ReferencedEnvelope bounds, IProgressMonitor monitor)
      throws RenderException {

    int endLayerStatus = ILayer.DONE;
    try {
      if (bounds == null || bounds.isNull()) {
        bounds = getContext().getImageBounds();
      }

      if (monitor.isCanceled()) return;

      getContext().setStatus(ILayer.WAIT);

      WebMapServer wms = getWMS();

      GetMapRequest request = wms.createGetMapRequest();

      // put in default exception format we understand as a client
      // (if suppoted by the server)
      WMSCapabilities capabilities = wms.getCapabilities();
      if (capabilities
          .getRequest()
          .getGetMap()
          .getFormats()
          .contains(GetMapRequest.EXCEPTION_XML)) {
        request.setExceptions(GetMapRequest.EXCEPTION_XML);
      }
      setImageFormat(wms, request);

      if (monitor.isCanceled()) return;

      double currScale = getContext().getViewportModel().getScaleDenominator();
      List<ILayer> layers = getLayers();
      for (int i = layers.size() - 1; i >= 0; i--) {
        ILayer ilayer = layers.get(i);
        Layer layer;
        double minScale = 0;
        double maxScale = Double.MAX_VALUE;
        layer = ilayer.getResource(org.geotools.data.ows.Layer.class, null);
        // check if there are min/max scale rules
        StyleBlackboard sb = (StyleBlackboard) ilayer.getStyleBlackboard();
        Style style = (Style) sb.lookup(Style.class);
        if (style != null) {
          Rule rule = style.getFeatureTypeStyles()[0].getRules()[0];
          minScale = rule.getMinScaleDenominator();
          maxScale = rule.getMaxScaleDenominator();
        }

        if (currScale >= minScale && currScale <= maxScale) {
          // check for a wms style
          StyleImpl wmsStyle =
              (StyleImpl) ilayer.getStyleBlackboard().get(WMSStyleContent.WMSSTYLE);
          if (wmsStyle != null) {
            request.addLayer(layer, wmsStyle);
          } else {
            request.addLayer(layer);
          }
        }
      }

      if (monitor.isCanceled()) return;

      List<Layer> wmsLayers = getWMSLayers();
      if (wmsLayers == null || wmsLayers.isEmpty()) {
        endLayerStatus = ILayer.WARNING;
        return;
      }

      // figure out request CRS
      String requestCRScode = findRequestCRS(wmsLayers, getViewportCRS(), getContext().getMap());
      // TODO: make findRequestCRS more efficient (we are running CRS.decode at *least* twice)
      CoordinateReferenceSystem requestCRS = CRS.decode(requestCRScode);

      // figure out viewport
      //            ReferencedEnvelope viewport;
      //            Envelope viewportBBox = getViewportBBox();
      //            CoordinateReferenceSystem viewportCRS = getViewportCRS();
      //            if (viewportBBox == null) {
      //                // change viewport to world
      //                viewportBBox = new Envelope(-180, 180, -90, 90);
      //                if (!DefaultGeographicCRS.WGS84.equals(viewportCRS)) { // reproject
      //                    viewport = new ReferencedEnvelope(viewportBBox,
      // DefaultGeographicCRS.WGS84);
      //                    viewportBBox = viewport.transform(viewportCRS, true);
      //                }
      //            }

      ReferencedEnvelope requestBBox = null;
      Envelope backprojectedBBox = null; // request bbox projected to the viewport crs
      //            viewport = new ReferencedEnvelope(viewportBBox, viewportCRS);
      //            requestBBox = calculateRequestBBox(wmsLayers, viewport, requestCRS);

      requestBBox = calculateRequestBBox(wmsLayers, bounds, requestCRS, capabilities.getVersion());

      // check that a request is needed (not out of a bounds, invalid, etc)
      if (requestBBox == NILL_BOX) {
        endLayerStatus = ILayer.WARNING;
        return;
      }
      assert requestBBox.getCoordinateReferenceSystem().equals(requestCRS);

      if (requestBBox.getCoordinateReferenceSystem().equals(getViewportCRS())) {
        backprojectedBBox = (Envelope) requestBBox;
      } else {
        backprojectedBBox = (Envelope) requestBBox.transform(getViewportCRS(), true);
      }

      if (WMSPlugin.isDebugging(Trace.RENDER)) {
        WMSPlugin.trace("Viewport CRS: " + getViewportCRS().getName()); // $NON-NLS-1$
        WMSPlugin.trace("Request CRS: " + requestCRS.getName()); // $NON-NLS-1$
        WMSPlugin.trace("Context Image bounds: " + getContext().getImageBounds()); // $NON-NLS-1$
        WMSPlugin.trace("Request BBox  bounds: " + requestBBox); // $NON-NLS-1$
        WMSPlugin.trace("Backprojected request bounds: " + backprojectedBBox); // $NON-NLS-1$
      }

      Service wmsService = capabilities.getService();
      Dimension maxDimensions = new Dimension(wmsService.getMaxWidth(), wmsService.getMaxHeight());
      //            Dimension imageDimensions =
      // calculateImageDimensions(getContext().getMapDisplay()
      //                    .getDisplaySize(), maxDimensions, getViewportBBox(), backprojectedBBox);
      Dimension imageDimensions =
          calculateImageDimensions(
              getContext().getImageSize(), maxDimensions, bounds, backprojectedBBox);
      if (imageDimensions.height < 1 || imageDimensions.width < 1) {
        endLayerStatus = ILayer.WARNING;
        return;
      }
      request.setDimensions(
          imageDimensions.width + "", imageDimensions.height + ""); // $NON-NLS-1$ //$NON-NLS-2$
      // epsg could be under identifiers or authority.
      Set<ReferenceIdentifier> identifiers = requestCRS.getIdentifiers();
      String srs = identifiers.isEmpty() ? EPSG_4326 : identifiers.iterator().next().toString();
      request.setSRS(srs); // EPSG_4326
      request.setBBox(requestBBox);
      // request.setBBox(requestBBox.getMinX() + "," + requestBBox.getMinY()+ "," +
      // requestBBox.getMaxX()+ "," + requestBBox.getMaxY());

      if (monitor.isCanceled()) return;

      setFilter(wms, request);

      // request.setProperty("DACS_ACS", null);
      BufferedImage image = readImage(wms, request, monitor);

      if (monitor.isCanceled()) return;

      if (image == null) {
        Exception e = new RuntimeException(Messages.BasicWMSRenderer2_unable_to_decode_image);
        throw wrapException(e);
      }

      // backprojectedBBox or viewportBBox
      renderGridCoverage(destination, backprojectedBBox, imageDimensions, requestBBox, image);

    } catch (Exception e) {
      if (e instanceof RenderException) throw (RenderException) e;
      throw new RenderException(e);
    } finally {
      getContext().setStatus(endLayerStatus);
      if (endLayerStatus == ILayer.DONE) {
        // clear the status message (rendering was successful)
        getContext().setStatusMessage(null);
      }
    }
  }
  public void render(Graphics2D destination, Envelope bounds, IProgressMonitor monitor)
      throws RenderException {
    WMTPlugin.trace("[BasicWMTRender.render] is called"); // $NON-NLS-1$

    if (monitor == null) {
      monitor = new NullProgressMonitor();
    }
    monitor.beginTask("Render WMT", 100); // $NON-NLS-1$
    setState(STARTING);

    ILayer layer = null;
    try {
      layer = getContext().getLayer();
      // assume everything will work fine
      layer.setStatus(ILayer.DONE);
      layer.setStatusMessage(""); // $NON-NLS-1$

      WMTSource wmtSource = getWmtSourceFromLayer(layer);

      if (wmtSource == null)
        throw new UnsupportedOperationException(Messages.Render_Error_NoSource);

      // Layer properties
      WMTLayerProperties layerProperties =
          new WMTLayerProperties((StyleBlackboard) layer.getStyleBlackboard());

      // Get map extent, which should be drawn
      ReferencedEnvelope mapExtent = getRenderBounds();
      if (mapExtent == null) {
        mapExtent = context.getViewportModel().getBounds();
      }

      // Scale
      double scale = getContext().getViewportModel().getScaleDenominator();
      WMTPlugin.trace("[BasicWMTRender.render] Scale: " + scale); // $NON-NLS-1$

      WMTRenderJob renderJob = null;
      try {
        renderJob = WMTRenderJob.createRenderJob(mapExtent, scale, wmtSource);
      } catch (Exception exc) {
        throw new UnsupportedOperationException(Messages.Render_Error_Projection);
      }

      // Find tiles
      Map<String, Tile> tileList =
          wmtSource.cutExtentIntoTiles(
              renderJob, WMTRenderJob.getScaleFactor(), false, layerProperties);

      // if we have nothing to display, return
      if (tileList.isEmpty()) {
        throw new UnsupportedOperationException(Messages.Render_Error_NoData);
      }

      // check if this are too many tiles
      if ((tileList = checkTooManyTiles(layer, wmtSource, layerProperties, renderJob, tileList))
          .isEmpty()) {
        throw new UnsupportedOperationException(Messages.Render_Error_TooManyTiles);
      }

      // Download and display tiles

      // look up the preference for caching tiles on-disk or in
      // memory and use the proper tilerange for that.
      TileRange range = createTileRange(wmtSource, renderJob, tileList);

      // create an empty raster symbolizer for rendering
      RasterSymbolizer style = styleBuilder.createRasterSymbolizer();

      // setup how much each tile is worth for the monitor work %
      int tileCount = range.getTileCount();
      int tileWorth = (tileCount / 100) * tileCount;

      int thisid = 0;
      if (testing) {
        staticid++;
        thisid = staticid;
      }

      // first render any tiles that are ready and render non-ready tiles with blank images
      Map<String, Tile> tiles = range.getTiles();
      Set<String> notRenderedTiles = new HashSet<String>();
      Set<String> renderedTiles = new HashSet<String>();

      renderReadyTiles(
          destination,
          monitor,
          renderJob,
          style,
          tileWorth,
          thisid,
          tiles,
          notRenderedTiles,
          renderedTiles);

      setState(RENDERING);

      // if the tilerange is not already completed, then load
      // the missing tiles
      if (!notRenderedTiles.isEmpty()) {
        renderNotRenderedTiles(
            destination,
            monitor,
            renderJob,
            range,
            style,
            tileWorth,
            thisid,
            notRenderedTiles,
            renderedTiles);
      }

      if (testing) {
        System.out.println("DONE!!!: " + thisid); // $NON-NLS-1$
      }
    } catch (UnsupportedOperationException doneExc) {
      setDone(monitor);

      layer.setStatus(ILayer.ERROR);
      layer.setStatusMessage(doneExc.getMessage());
      WMTPlugin.log("[BasicWMTRenderer.render] Error: ", doneExc); // $NON-NLS-1$

      return;
    } catch (CancellationException cancelExc) {
      return;
    } catch (Exception ex) {
      WMTPlugin.log("[BasicWMTRenderer.render] Unexpected Error: ", ex); // $NON-NLS-1$
    }

    setDone(monitor);
  }
  public boolean canAddLayer(ILayer layer) {

    if (!layer.hasResource(Layer.class)) return false;

    try {
      if (!layer
          .findGeoResource(Layer.class)
          .parent(ProgressManager.instance().get())
          .equals(getRenderContext().getGeoResource().parent(ProgressManager.instance().get())))
        return false;
    } catch (IOException e2) {
      return false;
    }

    double opacity = Double.NaN;

    ICompositeRenderContext context1 = (ICompositeRenderContext) context;

    IRenderContext[] contexts =
        context1.getContexts().toArray(new IRenderContext[context1.getContexts().size()]);
    Arrays.sort(contexts);
    List<Layer> owsLayers = new ArrayList<Layer>();
    IService currentService;
    try {
      owsLayers.add(layer.getResource(Layer.class, new NullProgressMonitor()));
      currentService = layer.getResource(IService.class, null);
    } catch (IOException e1) {
      WMSPlugin.log("", e1); // $NON-NLS-1$
      return false;
    }
    for (IRenderContext renderContext : contexts) {
      ILayer previousLayer = renderContext.getLayer();

      try {
        owsLayers.add(previousLayer.getResource(Layer.class, new NullProgressMonitor()));
        IService previousService = previousLayer.getResource(IService.class, null);
        if (currentService != previousService) {
          return false;
        }
      } catch (IOException e) {
        WMSPlugin.log("Error while retrieving service.", e); // $NON-NLS-1$
        return false;
      }

      if (BasicWMSRenderer2.findRequestCRS(owsLayers, context.getCRS(), context.getMap()) == null)
        return false;

      Style style = (Style) previousLayer.getStyleBlackboard().get(SLDContent.ID);
      if (style != null) {
        opacity = SLDs.rasterOpacity(SLDs.rasterSymbolizer(style));
      }
    }

    Style style = (Style) layer.getStyleBlackboard().get(SLDContent.ID);
    if (style == null && Double.isNaN(opacity)) {
      return true;
    }

    double result = SLDs.rasterOpacity(SLDs.rasterSymbolizer(style));

    if (result == opacity) {
      return true;
    }
    return false;
  }