Statistics
| Revision:

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

History | View | Annotate | Download (8.61 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.impl;
29

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

    
38
import org.gvsig.fmap.dal.exception.DataException;
39
import org.gvsig.fmap.geom.Geometry;
40
import org.gvsig.fmap.geom.primitive.Point;
41
import org.gvsig.fmap.geom.util.Converter;
42
import org.gvsig.geocoding.address.Address;
43
import org.gvsig.geocoding.address.Literal;
44
import org.gvsig.geocoding.address.RelationsComponent;
45
import org.gvsig.geocoding.address.impl.DefaultAddress;
46
import org.gvsig.geocoding.address.impl.DefaultAddressComponent;
47
import org.gvsig.geocoding.address.impl.DefaultLiteral;
48
import org.gvsig.geocoding.geommatches.MatcherUtils;
49
import org.gvsig.geocoding.result.DissolveResult;
50
import org.gvsig.geocoding.result.GeocodingResult;
51
import org.gvsig.geocoding.result.ScoredFeature;
52
import org.gvsig.geocoding.result.impl.GeomMatchResult;
53
import org.gvsig.geocoding.styles.AbstractGeocodingStyle;
54
import org.gvsig.tools.persistence.PersistenceException;
55
import org.gvsig.tools.persistence.PersistentState;
56
import org.slf4j.Logger;
57
import org.slf4j.LoggerFactory;
58

    
59
/**
60
 * Implemented Geocoding style with search by centroid. Search of the centroid of points,
61
 * lines or polygons geometries.
62
 * 
63
 * @author <a href="mailto:jsanz@prodevelop.es"> Jorge Gaspar Sanz Salinas</a>
64
 * @author <a href="mailto:vsanjaime@prodevelop.es"> Vicente Sanjaime Calvet</a>
65
 */
66

    
67
public class SimpleCentroid extends AbstractGeocodingStyle {
68

    
69
        private static final Logger log = LoggerFactory
70
                        .getLogger(SimpleCentroid.class);
71

    
72
        /**
73
         * spatial search over the geometries
74
         * 
75
         * @param lists
76
         *            list of lists with ScoredFeatures
77
         * @param address
78
         * @return
79
         */
80
        @Override
81
        public Set<GeocodingResult> match(List<List<ScoredFeature>> inLists,
82
                        Address address) {
83

    
84
                Set<GeocodingResult> results = new TreeSet<GeocodingResult>();
85

    
86
                // catch the first element of the relations Literal to get the field
87
                // descriptor
88
                // to make the dissolve process
89
                RelationsComponent rComp0 = (RelationsComponent) this
90
                                .getRelationsLiteral().get(0);
91
                String descriptDissol = rComp0.getValue();
92

    
93
                // Get the first list
94
                List<ScoredFeature> firstListFeatures = inLists.get(0);
95
                if (firstListFeatures.size() > 0) {
96
                        try {
97
                                Geometry geometry = firstListFeatures.get(0).getFeature()
98
                                                .getDefaultGeometry();
99
                                int dim = MatcherUtils.getGeometryDimension(geometry);
100

    
101
                                // POINTs FEATURES
102
                                if (dim == 0) {
103
                                        results = createPointsFeaturesResult(firstListFeatures);
104
                                }
105
                                // OTHER GEOMETRIES TYPES
106
                                else {
107
                                        // dissolve features selected
108
                                        List<DissolveResult> disRes = this.dissolveScoredFeatures(
109
                                                        descriptDissol, firstListFeatures);
110

    
111
                                        for (DissolveResult dissol : disRes) {
112
                                                GeomMatchResult matchres = new GeomMatchResult();
113
                                                Point position = null;
114

    
115
                                                Geometry geom = dissol.getGeom();
116
                                                com.vividsolutions.jts.geom.Geometry gemJTS = Converter
117
                                                                .geometryToJts(geom);
118
                                                // Lines
119
                                                if (gemJTS.getDimension() == 1) {
120
                                                        com.vividsolutions.jts.geom.Geometry geoJTS = Converter
121
                                                                        .geometryToJts(geom);
122
                                                        position = MatcherUtils
123
                                                                        .getLinePositionFromRelativeDistance(
124
                                                                                        geoJTS, 50);
125
                                                }
126
                                                // Polys
127
                                                if (gemJTS.getDimension() == 2) {
128
                                                        position = MatcherUtils.internalPointGeometry(geom);
129
                                                }
130
                                                matchres.setGeom(position);
131
                                                matchres.setMainSources(dissol.getScoredFeatures());
132
                                                matchres.setAddress(getResultAddress(dissol
133
                                                                .getScoredFeatures()));
134
                                                results.add(matchres);
135
                                                // log.debug("Insert result");
136
                                        }
137
                                }
138
                        } catch (DataException e) {
139
                                log.error("Error getting the features", e);
140
                        }
141
                }
142
                log.debug("Results:" + results.size());
143
                return results;
144
        }
145

    
146
        /**
147
         * Dissolve features geometries behind one field
148
         * 
149
         * @param field
150
         * @param features
151
         * @return list with dissolved features
152
         * @throws DataException
153
         */
154
        private List<DissolveResult> dissolveScoredFeatures(String field,
155
                        List<ScoredFeature> features) throws DataException {
156

    
157
                List<DissolveResult> listResults = new ArrayList<DissolveResult>();
158

    
159
                // Group geometries by main attribute
160
                HashMap<String, List<ScoredFeature>> dissolAttributes = MatcherUtils
161
                                .groupScoredFeaturesByAttribute(field, features);
162

    
163
                // For each group of features, to do geometries dissolve process getting
164
                // at the end one o more geometries
165
                for (Iterator<Map.Entry<String, List<ScoredFeature>>> iterator = dissolAttributes
166
                                .entrySet().iterator(); iterator.hasNext();) {
167
                        Map.Entry<String, List<ScoredFeature>> e = iterator.next();
168
                        List<ScoredFeature> feats = e.getValue();
169
                        Geometry geom = feats.get(0).getFeature().getDefaultGeometry();
170
                        com.vividsolutions.jts.geom.Geometry geoJTS = Converter
171
                                        .geometryToJts(geom);
172
                        int dim = geoJTS.getDimension();
173

    
174
                        List<DissolveResult> geomsDissol = new ArrayList<DissolveResult>();
175

    
176
                        // dissolve geoms
177
                        if (dim == 1) {
178
                                // log.debug("DISSOLVE LINES");
179
                                geomsDissol = MatcherUtils.dissolveGeomsJTS(feats,
180
                                                MatcherUtils.LINES);
181
                        }
182
                        if (dim == 2) {
183
                                // log.debug("DISSOLVE POLYS");
184
                                geomsDissol = MatcherUtils.dissolveGeomsJTS(feats,
185
                                                MatcherUtils.POLYS);
186
                        }
187

    
188
                        // insert each dissolve result in the general array
189
                        for (DissolveResult dissolveResult : geomsDissol) {
190
                                listResults.add(dissolveResult);
191
                        }
192
                }
193
                return listResults;
194
        }
195

    
196
        /**
197
         * Get result address
198
         * 
199
         * @return
200
         */
201
        private Address getResultAddress(List<ScoredFeature> sources) {
202

    
203
                // get the first element
204
                ScoredFeature feat = sources.get(0);
205

    
206
                Literal relLiteral = this.getRelationsLiteral();
207
                Literal literal = new DefaultLiteral();
208
                for (Object obj : relLiteral) {
209
                        RelationsComponent rel = (RelationsComponent) obj;
210
                        String key = rel.getKeyElement();
211
                        String fieldName = rel.getValue();
212
                        Object object = null;
213
                        String value = "";
214
                        try {
215
                                object = feat.getFeature().get(fieldName);
216
                                value = object.toString();
217
                        } catch (DataException e) {
218
                                log.error("Getting attributes ot the feature", e);
219
                        }
220
                        literal.add(new DefaultAddressComponent(key, value));
221
                }
222
                Address address = new DefaultAddress();
223
                address.setMainLiteral(literal);
224

    
225
                return address;
226
        }
227

    
228
        /**
229
         * This method creates the output from points features. Because this
230
         * elements can't dissolve themself.
231
         * 
232
         * @param sFeats
233
         * @return
234
         * @throws DataException
235
         */
236
        private Set<GeocodingResult> createPointsFeaturesResult(
237
                        List<ScoredFeature> sFeats) {
238

    
239
                Set<GeocodingResult> results = new TreeSet<GeocodingResult>();
240

    
241
                for (ScoredFeature sFeat : sFeats) {
242
                        GeomMatchResult result = new GeomMatchResult();
243
                        try {
244
                                result.setGeom(sFeat.getFeature().getDefaultGeometry());
245
                                List<ScoredFeature> sources = new ArrayList<ScoredFeature>();
246
                                sources.add(sFeat);
247
                                result.setMainSources(sources);
248
                                result.setAddress(getResultAddress(sources));
249
                                results.add(result);
250
                        } catch (DataException e) {
251
                                log.error("Error getting the feature", e);
252
                        }
253
                }
254
                return results;
255
        }
256

    
257
        /**
258
         * Saves the internal state of the object on the provided PersistentState
259
         * object.
260
         * 
261
         * @param state
262
         */
263
        public void saveToState(PersistentState state) throws PersistenceException {
264
                super.saveToState(state);
265
        }
266

    
267
        /**
268
         * Set the state of the object from the state passed as parameter.
269
         * 
270
         * @param state
271
         */
272
        public void setState(PersistentState state) throws PersistenceException {
273
                super.setState(state);
274
        }
275
}