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 | 3194 | fdiaz | /*
|
---|---|---|---|
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 | } |