Revision 4161

View differences:

org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/pom.xml
1
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2
  <modelVersion>4.0.0</modelVersion>
3
  <parent>
4
    <groupId>org.gvsig</groupId>
5
    <artifactId>org.gvsig.legend.filteredheatmap</artifactId>
6
    <version>1.0.50</version>
7
  </parent>
8
  <groupId>org.gvsig</groupId>
9
  <artifactId>org.gvsig.legend.filteredheatmap.lib</artifactId>
10
  <packaging>pom</packaging>
11
  <modules>
12
    <module>org.gvsig.legend.filteredheatmap.lib.api</module>
13
    <module>org.gvsig.legend.filteredheatmap.lib.impl</module>
14
  </modules>
15
</project>
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.api/src/main/java/org/gvsig/legend/filteredheatmap/lib/api/KernelExpressionAlgorithm.java
1
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.legend.filteredheatmap.lib.api;
7

  
8
import java.awt.Color;
9
import java.awt.Graphics2D;
10
import java.awt.image.BufferedImage;
11
import org.gvsig.expressionevaluator.Expression;
12
import org.gvsig.fmap.geom.Geometry;
13
import org.gvsig.tools.task.Cancellable;
14

  
15
/**
16
 *
17
 * @author osc
18
 */
19
public interface KernelExpressionAlgorithm {
20

  
21
    public void setDistance(int distance);
22

  
23
    public int getDistance();
24

  
25
    public void init(int with, int height);
26

  
27
    public void add(int px, int py);
28

  
29
    public void add(int px, int py, double value);
30

  
31
    public void drawWithOpaqueColors(BufferedImage img, Graphics2D g, Color[] colorTable, Cancellable cancel, Geometry roi, int limitProportionToDraw);
32

  
33
    public void drawWithAlphaColors(BufferedImage img, Graphics2D g, Color[] colorTable, Cancellable cancel, Geometry roi, int limitProportion);
34

  
35
    public Expression getKernelExpression();
36

  
37
    public void setKernelExpression(Expression kernelExpression);
38
}
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.api/src/main/java/org/gvsig/legend/filteredheatmap/lib/api/FilteredHeatmapLegendManager.java
1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2015 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 3
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.legend.filteredheatmap.lib.api;
24

  
25
import org.gvsig.expressionevaluator.SymbolTable;
26

  
27

  
28
public interface FilteredHeatmapLegendManager {
29

  
30
    /**
31
     * Creates an aggregate legend
32
     *
33
     * @return the aggregate legend
34
     */
35
    public FilteredHeatmapLegend create();
36

  
37
    public Class<? extends FilteredHeatmapLegend> getLegendClass(); 
38
    
39
    public SymbolTable createKernelSymbolTable(KernelExpressionAlgorithm alg, int x, int y);
40
    
41
    public KernelExpressionAlgorithm createKernelExpressionAlgorithm(int distance);
42
    
43
}
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.api/src/main/java/org/gvsig/legend/filteredheatmap/lib/api/FilteredHeatmapLegend.java
1
package org.gvsig.legend.filteredheatmap.lib.api;
2

  
3
import java.awt.Color;
4
import org.gvsig.expressionevaluator.Expression;
5
import org.gvsig.fmap.geom.Geometry;
6
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
7

  
8
public interface FilteredHeatmapLegend extends IVectorLegend {
9

  
10
    public int getDistance();
11

  
12
    public void setDistance(int distance);
13

  
14
    public void setColorTable(Color[] colorTable);
15

  
16
    public void setColorTable(int numColors, Color coldColor, Color hotColor);
17

  
18
    public Color[] getSourceColorTable();
19

  
20
    public Color[] getTargetColorTable();
21
    
22
    public Geometry getROI();
23
    
24
    public void setROI(Geometry roi);
25

  
26
    public boolean useRamp();
27

  
28
    public String getFieldName();
29

  
30
    public void setFieldName(String fieldName);
31

  
32
    public int getColorTableHotColorAlpha();
33

  
34
    public void setColorTableHotColorAlpha(int colorTableHotColorAlpha);
35

  
36
    public int getColorTableColdColorAlpha();
37

  
38
    public void setColorTableColdColorAlpha(int colorTableColdColorAlpha);
39

  
40
    public boolean useAlphaInColorTable();
41

  
42
    public boolean setUseAlphaInColorTable(boolean use);
43

  
44
    public int getRampNumColors();
45

  
46
    public Color getRampColdColor();
47

  
48
    public Color getRampHotColor();
49
    
50
    public int getFilterProportionValue();
51
    public void setFilterProportionValue(int proportionValue);
52
    
53
    public Expression getFilterByExpression();
54
    public void setFilterByExpression(Expression filterExpression);
55
    
56
    public boolean getUseFilterByExpression();
57
    public void setUseFilterByExpression(boolean useFilterExpression);
58
    
59
    public Expression getKernelExpression();
60
    public void setKernelExpression(Expression kernelExpression);
61
    
62
    
63

  
64
}
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.api/src/main/java/org/gvsig/legend/filteredheatmap/lib/api/FilteredHeatmapLegendLocator.java
1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2015 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.legend.filteredheatmap.lib.api;
24

  
25
import org.gvsig.expressionevaluator.SymbolTable;
26
import org.gvsig.tools.locator.AbstractLocator;
27
import org.gvsig.tools.locator.Locator;
28
import org.gvsig.tools.locator.LocatorException;
29

  
30

  
31
public class FilteredHeatmapLegendLocator extends AbstractLocator {
32

  
33
    /**
34
     * FilteredHeatmapLegend locator name
35
     */
36
    private static final String LOCATOR_NAME = "FilteredHeatmapLegendLocator";
37

  
38
    /**
39
     * HeatmapLegend manager name
40
     */
41
    public static final String MANAGER_NAME = "FilteredHeatmapLegendManager";
42

  
43
    /**
44
     * HeatmapLegend manager description
45
     */
46
    private static final String MANAGER_DESCRIPTION =
47
        "FilteredHeatmapLegend Manager of gvSIG";
48

  
49

  
50
    /**
51
     * Unique instance
52
     */
53
    private static final FilteredHeatmapLegendLocator instance = new FilteredHeatmapLegendLocator();
54

  
55
    @Override
56
    public String getLocatorName() {
57
        return LOCATOR_NAME;
58
    }
59

  
60
    /**
61
     * Registers the Class implementing the FilteredHeatmapLegendManager interface.
62
     *
63
     * @param clazz
64
     *            implementing the FilteredHeatmapLegendManager interface
65
     */
66
    public static void registerFilteredHeatmapLegendManager(Class clazz){
67
        getInstance().register(MANAGER_NAME, MANAGER_DESCRIPTION, clazz);
68
    }
69

  
70
    /**
71
     * Registers the default Class implementing the FilteredHeatmapLegendManager interface
72
     *
73
     * @param clazz
74
     *            implementing the FilteredHeatmapLegendManager interface
75
     */
76
    public static void registerDefaultFilteredHeatmapLegendManager(Class clazz){
77
        getInstance().registerDefault(MANAGER_NAME, MANAGER_DESCRIPTION, clazz);
78
    }
79

  
80
    /**
81
     * Return a reference to FilteredHeatmapLegendManager.
82
     *
83
     * @return a reference to HeatmapLegendManager
84
     * @throws LocatorException
85
     *             if there is no access to the class or the class
86
     *             cannot be instantiated
87
     * @see Locator#get(String)
88
     */
89
    public static FilteredHeatmapLegendManager getFilteredHeatmapLegendManager() throws LocatorException {
90
        return (FilteredHeatmapLegendManager) getInstance().get(MANAGER_NAME);
91
    }
92

  
93
    /**
94
     * @return
95
     */
96
    public static Locator getInstance() {
97
        return instance;
98
    }
99

  
100
}
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.api/src/main/java/org/gvsig/legend/filteredheatmap/lib/api/FilteredHeatmapLegendLibrary.java
1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2015 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.legend.filteredheatmap.lib.api;
24

  
25
import org.gvsig.fmap.mapcontext.MapContextLocator;
26
import org.gvsig.fmap.mapcontext.MapContextManager;
27
import org.gvsig.fmap.mapcontext.rendering.legend.driver.ILegendWriter;
28
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
29
import org.gvsig.symbology.SymbologyLocator;
30
import org.gvsig.symbology.SymbologyManager;
31
import org.gvsig.tools.library.AbstractLibrary;
32
import org.gvsig.tools.library.LibraryException;
33
import org.gvsig.tools.locator.ReferenceNotRegisteredException;
34

  
35

  
36
public class FilteredHeatmapLegendLibrary extends AbstractLibrary {
37

  
38
    @Override
39
    protected void doInitialize() throws LibraryException {
40
        registerAsAPI(FilteredHeatmapLegendLibrary.class);
41
    }
42

  
43
    @Override
44
    protected void doPostInitialize() throws LibraryException {
45
        // Validate there is any implementation registered.
46
        FilteredHeatmapLegendManager manager = FilteredHeatmapLegendLocator.getFilteredHeatmapLegendManager();
47
        if (manager == null) {
48
            throw new ReferenceNotRegisteredException(
49
                FilteredHeatmapLegendLocator.MANAGER_NAME, FilteredHeatmapLegendLocator.getInstance());
50
        }
51

  
52
        SymbologyManager symbolManager = SymbologyLocator.getSymbologyManager();
53
        ILegendWriter legendWriter = symbolManager.getDefaultLegendWriter();
54

  
55
        MapContextManager mcoman = MapContextLocator.getMapContextManager();
56
        mcoman.registerLegendWriter(
57
            FilteredHeatmapLegend.class,
58
            SymbolManager.LEGEND_FILE_EXTENSION.substring(1),
59
            legendWriter.getClass());
60
    }
61

  
62
}
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.api/src/main/resources/META-INF/services/org.gvsig.tools.library.Library
1
org.gvsig.legend.filteredheatmap.lib.api.FilteredHeatmapLegendLibrary
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.api/pom.xml
1
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2
  <modelVersion>4.0.0</modelVersion>
3
  <groupId>org.gvsig</groupId>
4
  <artifactId>org.gvsig.legend.filteredheatmap.lib.api</artifactId>
5
  <name>org.gvsig.legend.filteredheatmap.lib.api</name>
6
  <parent>
7
    <groupId>org.gvsig</groupId>
8
    <artifactId>org.gvsig.legend.filteredheatmap.lib</artifactId>
9
    <version>1.0.50</version>
10
  </parent>
11

  
12
  <build>
13
    <plugins>
14
      <plugin>
15
        <groupId>org.apache.maven.plugins</groupId>
16
        <artifactId>maven-jar-plugin</artifactId>
17
        <configuration>
18
        </configuration>
19
        <executions>
20
          <!-- Generates a jar file only with the test classes -->
21
          <execution>
22
            <goals>
23
              <goal>test-jar</goal>
24
            </goals>
25
          </execution>
26
        </executions>
27
      </plugin>
28
    </plugins>
29
  </build>
30

  
31
  <dependencies>
32
    <dependency>
33
      <groupId>org.gvsig</groupId>
34
      <artifactId>org.gvsig.tools.lib</artifactId>
35
      <scope>compile</scope>
36
    </dependency>
37
    <dependency>
38
      <groupId>org.gvsig</groupId>
39
      <artifactId>org.gvsig.fmap.mapcontext.api</artifactId>
40
      <scope>compile</scope>
41
    </dependency>
42
    <dependency>
43
      <groupId>org.gvsig</groupId>
44
      <artifactId>org.gvsig.symbology.lib.api</artifactId>
45
    </dependency>
46
  </dependencies>
47
</project>
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.impl/src/main/java/org/gvsig/legend/filteredheatmap/lib/impl/DefaultKernelExpressionAlgorithm.java
1
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.legend.filteredheatmap.lib.impl;
7

  
8
import java.awt.Color;
9
import java.awt.Graphics2D;
10
import java.awt.image.BufferedImage;
11
import java.util.ArrayList;
12
import java.util.Arrays;
13
import org.gvsig.expressionevaluator.Expression;
14
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
15
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
16
import org.gvsig.expressionevaluator.MutableSymbolTable;
17
import org.gvsig.fmap.geom.Geometry;
18
import org.gvsig.fmap.geom.GeometryUtils;
19
import org.gvsig.fmap.geom.primitive.Point;
20
import org.gvsig.legend.filteredheatmap.lib.api.KernelExpressionAlgorithm;
21
import org.gvsig.tools.logger.FilteredLogger;
22
import org.gvsig.tools.swing.api.ToolsSwingLocator;
23
import org.gvsig.tools.swing.api.ToolsSwingManager;
24
import org.gvsig.tools.task.Cancellable;
25
import org.slf4j.Logger;
26
import org.slf4j.LoggerFactory;
27

  
28
/**
29
 *
30
 * @author osc
31
 */
32
public class DefaultKernelExpressionAlgorithm implements KernelExpressionAlgorithm {
33

  
34
    private double[][] grid;
35
    private double[][] kernel;
36
    private int distance;
37
    private int height;
38
    private int with;
39
    private double maxValue;
40
    private double minValue;
41
    private Expression kernelExpression;
42
    protected static final Logger LOG = LoggerFactory
43
            .getLogger(KernelExpressionAlgorithm.class);
44
    protected static final FilteredLogger LOGF = new FilteredLogger(LOG, "KernelExpressionAlgorithm", 30);
45
    private boolean forceUpdate;
46
    private KernelSymbolTable kSymbolTable;
47
    private MutableSymbolTable kernelsymbolTable;
48

  
49
    public DefaultKernelExpressionAlgorithm(int distance, Expression kernelExpression) {
50
        this.init(distance, distance);
51
        this.setKernelExpression(kernelExpression);
52
        this.setDistance(distance);
53
    }
54

  
55
    @Override
56
    public Expression getKernelExpression() {
57
        return this.kernelExpression;
58
    }
59

  
60
    @Override
61
    public void setDistance(int distance) {
62
        if (forceUpdate) {
63
            forceUpdate = false;
64
        } else {
65
            if (this.distance == distance) {
66
                return;
67
            }
68
        }
69
        if (this.distance == distance) {
70
            return;
71
        }
72
        this.distance = distance;
73

  
74
        this.kernel = new double[2 * this.distance + 1][2 * this.distance + 1];
75
        if (kernelExpression == null || kernelExpression.isEmpty()) {
76
            return;
77
        }
78

  
79
        Object value;
80

  
81
        for (int y = -this.distance; y < this.distance + 1; y++) {
82
            for (int x = -this.distance; x < this.distance + 1; x++) {
83
                final double dDist = Math.sqrt(x * x + y * y);
84
                if (dDist < this.distance) {
85
                    kSymbolTable.setXY(x, y);
86
                    kSymbolTable.setAlgorithm(this);
87
                    try {
88
                        value = this.kernelExpression.execute(kernelsymbolTable);
89
                    } catch (Exception e) {
90
                        LOGF.warn("Problems executing expression.");
91
                        continue;
92
                    }
93
                    String obj = value.toString();
94
                    this.kernel[x + this.distance][y + this.distance] = Double.parseDouble(obj);
95

  
96
                } else {
97
                    this.kernel[x + this.distance][y + this.distance] = 0;
98
                }
99
            }
100
        }
101
    }
102

  
103
    @Override
104
    public int getDistance() {
105
        return this.distance;
106
    }
107

  
108
    @Override
109
    public void init(int with, int height) {
110
        this.with = with;
111
        this.height = height;
112
        this.grid = new double[with][height];
113
        this.maxValue = 0;
114
        this.minValue = 0;
115
    }
116

  
117
    @Override
118
    public void add(int px, int py) {
119
        add(px, py, 1);
120
    }
121

  
122
    @Override
123
    public void add(int px, int py, double value) {
124
        for (int y = -this.distance; y < this.distance + 1; y++) {
125
            for (int x = -this.distance; x < this.distance + 1; x++) {
126
                if (this.kernel[x + this.distance][y + this.distance] != 0) {
127
                    addValue(px + x, py + y, value * this.kernel[x + this.distance][y + this.distance]);
128
                }
129
            }
130
        }
131
    }
132

  
133
    private void addValue(int px, int py, double value) {
134
        if (px < 0 || py < 0 || px >= with || py >= height) {
135
            return;
136
        }
137
        value += this.grid[px][py];
138
        this.grid[px][py] = value;
139
        if (value > this.maxValue) {
140
            this.maxValue = value;
141
        }
142
        if (value < this.minValue) {
143
            this.minValue = value;
144
        }
145
    }
146

  
147
    @Override
148
    public void drawWithOpaqueColors(BufferedImage img, Graphics2D g, Color[] colorTable, Cancellable cancel, Geometry roi, int limitProportion) {
149
        try {
150
            ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
151
            Color c;
152
            double valueForLimit;
153
            if (limitProportion == 100) {
154
                return;
155
            } else if (limitProportion > 0 && limitProportion < 100) {
156
                ArrayList<Double> singleArray = new ArrayList<>();
157
                for (double[] ds : this.grid) {
158
                    for (double d : ds) {
159
                        if (d != 0) {
160
                            singleArray.add(d);
161
                        }
162
                    }
163
                }
164
                int size = singleArray.size();
165
                Double[] sd = singleArray.toArray(new Double[singleArray.size()]);
166
                Arrays.sort(sd);
167
                int indexForLimitValue = ((size - 1) * limitProportion) / 100;
168
                valueForLimit = sd[indexForLimitValue];
169
            } else {
170
                valueForLimit = 0.0;
171
            }
172

  
173
            int maxIndexColor = colorTable.length - 1;
174
            //double minValueToDraw = ((maxValue - minValue) * limitProportion) / 100;
175

  
176
            for (int x = 0; x < with; x++) {
177
                for (int y = 0; y < height; y++) {
178
                    if (cancel.isCanceled()) {
179
                        return;
180
                    }
181
                    if (roi != null) {
182
                        Point point = GeometryUtils.createPoint(x, y);
183
                        if (!roi.intersects(point)) {
184
                            continue;
185
                        }
186
                    }
187
                    double value = this.grid[x][y];
188
                    if (value > 0) {
189
                        if (value < valueForLimit) {
190
                            continue;
191
                        }
192
                        int icolor = this.calculateIndexColor(value, valueForLimit, maxIndexColor);
193
//                        int icolor = (int) (value * maxIndexColor / maxValue);
194
                        c = toolsSwingManager.alphaBlendingWithOpaqueBackground(
195
                                new Color(img.getRGB(x, y)),
196
                                colorTable[icolor]
197
                        );
198
                        img.setRGB(x, y, c.getRGB());
199
                    }
200
                }
201
            }
202
        } catch (Exception ex) {
203
            LOGF.warn("Problems drawing heatmap", ex);
204
        }
205
    }
206

  
207
    // Adapt values to the proportion between minValueToDraw and maxValue of the grid
208
    public int calculateIndexColor(double value, double minValueToDraw, int maxIndexColor) {
209

  
210
        double d = maxValue - minValueToDraw;
211
        double dif = value - minValueToDraw;
212

  
213
        int x = (int) ((dif * maxIndexColor) / d);
214
        if (x > maxIndexColor) {
215
            LOGF.warn("Problems drawing heatmap. Index color is bigger than maxIndexColor");
216
            return maxIndexColor;
217
        } else if (x < 0) {
218
            LOGF.warn("Problems drawing heatmap. Index color is bellow 0");
219
            return 0;
220
        }
221
        return x;
222
    }
223

  
224
    @Override
225
    public void drawWithAlphaColors(BufferedImage img, Graphics2D g, Color[] colorTable, Cancellable cancel, Geometry roi, int limitProportion) {
226
        try {
227
            ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
228
            Color c;
229
            double valueForLimit;
230
            if (limitProportion == 100) {
231
                return;
232
            } else if (limitProportion > 0 && limitProportion < 100) {
233
                ArrayList<Double> singleArray = new ArrayList<>();
234
                for (double[] ds : this.grid) {
235
                    for (double d : ds) {
236
                        if (d != 0) {
237
                            singleArray.add(d);
238
                        }
239
                    }
240
                }
241
                int size = singleArray.size();
242
                Double[] sd = singleArray.toArray(new Double[singleArray.size()]);
243
                Arrays.sort(sd);
244
                int indexForLimitValue = ((size - 1) * limitProportion) / 100;
245
                valueForLimit = sd[indexForLimitValue];
246
            } else {
247
                valueForLimit = 0.0;
248
            }
249

  
250
            int maxIndexColor = colorTable.length - 1;
251
            //double minValueToDraw = ((maxValue - minValue) * limitProportion) / 100;
252

  
253
            for (int x = 0; x < with; x++) {
254
                for (int y = 0; y < height; y++) {
255
                    if (cancel.isCanceled()) {
256
                        return;
257
                    }
258
                    if (roi != null) {
259
                        Point point = GeometryUtils.createPoint(x, y);
260
                        if (!roi.intersects(point)) {
261
                            continue;
262
                        }
263
                    }
264
                    double value = this.grid[x][y];
265
                    if (value > 0) {
266
                        if (value < valueForLimit) {
267
                            continue;
268
                        }
269
                        int icolor = this.calculateIndexColor(value, valueForLimit, maxIndexColor);
270
                        c = colorTable[icolor];
271
                        img.setRGB(x, y, c.getRGB());
272
                    }
273
                }
274
            }
275
        } catch (Exception ex) {
276
            LOGF.warn("Problems drawing heatmap", ex);
277
        }
278
    }
279

  
280
    @Override
281
    public void setKernelExpression(Expression kernelExpression) {
282
        if (this.kernelExpression != kernelExpression) {
283
            this.kernelExpression = kernelExpression;
284
            this.forceUpdate = true;
285
            this.setDistance(this.distance);
286

  
287
            this.kSymbolTable = new KernelSymbolTable(this, 0, 0);
288
//            kernelExpression.link(kSymbolTable);
289

  
290
            ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
291

  
292
            kernelsymbolTable = manager.createSymbolTable();
293
            kernelsymbolTable.addSymbolTable(kSymbolTable);
294

  
295
        }
296
    }
297

  
298
}
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.impl/src/main/java/org/gvsig/legend/filteredheatmap/lib/impl/DefaultFilteredHeatmapLegendManager.java
1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2015 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.legend.filteredheatmap.lib.impl;
24

  
25
import org.gvsig.expressionevaluator.SymbolTable;
26
import org.gvsig.legend.filteredheatmap.lib.api.FilteredHeatmapLegend;
27
import org.gvsig.legend.filteredheatmap.lib.api.FilteredHeatmapLegendManager;
28
import org.gvsig.legend.filteredheatmap.lib.api.KernelExpressionAlgorithm;
29

  
30

  
31
public class DefaultFilteredHeatmapLegendManager implements FilteredHeatmapLegendManager {
32

  
33
    @Override
34
    public FilteredHeatmapLegend create() {
35
        return new DefaultFilteredHeatmapLegend();
36
    }
37

  
38
    @Override
39
    public Class<? extends FilteredHeatmapLegend> getLegendClass() {
40
        return DefaultFilteredHeatmapLegend.class;
41
    }
42
    
43
        
44
    @Override
45
    public SymbolTable createKernelSymbolTable(KernelExpressionAlgorithm alg, int x, int y) {
46
        return new KernelSymbolTable(alg, x, y);
47
    }
48
    
49
    @Override
50
    public KernelExpressionAlgorithm createKernelExpressionAlgorithm(int distance) {
51
        return new DefaultKernelExpressionAlgorithm(distance, null);
52
    }
53

  
54
}
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.impl/src/main/java/org/gvsig/legend/filteredheatmap/lib/impl/KernelSymbolTable.java
1
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.legend.filteredheatmap.lib.impl;
7

  
8
import org.apache.commons.lang3.Range;
9
import org.gvsig.expressionevaluator.Interpreter;
10
import org.gvsig.expressionevaluator.spi.AbstractFunction;
11
import org.gvsig.expressionevaluator.spi.AbstractSymbolTable;
12
import org.gvsig.fmap.dal.DataManager;
13
import org.gvsig.legend.filteredheatmap.lib.api.KernelExpressionAlgorithm;
14

  
15
/**
16
 *
17
 * @author osc
18
 */
19
public class KernelSymbolTable extends AbstractSymbolTable {
20

  
21
    private KernelExpressionAlgorithm algorithm;
22
    private int pixely;
23
    private int pixelx;
24
    private double pixeldistance;
25

  
26
    public KernelSymbolTable(KernelExpressionAlgorithm algorithm, int x, int y) {
27
        super(DataManager.DAL_SYMBOL_TABLE);
28
        this.algorithm = algorithm;
29
        this.pixelx = x;
30
        this.pixely = y;
31
        this.pixeldistance = 15;
32
        this.addFunction(new KernelDistanceFunc());
33
        this.addFunction(new PixelDistanceFunc());
34
        this.addFunction(new PixelXFunc());
35
        this.addFunction(new PixelYFunc());
36

  
37
    }
38
    @Override
39
    public KernelSymbolTable clone() throws CloneNotSupportedException {
40
        KernelSymbolTable other = (KernelSymbolTable) super.clone();
41
        return other;
42
    }
43
    
44
    public void setAlgorithm(KernelExpressionAlgorithm algorithm) {
45
        this.algorithm = algorithm;
46
    }
47

  
48
    public void setXY(int x, int y) {
49
        this.pixelx = x;
50
        this.pixely = y;
51
        this.pixeldistance = Math.sqrt(pixelx * pixelx + pixely * pixely);
52
    }
53

  
54
    public class KernelDistanceFunc extends AbstractFunction {
55

  
56
        public KernelDistanceFunc() {
57
            super(
58
                    "Kernel Algorithm",
59
                    "kerneldistance",
60
                    Range.is(0),
61
                    "Return the distance",
62
                    "kerneldistance()",
63
                    null,
64
                    "Integer"
65
            );
66
        }
67

  
68
        @Override
69
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
70
            return algorithm.getDistance();
71
        }
72

  
73
    }
74

  
75
    public class PixelDistanceFunc extends AbstractFunction {
76

  
77
        public PixelDistanceFunc() {
78
            super(
79
                    "Kernel Algorithm",
80
                    "pixeldistance",
81
                    Range.is(0),
82
                    "Return the distance to the pixel",
83
                    "pixeldistance()",
84
                    null,
85
                    "Double"
86
            );
87
        }
88

  
89
        @Override
90
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
91
            return pixeldistance;
92
        }
93

  
94
    }
95

  
96
    public class PixelXFunc extends AbstractFunction {
97

  
98
        public PixelXFunc() {
99
            super(
100
                    "Kernel Algorithm",
101
                    "pixelx",
102
                    Range.is(0),
103
                    "Return the pixel coordinate x",
104
                    "pixelx()",
105
                    null,
106
                    "Double"
107
            );
108
        }
109

  
110
        @Override
111
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
112
            return pixelx;
113
        }
114

  
115
    }
116

  
117
    public class PixelYFunc extends AbstractFunction {
118

  
119
        public PixelYFunc() {
120
            super(
121
                    "Kernel Algorithm",
122
                    "pixely",
123
                    Range.is(0),
124
                    "Return the pixel coordinate y",
125
                    "pixely()",
126
                    null,
127
                    "Double"
128
            );
129
        }
130

  
131
        @Override
132
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
133
            return pixely;
134
        }
135

  
136
    }
137
}
org.gvsig.legend.filteredheatmap/tags/org.gvsig.legend.filteredheatmap-1.0.50/org.gvsig.legend.filteredheatmap.lib/org.gvsig.legend.filteredheatmap.lib.impl/src/main/java/org/gvsig/legend/filteredheatmap/lib/impl/DefaultFilteredHeatmapLegend.java
1
package org.gvsig.legend.filteredheatmap.lib.impl;
2

  
3
import java.awt.Color;
4
import java.awt.Graphics2D;
5
import java.awt.Image;
6
import java.awt.image.BufferedImage;
7
import java.util.ArrayList;
8
import java.util.Map;
9

  
10
import org.apache.commons.lang3.StringUtils;
11
import org.cresques.cts.ICoordTrans;
12
import org.gvsig.compat.print.PrintAttributes;
13
import org.gvsig.expressionevaluator.Expression;
14
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
15
import org.gvsig.expressionevaluator.MutableSymbolTable;
16
import org.gvsig.fmap.dal.DALLocator;
17

  
18
import org.gvsig.fmap.dal.exception.DataException;
19
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
20
import org.gvsig.fmap.dal.feature.Feature;
21
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
22
import org.gvsig.fmap.dal.feature.FeatureQuery;
23
import org.gvsig.fmap.dal.feature.FeatureSelection;
24
import org.gvsig.fmap.dal.feature.FeatureSet;
25
import org.gvsig.fmap.dal.feature.FeatureStore;
26
import org.gvsig.fmap.dal.feature.FeatureType;
27
import org.gvsig.fmap.geom.Geometry;
28
import org.gvsig.fmap.geom.primitive.Point;
29
import org.gvsig.fmap.mapcontext.MapContextException;
30
import org.gvsig.fmap.mapcontext.ViewPort;
31
import org.gvsig.fmap.mapcontext.layers.operations.IHasImageLegend;
32
import org.gvsig.fmap.mapcontext.rendering.legend.LegendException;
33
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
34
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
35
import org.gvsig.gui.ColorTablePainter;
36
import org.gvsig.gui.DefaultColorTablePainter;
37
import org.gvsig.legend.filteredheatmap.lib.api.FilteredHeatmapLegend;
38
import org.gvsig.legend.filteredheatmap.lib.api.KernelExpressionAlgorithm;
39
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl.AbstractVectorialLegend;
40
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl.DefaultFeatureDrawnNotification;
41
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.impl.SimpleTextSymbol;
42
import org.gvsig.tools.exception.BaseException;
43
import org.gvsig.tools.persistence.PersistentState;
44
import org.gvsig.tools.persistence.exception.PersistenceException;
45
import org.gvsig.tools.task.Cancellable;
46
import org.gvsig.tools.visitor.VisitCanceledException;
47
import org.gvsig.tools.visitor.Visitor;
48

  
49
public class DefaultFilteredHeatmapLegend extends AbstractVectorialLegend implements FilteredHeatmapLegend, IHasImageLegend {
50

  
51
    private ISymbol defaultSymbol;
52
    private KernelExpressionAlgorithm algorithm;
53
    private boolean isRamp;
54
    private Color[] sourceColorTable;
55
    private int colorTableHotColorAlpha;
56
    private int colorTableColdColorAlpha;
57
    private boolean useAlphaInColorTable;
58
    private String fieldName;
59
    private Image imageLegend;
60
    private HeatmapColorTable hmColorTable;
61
    private Color rampColdColor;
62
    private Color rampHotColor;
63
    private int rampNumColors;
64
    private Geometry roi;
65
    private int proportionValue;
66
    private Expression filterExpression;
67
    private boolean useFilterExpression;
68

  
69
    public DefaultFilteredHeatmapLegend() {
70

  
71
        this.defaultSymbol = new SimpleTextSymbol();
72
        Expression kernelPowExp = ExpressionEvaluatorLocator.getExpressionEvaluatorManager().createExpression();
73
        kernelPowExp.setPhrase("power(1-(power(pixeldistance(), 2)/power(kerneldistance(), 2)),2)");
74
        this.algorithm = new DefaultKernelExpressionAlgorithm(30, kernelPowExp);
75
        this.colorTableHotColorAlpha = 255;
76
        this.colorTableColdColorAlpha = 0;
77
        this.useAlphaInColorTable = false;
78
        this.setColorTable(100, new Color(0, 0, 255, 0), new Color(255, 0, 0, 255));
79
        this.imageLegend = null;
80
        this.hmColorTable = null;
81
        this.fieldName = null;
82
        
83
        
84
    }
85

  
86
    @Override
87
    public Expression getKernelExpression() {
88
        return this.algorithm.getKernelExpression();
89
    }
90

  
91
    @Override
92
    public void setKernelExpression(Expression kernelExpression) {
93
        this.algorithm.setKernelExpression(kernelExpression);
94
    }
95

  
96
    @Override
97
    public int getFilterProportionValue() {
98
        return this.proportionValue;
99
    }
100

  
101
    @Override
102
    public void setFilterProportionValue(int proportionValue) {
103
        this.proportionValue = proportionValue;
104
    }
105

  
106
    @Override
107
    public Expression getFilterByExpression() {
108
        return this.filterExpression;
109
    }
110

  
111
    @Override
112
    public void setFilterByExpression(Expression filterExpression) {
113
        this.filterExpression = filterExpression;
114
    }
115

  
116
    @Override
117
    public boolean getUseFilterByExpression() {
118
        return this.useFilterExpression;
119
    }
120

  
121
    @Override
122
    public void setUseFilterByExpression(boolean useFilterExpression) {
123
        this.useFilterExpression = useFilterExpression;
124
    }
125

  
126
    @Override
127
    protected String[] getRequiredFeatureAttributeNames(FeatureStore featureStore) throws DataException {
128
        FeatureType ftype = featureStore.getDefaultFeatureType();
129
//        String[] allAttributes = new String[ftype.getAttributeDescriptors().length];
130
        ArrayList<String> arrayAttributes = new ArrayList<>();
131
        for (FeatureAttributeDescriptor attributeDescriptor : ftype.getAttributeDescriptors()) {
132
            arrayAttributes.add(attributeDescriptor.getName());
133
        }
134
        String[] a = arrayAttributes.toArray(new String[arrayAttributes.size()]);
135
        return a;
136
    }
137

  
138
    @Override
139
    public ISymbol getDefaultSymbol() {
140
        return this.defaultSymbol;
141
    }
142

  
143
    @Override
144
    public void setDefaultSymbol(ISymbol is) {
145
    }
146

  
147
    @Override
148
    public ISymbol getSymbolByFeature(Feature ftr) throws MapContextException {
149
        return this.defaultSymbol;
150
    }
151

  
152
    @Override
153
    public int getShapeType() {
154
        return Geometry.TYPES.GEOMETRY;
155
    }
156

  
157
    @Override
158
    public void setShapeType(int i) {
159
    }
160

  
161
    @Override
162
    public boolean isUseDefaultSymbol() {
163
        return true;
164
    }
165

  
166
    @Override
167
    public void useDefaultSymbol(boolean bln) {
168
    }
169

  
170
    @Override
171
    public boolean isSuitableForShapeType(int shapeType) {
172
        return true;
173
    }
174

  
175
    @Override
176
    protected void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, Map queryParameters, ICoordTrans coordTrans, FeatureStore featureStore, FeatureQuery featureQuery, double dpi) throws LegendException {
177
        int saved_distance = this.algorithm.getDistance();
178
        try {
179
            int distance = (int) (this.algorithm.getDistance() * (dpi / 72));
180
            Geometry theROI = null;
181
            if (this.roi != null) {
182
                theROI = this.roi.cloneGeometry();
183
                theROI.transform(viewPort.getAffineTransform());
184
            }
185
            this.algorithm.init(image.getWidth(), image.getHeight());
186
            this.algorithm.setDistance(distance);
187
            super.draw(image, g, viewPort, cancel, scale, queryParameters, coordTrans, featureStore, featureQuery, dpi);
188
            if (!cancel.isCanceled()) {
189
                this.algorithm.drawWithOpaqueColors(image, g, this.getHeatMapColorTable().getColorTable(), cancel, theROI, this.getFilterProportionValue());
190
            }
191
        } finally {
192
            this.algorithm.setDistance(saved_distance);
193

  
194
        }
195
    }
196

  
197
    @Override
198
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
199
            double scale, Map queryParameters, ICoordTrans coordTrans,
200
            FeatureStore featureStore, FeatureQuery featureQuery, PrintAttributes properties)
201
            throws LegendException {
202
        int saved_distance = this.algorithm.getDistance();
203
        try {
204
            double dpi = viewPort.getDPI();
205
            // Ver CartographicSupportToolkit.getCartographicLength
206
            int distance = (int) (this.algorithm.getDistance() * (dpi / 72));
207
            Geometry theROI = null;
208
            if (this.roi != null) {
209
                theROI = this.roi.cloneGeometry();
210
                theROI.transform(viewPort.getAffineTransform());
211
            }
212
            this.algorithm.init(viewPort.getImageWidth(), viewPort.getImageHeight());
213
            this.algorithm.setDistance(distance);
214
            BufferedImage image = new BufferedImage(viewPort.getImageWidth(), viewPort.getImageHeight(), BufferedImage.TYPE_INT_ARGB);
215
            super.draw(image, g, viewPort, cancel, scale, queryParameters, coordTrans, featureStore, featureQuery, dpi);
216
            if (!cancel.isCanceled()) {
217
                this.algorithm.drawWithAlphaColors(image, g, this.getHeatMapColorTable().getColorTable(), cancel, theROI, this.getFilterProportionValue());
218
                g.drawImage(image, 0, 0, null);
219
            }
220
        } finally {
221
            this.algorithm.setDistance(saved_distance);
222

  
223
        }
224
    }
225

  
226
    @Override
227
    protected void drawFeatures(
228
            BufferedImage image,
229
            Graphics2D g,
230
            final ViewPort viewPort,
231
            final Cancellable cancel,
232
            final ICoordTrans coordTrans,
233
            double dpi,
234
            DefaultFeatureDrawnNotification drawnNotification,
235
            FeatureSet featureSet,
236
            FeatureSelection selection
237
    ) throws BaseException {
238
        int x = -1;
239
        if (!StringUtils.isEmpty(this.fieldName)) {
240
            x = featureSet.getDefaultFeatureType().getIndex(this.fieldName);
241
        }
242
        final int n = x;
243

  
244
        MutableSymbolTable symbolTable = ExpressionEvaluatorLocator.getManager().createSymbolTable();
245
        FeatureSymbolTable fst = DALLocator.getDataManager().createFeatureSymbolTable();
246
        symbolTable.addSymbolTable(fst);
247

  
248
        featureSet.accept(new Visitor() {
249
            @Override
250
            public void visit(Object o) throws VisitCanceledException, BaseException {
251
                if (cancel.isCanceled()) {
252
                    throw new VisitCanceledException();
253
                }
254
                Feature feature = (Feature) o;
255
                Geometry geom = feature.getDefaultGeometry();
256
                if (geom != null) {
257
                    Point pointGeo = geom.centroid();
258
                    if (coordTrans != null) {
259
                        pointGeo.reProject(coordTrans);
260
                    }
261
                    Point pointPixels = (Point) pointGeo.cloneGeometry();
262
                    pointPixels.transform(viewPort.getAffineTransform());
263
                    if (getUseFilterByExpression()) {
264
                        fst.setFeature(feature);
265
                        boolean validFeature = checkToFilterFeature(fst, symbolTable);
266
                        if (!validFeature) {
267
                            return;
268
                        }
269
                    }
270
                    if (n >= 0) {
271
                        double value = 0;
272
                        try {
273

  
274
                            value = feature.getDouble(n);
275
                        } catch (Exception ex) {
276
                        }
277
                        if (value > 0) {
278
                            algorithm.add((int) pointPixels.getX(), (int) pointPixels.getY(), value);
279
                        }
280
                    } else {
281
                        algorithm.add((int) pointPixels.getX(), (int) pointPixels.getY());
282
                    }
283
                }
284
            }
285
        });
286
    }
287

  
288
    protected boolean checkToFilterFeature(FeatureSymbolTable fst, MutableSymbolTable symbolTable) {
289
        if (filterExpression!=null && !filterExpression.isEmpty()) {
290
            Object value = filterExpression.execute(symbolTable);
291
            if (value instanceof Boolean) {
292
                return ((Boolean) value);
293
            } else {
294
                return false;
295
            }
296
        } else {
297
            return false;
298
        }
299
        
300
    }
301

  
302
    /**
303
     * @return the distance
304
     */
305
    @Override
306
    public int getDistance() {
307
        return this.algorithm.getDistance();
308
    }
309

  
310
    /**
311
     * @param distance the distance to set
312
     */
313
    @Override
314
    public void setDistance(int distance) {
315
        this.algorithm.setDistance(distance);
316
    }
317

  
318
    @Override
319
    public void setColorTable(Color[] colorTable) {
320
        this.isRamp = false;
321
        this.sourceColorTable = colorTable;
322
        this.imageLegend = null;
323
        this.hmColorTable = null;
324
        this.fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null, null));
325
    }
326

  
327
    @Override
328
    public void setColorTable(int numColors, Color coldColor, Color hotColor) {
329
        this.isRamp = true;
330
        this.rampColdColor = coldColor;
331
        this.rampHotColor = hotColor;
332
        this.rampNumColors = numColors;
333
        this.imageLegend = null;
334
        this.hmColorTable = null;
335
        this.fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null, null));
336
    }
337

  
338
    @Override
339
    public Color[] getSourceColorTable() {
340
        return this.sourceColorTable;
341
    }
342

  
343
    @Override
344
    public Color[] getTargetColorTable() {
345
        return this.getHeatMapColorTable().getColorTable();
346
    }
347

  
348
    private HeatmapColorTable getHeatMapColorTable() {
349
        if (this.hmColorTable == null) {
350
            if (this.useRamp()) {
351
                this.hmColorTable = new HeatmapColorTable(this.rampColdColor, this.rampHotColor, this.rampNumColors);
352
            } else {
353
                if (useAlphaInColorTable) {
354
                    this.hmColorTable = new HeatmapColorTable(this.getSourceColorTable(), colorTableColdColorAlpha, colorTableHotColorAlpha);
355
                } else {
356
                    this.hmColorTable
357
                            = this.hmColorTable = new HeatmapColorTable(this.getSourceColorTable());
358
                }
359
            }
360
        }
361
        return this.hmColorTable;
362
    }
363

  
364
    @Override
365
    public boolean useRamp() {
366
        return this.isRamp;
367
    }
368

  
369
    @Override
370
    public String getFieldName() {
371
        return this.fieldName;
372
    }
373

  
374
    @Override
375
    public void setFieldName(String fieldName) {
376
        this.fieldName = fieldName;
377
    }
378

  
379
    @Override
380
    public int getColorTableHotColorAlpha() {
381
        return colorTableHotColorAlpha;
382
    }
383

  
384
    @Override
385
    public void setColorTableHotColorAlpha(int colorTableHotColorAlpha) {
386
        this.colorTableHotColorAlpha = colorTableHotColorAlpha;
387
        this.imageLegend = null;
388
        this.hmColorTable = null;
389
    }
390

  
391
    @Override
392
    public int getColorTableColdColorAlpha() {
393
        return colorTableColdColorAlpha;
394
    }
395

  
396
    @Override
397
    public void setColorTableColdColorAlpha(int colorTableColdColorAlpha) {
398
        this.colorTableColdColorAlpha = colorTableColdColorAlpha;
399
        this.imageLegend = null;
400
        this.hmColorTable = null;
401
    }
402

  
403
    @Override
404
    public boolean useAlphaInColorTable() {
405
        return this.useAlphaInColorTable;
406
    }
407

  
408
    @Override
409
    public boolean setUseAlphaInColorTable(boolean use) {
410
        boolean x = this.useAlphaInColorTable;
411
        this.useAlphaInColorTable = use;
412
        this.hmColorTable = null;
413

  
414
        return x;
415
    }
416

  
417
    @Override
418
    public void setROI(Geometry roi) {
419
        this.roi = roi;
420
    }
421

  
422
    @Override
423
    public Geometry getROI() {
424
        return this.roi;
425
    }
426

  
427
    @Override
428
    public Image getImageLegend() {
429
        if (this.imageLegend == null) {
430
            BufferedImage img = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
431
            ColorTablePainter painter = new DefaultColorTablePainter(this.getTargetColorTable(), "");
432
            Graphics2D g = img.createGraphics();
433
            g.setClip(0, 0, 80, 20);
434
            g.setBackground(Color.WHITE);
435
            g.fillRect(0, 0, 80, 20);
436
            painter.paint(g, false);
437
            this.imageLegend = img;
438
        }
439
        return this.imageLegend;
440
    }
441

  
442
    @Override
443
    public String getPathImage() {
444
        return null;
445
    }
446

  
447
    @Override
448
    public void loadFromState(PersistentState state) throws PersistenceException {
449
        this.defaultSymbol = new SimpleTextSymbol();
450
        this.imageLegend = null;
451
        this.hmColorTable = null;
452

  
453
        super.loadFromState(state);
454
        this.isRamp = state.getBoolean("isRamp");
455
        this.sourceColorTable = (Color[]) state.getArray("sourceColorTable", Color.class);
456
        this.colorTableHotColorAlpha = state.getInt("colorTableHotColorAlpha");
457
        this.colorTableColdColorAlpha = state.getInt("colorTableColdColorAlpha");
458
        this.useAlphaInColorTable = state.getBoolean("useAlphaInColorTable");
459
        this.fieldName = state.getString("fieldName");
460
        this.rampNumColors = state.getInt("rampNumColors");
461
        this.rampColdColor = (Color) state.get("rampColdColor");
462
        this.rampHotColor = (Color) state.get("rampHotColor");
463
        
464
        this.proportionValue = state.getInt("proportionValue");
465
        this.useFilterExpression = state.getBoolean("useFilterExpression");
466
        this.filterExpression = (Expression) state.get("filterExpression");
467
        int distance = state.getInt("distance");
468
        Expression expression = (Expression) state.get("kernelExpression");
469
        this.algorithm = new DefaultKernelExpressionAlgorithm( distance, expression);
470
        
471
    }
472

  
473
    @Override
474
    public int getRampNumColors() {
475
        return this.rampNumColors;
476
    }
477

  
478
    @Override
479
    public Color getRampColdColor() {
480
        return this.rampColdColor;
481
    }
482

  
483
    @Override
484
    public Color getRampHotColor() {
485
        return this.rampHotColor;
486
    }
487

  
488
    @Override
489
    public void saveToState(PersistentState state) throws PersistenceException {
490
        super.saveToState(state);
491
        state.set("isRamp", isRamp); 
492
        state.set("sourceColorTable", sourceColorTable);
493
        state.set("colorTableHotColorAlpha", colorTableHotColorAlpha);
494
        state.set("colorTableColdColorAlpha", colorTableColdColorAlpha);
495
        state.set("useAlphaInColorTable", useAlphaInColorTable);
496
        state.set("fieldName", fieldName);
497
        state.set("distance", algorithm.getDistance());
498

  
499
        state.set("rampNumColors", rampNumColors);
500
        state.set("rampColdColor", rampColdColor);
501
        state.set("rampHotColor", rampHotColor);
502
        
503
        state.set("proportionValue", this.proportionValue);
504
        state.set("useFilterExpression", this.useFilterExpression);
505
        state.set("filterExpression", this.filterExpression);
506
        state.set("distance", this.algorithm.getDistance());
507
        state.set("kernelExpression", this.algorithm.getKernelExpression());
508
    }
509

  
510
    private static class HeatmapColorTable {
511

  
512
        private Color[] sourceColorTable = null;
513
        private int coldAlpha = -1;
514
        private int hotAlpha = -1;
515
        private Color coldColor = null;
516
        private Color hotColor = null;
517
        private Color[] targetColorTable = null;
518
        private int length = -1;
519

  
520
        public HeatmapColorTable(Color[] sourceColorTable) {
521
            this.sourceColorTable = sourceColorTable;
522
        }
523

  
524
        public HeatmapColorTable(Color[] sourceColorTable, int coldAlpha, int hotAlpha) {
525
            this.sourceColorTable = sourceColorTable;
526
            this.coldAlpha = coldAlpha;
527
            this.hotAlpha = hotAlpha;
528
        }
529

  
530
        public HeatmapColorTable(Color coldColor, Color hotColor, int length) {
531
            this.coldColor = coldColor;
532
            this.hotColor = hotColor;
533
            this.length = length;
534
        }
535

  
536
        public Color[] getColorTable() {
537
            if (targetColorTable == null) {
538
                if (sourceColorTable != null) { //Tenemos tabla de color
539
                    if (coldAlpha >= 0 || hotAlpha >= 0) { //Se usa alpha para la tabla de color
540
                        double alphaDelta = getDelta(coldAlpha, hotAlpha, sourceColorTable.length);
541
                        targetColorTable = new Color[sourceColorTable.length];
542
                        for (int i = 0; i < sourceColorTable.length; i++) {
543
                            Color sourceColor = sourceColorTable[i];
544
                            if (coldAlpha >= 0 && hotAlpha >= 0) {
545
                                targetColorTable[i]
546
                                        = new Color(sourceColor.getRed(), sourceColor.getGreen(), sourceColor.getBlue(),
547
                                                coldAlpha + (int) (i * alphaDelta));
548
                            } else {
549
                                targetColorTable[i] = sourceColor;
550
                            }
551
                        }
552
                    } else { //No se usa alpha para la tabla de color
553
                        targetColorTable = sourceColorTable;
554
                    }
555
                } else { // Tenemos gradiente
556
                    targetColorTable = new Color[length];
557

  
558
                    double deltaRed = (hotColor.getRed() - coldColor.getRed()) / length;
559
                    double deltaGreen = (hotColor.getGreen() - coldColor.getGreen()) / length;
560
                    double deltaBlue = (hotColor.getBlue() - coldColor.getBlue()) / length;
561
                    double deltaAlpha = (hotColor.getAlpha() - coldColor.getAlpha()) / length;
562
                    for (int i = 0; i < length; i++) {
563
                        targetColorTable[i]
564
                                = new Color(
565
                                        (int) (coldColor.getRed() + i * deltaRed),
566
                                        (int) (coldColor.getGreen() + i * deltaGreen),
567
                                        (int) (coldColor.getBlue() + i * deltaBlue),
568
                                        (int) (coldColor.getAlpha() + i * deltaAlpha));
569
                    }
570
                }
571
            }
572
            return targetColorTable;
573
        }
574

  
575
        private double getDelta(int x1, int x2, int lenght) {
576
            return (x2 - x1) / ((double) lenght - 1);
577
        }
578
    }
579

  
580
}
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff