Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libGeocoding / src / org / gvsig / geocoding / impl / DataGeocoderImpl.java @ 28375

History | View | Annotate | Download (9.35 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                Main development
26
 */
27

    
28
package org.gvsig.geocoding.impl;
29

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

    
36
import org.gvsig.fmap.dal.DALLocator;
37
import org.gvsig.fmap.dal.DataManager;
38
import org.gvsig.fmap.dal.DataStore;
39
import org.gvsig.fmap.dal.exception.DataException;
40
import org.gvsig.fmap.dal.feature.Feature;
41
import org.gvsig.fmap.dal.feature.FeatureQuery;
42
import org.gvsig.fmap.dal.feature.FeatureSelection;
43
import org.gvsig.fmap.dal.feature.FeatureSet;
44
import org.gvsig.fmap.dal.feature.FeatureStore;
45
import org.gvsig.geocoding.DataGeocoder;
46
import org.gvsig.geocoding.address.Address;
47
import org.gvsig.geocoding.address.AddressComponent;
48
import org.gvsig.geocoding.address.ComposedAddress;
49
import org.gvsig.geocoding.address.Literal;
50
import org.gvsig.geocoding.address.NumberAddress;
51
import org.gvsig.geocoding.address.RelationsComponent;
52
import org.gvsig.geocoding.pattern.Patterngeocoding;
53
import org.gvsig.geocoding.result.GeocodingResult;
54
import org.gvsig.geocoding.result.ScoredFeature;
55
import org.gvsig.geocoding.result.impl.DefaultScoredFeature;
56
import org.gvsig.geocoding.styles.AbstractGeocodingStyle;
57
import org.gvsig.geocoding.styles.impl.Composed;
58
import org.gvsig.geocoding.styles.impl.DoubleRange;
59
import org.gvsig.geocoding.styles.impl.SimpleCentroid;
60
import org.gvsig.geocoding.styles.impl.SimpleRange;
61
import org.gvsig.tools.evaluator.Evaluator;
62
import org.gvsig.tools.locator.LocatorException;
63
import org.slf4j.Logger;
64
import org.slf4j.LoggerFactory;
65

    
66
/**
67
 * Data geocoder implementation
68
 * 
69
 * @author <a href="mailto:jsanz@prodevelop.es"> Jorge Gaspar Sanz Salinas</a>
70
 * @author <a href="mailto:vsanjaime@prodevelop.es"> Vicente Sanjaime Calvet</a>
71
 */
72

    
73
public class DataGeocoderImpl implements DataGeocoder {
74

    
75
        private Logger log = LoggerFactory.getLogger(DataGeocoderImpl.class);
76
        private Patterngeocoding pattern = null;
77
        private DataManager manager = null;
78

    
79
        /**
80
         * Constructor with one pattern
81
         * 
82
         * @param pattern
83
         */
84
        public DataGeocoderImpl() {
85
                manager = DALLocator.getDataManager();
86
        }
87

    
88
        /**
89
         * Constructor with one pattern
90
         * 
91
         * @param pattern
92
         */
93
        public DataGeocoderImpl(Patterngeocoding pattern) {
94
                this.pattern = pattern;
95
                manager = DALLocator.getDataManager();
96
        }
97

    
98
        /**
99
         * set the pattern
100
         * 
101
         * @param pattern
102
         */
103
        public void setPattern(Patterngeocoding pattern) {
104
                this.pattern = pattern;
105

    
106
        }
107

    
108
        /**
109
         * Get the pattern
110
         * 
111
         * @return pattern
112
         */
113
        public Patterngeocoding getPattern() {
114
                return this.pattern;
115

    
116
        }
117

    
118
        /**
119
         * Geocoding process
120
         * 
121
         * @param address
122
         * @return results
123
         */
124
        public Set<GeocodingResult> geocode(Address address)
125
                        throws LocatorException, DataException {
126

    
127
                Set<GeocodingResult> results = new TreeSet<GeocodingResult>();
128
                // get the FeatureStore registred in the pattern
129
                DataStore store = getPattern().getSource().getLayerSource();
130
                // get the style
131
                AbstractGeocodingStyle astyle = getPattern().getSource().getStyle();
132
                // get literal with relations with the store
133
                Literal relationsLiteral = astyle.getRelationsLiteral();
134
                // list of list with one or more literal results
135
                List<List<ScoredFeature>> lists = new ArrayList<List<ScoredFeature>>();
136

    
137
                // SIMPLE CENTROID
138
                if (astyle instanceof SimpleCentroid) {
139
                        SimpleCentroid style = (SimpleCentroid) astyle;
140
                        Literal addressLiteral = address.getMainLiteral();
141
                        // literal search
142
                        List<ScoredFeature> literalResults = literalSearch(
143
                                        relationsLiteral, addressLiteral, store);
144
                        lists.add(literalResults);
145
                        // Geom search
146
                        results = style.match(lists, address);
147
                }
148

    
149
                // SIMPLE RANGE
150
                else if (astyle instanceof SimpleRange) {
151
                        SimpleRange style = (SimpleRange) astyle;
152
                        Literal addressLiteral = ((NumberAddress) address).getMainLiteral();
153
                        // literal search
154
                        List<ScoredFeature> literalResults = literalSearch(
155
                                        relationsLiteral, addressLiteral, store);
156
                        lists.add(literalResults);
157
                        // geom search
158
                        results = style.match(lists, address);
159
                }
160

    
161
                // DOUBLE RANGE
162
                else if (astyle instanceof DoubleRange) {
163
                        DoubleRange style = (DoubleRange) astyle;
164
                        Literal addressLiteral = ((NumberAddress) address).getMainLiteral();
165
                        // literal search
166
                        List<ScoredFeature> literalResults = literalSearch(
167
                                        relationsLiteral, addressLiteral, store);
168
                        lists.add(literalResults);
169
                        // number search
170
                        results = style.match(lists, address);
171
                }
172

    
173
                // STYLE COMPOSED
174
                else if (astyle instanceof Composed) {
175
                        Composed style = (Composed) astyle;
176
                        ComposedAddress cAddress = (ComposedAddress) address;
177

    
178
                        // main literal search
179
                        Literal mainAddressLiteral = cAddress.getMainLiteral();
180
                        List<ScoredFeature> literalResults = literalSearch(
181
                                        relationsLiteral, mainAddressLiteral, store);
182
                        lists.add(literalResults);
183
                        // search in others literals
184
                        List<Literal> intersectslist = cAddress.getIntersectionLiterals();
185
                        for (Literal addrLiteral : intersectslist) {
186
                                // literal search
187
                                List<ScoredFeature> secList = literalSearch(relationsLiteral,
188
                                                addrLiteral, store);
189
                                lists.add(secList);
190
                        }
191
                        // Match
192
                        results = style.match(lists, address);
193
                }
194
                return results;
195
        }
196

    
197
        /**
198
         * First scouting process, search literal elements in data store and return
199
         * a list with ok scored features
200
         * 
201
         * @param relationsLiteral
202
         * @param addressLiteral
203
         * @param store
204
         * @return
205
         * @throws DataException
206
         */
207
        private List<ScoredFeature> literalSearch(Literal relationsLiteral,
208
                        Literal addressLiteral, DataStore store) throws DataException {
209

    
210
                List<FeatureSelection> sels = new ArrayList<FeatureSelection>();
211
                FeatureSet features = null;
212

    
213
                String exp = "";
214

    
215
                int i = 0;
216
                // search features related with the parameters
217
                for (Object obj : relationsLiteral) {
218
                        RelationsComponent lit = (RelationsComponent) obj;
219
                        FeatureSelection selection = ((FeatureStore) store)
220
                                        .createFeatureSelection();
221
                        FeatureQuery query = ((FeatureStore) store).createFeatureQuery();
222
                        String key = lit.getKeyElement().trim();
223
                        String chain = getValueAddress(key, addressLiteral);
224

    
225
                        String fname = lit.getValue();
226
                        if (i == 0) {
227
                                exp = fname + " like '%" + chain + "%'";
228
                        } else {
229
                                exp = exp + " AND " + fname + " like '%" + chain + "%'";
230
                        }
231

    
232
                        Evaluator eval = manager.createExpresion(exp);
233

    
234
                        query.setFilter(eval);
235
                        features = ((FeatureStore) store).getFeatureSet(query);
236
                        selection.select(features);
237
                        sels.add(selection);
238
                        log.debug("Iteration " + i + " - Selection : "
239
                                        + selection.getSelectedCount());
240
                        i++;
241
                }
242
                // Put scores
243
                List<ScoredFeature> scores = createLiteralScores(store, sels);
244

    
245
                return scores;
246
        }
247

    
248
        /**
249
         * Create score of the feature to first literal search
250
         * 
251
         * @param store
252
         * @param sels
253
         * @return
254
         * @throws DataException
255
         */
256
        @SuppressWarnings("unchecked")
257
        private List<ScoredFeature> createLiteralScores(DataStore store,
258
                        List<FeatureSelection> sels) throws DataException {
259

    
260
                List<ScoredFeature> scores = new ArrayList<ScoredFeature>();
261

    
262
                FeatureSet features = ((FeatureStore) store).getFeatureSet();
263

    
264
                for (Iterator<Feature> it = features.iterator(); it.hasNext();) {
265
                        Feature feature = it.next();
266
                        double num = 0;
267
                        for (int i = 0; i < sels.size(); i++) {
268
                                FeatureSelection sel = sels.get(i);
269
                                if (sel.isSelected(feature)) {
270
                                        num = num + scorePonderated(i, sels.size());
271
                                }
272
                        }
273
                        if (num > 0.0) {
274
                                ScoredFeature scoFeat = new DefaultScoredFeature();
275
                                scoFeat.setReference(feature.getReference());
276
                                scoFeat.setScore(num);
277
                                scores.add(scoFeat);
278
                        }
279
                }
280
                return scores;
281
        }
282

    
283
        /**
284
         * Get the score value ponderated
285
         * 
286
         * @param i
287
         *            position
288
         * @param total
289
         * @return score
290
         */
291
        private double scorePonderated(int i, int total) {
292
                if (total == 1) {
293
                        return 100.0;
294
                }
295
                double score = 100.0 / (2.0 * (i + 1));
296
                return score;
297
        }
298

    
299
        /**
300
         * Get address value from key
301
         * 
302
         * @param key
303
         * @param addressLiteral
304
         * @return
305
         */
306
        private String getValueAddress(String key, Literal addressLiteral) {
307
                String value = "";
308
                for (Object obj : addressLiteral) {
309
                        AddressComponent aComp = (AddressComponent) obj;
310
                        String key2 = aComp.getKeyElement();
311
                        if (key.compareTo(key2) == 0) {
312
                                value = aComp.getValue();
313
                                break;
314
                        }
315
                }
316
                return value;
317
        }
318

    
319
}