Revision 9227

View differences:

org.gvsig.legend.urbanhorizontalsignage/tags/org.gvsig.legend.urbanhorizontalsignage-1.0.83/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.83/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.83/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.83/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.83/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.compat.print.PrintAttributes;
33
import org.gvsig.fmap.dal.feature.Feature;
34
import org.gvsig.fmap.geom.Geometry;
35
import org.gvsig.fmap.geom.GeometryLocator;
36
import org.gvsig.fmap.geom.GeometryManager;
37
import org.gvsig.fmap.geom.GeometryUtils;
38
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
39
import org.gvsig.fmap.geom.primitive.Envelope;
40
import org.gvsig.fmap.geom.primitive.Line;
41
import org.gvsig.fmap.geom.primitive.Point;
42
import org.gvsig.fmap.mapcontext.MapContext;
43
import org.gvsig.fmap.mapcontext.MapContextLocator;
44
import org.gvsig.fmap.mapcontext.ViewPort;
45
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
46
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol_v2;
47
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
48
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
49
import org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData;
50
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_CONT_DISC;
51
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC;
52
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_CONT;
53
import static org.gvsig.legend.urbanhorizontalsignage.lib.api.linelegend.UrbanHorizontalSignageData.CONTINUITY_MODE_DISC_DISC;
54
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageLocator;
55
import org.gvsig.legend.urbanhorizontalsignage.lib.api.UrbanHorizontalSignageManager;
56
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.AbstractSymbol;
57
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl.CartographicSupportToolkit;
58
import org.gvsig.tools.persistence.PersistentState;
59
import org.gvsig.tools.persistence.exception.PersistenceException;
60
import org.gvsig.tools.swing.api.TransparencySupport;
61
import org.gvsig.tools.task.Cancellable;
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

  
65
public class UrbanHorizontalSignageSymbol extends AbstractSymbol implements ISymbol_v2, TransparencySupport {
66

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

  
87

  
88
//    private static final String FIELD_SYMBOL_FOR_SELECTION = "symbolForSelection";
89
    private UrbanHorizontalSignageData data;
90

  
91
    transient private UrbanHorizontalSignageSymbol symbolForSelection;
92
    
93
    private boolean mustDrawOriginalGeometry;
94
    private Color colorForOriginalGeometry;
95
    private double cartographicSize;
96
    private double transparency; //[0.0, 1.0]
97

  
98
    public UrbanHorizontalSignageSymbol() {
99
        super();
100
        this.mustDrawOriginalGeometry = false;
101
        this.transparency = 1.0;
102
    }
103

  
104
    public void setData(UrbanHorizontalSignageData data) {
105
        this.data = data;
106
    }
107

  
108
    public UrbanHorizontalSignageData getData() {
109
        return data;
110
    }
111

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

  
125
    @Override
126
    public double getTransparency() {
127
        return transparency;
128
    }
129
    
130
    @Override
131
    public ISymbol getSymbolForSelection() {
132
        if (symbolForSelection == null) {
133
            symbolForSelection = (UrbanHorizontalSignageSymbol) cloneForSelection();
134
            symbolForSelection.mustDrawOriginalGeometry = true;
135
        } else {
136
            symbolForSelection.setColor(MapContext.getSelectionColor());
137
        }
138
        return symbolForSelection;
139
    }
140

  
141
    @Override
142
    public void draw(Graphics2D g, AffineTransform affineTransform,
143
            Geometry originalGeometry, Feature feature, Cancellable cancel) {
144
        
145
        if (true) {
146
            // Esto deberia ser para optimizar el pintado de 
147
            // geometrias grandes.
148
            try {
149
                Geometry env = originalGeometry.getEnvelope().getGeometry();
150
                env.transform(affineTransform);
151
                Envelope env2 = env.getEnvelope();
152
                if (env2.getLength(0) < 1.5 && env2.getLength(1) < 1.5) {
153
                    Color color = data.getSegmentsColor();
154
                    Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)(transparency*color.getAlpha()));
155
                    g.setColor(transparentColor);
156
                    Point upperCorner = env2.getUpperCorner();
157
                    int x = (int) upperCorner.getX();
158
                    int y = (int) upperCorner.getY();
159
                    g.drawLine(x, y, x, y);
160
                    return;
161
                }
162
            } catch (Exception ex) {
163
                LOG.warn("Error optimizing the drawing of the geometry. Continues with normal drawing.", ex);
164
                // Do nothing, continue with the draw of the original geometry
165
            }
166
        }
167

  
168
        UrbanHorizontalSignageManager uhsManager = UrbanHorizontalSignageLocator.getUrbanHorizontalSignageManager();
169
        uhsManager.calculateGeometries(originalGeometry, data);
170
        
171
        MultiPolygon geom = data.getSegmentsGeometry();
172
        if (geom != null && geom.getPrimitivesNumber() > 0) {
173
            Color color = data.getSegmentsColor();
174
            Shape shape = geom.getShape(affineTransform);
175
            Color transparentColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), (int)(transparency*color.getAlpha()));
176
            g.setColor(transparentColor);
177
            g.fill(shape);
178
            g.setColor(color.darker());
179
            g.draw(shape);
180
        }
181

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

  
198
        //For debug purposse only
199
        if(mustDrawOriginalGeometry){
200
            g.setColor(getColor());
201
            g.draw(originalGeometry.getShape(affineTransform));
202
        }
203

  
204
    }
205

  
206
    @Override
207
    public int getOnePointRgb() {
208
        return data.getSegmentsColor().getRGB();
209
    }
210

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

  
224
        Line geom = GeometryUtils.createLine(Geometry.SUBTYPES.GEOM2D);
225
        geom.addVertex(r.x + hPos, r.y + r.height - vPos);
226

  
227
        for (int i = 0; i < splitCount; i++) {
228
            swap = !swap;
229
            geom.addVertex(r.x + hPos + splitHSize, (swap ? vPos : r.height - vPos) + r.y);
230
            hPos += splitHSize;
231
        }
232

  
233
        try {
234
            if (properties == null) {
235
                draw(g, new AffineTransform(), geom, null, null);
236
            } else {
237
                print(g, new AffineTransform(), geom, properties);
238
            }
239
        } catch (Exception e) {
240
            throw new SymbolDrawingException(SymbolDrawingException.UNSUPPORTED_SET_OF_SETTINGS);
241
        }
242

  
243
    }
244

  
245
    @Override
246
    public Object clone() throws CloneNotSupportedException {
247
        UrbanHorizontalSignageSymbol copy = (UrbanHorizontalSignageSymbol) super.clone();
248

  
249
        if (symbolForSelection != null) {
250
            copy.symbolForSelection = (UrbanHorizontalSignageSymbol) symbolForSelection
251
                    .clone();
252
        }
253

  
254
        return copy;
255
    }
256

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

  
284
    }
285

  
286
    @Override
287
    public void saveToState(PersistentState state) throws PersistenceException {
288
        // Save parent fill symbol properties
289
        super.saveToState(state);
290

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

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

  
317
    @Override
318
    public int getSymbolType() {
319
        return Geometry.TYPES.CURVE;
320
    }
321

  
322
    @Override
323
    public boolean isSuitableFor(Geometry geom) {
324
        return geom.getGeometryType().isTypeOf(Geometry.TYPES.CURVE);
325
    }
326

  
327
    @Override
328
    public Color getColor() {
329
        return this.colorForOriginalGeometry;
330
    }
331

  
332
    @Override
333
    public void setColor(Color color) {
334
        this.colorForOriginalGeometry = color;
335
    }
336

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

  
356
    @Override
357
    public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
358
        double oldSize = getData().getWidth();
359
        setCartographicSize(getCartographicSize(
360
                viewPort,
361
                dpi,
362
                geom),
363
                geom);
364
        return oldSize;
365

  
366
//        return 0;
367
    }
368

  
369
    @Override
370
    public void setCartographicSize(double cartographicSize, Geometry geom) {
371
        //DO NOTHING
372
        this.getData().setWidth(cartographicSize);
373
    }
374

  
375
    @Override
376
    public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
377
        return CartographicSupportToolkit.getCartographicLength(
378
                this,
379
                getData().getWidth(),
380
                viewPort,
381
                dpi
382
        );
383

  
384
//        return 0;
385
    }
386

  
387
//    public static class RegisterPersistence implements Callable {
388
//
389
//        @Override
390
//        public Object call() throws Exception {
391
//            PersistenceManager manager = ToolsLocator.getPersistenceManager();
392
//            if (manager.getDefinition(URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME) == null) {
393
//                DynStruct definition = manager.addDefinition(
394
//                        UrbanHorizontalSignageSymbol.class,
395
//                        URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME,
396
//                        URBAN_HORIZONTAL_SIGNAGE_SYMBOL_PERSISTENCE_DEFINITION_NAME + " Persistence definition",
397
//                        null,
398
//                        null
399
//                );
400
//                // Extend the LineSymbol base definition
401
//                definition.extend(manager.getDefinition(AbstractSymbol.SYMBOL_PERSISTENCE_DEFINITION_NAME));
402
//                
403
//                definition.addDynFieldDouble(FIELD_WIDTH).setMandatory(false);
404
//                definition.addDynFieldInt(FIELD_CONTINUITY).setMandatory(false);
405
//                definition.addDynFieldObject(FIELD_SEGMENTS_COLOR).setClassOfValue(Color.class).setMandatory(false);
406
//                definition.addDynFieldDouble(FIELD_SEGMENTS_LENGTH).setMandatory(false);
407
//                definition.addDynFieldObject(FIELD_HOLES_COLOR).setClassOfValue(Color.class).setMandatory(false);
408
//                definition.addDynFieldDouble(FIELD_HOLES_LENGTH).setMandatory(false);
409
//                definition.addDynFieldBoolean(FIELD_PAINT_HOLES).setMandatory(false);
410
//                definition.addDynFieldDouble(FIELD_GAP_WIDTH).setMandatory(false);
411
//                definition.addDynFieldBoolean(FIELD_ROUND_VERTEX).setMandatory(false);
412
//                definition.addDynFieldDouble(FIELD_TRANSPARENCY).setMandatory(false);
413
//                definition.addDynFieldBoolean(FIELD_MUST_DRAW_ORIGINAL_GEOMETRY).setMandatory(false);
414
//                definition.addDynFieldObject(FIELD_COLOR_FOR_ORIGINAL_GEOMETRY).setClassOfValue(Color.class).setMandatory(false);
415
//            }
416
//            return Boolean.TRUE;
417
//        }
418
//
419
//    }
420

  
421
    public static class RegisterSymbol implements Callable {
422

  
423
        @Override
424
        public Object call() throws Exception {
425
            int[] shapeTypes;
426
            SymbolManager manager = MapContextLocator.getSymbolManager();
427

  
428
            shapeTypes = new int[]{Geometry.TYPES.CURVE, Geometry.TYPES.ARC,
429
                Geometry.TYPES.MULTICURVE, Geometry.TYPES.CIRCUMFERENCE,
430
                Geometry.TYPES.PERIELLIPSE, Geometry.TYPES.SPLINE,
431
                Geometry.TYPES.LINE, Geometry.TYPES.MULTILINE};
432
            manager.registerSymbol(SYMBOL_NAME,
433
                    shapeTypes,
434
                    UrbanHorizontalSignageSymbol.class);
435

  
436
            return Boolean.TRUE;
437
        }
438

  
439
    }
440

  
441
}
org.gvsig.legend.urbanhorizontalsignage/tags/org.gvsig.legend.urbanhorizontalsignage-1.0.83/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

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

Also available in: Unified diff