Revision 33 org.gvsig.lrs/trunk/org.gvsig.lrs/org.gvsig.lrs.lib/org.gvsig.lrs.lib.impl/src/main/java/org/gvsig/lrs/lib/impl/LrsCreateRouteAlgorithm.java
LrsCreateRouteAlgorithm.java | ||
---|---|---|
24 | 24 |
|
25 | 25 |
import java.util.ArrayList; |
26 | 26 |
import java.util.Collections; |
27 |
import java.util.Comparator; |
|
28 |
import java.util.HashMap; |
|
27 |
import java.util.Iterator; |
|
29 | 28 |
import java.util.List; |
30 |
import java.util.Map; |
|
31 | 29 |
import java.util.Map.Entry; |
32 | 30 |
import java.util.SortedMap; |
33 | 31 |
import java.util.TreeMap; |
34 | 32 |
|
35 | 33 |
import org.apache.commons.lang3.mutable.MutableInt; |
34 |
import org.slf4j.Logger; |
|
35 |
import org.slf4j.LoggerFactory; |
|
36 |
|
|
36 | 37 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
37 | 38 |
import org.gvsig.fmap.dal.feature.Feature; |
38 | 39 |
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
39 |
import org.gvsig.fmap.dal.feature.FeatureReference; |
|
40 |
import org.gvsig.fmap.dal.feature.FeatureSelection; |
|
41 | 40 |
import org.gvsig.fmap.dal.feature.FeatureSet; |
42 | 41 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
43 | 42 |
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters; |
... | ... | |
69 | 68 |
import org.gvsig.tools.task.SimpleTaskStatus; |
70 | 69 |
import org.gvsig.tools.visitor.VisitCanceledException; |
71 | 70 |
import org.gvsig.tools.visitor.Visitor; |
72 |
import org.omg.CosNaming.IstringHelper; |
|
73 |
import org.slf4j.Logger; |
|
74 |
import org.slf4j.LoggerFactory; |
|
75 | 71 |
|
76 | 72 |
/** |
77 | 73 |
* @author fdiaz |
... | ... | |
79 | 75 |
*/ |
80 | 76 |
public class LrsCreateRouteAlgorithm implements LrsAlgorithm { |
81 | 77 |
|
82 |
private static final Logger logger = |
|
83 |
LoggerFactory.getLogger(LrsCreateRouteAlgorithm.class); |
|
78 |
private static final Logger logger = LoggerFactory.getLogger(LrsCreateRouteAlgorithm.class); |
|
84 | 79 |
|
85 | 80 |
private LrsCreateRouteAlgorithmParams parameters; |
86 | 81 |
|
... | ... | |
117 | 112 |
* SimpleTaskStatus) |
118 | 113 |
*/ |
119 | 114 |
public void execute(SimpleTaskStatus taskStatus) throws LrsException { |
120 |
NewFeatureStoreParameters newFeatureStoreParameters = |
|
121 |
parameters.getNewFeatureStoreParameters(); |
|
115 |
NewFeatureStoreParameters newFeatureStoreParameters = parameters.getNewFeatureStoreParameters(); |
|
122 | 116 |
FeatureStore sourceFeatureStore = parameters.getSourceFeatureStore(); |
123 | 117 |
FeatureAttributeDescriptor idRouteField = parameters.getIdRouteField(); |
124 |
// LrsCoordinatesPriority coordinatePriority = |
|
125 |
// parameters.getCoordinatePriority(); |
|
126 |
// LrsSourceOfMeasures sourceOfMeasures = |
|
127 |
// parameters.getSourceOfMeasures(); |
|
128 |
FeatureAttributeDescriptor fromMeasureField = |
|
129 |
parameters.getFromMeasureField(); |
|
130 |
FeatureAttributeDescriptor toMeasureField = |
|
131 |
parameters.getToMeasureField(); |
|
132 |
// double measureFactor = parameters.getMeasureFactor(); |
|
133 |
// double measureOffset = parameters.getMeasureOffset(); |
|
134 |
// boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps(); |
|
118 |
FeatureAttributeDescriptor fromMeasureField = parameters.getFromMeasureField(); |
|
119 |
FeatureAttributeDescriptor toMeasureField = parameters.getToMeasureField(); |
|
135 | 120 |
|
136 | 121 |
logger.info(parameters.toString()); |
137 | 122 |
|
... | ... | |
160 | 145 |
toDataType = null; |
161 | 146 |
} |
162 | 147 |
|
163 |
FeatureStore newFeatureStore = LrsAlgorithmUtils
|
|
164 |
.createNewDataStore(newFeatureStoreParameters, idRouteField); |
|
148 |
FeatureStore newFeatureStore = |
|
149 |
LrsAlgorithmUtils.createNewDataStore(newFeatureStoreParameters, idRouteField);
|
|
165 | 150 |
|
166 | 151 |
FeatureSet sourceFeatures; |
167 | 152 |
if (sourceFeatureStore.getFeatureSelection().getSize() > 0) { |
... | ... | |
170 | 155 |
sourceFeatures = sourceFeatureStore.getFeatureSet(); |
171 | 156 |
} |
172 | 157 |
|
173 |
final SortedMap<String, List<MStructure>> featuresMap = |
|
174 |
new TreeMap<String, List<MStructure>>(); |
|
175 |
final MutableInt contId=new MutableInt(0); |
|
158 |
final SortedMap<String, List<MSegment>> featuresMap = new TreeMap<String, List<MSegment>>(); |
|
159 |
final MutableInt contId = new MutableInt(0); |
|
176 | 160 |
sourceFeatures.accept(new Visitor() { |
177 | 161 |
|
178 |
public void visit(Object obj) |
|
179 |
throws VisitCanceledException, BaseException { |
|
162 |
public void visit(Object obj) throws VisitCanceledException, BaseException { |
|
180 | 163 |
Feature feature = (Feature) obj; |
181 | 164 |
String routeName = (String) feature.get(routeFieldName); |
182 |
Geometry originalGeometry = feature.getDefaultGeometry(); |
|
183 | 165 |
Object objFrom = null; |
184 | 166 |
Object objTo = null; |
185 | 167 |
if (fromFieldName != null) { |
... | ... | |
189 | 171 |
objTo = feature.get(toFieldName); |
190 | 172 |
} |
191 | 173 |
if (!featuresMap.containsKey(routeName)) { |
192 |
featuresMap.put(routeName, new ArrayList<MStructure>());
|
|
174 |
featuresMap.put(routeName, new ArrayList<MSegment>());
|
|
193 | 175 |
} |
194 |
List<MStructure> mList = featuresMap.get(routeName); |
|
195 |
MStructure mStructure = new MStructure(); |
|
196 |
mStructure.geometry = originalGeometry; |
|
197 |
mStructure.fromField = |
|
198 |
LrsAlgorithmUtils.getAsDouble(objFrom, fromDataType); |
|
199 |
mStructure.toField = |
|
200 |
LrsAlgorithmUtils.getAsDouble(objTo, toDataType); |
|
201 |
mStructure.id=contId.getValue(); |
|
176 |
List<MSegment> mList = featuresMap.get(routeName); |
|
177 |
MSegment mSegment = new MSegment(); |
|
178 |
mSegment.geometry = feature.getDefaultGeometry().cloneGeometry(); |
|
179 |
mSegment.fromValue = LrsAlgorithmUtils.getAsDouble(objFrom, fromDataType); |
|
180 |
mSegment.toValue = LrsAlgorithmUtils.getAsDouble(objTo, toDataType); |
|
181 |
mSegment.id = contId.getValue(); |
|
202 | 182 |
contId.increment(); |
203 |
mList.add(mStructure);
|
|
183 |
mList.add(mSegment);
|
|
204 | 184 |
featuresMap.put(routeName, mList); |
205 | 185 |
} |
206 | 186 |
}); |
187 |
|
|
207 | 188 |
taskStatus.setRangeOfValues(0, featuresMap.size()); |
208 | 189 |
int taskCount = 0; |
209 | 190 |
|
210 | 191 |
newFeatureStore.edit(FeatureStore.MODE_FULLEDIT); |
211 | 192 |
|
212 |
// TODO Added to facilitate Tests. Remove afterwards |
|
213 |
StringBuffer resultDebug = new StringBuffer(); |
|
214 |
LrsSourceOfMeasures sourceOfMeasures = |
|
215 |
parameters.getSourceOfMeasures(); |
|
216 |
boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps(); |
|
217 |
LrsCoordinatesPriority coordinatePriority = |
|
218 |
parameters.getCoordinatePriority(); |
|
219 |
|
|
220 |
resultDebug.append(sourceOfMeasures.getName()); |
|
221 |
if (!sourceOfMeasures.equals(LrsSourceOfMeasures.TWO_FIELDS)) { |
|
222 |
if (ignoreSpatialGaps) |
|
223 |
resultDebug.append(" WITHOUT GAPS "); |
|
224 |
else |
|
225 |
resultDebug.append(" WITH GAPS "); |
|
226 |
resultDebug.append(coordinatePriority.getName()); |
|
227 |
} |
|
228 |
// END of Test addition |
|
229 |
|
|
230 |
for (Entry<String, List<MStructure>> entry : featuresMap |
|
231 |
.entrySet()) { |
|
193 |
for (Entry<String, List<MSegment>> entry : featuresMap.entrySet()) { |
|
232 | 194 |
String routeName = entry.getKey(); |
233 |
List<MStructure> mList = entry.getValue();
|
|
195 |
List<MSegment> mList = entry.getValue();
|
|
234 | 196 |
|
235 |
EditableFeature newFeature = |
|
236 |
newFeatureStore.createNewFeature(true); |
|
197 |
EditableFeature newFeature = newFeatureStore.createNewFeature(true); |
|
237 | 198 |
newFeature.set(routeFieldName, routeName); |
238 | 199 |
Geometry route = createGeometryRoute(mList); |
239 | 200 |
newFeature.setDefaultGeometry(route); |
240 | 201 |
|
241 |
// TODO Added to facilitate Tests. Remove afterwards |
|
242 |
String lineSeparator = System.getProperty("line.separator"); |
|
243 |
resultDebug.append(lineSeparator); |
|
244 |
resultDebug.append("Route: " + routeName); |
|
245 |
resultDebug.append(lineSeparator); |
|
246 |
if (route instanceof MultiLine) { |
|
247 |
MultiLine multiLine = (MultiLine) route; |
|
248 |
for (int j = 0; j < multiLine.getPrimitivesNumber(); j++) { |
|
249 |
Line line = (Line) multiLine.getPrimitiveAt(j); |
|
250 |
resultDebug.append("Line " + j + ":["); |
|
251 |
for (int i = 0; i < line.getNumVertices(); i++) { |
|
252 |
Point point = line.getVertex(i); |
|
253 |
Double x = point.getX(); |
|
254 |
Double y = point.getY(); |
|
255 |
Double m = |
|
256 |
point.getCoordinateAt(point.getDimension() - 1); |
|
257 |
resultDebug.append("(x=" + x.toString() + ",y=" |
|
258 |
+ y.toString() + ",m=" + m.toString() + ")"); |
|
259 |
} |
|
260 |
resultDebug.append("]"); |
|
261 |
resultDebug.append(lineSeparator); |
|
262 |
} |
|
263 |
} |
|
264 |
|
|
265 |
// END of Test addition |
|
266 |
|
|
267 | 202 |
newFeatureStore.update(newFeature); |
268 | 203 |
|
269 | 204 |
taskCount++; |
270 | 205 |
taskStatus.setCurValue(taskCount); |
271 | 206 |
|
272 | 207 |
} |
273 |
logger.debug(resultDebug.toString()); |
|
274 | 208 |
newFeatureStore.finishEditing(); |
275 | 209 |
|
276 | 210 |
} catch (Exception e1) { |
... | ... | |
282 | 216 |
|
283 | 217 |
} |
284 | 218 |
|
285 |
private Geometry createGeometryRoute(List<MStructure> mList) |
|
286 |
throws CreateGeometryException, GeometryOperationNotSupportedException, |
|
287 |
GeometryOperationException { |
|
219 |
private Geometry createGeometryRoute(List<MSegment> mList) throws CreateGeometryException, |
|
220 |
GeometryOperationNotSupportedException, GeometryOperationException, CreateEnvelopeException { |
|
288 | 221 |
LrsSourceOfMeasures sourceOfMeasures = parameters.getSourceOfMeasures(); |
289 | 222 |
Geometry geometryResult = null; |
290 | 223 |
simplifyMultilines(mList); |
... | ... | |
300 | 233 |
geometryResult = calculateGeometryByLength(mList); |
301 | 234 |
break; |
302 | 235 |
} |
303 |
geometryResult = simplifyMultiline(geometryResult); |
|
304 |
geometryResult = applyOffset(geometryResult); |
|
236 |
geometryResult = applyOffsetAndFactor(geometryResult); |
|
305 | 237 |
return geometryResult; |
306 | 238 |
} |
307 | 239 |
|
308 |
private Geometry calculateGeometryByLength(List<MStructure> mList) |
|
309 |
throws CreateGeometryException, GeometryOperationNotSupportedException, |
|
310 |
GeometryOperationException { |
|
240 |
private Geometry calculateGeometryByLength(List<MSegment> mList) throws CreateGeometryException, |
|
241 |
GeometryOperationNotSupportedException, GeometryOperationException, CreateEnvelopeException { |
|
311 | 242 |
boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps(); |
312 |
for (MStructure mStructure : mList) { |
|
313 |
mStructure.fromField = |
|
314 |
LrsAlgorithmUtils.getGeometryLength(mStructure.geometry, ignoreSpatialGaps); |
|
243 |
for (MSegment mSegment : mList) { |
|
244 |
mSegment.fromValue = LrsAlgorithmUtils.getGeometryLength(mSegment.geometry, ignoreSpatialGaps); |
|
315 | 245 |
} |
316 | 246 |
return calculateGeometryByOneField(mList); |
317 | 247 |
} |
318 | 248 |
|
319 |
private Geometry calculateGeometryByOneField(List<MStructure> mList) |
|
320 |
throws CreateGeometryException, GeometryOperationNotSupportedException, |
|
321 |
GeometryOperationException { |
|
249 |
private Geometry calculateGeometryByOneField(List<MSegment> mList) throws CreateGeometryException, |
|
250 |
GeometryOperationNotSupportedException, GeometryOperationException, CreateEnvelopeException { |
|
322 | 251 |
boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps(); |
323 |
GeometryManager geomanager = GeometryLocator.getGeometryManager();
|
|
252 |
GeometryManager gmanager = GeometryLocator.getGeometryManager(); |
|
324 | 253 |
try { |
325 |
mList=sortMList(mList);
|
|
254 |
mList = sortMList(mList);
|
|
326 | 255 |
} catch (Exception e) { |
327 | 256 |
logger.warn("Geometries couldn't be ordered"); |
328 | 257 |
} |
329 | 258 |
|
330 |
MultiLine mGeometry = (MultiLine) geomanager |
|
331 |
.create(Geometry.TYPES.MULTILINE, Geometry.SUBTYPES.GEOM2DM); |
|
332 |
//MutableDouble lastMValue = new MutableDouble(0); |
|
333 |
Double lastMValueGeometry= Double.valueOf(0); |
|
334 |
Double gapBetweenGeometries = Double.valueOf(0); |
|
335 |
Point lastPoint = null; |
|
259 |
MultiLine auxMultiLine = (MultiLine) gmanager.create(Geometry.TYPES.MULTILINE, Geometry.SUBTYPES.GEOM2DM); |
|
336 | 260 |
|
337 |
for (MStructure mStructure : mList) { |
|
338 |
Geometry geometry = mStructure.geometry; |
|
339 |
List<Line> geometryLines=LrsAlgorithmUtils.extractLines(geometry); |
|
340 |
Double geometryLength=LrsAlgorithmUtils.getGeometryLength(geometry, ignoreSpatialGaps); |
|
341 |
boolean firstLineInGeometry=true; |
|
342 |
|
|
343 |
if (!ignoreSpatialGaps) { |
|
344 |
gapBetweenGeometries = calculateGap(lastPoint, geometry); |
|
345 |
lastMValueGeometry+=gapBetweenGeometries; |
|
261 |
Point previousPoint = null; |
|
262 |
double previousM = 0.0; |
|
263 |
for (MSegment mSegment : mList) { |
|
264 |
Geometry geom = mSegment.geometry; |
|
265 |
Double geometryLength = mSegment.getLength(ignoreSpatialGaps); |
|
266 |
if (geom instanceof Line) { |
|
267 |
Line line = (Line) geom; |
|
268 |
Line auxLine = (Line) gmanager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM); |
|
269 |
double distance = 0.0; |
|
270 |
double firstM = previousM; |
|
271 |
for (int i = 0; i < line.getNumVertices(); i++) { |
|
272 |
Point vertex = line.getVertex(i); |
|
273 |
Point point = (Point) gmanager.create(Geometry.TYPES.POINT, Geometry.SUBTYPES.GEOM2DM); |
|
274 |
point.setX(vertex.getX()); |
|
275 |
point.setY(vertex.getY()); |
|
276 |
if (i == 0 && previousPoint != null) { |
|
277 |
boolean gap = false; |
|
278 |
if (areInSame2DLocation(previousPoint, vertex)) { |
|
279 |
// Buscamos si ha sido una bifurcaci?n |
|
280 |
previousPoint = getPossibleFork(auxMultiLine, vertex); |
|
281 |
// OJO, aqu? previousPoint pasa a ser 2DM |
|
282 |
} else { |
|
283 |
// En caso de salto, calculamos el previousPoint |
|
284 |
// // y si no, buscamos el v?rtice m?s cercano |
|
285 |
previousPoint = getClosestVertex(auxMultiLine, vertex); |
|
286 |
// OJO, aqu? previousPoint pasa a ser 2DM |
|
287 |
gap = true; |
|
288 |
} |
|
289 |
previousM = previousPoint.getCoordinateAt(previousPoint.getDimension() - 1); |
|
290 |
if (i == 0) { |
|
291 |
firstM = previousM; |
|
292 |
} |
|
293 |
if (gap && !ignoreSpatialGaps) { |
|
294 |
Point previousVertex = getPreviousVertexToPoint(auxMultiLine, previousPoint); |
|
295 |
previousVertex.getCoordinateAt(previousVertex.getDimension() - 1); |
|
296 |
previousM = |
|
297 |
strightLineThroughTwoPointsEquation(0, previousVertex.distance(previousPoint), |
|
298 |
previousVertex.getCoordinateAt(previousVertex.getDimension() - 1), previousM, |
|
299 |
previousVertex.distance(previousPoint) + previousPoint.distance(point)); |
|
300 |
firstM = previousM; |
|
301 |
} |
|
302 |
} |
|
303 |
if (i != 0) { |
|
304 |
distance += previousPoint.distance(vertex); |
|
305 |
} |
|
306 |
double m = |
|
307 |
strightLineThroughTwoPointsEquation(0, geometryLength, firstM, firstM + mSegment.fromValue, |
|
308 |
distance); |
|
309 |
point.setCoordinateAt(point.getDimension() - 1, m); |
|
310 |
auxLine.addVertex(point); |
|
311 |
previousM = m; |
|
312 |
previousPoint = vertex; |
|
313 |
} |
|
314 |
auxMultiLine.addPrimitive(auxLine); |
|
315 |
} else if (geom instanceof MultiLine) { |
|
316 |
MultiLine multiline = (MultiLine) geom; |
|
317 |
for (int i = 0; i < multiline.getPrimitivesNumber(); i++) { |
|
318 |
Line line = (Line) multiline.getPrimitiveAt(i); |
|
319 |
Line auxLine = (Line) gmanager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM); |
|
320 |
double distance = 0.0; |
|
321 |
double firstM = previousM; |
|
322 |
for (int j = 0; j < line.getNumVertices(); j++) { |
|
323 |
Point vertex = line.getVertex(j); |
|
324 |
Point point = (Point) gmanager.create(Geometry.TYPES.POINT, Geometry.SUBTYPES.GEOM2DM); |
|
325 |
point.setX(vertex.getX()); |
|
326 |
point.setY(vertex.getY()); |
|
327 |
if (j == 0 && previousPoint != null) { |
|
328 |
boolean gap = false; |
|
329 |
if (areInSame2DLocation(previousPoint, vertex)) { |
|
330 |
// Buscamos si ha sido una bifurcaci?n |
|
331 |
previousPoint = getPossibleFork(auxMultiLine, vertex); |
|
332 |
// OJO, aqu? previousPoint pasa a ser 2DM |
|
333 |
} else { |
|
334 |
// En caso de salto, calculamos el previousPoint |
|
335 |
previousPoint = getClosestVertex(auxMultiLine, vertex); |
|
336 |
// OJO, aqu? previousPoint pasa a ser 2DM |
|
337 |
gap = true; |
|
338 |
} |
|
339 |
previousM = previousPoint.getCoordinateAt(previousPoint.getDimension() - 1); |
|
340 |
if (j == 0) { |
|
341 |
firstM = previousM; |
|
342 |
} |
|
343 |
if (gap && !ignoreSpatialGaps) { |
|
344 |
Point previousVertex = getPreviousVertexToPoint(auxMultiLine, previousPoint); |
|
345 |
previousVertex.getCoordinateAt(previousVertex.getDimension() - 1); |
|
346 |
previousM = |
|
347 |
strightLineThroughTwoPointsEquation(0, previousVertex.distance(previousPoint), |
|
348 |
previousVertex.getCoordinateAt(previousVertex.getDimension() - 1), previousM, |
|
349 |
previousVertex.distance(previousPoint) + previousPoint.distance(point)); |
|
350 |
firstM = previousM; |
|
351 |
} |
|
352 |
} |
|
353 |
if (j != 0) { |
|
354 |
distance += previousPoint.distance(vertex); |
|
355 |
} |
|
356 |
double m = |
|
357 |
strightLineThroughTwoPointsEquation(0, geometryLength, firstM, firstM + mSegment.fromValue, |
|
358 |
distance); |
|
359 |
point.setCoordinateAt(point.getDimension() - 1, m); |
|
360 |
auxLine.addVertex(point); |
|
361 |
previousM = m; |
|
362 |
previousPoint = vertex; |
|
363 |
} |
|
364 |
multiline.addPrimitive(auxLine); |
|
365 |
} |
|
366 |
} else { |
|
367 |
// NO deber?a entrar por aqu? |
|
368 |
logger.warn("A not LINE nor MULTILINE geometry found in CreateRoute process"); |
|
346 | 369 |
} |
347 |
Double previouslyCalculatedMValue= getCalculatedMValueForFirstPoint(mGeometry,geometry); |
|
348 |
if (previouslyCalculatedMValue!=null){ |
|
349 |
lastPoint=null; |
|
350 |
lastMValueGeometry=previouslyCalculatedMValue; |
|
351 |
} |
|
370 |
} |
|
352 | 371 |
|
353 |
Double geometryMFirstPoint = lastMValueGeometry; |
|
354 |
lastMValueGeometry+=mStructure.fromField; |
|
355 |
Double geometryMLastPoint=lastMValueGeometry; |
|
372 |
return compactMultiLine(auxMultiLine); |
|
373 |
} |
|
356 | 374 |
|
357 |
Double distance=Double.valueOf(0);; |
|
358 |
for (Line line:geometryLines){ |
|
359 |
Double gapBetweenLines = Double.valueOf(0); |
|
360 |
Double lineLength=LrsAlgorithmUtils.getLineLength(line); |
|
361 |
if (!ignoreSpatialGaps&&!firstLineInGeometry) { |
|
362 |
gapBetweenLines = calculateGap(lastPoint, line); |
|
363 |
distance+=gapBetweenLines; |
|
364 |
firstLineInGeometry=false; |
|
375 |
/** |
|
376 |
* Joins consecutive adjacent lines into the multiLine that are not involved in a fork |
|
377 |
* |
|
378 |
* @param auxMultiLine |
|
379 |
* @return |
|
380 |
* @throws CreateGeometryException |
|
381 |
* @throws GeometryOperationException |
|
382 |
* @throws GeometryOperationNotSupportedException |
|
383 |
*/ |
|
384 |
private MultiLine compactMultiLine(MultiLine multiLine) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException { |
|
385 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
|
386 |
MultiLine result = (MultiLine) geomManager.create(multiLine.getGeometryType()); |
|
387 |
|
|
388 |
int primitivesNumber = multiLine.getPrimitivesNumber(); |
|
389 |
List<Line> lines = new ArrayList<Line>(primitivesNumber); |
|
390 |
for(int i = 0; i < primitivesNumber; i++){ |
|
391 |
lines.add((Line)multiLine.getPrimitiveAt(i).cloneGeometry()); |
|
392 |
} |
|
393 |
if (lines.size() > 0) { |
|
394 |
Line line = lines.get(0); |
|
395 |
while (lines.size() > 1) { |
|
396 |
Point lastVertex = line.getVertex(line.getNumVertices() - 1); |
|
397 |
lines.remove(0); |
|
398 |
// Borramos la primera linea de la lista ==> lines.get(0) es la siguiente |
|
399 |
Line line2 = lines.get(0); |
|
400 |
// Si el ultimo punto de la primera |
|
401 |
if (lastVertex.equals(line2.getVertex(0)) && !bifurcation(lastVertex, lines)) { |
|
402 |
for(int i = 1; i<line2.getNumVertices(); i++){ |
|
403 |
line.addVertex(line2.getVertex(i)); |
|
404 |
} |
|
405 |
} else { |
|
406 |
result.addPrimitive(line); |
|
407 |
line = line2; |
|
365 | 408 |
} |
409 |
} |
|
410 |
result.addPrimitive(line); |
|
411 |
} |
|
412 |
return result; |
|
413 |
} |
|
366 | 414 |
|
367 |
Double mFirstPoint = |
|
368 |
calculateM(geometryMLastPoint, geometryMFirstPoint, distance, geometryLength); |
|
369 |
distance+=lineLength; |
|
370 |
Double mLastPoint = |
|
371 |
calculateM(geometryMLastPoint, geometryMFirstPoint, distance, geometryLength); |
|
372 |
Line mLine=lineToMLine(line, mFirstPoint, mLastPoint); |
|
373 |
mGeometry.addPrimitive(mLine); |
|
374 |
lastPoint = mLine.getVertex(mLine.getNumVertices() - 1); |
|
415 |
/** |
|
416 |
* Checks if a bifurcation occurs at one point. |
|
417 |
* |
|
418 |
* @param point |
|
419 |
* @param lines |
|
420 |
* @return |
|
421 |
*/ |
|
422 |
private boolean bifurcation(Point point, List<org.gvsig.fmap.geom.primitive.Line> lines) { |
|
423 |
// Saltamos la primera linea |
|
424 |
for(int i = 1; i<lines.size(); i++){ |
|
425 |
if(point.equals(lines.get(i).getVertex(0))){ |
|
426 |
return true; |
|
375 | 427 |
} |
376 | 428 |
} |
377 |
return mGeometry; |
|
429 |
return false; |
|
430 |
} |
|
378 | 431 |
|
432 |
/** |
|
433 |
* Returns the previous vertex to a point. |
|
434 |
* |
|
435 |
* @param auxMultiLine |
|
436 |
* @param previousPoint |
|
437 |
* @return |
|
438 |
* @throws GeometryOperationException |
|
439 |
* @throws GeometryOperationNotSupportedException |
|
440 |
* @throws CreateGeometryException |
|
441 |
*/ |
|
442 |
private Point getPreviousVertexToPoint(MultiLine multiLine, Point point) throws CreateGeometryException, |
|
443 |
GeometryOperationNotSupportedException, GeometryOperationException { |
|
444 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
|
445 |
for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) { |
|
446 |
Line line = (Line) multiLine.getPrimitiveAt(i); |
|
447 |
if (line.intersects(point)) { |
|
448 |
for (int j = 0; j < line.getNumVertices() - 1; j++) { |
|
449 |
if (point.equals(line.getVertex(j + 1))) { |
|
450 |
return line.getVertex(j); |
|
451 |
} |
|
452 |
Line auxLine = (Line) geomManager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM); |
|
453 |
auxLine.addVertex(line.getVertex(j)); |
|
454 |
auxLine.addVertex(line.getVertex(j + 1)); |
|
455 |
if (auxLine.intersects(point)) { |
|
456 |
return line.getVertex(j); |
|
457 |
} |
|
458 |
} |
|
459 |
} |
|
460 |
} |
|
461 |
return null; |
|
462 |
} |
|
379 | 463 |
|
380 |
// for (MStructure mStructure : mList) { |
|
381 |
// Geometry geometry = mStructure.geometry; |
|
382 |
// |
|
383 |
// if (!ignoreSpatialGaps) { |
|
384 |
// gapBetweenLines = calculateGap(lastPoint, geometry); |
|
385 |
// lastMValue.add(gapBetweenLines); |
|
386 |
// } |
|
387 |
// Double fromDistance = lastMValue.getValue(); |
|
388 |
// lastMValue.add(mStructure.fromField); |
|
389 |
// Double toDistance = lastMValue.getValue(); |
|
390 |
// |
|
391 |
// if (geometry instanceof Line) { |
|
392 |
// Line line = (Line) geometry; |
|
393 |
// Line lineM = lineToMLine(line, fromDistance, toDistance); |
|
394 |
// mGeometry.addPrimitive(lineM); |
|
395 |
// lastPoint = lineM.getVertex(lineM.getNumVertices() - 1); |
|
396 |
// } |
|
397 |
// if (geometry instanceof MultiLine) { |
|
398 |
// MultiLine multiLine = (MultiLine) geometry; |
|
399 |
// Line[] lines = multilineToMlines(multiLine, fromDistance, |
|
400 |
// toDistance, ignoreSpatialGaps); |
|
401 |
// for (Line lineM : lines) { |
|
402 |
// mGeometry.addPrimitive(lineM); |
|
403 |
// lastPoint = lineM.getVertex(lineM.getNumVertices() - 1); |
|
464 |
// /** |
|
465 |
// * Returns the measure corresponding to the point into the geometry |
|
466 |
// * |
|
467 |
// * @param mGeometry |
|
468 |
// * @param point |
|
469 |
// * @return |
|
470 |
// * @throws GeometryOperationException |
|
471 |
// * @throws GeometryOperationNotSupportedException |
|
472 |
// * @throws CreateGeometryException |
|
473 |
// */ |
|
474 |
// private double getM(MultiLine multiLine, Point point) throws GeometryOperationNotSupportedException, |
|
475 |
// GeometryOperationException, CreateGeometryException { |
|
476 |
// GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
|
477 |
// if (!(multiLine.getGeometryType().isSubTypeOf(Geometry.SUBTYPES.GEOM2DM)) |
|
478 |
// || (multiLine.getGeometryType().isSubTypeOf(Geometry.SUBTYPES.GEOM3DM))) { |
|
479 |
// return Double.NaN; |
|
480 |
// } |
|
481 |
// if (!(point.getGeometryType().isSubTypeOf(Geometry.SUBTYPES.GEOM2DM)) |
|
482 |
// || (point.getGeometryType().isSubTypeOf(Geometry.SUBTYPES.GEOM3DM))) { |
|
483 |
// return Double.NaN; |
|
484 |
// } |
|
485 |
// for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) { |
|
486 |
// Line line = (Line) multiLine.getPrimitiveAt(i); |
|
487 |
// if (line.intersects(point)) { |
|
488 |
// for (int j = 0; j < line.getNumVertices() - 1; j++) { |
|
489 |
// Point vertex1 = line.getVertex(j); |
|
490 |
// double m1 = vertex1.getCoordinateAt(vertex1.getDimension() - 1); |
|
491 |
// double x1 = vertex1.getX(); |
|
492 |
// double y1 = vertex1.getY(); |
|
493 |
// if (point.equals(vertex1)) { |
|
494 |
// return m1; |
|
495 |
// } |
|
496 |
// Point vertex2 = line.getVertex(j + 1); |
|
497 |
// double m2 = vertex2.getCoordinateAt(vertex2.getDimension() - 1); |
|
498 |
// double x2 = vertex2.getX(); |
|
499 |
// double y2 = vertex2.getY(); |
|
500 |
// if (point.equals(vertex2)) { |
|
501 |
// return m2; |
|
502 |
// } |
|
503 |
// Line auxLine = (Line) geomManager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM); |
|
504 |
// auxLine.addVertex(line.getVertex(j)); |
|
505 |
// auxLine.addVertex(line.getVertex(j + 1)); |
|
506 |
// if (auxLine.intersects(point)) { |
|
507 |
// if (x1 != x2) { |
|
508 |
// return strightLineThroughTwoPointsEquation(x1, x2, m1, m2, point.getX()); |
|
509 |
// } else { |
|
510 |
// return strightLineThroughTwoPointsEquation(y1, y2, m1, m2, point.getY()); |
|
511 |
// } |
|
512 |
// } |
|
404 | 513 |
// } |
405 | 514 |
// } |
406 | 515 |
// } |
407 |
// return mGeometry;
|
|
408 |
} |
|
516 |
// return Double.NaN;
|
|
517 |
// }
|
|
409 | 518 |
|
410 |
private Double getCalculatedMValueForFirstPoint(Geometry mGeometry,Geometry geometry){ |
|
411 |
List<Point> mPoints=LrsAlgorithmUtils.extractPoints(mGeometry); |
|
412 |
Point point=LrsAlgorithmUtils.extractFirstPoint(geometry); |
|
413 |
for (Point mPoint:mPoints){ |
|
414 |
if ( mPoint.getX()==point.getX() && mPoint.getY()==point.getY() ){ |
|
415 |
int dimensionM=mPoint.getDimension()-1; |
|
416 |
return mPoint.getCoordinateAt(dimensionM); |
|
519 |
/** |
|
520 |
* Checks if a bifurcation occurs at one point and return the vertex with maximum M |
|
521 |
* |
|
522 |
* @param multiLine |
|
523 |
* @param vertex |
|
524 |
* @return |
|
525 |
*/ |
|
526 |
private Point getPossibleFork(MultiLine multiLine, Point point) { |
|
527 |
|
|
528 |
List<Point> vertices = new ArrayList<Point>(); |
|
529 |
for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) { |
|
530 |
Line line = (Line) multiLine.getPrimitiveAt(i); |
|
531 |
for (int j = 0; j < line.getNumVertices(); j++) { |
|
532 |
Point vertex = line.getVertex(j); |
|
533 |
if (areInSame2DLocation(vertex, point)) { |
|
534 |
vertices.add(vertex); |
|
535 |
} |
|
417 | 536 |
} |
418 | 537 |
} |
538 |
if (vertices.size() > 0) { |
|
539 |
Double maxM = Double.NEGATIVE_INFINITY; |
|
540 |
Point forked = null; |
|
541 |
for (Iterator<Point> iterator = vertices.iterator(); iterator.hasNext();) { |
|
542 |
Point vertex = (Point) iterator.next(); |
|
543 |
double m = vertex.getCoordinateAt(vertex.getDimension() - 1); |
|
544 |
if (m > maxM) { |
|
545 |
maxM = m; |
|
546 |
forked = vertex; |
|
547 |
} |
|
548 |
} |
|
549 |
return forked; |
|
550 |
} |
|
419 | 551 |
return null; |
420 | 552 |
} |
421 | 553 |
|
422 |
private Geometry calculateGeometryByTwoField(List<MStructure> mList) |
|
423 |
throws CreateGeometryException, GeometryOperationNotSupportedException, |
|
424 |
GeometryOperationException { |
|
425 |
GeometryManager geomanager = GeometryLocator.getGeometryManager(); |
|
426 |
MultiLine mGeometry = (MultiLine) geomanager |
|
427 |
.create(Geometry.TYPES.MULTILINE, Geometry.SUBTYPES.GEOM2DM); |
|
554 |
/** |
|
555 |
* Compares x & y coordinates of a point. |
|
556 |
* |
|
557 |
* @param p1 |
|
558 |
* @param p2 |
|
559 |
* @return |
|
560 |
*/ |
|
561 |
private boolean areInSame2DLocation(Point p1, Point p2) { |
|
562 |
return ((p1.getX() == p2.getX()) && (p1.getY() == p2.getY())); |
|
563 |
} |
|
428 | 564 |
|
429 |
for (MStructure mStructure : mList) { |
|
430 |
Geometry geometry = mStructure.geometry; |
|
431 |
List<Line> geometryLines=LrsAlgorithmUtils.extractLines(geometry); |
|
432 |
Double geometryLength=LrsAlgorithmUtils.getGeometryLength(geometry); |
|
565 |
/** |
|
566 |
* Returns the vertex of the multiline closest to a point |
|
567 |
* |
|
568 |
* @param mGeometry |
|
569 |
* @param vertex |
|
570 |
* @return |
|
571 |
* @throws GeometryOperationException |
|
572 |
* @throws GeometryOperationNotSupportedException |
|
573 |
* @throws CreateEnvelopeException |
|
574 |
*/ |
|
575 |
private Point getClosestVertex(MultiLine multiLine, Point point) throws CreateEnvelopeException, |
|
576 |
GeometryOperationNotSupportedException, GeometryOperationException { |
|
577 |
Point result = null; |
|
578 |
double minDistance = Double.POSITIVE_INFINITY; |
|
433 | 579 |
|
434 |
Double geometryMFirstPoint = mStructure.fromField; |
|
435 |
Double geometryMLastPoint=mStructure.toField; |
|
436 |
|
|
437 |
Double distance=Double.valueOf(0); |
|
438 |
for (Line line:geometryLines){ |
|
439 |
Double lineLength=LrsAlgorithmUtils.getLineLength(line); |
|
440 |
Double mFirstPoint = |
|
441 |
calculateM(geometryMLastPoint, geometryMFirstPoint, distance, geometryLength); |
|
442 |
distance+=lineLength; |
|
443 |
Double mLastPoint = |
|
444 |
calculateM(geometryMLastPoint, geometryMFirstPoint, distance, geometryLength); |
|
445 |
Line mLine=lineToMLine(line, mFirstPoint, mLastPoint); |
|
446 |
mGeometry.addPrimitive(mLine); |
|
580 |
for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) { |
|
581 |
Line line = (Line) multiLine.getPrimitiveAt(i); |
|
582 |
for (int j = 0; j < line.getNumVertices(); j++) { |
|
583 |
Point vertex = line.getVertex(j); |
|
584 |
double distance = point.distance(vertex); |
|
585 |
if (distance <= minDistance) { |
|
586 |
minDistance = distance; |
|
587 |
result = vertex; |
|
588 |
} |
|
447 | 589 |
} |
448 | 590 |
} |
449 | 591 |
|
450 |
// for (MStructure mStructure : mList) { |
|
451 |
// Geometry geometry = mStructure.geometry; |
|
452 |
// Double fromDistance = mStructure.fromField; |
|
453 |
// Double toDistance = mStructure.toField; |
|
454 |
// if (geometry instanceof Line) { |
|
455 |
// Line line = (Line) geometry; |
|
456 |
// Line lineM = lineToMLine(line, fromDistance, toDistance); |
|
457 |
// mGeometry.addPrimitive(lineM); |
|
592 |
return result; |
|
593 |
} |
|
594 |
|
|
595 |
// /** |
|
596 |
// * @param closestPoints |
|
597 |
// * @return |
|
598 |
// * @throws CreateEnvelopeException |
|
599 |
// * @throws GeometryOperationException |
|
600 |
// * @throws GeometryOperationNotSupportedException |
|
601 |
// */ |
|
602 |
// private Point getClosestPointByCoordinatePriority(Geometry[] closestPoints) throws CreateEnvelopeException, |
|
603 |
// GeometryOperationNotSupportedException, GeometryOperationException { |
|
604 |
// LrsCoordinatesPriority coordinatePriority = parameters.getCoordinatePriority(); |
|
605 |
// GeometryManager geomanager = GeometryLocator.getGeometryManager(); |
|
606 |
// Envelope envelope = geomanager.createEnvelope(Geometry.SUBTYPES.GEOM2D); |
|
607 |
// for (int i = 0; i < closestPoints.length; i++) { |
|
608 |
// envelope.add(closestPoints[i]); |
|
609 |
// } |
|
610 |
// Point origin = envelope.getLowerCorner(); |
|
611 |
// switch (coordinatePriority) { |
|
612 |
// case DOWN_LEFT: |
|
613 |
// break; |
|
614 |
// case DOWN_RIGHT: |
|
615 |
// Double maxX = envelope.getMaximum(DIMENSIONS.X); |
|
616 |
// origin.setX(maxX); |
|
617 |
// break; |
|
618 |
// case UP_LEFT: |
|
619 |
// Double maxY = envelope.getMaximum(DIMENSIONS.Y); |
|
620 |
// origin.setY(maxY); |
|
621 |
// break; |
|
622 |
// case UP_RIGHT: |
|
623 |
// origin = envelope.getUpperCorner(); |
|
624 |
// break; |
|
625 |
// default: |
|
626 |
// break; |
|
627 |
// } |
|
628 |
// Point closestPoint = null; |
|
629 |
// double minDistance = Double.POSITIVE_INFINITY; |
|
630 |
// for (int i = 0; i < closestPoints.length; i++) { |
|
631 |
// Point point = (Point) closestPoints[i]; |
|
632 |
// double distance = origin.distance(point); |
|
633 |
// if (minDistance > distance) { |
|
634 |
// minDistance = distance; |
|
635 |
// closestPoint = point; |
|
458 | 636 |
// } |
459 |
// if (geometry instanceof MultiLine) { |
|
460 |
// MultiLine multiLine = (MultiLine) geometry; |
|
461 |
// Line[] lines = |
|
462 |
// multilineToMlines(multiLine, fromDistance, toDistance); |
|
463 |
// for (Line lineM : lines) { |
|
464 |
// mGeometry.addPrimitive(lineM); |
|
465 |
// } |
|
466 |
// } |
|
467 | 637 |
// } |
638 |
// return closestPoint; |
|
639 |
// } |
|
468 | 640 |
|
469 |
return mGeometry; |
|
470 |
} |
|
471 |
|
|
472 |
// private Line[] multilineToMlines(MultiLine multiLine, Double fromDistance, |
|
473 |
// Double toDistance) throws GeometryOperationNotSupportedException, |
|
474 |
// GeometryOperationException, CreateGeometryException { |
|
475 |
// return multilineToMlines(multiLine, fromDistance, toDistance, true); |
|
476 |
// } |
|
477 |
// |
|
478 |
// private Line[] multilineToMlines(MultiLine multiLine, Double fromDistance, |
|
479 |
// Double toDistance, boolean ignoreSpatialGaps) |
|
480 |
// throws GeometryOperationNotSupportedException, |
|
481 |
// GeometryOperationException, CreateGeometryException { |
|
482 |
// |
|
483 |
// Line[] lines = new Line[multiLine.getPrimitivesNumber()]; |
|
484 |
// Double multiLineLength = |
|
485 |
// getMultiLineLength(multiLine, ignoreSpatialGaps); |
|
486 |
// Double mFirstPoint = fromDistance; |
|
487 |
// Double mLastPoint = null; |
|
488 |
// Double distance = Double.valueOf(0); |
|
489 |
// Point lastPoint = null; |
|
490 |
// for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) { |
|
491 |
// |
|
492 |
// Line line = (Line) multiLine.getPrimitiveAt(i); |
|
493 |
// Double lineLength = getLineLength(line); |
|
494 |
// Double gap = Double.valueOf(0); |
|
495 |
// |
|
496 |
// if (!ignoreSpatialGaps && lastPoint != null) { |
|
497 |
// Point firstPoint = line.getVertex(0); |
|
498 |
// gap = firstPoint.distance(lastPoint); |
|
499 |
// distance += gap; |
|
641 |
// private Double getCalculatedMValueForFirstPoint(Geometry mGeometry, Geometry geometry) { |
|
642 |
// List<Point> mPoints = extractPoints(mGeometry); |
|
643 |
// Point point = extractFirstPoint(geometry); |
|
644 |
// for (Point mPoint : mPoints) { |
|
645 |
// if (mPoint.getX() == point.getX() && mPoint.getY() == point.getY()) { |
|
646 |
// int dimensionM = mPoint.getDimension() - 1; |
|
647 |
// return mPoint.getCoordinateAt(dimensionM); |
|
500 | 648 |
// } |
501 |
// mFirstPoint = |
|
502 |
// calculateM(toDistance, fromDistance, distance, multiLineLength); |
|
503 |
// distance += lineLength; |
|
504 |
// mLastPoint = |
|
505 |
// calculateM(toDistance, fromDistance, distance, multiLineLength); |
|
506 |
// lines[i] = lineToMLine(line, mFirstPoint, mLastPoint); |
|
507 |
// lastPoint = lines[i].getVertex(line.getNumVertices() - 1); |
|
508 | 649 |
// } |
509 |
// return lines;
|
|
650 |
// return null;
|
|
510 | 651 |
// } |
511 | 652 |
|
512 |
private Line lineToMLine(Line line, Double minMValue, Double maxMValue) |
|
513 |
throws CreateGeometryException, GeometryOperationNotSupportedException, |
|
514 |
GeometryOperationException { |
|
653 |
/** |
|
654 |
* Returns a multiline calculate by two field method |
|
655 |
* |
|
656 |
* @param mList |
|
657 |
* @return |
|
658 |
* @throws CreateGeometryException |
|
659 |
* @throws GeometryOperationNotSupportedException |
|
660 |
* @throws GeometryOperationException |
|
661 |
*/ |
|
662 |
private MultiLine calculateGeometryByTwoField(List<MSegment> mList) throws CreateGeometryException, |
|
663 |
GeometryOperationNotSupportedException, GeometryOperationException { |
|
515 | 664 |
GeometryManager geomanager = GeometryLocator.getGeometryManager(); |
516 |
Double lineLength = LrsAlgorithmUtils.getLineLength(line); |
|
517 |
Line lineM = (Line) geomanager.create(Geometry.TYPES.LINE, |
|
518 |
Geometry.SUBTYPES.GEOM2DM); |
|
665 |
MultiLine mGeometry = (MultiLine) geomanager.create(Geometry.TYPES.MULTILINE, Geometry.SUBTYPES.GEOM2DM); |
|
666 |
|
|
667 |
for (MSegment mSegment : mList) { |
|
668 |
Geometry geometry = mSegment.geometry; |
|
669 |
List<Line> geometryLines = extractLines(geometry); |
|
670 |
Double geometryLength = LrsAlgorithmUtils.getGeometryLength(geometry); |
|
671 |
|
|
672 |
Double geometryMFirstPoint = mSegment.fromValue; |
|
673 |
Double geometryMLastPoint = mSegment.toValue; |
|
674 |
|
|
675 |
Double distance = Double.valueOf(0); |
|
676 |
for (Line line : geometryLines) { |
|
677 |
Double lineLength = getLineLength(line); |
|
678 |
Double mFirstPoint = calculateM(geometryMLastPoint, geometryMFirstPoint, distance, geometryLength); |
|
679 |
distance += lineLength; |
|
680 |
Double mLastPoint = calculateM(geometryMLastPoint, geometryMFirstPoint, distance, geometryLength); |
|
681 |
Line mLine = lineToMLine(line, mFirstPoint, mLastPoint); |
|
682 |
mGeometry.addPrimitive(mLine); |
|
683 |
} |
|
684 |
} |
|
685 |
|
|
686 |
return mGeometry; |
|
687 |
} |
|
688 |
|
|
689 |
/** |
|
690 |
* Converts a Line2D in a Line2DM filled it with proportional calculated M's |
|
691 |
* |
|
692 |
* @param line |
|
693 |
* @param minMValue |
|
694 |
* @param maxMValue |
|
695 |
* @return |
|
696 |
* @throws CreateGeometryException |
|
697 |
* @throws GeometryOperationNotSupportedException |
|
698 |
* @throws GeometryOperationException |
|
699 |
*/ |
|
700 |
private Line lineToMLine(Line line, Double minMValue, Double maxMValue) throws CreateGeometryException, |
|
701 |
GeometryOperationNotSupportedException, GeometryOperationException { |
|
702 |
GeometryManager geomanager = GeometryLocator.getGeometryManager(); |
|
703 |
Double lineLength = getLineLength(line); |
|
704 |
Line lineM = (Line) geomanager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM); |
|
519 | 705 |
Double inLineDistance = Double.valueOf(0); |
520 | 706 |
for (int i = 0; i < line.getNumVertices(); i++) { |
521 | 707 |
Point vertex = line.getVertex(i); |
522 |
Point mVertex = (Point) geomanager.create(Geometry.TYPES.POINT, |
|
523 |
Geometry.SUBTYPES.GEOM2DM); |
|
708 |
Point mVertex = (Point) geomanager.create(Geometry.TYPES.POINT, Geometry.SUBTYPES.GEOM2DM); |
|
524 | 709 |
mVertex.setX(vertex.getX()); |
525 | 710 |
mVertex.setY(vertex.getY()); |
526 | 711 |
|
... | ... | |
532 | 717 |
else { |
533 | 718 |
Point previousVertex = line.getVertex(i - 1); |
534 | 719 |
inLineDistance += vertex.distance(previousVertex); |
535 |
mValue = calculateM(maxMValue, minMValue, inLineDistance, |
|
536 |
lineLength); |
|
720 |
mValue = calculateM(maxMValue, minMValue, inLineDistance, lineLength); |
|
537 | 721 |
} |
538 | 722 |
|
539 | 723 |
mVertex.setCoordinateAt(mVertex.getDimension() - 1, mValue); |
... | ... | |
542 | 726 |
return lineM; |
543 | 727 |
} |
544 | 728 |
|
545 |
private Double calculateM(Double maxValue, Double minValue, |
|
546 |
Double relativeDistance, Double totalLength) { |
|
547 |
// mValue=((newMax-newMin)*(mCoordinate-oldMin)/(oldMax-oldMin))+newMin; |
|
729 |
/** |
|
730 |
* Reduced versi?n of stright line through two points equation to calculate M's |
|
731 |
* |
|
732 |
* @param maxValue |
|
733 |
* @param minValue |
|
734 |
* @param relativeDistance |
|
735 |
* @param totalLength |
|
736 |
* @return |
|
737 |
*/ |
|
738 |
private Double calculateM(Double maxValue, Double minValue, Double relativeDistance, Double totalLength) { |
|
548 | 739 |
if (totalLength.equals(Double.valueOf(0))) |
549 | 740 |
return Double.POSITIVE_INFINITY; |
550 |
return ((maxValue - minValue) * (relativeDistance) / (totalLength)) |
|
551 |
+ minValue; |
|
741 |
return ((maxValue - minValue) * (relativeDistance) / (totalLength)) + minValue; |
|
552 | 742 |
} |
553 | 743 |
|
554 |
private void simplifyMultilines(List<MStructure> mList) |
|
555 |
throws CreateGeometryException, LocatorException { |
|
556 |
List<MStructure> simplifiedMList = new ArrayList<MStructure>(); |
|
557 |
for (MStructure mStructure : mList) { |
|
558 |
mStructure.geometry=simplifyMultiline(mStructure.geometry); |
|
559 |
simplifiedMList.add(mStructure); |
|
744 |
/** |
|
745 |
* Stright line through two points equation. |
|
746 |
* |
|
747 |
* @param x1 |
|
748 |
* @param x2 |
|
749 |
* @param y1 |
|
750 |
* @param y2 |
|
751 |
* @param x |
|
752 |
* @return |
|
753 |
*/ |
|
754 |
private double strightLineThroughTwoPointsEquation(double x1, double x2, double y1, double y2, double x) { |
|
755 |
if (x2 - x1 == 0.0) { |
|
756 |
return Double.POSITIVE_INFINITY; |
|
560 | 757 |
} |
561 |
mList = simplifiedMList;
|
|
758 |
return ((y2 - y1) * (x - x1) / (x2 - x1)) + y1;
|
|
562 | 759 |
} |
563 | 760 |
|
564 |
private Geometry simplifyMultiline(Geometry geometry) throws CreateGeometryException, LocatorException{ |
|
761 |
/** |
|
762 |
* Simplify the multilines in mList calling simplifyMultiline method |
|
763 |
* |
|
764 |
* @param mList |
|
765 |
* @throws CreateGeometryException |
|
766 |
* @throws LocatorException |
|
767 |
*/ |
|
768 |
private void simplifyMultilines(List<MSegment> mList) throws CreateGeometryException, LocatorException { |
|
769 |
for (MSegment mSegment : mList) { |
|
770 |
mSegment.geometry = simplifyMultiline(mSegment.geometry); |
|
771 |
} |
|
772 |
} |
|
773 |
|
|
774 |
/** |
|
775 |
* Simplify a Multiline ordering and joining her lines if can. |
|
776 |
* |
|
777 |
* @param geometry |
|
778 |
* @return |
|
779 |
* @throws CreateGeometryException |
|
780 |
* @throws LocatorException |
|
781 |
*/ |
|
782 |
private Geometry simplifyMultiline(Geometry geometry) throws CreateGeometryException, LocatorException { |
|
565 | 783 |
if (geometry instanceof MultiLine) { |
566 | 784 |
MultiLine multiline = (MultiLine) geometry; |
567 | 785 |
|
... | ... | |
576 | 794 |
|
577 | 795 |
Line line = null; |
578 | 796 |
while (complexLines.size() > 0) { |
579 |
line = complexLines.get(0); |
|
580 |
complexLines.remove(0); |
|
581 |
int i=0; |
|
582 |
while (i<complexLines.size()) { |
|
583 |
Line auxLine=null; |
|
584 |
if (complexLines.size()>0){ |
|
585 |
auxLine=complexLines.get(i); |
|
586 |
} |
|
797 |
line = complexLines.remove(0); |
|
798 |
int i = 0; |
|
799 |
while (i < complexLines.size()) { |
|
800 |
Line auxLine = complexLines.get(i); |
|
587 | 801 |
Line unitedLine = unionAdjacentLines(line, auxLine); |
588 | 802 |
if (unitedLine != null) { |
589 | 803 |
line = unitedLine; |
590 | 804 |
complexLines.remove(i); |
591 |
i=0;
|
|
592 |
}else{
|
|
805 |
i = 0;
|
|
806 |
} else {
|
|
593 | 807 |
i++; |
594 | 808 |
} |
595 | 809 |
} |
... | ... | |
600 | 814 |
geometry = simplifiedLines.get(0); |
601 | 815 |
} else { |
602 | 816 |
MultiLine simplifiedMultiLine = |
603 |
(MultiLine) GeometryLocator.getGeometryManager() |
|
604 |
.create(multiline.getGeometryType()); |
|
817 |
(MultiLine) GeometryLocator.getGeometryManager().create(multiline.getGeometryType()); |
|
605 | 818 |
for (Line simpleLine : simplifiedLines) { |
606 | 819 |
simplifiedMultiLine.addPrimitive(simpleLine); |
607 | 820 |
} |
... | ... | |
612 | 825 |
return geometry; |
613 | 826 |
} |
614 | 827 |
|
828 |
/** |
|
829 |
* Join two adjacent lines flipping it if necessary |
|
830 |
* |
|
831 |
* @param line1 |
|
832 |
* @param line2 |
|
833 |
* @return |
|
834 |
*/ |
|
615 | 835 |
private Line unionAdjacentLines(Line line1, Line line2) { |
616 | 836 |
if (line1 == null || line2 == null) { |
617 | 837 |
return null; |
618 | 838 |
} |
619 | 839 |
Line resultLine; |
620 | 840 |
try { |
621 |
resultLine = (Line) GeometryLocator.getGeometryManager() |
|
622 |
.create(line1.getGeometryType()); |
|
841 |
resultLine = (Line) GeometryLocator.getGeometryManager().create(line1.getGeometryType()); |
|
623 | 842 |
} catch (Exception e) { |
624 | 843 |
return null; |
625 | 844 |
} |
... | ... | |
631 | 850 |
if (lastPointL1.equals(firstPointL2)) { |
632 | 851 |
resultLine = (Line) line1.cloneGeometry(); |
633 | 852 |
for (int i = 1; i < line2.getNumVertices(); i++) { |
634 |
resultLine |
|
635 |
.addVertex((Point) line2.getVertex(i).cloneGeometry()); |
|
853 |
resultLine.addVertex((Point) line2.getVertex(i).cloneGeometry()); |
|
636 | 854 |
} |
637 | 855 |
return resultLine; |
638 | 856 |
} |
639 | 857 |
if (lastPointL2.equals(firstPointL1)) { |
640 | 858 |
resultLine = (Line) line2.cloneGeometry(); |
641 | 859 |
for (int i = 1; i < line1.getNumVertices(); i++) { |
642 |
resultLine |
|
643 |
.addVertex((Point) line1.getVertex(i).cloneGeometry()); |
|
860 |
resultLine.addVertex((Point) line1.getVertex(i).cloneGeometry()); |
|
644 | 861 |
} |
645 | 862 |
return resultLine; |
646 | 863 |
} |
647 | 864 |
if (firstPointL1.equals(firstPointL2)) { |
648 | 865 |
for (int i = line1.getNumVertices() - 1; i >= 0; i--) { |
649 |
resultLine |
|
650 |
.addVertex((Point) line1.getVertex(i).cloneGeometry()); |
|
866 |
resultLine.addVertex((Point) line1.getVertex(i).cloneGeometry()); |
|
651 | 867 |
} |
652 | 868 |
for (int i = 1; i < line2.getNumVertices(); i++) { |
653 |
resultLine |
|
654 |
.addVertex((Point) line2.getVertex(i).cloneGeometry()); |
|
869 |
resultLine.addVertex((Point) line2.getVertex(i).cloneGeometry()); |
|
655 | 870 |
} |
656 | 871 |
return resultLine; |
657 | 872 |
} |
658 | 873 |
if (lastPointL1.equals(lastPointL2)) { |
659 | 874 |
resultLine = (Line) line1.cloneGeometry(); |
660 | 875 |
for (int i = line2.getNumVertices() - 2; i >= 0; i--) { |
661 |
resultLine |
|
662 |
.addVertex((Point) line2.getVertex(i).cloneGeometry()); |
|
876 |
resultLine.addVertex((Point) line2.getVertex(i).cloneGeometry()); |
|
663 | 877 |
} |
664 | 878 |
return resultLine; |
665 | 879 |
} |
666 | 880 |
return null; |
667 | 881 |
} |
668 | 882 |
|
669 |
|
|
670 |
// private Double calculateGap(Point lastPoint, Line line) |
|
671 |
// throws GeometryOperationNotSupportedException, |
|
883 |
// /** |
|
884 |
// * Calculate distance between a point and the firstPoint of the geometry |
|
885 |
// * |
|
886 |
// * @param point |
|
887 |
// * @param geometry |
|
888 |
// * @return |
|
889 |
// * @throws GeometryOperationNotSupportedException |
|
890 |
// * @throws GeometryOperationException |
|
891 |
// */ |
|
892 |
// private Double calculateGap(Point point, Geometry geometry) throws GeometryOperationNotSupportedException, |
|
672 | 893 |
// GeometryOperationException { |
673 | 894 |
// Double gap = new Double(0); |
674 |
// if (lastPoint != null) { |
|
675 |
// Point firstPoint = line.getVertex(0); |
|
676 |
// gap = firstPoint.distance(lastPoint); |
|
895 |
// if (geometry instanceof Line) { |
|
896 |
// Line line = (Line) geometry; |
|
897 |
// if (point != null) { |
|
898 |
// Point firstPoint = line.getVertex(0); |
|
899 |
// gap = firstPoint.distance(point); |
|
900 |
// } |
|
677 | 901 |
// } |
902 |
// if (geometry instanceof MultiLine) { |
|
903 |
// MultiLine multiLine = (MultiLine) geometry; |
|
904 |
// if (point != null) { |
|
905 |
// Line line = (Line) multiLine.getPrimitiveAt(0); |
|
906 |
// Point firstPoint = line.getVertex(0); |
|
907 |
// gap = firstPoint.distance(point); |
|
908 |
// } |
|
909 |
// } |
|
678 | 910 |
// return gap; |
679 | 911 |
// } |
680 | 912 |
|
681 |
private Double calculateGap(Point lastPoint, Geometry geometry) |
|
682 |
throws GeometryOperationNotSupportedException, |
|
683 |
GeometryOperationException { |
|
684 |
Double gap = new Double(0); |
|
685 |
if (geometry instanceof Line) { |
|
686 |
Line line = (Line) geometry; |
|
687 |
if (lastPoint != null) { |
|
688 |
Point firstPoint = line.getVertex(0); |
|
689 |
gap = firstPoint.distance(lastPoint); |
|
690 |
} |
|
691 |
} |
|
692 |
if (geometry instanceof MultiLine) { |
|
693 |
MultiLine multiLine = (MultiLine) geometry; |
|
694 |
if (lastPoint != null) { |
|
695 |
Line line = (Line) multiLine.getPrimitiveAt(0); |
|
696 |
Point firstPoint = line.getVertex(0); |
|
697 |
gap = firstPoint.distance(lastPoint); |
|
698 |
} |
|
699 |
} |
|
700 |
return gap; |
|
701 |
} |
|
702 |
|
|
703 |
private List<MStructure> sortMList(List<MStructure> mList) |
|
704 |
throws CreateEnvelopeException, GeometryOperationNotSupportedException, |
|
705 |
GeometryOperationException { |
|
706 |
LrsCoordinatesPriority coordinatePriority = |
|
707 |
parameters.getCoordinatePriority(); |
|
913 |
/** |
|
914 |
* Sorts mList |
|
915 |
* |
|
916 |
* @param mList |
|
917 |
* @return |
|
918 |
* @throws CreateEnvelopeException |
|
919 |
* @throws GeometryOperationNotSupportedException |
|
920 |
* @throws GeometryOperationException |
|
921 |
*/ |
|
922 |
private List<MSegment> sortMList(List<MSegment> mList) throws CreateEnvelopeException, |
|
923 |
GeometryOperationNotSupportedException, GeometryOperationException { |
|
924 |
LrsCoordinatesPriority coordinatePriority = parameters.getCoordinatePriority(); |
|
708 | 925 |
GeometryManager geomanager = GeometryLocator.getGeometryManager(); |
709 | 926 |
Envelope envelope = geomanager.createEnvelope(Geometry.SUBTYPES.GEOM2D); |
710 |
for (MStructure mStructure : mList) {
|
|
711 |
envelope.add(mStructure.geometry.getEnvelope());
|
|
927 |
for (MSegment mSegment : mList) {
|
|
928 |
envelope.add(mSegment.geometry.getEnvelope());
|
|
712 | 929 |
} |
713 | 930 |
Point origin = envelope.getLowerCorner(); |
714 | 931 |
switch (coordinatePriority) { |
... | ... | |
729 | 946 |
break; |
730 | 947 |
} |
731 | 948 |
|
732 |
List<Route> routes=createRoutes(mList,origin); |
|
733 |
mList=extractMStructures(routes,origin,mList); |
|
734 |
return mList; |
|
735 |
|
|
736 |
//SECOND ATTEMPT |
|
737 |
// List<MStructure> orderedMlist=new ArrayList<MStructure>(); |
|
738 |
// while (!mList.isEmpty()){ |
|
739 |
// List<Point> orderedExtremePoints=getExtremePoints(mList,origin); |
|
740 |
// while ( !orderedExtremePoints.isEmpty() ){ |
|
741 |
// Point initialPoint= orderedExtremePoints.get(0); |
|
742 |
// orderedExtremePoints.remove(0); |
|
743 |
// MStructure initialMStructure=getMStructureWithExtremePoint(initialPoint); |
|
744 |
// orderMStructure(initialMStructure,origin); //Flips Geometry if it is necessary. |
|
745 |
// orderedMlist.add(initialMStructure); |
|
746 |
// mList.remove(initialMStructure); |
|
747 |
// List<Point> pointsInMStructure=getPointsInMStructure(initialMStructure); |
|
748 |
// orderedExtremePoints.removeAll(pointsInMStructure); |
|
749 |
// Point nextPoint=getNextPointInLine(initialMStructure, initialPoint); |
|
750 |
// while (nextPoint!=null){ |
|
751 |
// MStructure nextMStructure=getMStructureWithNextPoint(nextPoint); |
|
752 |
// orderMStructure(nextMStructure,origin); |
|
753 |
// orderedMlist.add(initialMStructure); |
|
754 |
// mList.remove(initialMStructure); |
|
755 |
// pointsInMStructure=getPointsInMStructure(nextMStructure); |
|
756 |
// orderedExtremePoints.removeAll(pointsInMStructure); |
|
757 |
// nextPoint=getNextPointInLine(nextMStructure, nextPoint); |
|
758 |
// } |
|
759 |
// } |
|
760 |
// } |
|
761 |
// mList=orderedMlist; |
|
762 |
|
|
763 |
|
|
764 |
//FIRST ATTEMPT |
|
765 |
// GeometryDistanceToPointComparator comaparatorMList = |
|
766 |
// new GeometryDistanceToPointComparator(origin); |
|
767 |
// Collections.sort(mList, comaparatorMList); |
|
768 |
// |
|
769 |
// for (MStructure mStructure : mList) { |
|
770 |
// Geometry geometry = mStructure.geometry; |
|
771 |
// if (geometry instanceof Line) { |
|
772 |
// Line line = (Line) geometry; |
|
773 |
// Double firstPointDistance = origin.distance(line.getVertex(0)); |
|
774 |
// Double lastPointDistance = |
|
775 |
// origin.distance(line.getVertex(line.getNumVertices() - 1)); |
|
776 |
// if (lastPointDistance < firstPointDistance) { |
|
777 |
// geometry.flip(); |
|
778 |
// } |
|
779 |
// } |
|
780 |
// if (geometry instanceof MultiLine) { |
|
781 |
// MultiLine multiLine = (MultiLine) geometry; |
|
782 |
// Line firstLine = (Line) multiLine.getPrimitiveAt(0); |
|
783 |
// Line lastLine = (Line) multiLine |
|
784 |
// .getPrimitiveAt(multiLine.getPrimitivesNumber() - 1); |
|
785 |
// Double firstPointDistance = |
|
786 |
// origin.distance(firstLine.getVertex(0)); |
|
787 |
// Double lastPointDistance = origin.distance( |
|
788 |
// lastLine.getVertex(lastLine.getNumVertices() - 1)); |
|
789 |
// if (lastPointDistance < firstPointDistance) { |
|
790 |
// geometry.flip(); |
|
791 |
// } |
|
792 |
// } |
|
793 |
// mStructure.geometry = geometry; |
|
794 |
// } |
|
795 |
|
|
949 |
List<Stretch> stretches = createStretches(mList, origin); |
|
950 |
stretches = sortStretches(stretches, origin); |
|
951 |
return extractSegmentsFromStretches(stretches); |
|
796 | 952 |
} |
797 | 953 |
|
798 |
private List<MStructure> extractMStructures(List<Route> routes, Point origin,List<MStructure> mList) throws GeometryOperationNotSupportedException, GeometryOperationException{ |
|
799 |
List<MStructure> orderedMList=new ArrayList<MStructure>(); |
|
800 |
Point initialPoint=origin; |
|
801 |
while (!routes.isEmpty()){ |
|
802 |
Route route=getNearestRoute(routes, initialPoint, mList,origin); |
|
803 |
routes.remove(route); |
|
804 |
int i=0; |
|
805 |
while (!route.structures.isEmpty()){ |
|
806 |
MStructure structure=route.structures.get(i); |
|
807 |
route.structures.remove(i); |
|
808 |
orderedMList.add(structure); |
|
809 |
removeRepeatedStructures(routes, structure); |
|
954 |
/** |
|
955 |
* Extracts segment from stretches and returns a list of segment. |
|
956 |
* |
|
957 |
* @param stretches |
|
958 |
* @return |
|
959 |
*/ |
|
960 |
private List<MSegment> extractSegmentsFromStretches(List<Stretch> stretches) { |
|
961 |
List<MSegment> result = new ArrayList<MSegment>(); |
|
962 |
for (Stretch stretch : stretches) { |
|
963 |
for (int i = 0; i < stretch.getSegmentNumber(); i++) { |
|
964 |
result.add(stretch.getSegment(i)); |
|
810 | 965 |
} |
811 |
initialPoint=route.finalPoint; |
|
812 | 966 |
} |
813 |
return orderedMList;
|
|
967 |
return result;
|
|
814 | 968 |
} |
815 | 969 |
|
816 |
private Route getNearestRoute(List<Route> routes, Point point,List<MStructure> mList, Point originPoint) |
|
817 |
throws GeometryOperationNotSupportedException, GeometryOperationException{ |
|
818 |
double minDistance = Double.POSITIVE_INFINITY; |
|
819 |
Route nearestRoute = null; |
|
970 |
/** |
|
971 |
* Sort the stretches |
|
972 |
* |
|
973 |
* @param stretches |
|
974 |
* @param origin |
|
975 |
* @return |
|
976 |
* @throws GeometryOperationNotSupportedException |
|
977 |
* @throws GeometryOperationException |
|
978 |
*/ |
|
979 |
private List<Stretch> sortStretches(List<Stretch> stretches, Point origin) |
|
980 |
throws GeometryOperationNotSupportedException, GeometryOperationException { |
|
981 |
List<Stretch> result = new ArrayList<Stretch>(); |
|
820 | 982 |
|
821 |
if (!point.equals(originPoint)){ |
|
822 |
if (isTriplePoint(mList, point)){ |
|
823 |
point=originPoint; |
|
983 |
Point originPoint = origin; |
|
984 |
while (result.size() < stretches.size()) { |
|
985 |
// Buscamos tramos que sean adyacentes al origin |
|
986 |
if (result.size() == 0) { |
|
987 |
addUnvisitedAdjacentStretches(stretches, result, originPoint); |
|
824 | 988 |
} |
825 |
} |
|
989 |
if (result.size() == 0) { |
|
990 |
result.add(getNearestUnvisitedStretch(stretches, originPoint, result)); |
|
991 |
} |
|
826 | 992 |
|
827 |
for (Route route:routes){ |
|
828 |
Double initialDistance=point.distance(route.initialPoint); |
|
829 |
if(initialDistance<minDistance){ |
|
830 |
minDistance = initialDistance; |
|
831 |
nearestRoute = route; |
|
993 |
boolean addedAdjacentStretches = true; |
|
994 |
while (addedAdjacentStretches) { |
|
995 |
addedAdjacentStretches = false; |
|
996 |
int visitedNumber = result.size(); |
|
997 |
for (int i = 0; i < visitedNumber; i++) { |
|
998 |
Stretch visited = result.get(i); |
|
999 |
addUnvisitedAdjacentStretches(stretches, result, visited.getFinalPoint()); |
|
1000 |
} |
|
1001 |
addedAdjacentStretches = (visitedNumber < result.size()); |
|
832 | 1002 |
} |
833 |
Double finalDistance=point.distance(route.finalPoint); |
|
834 |
if(finalDistance<minDistance){ |
|
835 |
minDistance = finalDistance; |
|
836 |
nearestRoute = route; |
|
1003 |
|
|
1004 |
int visitedNumber = result.size(); |
|
1005 |
for (int i = visitedNumber - 1; i >= 0; i--) { |
|
1006 |
Stretch visited = result.get(i); |
|
1007 |
Stretch nearest = getNearestUnvisitedStretch(stretches, visited.getFinalPoint(), result); |
|
1008 |
if (nearest != null) { |
|
1009 |
result.add(nearest); |
|
1010 |
break; |
|
1011 |
} |
|
837 | 1012 |
} |
838 | 1013 |
} |
839 |
Double initialDistance=point.distance(nearestRoute.initialPoint);
|
|
840 |
Double finalDistance=point.distance(nearestRoute.finalPoint);
|
|
1014 |
return result;
|
|
1015 |
}
|
|
841 | 1016 |
|
842 |
if (finalDistance<initialDistance){ |
|
843 |
Collections.reverse(nearestRoute.structures); |
|
844 |
for (MStructure structure :nearestRoute.structures){ |
|
845 |
structure.geometry.flip(); |
|
1017 |
/** |
|
1018 |
* Adds unvisited adjacent stretches to the visited list |
|
1019 |
* |
|
1020 |
* @param stretches |
|
1021 |
* @param visited |
|
1022 |
* @param originPoint |
|
1023 |
* @throws GeometryOperationNotSupportedException |
|
1024 |
* @throws GeometryOperationException |
|
1025 |
*/ |
|
1026 |
private void addUnvisitedAdjacentStretches(List<Stretch> stretches, List<Stretch> visited, Point originPoint) |
|
1027 |
throws GeometryOperationNotSupportedException, GeometryOperationException { |
|
1028 |
for (Stretch stretch : stretches) { |
|
1029 |
if (!visited.contains(stretch)) { |
|
1030 |
if (areInSame2DLocation(stretch.getInitialPoint(), originPoint)) { |
|
1031 |
visited.add(stretch); |
|
1032 |
} else if (areInSame2DLocation(stretch.getFinalPoint(), originPoint)) { |
|
1033 |
visited.add(stretch.flip()); |
|
1034 |
} |
|
846 | 1035 |
} |
847 | 1036 |
} |
848 |
return nearestRoute; |
|
849 | 1037 |
} |
850 | 1038 |
|
851 |
private void removeRepeatedStructures(List<Route>routes, MStructure structureToRemove){ |
|
852 |
for (Route route:routes){ |
|
853 |
int i=0; |
|
854 |
boolean removed=false; |
|
855 |
while (i< route.structures.size()&&!removed){ |
|
856 |
if (route.structures.get(i).id==structureToRemove.id){ |
|
857 |
route.structures.remove(i); |
|
858 |
removed=true; |
|
1039 |
/** |
|
1040 |
* Returns the unvisited stretch nearest to a point |
|
1041 |
* |
|
1042 |
* @param stretches |
|
1043 |
* @param origin |
|
1044 |
* @param visited |
|
1045 |
* @return |
|
1046 |
* @throws GeometryOperationNotSupportedException |
|
1047 |
* @throws GeometryOperationException |
|
1048 |
*/ |
|
1049 |
private Stretch getNearestUnvisitedStretch(List<Stretch> stretches, Point origin, List<Stretch> visited) |
|
1050 |
throws GeometryOperationNotSupportedException, GeometryOperationException { |
|
1051 |
|
|
1052 |
double minDistance = Double.POSITIVE_INFINITY; |
|
1053 |
Stretch nearest = null; |
|
1054 |
boolean needFlip = false; |
|
1055 |
for (Stretch stretch : stretches) { |
|
1056 |
if (!visited.contains(stretch)) { |
|
1057 |
Double initialDistance = origin.distance(stretch.getInitialPoint()); |
|
1058 |
if (initialDistance < minDistance) { |
|
1059 |
minDistance = initialDistance; |
|
1060 |
nearest = stretch; |
|
1061 |
needFlip = false; |
|
859 | 1062 |
} |
860 |
i++; |
|
1063 |
Double finalDistance = origin.distance(stretch.getFinalPoint()); |
|
1064 |
if (finalDistance < minDistance) { |
|
1065 |
minDistance = finalDistance; |
|
1066 |
nearest = stretch; |
|
1067 |
needFlip = true; |
|
1068 |
} |
|
861 | 1069 |
} |
862 | 1070 |
} |
1071 |
if (needFlip && nearest != null) { |
|
1072 |
nearest.flip(); |
|
1073 |
} |
|
1074 |
return nearest; |
|
863 | 1075 |
} |
864 | 1076 |
|
1077 |
/** |
|
1078 |
* Creates stretches from mList and returns a list of stretches |
|
1079 |
* |
|
1080 |
* @param mList |
|
1081 |
* @param origin |
|
1082 |
* @return |
|
1083 |
* @throws GeometryOperationNotSupportedException |
|
1084 |
* @throws GeometryOperationException |
|
1085 |
*/ |
|
1086 |
private List<Stretch> createStretches(List<MSegment> mList, Point origin) |
|
1087 |
throws GeometryOperationNotSupportedException, GeometryOperationException { |
|
865 | 1088 |
|
866 |
private List <Route> createRoutes(List<MStructure> mList, Point origin) throws GeometryOperationNotSupportedException, GeometryOperationException{ |
|
867 |
List <Route> routes=new ArrayList<Route>(); |
|
868 |
for (MStructure mStructure:mList){ |
|
869 |
Geometry geometry=mStructure.geometry; |
|
870 |
List<Line> lines=LrsAlgorithmUtils.extractLines(geometry); |
|
871 |
for (Line initialLine:lines){ |
|
872 |
if (!isAddedLine(routes,initialLine)){ |
|
873 |
Route route=new Route(); |
|
874 |
routes.add(route); |
|
875 |
MStructure mStructureOrdered=mStructure.clone(); |
|
876 |
if (isFlippedLine(initialLine, origin)){ |
|
877 |
mStructureOrdered.geometry.flip(); |
|
878 |
route.initialPoint=initialLine.getVertex(initialLine.getNumVertices()-1); |
|
879 |
route.finalPoint=initialLine.getVertex(0); |
|
880 |
}else{ |
|
881 |
route.initialPoint=initialLine.getVertex(0); |
|
882 |
route.finalPoint=initialLine.getVertex(initialLine.getNumVertices()-1); |
|
883 |
} |
|
1089 |
List<MSegment> addedMSegment = new ArrayList<LrsCreateRouteAlgorithm.MSegment>(); |
|
1090 |
List<Stretch> stretches = new ArrayList<Stretch>(); |
|
1091 |
while (addedMSegment.size() < mList.size()) { |
|
1092 |
for (MSegment mSegment : mList) { |
|
1093 |
if (!addedMSegment.contains(mSegment)) { |
|
1094 |
Stretch stretch = new Stretch(); |
|
1095 |
stretches.add(stretch); |
|
1096 |
stretch.addSegment(mSegment); |
|
1097 |
addedMSegment.add(mSegment); |
|
884 | 1098 |
|
885 |
route.structures.add(mStructureOrdered); |
|
886 |
route.lines.add(initialLine); |
|
887 |
Double initialPointDistance=route.initialPoint.distance(origin); |
|
888 |
Double finalPointDistance=route.finalPoint.distance(origin); |
|
889 |
int i=0; |
|
890 |
boolean insertLowPriority=false; |
|
891 |
while (i<mList.size() && !insertLowPriority){ |
|
892 |
if (i>=mList.size()){ |
|
893 |
insertLowPriority=true; |
|
894 |
i=0; |
|
1099 |
List<MSegment> initialNextSegments = |
|
1100 |
mSegment.searchNextSegments(stretch.getInitialPoint(), mList); |
|
1101 |
do { |
|
1102 |
if (initialNextSegments.size() == 1) { |
|
1103 |
MSegment previousSegment = initialNextSegments.get(0); |
|
1104 |
if (!addedMSegment.contains(previousSegment)) { |
|
1105 |
if (!previousSegment.getFinalPoint().equals(stretch.getInitialPoint())) { |
|
1106 |
previousSegment.flip(); |
|
1107 |
} |
|
1108 |
stretch.addSegment(0, previousSegment); |
|
1109 |
addedMSegment.add(previousSegment); |
|
1110 |
initialNextSegments = |
|
1111 |
previousSegment.searchNextSegments(stretch.getInitialPoint(), mList); |
|
1112 |
} else { |
|
1113 |
break; |
|
1114 |
} |
|
1115 |
} else { |
|
1116 |
break; |
|
895 | 1117 |
} |
896 |
boolean lineAdded=false; |
|
897 |
MStructure mStructureAdded=mList.get(i); |
|
898 |
Geometry geometryAdded=mStructureAdded.geometry; |
|
899 |
List<Line> linesAdded=LrsAlgorithmUtils.extractLines(geometryAdded); |
|
900 |
for (Line addedLine:linesAdded){ |
|
901 |
if (!isAddedLine(routes,addedLine)){ |
|
1118 |
} while (initialNextSegments.size() == 1); |
|
902 | 1119 |
|
903 |
MStructure mStructureAddedOrdered=mStructureAdded.clone(); |
|
904 |
Point initialPoint=addedLine.getVertex(0); |
|
905 |
Point finalPoint=addedLine.getVertex(addedLine.getNumVertices()-1); |
|
906 |
|
|
907 |
if ( route.initialPoint.equals(initialPoint) ){ |
|
908 |
if (!isTriplePoint(mList,initialPoint)){ |
|
909 |
Double distanceAddedPoint=origin.distance(finalPoint); |
|
910 |
boolean lowPriority=false; |
|
911 |
if (distanceAddedPoint>finalPointDistance){ |
|
912 |
lowPriority=true; |
|
913 |
} |
|
914 |
if (!lowPriority||insertLowPriority){ |
|
915 |
initialPointDistance=distanceAddedPoint; |
|
916 |
mStructureAddedOrdered.geometry.flip(); |
|
917 |
route.initialPoint=finalPoint; |
|
918 |
route.structures.add(0, mStructureAddedOrdered); |
|
919 |
route.lines.add(addedLine); |
|
920 |
lineAdded=true; |
|
921 |
} |
|
922 |
} |
|
923 |
}else if ( route.initialPoint.equals(finalPoint) ) { |
|
924 |
if (!isTriplePoint(mList,finalPoint)){ |
|
925 |
Double distanceAddedPoint=origin.distance(initialPoint); |
|
926 |
boolean lowPriority=false; |
|
927 |
if (distanceAddedPoint>initialPointDistance){ |
|
928 |
lowPriority=true; |
|
929 |
} |
|
930 |
if (!lowPriority||insertLowPriority){ |
|
931 |
initialPointDistance=distanceAddedPoint; |
|
932 |
route.initialPoint=initialPoint; |
|
933 |
route.structures.add(0, mStructureAddedOrdered); |
|
934 |
route.lines.add(addedLine); |
|
935 |
lineAdded=true; |
|
936 |
} |
|
937 |
} |
|
938 |
}else if ( route.finalPoint.equals(initialPoint) ){ |
|
939 |
if (!isTriplePoint(mList,finalPoint)){ |
|
940 |
Double distanceAddedPoint=origin.distance(initialPoint); |
|
941 |
boolean lowPriority=false; |
Also available in: Unified diff