Statistics
| Revision:

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

History | View | Annotate | Download (12.2 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.NumberAddress;
42
import org.gvsig.geocoding.RelationsComponent;
43
import org.gvsig.geocoding.geommatches.MatcherUtils;
44
import org.gvsig.geocoding.result.GeocodingResult;
45
import org.gvsig.geocoding.result.GeomMatchResult;
46
import org.gvsig.geocoding.result.ScoredFeature;
47
import org.gvsig.tools.persistence.AbstractPersistenceManager;
48
import org.gvsig.tools.persistence.PersistenceException;
49
import org.gvsig.tools.persistence.PersistentState;
50
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52

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

    
60
public class DoubleRange extends AbstractRange {
61

    
62
        private static final Logger log = LoggerFactory
63
                        .getLogger(DoubleRange.class);
64

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

    
70
        private RelationsComponent firstLeftNumber;
71
        private RelationsComponent firstRightNumber;
72
        private RelationsComponent lastLeftNumber;
73
        private RelationsComponent lastRightNumber;
74

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

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

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

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

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

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

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

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

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

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

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

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

    
206
                Set<GeocodingResult> results = new TreeSet<GeocodingResult>();
207

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

    
217
                // get the list
218
                List<ScoredFeature> sFeats = inLists.get(0);
219

    
220
                int number = ((NumberAddress) address).getNumber();
221

    
222
                try {
223
                        for (ScoredFeature sFeat : sFeats) {
224

    
225
                                Feature fea = sFeat.getFeature();
226

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

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

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

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

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

    
328
                return res;
329
        }
330

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

    
345
                Geometry geom = feat.getReference().getFeature().getDefaultGeometry();
346
                com.vividsolutions.jts.geom.Geometry geJTS = MatcherUtils
347
                                .parseGeomGVToJTS(geom);
348
                int relative = calculateRelativeDistance(number, first, last);
349
                Point2D position = MatcherUtils.getLinePositionFromRelativeDistance(
350
                                geJTS, relative);
351
                // create result
352
                GeomMatchResult res = new GeomMatchResult();
353
                List<ScoredFeature> list = new ArrayList<ScoredFeature>();
354
                list.add(feat);
355
                res.setGeom(position);
356
                res.setSources(list);
357

    
358
                return res;
359
        }
360

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

    
372
                int[] range = new int[4];
373

    
374
                Object oRFirst = feat.get(firstRightNumberDesc.getName());
375
                Object oRLast = feat.get(lastRightNumberDesc.getName());
376
                Object oLFirst = feat.get(firstLeftNumberDesc.getName());
377
                Object oLLast = feat.get(lastLeftNumberDesc.getName());
378

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

    
420
                return range;
421
        }
422

    
423
}