Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.lib / org.gvsig.vectorediting.lib.prov / org.gvsig.vectorediting.lib.prov.chamfer / src / main / java / org / gvsig / vectorediting / lib / prov / chamfer / SegmentData.java @ 3194

History | View | Annotate | Download (7.11 KB)

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.vectorediting.lib.prov.chamfer;
7

    
8
import java.util.Iterator;
9
import org.gvsig.fmap.dal.feature.Feature;
10
import org.gvsig.fmap.geom.Geometry;
11
import org.gvsig.fmap.geom.GeometryException;
12
import org.gvsig.fmap.geom.GeometryUtils;
13
import org.gvsig.fmap.geom.aggregate.Aggregate;
14
import org.gvsig.fmap.geom.operation.GeometryOperationException;
15
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
16
import org.gvsig.fmap.geom.primitive.Line;
17
import org.gvsig.fmap.geom.primitive.Point;
18
import org.gvsig.fmap.geom.primitive.Polygon;
19
import org.gvsig.fmap.geom.primitive.Primitive;
20

    
21
/**
22
 *
23
 * @author fdiaz
24
 */
25
public class SegmentData {
26
    
27
    public static final int SEGMENT_POSITION_FIRST = 0;
28
    public static final int SEGMENT_POSITION_MIDDLE = 1;
29
    public static final int SEGMENT_POSITION_LAST = 2;
30
    
31
    private Feature feature = null;
32
    //        private Geometry geometry;
33
    //If the geometry is an Aggregate, this is the primitive that contains the projected point, if not, it is the geometry itself
34
    private Primitive primitive = null;
35
    //Projected point on the primitive of the input point
36
    private Point projectedPoint = null;
37
    //Line with only two vertices, represents the segment in which the projected point is located
38
    private Line line = null;
39
    //Index on the primitive of the first vertex of the segment
40
    private Integer idxVertex = null;
41
    //Three possible values: 0 (first), 1 (middle), 2 (last)
42
    //        Integer position;
43

    
44
    public SegmentData(Feature feature, Point inputPoint) {
45
        this.feature = feature;
46
        if (!fill(feature.getDefaultGeometry(), inputPoint)) {
47
            this.primitive = null;
48
            this.projectedPoint = null;
49
            this.line = null;
50
            this.idxVertex = null;
51
        }
52
    }
53

    
54
    public Feature getFeature() {
55
        return this.feature;
56
    }
57

    
58
    public Geometry getGeometry() {
59
        return this.feature.getDefaultGeometry();
60
    }
61

    
62
    public Primitive getPrimitive() {
63
        return this.primitive;
64
    }
65

    
66
    public Point getProjectedPoint() {
67
        return this.projectedPoint;
68
    }
69

    
70
    public Line getLine() {
71
        return this.line;
72
    }
73

    
74
    public Integer getIdxVertex() {
75
        return this.idxVertex;
76
    }
77

    
78
    private boolean fill(Geometry geometry, Point inputPoint) {
79
        //            double distance = Double.POSITIVE_INFINITY;
80
        try {
81
            Iterator<Point> it; // = null;
82
            switch (geometry.getType()) {
83
                case Geometry.TYPES.LINE:
84
                    primitive = (Primitive) geometry;
85
                    break;
86
                case Geometry.TYPES.POLYGON:
87
                    primitive = (Primitive) geometry;
88
                    break;
89
                case Geometry.TYPES.MULTILINE:
90
                case Geometry.TYPES.MULTIPOLYGON:
91
                    Aggregate aggregate = (Aggregate) geometry;
92
                    primitive = getNearestPrimitive(aggregate, inputPoint);
93
                    if (primitive == null) {
94
                        return false;
95
                    }
96
                    break;
97
                default:
98
                    return false;
99
            }
100
            switch (primitive.getType()) {
101
                case Geometry.TYPES.LINE:
102
                    it = ((Line) primitive).iterator();
103
                    break;
104
                case Geometry.TYPES.POLYGON:
105
                    it = ((Polygon) primitive).iterator();
106
                    break;
107
                default:
108
                    return false;
109
            }
110
            projectedPoint = (Point) primitive.toLines().closestPoints(inputPoint)[0];
111
            Integer auxPosition = SEGMENT_POSITION_FIRST;
112
            Line auxLine = null;
113
            Line tmpLine; // = null;
114
            int idx = 0;
115
            if (it != null && it.hasNext()) {
116
                Point prevVertex = it.next().cloneGeometry();
117
                double distance = Double.POSITIVE_INFINITY;
118
                while (it.hasNext()) {
119
                    Point currentVertex = it.next().cloneGeometry();
120
                    tmpLine = GeometryUtils.createLine(prevVertex, currentVertex, geometry.getGeometryType().getSubType());
121
                    double d = tmpLine.distance(projectedPoint);
122
                    if (d < distance) {
123
                        idxVertex = idx;
124
                        distance = d;
125
                        auxLine = tmpLine;
126
                    }
127
                    prevVertex = currentVertex;
128
                    idx++;
129
                }
130
            }
131
            if (idxVertex != null) {
132
                line = auxLine;
133
                return true;
134
            }
135
        } catch (GeometryException | GeometryOperationNotSupportedException | GeometryOperationException ex) {
136
            //TODO:
137
            return false;
138
        }
139
        return false;
140
    }
141

    
142
    private int primitiveNumVertices() {
143
        switch (primitive.getType()) {
144
            case Geometry.TYPES.LINE:
145
                return ((Line) primitive).getNumVertices();
146
            case Geometry.TYPES.POLYGON:
147
                return ((Polygon) primitive).getNumVertices();
148
            default:
149
                return 0;
150
        }
151
    }
152

    
153
    private Primitive getNearestPrimitive(Aggregate aggregate, Point point) throws GeometryOperationNotSupportedException, GeometryOperationException {
154
        if (aggregate == null || point == null) {
155
            throw new IllegalArgumentException("Parameters should not be null");
156
        }
157
        double distance = Double.POSITIVE_INFINITY;
158
        Primitive nearestPrimitive = null;
159
        for (Geometry geometry : aggregate) {
160
            if (geometry instanceof Aggregate) {
161
                return getNearestPrimitive((Aggregate) geometry, point);
162
            }
163
            Primitive prim = (Primitive) geometry;
164
            double d = prim.distance(point);
165
            if (d < distance) {
166
                distance = d;
167
                nearestPrimitive = (Primitive) prim.cloneGeometry();
168
            }
169
        }
170
        return nearestPrimitive;
171
    }
172

    
173
    public Integer getPosition() throws GeometryOperationNotSupportedException, GeometryOperationException {
174
        if (idxVertex != null) {
175
            if (primitive.getType() == Geometry.TYPES.LINE && primitiveNumVertices() == 2) {
176
                if (((Line) primitive).getVertex(0).distance(projectedPoint) <= ((Line) primitive).getVertex(1).distance(projectedPoint)) {
177
                    return SEGMENT_POSITION_LAST;
178
                } else {
179
                    return SEGMENT_POSITION_FIRST;
180
                }
181
            }
182
            if (idxVertex == 0) {
183
                return SEGMENT_POSITION_FIRST;
184
            } else if (idxVertex >= primitiveNumVertices() - 2) {
185
                return SEGMENT_POSITION_LAST;
186
            }
187
            return SEGMENT_POSITION_MIDDLE;
188
        }
189
        return null;
190
    }
191

    
192
    public boolean isFilled() {
193
        return this.feature != null && this.primitive != null && this.projectedPoint != null && this.line != null && this.idxVertex != null;
194
    }
195
    
196
}