Revision 27

View differences:

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
22 22
 */
23 23
package org.gvsig.lrs.lib.impl;
24 24

  
25
import java.awt.Dimension;
26
import java.awt.geom.Point2D;
27
import java.io.File;
28
import java.sql.Array;
29 25
import java.util.ArrayList;
30
import java.util.Arrays;
26
import java.util.Collections;
31 27
import java.util.Comparator;
32 28
import java.util.HashMap;
33
import java.util.Iterator;
34 29
import java.util.List;
35 30
import java.util.Map;
36 31
import java.util.Map.Entry;
32
import java.util.SortedMap;
33
import java.util.TreeMap;
37 34

  
38
import javax.xml.transform.Source;
39

  
40
import org.apache.commons.lang3.mutable.MutableDouble;
41
import org.gvsig.fmap.dal.DALLocator;
42
import org.gvsig.fmap.dal.DataManager;
43
import org.gvsig.fmap.dal.DataServerExplorer;
44
import org.gvsig.fmap.dal.DataServerExplorerParameters;
45
import org.gvsig.fmap.dal.DataStore;
46
import org.gvsig.fmap.dal.DataTypes;
47
import org.gvsig.fmap.dal.exception.DataException;
35
import org.apache.commons.lang3.mutable.MutableInt;
48 36
import org.gvsig.fmap.dal.feature.EditableFeature;
49
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
50
import org.gvsig.fmap.dal.feature.EditableFeatureType;
51 37
import org.gvsig.fmap.dal.feature.Feature;
52 38
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
53 39
import org.gvsig.fmap.dal.feature.FeatureReference;
......
55 41
import org.gvsig.fmap.dal.feature.FeatureSet;
56 42
import org.gvsig.fmap.dal.feature.FeatureStore;
57 43
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
58
import org.gvsig.fmap.dal.store.shp.SHPNewStoreParameters;
59 44
import org.gvsig.fmap.geom.Geometry;
60 45
import org.gvsig.fmap.geom.Geometry.DIMENSIONS;
61
import org.gvsig.fmap.geom.GeometryException;
62 46
import org.gvsig.fmap.geom.GeometryLocator;
63 47
import org.gvsig.fmap.geom.GeometryManager;
64 48
import org.gvsig.fmap.geom.aggregate.MultiLine;
......
69 53
import org.gvsig.fmap.geom.primitive.Envelope;
70 54
import org.gvsig.fmap.geom.primitive.Line;
71 55
import org.gvsig.fmap.geom.primitive.Point;
72
import org.gvsig.fmap.geom.type.GeometryType;
73 56
import org.gvsig.lrs.lib.api.LrsAlgorithm;
74 57
import org.gvsig.lrs.lib.api.LrsAlgorithmParams;
75 58
import org.gvsig.lrs.lib.api.LrsCoordinatesPriority;
......
81 64
import org.gvsig.tools.dataTypes.DataType;
82 65
import org.gvsig.tools.exception.BaseException;
83 66
import org.gvsig.tools.i18n.I18nManager;
67
import org.gvsig.tools.locator.LocatorException;
84 68
import org.gvsig.tools.service.Manager;
85 69
import org.gvsig.tools.task.SimpleTaskStatus;
86 70
import org.gvsig.tools.visitor.VisitCanceledException;
87 71
import org.gvsig.tools.visitor.Visitor;
72
import org.omg.CosNaming.IstringHelper;
88 73
import org.slf4j.Logger;
89 74
import org.slf4j.LoggerFactory;
90 75

  
......
94 79
 */
95 80
public class LrsCreateRouteAlgorithm implements LrsAlgorithm {
96 81

  
97
    private static final Logger logger = LoggerFactory.getLogger(LrsCreateRouteAlgorithm.class);
82
    private static final Logger logger =
83
        LoggerFactory.getLogger(LrsCreateRouteAlgorithm.class);
98 84

  
99 85
    private LrsCreateRouteAlgorithmParams parameters;
100 86

  
101

  
102 87
    /**
103 88
     *
104 89
     */
......
121 106
     *
122 107
     * @see org.gvsig.lrs.lib.api.LrsAlgorithm#getParams()
123 108
     */
124
    public  LrsAlgorithmParams getParams() {
109
    public LrsAlgorithmParams getParams() {
125 110
        return this.parameters;
126 111
    }
127 112

  
128 113
    /*
129 114
     * (non-Javadoc)
130
     * @see org.gvsig.lrs.lib.api.LrsAlgorithm#execute(org.gvsig.tools.task.SimpleTaskStatus)
115
     *
116
     * @see org.gvsig.lrs.lib.api.LrsAlgorithm#execute(org.gvsig.tools.task.
117
     * SimpleTaskStatus)
131 118
     */
132 119
    public void execute(SimpleTaskStatus taskStatus) throws LrsException {
133
        NewFeatureStoreParameters newFeatureStoreParameters = parameters.getNewFeatureStoreParameters();
120
        NewFeatureStoreParameters newFeatureStoreParameters =
121
            parameters.getNewFeatureStoreParameters();
134 122
        FeatureStore sourceFeatureStore = parameters.getSourceFeatureStore();
135 123
        FeatureAttributeDescriptor idRouteField = parameters.getIdRouteField();
136
        //LrsCoordinatesPriority coordinatePriority = parameters.getCoordinatePriority();
137
        //LrsSourceOfMeasures sourceOfMeasures = parameters.getSourceOfMeasures();
138
        FeatureAttributeDescriptor fromMeasureField = parameters.getFromMeasureField();
139
        FeatureAttributeDescriptor toMeasureField = parameters.getToMeasureField();
140
        //double measureFactor = parameters.getMeasureFactor();
141
        //double measureOffset = parameters.getMeasureOffset();
142
        //boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps();
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();
143 135

  
144 136
        logger.info(parameters.toString());
145 137

  
......
148 140
        taskStatus.message(i18nManager.getTranslation("grouping_features"));
149 141

  
150 142
        try {
151
            final String routeFieldName=idRouteField.getName();
143
            final String routeFieldName = idRouteField.getName();
152 144
            final String fromFieldName;
153 145
            final DataType fromDataType;
154 146
            final DataType toDataType;
155
            if (fromMeasureField!=null){
156
                fromFieldName=fromMeasureField.getName();
157
                fromDataType=fromMeasureField.getDataType();
158
            }else{
159
                fromFieldName=null;
160
                fromDataType=null;
147
            if (fromMeasureField != null) {
148
                fromFieldName = fromMeasureField.getName();
149
                fromDataType = fromMeasureField.getDataType();
150
            } else {
151
                fromFieldName = null;
152
                fromDataType = null;
161 153
            }
162 154
            final String toFieldName;
163
            if (toMeasureField!=null){
164
                toFieldName=toMeasureField.getName();
165
                toDataType=toMeasureField.getDataType();
166
            }else{
167
                toFieldName=null;
168
                toDataType=null;
155
            if (toMeasureField != null) {
156
                toFieldName = toMeasureField.getName();
157
                toDataType = toMeasureField.getDataType();
158
            } else {
159
                toFieldName = null;
160
                toDataType = null;
169 161
            }
170 162

  
171
            FeatureStore newFeatureStore=LrsAlgorithmUtils.createNewDataStore(newFeatureStoreParameters,idRouteField);
163
            FeatureStore newFeatureStore = LrsAlgorithmUtils
164
                .createNewDataStore(newFeatureStoreParameters, idRouteField);
172 165

  
173 166
            FeatureSet sourceFeatures;
174
            if (sourceFeatureStore.getFeatureSelection().getSize()>0){
175
                sourceFeatures=sourceFeatureStore.getFeatureSelection();
176
            }else{
177
                sourceFeatures=sourceFeatureStore.getFeatureSet();
167
            if (sourceFeatureStore.getFeatureSelection().getSize() > 0) {
168
                sourceFeatures = sourceFeatureStore.getFeatureSelection();
169
            } else {
170
                sourceFeatures = sourceFeatureStore.getFeatureSet();
178 171
            }
179 172

  
180
            final Map<String,List<MStructure>> featuresMap=new HashMap<String, List<MStructure>>();
173
            final SortedMap<String, List<MStructure>> featuresMap =
174
                new TreeMap<String, List<MStructure>>();
175
            final MutableInt contId=new MutableInt(0);
181 176
            sourceFeatures.accept(new Visitor() {
182 177

  
183
                public void visit(Object obj) throws VisitCanceledException, BaseException {
184
                    Feature feature=(Feature)obj;
185
                    String routeName=(String)feature.get(routeFieldName);
186
                    Geometry originalGeometry=feature.getDefaultGeometry();
187
                    Object objFrom=null;
188
                    Object objTo=null;
189
                    if (fromFieldName!=null){
190
                        objFrom=feature.get(fromFieldName);
178
                public void visit(Object obj)
179
                    throws VisitCanceledException, BaseException {
180
                    Feature feature = (Feature) obj;
181
                    String routeName = (String) feature.get(routeFieldName);
182
                    Geometry originalGeometry = feature.getDefaultGeometry();
183
                    Object objFrom = null;
184
                    Object objTo = null;
185
                    if (fromFieldName != null) {
186
                        objFrom = feature.get(fromFieldName);
191 187
                    }
192
                    if (toFieldName!=null){
193
                        objTo=feature.get(toFieldName);
188
                    if (toFieldName != null) {
189
                        objTo = feature.get(toFieldName);
194 190
                    }
195
                    if (!featuresMap.containsKey(routeName)){
191
                    if (!featuresMap.containsKey(routeName)) {
196 192
                        featuresMap.put(routeName, new ArrayList<MStructure>());
197 193
                    }
198
                    List<MStructure> mList=featuresMap.get(routeName);
199
                    MStructure mStructure=new MStructure();
200
                    mStructure.geometry=originalGeometry;
201
                    mStructure.fromField=LrsAlgorithmUtils.getAsDouble(objFrom,fromDataType);
202
                    mStructure.toField=LrsAlgorithmUtils.getAsDouble(objTo,toDataType);
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();
202
                    contId.increment();
203 203
                    mList.add(mStructure);
204 204
                    featuresMap.put(routeName, mList);
205 205
                }
206 206
            });
207

  
208 207
            taskStatus.setRangeOfValues(0, featuresMap.size());
209
            int taskCount=0;
208
            int taskCount = 0;
210 209

  
211 210
            newFeatureStore.edit(FeatureStore.MODE_FULLEDIT);
212 211

  
213
            //TODO Added to facilitate Tests. Remove afterwards
214
            StringBuffer resultDebug=new StringBuffer();
215
            LrsSourceOfMeasures sourceOfMeasures = parameters.getSourceOfMeasures();
212
            // TODO Added to facilitate Tests. Remove afterwards
213
            StringBuffer resultDebug = new StringBuffer();
214
            LrsSourceOfMeasures sourceOfMeasures =
215
                parameters.getSourceOfMeasures();
216 216
            boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps();
217
            LrsCoordinatesPriority coordinatePriority = parameters.getCoordinatePriority();
217
            LrsCoordinatesPriority coordinatePriority =
218
                parameters.getCoordinatePriority();
218 219

  
219
            resultDebug.append (sourceOfMeasures.getName());
220
            if (!sourceOfMeasures.equals(LrsSourceOfMeasures.TWO_FIELDS)){
221
                if (ignoreSpatialGaps)resultDebug.append (" WITHOUT GAPS ");
222
                else resultDebug.append (" WITH GAPS ");
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 ");
223 226
                resultDebug.append(coordinatePriority.getName());
224 227
            }
225
            //END of Test addition
228
            // END of Test addition
226 229

  
227
            for(Entry<String, List<MStructure>> entry : featuresMap.entrySet()) {
230
            for (Entry<String, List<MStructure>> entry : featuresMap
231
                .entrySet()) {
228 232
                String routeName = entry.getKey();
229 233
                List<MStructure> mList = entry.getValue();
230 234

  
231
                EditableFeature newFeature = newFeatureStore.createNewFeature(true);
235
                EditableFeature newFeature =
236
                    newFeatureStore.createNewFeature(true);
232 237
                newFeature.set(routeFieldName, routeName);
233 238
                Geometry route = createGeometryRoute(mList);
234 239
                newFeature.setDefaultGeometry(route);
235 240

  
236

  
237
                //TODO Added to facilitate Tests. Remove afterwards
238
                String lineSeparator=System.getProperty("line.separator");
241
                // TODO Added to facilitate Tests. Remove afterwards
242
                String lineSeparator = System.getProperty("line.separator");
239 243
                resultDebug.append(lineSeparator);
240
                resultDebug.append("Route: "+routeName);
244
                resultDebug.append("Route: " + routeName);
241 245
                resultDebug.append(lineSeparator);
242
                if (route instanceof MultiLine){
243
                    MultiLine multiLine=(MultiLine)route;
244
                    for (int j=0;j<multiLine.getPrimitivesNumber();j++){
245
                        Line line=(Line)multiLine.getPrimitiveAt(j);
246
                        resultDebug.append("Line "+j+":[");
247
                        for (int i=0;i<line.getNumVertices();i++){
248
                            Point point=line.getVertex(i);
249
                            Double x=point.getX();
250
                            Double y=point.getY();
251
                            Double m=point.getCoordinateAt(point.getDimension()-1);
252
                            resultDebug.append("(x="+x.toString()+",y="+y.toString()+",m="+m.toString()+")");
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() + ")");
253 259
                        }
254 260
                        resultDebug.append("]");
255 261
                        resultDebug.append(lineSeparator);
256 262
                    }
257 263
                }
258 264

  
259
                //END of Test addition
265
                // END of Test addition
260 266

  
261

  
262 267
                newFeatureStore.update(newFeature);
263 268

  
264 269
                taskCount++;
......
273 278
            throw new LrsCreateRouteException("Error creating routes", e1);
274 279
        }
275 280

  
276

  
277 281
        taskStatus.terminate();
278 282

  
279

  
280
//        FeatureSelection selection;
281
//        try {
282
//            outputFeatureStore.edit(FeatureStore.MODE_FULLEDIT);
283
//            selection = sourceFeatureStore.getFeatureSelection();
284
//            if (selection == null || selection.isEmpty()) {
285
//                selection = sourceFeatureStore.createFeatureSelection();
286
//                selection.selectAll();
287
//            }
288
//            taskStatus.message("Grouping features");
289
//            Map<Object, List<FeatureReference>> groupedReferences = getGroupedReferences(selection, idRouteField);
290
//
291
//            taskStatus.message("Creating routes");
292
//
293
//            Set<Object> keys = groupedReferences.keySet();
294
//            taskStatus.setRangeOfValues(0, keys.size());
295
//            int i=0;
296
//            for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
297
//                taskStatus.setCurValue(i++);
298
//                Object key = (Object) iterator.next();
299
//                EditableFeature newFeature = outputFeatureStore.createNewFeature(true);
300
//                newFeature.set(idRouteField.getName(), key);
301
//
302
//                List<FeatureReference> references = groupedReferences.get(key);
303
//                Geometry route = createRoute(references, coordinatePriority, sourceOfMeasures, fromMeasureField, toMeasureField, measureFactor, measureOffset, ignoreSpatialGaps);
304
//                route = calibrateRoute(route);
305
//                newFeature.setDefaultGeometry(route);
306
//                outputFeatureStore.update(newFeature);
307
//            }
308
//            outputFeatureStore.finishEditing();
309
//            taskStatus.terminate();
310
//
311
//        } catch (DataException e) {
312
//            // TODO Auto-generated catch block
313
//            e.printStackTrace();
314
//        } catch (BaseException e) {
315
//            // TODO Auto-generated catch block
316
//            e.printStackTrace();
317
//        }
318 283
    }
319 284

  
320
    private Geometry createGeometryRoute(List<MStructure> mList) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
321
        LrsSourceOfMeasures sourceOfMeasures =parameters.getSourceOfMeasures();
322
        Geometry geometryResult=null;
285
    private Geometry createGeometryRoute(List<MStructure> mList)
286
        throws CreateGeometryException, GeometryOperationNotSupportedException,
287
        GeometryOperationException {
288
        LrsSourceOfMeasures sourceOfMeasures = parameters.getSourceOfMeasures();
289
        Geometry geometryResult = null;
290
        simplifyMultilines(mList);
323 291
        switch (sourceOfMeasures) {
324 292
        case ONE_FIELD:
325
            geometryResult= calculateGeometryByOneField(mList);
293
            geometryResult = calculateGeometryByOneField(mList);
326 294
            break;
327 295
        case TWO_FIELDS:
328
            geometryResult= calculateGeometryByTwoField(mList);
296
            geometryResult = calculateGeometryByTwoField(mList);
329 297
            break;
330 298
        case LENGTH:
331 299
        default:
332
            geometryResult= calculateGeometryByLength(mList);
300
            geometryResult = calculateGeometryByLength(mList);
333 301
            break;
334 302
        }
335
        geometryResult=applyOffset(geometryResult);
303
        geometryResult = simplifyMultiline(geometryResult);
304
        geometryResult = applyOffset(geometryResult);
336 305
        return geometryResult;
337 306
    }
338 307

  
339
    private Geometry calculateGeometryByLength(List<MStructure> mList) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException{
340
        return null;
308
    private Geometry calculateGeometryByLength(List<MStructure> mList)
309
        throws CreateGeometryException, GeometryOperationNotSupportedException,
310
        GeometryOperationException {
311
        boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps();
312
        for (MStructure mStructure : mList) {
313
            mStructure.fromField =
314
                getGeometryLength(mStructure.geometry, ignoreSpatialGaps);
315
        }
316
        return calculateGeometryByOneField(mList);
341 317
    }
342 318

  
343
    private Geometry calculateGeometryByOneField(List<MStructure> mList) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
319
    private Geometry calculateGeometryByOneField(List<MStructure> mList)
320
        throws CreateGeometryException, GeometryOperationNotSupportedException,
321
        GeometryOperationException {
344 322
        boolean ignoreSpatialGaps = parameters.ignoreSpatialGaps();
345
        GeometryManager geomanager= GeometryLocator.getGeometryManager();
323
        GeometryManager geomanager = GeometryLocator.getGeometryManager();
346 324
        try {
347
            sortMList(mList);
325
            mList=sortMList(mList);
348 326
        } catch (Exception e) {
349 327
            logger.warn("Geometries couldn't be ordered");
350 328
        }
351
        MultiLine mGeometry= (MultiLine)geomanager.create(Geometry.TYPES.MULTILINE, Geometry.SUBTYPES.GEOM2DM);
352
        MutableDouble lastMValue=new MutableDouble(0);
353
        Double gap=Double.valueOf(0);
354
        Point lastPoint=null;
355
        for (MStructure mStructure:mList){
356
            Geometry geometry=mStructure.geometry;
357
            if(!ignoreSpatialGaps){
358
                gap=calculateGap(lastPoint, geometry);
359
                lastMValue.add(gap);
329

  
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;
336

  
337
        for (MStructure mStructure : mList) {
338
            Geometry geometry = mStructure.geometry;
339
            List<Line> geometryLines=extractLines(geometry);
340
            Double geometryLength=getGeometryLength(geometry, ignoreSpatialGaps);
341
            boolean firstLineInGeometry=true;
342

  
343
            if (!ignoreSpatialGaps) {
344
                gapBetweenGeometries = calculateGap(lastPoint, geometry);
345
                lastMValueGeometry+=gapBetweenGeometries;
360 346
            }
361
            Double fromDistance=lastMValue.getValue();
362
            lastMValue.add(mStructure.fromField);
363
            Double toDistance=lastMValue.getValue();
347
            Double previouslyCalculatedMValue= getCalculatedMValueForFirstPoint(mGeometry,geometry);
348
            if (previouslyCalculatedMValue!=null){
349
                lastPoint=null;
350
                lastMValueGeometry=previouslyCalculatedMValue;
351
            }
364 352

  
365
            if (geometry instanceof Line){
366
                Line line=(Line) geometry;
367
                Line lineM=lineToMLine(line, fromDistance, toDistance);
368
                mGeometry.addPrimitive(lineM);
369
                lastPoint=lineM.getVertex(lineM.getNumVertices()-1);
370
            }
371
            if (geometry instanceof MultiLine){
372
                MultiLine multiLine =(MultiLine) geometry;
373
                Line[] lines=multilineToMlines(multiLine, fromDistance, toDistance,ignoreSpatialGaps);
374
                for (Line lineM:lines){
375
                    mGeometry.addPrimitive(lineM);
376
                    lastPoint=lineM.getVertex(lineM.getNumVertices()-1);
353
            Double geometryMFirstPoint = lastMValueGeometry;
354
            lastMValueGeometry+=mStructure.fromField;
355
            Double geometryMLastPoint=lastMValueGeometry;
356

  
357
            Double distance=Double.valueOf(0);;
358
            for (Line line:geometryLines){
359
                Double gapBetweenLines = Double.valueOf(0);
360
                Double lineLength=getLineLength(line);
361
                if (!ignoreSpatialGaps&&!firstLineInGeometry) {
362
                    gapBetweenLines = calculateGap(lastPoint, line);
363
                    distance+=gapBetweenLines;
364
                    firstLineInGeometry=false;
377 365
                }
366

  
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);
378 375
            }
379 376
        }
380 377
        return mGeometry;
378

  
379

  
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);
404
//                }
405
//            }
406
//        }
407
//        return mGeometry;
381 408
    }
382 409

  
383
    private Double calculateGap(Point lastPoint, Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException{
384
        Double gap=new Double(0);
385
        if (geometry instanceof Line){
386
            Line line=(Line) geometry;
387
            if (lastPoint!=null){
388
                Point firstPoint=line.getVertex(0);
389
                gap=firstPoint.distance(lastPoint);
410
    private Double getCalculatedMValueForFirstPoint(Geometry mGeometry,Geometry geometry){
411
        List<Point> mPoints=extractPoints(mGeometry);
412
        Point point=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);
390 417
            }
391 418
        }
392
        if (geometry instanceof MultiLine){
393
            MultiLine multiLine =(MultiLine) geometry;
394
            if (lastPoint!=null){
395
                Line line=(Line) multiLine.getPrimitiveAt(0);
396
                Point firstPoint=line.getVertex(0);
397
                gap=firstPoint.distance(lastPoint);
419
        return null;
420
    }
421

  
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);
428

  
429
        for (MStructure mStructure : mList) {
430
            Geometry geometry = mStructure.geometry;
431
            List<Line> geometryLines=extractLines(geometry);
432
            Double geometryLength=getGeometryLength(geometry);
433

  
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=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);
398 447
            }
399 448
        }
449

  
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);
458
//            }
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
//        }
468

  
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;
500
//            }
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
//        }
509
//        return lines;
510
//    }
511

  
512
    private Line lineToMLine(Line line, Double minMValue, Double maxMValue)
513
        throws CreateGeometryException, GeometryOperationNotSupportedException,
514
        GeometryOperationException {
515
        GeometryManager geomanager = GeometryLocator.getGeometryManager();
516
        Double lineLength = getLineLength(line);
517
        Line lineM = (Line) geomanager.create(Geometry.TYPES.LINE,
518
            Geometry.SUBTYPES.GEOM2DM);
519
        Double inLineDistance = Double.valueOf(0);
520
        for (int i = 0; i < line.getNumVertices(); i++) {
521
            Point vertex = line.getVertex(i);
522
            Point mVertex = (Point) geomanager.create(Geometry.TYPES.POINT,
523
                Geometry.SUBTYPES.GEOM2DM);
524
            mVertex.setX(vertex.getX());
525
            mVertex.setY(vertex.getY());
526

  
527
            Double mValue;
528
            if (i == 0)
529
                mValue = minMValue;
530
            else if (i == line.getNumVertices() - 1)
531
                mValue = maxMValue;
532
            else {
533
                Point previousVertex = line.getVertex(i - 1);
534
                inLineDistance += vertex.distance(previousVertex);
535
                mValue = calculateM(maxMValue, minMValue, inLineDistance,
536
                    lineLength);
537
            }
538

  
539
            mVertex.setCoordinateAt(mVertex.getDimension() - 1, mValue);
540
            lineM.addVertex(mVertex);
541
        }
542
        return lineM;
543
    }
544

  
545
    private Double calculateM(Double maxValue, Double minValue,
546
        Double relativeDistance, Double totalLength) {
547
        // mValue=((newMax-newMin)*(mCoordinate-oldMin)/(oldMax-oldMin))+newMin;
548
        if (totalLength.equals(Double.valueOf(0)))
549
            return Double.POSITIVE_INFINITY;
550
        return ((maxValue - minValue) * (relativeDistance) / (totalLength))
551
            + minValue;
552
    }
553

  
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);
560
        }
561
        mList = simplifiedMList;
562
    }
563

  
564
    private Geometry simplifyMultiline(Geometry geometry) throws CreateGeometryException, LocatorException{
565
        if (geometry instanceof MultiLine) {
566
            MultiLine multiline = (MultiLine) geometry;
567

  
568
            if (multiline.getPrimitivesNumber() == 1) {
569
                return multiline.getPrimitiveAt(0);
570
            } else {
571
                List<Line> simplifiedLines = new ArrayList<Line>();
572
                List<Line> complexLines = new ArrayList<Line>();
573
                for (int i = 0; i < multiline.getPrimitivesNumber(); i++) {
574
                    complexLines.add((Line) multiline.getPrimitiveAt(i));
575
                }
576

  
577
                Line line = null;
578
                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
                        }
587
                        Line unitedLine = unionAdjacentLines(line, auxLine);
588
                        if (unitedLine != null) {
589
                            line = unitedLine;
590
                            complexLines.remove(i);
591
                            i=0;
592
                        }else{
593
                            i++;
594
                        }
595
                    }
596
                    simplifiedLines.add(line);
597
                }
598

  
599
                if (simplifiedLines.size() == 1) {
600
                    geometry = simplifiedLines.get(0);
601
                } else {
602
                    MultiLine simplifiedMultiLine =
603
                        (MultiLine) GeometryLocator.getGeometryManager()
604
                            .create(multiline.getGeometryType());
605
                    for (Line simpleLine : simplifiedLines) {
606
                        simplifiedMultiLine.addPrimitive(simpleLine);
607
                    }
608
                    return simplifiedMultiLine;
609
                }
610
            }
611
        }
612
        return geometry;
613
    }
614

  
615
    private Line unionAdjacentLines(Line line1, Line line2) {
616
        if (line1 == null || line2 == null) {
617
            return null;
618
        }
619
        Line resultLine;
620
        try {
621
            resultLine = (Line) GeometryLocator.getGeometryManager()
622
                .create(line1.getGeometryType());
623
        } catch (Exception e) {
624
            return null;
625
        }
626

  
627
        Point firstPointL1 = line1.getVertex(0);
628
        Point lastPointL1 = line1.getVertex(line1.getNumVertices() - 1);
629
        Point firstPointL2 = line2.getVertex(0);
630
        Point lastPointL2 = line2.getVertex(line2.getNumVertices() - 1);
631
        if (lastPointL1.equals(firstPointL2)) {
632
            resultLine = (Line) line1.cloneGeometry();
633
            for (int i = 1; i < line2.getNumVertices(); i++) {
634
                resultLine
635
                    .addVertex((Point) line2.getVertex(i).cloneGeometry());
636
            }
637
            return resultLine;
638
        }
639
        if (lastPointL2.equals(firstPointL1)) {
640
            resultLine = (Line) line2.cloneGeometry();
641
            for (int i = 1; i < line1.getNumVertices(); i++) {
642
                resultLine
643
                    .addVertex((Point) line1.getVertex(i).cloneGeometry());
644
            }
645
            return resultLine;
646
        }
647
        if (firstPointL1.equals(firstPointL2)) {
648
            for (int i = line1.getNumVertices() - 1; i >= 0; i--) {
649
                resultLine
650
                    .addVertex((Point) line1.getVertex(i).cloneGeometry());
651
            }
652
            for (int i = 1; i < line2.getNumVertices(); i++) {
653
                resultLine
654
                    .addVertex((Point) line2.getVertex(i).cloneGeometry());
655
            }
656
            return resultLine;
657
        }
658
        if (lastPointL1.equals(lastPointL2)) {
659
            resultLine = (Line) line1.cloneGeometry();
660
            for (int i = line2.getNumVertices() - 2; i >= 0; i--) {
661
                resultLine
662
                    .addVertex((Point) line2.getVertex(i).cloneGeometry());
663
            }
664
            return resultLine;
665
        }
666
        return null;
667
    }
668

  
669

  
670
//    private Double calculateGap(Point lastPoint, Line line)
671
//        throws GeometryOperationNotSupportedException,
672
//        GeometryOperationException {
673
//        Double gap = new Double(0);
674
//        if (lastPoint != null) {
675
//            Point firstPoint = line.getVertex(0);
676
//            gap = firstPoint.distance(lastPoint);
677
//        }
678
//        return gap;
679
//    }
680

  
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
        }
400 700
        return gap;
401 701
    }
402 702

  
403
    private void sortMList(List<MStructure> mList) throws CreateEnvelopeException, GeometryOperationNotSupportedException, GeometryOperationException {
404
        LrsCoordinatesPriority coordinatePriority = parameters.getCoordinatePriority();
405
        GeometryManager geomanager= GeometryLocator.getGeometryManager();
703
    private List<MStructure> sortMList(List<MStructure> mList)
704
        throws CreateEnvelopeException, GeometryOperationNotSupportedException,
705
        GeometryOperationException {
706
        LrsCoordinatesPriority coordinatePriority =
707
            parameters.getCoordinatePriority();
708
        GeometryManager geomanager = GeometryLocator.getGeometryManager();
406 709
        Envelope envelope = geomanager.createEnvelope(Geometry.SUBTYPES.GEOM2D);
407
        for (MStructure mStructure:mList){
710
        for (MStructure mStructure : mList) {
408 711
            envelope.add(mStructure.geometry.getEnvelope());
409 712
        }
410
        Point origin=envelope.getLowerCorner();
713
        Point origin = envelope.getLowerCorner();
411 714
        switch (coordinatePriority) {
412 715
        case DOWN_LEFT:
413 716
            break;
414 717
        case DOWN_RIGHT:
415
            Double maxX =envelope.getMaximum(DIMENSIONS.X);
718
            Double maxX = envelope.getMaximum(DIMENSIONS.X);
416 719
            origin.setX(maxX);
417 720
            break;
418 721
        case UP_LEFT:
419
            Double maxY =envelope.getMaximum(DIMENSIONS.Y);
722
            Double maxY = envelope.getMaximum(DIMENSIONS.Y);
420 723
            origin.setY(maxY);
421 724
            break;
422 725
        case UP_RIGHT:
423
            origin=envelope.getUpperCorner();
726
            origin = envelope.getUpperCorner();
424 727
            break;
425 728
        default:
426 729
            break;
427 730
        }
428
        GeometryDistanceToPointComparator comaparatorMList=new GeometryDistanceToPointComparator(origin);
429
        MStructure[] orderedMStruct=(MStructure[])mList.toArray();
430
        Arrays.sort(orderedMStruct, comaparatorMList);
431
        mList=new ArrayList<MStructure>(Arrays.asList(orderedMStruct));
432 731

  
433
        for (MStructure mStructure:mList){
434
            Geometry geometry=mStructure.geometry;
435
            if (geometry instanceof Line){
436
                Line line=(Line)geometry;
437
                Double firstPointDistance=origin.distance(line.getVertex(0));
438
                Double lastPointDistance=origin.distance(line.getVertex(line.getNumVertices()-1));
439
                if (lastPointDistance<firstPointDistance){
440
                    geometry.flip();
441
                }
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

  
796
    }
797

  
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);
442 810
            }
443
            if (geometry instanceof MultiLine){
444
                MultiLine multiLine=(MultiLine)geometry;
445
                Line firstLine=(Line)multiLine.getPrimitiveAt(0);
446
                Line lastLine=(Line)multiLine.getPrimitiveAt(multiLine.getPrimitivesNumber()-1);
447
                Double firstPointDistance=origin.distance(firstLine.getVertex(0));
448
                Double lastPointDistance=origin.distance(lastLine.getVertex(lastLine.getNumVertices()-1));
449
                if (lastPointDistance<firstPointDistance){
450
                    geometry.flip();
451
                }
452
            }
453
            mStructure.geometry=geometry;
811
            initialPoint=route.finalPoint;
454 812
        }
813
        return orderedMList;
455 814
    }
456 815

  
457
    private Geometry applyOffset(Geometry geometry){
458
        double measureFactor = parameters.getMeasureFactor();
459
        double measureOffset = parameters.getMeasureOffset();
460
        if (geometry instanceof Line){
461
            Line line=(Line) geometry;
462
            for (int i=0;i<line.getNumVertices();i++){
463
                Point mVertex=line.getVertex(i);
464
                Double mValue=mVertex.getCoordinateAt(mVertex.getDimension()-1);
465
                Double newMValue=(mValue*measureFactor)+measureOffset;
466
                mVertex.setCoordinateAt(mVertex.getDimension()-1, newMValue);
467
                line.setVertex(i, mVertex);
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;
820

  
821
        if (!point.equals(originPoint)){
822
            if (isTriplePoint(mList, point)){
823
                point=originPoint;
468 824
            }
469 825
        }
470
        if (geometry instanceof MultiLine){
471
            MultiLine multiLine =(MultiLine) geometry;
472
            for (int i=0;i<multiLine.getPrimitivesNumber();i++){
473
                Line line=(Line) multiLine.getPrimitiveAt(i);
474
                for (int j=0;j<line.getNumVertices();j++){
475
                    Point mVertex=line.getVertex(j);
476
                    Double mValue=mVertex.getCoordinateAt(mVertex.getDimension()-1);
477
                    Double newMValue=(mValue*measureFactor)+measureOffset;
478
                    mVertex.setCoordinateAt(mVertex.getDimension()-1, newMValue);
479
                    line.setVertex(j, mVertex);
826

  
827
        for (Route route:routes){
828
            Double initialDistance=point.distance(route.initialPoint);
829
            if(initialDistance<minDistance){
830
                minDistance = initialDistance;
831
                nearestRoute = route;
832
            }
833
            Double finalDistance=point.distance(route.finalPoint);
834
            if(finalDistance<minDistance){
835
                minDistance = finalDistance;
836
                nearestRoute = route;
837
            }
838
        }
839
        Double initialDistance=point.distance(nearestRoute.initialPoint);
840
        Double finalDistance=point.distance(nearestRoute.finalPoint);
841

  
842
        if (finalDistance<initialDistance){
843
            Collections.reverse(nearestRoute.structures);
844
            for (MStructure structure :nearestRoute.structures){
845
                structure.geometry.flip();
846
            }
847
        }
848
        return nearestRoute;
849
    }
850

  
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;
480 859
                }
860
                i++;
481 861
            }
482 862
        }
483
        return geometry;
484 863
    }
485 864

  
486
    private Geometry calculateGeometryByTwoField(List<MStructure> mList) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException{
487
        GeometryManager geomanager= GeometryLocator.getGeometryManager();
488
        MultiLine mGeometry= (MultiLine)geomanager.create(Geometry.TYPES.MULTILINE, Geometry.SUBTYPES.GEOM2DM);
865

  
866
    private List <Route> createRoutes(List<MStructure> mList, Point origin) throws GeometryOperationNotSupportedException, GeometryOperationException{
867
        List <Route> routes=new ArrayList<Route>();
489 868
        for (MStructure mStructure:mList){
490 869
            Geometry geometry=mStructure.geometry;
491
            Double fromDistance=mStructure.fromField;
492
            Double toDistance=mStructure.toField;
493
            if (geometry instanceof Line){
494
                Line line=(Line) geometry;
495
                Line lineM=lineToMLine(line, fromDistance, toDistance);
496
                mGeometry.addPrimitive(lineM);
497
            }
498
            if (geometry instanceof MultiLine){
499
                MultiLine multiLine =(MultiLine) geometry;
500
                Line[] lines=multilineToMlines(multiLine, fromDistance, toDistance);
501
                for (Line lineM:lines){
502
                    mGeometry.addPrimitive(lineM);
870
            List<Line> lines=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
                    }
884

  
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;
895
                        }
896
                        boolean lineAdded=false;
897
                        MStructure mStructureAdded=mList.get(i);
898
                        Geometry geometryAdded=mStructureAdded.geometry;
899
                        List<Line> linesAdded=extractLines(geometryAdded);
900
                        for (Line addedLine:linesAdded){
901
                            if (!isAddedLine(routes,addedLine)){
902

  
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;
942
                                        if (distanceAddedPoint<initialPointDistance){
943
                                            lowPriority=true;
944
                                        }
945
                                        if (!lowPriority||insertLowPriority){
946
                                            finalPointDistance=distanceAddedPoint;
947
                                            route.finalPoint=finalPoint;
948
                                            route.structures.add(mStructureAddedOrdered);
949
                                            route.lines.add(addedLine);
950
                                            lineAdded=true;
951
                                        }
952
                                    }
953
                                }else if ( route.finalPoint.equals(finalPoint) ){
954
                                    if (!isTriplePoint(mList,finalPoint)){
955
                                        Double distanceAddedPoint=origin.distance(initialPoint);
956
                                        boolean lowPriority=false;
957
                                        if (distanceAddedPoint<finalPointDistance){
958
                                            lowPriority=true;
959
                                        }
960
                                        if (!lowPriority||insertLowPriority){
961
                                            finalPointDistance=distanceAddedPoint;
962
                                            mStructureAddedOrdered.geometry.flip();
963
                                            route.finalPoint=initialPoint;
964
                                            route.structures.add(mStructureAddedOrdered);
965
                                            route.lines.add(addedLine);
966
                                            lineAdded=true;
967
                                        }
968
                                    }
969
                                }
970
                            }
971
                        }
972
                        if (lineAdded){
973
                            i=0;
974
                        }else{
975
                            i++;
976
                        }
977
                    }
503 978
                }
504 979
            }
980

  
505 981
        }
982
        return routes;
983
    }
506 984

  
507
        return mGeometry;
985
    private boolean isTriplePoint(List <MStructure> mList,Point point){
986
        List <Point> points=new ArrayList<Point>();
987
        for (MStructure structure:mList){
988
            points.addAll(extractPoints(structure.geometry));
989
        }
990

  
991
        int cont=0;
992
        for (int i=0;i<points.size();i++){
993
            if (points.get(i).equals(point)){
994
                cont++;
995
            }
996
            if (cont==3){
997
                return true;
998
            }
999
        }
1000
        return false;
508 1001
    }
509
    private Line[] multilineToMlines(MultiLine multiLine,Double fromDistance, Double toDistance) throws GeometryOperationNotSupportedException, GeometryOperationException, CreateGeometryException{
510
        return multilineToMlines(multiLine,fromDistance, toDistance,true);
1002

  
1003
    private Point extractFirstPoint(Geometry geometry){
1004
        Point firstPoint=null;
1005
        List<Line> lines= extractLines(geometry);
1006
        if (lines!=null && !lines.isEmpty()){
1007
            firstPoint=lines.get(0).getVertex(0);
1008
        }
1009
        return firstPoint;
511 1010
    }
512
    private Line[] multilineToMlines(MultiLine multiLine,Double fromDistance, Double toDistance,boolean ignoreSpatialGaps) throws GeometryOperationNotSupportedException, GeometryOperationException, CreateGeometryException{
513 1011

  
514
        Line[] lines=new Line[multiLine.getPrimitivesNumber()];
515
        Double multiLineLength=getMultiLineLength(multiLine,ignoreSpatialGaps);
516
        Double mFirstPoint=fromDistance;
517
        Double mLastPoint=null;
518
        Double distance=Double.valueOf(0);
519
        Point lastPoint=null;
520
        for (int i=0;i<multiLine.getPrimitivesNumber();i++){
1012
    private List<Point> extractPoints(Geometry geometry){
1013
        List<Point> points=new ArrayList<Point>();
1014
        List<Line> lines=extractLines(geometry);
1015
        for (Line line: lines){
1016
            for (int i=0;i<line.getNumVertices();i++){
1017
                points.add(line.getVertex(i));
1018
            }
1019
        }
1020
        return points;
1021
    }
521 1022

  
522
            Line line=(Line) multiLine.getPrimitiveAt(i);
523
            Double lineLength=getLineLength(line);
524
            Double gap=Double.valueOf(0);
525

  
526
            if (!ignoreSpatialGaps&&lastPoint!=null){
527
                Point firstPoint=line.getVertex(0);
528
                gap=firstPoint.distance(lastPoint);
529
                distance+=gap;
1023
    private List<Line> extractLines(Geometry geometry){
1024
        List<Line> lines=new ArrayList<Line>();
1025
        if (geometry instanceof  Line){
1026
            lines.add((Line) geometry);
1027
        }
1028
        if (geometry instanceof MultiLine){
1029
            MultiLine multiline=(MultiLine)geometry;
1030
            for (int i=0;i<multiline.getPrimitivesNumber();i++){
1031
                lines.add((Line) multiline.getPrimitiveAt(i));
530 1032
            }
531
            mFirstPoint=calculateM(toDistance,fromDistance, distance, multiLineLength);
532
            distance+=lineLength;
533
            mLastPoint=calculateM(toDistance,fromDistance, distance, multiLineLength);
534
            lines[i]=lineToMLine(line, mFirstPoint, mLastPoint);
535
            lastPoint=lines[i].getVertex(line.getNumVertices()-1);
536 1033
        }
537 1034
        return lines;
538 1035
    }
539 1036

  
540
    private Line lineToMLine(Line line,Double minMValue, Double maxMValue) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException{
541
        GeometryManager geomanager= GeometryLocator.getGeometryManager();
542
        Double lineLength=getLineLength(line);
543
        Line lineM=(Line)geomanager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM);
544
        Double inLineDistance=Double.valueOf(0);
545
        for (int i=0;i<line.getNumVertices();i++){
546
            Point vertex=line.getVertex(i);
547
            Point mVertex=(Point)geomanager.create(Geometry.TYPES.POINT, Geometry.SUBTYPES.GEOM2DM);
548
            mVertex.setX(vertex.getX());
549
            mVertex.setY(vertex.getY());
550

  
551
            Double mValue;
552
            if (i==0)mValue=minMValue;
553
            else if (i==line.getNumVertices()-1) mValue=maxMValue;
554
            else{
555
                Point previousVertex=line.getVertex(i-1);
556
                inLineDistance+=vertex.distance(previousVertex);
557
                mValue=calculateM(maxMValue,minMValue, inLineDistance, lineLength);
1037
    private boolean isAddedLine(List<Route> routes,Line line){
1038
        for (Route route:routes){
1039
            if (route.lines.contains(line)){
1040
                return true;
558 1041
            }
559

  
560
            mVertex.setCoordinateAt(mVertex.getDimension()-1, mValue);
561
            lineM.addVertex(mVertex);
562 1042
        }
563
        return lineM;
1043
        return false;
564 1044
    }
565 1045

  
566
    private Double calculateM(Double maxValue, Double minValue, Double relativeDistance, Double totalLength){
567
        //mValue=((newMax-newMin)*(mCoordinate-oldMin)/(oldMax-oldMin))+newMin;
568
        if (totalLength.equals(Double.valueOf(0) )) return Double.POSITIVE_INFINITY;
569
        return ((maxValue-minValue)*(relativeDistance)/(totalLength))+minValue;
1046
    private boolean isFlippedLine(Line line,Point origin) throws GeometryOperationNotSupportedException, GeometryOperationException{
1047
        Point initialPoint=line.getVertex(0);
1048
        Point finalPoint=line.getVertex(line.getNumVertices()-1);
1049
        Double distance1=origin.distance(initialPoint);
1050
        Double distance2=origin.distance(finalPoint);
1051
        if (distance1>distance2){
1052
            return true;
1053
        }else {
1054
            return false;
1055
        }
570 1056
    }
571 1057

  
572
//    private Line lineToMLine(Line line,Point previousVertex, MutableDouble distance) throws CreateGeometryException{
573
//        GeometryManager geomanager= GeometryLocator.getGeometryManager();
574
//        Line lineM=(Line)geomanager.create(Geometry.TYPES.LINE, Geometry.SUBTYPES.GEOM2DM);
575
//        for (int i=0;i<line.getNumVertices();i++){
576
//            Point vertex=line.getVertex(i);
577
//            Point mVertex=(Point)geomanager.create(Geometry.TYPES.POINT, Geometry.SUBTYPES.GEOM2DM);
578
//            mVertex.setX(vertex.getX());
579
//            mVertex.setY(vertex.getY());
1058

  
1059
//    private List<Point> getExtremePoints(List<MStructure> mList,Point origin){
1060
//        List<Point> pointsInExtremes=new ArrayList<Point>();
1061
//        for (MStructure mStructure: mList){
1062
//            Geometry geometry=mStructure.geometry;
1063
//            if (geometry instanceof Line){
1064
//                Line line=(Line)geometry;
1065
//                pointsInExtremes.add(line.getVertex(0));
1066
//                pointsInExtremes.add(line.getVertex(line.getNumVertices()-1));
1067
//            }
1068
//            if (geometry instanceof MultiLine){
1069
//                MultiLine multiline=(MultiLine)geometry;
1070
//                for (int i=0;i<multiline.getPrimitivesNumber();i++){
1071
//                    Line line=(Line)multiline.getPrimitiveAt(i);
1072
//                    pointsInExtremes.add(line.getVertex(0));
1073
//                    pointsInExtremes.add(line.getVertex(line.getNumVertices()-1));
1074
//                }
1075
//            }
580 1076
//
581
//            if (previousVertex==null){
582
//                previousVertex=vertex;
583
//            }else{
584
//                try {
585
//                    distance.setValue(distance.getValue()+vertex.distance(previousVertex));
586
//                    previousVertex=vertex;
587
//                } catch (Exception e) {
588
//                    previousVertex=vertex;
589
//                    distance.setValue(Double.NaN);
1077
//            PointToReferencePointComparator pointComparator= new PointToReferencePointComparator(origin);
1078
//            Collections.sort(pointsInExtremes, pointComparator);
1079
//
1080
//            List<Point> orderedExtremePoints=new ArrayList<Point>();
1081
//            while ( !pointsInExtremes.isEmpty() ){
1082
//                Point extremePoint=pointsInExtremes.get(0);
1083
//                if ( isLoopOrUnique(mList, extremePoint) ){
1084
//                    orderedExtremePoints.add(extremePoint);
590 1085
//                }
1086
//                while (pointsInExtremes.contains(extremePoint)){
1087
//                    pointsInExtremes.remove(extremePoint);
1088
//                }
591 1089
//            }
592
//            mVertex.setCoordinateAt(mVertex.getDimension()-1, distance.getValue());
593
//            lineM.addVertex(mVertex);
594 1090
//        }
595
//        return lineM;
1091
//
1092
//        return orderedExtremePoints;
596 1093
//    }
597 1094

  
1095
//    private boolean isLoopOrUnique(List<MStructure> mList, Point extremePoint){
1096
//        boolean repeated=false;
1097
//        boolean loop=false;
1098
//
1099
//        int i=0;
1100
//        boolean firstAparition=false;
1101
//        while( !repeated && !loop){
1102
//            if (geometry instanceof Line){
1103
//                Line line=(Line)geometry;
1104
//                pointsInExtremes.add(line.getVertex(0));
1105
//                pointsInExtremes.add(line.getVertex(line.getNumVertices()-1));
1106
//            }
1107
//            if (geometry instanceof MultiLine){
1108
//                MultiLine multiline=(MultiLine)geometry;
1109
//                for (int i=0;i<multiline.getPrimitivesNumber();i++){
1110
//                    Line line=(Line)multiline.getPrimitiveAt(i);
1111
//                    pointsInExtremes.add(line.getVertex(0));
1112
//                    pointsInExtremes.add(line.getVertex(line.getNumVertices()-1));
1113
//                }
1114
//            }
1115
//        }
1116
//
1117
//        return loop&&!repeated;
1118
//    }
598 1119

  
599
    /**
600
     * @param route
601
     * @return
602
     */
603
    private Geometry calibrateRoute(Geometry route) {
604
        // TODO Auto-generated method stub
605
        return route;
1120
    private Geometry applyOffset(Geometry geometry) {
1121
        double measureFactor = parameters.getMeasureFactor();
1122
        double measureOffset = parameters.getMeasureOffset();
1123
        if (geometry instanceof Line) {
1124
            Line line = (Line) geometry;
1125
            for (int i = 0; i < line.getNumVertices(); i++) {
1126
                Point mVertex = line.getVertex(i);
1127
                Double mValue =
1128
                    mVertex.getCoordinateAt(mVertex.getDimension() - 1);
1129
                Double newMValue = (mValue * measureFactor) + measureOffset;
1130
                mVertex.setCoordinateAt(mVertex.getDimension() - 1, newMValue);
1131
                line.setVertex(i, mVertex);
1132
            }
1133
        }
1134
        if (geometry instanceof MultiLine) {
1135
            MultiLine multiLine = (MultiLine) geometry;
1136
            for (int i = 0; i < multiLine.getPrimitivesNumber(); i++) {
1137
                Line line = (Line) multiLine.getPrimitiveAt(i);
1138
                for (int j = 0; j < line.getNumVertices(); j++) {
1139
                    Point mVertex = line.getVertex(j);
1140
                    Double mValue =
1141
                        mVertex.getCoordinateAt(mVertex.getDimension() - 1);
1142
                    Double newMValue = (mValue * measureFactor) + measureOffset;
1143
                    mVertex.setCoordinateAt(mVertex.getDimension() - 1,
1144
                        newMValue);
1145
                    line.setVertex(j, mVertex);
1146
                }
1147
            }
1148
        }
1149
        return geometry;
606 1150
    }
607 1151

  
608
    private Map<Object, List<FeatureReference>> getGroupedReferences(FeatureSelection selection, final FeatureAttributeDescriptor idRouteField) throws BaseException {
609
        final Map<Object, List<FeatureReference>> refs = new HashMap<Object, List<FeatureReference>>();
1152

  
1153

  
1154
    private Map<Object, List<FeatureReference>> getGroupedReferences(
1155
        FeatureSelection selection,
1156
        final FeatureAttributeDescriptor idRouteField) throws BaseException {
1157
        final Map<Object, List<FeatureReference>> refs =
1158
            new HashMap<Object, List<FeatureReference>>();
610 1159
        selection.accept(new Visitor() {
611 1160

  
612
            public void visit(Object obj) throws VisitCanceledException, BaseException {
1161
            public void visit(Object obj)
1162
                throws VisitCanceledException, BaseException {
613 1163
                Feature feature = (Feature) obj;
614 1164
                Object id = feature.getFeature(idRouteField.getName());
615 1165
                FeatureReference reference = feature.getReference();
......
624 1174
        return refs;
625 1175
    }
626 1176

  
627
//    private MultiLine createRoute(List<FeatureReference> references, LrsCoordinatesPriority coordinatePriority, LrsSourceOfMeasures sourceOfMeasures, FeatureAttributeDescriptor fromMeasureField,FeatureAttributeDescriptor toMeasureField, double measureFactor, double measureOffset, boolean ignoreSpatialGaps) throws CreateGeometryException, DataException, CreateEnvelopeException, GeometryOperationNotSupportedException, GeometryOperationException{
628
//
629
//        Envelope envelope = getEnvelope(references);
630
//        Point p = getOriginPointAccordingPriorityCoordinates(envelope, coordinatePriority);
631
//        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
632
//
633
//        //FIXME: cuando est? esto tendr? que ser GEOM2DM o incluso GEOM3DM
634
//        MultiLine route = geometryManager.createMultiLine(Geometry.SUBTYPES.GEOM2D);
635
//        double m = 0;
636
//        Point previousVertex = null;
637
//        List<FeatureReference> orderedReferences = getOrderedReferences(references, (Point)p.cloneGeometry());
638
//        for (Iterator iterator = orderedReferences.iterator(); iterator.hasNext();) {
639
//            FeatureReference featureReference = (FeatureReference) iterator.next();
640
//            Feature feature = featureReference.getFeature();
641
//            Geometry geometry = feature.getDefaultGeometry();
642
//            if (geometry instanceof Line) {
643
//                Line line = (Line) geometry;
644
//                Point firstVertex = line.getVertex(0);
645
//                Point lastVertex = line.getVertex(line.getNumVertices() - 1);
646
//                boolean ascendantOrder = isAscendantOrder(p, firstVertex, lastVertex);
647
//                //FIXME: cuando est? disponible esto deber? ser GEOM2DM (?o incluso GEOM3DM?)
648
//                Line tramo = geometryManager.createLine(Geometry.SUBTYPES.GEOM3D);
649
//                double lineLength = getLineLength(line);
650
//                for(int i=0; i<line.getNumVertices(); i++){
651
//                    Point vertex = getNextVertex(line, ascendantOrder, i);
652
//
653
//                    switch (sourceOfMeasures) {
654
//                    case ONE_FIELD:
655
//                        m = calculateMByOneField(m, previousVertex, i, vertex, feature.getDouble(fromMeasureField.getName()), lineLength, measureFactor, measureOffset, ignoreSpatialGaps);
656
//                        break;
657
//                    case TWO_FIELDS:
658
//                        m = calculateMByTwoField(m, previousVertex, i, vertex, feature.getDouble(fromMeasureField.getName()), feature.getDouble(toMeasureField.getName()), lineLength, measureFactor, measureOffset);
659
//                        break;
660
//                    case LENGTH:
661
//                    default:
662
//                        m = calculateMByLength(m, previousVertex, i, vertex, ignoreSpatialGaps, measureFactor, measureOffset);
663
//                        break;
664
//                    }
665
//                    // FIXME: cuando est? disponible esto deber? ser GEOM2DM (?o incluso GEOM3DM?)
666
//                    Point mvertex = geometryManager.createPoint(vertex.getX(), vertex.getY(), Geometry.SUBTYPES.GEOM3D);
667
//                    mvertex.setCoordinateAt(2, m);
668
//                    tramo.addVertex(mvertex);
669
//                    previousVertex = vertex;
670
//                    p = vertex;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff