Revision 10483

View differences:

org.gvsig.legend.urbanhorizontalsignage/tags/org.gvsig.legend.urbanhorizontalsignage-1.0.107/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 org.gvsig.legend.urbanhorizontalsignage.lib.impl.linelegend.SplittedLine;
4
import java.util.List;
5
import junit.framework.TestCase;
6
import org.gvsig.fmap.geom.GeometryUtils;
7
import org.gvsig.fmap.geom.primitive.Line;
8
import org.gvsig.fmap.geom.primitive.Point;
9
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData;
10
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLocator;
11
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
12
import org.slf4j.Logger;
13
import org.slf4j.LoggerFactory;
14

  
15
public class Test01CalculateGeometries extends TestCase {
16

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

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

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

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

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

  
66
//        data.setWidth(20);
67
//        data.setContinuity(UrbanHorizontalSignageData.DEFAULT_CONTINUITY_VALUE);
68
//        data.setSegmentsLength(100);
69
//        data.setHolesLength(50);
70
//        data.setGapWith(10);
71
//        data.setSegmentsColor(Color.RED);
72
//        data.setHolesColor(Color.BLACK);
73
//        data.setRoundVertex(false);
74
//        data.setPaintHoles(true);
75
        
76
        SplittedLine splittedLine = uhsManager.splitLine(line, 1, 0.5);
77
        
78
        List<Line> segments = splittedLine.getSegments();
79
        List<Line> holes = splittedLine.getHoles();
80
        
81
        assertEquals(7, segments.size());
82
        assertEquals(6, holes.size());
83
        
84
        double x = 0;
85
        for (Line segment : segments) {
86
            assertEquals(x, segment.getVertex(0).getX());
87
            assertEquals(x+1.0, segment.getVertex(1).getX());
88
            x += 1.50;
89
        }
90
        x = 1.0;
91
        for (Line hole : holes) {
92
            assertEquals(x, hole.getVertex(0).getX());
93
            assertEquals(x+0.5, hole.getVertex(1).getX());
94
            x += 1.50;
95
        }
96
    }
97
    
98
    
99
}
org.gvsig.legend.urbanhorizontalsignage/tags/org.gvsig.legend.urbanhorizontalsignage-1.0.107/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 org.gvsig.legend.urbanhorizontalsignage.lib.impl.linelegend.DefaultUrbanHorizontalSignageLegend;
26
import org.gvsig.legend.urbanhorizontalsignage.lib.impl.linelegend.DefaultUrbanHorizontalSignageData;
27
import org.gvsig.legend.urbanhorizontalsignage.lib.impl.linelegend.SplittedLine;
28
import java.io.File;
29
import java.util.Iterator;
30
import java.util.List;
31
import java.util.UUID;
32
import org.apache.commons.lang3.StringUtils;
33
import org.gvsig.fmap.dal.DALLocator;
34
import org.gvsig.fmap.dal.DataManager;
35
import org.gvsig.fmap.dal.DataStoreParameters;
36
import org.gvsig.fmap.dal.exception.DataException;
37
import org.gvsig.fmap.dal.feature.EditableFeature;
38
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
39
import org.gvsig.fmap.dal.feature.EditableFeatureType;
40
import org.gvsig.fmap.dal.feature.Feature;
41
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
42
import org.gvsig.fmap.dal.feature.FeatureSet;
43
import org.gvsig.fmap.dal.feature.FeatureStore;
44
import org.gvsig.fmap.dal.store.jdbc.JDBCNewStoreParameters;
45
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters;
46
import org.gvsig.fmap.dal.store.jdbc2.JDBCServerExplorer;
47
import org.gvsig.fmap.geom.DataTypes;
48
import org.gvsig.fmap.geom.Geometry;
49
import static org.gvsig.fmap.geom.Geometry.JOIN_STYLE_MITRE;
50
import static org.gvsig.fmap.geom.Geometry.JOIN_STYLE_ROUND;
51
import org.gvsig.fmap.geom.GeometryLocator;
52
import org.gvsig.fmap.geom.GeometryManager;
53
import org.gvsig.fmap.geom.GeometryUtils;
54
import org.gvsig.fmap.geom.aggregate.MultiLine;
55
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
56
import org.gvsig.fmap.geom.exception.CreateGeometryException;
57
import org.gvsig.fmap.geom.operation.GeometryOperationException;
58
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
59
import org.gvsig.fmap.geom.primitive.Line;
60
import org.gvsig.fmap.geom.primitive.Point;
61
import org.gvsig.fmap.geom.primitive.Polygon;
62
import org.gvsig.fmap.geom.type.GeometryType;
63
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageConfig;
64
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData;
65
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_CONT;
66
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_CONT_CONT;
67
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_CONT_DISC;
68
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC;
69
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_CONT;
70
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_DISC;
71
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageLegend;
72
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLocator;
73
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageManager;
74
import org.gvsig.tools.ToolsLocator;
75
import org.gvsig.tools.folders.FoldersManager;
76
import org.gvsig.tools.task.SimpleTaskStatus;
77
import org.gvsig.tools.util.HasAFile;
78
import org.slf4j.LoggerFactory;
79

  
80
@SuppressWarnings("UseSpecificCatch")
81
public class DefaultUrbanHorizontalSignageManager implements UrbanHorizontalSignageManager {
82

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

  
85
    @Override
86
    public UrbanHorizontalSignageLegend createUrbanHorizontalSignageLegend() {
87
        return new DefaultUrbanHorizontalSignageLegend();
88
    }
89

  
90
    @Override
91
    public Class<? extends UrbanHorizontalSignageLegend> getUrbanHorizontalSignageLegendClass() {
92
        return DefaultUrbanHorizontalSignageLegend.class;
93
    }
94

  
95
    @Override
96
    public UrbanHorizontalSignageData createUrbanHorizontalSignageData() {
97
        return new DefaultUrbanHorizontalSignageData();
98
    }
99

  
100
    @Override
101
    public void calculateGeometries(Geometry originalGeometry, UrbanHorizontalSignageData data) {
102
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
103
        try {
104
            MultiPolygon segments = geomManager.createMultiPolygon(originalGeometry.getGeometryType().getSubType());
105
            MultiPolygon holes = geomManager.createMultiPolygon(originalGeometry.getGeometryType().getSubType());
106
            MultiLine lineSegments = geomManager.createMultiLine(originalGeometry.getGeometryType().getSubType());
107
            MultiLine lineHoles = geomManager.createMultiLine(originalGeometry.getGeometryType().getSubType());
108
            MultiLine lines = originalGeometry.toLines();
109
            final double offsetValueInMeters = Math.abs(data.getGapWidth() / 2.0 + data.getWidth() / 2.0);
110
            final double bufferValueInMeters = Math.abs(data.getWidth() / 2.0);
111
            for (Geometry geom : lines) {
112
                Line line = (Line) geom;
113
                switch (data.getContinuity()) {
114
                    case CONTINUITY_MODE_CONT:
115
                    default:
116
                        Geometry buffer = line.buffer(
117
                                bufferValueInMeters,
118
                                data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
119
                                true
120
                        );
121
                        if (buffer != null) {
122
                            segments.addPrimitives(buffer);
123
                            lineSegments.addPrimitives(line);
124
                        }
125
                        break;
126

  
127
                    case CONTINUITY_MODE_DISC:
128
                        SplittedLine splittedLine = splitLine(line, data.getSegmentsLength(), data.getHolesLength());
129
                        List<Line> splittedSegments = splittedLine.getSegments();
130
                        List<Line> splittedHoles = splittedLine.getHoles();
131
                        for (Line segment : splittedSegments) {
132
                            buffer = segment.buffer(bufferValueInMeters,
133
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
134
                                    true
135
                            );
136
                            if (buffer != null) {
137
                                segments.addPrimitives(buffer);
138
                                lineSegments.addPrimitives(segment);
139
                            }
140
                        }
141
                        for (Line hole : splittedHoles) {
142
                            buffer = hole.buffer(
143
                                    bufferValueInMeters,
144
                                    data.isRoundVertex() ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE,
145
                                    true
146
                            );
147
                            if (buffer != null) {
148
                                holes.addPrimitives(buffer);
149
                                lineHoles.addPrimitives(hole);
150
                            }
151
                        }
152
                        break;
153

  
154
                    case CONTINUITY_MODE_CONT_CONT:
155
                        //Left
156
                        addOffsetedAndBufferedSegment(segments, lineSegments, line, offsetValueInMeters, bufferValueInMeters, data.isRoundVertex());
157
                        //Right
158
                        addOffsetedAndBufferedSegment(segments, lineSegments, line, -offsetValueInMeters, bufferValueInMeters, data.isRoundVertex());
159
                        break;
160

  
161
                    case CONTINUITY_MODE_CONT_DISC:
162
                        //Left
163
                        addOffsetedAndBufferedSegment(segments, lineSegments, line, offsetValueInMeters, bufferValueInMeters, data.isRoundVertex());
164
                        //Right
165
                        splittedLine = splitLine(line, data.getSegmentsLength(), data.getHolesLength());
166
                        splittedSegments = splittedLine.getSegments();
167
                        splittedHoles = splittedLine.getHoles();
168
                        for (Line segment : splittedSegments) {
169
                            addOffsetedAndBufferedSegment(segments, lineSegments, segment, -offsetValueInMeters, bufferValueInMeters, true);
170
                        }
171
                        for (Line hole : splittedHoles) {
172
                            addOffsetedAndBufferedSegment(holes, lineHoles, hole, -offsetValueInMeters, bufferValueInMeters, true);
173
                        }
174
                        break;
175

  
176
                    case CONTINUITY_MODE_DISC_CONT:
177
                        //Left
178
                        splittedLine = splitLine(line, data.getSegmentsLength(), data.getHolesLength());
179
                        splittedSegments = splittedLine.getSegments();
180
                        splittedHoles = splittedLine.getHoles();
181
                        for (Line segment : splittedSegments) {
182
                            addOffsetedAndBufferedSegment(segments, lineSegments, segment, offsetValueInMeters, bufferValueInMeters, true);
183
                        }
184
                        for (Line hole : splittedHoles) {
185
                            addOffsetedAndBufferedSegment(holes, lineHoles, hole, offsetValueInMeters, bufferValueInMeters, true);
186
                        }
187
                        //Right
188
                        addOffsetedAndBufferedSegment(segments, lineSegments, line, -offsetValueInMeters, bufferValueInMeters, data.isRoundVertex());
189
                        break;
190

  
191
                    case CONTINUITY_MODE_DISC_DISC:
192
                        splittedLine = splitLine(line, data.getSegmentsLength(), data.getHolesLength());
193
                        splittedSegments = splittedLine.getSegments();
194
                        splittedHoles = splittedLine.getHoles();
195
                        //Left
196
                        for (Line segment : splittedSegments) {
197
                            addOffsetedAndBufferedSegment(segments, lineSegments, segment, offsetValueInMeters, bufferValueInMeters, true);
198
                        }
199
                        for (Line hole : splittedHoles) {
200
                            addOffsetedAndBufferedSegment(holes, lineHoles, hole, offsetValueInMeters, bufferValueInMeters, true);
201
                        }
202
                        //Right
203
                        for (Line segment : splittedSegments) {
204
                            addOffsetedAndBufferedSegment(segments, lineSegments, segment, -offsetValueInMeters, bufferValueInMeters, true);
205
                        }
206
                        for (Line hole : splittedHoles) {
207
                            addOffsetedAndBufferedSegment(holes, lineHoles, hole, -offsetValueInMeters, bufferValueInMeters, true);
208
                        }
209
                        break;
210

  
211
                }
212

  
213
            }
214
            data.setSegmentsGeometry(segments);
215
            data.setHolesGeometry(holes);
216
            data.setLineSegmentsGeometry(lineSegments);
217
            data.setLineHolesGeometry(lineHoles);
218
        } catch (Exception ex) {
219
            LOGGER.warn("Can't calculate geometries.", ex);
220
//            Logger.getLogger(DefaultUrbanHorizontalSignageManager.class.getName()).log(Level.SEVERE, null, ex);
221
        }
222

  
223
    }
224

  
225
    protected void addOffsetedAndBufferedSegment(MultiPolygon segments, MultiLine lineSegments, Line segment, final double offsetValueInMeters, final double bufferValueInMeters, boolean roundVertex) throws GeometryOperationException, GeometryOperationNotSupportedException {
226
        Geometry buffer;
227
        final int joinStyle = roundVertex ? JOIN_STYLE_ROUND : JOIN_STYLE_MITRE;
228

  
229
        Geometry segmentOffset;
230
        if (segment.isClosed() && segment.getNumVertices() > 2 && segment.isCCW()) {
231
            Line cloned = segment.cloneGeometry();
232
            cloned.flip();
233
            segmentOffset = cloned.offset(
234
                    joinStyle,
235
                    -offsetValueInMeters
236
            );
237
        } else {
238
            segmentOffset = segment.cloneGeometry().offset(
239
                    joinStyle,
240
                    offsetValueInMeters
241
            );
242
        }
243
        if (segmentOffset == null) {
244
            return;
245
        }
246
        buffer = segmentOffset.buffer(bufferValueInMeters, joinStyle,
247
                true
248
        );
249
        if (buffer != null) {
250
            segments.addPrimitives(buffer);
251
            lineSegments.addPrimitives(segmentOffset);
252
        }
253
    }
254

  
255
    /*
256
        segmentLength & holesLenght in meters
257
     */
258
 /*friend*/
259
    SplittedLine splitLine(Line line, double segmentLength, double holesLength) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException, CloneNotSupportedException {
260
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
261
        SplittedLine res = new SplittedLine();
262

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

  
336
        if (currentSegment.getNumVertices() > 1) {
337
            if (isHole) {
338
                res.addHole(currentSegment.cloneGeometry());
339
            } else {
340
                res.addSegment(currentSegment.cloneGeometry());
341
            }
342
        }
343

  
344
        return res;
345
    }
346

  
347
    /**
348
     * @deprecated
349
     * use {@link GeometryUtils.calculateLambdaPoint}
350
     * 
351
     * @param p1
352
     * @param p2
353
     * @param lambda
354
     * @return
355
     * @throws CreateGeometryException
356
     * @throws GeometryOperationNotSupportedException
357
     * @throws GeometryOperationException
358
     * @deprecated
359
     */
360
    @Deprecated 
361
    Point calculateIntermediatePoint(Point p1, Point p2, double lambda) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
362
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
363
        GeometryType geomType = p1.getGeometryType();
364
        int subtype = geomType.getSubType();
365
        int dimension = geomType.getDimension();
366
        double[] coords = new double[dimension];
367
        Point p = geomManager.createPoint(0, 0, subtype);
368
        double distance = p1.distance(p2);
369
        for (int d = 0; d < dimension; d++) {
370
            p.setCoordinateAt(
371
                    d,
372
                    p1.getCoordinateAt(d) + (p2.getCoordinateAt(d) - p1.getCoordinateAt(d)) * lambda);
373
        }
374

  
375
        return p;
376
    }
377

  
378
    @Override
379
    public FeatureStore createTemporaryPolygonsFromLines(UrbanHorizontalSignageConfig config, FeatureSet lines, SimpleTaskStatus status) {
380

  
381
        //TODO: el status....
382
        UrbanHorizontalSignageManager uhsManager = UrbanHorizontalSignageLocator.getUrbanHorizontalSignageManager();
383
        EditableFeatureType targetFeatureType = createTargetFeatureType(lines.getFeatureStore());
384
        FeatureStore targetStore = createTemporalStore(targetFeatureType);
385
        try {
386
            targetStore.edit(FeatureStore.MODE_APPEND);
387

  
388
            for (Feature feature : lines) {
389

  
390
                Geometry originalGeometry = feature.getDefaultGeometry();
391

  
392
                UrbanHorizontalSignageData data = config.getValues(feature);
393

  
394
                uhsManager.calculateGeometries(originalGeometry, data);
395

  
396
                MultiPolygon multiGeom = data.getSegmentsGeometry();
397
                MultiLine multiLine = data.getLineSegmentsGeometry();
398
                insertPolygonsOfLine(multiGeom, multiLine, targetStore, feature, config, config.getSegmentsColorFieldName());
399

  
400
                switch (data.getContinuity()) {
401
                    case CONTINUITY_MODE_CONT_DISC:
402
                    case CONTINUITY_MODE_DISC_CONT:
403
                    case CONTINUITY_MODE_DISC:
404
                    case CONTINUITY_MODE_DISC_DISC:
405
                        if (data.isPaintHoles()) {
406
                            multiGeom = data.getHolesGeometry();
407
                            multiLine = data.getLineHolesGeometry();
408
                            insertPolygonsOfLine(multiGeom, multiLine, targetStore, feature, config, config.getHolesColorFieldName());
409
                        }
410
                }
411

  
412
            }
413

  
414
            targetStore.finishEditing();
415
            return targetStore;
416

  
417
        } catch (Exception e) {
418
            LOGGER.debug("Can't create temporary polygons store.", e);
419
        }
420

  
421
        return null;
422
    }
423

  
424
    private void insertPolygonsOfLine(MultiPolygon multiGeom, MultiLine multiLine, FeatureStore targetStore, Feature feature, UrbanHorizontalSignageConfig config, String colorFieldName) throws GeometryOperationNotSupportedException, GeometryOperationException, DataException {
425
        if (multiGeom != null && multiGeom.getPrimitivesNumber() > 0) {
426
            for (int i = 0; i < multiGeom.getPrimitivesNumber(); i++) {
427
                Polygon polygon = (Polygon) multiGeom.getPrimitiveAt(i);
428
                Line line = (Line) multiLine.getPrimitiveAt(i);
429
                EditableFeature targetFeature = targetStore.createNewFeature();
430
                targetFeature.copyFrom(feature, (FeatureAttributeDescriptor t) -> !(t.isPrimaryKey() || (t.isIndexed() && !t.allowIndexDuplicateds()) || t.getType() == DataTypes.GEOMETRY));
431

  
432
                if (StringUtils.isNotBlank(config.getTargetColorFieldName())) {
433
                    targetFeature.set(config.getTargetColorFieldName(), feature.get(colorFieldName));
434
                }
435

  
436
                if (StringUtils.isNotBlank(config.getTargetLenghtFieldName())) {
437
                    targetFeature.set(config.getTargetLenghtFieldName(), line.perimeter());
438
                }
439

  
440
                if (StringUtils.isNotBlank(config.getTargetAreaFieldName())) {
441
                    targetFeature.set(config.getTargetAreaFieldName(), polygon.area());
442
                }
443

  
444
                targetFeature.setDefaultGeometry(polygon);
445
                targetStore.insert(targetFeature);
446
            }
447
        }
448
    }
449

  
450
    private EditableFeatureType createTargetFeatureType(FeatureStore store) {
451
        DataManager dataManager = DALLocator.getDataManager();
452

  
453
        EditableFeatureType featureType = dataManager.createFeatureType();
454
        featureType.addAll(store.getDefaultFeatureTypeQuietly());
455
        for (FeatureAttributeDescriptor attr : featureType) {
456
            EditableFeatureAttributeDescriptor eattr = (EditableFeatureAttributeDescriptor) attr;
457
            eattr.setIsPrimaryKey(false);
458
            eattr.setIsIndexed(false);
459
            eattr.setAllowNull(true);
460
        }
461

  
462
        EditableFeatureAttributeDescriptor attr = (EditableFeatureAttributeDescriptor) featureType.getDefaultGeometryAttribute();
463
        attr.setGeometryType(Geometry.TYPES.POLYGON, Geometry.SUBTYPES.GEOM2D);
464

  
465
        return featureType;
466
    }
467

  
468
    private FeatureStore createTemporalStore(EditableFeatureType featType) {
469
        if (featType.getStore() != null) {
470
            throw new IllegalArgumentException("Can't create temporal store from a feature type of a already existent store.");
471
        }
472
        try {
473
            // crear ruta de archivo temporal
474
            FoldersManager foldersManager = ToolsLocator.getFoldersManager();
475
            File tempFile = foldersManager.getUniqueTemporaryFile("urbanHorizontalSignage_temporal_store_" + UUID.randomUUID().toString());
476

  
477
            // crear SERVER STORE
478
            DataManager dataManager = DALLocator.getDataManager();
479
            JDBCServerExplorerParameters serverParameters = (JDBCServerExplorerParameters) dataManager.createServerExplorerParameters("H2Spatial");
480
            ((HasAFile) serverParameters).setFile(tempFile);
481
            JDBCServerExplorer serverExplorer = (JDBCServerExplorer) dataManager.openServerExplorer("H2Spatial", serverParameters);
482

  
483
            //Crear tablas en server store
484
            JDBCNewStoreParameters parametersResults = serverExplorer.getAddParameters();
485
            parametersResults.setDynValue("Table", "results");
486

  
487
            parametersResults.setDefaultFeatureType(featType);
488
            serverExplorer.add("H2Spatial", parametersResults, true);
489

  
490
            DataStoreParameters storeParametersResults = dataManager.createStoreParameters("H2Spatial");
491
            storeParametersResults.setDynValue("database_file", tempFile);
492
            storeParametersResults.setDynValue("Table", "results");
493

  
494
            //Creaci?n del store con los resultados
495
            FeatureStore storeResults = (FeatureStore) dataManager.openStore("H2Spatial", storeParametersResults);
496

  
497
            return storeResults;
498
        } catch (Exception ex) {
499
            LOGGER.debug("Can't create temporal store.", ex);
500
            return null;
501
        }
502
    }
503

  
504
    @Override
505
    public void convertLinesToPolygons(
506
            UrbanHorizontalSignageConfig config,
507
            FeatureSet source,
508
            FeatureStore targetStore,
509
            boolean deleteSourceAtFinish,
510
            SimpleTaskStatus status
511
    ) {
512

  
513
        boolean needFinishEditing = !(targetStore.isEditing() || targetStore.isAppending());
514
        try {
515
            if (needFinishEditing) {
516
                targetStore.edit();
517
            }
518
            for (Feature feature : source) {
519
                Geometry geom = feature.getDefaultGeometry();
520
                UrbanHorizontalSignageData data = config.getValues(feature);
521
                calculateGeometries(geom, data);
522

  
523
                MultiPolygon multiGeom = data.getSegmentsGeometry();
524
                MultiLine multiLine = data.getLineSegmentsGeometry();
525
                insertPolygonsOfLine(multiGeom, multiLine, targetStore, feature, config, config.getSegmentsColorFieldName());
526

  
527
                switch (data.getContinuity()) {
528
                    case CONTINUITY_MODE_CONT_DISC:
529
                    case CONTINUITY_MODE_DISC_CONT:
530
                    case CONTINUITY_MODE_DISC:
531
                    case CONTINUITY_MODE_DISC_DISC:
532
                        if (data.isPaintHoles()) {
533
                            multiGeom = data.getHolesGeometry();
534
                            multiLine = data.getLineHolesGeometry();
535
                            insertPolygonsOfLine(multiGeom, multiLine, targetStore, feature, config, config.getHolesColorFieldName());
536
                        }
537
                }
538
            }
539
            if (needFinishEditing) {
540
                targetStore.finishEditing();
541
            }
542

  
543
        } catch (Exception ex) {
544
            FeatureStore.cancelEditingQuietly(targetStore);
545
            throw new RuntimeException("Can't convert lines to polygons\n"+ex.getLocalizedMessage(), ex);
546
        }
547
        if (deleteSourceAtFinish) {
548
            FeatureStore sourceStore = null;
549
            try {
550
                sourceStore = source.getFeatureStore();
551
                needFinishEditing = !(sourceStore.isEditing() || sourceStore.isAppending());
552
                if (needFinishEditing) {
553
                    sourceStore.edit();
554
                }
555
                for (Feature feature : source) {
556
                    source.delete(feature);
557
                }
558
                if (needFinishEditing) {
559
                    sourceStore.finishEditing();
560
                }
561
            } catch (Exception ex) {
562
                FeatureStore.cancelEditingQuietly(sourceStore);
563
                throw new RuntimeException("Can't delete source lines", ex);
564
            }
565
        }
566
    }
567
    
568
}
org.gvsig.legend.urbanhorizontalsignage/tags/org.gvsig.legend.urbanhorizontalsignage-1.0.107/org.gvsig.legend.urbanhorizontalsignage.lib/org.gvsig.legend.urbanhorizontalsignage.lib.impl/src/main/java/org/gvsig/legend/urbanhorizontalsignage/lib/impl/UrbanHorizontalSignageLibraryImpl.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2015 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 2
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

  
25
package org.gvsig.legend.urbanhorizontalsignage.lib.impl;
26

  
27
import org.gvsig.legend.urbanhorizontalsignage.lib.impl.linelegend.DefaultUrbanHorizontalSignageLegend;
28
import org.gvsig.legend.urbanhorizontalsignage.lib.impl.linelegend.UrbanHorizontalSignageSymbol;
29
import org.gvsig.legend.urbanhorizontalsignage.lib.impl.linelegend.DefaultUrbanHorizontalSignageConfig;
30
import java.io.InputStream;
31
import java.util.Map;
32
import org.gvsig.fmap.mapcontext.MapContextLibrary;
33
import org.gvsig.fmap.mapcontext.MapContextLocator;
34
import org.gvsig.fmap.mapcontext.MapContextManager;
35
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLibrary;
36
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLocator;
37
import org.gvsig.symbology.impl.SymbologyDefaultImplLibrary;
38
import org.gvsig.tools.ToolsLocator;
39
import org.gvsig.tools.dynobject.DynStruct;
40
import org.gvsig.tools.library.AbstractLibrary;
41
import org.gvsig.tools.library.LibraryException;
42
import org.gvsig.tools.persistence.PersistenceManager;
43

  
44
public class UrbanHorizontalSignageLibraryImpl extends AbstractLibrary {
45

  
46
    @Override
47
    public void doRegistration() {
48
        registerAsImplementationOf(UrbanHorizontalSignageLibrary.class);
49
        this.require(MapContextLibrary.class);
50
        this.require(SymbologyDefaultImplLibrary.class);
51
    }
52

  
53
    @Override
54
    protected void doInitialize() throws LibraryException {
55
        UrbanHorizontalSignageLocator.registerUrbanHorizontalSignageManager(DefaultUrbanHorizontalSignageManager.class);
56
        MapContextManager mcmanager = MapContextLocator.getMapContextManager();
57
        mcmanager.registerLegend("UrbanHorizontalSignageLegend", DefaultUrbanHorizontalSignageLegend.class);
58
    }
59

  
60
    @Override
61
    protected void doPostInitialize() throws LibraryException {
62
        PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
63
        InputStream is = this.getClass().getResourceAsStream("UrbanHorizontalSignagePersistence.xml");
64
        Map<String,DynStruct> definitions;
65
        try {
66
            definitions = ToolsLocator.getDynObjectManager().importDynClassDefinitions(is, this.getClass().getClassLoader());
67
        } catch (Exception ex) {
68
            throw new LibraryException(this.getClass(), ex);
69
        }
70
        
71
        persistenceManager.addDefinition(
72
                DefaultUrbanHorizontalSignageLegend.class,
73
                "DefaultUrbanHorizontalSignageLegend",
74
                definitions,
75
                null,
76
                null);
77
        persistenceManager.addDefinition(
78
                UrbanHorizontalSignageSymbol.class,
79
                "UrbanHorizontalSignageSymbol",
80
                definitions,
81
                null,
82
                null
83
        );
84
        persistenceManager.addDefinition(
85
                DefaultUrbanHorizontalSignageConfig.class,
86
                "DefaultUrbanHorizontalSignageConfig",
87
                definitions,
88
                null,
89
                null
90
        );
91
    }
92

  
93
}
org.gvsig.legend.urbanhorizontalsignage/tags/org.gvsig.legend.urbanhorizontalsignage-1.0.107/org.gvsig.legend.urbanhorizontalsignage.lib/org.gvsig.legend.urbanhorizontalsignage.lib.impl/src/main/java/org/gvsig/legend/urbanhorizontalsignage/lib/impl/linelegend/SplittedLine.java
1
package org.gvsig.legend.urbanhorizontalsignage.lib.impl.linelegend;
2

  
3
import java.util.ArrayList;
4
import java.util.List;
5
import org.gvsig.fmap.geom.primitive.Line;
6

  
7
/**
8
 *
9
 * @author gvSIG Team
10
 */
11
public class SplittedLine {
12
    
13
    List<Line> segments;
14
    List<Line> holes;
15

  
16
    public SplittedLine() {
17
        segments = new ArrayList<>();
18
        holes = new ArrayList<>();
19
    }
20

  
21
    public List<Line> getSegments() {
22
        return this.segments;
23
    }
24

  
25
    public List<Line> getHoles() {
26
        return this.holes;
27
    }
28

  
29
    public void addSegment(Line segment) {
30
        this.segments.add(segment);
31
    }
32

  
33
    public void addHole(Line hole) {
34
        this.holes.add(hole);
35
    }
36
    
37
}
org.gvsig.legend.urbanhorizontalsignage/tags/org.gvsig.legend.urbanhorizontalsignage-1.0.107/org.gvsig.legend.urbanhorizontalsignage.lib/org.gvsig.legend.urbanhorizontalsignage.lib.impl/src/main/java/org/gvsig/legend/urbanhorizontalsignage/lib/impl/linelegend/DefaultUrbanHorizontalSignageLegend.java
1
package org.gvsig.legend.urbanhorizontalsignage.lib.impl.linelegend;
2

  
3
import java.awt.Image;
4
import java.util.ArrayList;
5
import java.util.List;
6
import org.apache.commons.lang3.StringUtils;
7
import org.gvsig.fmap.dal.exception.DataException;
8
import org.gvsig.fmap.dal.feature.Feature;
9
import org.gvsig.fmap.dal.feature.FeatureStore;
10
import org.gvsig.fmap.geom.Geometry;
11
import org.gvsig.fmap.geom.GeometryUtils;
12
import org.gvsig.fmap.mapcontext.MapContextException;
13
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
14
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageConfig;
15
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData;
16
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageLegend;
17
import org.gvsig.symbology.SymbologyLocator;
18
import org.gvsig.symbology.SymbologyManager;
19
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.impl.AbstractVectorialLegend;
20
import org.gvsig.tools.persistence.PersistentState;
21
import org.gvsig.tools.persistence.exception.PersistenceException;
22
import org.slf4j.Logger;
23
import org.slf4j.LoggerFactory;
24

  
25
public class DefaultUrbanHorizontalSignageLegend 
26
        extends AbstractVectorialLegend 
27
        implements UrbanHorizontalSignageLegend //, IHasImageLegend 
28
{
29
    
30
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultUrbanHorizontalSignageLegend.class);
31

  
32
    private final UrbanHorizontalSignageSymbol defaultSymbol;
33
    
34
    private UrbanHorizontalSignageConfig config;
35
    
36
    private Image imageLegend;
37
    
38
    public DefaultUrbanHorizontalSignageLegend() {
39
        
40
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
41
        this.defaultSymbol = new UrbanHorizontalSignageSymbol();
42
        DefaultUrbanHorizontalSignageData data = new DefaultUrbanHorizontalSignageData();
43
        data.setContinuity(UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_CONT);
44
        this.defaultSymbol.setData(new DefaultUrbanHorizontalSignageData());
45
        
46
        this.config = new DefaultUrbanHorizontalSignageConfig();
47
    }
48

  
49
    @Override
50
    public ISymbol getDefaultSymbol() {
51
        return this.defaultSymbol;
52
    }
53

  
54
    @Override
55
    public void setDefaultSymbol(ISymbol is) {
56
        //DO NOTHING
57
    }
58

  
59
    @Override
60
    public ISymbol getSymbolByFeature(Feature ftr) throws MapContextException {
61

  
62
        UrbanHorizontalSignageData values = this.getConfig().getValues(ftr);
63

  
64
        UrbanHorizontalSignageSymbol symbol = new UrbanHorizontalSignageSymbol();
65
        symbol.setData(values);
66
        return symbol;
67
    }
68

  
69
    @Override
70
    public int getShapeType() {
71
        return Geometry.TYPES.CURVE;
72
    }
73

  
74
    @Override
75
    public void setShapeType(int i) {
76
    }
77

  
78
    @Override
79
    public boolean isUseDefaultSymbol() {
80
        return true;
81
    }
82

  
83
    @Override
84
    public void useDefaultSymbol(boolean bln) {
85
    }
86

  
87
    @Override
88
    public boolean isSuitableForShapeType(int shapeType) {
89
        return (GeometryUtils.isSubtype(Geometry.TYPES.CURVE, shapeType) ||  
90
            GeometryUtils.isSubtype(Geometry.TYPES.MULTICURVE, shapeType));
91
    }
92

  
93
    @Override
94
    public void loadFromState(PersistentState state) throws PersistenceException {
95
//        this.defaultSymbol = new SimpleTextSymbol();
96
        this.imageLegend = null;
97

  
98
        super.loadFromState(state);
99
        this.config = (UrbanHorizontalSignageConfig) state.get("config");
100
        if(this.config == null){
101
            this.config = new DefaultUrbanHorizontalSignageConfig();
102
        }
103
    }
104

  
105
    @Override
106
    public void saveToState(PersistentState state) throws PersistenceException {
107
        super.saveToState(state);
108
        state.set("config", this.getConfig());
109
    }
110

  
111
    @Override
112
    protected String[] getRequiredFeatureAttributeNames(FeatureStore fs) throws DataException {
113
        List<String> names = new ArrayList<>(10);
114
        UrbanHorizontalSignageConfig theConfig = this.getConfig();
115
        
116
        String name = theConfig.getWidthFieldName();
117
        if( StringUtils.isNotBlank(name) ) {
118
            names.add(name);
119
        }
120
        name = theConfig.getContinuityFieldName();
121
        if( StringUtils.isNotBlank(name) ) {
122
            names.add(name);
123
        }
124
        name = theConfig.getHolesLengthFieldName();
125
        if( StringUtils.isNotBlank(name) ) {
126
            names.add(name);
127
        }
128
        name = theConfig.getHolesColorFieldName();
129
        if( StringUtils.isNotBlank(name) ) {
130
            names.add(name);
131
        }
132
        name = theConfig.getPaintHolesFieldName();
133
        if( StringUtils.isNotBlank(name) ) {
134
            names.add(name);
135
        }
136
        name = theConfig.getPaintHolesFieldName();
137
        if( StringUtils.isNotBlank(name) ) {
138
            names.add(name);
139
        }
140
        name = theConfig.getSegmentsLengthFieldName();
141
        if( StringUtils.isNotBlank(name) ) {
142
            names.add(name);
143
        }
144
        name = theConfig.getSegmentsColorFieldName();
145
        if( StringUtils.isNotBlank(name) ) {
146
            names.add(name);
147
        }
148
        name = theConfig.getRoundVertexFieldName();
149
        if( StringUtils.isNotBlank(name) ) {
150
            names.add(name);
151
        }
152
        name = fs.getDefaultFeatureType().getDefaultGeometryAttributeName();
153
        if( StringUtils.isNotBlank(name) ) {
154
            names.add(name);
155
        }
156
        return names.toArray(new String[names.size()]);
157
    }
158

  
159
    @Override
160
    public UrbanHorizontalSignageConfig getConfig() {
161
        return config;
162
    }
163
    
164
}
org.gvsig.legend.urbanhorizontalsignage/tags/org.gvsig.legend.urbanhorizontalsignage-1.0.107/org.gvsig.legend.urbanhorizontalsignage.lib/org.gvsig.legend.urbanhorizontalsignage.lib.impl/src/main/java/org/gvsig/legend/urbanhorizontalsignage/lib/impl/linelegend/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.linelegend;
25

  
26
import java.awt.Color;
27
import java.awt.Graphics2D;
28
import java.awt.Rectangle;
29
import java.awt.Shape;
30
import java.awt.geom.AffineTransform;
31
import java.util.concurrent.Callable;
32
import org.gvsig.fmap.dal.feature.Feature;
33
import org.gvsig.fmap.geom.Geometry;
34
import org.gvsig.fmap.geom.GeometryUtils;
35
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
36
import org.gvsig.fmap.geom.primitive.Envelope;
37
import org.gvsig.fmap.geom.primitive.Line;
38
import org.gvsig.fmap.geom.primitive.Point;
39
import org.gvsig.fmap.mapcontext.MapContext;
40
import org.gvsig.fmap.mapcontext.MapContextLocator;
41
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
42
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol_v2;
43
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
44
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLocator;
45
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageManager;
46
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData;
47
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_CONT_DISC;
48
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC;
49
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_CONT;
50
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_DISC;
51
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.AbstractSymbol;
52
import org.gvsig.tools.persistence.PersistentState;
53
import org.gvsig.tools.persistence.exception.PersistenceException;
54
import org.gvsig.tools.swing.api.TransparencySupport;
55
import org.gvsig.tools.task.Cancellable;
56
import org.slf4j.Logger;
57
import org.slf4j.LoggerFactory;
58

  
59
public class UrbanHorizontalSignageSymbol extends AbstractSymbol implements ISymbol_v2, TransparencySupport {
60

  
61
    private static final Logger LOG = LoggerFactory.getLogger(UrbanHorizontalSignageSymbol.class);
62
    private static final String SYMBOL_NAME = "UrbanHorizontalSignageSymbol";
63
    private static final String URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME = "UrbanHorizontalSignageSymbol";
64
    
65
    private static final String FIELD_WIDTH = "width";
66
    private static final String FIELD_CONTINUITY = "continuity";
67
    private static final String FIELD_SEGMENTS_COLOR = "segmentsColor";
68
    private static final String FIELD_SEGMENTS_LENGTH = "segmentsLength";
69
    private static final String FIELD_HOLES_COLOR = "holesColor";
70
    private static final String FIELD_HOLES_LENGTH = "holesLength";
71
    private static final String FIELD_PAINT_HOLES = "paintHoles";
72
    private static final String FIELD_GAP_WIDTH = "gapWidth";
73
    private static final String FIELD_ROUND_VERTEX = "roundVertex";
74
    private static final String FIELD_SEGMENTS_GEOMETRY = "segmentsGeometry";
75
    private static final String FIELD_HOLES_GEOMETRY = "holesGeometry";
76
    private static final String FIELD_TRANSPARENCY = "transparency";
77
    private static final String FIELD_MUST_DRAW_ORIGINAL_GEOMETRY = "mustDrawOriginalGeometry";
78
    private static final String FIELD_COLOR_FOR_ORIGINAL_GEOMETRY = "colorForOriginalGeometry";
79

  
80
    
81

  
82
//    private static final String FIELD_SYMBOL_FOR_SELECTION = "symbolForSelection";
83
    private UrbanHorizontalSignageData data;
84

  
85
    transient private UrbanHorizontalSignageSymbol symbolForSelection;
86
    
87
    private boolean mustDrawOriginalGeometry;
88
    private Color colorForOriginalGeometry;
89
    private double cartographicSize;
90
    private double transparency; //[0.0, 1.0]
91

  
92
    public UrbanHorizontalSignageSymbol() {
93
        super();
94
        this.mustDrawOriginalGeometry = false;
95
        this.transparency = 1.0;
96
    }
97

  
98
    public void setData(UrbanHorizontalSignageData data) {
99
        this.data = data;
100
    }
101

  
102
    public UrbanHorizontalSignageData getData() {
103
        return data;
104
    }
105

  
106
    /**
107
     * Sets the transparency for symbol. The valid values are in [0.0, 1.0]
108
     * 
109
     * @param transparency 
110
     */
111
    @Override
112
    public void setTransparency(double transparency) {
113
        if(transparency < 0 || transparency > 1.0){
114
            throw new IllegalArgumentException("Transparency value must be in [0.0, 1.0] ("+transparency+")");
115
        }
116
        this.transparency = transparency;
117
    }
118

  
119
    @Override
120
    public double getTransparency() {
121
        return transparency;
122
    }
123
    
124
    @Override
125
    public ISymbol getSymbolForSelection(Color selectionColor) {
126
        if (symbolForSelection == null) {
127
            symbolForSelection = (UrbanHorizontalSignageSymbol) cloneForSelection();
128
            symbolForSelection.mustDrawOriginalGeometry = true;
129
        }
130
        symbolForSelection.setColor(selectionColor);
131
        return symbolForSelection;
132
    }
133

  
134
    protected Geometry getSampleGeometry(Rectangle r) {
135
        final int hGap = (int) (r.getWidth() * 0.1); // the left and right margins
136
        final int vPos = 1; 						 // the top and bottom margins
137
        final int splitCount = 3; 					 // number of lines
138
        final int splitHSize = (r.width - hGap - hGap) / splitCount;
139
        int hPos = hGap;
140
        boolean swap = false;
141

  
142
        Line geom = GeometryUtils.createLine(Geometry.SUBTYPES.GEOM2D);
143
        geom.addVertex(r.x + hPos, r.y + r.height - vPos);
144

  
145
        for (int i = 0; i < splitCount; i++) {
146
            swap = !swap;
147
            geom.addVertex(r.x + hPos + splitHSize, (swap ? vPos : r.height - vPos) + r.y);
148
            hPos += splitHSize;
149
        }
150
        return geom;
151
    }
152
    
153

  
154
    @Override
155
    public void draw(Graphics2D g, AffineTransform affineTransform,
156
            Geometry originalGeometry, Feature feature, Cancellable cancel, Rectangle r) {
157
        if(r != null){
158
            originalGeometry = getSampleGeometry(r);
159
        }
160
        if (true) {
161
            // Esto deberia ser para optimizar el pintado de 
162
            // geometrias grandes.
163
            try {
164
                Geometry env = originalGeometry.getEnvelope().getGeometry();
165
                env.transform(affineTransform);
166
                Envelope env2 = env.getEnvelope();
167
                if (env2.getLength(0) < 1.5 && env2.getLength(1) < 1.5) {
168
                    Color color = data.getSegmentsColor();
169
                    Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)(transparency*color.getAlpha()));
170
                    g.setColor(transparentColor);
171
                    Point upperCorner = env2.getUpperCorner();
172
                    int x = (int) upperCorner.getX();
173
                    int y = (int) upperCorner.getY();
174
                    g.drawLine(x, y, x, y);
175
                    return;
176
                }
177
            } catch (Exception ex) {
178
                LOG.warn("Error optimizing the drawing of the geometry. Continues with normal drawing.", ex);
179
                // Do nothing, continue with the draw of the original geometry
180
            }
181
        }
182

  
183
        UrbanHorizontalSignageManager uhsManager = UrbanHorizontalSignageLocator.getUrbanHorizontalSignageManager();
184
        uhsManager.calculateGeometries(originalGeometry, data);
185
        
186
        MultiPolygon geom = data.getSegmentsGeometry();
187
        if (geom != null && geom.getPrimitivesNumber() > 0) {
188
            Color color = data.getSegmentsColor();
189
            Shape shape = geom.getShape(affineTransform);
190
            Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)(transparency*color.getAlpha()));
191
            g.setColor(transparentColor);
192
            g.fill(shape);
193
            g.setColor(color.darker());
194
            g.draw(shape);
195
        }
196

  
197
        switch (data.getContinuity()) {
198
            case CONTINUITY_MODE_CONT_DISC:
199
            case CONTINUITY_MODE_DISC_CONT:
200
            case CONTINUITY_MODE_DISC:
201
            case CONTINUITY_MODE_DISC_DISC:
202
                if (data.isPaintHoles()) {
203
                    geom = data.getHolesGeometry();
204
                    if (geom != null && geom.getPrimitivesNumber() > 0) {
205
                        Color color = data.getHolesColor();
206
                        Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)(transparency*color.getAlpha()));
207
                        g.setColor(transparentColor);
208
                        g.fill(geom.getShape(affineTransform));
209
                    }
210
                }
211
        }
212

  
213
        //For debug purposse only
214
        if(mustDrawOriginalGeometry){
215
            g.setColor(getColor());
216
            g.draw(originalGeometry.getShape(affineTransform));
217
        }
218

  
219
    }
220

  
221
    @Override
222
    public Object clone() throws CloneNotSupportedException {
223
        UrbanHorizontalSignageSymbol copy = (UrbanHorizontalSignageSymbol) super.clone();
224

  
225
        if (symbolForSelection != null) {
226
            copy.symbolForSelection = (UrbanHorizontalSignageSymbol) symbolForSelection
227
                    .clone();
228
        }
229

  
230
        return copy;
231
    }
232

  
233
    @Override
234
    public void loadFromState(PersistentState state) throws PersistenceException {
235
        // Set parent style properties
236
        super.loadFromState(state);
237
        
238
        UrbanHorizontalSignageData theData = new DefaultUrbanHorizontalSignageData();
239
        theData.setWidth(state.getDouble(FIELD_WIDTH, UrbanHorizontalSignageData.DEFAULT_WIDTH_VALUE));
240
        theData.setContinuity(state.getInt(FIELD_CONTINUITY, UrbanHorizontalSignageData.DEFAULT_CONTINUITY_VALUE));
241
        
242
        Color color = (Color) state.get(FIELD_SEGMENTS_COLOR);
243
        theData.setSegmentsColor(color != null ? color : UrbanHorizontalSignageData.DEFAULT_SEGMENT_COLOR_VALUE);
244
        
245
        theData.setSegmentsLength(state.getDouble(FIELD_SEGMENTS_LENGTH, UrbanHorizontalSignageData.DEFAULT_SEGMENT_LENGTH_VALUE));
246
        
247
        color = (Color) state.get(FIELD_HOLES_COLOR);
248
        theData.setHolesColor(color != null ? color : UrbanHorizontalSignageData.DEFAULT_HOLES_COLOR_VALUE);
249
        
250
        theData.setHolesLength(state.getDouble(FIELD_HOLES_LENGTH, UrbanHorizontalSignageData.DEFAULT_HOLES_LENGTH_VALUE));
251
        theData.setGapWidth(state.getDouble(FIELD_GAP_WIDTH, UrbanHorizontalSignageData.DEFAULT_GAP_WIDTH_VALUE));
252
        theData.setRoundVertex(state.getBoolean(FIELD_ROUND_VERTEX, UrbanHorizontalSignageData.DEFAULT_ROUND_VERTEX_VALUE));
253
        
254
        this.transparency = state.getDouble(FIELD_TRANSPARENCY, 1.0);
255
        this.mustDrawOriginalGeometry = state.getBoolean(FIELD_MUST_DRAW_ORIGINAL_GEOMETRY, false);
256
        color = (Color) state.get(FIELD_COLOR_FOR_ORIGINAL_GEOMETRY);
257
        this.colorForOriginalGeometry = color != null ? color : MapContext.DEFAULT_SELECTION_COLOR;
258
        this.data = theData;
259

  
260
    }
261

  
262
    @Override
263
    public void saveToState(PersistentState state) throws PersistenceException {
264
        // Save parent fill symbol properties
265
        super.saveToState(state);
266

  
267
        // Save own properties
268
        
269
        if(data != null){
270
            state.set(FIELD_WIDTH, data.getWidth());
271
            state.set(FIELD_CONTINUITY, data.getContinuity());
272
            state.set(FIELD_SEGMENTS_COLOR, data.getSegmentsColor());
273
            state.set(FIELD_SEGMENTS_LENGTH, data.getSegmentsLength());
274
            state.set(FIELD_HOLES_COLOR, data.getHolesColor());
275
            state.set(FIELD_HOLES_LENGTH, data.getHolesLength());
276
            state.set(FIELD_PAINT_HOLES, data.isPaintHoles());
277
            state.set(FIELD_GAP_WIDTH, data.getGapWidth());
278
            state.set(FIELD_ROUND_VERTEX, data.isRoundVertex());
279
        }
280
        state.set(FIELD_MUST_DRAW_ORIGINAL_GEOMETRY, mustDrawOriginalGeometry);
281
        state.set(FIELD_COLOR_FOR_ORIGINAL_GEOMETRY, colorForOriginalGeometry);
282
        state.set(FIELD_TRANSPARENCY, this.getTransparency());
283
    }
284

  
285
    @Override
286
    public int getSymbolType() {
287
        return Geometry.TYPES.CURVE;
288
    }
289

  
290
    @Override
291
    public boolean isSuitableFor(Geometry geom) {
292
        return geom.getGeometryType().isTypeOf(Geometry.TYPES.CURVE);
293
    }
294

  
295
    @Override
296
    public Color getColor() {
297
        return this.colorForOriginalGeometry;
298
    }
299

  
300
    @Override
301
    public void setColor(Color color) {
302
        this.colorForOriginalGeometry = color;
303
    }
304

  
305
//    public static class RegisterPersistence implements Callable {
306
//
307
//        @Override
308
//        public Object call() throws Exception {
309
//            PersistenceManager manager = ToolsLocator.getPersistenceManager();
310
//            if (manager.getDefinition(URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
311
//                DynStruct definition = manager.addDefinition(
312
//                        UrbanHorizontalSignageSymbol.class,
313
//                        URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME,
314
//                        URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME + " Persistence definition",
315
//                        null,
316
//                        null
317
//                );
318
//                // Extend the LineSymbol base definition
319
//                definition.extend(manager.getDefinition(AbstractSymbol.SYMBOL_PERSISTENCE_DEFINITION_NAME));
320
//                
321
//                definition.addDynFieldDouble(FIELD_WIDTH).setMandatory(false);
322
//                definition.addDynFieldInt(FIELD_CONTINUITY).setMandatory(false);
323
//                definition.addDynFieldObject(FIELD_SEGMENTS_COLOR).setClassOfValue(Color.class).setMandatory(false);
324
//                definition.addDynFieldDouble(FIELD_SEGMENTS_LENGTH).setMandatory(false);
325
//                definition.addDynFieldObject(FIELD_HOLES_COLOR).setClassOfValue(Color.class).setMandatory(false);
326
//                definition.addDynFieldDouble(FIELD_HOLES_LENGTH).setMandatory(false);
327
//                definition.addDynFieldBoolean(FIELD_PAINT_HOLES).setMandatory(false);
328
//                definition.addDynFieldDouble(FIELD_GAP_WIDTH).setMandatory(false);
329
//                definition.addDynFieldBoolean(FIELD_ROUND_VERTEX).setMandatory(false);
330
//                definition.addDynFieldDouble(FIELD_TRANSPARENCY).setMandatory(false);
331
//                definition.addDynFieldBoolean(FIELD_MUST_DRAW_ORIGINAL_GEOMETRY).setMandatory(false);
332
//                definition.addDynFieldObject(FIELD_COLOR_FOR_ORIGINAL_GEOMETRY).setClassOfValue(Color.class).setMandatory(false);
333
//            }
334
//            return Boolean.TRUE;
335
//        }
336
//
337
//    }
338

  
339
    public static class RegisterSymbol implements Callable {
340

  
341
        @Override
342
        public Object call() throws Exception {
343
            int[] shapeTypes;
344
            SymbolManager manager = MapContextLocator.getSymbolManager();
345

  
346
            shapeTypes = new int[]{Geometry.TYPES.CURVE, Geometry.TYPES.ARC,
347
                Geometry.TYPES.MULTICURVE, Geometry.TYPES.CIRCUMFERENCE,
348
                Geometry.TYPES.PERIELLIPSE, Geometry.TYPES.SPLINE,
349
                Geometry.TYPES.LINE, Geometry.TYPES.MULTILINE};
350
            manager.registerSymbol(SYMBOL_NAME,
351
                    shapeTypes,
352
                    UrbanHorizontalSignageSymbol.class);
353

  
354
            return Boolean.TRUE;
355
        }
356

  
357
    }
358

  
359
}
org.gvsig.legend.urbanhorizontalsignage/tags/org.gvsig.legend.urbanhorizontalsignage-1.0.107/org.gvsig.legend.urbanhorizontalsignage.lib/org.gvsig.legend.urbanhorizontalsignage.lib.impl/src/main/java/org/gvsig/legend/urbanhorizontalsignage/lib/impl/linelegend/DefaultUrbanHorizontalSignageConfig.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.linelegend;
7

  
8
import java.awt.Color;
9
import org.gvsig.fmap.dal.feature.Feature;
10
import org.gvsig.fmap.dal.feature.FeatureType;
11
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageConfig;
12
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageConfig.DEFAULT_GAP_WIDTH_VALUE;
13
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData;
14
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.DEFAULT_CONTINUITY_VALUE;
15
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.DEFAULT_HOLES_COLOR_VALUE;
16
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.DEFAULT_HOLES_LENGTH_VALUE;
17
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.DEFAULT_PAINT_HOLES_VALUE;
18
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.DEFAULT_ROUND_VERTEX_VALUE;
19
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.DEFAULT_SEGMENT_COLOR_VALUE;
20
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.DEFAULT_SEGMENT_LENGTH_VALUE;
21
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.DEFAULT_WIDTH_VALUE;
22
import org.gvsig.tools.ToolsLocator;
23
import org.gvsig.tools.dataTypes.DataTypesManager;
24
import org.gvsig.tools.persistence.PersistentState;
25
import org.gvsig.tools.persistence.exception.PersistenceException;
26
import org.gvsig.tools.swing.api.DataTypes;
27
import org.slf4j.Logger;
28
import org.slf4j.LoggerFactory;
29

  
30
/**
31
 *
32
 * @author fdiaz
33
 */
34
public class DefaultUrbanHorizontalSignageConfig implements UrbanHorizontalSignageConfig {
35

  
36
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultUrbanHorizontalSignageConfig.class);
37

  
38
    private String widthFieldName;
39
    private String continuityFieldName;
40
    private String holesLengthFieldName;
41
    private String holesColorFieldName;
42
    private String paintHolesFieldName;
43
    private String segmentsLengthFieldName;
44
    private String segmentsColorFieldName;
45
    private String roundVertexFieldName;
46
    private int gapWidth;
47
    private String targetColorFieldName;
48
    private String targetLenghtFieldName;
49
    private String targetAreaFieldName;
50
    
51
    public DefaultUrbanHorizontalSignageConfig() {
52
        this.gapWidth = DEFAULT_GAP_WIDTH_VALUE;
53
    }
54

  
55
    @Override
56
    public void loadFromState(PersistentState state) throws PersistenceException {
57

  
58
        this.widthFieldName = state.getString("widthFieldName");
59
        this.continuityFieldName = state.getString("continuityFieldName");
60
        this.holesLengthFieldName = state.getString("holesLengthFieldName");
61
        this.holesColorFieldName = state.getString("holesColorFieldName");
62
        this.paintHolesFieldName = state.getString("paintHolesFieldName");
63
        this.segmentsLengthFieldName = state.getString("segmentsLengthFieldName");
64
        this.segmentsColorFieldName = state.getString("segmentsColorFieldName");
65
        this.roundVertexFieldName = state.getString("roundVertexFieldName");
66
        this.gapWidth = state.getInt("gapWidth", DEFAULT_GAP_WIDTH_VALUE);
67
    }
68

  
69
    @Override
70
    public void saveToState(PersistentState state) throws PersistenceException {
71
        state.set("widthFieldName", this.widthFieldName);
72
        state.set("continuityFieldName", this.continuityFieldName);
73
        state.set("holesLengthFieldName", this.holesLengthFieldName);
74
        state.set("holesColorFieldName", this.holesColorFieldName);
75
        state.set("paintHolesFieldName", this.paintHolesFieldName);
76
        state.set("segmentsLengthFieldName", this.segmentsLengthFieldName);
77
        state.set("segmentsColorFieldName", this.segmentsColorFieldName);
78
        state.set("roundVertexFieldName", this.roundVertexFieldName);
79
        state.set("gapWidth", this.gapWidth);
80
    }
81

  
82
    @Override
83
    public String getWidthFieldName() {
84
        return this.widthFieldName;
85
    }
86

  
87
    @Override
88
    public void setWidthFieldName(String fieldName) {
89
        this.widthFieldName = fieldName;
90
    }
91

  
92
    @Override
93
    public String getContinuityFieldName() {
94
        return this.continuityFieldName;
95
    }
96

  
97
    @Override
98
    public void setContinuityFieldName(String fieldName) {
99
        this.continuityFieldName = fieldName;
100
    }
101

  
102
    @Override
103
    public String getSegmentsColorFieldName() {
104
        return this.segmentsColorFieldName;
105
    }
106

  
107
    @Override
108
    public void setSegmentsColorFieldName(String fieldName) {
109
        this.segmentsColorFieldName = fieldName;
110
    }
111

  
112
    @Override
113
    public String getSegmentsLengthFieldName() {
114
        return this.segmentsLengthFieldName;
115
    }
116

  
117
    @Override
118
    public void setSegmentsLengthFieldName(String fieldName) {
119
        this.segmentsLengthFieldName = fieldName;
120
    }
121

  
122
    @Override
123
    public String getPaintHolesFieldName() {
124
        return this.paintHolesFieldName;
125
    }
126

  
127
    @Override
128
    public void setPaintHolesFieldName(String fieldName) {
129
        this.paintHolesFieldName = fieldName;
130
    }
131

  
132
    @Override
133
    public String getHolesColorFieldName() {
134
        return this.holesColorFieldName;
135
    }
136

  
137
    @Override
138
    public void setHolesColorFieldName(String fieldName) {
139
        this.holesColorFieldName = fieldName;
140
    }
141

  
142
    @Override
143
    public String getHolesLengthFieldName() {
144
        return this.holesLengthFieldName;
145
    }
146

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

Also available in: Unified diff