Ticket #14247: josm_ticket_14247_gpx_heat_map_config_by_kidelo_v1.patch

File josm_ticket_14247_gpx_heat_map_config_by_kidelo_v1.patch, 10.7 KB (added by kidelo, 7 years ago)

Visualize GPX Heat Map Colors by kidelo, version 1

  • src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java

     
    2828import java.util.Date;
    2929import java.util.List;
    3030
     31import javax.swing.ImageIcon;
     32
    3133import org.openstreetmap.josm.Main;
    3234import org.openstreetmap.josm.data.SystemOfMeasurement;
    3335import org.openstreetmap.josm.data.SystemOfMeasurement.SoMChangeListener;
     
    153155    private static Color[] heatMapLutColorJosmRed2Blue = createColorFromResource("red2blue");
    154156
    155157    // user defined heatmap color
    156     private Color[] heatMapLutUserColor = createColorLut(Color.BLACK, Color.WHITE);
     158    private Color[] heatMapLutColor = createColorLut(Color.BLACK, Color.WHITE);
    157159
    158     // heat map color in use
    159     private Color[] heatMapLutColor;
    160 
    161160    private void setupColors() {
    162161        hdopAlpha = Main.pref.getInteger("hdop.color.alpha", -1);
    163162        velocityScale = ColorScale.createHSBScale(256);
     
    165164        hdopScale = ColorScale.createHSBScale(256).makeReversed().addTitle(tr("HDOP"));
    166165        dateScale = ColorScale.createHSBScale(256).addTitle(tr("Time"));
    167166        directionScale = ColorScale.createCyclicScale(256).setIntervalCount(4).addTitle(tr("Direction"));
    168         heatMapLutColor = heatMapLutUserColor;
    169167
    170168        systemOfMeasurementChanged(null, null);
    171169    }
     
    513511        }
    514512
    515513        // heat mode
    516         if (ColorMode.HEATMAP == colored && neutralColor != null) {
     514        if (ColorMode.HEATMAP == colored) {
    517515
    518             // generate new user color map
    519             heatMapLutUserColor = createColorLut(Color.BLACK, neutralColor.darker(),
    520                                                  neutralColor, neutralColor.brighter(), Color.WHITE);
     516            // generate and get new user color map
     517            heatMapLutColor = selectColorMap(neutralColor != null ? neutralColor : Color.WHITE, heatMapDrawColorTableIdx);
    521518
    522             // decide what, keep order is sync with setting on GUI
    523             Color[][] lut = {
    524                     heatMapLutUserColor,
    525                     heatMapLutColorJosmInferno,
    526                     heatMapLutColorJosmViridis,
    527                     heatMapLutColorJosmBrown2Green,
    528                     heatMapLutColorJosmRed2Blue
    529             };
    530 
    531             // select by index
    532             if (heatMapDrawColorTableIdx < lut.length) {
    533                 heatMapLutColor = lut[ heatMapDrawColorTableIdx ];
    534             } else {
    535                 // fallback
    536                 heatMapLutColor = heatMapLutUserColor;
    537             }
    538 
    539519            // force redraw of image
    540520            heatMapMapViewState = null;
    541521        }
     
    782762    }
    783763
    784764    /**
    785      * Creates a linear distributed colormap by linear blending between colors
    786      * @param colors 1..n colors
    787      * @return array of Color objects
     765     * Generates a linear gradient map image
     766     *
     767     * @param width  image width
     768     * @param height image height
     769     * @param colors 1..n color descriptions
     770     * @return image object
    788771     */
    789     protected static Color[] createColorLut(Color... colors) {
     772    protected static BufferedImage createImageGradientMap(int width, int height, Color... colors) {
    790773
    791         // number of lookup entries
    792         int tableSize = 256;
    793 
    794774        // create image an paint object
    795         BufferedImage img = new BufferedImage(tableSize, 1, BufferedImage.TYPE_INT_RGB);
    796         Graphics2D g = img.createGraphics();
     775        final BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
     776        final Graphics2D g = img.createGraphics();
    797777
    798778        float[] fract = new float[ colors.length ];
    799779
     
    803783        }
    804784
    805785        // draw the gradient map
    806         LinearGradientPaint gradient = new LinearGradientPaint(0, 0, tableSize, 1, fract, colors,
     786        LinearGradientPaint gradient = new LinearGradientPaint(0, 0, width, height, fract, colors,
    807787                                                               MultipleGradientPaint.CycleMethod.NO_CYCLE);
    808788        g.setPaint(gradient);
    809         g.fillRect(0, 0, tableSize, 1);
     789        g.fillRect(0, 0, width, height);
    810790        g.dispose();
    811791
    812792        // access it via raw interface
    813         final Raster imgRaster = img.getData();
     793        return img;
     794    }
    814795
     796    /**
     797     * Creates a linear distributed colormap by linear blending between colors
     798     * @param colors 1..n colors
     799     * @return array of Color objects
     800     */
     801    protected static Color[] createColorLut(Color... colors) {
     802
     803        // number of lookup entries
     804        final int tableSize = 256;
     805
     806        // access it via raw interface
     807        final Raster imgRaster = createImageGradientMap(tableSize, 1, colors).getData();
     808
    815809        // the pixel storage
    816810        int[] pixel = new int[1];
    817811
     
    824818        for (int i = 0; i < tableSize; i++) {
    825819
    826820            // get next single pixel
    827             imgRaster.getDataElements((int) (i * (double) img.getWidth() / tableSize), 0, pixel);
     821            imgRaster.getDataElements(i, 0, pixel);
    828822
    829823            // get color and map
    830824            Color c = new Color(pixel[0]);
     
    925919    }
    926920
    927921    /**
     922     * Returns the next user color map
     923     *
     924     * @param userColor - default or fallback user color
     925     * @param tableIdx  - selected user color index
     926     * @return color array
     927     */
     928    protected static Color[] selectColorMap(Color userColor, int tableIdx) {
     929
     930        // generate new user color map
     931        Color[] nextUserColor = createColorLut(Color.BLACK, userColor.darker(),
     932                                               userColor, userColor.brighter(), Color.WHITE);
     933
     934        // decide what, keep order is sync with setting on GUI
     935        Color[][] lut = {
     936                nextUserColor,
     937                heatMapLutColorJosmInferno,
     938                heatMapLutColorJosmViridis,
     939                heatMapLutColorJosmBrown2Green,
     940                heatMapLutColorJosmRed2Blue
     941        };
     942
     943        // select by index
     944        if (tableIdx < lut.length) {
     945            nextUserColor = lut[ tableIdx ];
     946        }
     947
     948        return nextUserColor;
     949    }
     950
     951    /**
     952     * Generates a Icon
     953     *
     954     * @param userColor selected user color
     955     * @param tableIdx tabled index
     956     * @param size size of the image
     957     * @return a image icon that shows the
     958     */
     959    public static ImageIcon getColorMapImageIcon(Color userColor, int tableIdx, int size) {
     960
     961        final BufferedImage img = createImageGradientMap(size, size, selectColorMap(userColor, tableIdx));
     962        return new ImageIcon(img);
     963    }
     964
     965    /**
    928966     * Draw gray heat map with current Graphics2D setting
    929967     * @param gB              the common draw object to use
    930968     * @param mv              the meta data to current displayed area
  • src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java

     
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55import static org.openstreetmap.josm.tools.I18n.trc;
    66
     7import java.awt.Color;
    78import java.awt.Component;
    89import java.awt.GridBagLayout;
    910import java.awt.event.ActionListener;
     
    1920
    2021import org.openstreetmap.josm.Main;
    2122import org.openstreetmap.josm.actions.ExpertToggleAction;
     23import org.openstreetmap.josm.gui.layer.gpx.GpxDrawHelper;
    2224import org.openstreetmap.josm.gui.layer.markerlayer.Marker;
    2325import org.openstreetmap.josm.gui.layer.markerlayer.Marker.TemplateEntryProperty;
    2426import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane.ValidationListener;
     
    5557    private final JRadioButton colorTypeDirection = new JRadioButton(tr("Direction (red = west, yellow = north, green = east, blue = south)"));
    5658    private final JRadioButton colorTypeDilution = new JRadioButton(tr("Dilution of Position (red = high, green = low, if available)"));
    5759    private final JRadioButton colorTypeTime = new JRadioButton(tr("Track date"));
    58     private final JRadioButton colorTypeHeatMap = new JRadioButton(tr("Heat Map (dark = few tracks, bright = many tracks)"));
     60    private final JRadioButton colorTypeHeatMap = new JRadioButton(tr("Heat Map (dark = few, bright = many)"));
    5961    private final JRadioButton colorTypeNone = new JRadioButton(tr("Single Color (can be customized for named layers)"));
    6062    private final JRadioButton colorTypeGlobal = new JRadioButton(tr("Use global settings"));
    6163    private final JosmComboBox<String> colorTypeVelocityTune = new JosmComboBox<>(new String[] {tr("Car"), tr("Bicycle"), tr("Foot")});
     
    6567        trc("Heat map", "Viridis"),
    6668        trc("Heat map", "Wood"),
    6769        trc("Heat map", "Heat")});
     70    private JLabel colorTypeHeatIconLabel;
    6871    private final JCheckBox makeAutoMarkers = new JCheckBox(tr("Create markers when reading GPX"));
    6972    private final JCheckBox drawGpsArrows = new JCheckBox(tr("Draw Direction Arrows"));
    7073    private final JCheckBox drawGpsArrowsFast = new JCheckBox(tr("Fast drawing (looks uglier)"));
     
    259262        colorTypeVelocityTune.setToolTipText(tr("Allows to tune the track coloring for different average speeds."));
    260263
    261264        colorTypeHeatMapTune.setToolTipText(tr("Selects the color schema for heat map."));
     265        colorTypeHeatIconLabel = new JLabel();
    262266
    263267        add(Box.createVerticalGlue(), GBC.eol().insets(0, 20, 0, 0));
    264268
     
    273277        add(colorTypeDilution, GBC.eol().insets(40, 0, 0, 0));
    274278        add(colorTypeTime, GBC.eol().insets(40, 0, 0, 0));
    275279        add(colorTypeHeatMap, GBC.std().insets(40, 0, 0, 0));
    276         add(colorTypeHeatMapTune, GBC.eop().fill(GBC.HORIZONTAL).insets(5, 0, 0, 5));
     280        add(colorTypeHeatIconLabel, GBC.std().insets(5, 0, 0, 5));
     281        add(colorTypeHeatMapTune, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 0, 0, 5));
    277282
     283        colorTypeHeatMapTune.addPropertyChangeListener(e -> {
     284            // get image size of environment
     285            final int iconSize = (int) colorTypeHeatMapTune.getPreferredSize().getHeight();
     286            // ask the GPX draw for the correct color of that layer
     287            final Color color = GpxDrawHelper.DEFAULT_COLOR.getChildColor(layerName).get();
     288            colorTypeHeatIconLabel.setIcon(GpxDrawHelper.getColorMapImageIcon(color, colorTypeHeatMapTune.getSelectedIndex(), iconSize));
     289        });
     290
    278291        ExpertToggleAction.addVisibilitySwitcher(colorTypeDirection);
    279292        ExpertToggleAction.addVisibilitySwitcher(colorTypeDilution);
    280293