Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libGeocoding / src / org / gvsig / geocoding / styles / DoubleRange.java @ 27462

History | View | Annotate | Download (13.4 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 * 
21
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2008 Prodevelop S.L. main development
26
 */
27

    
28
package org.gvsig.geocoding.styles;
29

    
30
import java.util.ArrayList;
31
import java.util.List;
32
import java.util.Set;
33
import java.util.TreeSet;
34

    
35
import org.gvsig.fmap.dal.exception.DataException;
36
import org.gvsig.fmap.dal.feature.Feature;
37
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
38
import org.gvsig.fmap.geom.Geometry;
39
import org.gvsig.fmap.geom.primitive.Point2D;
40
import org.gvsig.geocoding.Address;
41
import org.gvsig.geocoding.AddressComponent;
42
import org.gvsig.geocoding.Literal;
43
import org.gvsig.geocoding.NumberAddress;
44
import org.gvsig.geocoding.RelationsComponent;
45
import org.gvsig.geocoding.geommatches.MatcherUtils;
46
import org.gvsig.geocoding.result.GeocodingResult;
47
import org.gvsig.geocoding.result.GeomMatchResult;
48
import org.gvsig.geocoding.result.ScoredFeature;
49
import org.gvsig.tools.persistence.AbstractPersistenceManager;
50
import org.gvsig.tools.persistence.PersistenceException;
51
import org.gvsig.tools.persistence.PersistentState;
52
import org.slf4j.Logger;
53
import org.slf4j.LoggerFactory;
54

    
55
/**
56
 * 
57
 * 
58
 * @author <a href="mailto:jsanz@prodevelop.es"> Jorge Gaspar Sanz Salinas</a>
59
 * @author <a href="mailto:vsanjaime@prodevelop.es"> Vicente Sanjaime Calvet</a>
60
 */
61

    
62
public class DoubleRange extends AbstractRange {
63

    
64
        private static final Logger log = LoggerFactory
65
                        .getLogger(DoubleRange.class);
66

    
67
        private static final String FIRSTLEFTNUMBER = "firstleftnumber";
68
        private static final String FIRSTRIGHTNUMBER = "firstrightnumber";
69
        private static final String LASTLEFTNUMBER = "lastleftnumber";
70
        private static final String LASTRIGHTNUMBER = "firstrightnumber";
71

    
72
        private RelationsComponent firstLeftNumber;
73
        private RelationsComponent firstRightNumber;
74
        private RelationsComponent lastLeftNumber;
75
        private RelationsComponent lastRightNumber;
76

    
77
        /**
78
         * Get relation component that define the field of data source that it has
79
         * the first left number of the feature
80
         * 
81
         * @return
82
         */
83
        public RelationsComponent getFirstLeftNumber() {
84
                return firstLeftNumber;
85
        }
86

    
87
        /**
88
         * Set relation component that define the field of data source that it has
89
         * the first left number of the feature
90
         * 
91
         * @param firstLeftNumber
92
         */
93
        public void setFirstLeftNumber(RelationsComponent firstLeftNumber) {
94
                this.firstLeftNumber = firstLeftNumber;
95
        }
96

    
97
        /**
98
         * Get relation component that define the field of data source that it has
99
         * the first right number of the feature
100
         * 
101
         * @return
102
         */
103
        public RelationsComponent getFirstRightNumber() {
104
                return firstRightNumber;
105
        }
106

    
107
        /**
108
         * Set relation component that define the field of data source that it has
109
         * the first right number of the feature
110
         * 
111
         * @param firstRightNumber
112
         */
113
        public void setFirstRightNumber(RelationsComponent firstRightNumber) {
114
                this.firstRightNumber = firstRightNumber;
115
        }
116

    
117
        /**
118
         * Get relation component that define the field of data source that it has
119
         * the last left number of the feature
120
         * 
121
         * @return
122
         */
123
        public RelationsComponent getLastLeftNumber() {
124
                return lastLeftNumber;
125
        }
126

    
127
        /**
128
         * Set relation component that define the field of data source that it has
129
         * the last left number of the feature
130
         * 
131
         * @param lastLeftNumber
132
         */
133
        public void setLastLeftNumber(RelationsComponent lastLeftNumber) {
134
                this.lastLeftNumber = lastLeftNumber;
135
        }
136

    
137
        /**
138
         * Get relation component that define the field of data source that it has
139
         * the last right number of the feature
140
         * 
141
         * @return
142
         */
143
        public RelationsComponent getLastRightNumber() {
144
                return lastRightNumber;
145
        }
146

    
147
        /**
148
         * Set relation component that define the field of data source that it has
149
         * the last right number of the feature
150
         * 
151
         * @param lastRightNumber
152
         */
153
        public void setLastRightNumber(RelationsComponent lastRightNumber) {
154
                this.lastRightNumber = lastRightNumber;
155
        }
156

    
157
        /**
158
         * Get the persistent state of the doublerange and append to the passed
159
         * state.
160
         * 
161
         * @param state
162
         */
163
        @Override
164
        public PersistentState getState() throws PersistenceException {
165
                return AbstractPersistenceManager.getState(this);
166
        }
167

    
168
        /**
169
         * Load the state of the doublerange over the passed state.
170
         * 
171
         * @param state
172
         */
173
        @Override
174
        public void loadState(PersistentState state) throws PersistenceException {
175
                state.setTheClass(this);
176
                state.set(FIRSTLEFTNUMBER, this.firstLeftNumber);
177
                state.set(FIRSTRIGHTNUMBER, this.firstRightNumber);
178
                state.set(LASTLEFTNUMBER, this.lastLeftNumber);
179
                state.set(LASTRIGHTNUMBER, this.lastRightNumber);
180
        }
181

    
182
        /**
183
         * Set the state of the doublerange from the state passed as parameter.
184
         * 
185
         * @param state
186
         */
187
        @Override
188
        public void setState(PersistentState state) throws PersistenceException {
189
                this.firstLeftNumber = (RelationsComponent) state.get(FIRSTLEFTNUMBER);
190
                this.firstRightNumber = (RelationsComponent) state
191
                                .get(FIRSTRIGHTNUMBER);
192
                this.lastLeftNumber = (RelationsComponent) state.get(LASTLEFTNUMBER);
193
                this.lastRightNumber = (RelationsComponent) state.get(LASTRIGHTNUMBER);
194
        }
195

    
196
        /**
197
         * spatial search over the geometries
198
         * 
199
         * @param lists
200
         *            list of lists with ScoredFeatures
201
         * @param address
202
         * @return
203
         */
204
        @Override
205
        public Set<GeocodingResult> match(List<List<ScoredFeature>> inLists,
206
                        Address address) {
207

    
208
                Set<GeocodingResult> results = new TreeSet<GeocodingResult>();
209

    
210
                FeatureAttributeDescriptor firstLeftNumberDesc = this
211
                                .getFirstLeftNumber().getValue();
212
                FeatureAttributeDescriptor lastLeftNumberDesc = this
213
                                .getLastLeftNumber().getValue();
214
                FeatureAttributeDescriptor firstRightNumberDesc = this
215
                                .getFirstRightNumber().getValue();
216
                FeatureAttributeDescriptor lastRightNumberDesc = this
217
                                .getLastRightNumber().getValue();
218

    
219
                // get the list
220
                List<ScoredFeature> sFeats = inLists.get(0);
221
                if (sFeats.size() > 0) {
222
                        int number = ((NumberAddress) address).getNumber();
223

    
224
                        try {
225
                                for (ScoredFeature sFeat : sFeats) {
226

    
227
                                        Feature fea = sFeat.getFeature();
228

    
229
                                        int[] range = getNumberRange(fea, firstLeftNumberDesc,
230
                                                        lastLeftNumberDesc, firstRightNumberDesc,
231
                                                        lastRightNumberDesc);
232
                                        int firstL = range[0];
233
                                        int lastL = range[1];
234
                                        int firstR = range[2];
235
                                        int lastR = range[3];
236

    
237
                                        // Number even (Par)
238
                                        if (number % 2 == 0) {
239
                                                // Left numbers - EVEN // right numbers - ODD
240
                                                if (firstL % 2 == 0) {
241
                                                        if (number >= firstL && number <= lastL) {
242
                                                                // create result
243
                                                                GeomMatchResult res = calculatePosition(sFeat,
244
                                                                                number, firstL, lastL);
245
                                                                // add result to the list
246
                                                                results.add(res);
247
                                                        }
248
                                                }
249
                                                // Left numbers - ODD // right numbers - EVEN
250
                                                else {
251
                                                        if (number >= firstR && number <= lastR) {
252
                                                                // create result
253
                                                                GeomMatchResult res = calculatePosition(sFeat,
254
                                                                                number, firstR, lastR);                                                                
255
                                                                // add result to the list
256
                                                                results.add(res);
257
                                                        }
258
                                                }
259
                                        }
260
                                        // number odd (Impar)
261
                                        else {
262
                                                // Left numbers - EVEN // right numbers - ODD
263
                                                if (firstL % 2 == 0) {
264
                                                        if (number >= firstR && number <= lastR) {
265
                                                                // create result
266
                                                                GeomMatchResult res = calculatePosition(sFeat,
267
                                                                                number, firstR, lastR);                                                                
268
                                                                // add result to the list
269
                                                                results.add(res);
270
                                                        }
271
                                                }
272
                                                // Left numbers - ODD // right numbers - EVEN
273
                                                else {
274
                                                        if (number >= firstL && number <= lastL) {
275
                                                                // create result
276
                                                                GeomMatchResult res = calculatePosition(sFeat,
277
                                                                                number, firstL, lastL);
278
                                                                // add result to the list
279
                                                                results.add(res);
280
                                                        }
281
                                                }
282
                                        }
283
                                }
284
                        } catch (DataException e) {
285
                                log.error("Error getting the features", e);
286
                        }
287
                }
288
                return results;
289
        }
290

    
291
        /**
292
         * Calculate the relative distance in line
293
         * 
294
         * @param number
295
         * @param first
296
         * @param last
297
         * @return
298
         */
299
        private int calculateRelativeDistance(int number, int first, int last) {
300
                int total = Math.abs(last - first);
301
                int ini = Math.abs(number - first);
302
                return (ini * 100) / total;
303
        }
304

    
305
        /**
306
         * calculate the position
307
         * 
308
         * @param feat
309
         * @param number
310
         * @param first
311
         * @param last
312
         * @return
313
         * @throws DataException
314
         */
315
        private GeomMatchResult calculatePosition(ScoredFeature feat, int number,
316
                        int first, int last) throws DataException {
317

    
318
                Geometry geom = feat.getReference().getFeature().getDefaultGeometry();
319
                com.vividsolutions.jts.geom.Geometry geJTS = MatcherUtils
320
                                .parseGeomGVToJTS(geom);
321
                int relative = calculateRelativeDistance(number, first, last);
322
                Point2D position = MatcherUtils.getLinePositionFromRelativeDistance(
323
                                geJTS, relative);
324
                // create result
325
                GeomMatchResult res = new GeomMatchResult();
326
                List<ScoredFeature> list = new ArrayList<ScoredFeature>();
327
                list.add(feat);
328
                res.setGeom(position);
329
                res.setMainSources(list);
330

    
331
                return res;
332
        }
333

    
334
        /**
335
         * Calculate the position with a offset positive or negative
336
         * 
337
         * @param feat
338
         * @param number
339
         * @param first
340
         * @param last
341
         * @param offset
342
         * @return
343
         * @throws DataException
344
         */
345
        private GeomMatchResult calculateOffsetPosition(ScoredFeature feat,
346
                        int number, int first, int last, int offset) throws DataException {
347

    
348
                Geometry geom = feat.getReference().getFeature().getDefaultGeometry();
349
                com.vividsolutions.jts.geom.Geometry geJTS = MatcherUtils
350
                                .parseGeomGVToJTS(geom);
351
                int relative = calculateRelativeDistance(number, first, last);
352
                Point2D position = MatcherUtils.getLinePositionFromRelativeDistance(
353
                                geJTS, relative);
354
                // create result
355
                GeomMatchResult res = new GeomMatchResult();
356
                List<ScoredFeature> list = new ArrayList<ScoredFeature>();
357
                list.add(feat);
358
                res.setGeom(position);
359
                res.setMainSources(list);
360
                res.setAddress(getResultAddress(list, number));
361
                return res;
362
        }
363

    
364
        /**
365
         * 
366
         * @param feat
367
         * @return
368
         */
369
        private int[] getNumberRange(Feature feat,
370
                        FeatureAttributeDescriptor firstRightNumberDesc,
371
                        FeatureAttributeDescriptor lastRightNumberDesc,
372
                        FeatureAttributeDescriptor firstLeftNumberDesc,
373
                        FeatureAttributeDescriptor lastLeftNumberDesc) {
374

    
375
                int[] range = new int[4];
376

    
377
                Object oRFirst = feat.get(firstRightNumberDesc.getName());
378
                Object oRLast = feat.get(lastRightNumberDesc.getName());
379
                Object oLFirst = feat.get(firstLeftNumberDesc.getName());
380
                Object oLLast = feat.get(lastLeftNumberDesc.getName());
381

    
382
                // RIGHT FIRST
383
                if (oRFirst instanceof Double) {
384
                        range[0] = ((Double) oRFirst).intValue();
385
                }
386
                if (oRFirst instanceof Integer) {
387
                        range[0] = ((Integer) oRFirst).intValue();
388
                }
389
                if (oRFirst instanceof String) {
390
                        range[0] = Integer.parseInt(((String) oRFirst));
391
                }
392
                // RIGHT LAST
393
                if (oRLast instanceof Double) {
394
                        range[1] = ((Double) oRLast).intValue();
395
                }
396
                if (oRLast instanceof Integer) {
397
                        range[1] = ((Integer) oRLast).intValue();
398
                }
399
                if (oRLast instanceof String) {
400
                        range[1] = Integer.parseInt(((String) oRLast));
401
                }
402
                // LEFT FIRST
403
                if (oLFirst instanceof Double) {
404
                        range[2] = ((Double) oLFirst).intValue();
405
                }
406
                if (oLFirst instanceof Integer) {
407
                        range[2] = ((Integer) oLFirst).intValue();
408
                }
409
                if (oLFirst instanceof String) {
410
                        range[2] = Integer.parseInt(((String) oLFirst));
411
                }
412
                // LEFT LAST
413
                if (oLLast instanceof Double) {
414
                        range[3] = ((Double) oLLast).intValue();
415
                }
416
                if (oLLast instanceof Integer) {
417
                        range[3] = ((Integer) oLLast).intValue();
418
                }
419
                if (oLLast instanceof String) {
420
                        range[3] = Integer.parseInt(((String) oLLast));
421
                }
422

    
423
                return range;
424
        }
425
        
426
        /**
427
         * 
428
         * @return
429
         */
430
        private Address getResultAddress(List<ScoredFeature> sources, int number){
431
                
432
                //get the first element 
433
                ScoredFeature feat = sources.get(0);
434
                
435
                Literal relLiteral = this.getRelationsLiteral();
436
                Literal literal = new Literal();
437
                for (Object obj : relLiteral) {
438
                        RelationsComponent rel = (RelationsComponent)obj;
439
                        String key = rel.getKeyElement();
440
                        FeatureAttributeDescriptor desc = rel.getValue();
441
                        String fieldName = desc.getName();
442
                        Object object = null;
443
                        String value ="";
444
                        try {
445
                                object = feat.getFeature().get(fieldName);
446
                                value = object.toString();
447
                        } catch (DataException e) {
448
                                log.error("Getting attributes ot the feature",e);
449
                        }                        
450
                        literal.add(new AddressComponent(key,value));
451
                }
452

    
453
                NumberAddress address = new NumberAddress();
454
                address.setMainLiteral(literal);                
455
                address.setNumber(number);
456
                return address;
457
        }
458

    
459
}