Package org.locationtech.udig.style.jgrass.legend

Source Code of org.locationtech.udig.style.jgrass.legend.RasterLegendGraphic

/*
* JGrass - Free Open Source Java GIS http://www.jgrass.org
* (C) HydroloGIS - www.hydrologis.com
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the HydroloGIS BSD
* License v1.0 (http://udig.refractions.net/files/hsd3-v10.html).
*/
package org.locationtech.udig.style.jgrass.legend;

import static java.lang.Math.round;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.List;

import org.locationtech.udig.mapgraphic.MapGraphic;
import org.locationtech.udig.mapgraphic.MapGraphicContext;
import org.locationtech.udig.project.IBlackboard;
import org.locationtech.udig.project.ILayer;
import org.locationtech.udig.project.IMap;
import org.locationtech.udig.project.ui.ApplicationGIS;
import org.locationtech.udig.ui.graphics.ViewportGraphics;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.geotools.gce.grassraster.JGrassMapEnvironment;
import org.geotools.gce.grassraster.core.color.JGrassColorTable;

import org.locationtech.udig.catalog.jgrass.activeregion.dialogs.JGRasterChooserDialog;
import org.locationtech.udig.catalog.jgrass.core.JGrassMapGeoResource;


/**
* @author Andrea Antonello - www.hydrologis.com
*/
public class RasterLegendGraphic implements MapGraphic {

    public final static String LEGEND_SEPERATOR = "|"; //$NON-NLS-1$

    private Thread run;

    private Display display;

    private Thread run2;

    private static Shell shell;

    private RasterLegendStyle legendStyle;

    public void draw( MapGraphicContext context ) {
        IMap activeMap = ApplicationGIS.getActiveMap();
        IMap currentMap = context.getLayer().getMap();
        if (!activeMap.equals(currentMap)) {
            return;
        }

        context.getLayer().setStatus(ILayer.WORKING);

        display = Display.getDefault();
        setShell();

        /*
         * get the blackboard from the map and not from the layer. This
         * is due to the fact that we need the mapreader here to get the
         * legend string. The mapreader is put on blackboard by the
         * raster renderer.
         */

        IBlackboard blackboard = context.getMap().getBlackboard();
        legendStyle = (RasterLegendStyle) blackboard.get(RasterLegendStyleContent.ID);
        if (legendStyle == null) {
            legendStyle = RasterLegendStyleContent.createDefault();
            blackboard.put(RasterLegendStyleContent.ID, legendStyle);
            // ((IBlackboard) blackboard).setSelected(new String[]{RasterLegendStyleContent.ID});
        }

        String mapPath = legendStyle.mapPath;
        if (mapPath == null) {
            getMapPath(blackboard);
            mapPath = legendStyle.mapPath;
        }

        if (mapPath == null) {
            return;
        }

        File cellFile = new File(mapPath);
        if (!cellFile.exists()) {
            context.getLayer().setStatus(ILayer.ERROR);
            return;
        }
        JGrassMapEnvironment jGrassMapEnvironment = new JGrassMapEnvironment(cellFile);
        List<String> categories = null;
        List<String> colorRules = null;
        try {
            categories = jGrassMapEnvironment.getCategories();
            colorRules = jGrassMapEnvironment.getColorRules(null);
        } catch (IOException e) {
            e.printStackTrace();
            context.getLayer().setStatus(ILayer.ERROR);
            return;
        }

        final ViewportGraphics graphics = context.getGraphics();

        /* Draw the legend. */
        if (categories.size() == 0 || categories.size() != colorRules.size()) {
            // draw a color ramp legend

            int rulesNum = colorRules.size();

            // get initially the text properties from the title
            String titleString = legendStyle.titleString;
            int textheight = (int) round(graphics.getStringBounds(titleString).getHeight());
            if (titleString.length() == 0)
                textheight = 0;

            int w = round(legendStyle.legendWidth);
            int h = round(legendStyle.legendHeight);
            int x = round(legendStyle.xPos);
            int y = round(legendStyle.yPos);

            int bWidth = round(legendStyle.boxWidth);
            /*
             * calculate the boxheight from:
             * legendHeight = 1/2 bHeight + textHeight + 1/2 bHeight + rulseNum*bHeight + 1/2 bHeight
             */
            int bHeight = round((h - textheight) / (3f / 2f + rulesNum));
            int yInset = bHeight / 2;
            int xInset = 15;

            int currentX = x + xInset;
            int currentY = y + yInset + textheight;
            if (textheight == 0) {
                currentY = y;
                h = h - yInset;
            }

            if (legendStyle.isRoundedRectangle) {
                graphics.setColor(legendStyle.backgroundColor);
                graphics.fillRoundRect(round(x), round(y), round(w), round(h), 15, 15);
                graphics.setColor(legendStyle.foregroundColor);
                graphics.setBackground(legendStyle.backgroundColor);
                graphics.drawRoundRect(round(x), round(y), round(w), round(h), 15, 15);
            } else {
                graphics.setColor(legendStyle.backgroundColor);
                graphics.fillRect(round(x), round(y), round(w), round(h));
                graphics.setColor(legendStyle.foregroundColor);
                graphics.setBackground(legendStyle.backgroundColor);
                graphics.drawRect(round(x), round(y), round(w), round(h));
            }

            // draw the title
            if (textheight != 0) {
                graphics.setColor(legendStyle.fontColor);
                graphics.drawString(titleString, currentX,// +horizontalMargin,
                        currentY,// +textVerticalOffset,
                        ViewportGraphics.ALIGN_LEFT, ViewportGraphics.ALIGN_LEFT);
            }
            currentY = currentY + yInset;

            for( int i = 0; i < colorRules.size(); i++ ) {
                String rule = colorRules.get(i);

                double[] values = new double[2];
                Color[] colors = new Color[2];
                JGrassColorTable.parseColorRule(rule, values, colors);

                String firstValue = String.valueOf(values[0]);
                Color actualColor = colors[0];

                String secondValue = String.valueOf(values[1]);
                Color nextColor = colors[1];

                graphics.fillGradientRectangle(currentX, currentY, bWidth, bHeight, actualColor, nextColor, true);

                int tx = round(currentX + 1.5f * bWidth);
                graphics.setColor(legendStyle.fontColor);
                graphics.drawString(String.format("%-8.2f", Float.parseFloat(firstValue)), //$NON-NLS-1$
                        tx,// +horizontalMargin,
                        currentY, // - graphics.getFontAscent(),// +textVerticalOffset,
                        ViewportGraphics.ALIGN_LEFT, ViewportGraphics.ALIGN_MIDDLE);

                currentY = currentY + bHeight;

                if (i == colorRules.size() - 1) {
                    // add also last text
                    tx = round(currentX + 1.5f * bWidth);
                    graphics.setColor(legendStyle.fontColor);
                    graphics.drawString(String.format("%-8.2f", Float.parseFloat(secondValue)), //$NON-NLS-1$
                            tx,// +horizontalMargin,
                            currentY, // - graphics.getFontAscent(),// +textVerticalOffset,
                            ViewportGraphics.ALIGN_LEFT, ViewportGraphics.ALIGN_MIDDLE);
                }

            }

        } else {

            // draw a categories legend
            int rulesNum = colorRules.size();

            // get initially the text properties from the title
            String titleString = legendStyle.titleString;
            int textheight = (int) round(graphics.getStringBounds(titleString).getHeight());
            if (titleString.length() == 0)
                textheight = 0;

            int w = round(legendStyle.legendWidth);
            int h = round(legendStyle.legendHeight);
            int x = round(legendStyle.xPos);
            int y = round(legendStyle.yPos);

            int bWidth = round(legendStyle.boxWidth);
            /*
             * calculate the boxheight from:
             * legendHeight = 1/2 bHeight + textHeight + 1/2 bHeight + rulseNum*(bHeight + 1/3 bHeight) + 1/2 bHeight
             */
            int bHeight = round((h - textheight) / (3f / 2f + 4f / 3f * rulesNum));
            int yInset = bHeight / 2;
            int xInset = 15;

            int currentX = x + xInset;
            int currentY = y + yInset + textheight;
            if (textheight == 0) {
                currentY = y;
                h = (int) (h - yInset - 1f / 3f * bHeight);
            }

            if (legendStyle.isRoundedRectangle) {
                graphics.setColor(legendStyle.backgroundColor);
                graphics.fillRoundRect(round(x), round(y), round(w), round(h), 15, 15);
                graphics.setColor(legendStyle.foregroundColor);
                graphics.setBackground(legendStyle.backgroundColor);
                graphics.drawRoundRect(round(x), round(y), round(w), round(h), 15, 15);
            } else {
                graphics.setColor(legendStyle.backgroundColor);
                graphics.fillRect(round(x), round(y), round(w), round(h));
                graphics.setColor(legendStyle.foregroundColor);
                graphics.setBackground(legendStyle.backgroundColor);
                graphics.drawRect(round(x), round(y), round(w), round(h));
            }

            // draw the title
            if (textheight != 0) {
                graphics.setColor(legendStyle.fontColor);
                graphics.drawString(titleString, currentX,// +horizontalMargin,
                        currentY,// +textVerticalOffset,
                        ViewportGraphics.ALIGN_LEFT, ViewportGraphics.ALIGN_LEFT);
            }
            currentY = currentY + yInset;

            for( int i = 0; i < colorRules.size(); i++ ) {
                String rule = colorRules.get(i);
                String cat = categories.get(i);

                int lastColon = cat.lastIndexOf(':');
                String attribute = cat.substring(lastColon + 1);

                double[] values = new double[2];
                Color[] colors = new Color[2];
                JGrassColorTable.parseColorRule(rule, values, colors);
                String firstValue = String.valueOf(values[0]);

                graphics.setColor(Color.black);
                graphics.drawRect(currentX, currentY, bWidth, bHeight);
                graphics.setColor(colors[0]);
                graphics.fillRect(currentX, currentY, bWidth, bHeight);

                int tx = round(currentX + 1.5f * bWidth);
                int tHeight = (int) round(graphics.getStringBounds(attribute).getHeight());
                graphics.setColor(legendStyle.fontColor);
                int ty = round(currentY - graphics.getFontAscent() + tHeight);// + tHeight -
                // bHeight/3f);
                graphics.drawString(attribute, tx,// +horizontalMargin,
                        ty, // - graphics.getFontAscent(),// +textVerticalOffset,
                        ViewportGraphics.ALIGN_LEFT, ViewportGraphics.ALIGN_MIDDLE);

                currentY = round(currentY + 4f / 3f * bHeight);

            }

        }

        System.out.println();

        // if (colorRules.size() > 0) {
        //
        // int leftentries = (legendSplit.length - 1) / 2;
        // String[][] legend = new String[leftentries][2];
        //
        // int numberOfLegendEntries = 0;
        // int index = 1;
        // for( int i = 0; i < legend.length; i++ ) {
        //
        // String legendText = legendSplit[index].replace('_', ' ');
        //
        // if (isDiscrete) {
        // // draw discrete legend
        // legend[i][0] = legendText;
        // } else {
        // // draw a legend with range blending
        //                    if (!legendText.equals("")) { //$NON-NLS-1$
        //                        String[] intervalMaxMin = legendText.split(" to "); //$NON-NLS-1$
        // float intervalmin = Float.parseFloat(intervalMaxMin[0]);
        // float intervalmax = Float.parseFloat(intervalMaxMin[1]);
        // float delta = (intervalmax - intervalmin) / 6f;
        // legend[i - 3][0] = String.valueOf(intervalmin);
        // legend[i - 2][0] = String.valueOf(intervalmin + delta);
        // legend[i - 1][0] = String.valueOf(intervalmin + 2f * delta);
        // legend[i][0] = String.valueOf(intervalmin + 3f * delta);
        // legend[i + 1][0] = String.valueOf(intervalmin + 4f * delta);
        // legend[i + 2][0] = String.valueOf(intervalmin + 5f * delta);
        // legend[i + 3][0] = String.valueOf(intervalmax);
        // }
        // }
        // String legendColor = legendSplit[index + 1];
        // legend[i][1] = legendColor;
        // index = index + 2;
        // }
        //
        // // remove double entries and search for the longest string
        // LinkedHashMap<String, String> leg = new LinkedHashMap<String, String>(6);
        // int maxStringLength = 0;
        // for( int j = 0; j < legend.length; j++ ) {
        // leg.put(legend[j][0], legend[j][1]);
        //
        // double textWidth = graphics.getStringBounds(legend[j][0]).getWidth();
        // if (textWidth > maxStringLength) {
        // maxStringLength = (int) textWidth;
        // }
        // }
        // // check if the supplied title is longer
        // String titleString = legendStyle.titleString;
        // double textWidth = graphics.getStringBounds(titleString).getWidth();
        // if (maxStringLength < (int) textWidth)
        // maxStringLength = (int) textWidth;
        //
        // int textheight = (int) Math
        // .ceil(graphics.getStringBounds(titleString).getHeight() / 5.0);
        //
        // legend = new String[leg.size()][2];
        // numberOfLegendEntries = legend.length;
        // // Iterate over the keys in the map
        // Iterator<String> it = leg.keySet().iterator();
        // for( int i = 0; i < legend.length; i++ ) {
        // // Get key
        // legend[i][0] = it.next();
        // legend[i][1] = leg.get(legend[i][0]);
        // }
        //
        // /*
        // * finally start to draw
        // */
        // float bWidth = legendStyle.boxWidth;
        // // estimate min width (inset + boxwidth + space before test + longest text + inset)
        // float minwidth = bWidth / 4f + bWidth + 0.5f * bWidth + maxStringLength + bWidth / 4f;
        // if (legendStyle.legendWidth < minwidth) {
        // legendStyle.legendWidth = (int) minwidth;
        // }
        //
        // float w = legendStyle.legendWidth;
        // float h = legendStyle.legendHeight;
        // float x = legendStyle.xPos;
        // float y = legendStyle.yPos;
        // /*
        // * draw the box
        // */
        // if (legendStyle.isRoundedRectangle) {
        // graphics.setColor(legendStyle.backgroundColor);
        // graphics.fillRoundRect((int) x, (int) y, (int) w, (int) h, 15, 15);
        // graphics.setColor(legendStyle.foregroundColor);
        // graphics.setBackground(legendStyle.backgroundColor);
        // graphics.drawRoundRect((int) x, (int) y, (int) w, (int) h, 15, 15);
        // } else {
        // graphics.setColor(legendStyle.backgroundColor);
        // graphics.fillRect((int) x, (int) y, (int) w, (int) h);
        // graphics.setColor(legendStyle.foregroundColor);
        // graphics.setBackground(legendStyle.backgroundColor);
        // graphics.drawRect((int) x, (int) y, (int) w, (int) h);
        // }
        // /*
        // * discrete or not dependent parts
        // */
        // float strokewidth = 1f;
        // // upper and lower inset
        // float yinset = bWidth / 2f;
        // yinset = (float) Math.ceil(yinset);
        // if (isDiscrete) {
        // // the size of the box
        // float ybox = (h - 2f * strokewidth * numberOfLegendEntries - 2f * yinset)
        // / (numberOfLegendEntries * 6f / 5f - 1f / 5f - 0.75f - boxheightcorrection);
        // ybox = (float) Math.ceil(ybox);
        // // space between a box and the other
        // float yglue = ybox / 5f;
        // yglue = (float) Math.ceil(yglue);
        //
        // float currentX = x + yinset / 2f;
        // float currentY = y + yinset / 2f;
        //
        // // draw the title
        // float dx = currentX;// + 1.5f * bWidth;
        // float dy = currentY + ybox * 3f / 4f;
        // graphics.setColor(legendStyle.fontColor);
        // graphics.drawString(titleString, (int) dx,// +horizontalMargin,
        // (int) dy,// +textVerticalOffset,
        // ViewportGraphics.ALIGN_LEFT, ViewportGraphics.ALIGN_LEFT);
        // currentY = currentY + ybox + yglue;
        //
        // // draw the colorbox
        // for( int i = 0; i < legend.length; i++ ) {
        //
        // graphics.setColor(legendStyle.foregroundColor);
        // graphics.setStroke(ViewportGraphics.LINE_SOLID, (int) strokewidth);
        // graphics.drawRect((int) currentX, (int) currentY, (int) bWidth, (int) ybox);
        //
        // String attribute = legend[i][0];
        // graphics.setColor(JGrassUtilities.getColor(legend[i][1], Color.black));
        // graphics.fillRect((int) currentX + 2, (int) currentY + 2, (int) bWidth - 4,
        // (int) ybox - 4);
        //
        // float tx = currentX + 1.5f * bWidth;
        // float ty = currentY + ybox * 3f / 4f;
        //
        // graphics.setColor(legendStyle.fontColor);
        // graphics.drawString(attribute, (int) tx,// +horizontalMargin,
        // (int) ty,// +textVerticalOffset,
        // ViewportGraphics.ALIGN_LEFT, ViewportGraphics.ALIGN_LEFT);
        //
        // currentY = currentY + ybox + yglue;
        // }
        //
        // } else {
        // // GRADIENT LEGEND
        // // the size of the box
        // float ybox = (h - 2f * yinset)
        // / (numberOfLegendEntries + boxheightcorrection + textheight);
        //
        // ybox = (float) Math.floor(ybox);
        //
        // float currentX = x + yinset;
        // float currentY = y + 2f * yinset;
        // float startX = x + yinset;
        // float startY = y + yinset;
        //
        // // draw the title
        // graphics.setColor(legendStyle.fontColor);
        // graphics.drawString(titleString, (int) currentX,// +horizontalMargin,
        // (int) currentY,// +textVerticalOffset,
        // ViewportGraphics.ALIGN_LEFT, ViewportGraphics.ALIGN_LEFT);
        // currentY = currentY + yinset;
        //
        // for( int i = 0; i < legend.length; i++ ) {
        // String attribute = legend[i][0];
        // Color actualColor = JGrassUtilities.getColor(legend[i][1], Color.black);
        // Color nextColor = null;
        //
        // if (i != legend.length - 1) {
        // nextColor = JGrassUtilities.getColor(legend[i + 1][1], Color.black);
        //
        // graphics.fillGradientRectangle((int) currentX, (int) currentY,
        // (int) bWidth, (int) ybox, actualColor, nextColor, true);
        // } else {
        // // in the last just make it without gradient
        // nextColor = actualColor;
        // graphics.fillGradientRectangle((int) currentX, (int) currentY,
        // (int) bWidth, (int) ybox, actualColor, nextColor, true);
        // }
        //
        // if (i % 3 == 0) {
        // float tx = currentX + 1.5f * bWidth;
        // float ty = currentY + ybox * 3f / 4f;
        // graphics.setColor(legendStyle.fontColor);
        //                        graphics.drawString(Format.sprintf("%-8.2f", Float.parseFloat(attribute)), //$NON-NLS-1$
        // (int) tx,// +horizontalMargin,
        // (int) ty, // - graphics.getFontAscent(),// +textVerticalOffset,
        // ViewportGraphics.ALIGN_LEFT, ViewportGraphics.ALIGN_MIDDLE);
        // }
        //
        // currentY = currentY + ybox;
        //
        // }
        // /*
        // * correct the box errors due to the rounding
        // */
        // float end = currentY + yinset;
        // float falseEnd = y + h;
        // // delete
        // Rectangle eraseRec = new Rectangle((int) x - 1, (int) end, (int) w + 1,
        // (int) (falseEnd - end));
        // graphics.setColor(new Color(0, 0, 0));
        // graphics.setClip(eraseRec);
        //
        // // draw the colorbox
        // graphics.setColor(legendStyle.foregroundColor);
        // graphics.drawRect((int) startX, (int) startY, (int) bWidth,
        // (int) ((numberOfLegendEntries - 0.5f) * ybox));
        //
        // }
        //
        // }

        context.getLayer().setStatus(ILayer.DONE);
    }

    private void getMapPath( final IBlackboard blackboard ) {
        run = new Thread(new Runnable(){
            public void run() {
                display.syncExec(new Runnable(){
                    public void run() {
                        JGRasterChooserDialog chooserDialog = new JGRasterChooserDialog(null);
                        chooserDialog.open(shell, SWT.SINGLE);
                        List<JGrassMapGeoResource> resources = chooserDialog.getSelectedResources();
                        if (resources != null && resources.size() > 0) {
                            JGrassMapGeoResource res = resources.get(0);
                            File mapFile = res.getMapFile();
                            legendStyle.mapPath = mapFile.getAbsolutePath();
                            blackboard.put(RasterLegendStyleContent.ID, legendStyle);
                            // ((StyleBlackboard) blackboard).setSelected(new
                            // String[]{RasterLegendStyleContent.ID});
                        }
                    }
                });
            }
        });
        run.start();

        while( run.isAlive() ) {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    private void setShell() {
        if (shell != null)
            return;

        run2 = new Thread(new Runnable(){
            public void run() {
                display.syncExec(new Runnable(){
                    public void run() {
                        shell = PlatformUI.getWorkbench().getDisplay().getActiveShell();
                    }
                });
            }
        });
        run2.start();
        while( run2.isAlive() ) {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
TOP

Related Classes of org.locationtech.udig.style.jgrass.legend.RasterLegendGraphic

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.