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 |
} |