svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libGeocoding / src / org / gvsig / geocoding / geommatches / SimpleLineMatcher.java @ 27057
History | View | Annotate | Download (7.33 KB)
1 |
/* gvSIG. Geographic Information System of the Valencian Government
|
---|---|
2 |
*
|
3 |
* Copyright (C) 2007-2008 Infrastructures and Transports Department
|
4 |
* of the Valencian Government (CIT)
|
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 |
*/
|
22 |
|
23 |
/*
|
24 |
* AUTHORS (In addition to CIT):
|
25 |
* 2008 Prodevelop S.L main development
|
26 |
*/
|
27 |
|
28 |
package org.gvsig.geocoding.geommatches; |
29 |
|
30 |
import java.awt.geom.PathIterator; |
31 |
import java.util.ArrayList; |
32 |
import java.util.HashMap; |
33 |
import java.util.Iterator; |
34 |
import java.util.List; |
35 |
import java.util.Map; |
36 |
|
37 |
import org.gvsig.fmap.dal.feature.Feature; |
38 |
import org.gvsig.fmap.geom.Geometry; |
39 |
import org.gvsig.fmap.geom.primitive.Curve2D; |
40 |
import org.gvsig.fmap.geom.primitive.Point2D; |
41 |
import org.gvsig.fmap.geom.util.UtilFunctions; |
42 |
|
43 |
import com.vividsolutions.jts.geom.Coordinate; |
44 |
import com.vividsolutions.jts.linearref.LengthIndexedLine; |
45 |
|
46 |
/**
|
47 |
*
|
48 |
* This class searchs positions over lines (ways)
|
49 |
*
|
50 |
* @author <a href="mailto:jsanz@prodevelop.es"> Jorge Gaspar Sanz Salinas</a>
|
51 |
* @author <a href="mailto:vsanjaime@prodevelop.es"> Vicente Sanjaime Calvet</a>
|
52 |
*
|
53 |
*/
|
54 |
public class SimpleLineMatcher extends GeomMatcher { |
55 |
|
56 |
/**
|
57 |
* This method gets the position over lines (Streets) or next to the lines
|
58 |
*
|
59 |
* @return
|
60 |
*/
|
61 |
@SuppressWarnings("unchecked") |
62 |
public Geometry[] match() { |
63 |
|
64 |
// Group the geometries by one field
|
65 |
HashMap geomstreets1 = groupFeaturesByAttribute(this |
66 |
.getGroupFieldPosition(), (List) this.getFeatures().get(0)); |
67 |
Iterator it = geomstreets1.entrySet().iterator();
|
68 |
Point2D[] points = new Point2D[geomstreets1.size()]; |
69 |
int position = 0; |
70 |
while (it.hasNext()) {
|
71 |
Map.Entry e = (Map.Entry) it.next(); |
72 |
ArrayList geomss = (ArrayList) e.getValue(); |
73 |
// Insert geometries of one street into array
|
74 |
Geometry[] arrGeoms = new Geometry[geomss.size()]; |
75 |
for (int i = 0; i < geomss.size(); i++) { |
76 |
arrGeoms[i] = (Geometry) geomss.get(i); |
77 |
} |
78 |
// Parse geometries to JTS
|
79 |
com.vividsolutions.jts.geom.Geometry[] geomsjts = parseGeomsToJTS(
|
80 |
geomss.get(0).getClass(), arrGeoms);
|
81 |
// Make the UNION of the all geometries with the same attribute
|
82 |
com.vividsolutions.jts.geom.Geometry geomstreetjts = unionLinesJTS(geomsjts); |
83 |
|
84 |
// Get the point of the geometry (LINE)
|
85 |
Point2D point = getLinesPosition(geomstreetjts, getParams());
|
86 |
points[position] = point; |
87 |
position++; |
88 |
} |
89 |
|
90 |
return points;
|
91 |
|
92 |
} |
93 |
|
94 |
/**
|
95 |
* Calculate the position inside sigle line
|
96 |
*
|
97 |
* @param geometryJts
|
98 |
* line of street
|
99 |
* @param params
|
100 |
* Parameters to position the point over the lines
|
101 |
* @return
|
102 |
*/
|
103 |
private Point2D getLinesPosition( |
104 |
com.vividsolutions.jts.geom.Geometry geometryJts, |
105 |
MatchesParams params) { |
106 |
|
107 |
double totaldistance = geometryJts.getLength();
|
108 |
LengthIndexedLine lenline = new LengthIndexedLine(geometryJts);
|
109 |
|
110 |
Long distance = params.getDistance();
|
111 |
Integer relativedist = params.getRelativeDistance();
|
112 |
Double offset = params.getOffset();
|
113 |
|
114 |
Coordinate coors = null;
|
115 |
|
116 |
// first calculate with the distance
|
117 |
if (distance != null) { |
118 |
|
119 |
if (lenline.isValidIndex(distance)) {
|
120 |
coors = lenline.extractPoint(distance); |
121 |
// with offset
|
122 |
if (offset != null && offset.doubleValue() > 0) { |
123 |
return getOffsetPosition(new Point2D(coors.x, coors.y), |
124 |
offset); |
125 |
} |
126 |
// Without offset
|
127 |
else {
|
128 |
return new Point2D(coors.x, coors.y); |
129 |
} |
130 |
} |
131 |
} |
132 |
// Calculate percentage of distance
|
133 |
else if (relativedist != null) { |
134 |
if (totaldistance > 0) { |
135 |
double dist = (relativedist * totaldistance) / 100.0; |
136 |
coors = lenline.extractPoint(dist); |
137 |
// with offset
|
138 |
if (offset != null && offset.doubleValue() > 0) { |
139 |
return getOffsetPosition(new Point2D(coors.x, coors.y), |
140 |
offset); |
141 |
} |
142 |
// Without offset
|
143 |
else {
|
144 |
return new Point2D(coors.x, coors.y); |
145 |
} |
146 |
} |
147 |
} |
148 |
// Any other case
|
149 |
else {
|
150 |
if (totaldistance > 0) { |
151 |
double dist = totaldistance / 2.0; |
152 |
coors = lenline.extractPoint(dist); |
153 |
// with offset
|
154 |
if (offset != null && offset.doubleValue() > 0) { |
155 |
return getOffsetPosition(new Point2D(coors.x, coors.y), |
156 |
offset); |
157 |
} |
158 |
// Without offset
|
159 |
else {
|
160 |
return new Point2D(coors.x, coors.y); |
161 |
} |
162 |
} |
163 |
} |
164 |
return null; |
165 |
} |
166 |
|
167 |
/**
|
168 |
* Calculate the position in the line with offset
|
169 |
*
|
170 |
* @param linePoint
|
171 |
* middle point over the liner
|
172 |
* @param dist
|
173 |
* perpendicular distance since the line
|
174 |
* @return
|
175 |
*/
|
176 |
@SuppressWarnings("unchecked") |
177 |
private Point2D getOffsetPosition(Point2D linePoint, double dist) { |
178 |
|
179 |
List feats = (List) getFeatures().get(0); |
180 |
Geometry[] geoms = new Geometry[feats.size()]; |
181 |
Iterator it = feats.iterator();
|
182 |
int cont = 0; |
183 |
while (it.hasNext()) {
|
184 |
geoms[cont] = (Geometry) ((Feature) it.next()) |
185 |
.getGeometry("GEOMETRY");
|
186 |
cont++; |
187 |
} |
188 |
for (int j = 0; j < geoms.length; j++) { |
189 |
double[] coords = new double[6]; |
190 |
Point2D inicio = null; |
191 |
Point2D fin = null; |
192 |
|
193 |
boolean inter = geoms[j].intersects(linePoint.getBounds2D());
|
194 |
if (inter) {
|
195 |
PathIterator iter = ((Curve2D) geoms[j]).getGeneralPathX()
|
196 |
.getPathIterator(null);
|
197 |
iter.currentSegment(coords); |
198 |
inicio = new Point2D(coords[0], coords[1]); |
199 |
|
200 |
iter.next(); |
201 |
iter.currentSegment(coords); |
202 |
fin = new Point2D(coords[0], coords[1]); |
203 |
|
204 |
log.debug("Return point with offset");
|
205 |
return getPerpendicularPoint(inicio, fin, linePoint, dist);
|
206 |
} |
207 |
|
208 |
} |
209 |
log.debug("Return original point without offset");
|
210 |
return linePoint;
|
211 |
|
212 |
} |
213 |
|
214 |
/**
|
215 |
*
|
216 |
* This method calculates a point perpendicular to the line at a distance
|
217 |
*
|
218 |
* @param inicio
|
219 |
* initial point of the line
|
220 |
* @param fin
|
221 |
* end point of the line
|
222 |
* @param linePoint
|
223 |
* middle point over line
|
224 |
* @param dist
|
225 |
* perpendicular distance to the line
|
226 |
* @return
|
227 |
*/
|
228 |
private Point2D getPerpendicularPoint(Point2D inicio, Point2D fin, |
229 |
Point2D linePoint, double dist) { |
230 |
|
231 |
java.awt.geom.Point2D p1 = new java.awt.geom.Point2D.Double(inicio
|
232 |
.getX(), inicio.getY()); |
233 |
java.awt.geom.Point2D p2 = new java.awt.geom.Point2D.Double(fin.getX(),
|
234 |
fin.getY()); |
235 |
java.awt.geom.Point2D perpPoint = new java.awt.geom.Point2D.Double(
|
236 |
linePoint.getX(), linePoint.getY()); |
237 |
|
238 |
java.awt.geom.Point2D[] p = UtilFunctions.getPerpendicular(p1, p2,
|
239 |
perpPoint); |
240 |
java.awt.geom.Point2D unit = UtilFunctions.getUnitVector(p[0], p[1]); |
241 |
|
242 |
java.awt.geom.Point2D res = new java.awt.geom.Point2D.Double(perpPoint
|
243 |
.getX() |
244 |
+ (unit.getX() * dist), perpPoint.getY() + (unit.getY() * dist)); |
245 |
|
246 |
return new Point2D(res.getX(), res.getY()); |
247 |
} |
248 |
|
249 |
} |