Revision 5087

View differences:

org.gvsig.legend.urbanhorizontalsignage/trunk/org.gvsig.legend.urbanhorizontalsignage.lib/org.gvsig.legend.urbanhorizontalsignage.lib.impl/src/test/java/org/gvsig/legend/urbanhorizontalsignage/lib/impl/Test01CalculateGeometries.java
1
package org.gvsig.legend.urbanhorizontalsignage.lib.impl;
2

  
3
import java.util.List;
4
import junit.framework.TestCase;
5
import org.gvsig.fmap.geom.GeometryUtils;
6
import org.gvsig.fmap.geom.primitive.Line;
7
import org.gvsig.fmap.geom.primitive.Point;
8
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData;
9
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLocator;
10
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
11
import org.slf4j.Logger;
12
import org.slf4j.LoggerFactory;
13

  
14
public class Test01CalculateGeometries extends TestCase {
15

  
16
    private static final Logger LOGGER = LoggerFactory.getLogger(Test01CalculateGeometries.class);
17

  
18
    public Test01CalculateGeometries(String testName) {
19
        super(testName);
20
    }
21

  
22
    @Override
23
    protected void setUp() throws Exception {
24
        super.setUp();
25
        new DefaultLibrariesInitializer().fullInitialize();
26
    }
27

  
28
    @Override
29
    protected void tearDown() throws Exception {
30
        super.tearDown();
31
    }
32

  
33
    // TODO add test methods here. The name must begin with 'test'. For example:
34
    // public void testHello() {}
35
    public void test01CalculateIntermediatePoint() {
36
        final String testid = "calculateIntermediatePoint";
37
        Point p1 = GeometryUtils.createPoint(0,0);
38
        Point p2 = GeometryUtils.createPoint(10,0);
39
              
40
        DefaultUrbanHorizontalSignageManager uhsManager = (DefaultUrbanHorizontalSignageManager)UrbanHorizontalSignageLocator.getUrbanHorizontalSignageManager();
41
        try {
42
            for (double lambda = 0; lambda <= 1; lambda += 0.1) {
43
                Point intermediatePoint = uhsManager.calculateIntermediatePoint(p1, p2, lambda);
44
                assertEquals(10*lambda, intermediatePoint.getCoordinateAt(0));
45
                assertEquals(0.0, intermediatePoint.getCoordinateAt(1));
46
            }
47
        } catch (Exception ex) {
48
            //TODO:
49
            fail(ex.getMessage());
50
        }
51
        
52
        
53
    }
54
    
55
    public void test02SplitLine() throws Exception {
56
        final String testid = "splitLine";
57
        
58
        Point p1 = GeometryUtils.createPoint(0,0);
59
        Point p2 = GeometryUtils.createPoint(10,0);
60
        Line line = GeometryUtils.createLine(p1, p2, 0);
61
        
62
        DefaultUrbanHorizontalSignageManager uhsManager = (DefaultUrbanHorizontalSignageManager)UrbanHorizontalSignageLocator.getUrbanHorizontalSignageManager();
63
//        UrbanHorizontalSignageData data = uhsManager.createUrbanHorizontalSignageData();
64

  
65
//        data.setWidth(20);
66
//        data.setContinuity(UrbanHorizontalSignageData.DEFAULT_CONTINUITY_VALUE);
67
//        data.setSegmentsLength(100);
68
//        data.setHolesLength(50);
69
//        data.setGapWith(10);
70
//        data.setSegmentsColor(Color.RED);
71
//        data.setHolesColor(Color.BLACK);
72
//        data.setRoundVertex(false);
73
//        data.setPaintHoles(true);
74
        
75
        DefaultUrbanHorizontalSignageManager.SplittedLine splittedLine = uhsManager.splitLine(line, 1, 0.5);
76
        
77
        List<Line> segments = splittedLine.getSegments();
78
        List<Line> holes = splittedLine.getHoles();
79
        
80
        assertEquals(7, segments.size());
81
        assertEquals(6, holes.size());
82
        
83
        double x = 0;
84
        for (Line segment : segments) {
85
            assertEquals(x, segment.getVertex(0).getX());
86
            assertEquals(x+1.0, segment.getVertex(1).getX());
87
            x += 1.50;
88
        }
89
        x = 1.0;
90
        for (Line hole : holes) {
91
            assertEquals(x, hole.getVertex(0).getX());
92
            assertEquals(x+0.5, hole.getVertex(1).getX());
93
            x += 1.50;
94
        }
95
    }
96
    
97
    
98
}
org.gvsig.legend.urbanhorizontalsignage/trunk/org.gvsig.legend.urbanhorizontalsignage.lib/org.gvsig.legend.urbanhorizontalsignage.lib.impl/src/main/java/org/gvsig/legend/urbanhorizontalsignage/lib/impl/DefaultUrbanHorizontalSignageData.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.urbanhorizontalsignage.lib.impl;
7

  
8
import java.awt.Color;
9
import org.gvsig.fmap.geom.Geometry;
10
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
11
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData;
12

  
13
/**
14
 *
15
 * @author fdiaz
16
 */
17
public class DefaultUrbanHorizontalSignageData implements UrbanHorizontalSignageData {
18
    
19
    private double width;
20
    private int continuity;
21
    private Color segmentsColor;
22
    private double segmentsLength;
23
    private MultiPolygon segmentsGeometry;
24
    private boolean isPaintHoles;
25
    private Color holesColor;
26
    private double holesLength;
27
    private MultiPolygon holesGeometry;
28
    private double gapWidth;
29
    private Geometry originalGeometry;
30
    private boolean roundVertex;
31

  
32
    public DefaultUrbanHorizontalSignageData() {
33
        width = DEFAULT_WIDTH_VALUE;
34
        continuity = DEFAULT_CONTINUITY_VALUE;
35
        segmentsColor = DEFAULT_SEGMENT_COLOR_VALUE;
36
        segmentsLength = DEFAULT_SEGMENT_LENGTH_VALUE;
37
        isPaintHoles = DEFAULT_PAINT_HOLES_VALUE;
38
        holesColor = DEFAULT_HOLES_COLOR_VALUE;
39
        holesLength = DEFAULT_HOLES_LENGTH_VALUE;
40
        gapWidth = DEFAULT_GAP_WIDTH_VALUE;
41
        roundVertex = DEFAULT_ROUND_VERTEX_VALUE;
42
    }
43

  
44
    @Override
45
    public double getWidth() {
46
        return this.width;
47
    }
48

  
49
    @Override
50
    public void setWidth(double value) {
51
        this.width = value;
52
    }
53

  
54
    @Override
55
    public int getContinuity() {
56
        return this.continuity;
57
    }
58

  
59
    @Override
60
    public void setContinuity(int value) {
61
        this.continuity = value;
62
    }
63

  
64
    @Override
65
    public Color getSegmentsColor() {
66
        return this.segmentsColor;
67
    }
68

  
69
    @Override
70
    public void setSegmentsColor(Color value) {
71
        this.segmentsColor = value;
72
    }
73

  
74
    @Override
75
    public double getSegmentsLength() {
76
        return this.segmentsLength;
77
    }
78

  
79
    @Override
80
    public void setSegmentsLength(double value) {
81
        this.segmentsLength = value;
82
    }
83

  
84
    @Override
85
    public MultiPolygon getSegmentsGeometry() {
86
        return this.segmentsGeometry;
87
    }
88

  
89
    @Override
90
    public void setSegmentsGeometry(MultiPolygon value) {
91
        this.segmentsGeometry = value;
92
    }
93

  
94
    @Override
95
    public boolean isPaintHoles() {
96
        return this.isPaintHoles;
97
    }
98

  
99
    @Override
100
    public void setPaintHoles(boolean value) {
101
        this.isPaintHoles = value;
102
    }
103

  
104
    @Override
105
    public Color getHolesColor() {
106
        return this.holesColor;
107
    }
108

  
109
    @Override
110
    public void setHolesColor(Color value) {
111
        this.holesColor = value;
112
    }
113

  
114
    @Override
115
    public double getHolesLength() {
116
        return this.holesLength;
117
    }
118

  
119
    @Override
120
    public void setHolesLength(double value) {
121
        this.holesLength = value;
122
    }
123

  
124
    @Override
125
    public MultiPolygon getHolesGeometry() {
126
        return this.holesGeometry;
127
    }
128

  
129
    @Override
130
    public void setHolesGeometry(MultiPolygon value) {
131
        this.holesGeometry = value;
132
    }
133

  
134
    @Override
135
    public double getGapWidth() {
136
        return this.gapWidth;
137
    }
138

  
139
    @Override
140
    public void setGapWidth(double value) {
141
        this.gapWidth = value;
142
    }
143
    
144
    public boolean isRoundVertex(){
145
        return this.roundVertex;
146
    }
147

  
148
    public void setRoundVertex(boolean value){
149
        this.roundVertex = value;
150
    }
151

  
152

  
153
}
org.gvsig.legend.urbanhorizontalsignage/trunk/org.gvsig.legend.urbanhorizontalsignage.lib/org.gvsig.legend.urbanhorizontalsignage.lib.impl/src/main/java/org/gvsig/legend/urbanhorizontalsignage/lib/impl/DefaultUrbanHorizontalSignageManager.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.urbanhorizontalsignage.lib.impl;
24

  
25
import java.util.ArrayList;
26
import java.util.Iterator;
27
import java.util.List;
28
import org.apache.commons.lang3.tuple.MutablePair;
29
import org.gvsig.fmap.geom.Geometry;
30
import static org.gvsig.fmap.geom.Geometry.JOIN_STYLE_BEVEL;
31
import static org.gvsig.fmap.geom.Geometry.JOIN_STYLE_MITRE;
32
import static org.gvsig.fmap.geom.Geometry.JOIN_STYLE_ROUND;
33
import org.gvsig.fmap.geom.GeometryLocator;
34
import org.gvsig.fmap.geom.GeometryManager;
35
import org.gvsig.fmap.geom.aggregate.MultiLine;
36
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
37
import org.gvsig.fmap.geom.exception.CreateGeometryException;
38
import org.gvsig.fmap.geom.operation.GeometryOperationException;
39
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
40
import org.gvsig.fmap.geom.primitive.Line;
41
import org.gvsig.fmap.geom.primitive.Point;
42
import org.gvsig.fmap.geom.primitive.Primitive;
43
import org.gvsig.fmap.geom.type.GeometryType;
44
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData;
45
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_CONT;
46
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_CONT_CONT;
47
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_CONT_DISC;
48
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC;
49
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_CONT;
50
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_DISC;
51
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLegend;
52
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageManager;
53
import org.slf4j.LoggerFactory;
54

  
55
public class DefaultUrbanHorizontalSignageManager implements UrbanHorizontalSignageManager {
56

  
57
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DefaultUrbanHorizontalSignageManager.class);
58

  
59
    @Override
60
    public UrbanHorizontalSignageLegend create() {
61
        return new DefaultUrbanHorizontalSignageLegend();
62
    }
63

  
64
    @Override
65
    public Class<? extends UrbanHorizontalSignageLegend> getLegendClass() {
66
        return DefaultUrbanHorizontalSignageLegend.class;
67
    }
68

  
69
    @Override
70
    public UrbanHorizontalSignageData createUrbanHorizontalSignageData() {
71
        return new DefaultUrbanHorizontalSignageData();
72
    }
73

  
74
    @Override
75
    public void calculateGeometries(Geometry originalGeometry, UrbanHorizontalSignageData data) {
76
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
77
        try {
78
            MultiPolygon segments = geomManager.createMultiPolygon(originalGeometry.getGeometryType().getSubType());
79
            MultiPolygon holes = geomManager.createMultiPolygon(originalGeometry.getGeometryType().getSubType());
80
            MultiLine lines = originalGeometry.toLines();
81
            final double offsetValueInMeters = data.getGapWidth()/2.0+data.getWidth()/2.0;
82
            final double bufferValueInMeters = data.getWidth() / 2.0;
83
            for (Geometry geom : lines) {
84
                Line line = (Line) geom;
85
                switch (data.getContinuity()) {
86
                    case CONTINUITY_MODE_CONT:
87
                    default:
88
                        Geometry buffer = line.buffer(
89
                                bufferValueInMeters,
90
                                data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
91
                                true
92
                        );
93
                        segments.addPrimitives(buffer);
94
                        break;
95
                    
96
                    case CONTINUITY_MODE_DISC:
97
                        SplittedLine splittedLine = splitLine(line, data.getSegmentsLength(), data.getHolesLength());
98
                        List<Line> splittedSegments = splittedLine.getSegments();
99
                        List<Line> splittedHoles = splittedLine.getHoles();
100
                        for (Line segment : splittedSegments) {
101
                            buffer = segment.buffer(bufferValueInMeters,
102
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
103
                                    true
104
                            );
105
                            segments.addPrimitives(buffer);
106
                        }
107
                        for (Line hole : splittedHoles) {
108
                            buffer = hole.buffer(
109
                                    bufferValueInMeters,
110
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
111
                                    true
112
                            );
113
                            holes.addPrimitives(buffer);
114
                        }
115
                        break;
116
                        
117
                    case CONTINUITY_MODE_CONT_CONT:
118
                        //Left
119
                        Geometry leftGeom = line.cloneGeometry().offset(-offsetValueInMeters).buffer(
120
                                bufferValueInMeters,
121
                                data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
122
                                true
123
                        );
124
                        segments.addPrimitives(leftGeom);
125
                        //Right
126
                        Geometry rightGeom = line.cloneGeometry().offset(offsetValueInMeters).buffer(
127
                                bufferValueInMeters,
128
                                data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
129
                                true
130
                        );
131
                        segments.addPrimitives(rightGeom);
132
                        break;
133
                        
134
                    case CONTINUITY_MODE_CONT_DISC:
135
                        //Left
136
                        leftGeom = line.cloneGeometry().offset(-offsetValueInMeters).buffer(
137
                                bufferValueInMeters,
138
                                data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
139
                                true
140
                        );
141
                        segments.addPrimitives(leftGeom);
142
                        //Right
143
                        splittedLine = splitLine(line, data.getSegmentsLength(), data.getHolesLength());
144
                        splittedSegments = splittedLine.getSegments();
145
                        splittedHoles = splittedLine.getHoles();
146
                        for (Line segment : splittedSegments) {
147
                            buffer = segment.cloneGeometry().offset(offsetValueInMeters).buffer(
148
                                    bufferValueInMeters,
149
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
150
                                    true
151
                            );
152
                            segments.addPrimitives(buffer);
153
                        }
154
                        for (Line hole : splittedHoles) {
155
                            buffer = hole.cloneGeometry().offset(offsetValueInMeters).buffer(
156
                                    bufferValueInMeters,
157
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
158
                                    true
159
                            );
160
                            holes.addPrimitives(buffer);
161
                        }
162
                        break;
163

  
164
                    case CONTINUITY_MODE_DISC_CONT:
165
                        //Left
166
                        splittedLine = splitLine(line, data.getSegmentsLength(), data.getHolesLength());
167
                        splittedSegments = splittedLine.getSegments();
168
                        splittedHoles = splittedLine.getHoles();
169
                        for (Line segment : splittedSegments) {
170
                            buffer = segment.cloneGeometry().offset(-offsetValueInMeters).buffer(
171
                                    bufferValueInMeters,
172
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
173
                                    true
174
                            );
175
                            segments.addPrimitives(buffer);
176
                        }
177
                        for (Line hole : splittedHoles) {
178
                            buffer = hole.cloneGeometry().offset(-offsetValueInMeters).buffer(
179
                                    bufferValueInMeters,
180
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
181
                                    true
182
                            );
183
                            holes.addPrimitives(buffer);
184
                        }
185
                        //Right
186
                        rightGeom = line.cloneGeometry().offset(offsetValueInMeters).buffer(
187
                                bufferValueInMeters,
188
                                data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
189
                                true
190
                        );
191
                        segments.addPrimitives(rightGeom);
192
                        break;
193
                        
194
                    case CONTINUITY_MODE_DISC_DISC:
195
                        splittedLine = splitLine(line, data.getSegmentsLength(), data.getHolesLength());
196
                        splittedSegments = splittedLine.getSegments();
197
                        splittedHoles = splittedLine.getHoles();
198
                        //Left
199
                        for (Line segment : splittedSegments) {
200
                            buffer = segment.cloneGeometry().offset(-offsetValueInMeters).buffer(
201
                                    bufferValueInMeters,
202
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
203
                                    true
204
                            );
205
                            segments.addPrimitives(buffer);
206
                        }
207
                        for (Line hole : splittedHoles) {
208
                            buffer = hole.cloneGeometry().offset(-offsetValueInMeters).buffer(
209
                                    bufferValueInMeters,
210
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
211
                                    true
212
                            );
213
                            holes.addPrimitives(buffer);
214
                        }
215
                        //Right
216
                        for (Line segment : splittedSegments) {
217
                            Geometry offset = segment.cloneGeometry().offset(offsetValueInMeters);
218
                            buffer = offset.buffer(
219
                                    bufferValueInMeters,
220
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
221
                                    true
222
                            );
223
                            segments.addPrimitives(buffer);
224
                        }
225
                        for (Line hole : splittedHoles) {
226
                            buffer = hole.cloneGeometry().offset(offsetValueInMeters).buffer(
227
                                    bufferValueInMeters,
228
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
229
                                    true
230
                            );
231
                            holes.addPrimitives(buffer);
232
                        }
233
                        break;
234

  
235
                }
236

  
237
            }
238
            data.setSegmentsGeometry(segments);
239
            data.setHolesGeometry(holes);
240
        } catch (Exception ex) {
241
            LOGGER.warn("Can't calculate geometries.", ex);
242
            //VOY POR AQU?
243

  
244
//            Logger.getLogger(DefaultUrbanHorizontalSignageManager.class.getName()).log(Level.SEVERE, null, ex);
245
        }
246

  
247
    }
248

  
249
    /*
250
        segmentLength & holesLenght in meters
251
    */
252
    /*friend*/SplittedLine splitLine(Line line, double segmentLength, double holesLength) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException, CloneNotSupportedException {
253
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
254
        SplittedLine res = new SplittedLine();
255

  
256
        Point previousPoint = null;
257
        double previousLength = 0;
258
        Line currentSegment = geomManager.createLine(line.getGeometryType().getSubType());
259
        boolean isHole = false;
260
        boolean advanceToNext = true;
261
        Iterator<Point> it = line.iterator();
262
        Point currentPoint = null;
263
        while (it.hasNext() || !advanceToNext) {
264
            if (advanceToNext) {
265
                currentPoint = it.next();
266
            }
267
            if (previousPoint == null) {
268
                previousPoint = currentPoint.clone();
269
                currentSegment.addVertex(previousPoint);
270
                advanceToNext = true;
271
                continue;
272
            }
273
            double distance = previousPoint.distance(currentPoint);
274
            if (!isHole) {
275
                if (previousLength + distance < segmentLength) {
276
                    previousLength += distance;
277
                    if(distance > 0.0){
278
                        currentSegment.addVertex(currentPoint);
279
                    }
280
                    previousPoint = currentPoint.cloneGeometry();
281
                    advanceToNext = true;
282
                    continue;
283
                } else {
284
                    //buscar punto dentro del segmento a una distancia = segmentLengthMeters-previousLength
285
                    Point point = calculateIntermediatePoint(previousPoint, currentPoint, (segmentLength - previousLength) / distance);
286
                    //a?adirlo al currentSegment,
287
                    currentSegment.addVertex(point);
288
                    //a?adir  el currentSegment a la lista de segmentos
289
                    res.addSegment(currentSegment.cloneGeometry());
290
                    //crear un nuevo currentSegment y meter el punto como primero
291
                    currentSegment = geomManager.createLine(line.getGeometryType().getSubType());
292
                    currentSegment.addVertex(point);
293
                    //cambiar modo ==> isHole = true
294
                    isHole = !isHole;
295
                    previousPoint = point.clone();
296
                    previousLength = 0;
297
                    advanceToNext = false;
298
                    continue;
299
                }
300
            } else {
301
                if (previousLength + distance < holesLength) {
302
                    previousLength += distance;
303
                    if(distance > 0.0){
304
                        currentSegment.addVertex(currentPoint);
305
                    }
306
                    previousPoint = currentPoint.cloneGeometry();
307
                    advanceToNext = true;
308
                    continue;
309
                } else {
310
                    //buscar punto dentro del segmento a una distancia = segmentLengthMeters-previousLength
311
                    Point point = calculateIntermediatePoint(previousPoint, currentPoint, (holesLength - previousLength) / distance);
312
                    //a?adirlo al currentSegment,
313
                    currentSegment.addVertex(point);
314
                    //a?adir  el surrentSegment a la lista de segmentos
315
                    res.addHole(currentSegment.cloneGeometry());
316
                    //crear un nuevo currentSegment y meter el punto como primero
317
                    currentSegment = geomManager.createLine(line.getGeometryType().getSubType());
318
                    currentSegment.addVertex(point);
319
                    //Cambiar modo Segment <==> Hole
320
                    isHole = !isHole;
321
                    previousPoint = point.clone();
322
                    previousLength = 0;
323
                    advanceToNext = false;
324
                    continue;
325
                }
326
            }
327
        }
328
//        currentSegment.addVertex(currentPoint);
329
        if (currentSegment.getNumVertices() > 1) {
330
            if (isHole) {
331
                res.addHole(currentSegment.cloneGeometry());
332
            } else {
333
                res.addSegment(currentSegment.cloneGeometry());
334
            }
335
        }
336

  
337
        return res;
338
    }
339

  
340
    Point calculateIntermediatePoint(Point p1, Point p2, double lambda) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
341
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
342
        GeometryType geomType = p1.getGeometryType();
343
        int subtype = geomType.getSubType();
344
        int dimension = geomType.getDimension();
345
        double[] coords = new double[dimension];
346
        Point p = geomManager.createPoint(0, 0, subtype);
347
        double distance = p1.distance(p2);
348
        for (int d = 0; d < dimension; d++) {
349
            p.setCoordinateAt(
350
                    d,
351
                    p1.getCoordinateAt(d) + (p2.getCoordinateAt(d) - p1.getCoordinateAt(d)) * lambda);
352
        }
353
        
354
        return p;
355
    }
356

  
357
    /*friend*/ static class SplittedLine {
358

  
359
        List<Line> segments;
360
        List<Line> holes;
361

  
362
        public SplittedLine() {
363
            segments = new ArrayList<>();
364
            holes = new ArrayList<>();
365
        }
366

  
367
        public List<Line> getSegments() {
368
            return this.segments;
369
        }
370

  
371
        public List<Line> getHoles() {
372
            return this.holes;
373
        }
374

  
375
        public void addSegment(Line segment) {
376
            this.segments.add(segment);
377
        }
378

  
379
        public void addHole(Line hole) {
380
            this.holes.add(hole);
381
        }
382

  
383
    }
384

  
385
}
org.gvsig.legend.urbanhorizontalsignage/trunk/org.gvsig.legend.urbanhorizontalsignage.lib/org.gvsig.legend.urbanhorizontalsignage.lib.impl/src/main/java/org/gvsig/legend/urbanhorizontalsignage/lib/impl/DefaultUrbanHorizontalSignageLegend.java
1
package org.gvsig.legend.urbanhorizontalsignage.lib.impl;
2

  
3
import java.awt.Color;
4
import java.awt.Image;
5
import org.gvsig.fmap.dal.exception.DataException;
6
import org.gvsig.fmap.dal.feature.Feature;
7
import org.gvsig.fmap.dal.feature.FeatureStore;
8
import org.gvsig.fmap.dal.feature.FeatureType;
9
import org.gvsig.fmap.geom.Geometry;
10
import org.gvsig.fmap.mapcontext.MapContextException;
11
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
12
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData;
13
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.DEFAULT_CONTINUITY_VALUE;
14
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.DEFAULT_GAP_WIDTH_VALUE;
15
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.DEFAULT_HOLES_COLOR_VALUE;
16
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.DEFAULT_HOLES_LENGTH_VALUE;
17
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.DEFAULT_PAINT_HOLES_VALUE;
18
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.DEFAULT_ROUND_VERTEX_VALUE;
19
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.DEFAULT_SEGMENT_COLOR_VALUE;
20
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.DEFAULT_SEGMENT_LENGTH_VALUE;
21
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.DEFAULT_WIDTH_VALUE;
22
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLegend;
23
import org.gvsig.symbology.SymbologyLocator;
24
import org.gvsig.symbology.SymbologyManager;
25
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl.AbstractVectorialLegend;
26
import org.gvsig.tools.ToolsLocator;
27
import org.gvsig.tools.dataTypes.DataTypesManager;
28
import org.gvsig.tools.persistence.PersistentState;
29
import org.gvsig.tools.persistence.exception.PersistenceException;
30
import org.gvsig.tools.swing.api.DataTypes;
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

  
34
public class DefaultUrbanHorizontalSignageLegend 
35
        extends AbstractVectorialLegend 
36
        implements UrbanHorizontalSignageLegend //, IHasImageLegend 
37
{
38
    
39
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultUrbanHorizontalSignageLegend.class);
40

  
41
    private UrbanHorizontalSignageSymbol defaultSymbol;
42
    private Image imageLegend;
43
    private String widthFieldName;
44
    private String continuityFieldName;
45
    private String holesLengthFieldName;
46
    private String holesColorFieldName;
47
    private String paintHolesFieldName;
48
    private String segmentsLengthFieldName;
49
    private String segmentsColorFieldName;
50
    private String roundVertexFieldName;
51
    private int gapWidth;
52
    
53
    public DefaultUrbanHorizontalSignageLegend() {
54
        
55
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
56
        this.defaultSymbol = new UrbanHorizontalSignageSymbol();
57
        DefaultUrbanHorizontalSignageData data = new DefaultUrbanHorizontalSignageData();
58
        data.setContinuity(UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_CONT);
59
        this.defaultSymbol.setData(new DefaultUrbanHorizontalSignageData());
60
        
61
        this.gapWidth = DEFAULT_GAP_WIDTH_VALUE;
62
    }
63

  
64
//    @Override
65
//    protected String[] getRequiredFeatureAttributeNames(FeatureStore featureStore) throws DataException {
66
//        FeatureType ftype = featureStore.getDefaultFeatureType();
67
//        if( StringUtils.isEmpty(this.fieldName) ) {
68
//            return new String[]{
69
//                ftype.getDefaultGeometryAttributeName()
70
//            };
71
//        }
72
//        return new String[]{
73
//            ftype.getDefaultGeometryAttributeName(),
74
//            this.fieldName
75
//        };
76
//    }
77

  
78
    @Override
79
    public ISymbol getDefaultSymbol() {
80
        return this.defaultSymbol;
81
    }
82

  
83
    @Override
84
    public void setDefaultSymbol(ISymbol is) {
85
        //DO NOTHING
86
    }
87

  
88
    @Override
89
    public ISymbol getSymbolByFeature(Feature ftr) throws MapContextException {
90

  
91
        UrbanHorizontalSignageData values = getValues(ftr);
92

  
93
        UrbanHorizontalSignageSymbol symbol = new UrbanHorizontalSignageSymbol();
94
        symbol.setData(values);
95
        return symbol;
96
    }
97

  
98
    @Override
99
    public int getShapeType() {
100
        return Geometry.TYPES.CURVE;
101
    }
102

  
103
    @Override
104
    public void setShapeType(int i) {
105
    }
106

  
107
    @Override
108
    public boolean isUseDefaultSymbol() {
109
        return true;
110
    }
111

  
112
    @Override
113
    public void useDefaultSymbol(boolean bln) {
114
    }
115

  
116
    @Override
117
    public boolean isSuitableForShapeType(int shapeType) {
118
        return true;
119
    }
120

  
121
//    @Override
122
//    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 {
123
//        int saved_distance = this.algorithm.getDistance();
124
//        try {
125
//            int distance = (int) (this.algorithm.getDistance() * (dpi / 72));
126
//            Geometry theROI = null;
127
//            if (this.roi!=null) {
128
//                theROI = this.roi.cloneGeometry();
129
//                theROI.transform(viewPort.getAffineTransform());
130
//            }
131
//            this.algorithm.setDistance(distance);
132
//            this.algorithm.init(image.getWidth(), image.getHeight());
133
//            super.draw(image, g, viewPort, cancel, scale, queryParameters, coordTrans, featureStore, featureQuery, dpi);
134
//            if( !cancel.isCanceled() ) {
135
//                this.algorithm.drawWithOpaqueColors(image, g, this.getHeatMapColorTable().getColorTable(), cancel, theROI);
136
//            }
137
//        } finally {
138
//            this.algorithm.setDistance(saved_distance);
139
//
140
//        }
141
//    }
142
    
143
//    @Override
144
//    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
145
//            double scale, Map queryParameters, ICoordTrans coordTrans,
146
//            FeatureStore featureStore, FeatureQuery featureQuery, PrintAttributes properties)
147
//            throws LegendException {
148
//        int saved_distance = this.algorithm.getDistance();
149
//        try {
150
//            double dpi = viewPort.getDPI();
151
//            // Ver CartographicSupportToolkit.getCartographicLength
152
//            int distance = (int) (this.algorithm.getDistance() * (dpi / 72));
153
//            Geometry theROI = null;
154
//            if (this.roi!=null) {
155
//                theROI = this.roi.cloneGeometry();
156
//                theROI.transform(viewPort.getAffineTransform());
157
//            }
158
//            this.algorithm.setDistance(distance);
159
//            this.algorithm.init(viewPort.getImageWidth(), viewPort.getImageHeight());
160
//            BufferedImage image = new BufferedImage(viewPort.getImageWidth(), viewPort.getImageHeight(), BufferedImage.TYPE_INT_ARGB);
161
//            super.draw(image, g, viewPort, cancel, scale, queryParameters, coordTrans, featureStore, featureQuery, dpi);
162
//            if (!cancel.isCanceled()) {
163
//                this.algorithm.drawWithAlphaColors(image, g, this.getHeatMapColorTable().getColorTable(), cancel, theROI);
164
//                g.drawImage(image, 0, 0, null);
165
//            }
166
//        } finally {
167
//            this.algorithm.setDistance(saved_distance);
168
//
169
//        }
170
//    }
171

  
172
//    @Override
173
//    protected void drawFeatures(
174
//            BufferedImage image,
175
//            Graphics2D g,
176
//            final ViewPort viewPort,
177
//            final Cancellable cancel,
178
//            final ICoordTrans coordTrans,
179
//            double dpi,
180
//            DefaultFeatureDrawnNotification drawnNotification,
181
//            FeatureSet featureSet,
182
//            FeatureSelection selection
183
//    ) throws BaseException {
184
//
185
//        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
186
//
187
//        UrbanHorizontalSignageManager uhsManager = UrbanHorizontalSignageLocator.getUrbanHorizontalSignageManager();
188
//
189
//        try {
190
//            featureSet.accept(new Visitor() {
191
//                @Override
192
//                public void visit(Object obj) throws VisitCanceledException,
193
//                        BaseException {
194
//                    if (cancel.isCanceled()) {
195
//                        throw new VisitCanceledException();
196
//                    }
197
//                    Feature feature = (Feature) obj;
198
//                    UrbanHorizontalSignageData values = getValues(feature);
199
//                    Geometry originalGeometry = feature.getDefaultGeometry();
200
//                    
201
//                    ISimpleLineSymbol lineSymbol = symbologyManager.createSimpleLineSymbol();
202
//                    lineSymbol.setColor(Color.YELLOW);
203
//                    
204
//                    uhsManager.calculateGeometries(originalGeometry, values);
205
//                    MultiPolygon geom;
206
//                    
207
//                    ISimpleFillSymbol segmentsSymbol = symbologyManager.createSimpleFillSymbol();;
208
//                    segmentsSymbol.setFillColor(values.getSegmentsColor());
209
//                    
210
//                    ISimpleFillSymbol holesSymbol = symbologyManager.createSimpleFillSymbol();
211
//                    holesSymbol.setFillColor(values.getHolesColor());
212
//
213
//                    geom = values.getSegmentsGeometry();
214
//                    if (geom != null && geom.getPrimitivesNumber() > 0) {
215
//                        segmentsSymbol.draw(g, viewPort.getAffineTransform(), geom,
216
//                                feature, cancel);
217
//                    }
218
//
219
//                    switch (values.getContinuity()) {
220
////                        case CONTINUITY_MODE_CONT:
221
////                        case CONTINUITY_MODE_CONT_CONT:
222
////                            geom = values.getSegmentsGeometry();
223
////                            if(geom != null && geom.getPrimitivesNumber()>0){
224
////                                segmentsSymbol.draw(g, viewPort.getAffineTransform(), geom,
225
////                                        feature, cancel);
226
////                            }
227
////                            break;
228
//                        case CONTINUITY_MODE_CONT_DISC:
229
//                        case CONTINUITY_MODE_DISC_CONT:
230
//                        case CONTINUITY_MODE_DISC:
231
//                        case CONTINUITY_MODE_DISC_DISC:
232
//                            if(values.isPaintHoles()){
233
//                                geom = values.getHolesGeometry();
234
//                                if(geom != null && geom.getPrimitivesNumber()>0){
235
//                                    holesSymbol.draw(g, viewPort.getAffineTransform(), geom,
236
//                                            feature, cancel);
237
//                                }
238
//                            }
239
//                    }
240
//
241
//                    //For debug purposse only
242
//                    lineSymbol.draw(g, viewPort.getAffineTransform(), originalGeometry,
243
//                            feature, cancel);
244
//                }
245
//            });
246
//
247
//        } catch (ConcurrentDataModificationException e) {
248
//            cancel.setCanceled(true);
249
//        }
250
//    }
251

  
252
//    @Override
253
//    public Image getImageLegend() {
254
//        if( this.imageLegend==null ) {
255
////            BufferedImage img = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
256
////            ColorTablePainter painter = new DefaultColorTablePainter(this.getTargetColorTable(),"");
257
////            Graphics2D g = img.createGraphics();
258
////            g.setClip(0, 0, 80, 20);
259
////            g.setBackground(Color.WHITE);
260
////            g.fillRect(0, 0, 80, 20);
261
////            painter.paint(g, false);
262
////            this.imageLegend = img;
263
//        }
264
//        return this.imageLegend;
265
//    }
266
//
267
//    @Override
268
//    public String getPathImage() {
269
//        return null;
270
//    }
271

  
272
    @Override
273
    public void loadFromState(PersistentState state) throws PersistenceException {
274
//        this.defaultSymbol = new SimpleTextSymbol();
275
        this.imageLegend = null;
276

  
277
        super.loadFromState(state);
278
        this.widthFieldName = state.getString("widthFieldName");
279
        this.continuityFieldName = state.getString("continuityFieldName");
280
        this.holesLengthFieldName = state.getString("holesLengthFieldName");
281
        this.holesColorFieldName = state.getString("holesColorFieldName");
282
        this.paintHolesFieldName = state.getString("paintHolesFieldName");
283
        this.segmentsLengthFieldName = state.getString("segmentsLengthFieldName");
284
        this.segmentsColorFieldName = state.getString("segmentsColorFieldName");
285
        this.roundVertexFieldName = state.getString("roundVertexFieldName");
286
        this.gapWidth = state.getInt("gapWidth", DEFAULT_GAP_WIDTH_VALUE);
287
    }
288

  
289
    @Override
290
    public void saveToState(PersistentState state) throws PersistenceException {
291
        super.saveToState(state);
292
        state.set("widthFieldName", this.widthFieldName);
293
        state.set("continuityFieldName", this.continuityFieldName);
294
        state.set("holesLengthFieldName", this.holesLengthFieldName);
295
        state.set("holesColorFieldName", this.holesColorFieldName);
296
        state.set("paintHolesFieldName", this.paintHolesFieldName);
297
        state.set("segmentsLengthFieldName", this.segmentsLengthFieldName);
298
        state.set("segmentsColorFieldName", this.segmentsColorFieldName);
299
        state.set("roundVertexFieldName", this.roundVertexFieldName);
300
        state.set("gapWidth", this.gapWidth);
301
    }
302

  
303
    @Override
304
    protected String[] getRequiredFeatureAttributeNames(FeatureStore fs) throws DataException {
305
        return new String[]{
306
            this.widthFieldName,
307
            this.continuityFieldName,
308
            this.holesLengthFieldName,
309
            this.holesColorFieldName,
310
            this.paintHolesFieldName,
311
            this.segmentsLengthFieldName,
312
            this.segmentsColorFieldName,
313
            this.roundVertexFieldName,
314
            fs.getDefaultFeatureType().getDefaultGeometryAttributeName()};
315
    }
316

  
317
    @Override
318
    public String getWidthFieldName() {
319
        return this.widthFieldName;
320
    }
321

  
322
    @Override
323
    public void setWidthFieldName(String fieldName) {
324
        this.widthFieldName = fieldName;
325
    }
326

  
327
    @Override
328
    public String getContinuityFieldName() {
329
        return this.continuityFieldName;
330
    }
331

  
332
    @Override
333
    public void setContinuityFieldName(String fieldName) {
334
        this.continuityFieldName = fieldName;
335
    }
336

  
337
    @Override
338
    public String getSegmentsColorFieldName() {
339
        return this.segmentsColorFieldName;
340
    }
341

  
342
    @Override
343
    public void setSegmentsColorFieldName(String fieldName) {
344
        this.segmentsColorFieldName = fieldName;
345
    }
346

  
347
    @Override
348
    public String getSegmentsLengthFieldName() {
349
        return this.segmentsLengthFieldName;
350
    }
351

  
352
    @Override
353
    public void setSegmentsLengthFieldName(String fieldName) {
354
        this.segmentsLengthFieldName = fieldName;
355
    }
356

  
357
    @Override
358
    public String getPaintHolesFieldName() {
359
        return this.paintHolesFieldName;
360
    }
361

  
362
    @Override
363
    public void setPaintHolesFieldName(String fieldName) {
364
        this.paintHolesFieldName = fieldName;
365
    }
366

  
367
    @Override
368
    public String getHolesColorFieldName() {
369
        return this.holesColorFieldName;
370
    }
371

  
372
    @Override
373
    public void setHolesColorFieldName(String fieldName) {
374
        this.holesColorFieldName = fieldName;
375
    }
376

  
377
    @Override
378
    public String getHolesLengthFieldName() {
379
        return this.holesLengthFieldName;
380
    }
381

  
382
    @Override
383
    public void setHolesLengthFieldName(String fieldName) {
384
        this.holesLengthFieldName = fieldName;
385
    }
386
    
387
    @Override
388
    public String getRoundVertexFieldName() {
389
        return this.roundVertexFieldName;
390
    }
391

  
392
    @Override
393
    public void setRoundVertexFieldName(String fieldName) {
394
        this.roundVertexFieldName = fieldName;
395
    }
396
    
397
    @Override
398
    public int getGapWidth() {
399
        return this.gapWidth;
400
    }
401

  
402
    @Override
403
    public void setGapWith(int value) {
404
        this.gapWidth = value;
405
    }
406

  
407
    @Override
408
    public UrbanHorizontalSignageData getValues(Feature feature) {
409
        UrbanHorizontalSignageData data = new DefaultUrbanHorizontalSignageData();
410
        DataTypesManager manager = ToolsLocator.getDataTypesManager();
411
        FeatureType ftype = feature.getType();
412
        double valueDouble = feature.getIntOrDefault( this.widthFieldName, (int)DEFAULT_WIDTH_VALUE*100 )/100.0;
413
        data.setWidth(valueDouble);
414
        int valueInt = feature.getIntOrDefault( this.continuityFieldName, DEFAULT_CONTINUITY_VALUE );
415
        data.setContinuity(valueInt);
416
        Color valueColor = (Color)feature.getOrDefault( this.segmentsColorFieldName, DataTypes.COLOR, DEFAULT_SEGMENT_COLOR_VALUE );
417
        data.setSegmentsColor(valueColor);
418
        valueDouble = feature.getIntOrDefault( this.segmentsLengthFieldName, (int)DEFAULT_SEGMENT_LENGTH_VALUE*100 )/100.0;
419
        data.setSegmentsLength(valueDouble);
420
        valueDouble = feature.getIntOrDefault( this.holesLengthFieldName, (int)DEFAULT_HOLES_LENGTH_VALUE*100 )/100.0;
421
        data.setHolesLength(valueDouble);
422
        boolean valueBoolean = feature.getBooleanOrDefault( this.paintHolesFieldName, DEFAULT_PAINT_HOLES_VALUE );
423
        data.setPaintHoles(valueBoolean);
424
        valueColor = (Color) feature.getOrDefault( this.holesColorFieldName, DataTypes.COLOR, DEFAULT_HOLES_COLOR_VALUE );
425
        data.setHolesColor(valueColor);
426
        valueBoolean = feature.getBooleanOrDefault( this.roundVertexFieldName, DEFAULT_ROUND_VERTEX_VALUE );
427
        data.setRoundVertex(valueBoolean);
428

  
429
        data.setGapWidth(this.getGapWidth()/100.0);
430
        
431
        return data;
432
    }
433

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

  
26
import java.awt.Color;
27
import java.awt.Graphics2D;
28
import java.awt.Rectangle;
29
import java.awt.geom.AffineTransform;
30
import java.util.Objects;
31
import java.util.concurrent.Callable;
32
import java.util.logging.Level;
33
import org.gvsig.compat.print.PrintAttributes;
34
import org.gvsig.fmap.dal.feature.Feature;
35
import org.gvsig.fmap.geom.Geometry;
36
import org.gvsig.fmap.geom.GeometryLocator;
37
import org.gvsig.fmap.geom.GeometryManager;
38
import org.gvsig.fmap.geom.GeometryUtils;
39
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
40
import org.gvsig.fmap.geom.operation.GeometryOperationException;
41
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
42
import org.gvsig.fmap.geom.primitive.Envelope;
43
import org.gvsig.fmap.geom.primitive.Line;
44
import org.gvsig.fmap.geom.primitive.Point;
45
import org.gvsig.fmap.mapcontext.MapContext;
46
import org.gvsig.fmap.mapcontext.MapContextLocator;
47
import org.gvsig.fmap.mapcontext.ViewPort;
48
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
49
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol_v2;
50
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
51
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
52
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData;
53
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_CONT_DISC;
54
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC;
55
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_CONT;
56
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_DISC;
57
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLocator;
58
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageManager;
59
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.AbstractSymbol;
60
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.CartographicSupportToolkit;
61
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
62
import static org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.impl.AbstractLineSymbol.LINE_SYMBOL_PERSISTENCE_DEFINITION_NAME;
63
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.impl.SimpleLineSymbol;
64
import org.gvsig.tools.ToolsLocator;
65
import org.gvsig.tools.dynobject.DynStruct;
66
import org.gvsig.tools.persistence.PersistenceManager;
67
import org.gvsig.tools.persistence.PersistentState;
68
import org.gvsig.tools.persistence.exception.PersistenceException;
69
import org.gvsig.tools.task.Cancellable;
70
import org.slf4j.Logger;
71
import org.slf4j.LoggerFactory;
72
import org.gvsig.tools.swing.api.TransparencySupport;
73

  
74
public class UrbanHorizontalSignageSymbol extends AbstractSymbol implements ISymbol_v2, TransparencySupport {
75

  
76
    private static final Logger LOG = LoggerFactory.getLogger(UrbanHorizontalSignageSymbol.class);
77
    private static final String SYMBOL_NAME = "UrbanHorizontalSignageSymbol";
78
    private static final String URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME = "UrbanHorizontalSignageSymbol";
79
    
80
    private static final String FIELD_WIDTH = "width";
81
    private static final String FIELD_CONTINUITY = "continuity";
82
    private static final String FIELD_SEGMENTS_COLOR = "segmentsColor";
83
    private static final String FIELD_SEGMENTS_LENGTH = "segmentsLength";
84
    private static final String FIELD_HOLES_COLOR = "holesColor";
85
    private static final String FIELD_HOLES_LENGTH = "holesLength";
86
    private static final String FIELD_PAINT_HOLES = "paintHoles";
87
    private static final String FIELD_GAP_WIDTH = "gapWidth";
88
    private static final String FIELD_ROUND_VERTEX = "roundVertex";
89
    private static final String FIELD_SEGMENTS_GEOMETRY = "segmentsGeometry";
90
    private static final String FIELD_HOLES_GEOMETRY = "holesGeometry";
91
    private static final String FIELD_TRANSPARENCY = "transparency";
92
    private static final String FIELD_MUST_DRAW_ORIGINAL_GEOMETRY = "mustDrawOriginalGeometry";
93
    private static final String FIELD_COLOR_FOR_ORIGINAL_GEOMETRY = "colorForOriginalGeometry";
94
    
95

  
96

  
97
//    private static final String FIELD_SYMBOL_FOR_SELECTION = "symbolForSelection";
98
    private UrbanHorizontalSignageData data;
99

  
100
    transient private UrbanHorizontalSignageSymbol symbolForSelection;
101
    
102
    private boolean mustDrawOriginalGeometry;
103
    private Color colorForOriginalGeometry;
104
    private double cartographicSize;
105
    private double transparency; //[0.0, 1.0]
106

  
107
    public UrbanHorizontalSignageSymbol() {
108
        super();
109
        this.mustDrawOriginalGeometry = false;
110
        this.transparency = 1.0;
111
    }
112

  
113
    public void setData(UrbanHorizontalSignageData data) {
114
        this.data = data;
115
    }
116

  
117
    public UrbanHorizontalSignageData getData() {
118
        return data;
119
    }
120

  
121
    /**
122
     * Sets the transparency for symbol. The valid values are in [0.0, 1.0]
123
     * 
124
     * @param transparency 
125
     */
126
    @Override
127
    public void setTransparency(double transparency) {
128
        if(transparency < 0 || transparency > 1.0){
129
            throw new IllegalArgumentException("Transparency value must be in [0.0, 1.0] ("+transparency+")");
130
        }
131
        this.transparency = transparency;
132
    }
133

  
134
    @Override
135
    public double getTransparency() {
136
        return transparency;
137
    }
138
    
139
    @Override
140
    public ISymbol getSymbolForSelection() {
141
        if (symbolForSelection == null) {
142
            symbolForSelection = (UrbanHorizontalSignageSymbol) cloneForSelection();
143
            symbolForSelection.mustDrawOriginalGeometry = true;
144
        } else {
145
            symbolForSelection.setColor(MapContext.getSelectionColor());
146
        }
147
        return symbolForSelection;
148
    }
149

  
150
    @Override
151
    public void draw(Graphics2D g, AffineTransform affineTransform,
152
            Geometry originalGeometry, Feature feature, Cancellable cancel) {
153
        
154
        if (true) {
155
            // Esto deberia ser para optimizar el pintado de 
156
            // geometrias grandes.
157
            try {
158
                Geometry env = originalGeometry.getEnvelope().getGeometry();
159
                env.transform(affineTransform);
160
                Envelope env2 = env.getEnvelope();
161
                if (env2.getLength(0) < 1.5 && env2.getLength(1) < 1.5) {
162
                    g.setColor(data.getSegmentsColor());
163
                    Point upperCorner = env2.getUpperCorner();
164
                    int x = (int) upperCorner.getX();
165
                    int y = (int) upperCorner.getY();
166
                    g.drawLine(x, y, x, y);
167
                    return;
168
                }
169
            } catch (Exception ex) {
170
                LOG.warn("Error optimizing the drawing of the geometry. Continues with normal drawing.", ex);
171
                // Do nothing, continue with the draw of the original geometry
172
            }
173
        }
174

  
175
        UrbanHorizontalSignageManager uhsManager = UrbanHorizontalSignageLocator.getUrbanHorizontalSignageManager();
176
        uhsManager.calculateGeometries(originalGeometry, data);
177
        
178
        MultiPolygon geom = data.getSegmentsGeometry();
179
        if (geom != null && geom.getPrimitivesNumber() > 0) {
180
            Color color = data.getSegmentsColor();
181
            Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)(255*transparency));
182
            g.setColor(transparentColor);
183
            g.fill(geom.getShape(affineTransform));
184
        }
185

  
186
        switch (data.getContinuity()) {
187
            case CONTINUITY_MODE_CONT_DISC:
188
            case CONTINUITY_MODE_DISC_CONT:
189
            case CONTINUITY_MODE_DISC:
190
            case CONTINUITY_MODE_DISC_DISC:
191
                if (data.isPaintHoles()) {
192
                    geom = data.getHolesGeometry();
193
                    if (geom != null && geom.getPrimitivesNumber() > 0) {
194
                        Color color = data.getHolesColor();
195
                        Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)(255*transparency));
196
                        g.setColor(transparentColor);
197
                        g.fill(geom.getShape(affineTransform));
198
                    }
199
                }
200
        }
201

  
202
        //For debug purposse only
203
        if(mustDrawOriginalGeometry){
204
            g.setColor(getColor());
205
            g.draw(originalGeometry.getShape(affineTransform));
206
        }
207

  
208
    }
209

  
210
    @Override
211
    public int getOnePointRgb() {
212
        return data.getSegmentsColor().getRGB();
213
    }
214

  
215
    @Override
216
    public void drawInsideRectangle(Graphics2D g,
217
            AffineTransform scaleInstance, Rectangle r, PrintAttributes properties) throws SymbolDrawingException {
218
        
219
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
220
        
221
        final int hGap = (int) (r.getWidth() * 0.1); // the left and right margins
222
        final int vPos = 1; 						 // the top and bottom margins
223
        final int splitCount = 3; 					 // number of lines
224
        final int splitHSize = (r.width - hGap - hGap) / splitCount;
225
        int hPos = hGap;
226
        boolean swap = false;
227

  
228
        Line geom = GeometryUtils.createLine(Geometry.SUBTYPES.GEOM2D);
229
        geom.addVertex(r.x + hPos, r.y + r.height - vPos);
230

  
231
        for (int i = 0; i < splitCount; i++) {
232
            swap = !swap;
233
            geom.addVertex(r.x + hPos + splitHSize, (swap ? vPos : r.height - vPos) + r.y);
234
            hPos += splitHSize;
235
        }
236

  
237
        try {
238
            if (properties == null) {
239
                draw(g, new AffineTransform(), geom, null, null);
240
            } else {
241
                print(g, new AffineTransform(), geom, properties);
242
            }
243
        } catch (Exception e) {
244
            throw new SymbolDrawingException(SymbolDrawingException.UNSUPPORTED_SET_OF_SETTINGS);
245
        }
246

  
247
    }
248

  
249
    @Override
250
    public Object clone() throws CloneNotSupportedException {
251
        UrbanHorizontalSignageSymbol copy = (UrbanHorizontalSignageSymbol) super.clone();
252

  
253
        if (symbolForSelection != null) {
254
            copy.symbolForSelection = (UrbanHorizontalSignageSymbol) symbolForSelection
255
                    .clone();
256
        }
257

  
258
        return copy;
259
    }
260

  
261
    @Override
262
    public void loadFromState(PersistentState state) throws PersistenceException {
263
        // Set parent style properties
264
        super.loadFromState(state);
265
        
266
        UrbanHorizontalSignageData data = new DefaultUrbanHorizontalSignageData();
267
        data.setWidth(state.getDouble(FIELD_WIDTH, UrbanHorizontalSignageData.DEFAULT_WIDTH_VALUE));
268
        data.setContinuity(state.getInt(FIELD_CONTINUITY, UrbanHorizontalSignageData.DEFAULT_CONTINUITY_VALUE));
269
        
270
        Color color = (Color) state.get(FIELD_SEGMENTS_COLOR);
271
        data.setSegmentsColor(color != null ? color : UrbanHorizontalSignageData.DEFAULT_SEGMENT_COLOR_VALUE);
272
        
273
        data.setSegmentsLength(state.getDouble(FIELD_SEGMENTS_LENGTH, UrbanHorizontalSignageData.DEFAULT_SEGMENT_LENGTH_VALUE));
274
        
275
        color = (Color) state.get(FIELD_HOLES_COLOR);
276
        data.setHolesColor(color != null ? color : UrbanHorizontalSignageData.DEFAULT_HOLES_COLOR_VALUE);
277
        
278
        data.setHolesLength(state.getDouble(FIELD_HOLES_LENGTH, UrbanHorizontalSignageData.DEFAULT_HOLES_LENGTH_VALUE));
279
        data.setGapWidth(state.getDouble(FIELD_GAP_WIDTH, UrbanHorizontalSignageData.DEFAULT_GAP_WIDTH_VALUE));
280
        data.setRoundVertex(state.getBoolean(FIELD_ROUND_VERTEX, UrbanHorizontalSignageData.DEFAULT_ROUND_VERTEX_VALUE));
281
        
282
        this.transparency = state.getDouble(FIELD_TRANSPARENCY, 1.0);
283
        this.mustDrawOriginalGeometry = state.getBoolean(FIELD_MUST_DRAW_ORIGINAL_GEOMETRY, false);
284
        color = (Color) state.get(FIELD_COLOR_FOR_ORIGINAL_GEOMETRY);
285
        this.colorForOriginalGeometry = color != null ? color : MapContext.getSelectionColor();
286
        this.data = data;
287

  
288
    }
289

  
290
    @Override
291
    public void saveToState(PersistentState state) throws PersistenceException {
292
        // Save parent fill symbol properties
293
        super.saveToState(state);
294

  
295
        // Save own properties
296
        
297
        if(data != null){
298
            state.set(FIELD_WIDTH, data.getWidth());
299
            state.set(FIELD_CONTINUITY, data.getContinuity());
300
            state.set(FIELD_SEGMENTS_COLOR, data.getSegmentsColor());
301
            state.set(FIELD_SEGMENTS_LENGTH, data.getSegmentsLength());
302
            state.set(FIELD_HOLES_COLOR, data.getHolesColor());
303
            state.set(FIELD_HOLES_LENGTH, data.getHolesLength());
304
            state.set(FIELD_PAINT_HOLES, data.isPaintHoles());
305
            state.set(FIELD_GAP_WIDTH, data.getGapWidth());
306
            state.set(FIELD_ROUND_VERTEX, data.isRoundVertex());
307
        }
308
        state.set(FIELD_MUST_DRAW_ORIGINAL_GEOMETRY, mustDrawOriginalGeometry);
309
        state.set(FIELD_COLOR_FOR_ORIGINAL_GEOMETRY, colorForOriginalGeometry);
310
        state.set(FIELD_TRANSPARENCY, this.getTransparency());
311
    }
312

  
313
    @Override
314
    public void getPixExtentPlus(Geometry geom, float[] distances, ViewPort viewPort, int dpi) {
315
        float cs = (float) getCartographicSize(viewPort, dpi, geom);
316
        // TODO and add the line offset
317
        distances[0] = cs;
318
        distances[1] = cs;
319
    }
320

  
321
    @Override
322
    public int getSymbolType() {
323
        return Geometry.TYPES.CURVE;
324
    }
325

  
326
    @Override
327
    public boolean isSuitableFor(Geometry geom) {
328
        return geom.getGeometryType().isTypeOf(Geometry.TYPES.CURVE);
329
    }
330

  
331
    @Override
332
    public Color getColor() {
333
        return this.colorForOriginalGeometry;
334
    }
335

  
336
    @Override
337
    public void setColor(Color color) {
338
        this.colorForOriginalGeometry = color;
339
    }
340

  
341
    @Override
342
    public void print(Graphics2D g, AffineTransform at, Geometry shape, PrintAttributes properties) {
343
        draw(g, at, shape, null, null);
344
//		double originalSize = getLineWidth();
345
//		double size=originalSize;
346
//		// scale it to size
347
//		int pq = properties.getPrintQuality();
348
//		if (pq == PrintAttributes.PRINT_QUALITY_NORMAL){
349
//			size *= (double) 300/72;
350
//		}else if (pq == PrintAttributes.PRINT_QUALITY_HIGH){
351
//			size *= (double) 600/72;
352
//		}else if (pq == PrintAttributes.PRINT_QUALITY_DRAFT){
353
//			// size *= 72/72; // (which is the same than doing nothing)
354
//		}
355
//		setLineWidth(size);
356
//		draw(g,at,geom,null, null);
357
//		setLineWidth(originalSize);
358
    }
359

  
360
    @Override
361
    public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
362
        double oldSize = getData().getWidth();
363
        setCartographicSize(getCartographicSize(
364
                viewPort,
365
                dpi,
366
                geom),
367
                geom);
368
        return oldSize;
369

  
370
//        return 0;
371
    }
372

  
373
    @Override
374
    public void setCartographicSize(double cartographicSize, Geometry geom) {
375
        //DO NOTHING
376
        this.getData().setWidth(cartographicSize);
377
    }
378

  
379
    @Override
380
    public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
381
        return CartographicSupportToolkit.getCartographicLength(
382
                this,
383
                getData().getWidth(),
384
                viewPort,
385
                dpi
386
        );
387

  
388
//        return 0;
389
    }
390

  
391
//    public static class RegisterPersistence implements Callable {
392
//
393
//        @Override
394
//        public Object call() throws Exception {
395
//            PersistenceManager manager = ToolsLocator.getPersistenceManager();
396
//            if (manager.getDefinition(URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
397
//                DynStruct definition = manager.addDefinition(
398
//                        UrbanHorizontalSignageSymbol.class,
399
//                        URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME,
400
//                        URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME + " Persistence definition",
401
//                        null,
402
//                        null
403
//                );
404
//                // Extend the LineSymbol base definition
405
//                definition.extend(manager.getDefinition(AbstractSymbol.SYMBOL_PERSISTENCE_DEFINITION_NAME));
406
//                
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff