Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / org.gvsig.oracle / src / org / gvsig / fmap / dal / store / oracle / OracleSetProvider.java @ 37896

History | View | Annotate | Download (12.7 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
 * 2009 Prodevelop S.L. main development
26
 */
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.fmap.dal.store.oracle;
32

    
33
import java.sql.Connection;
34

    
35
import org.gvsig.fmap.dal.exception.DataException;
36
import org.gvsig.fmap.dal.feature.FeatureQuery;
37
import org.gvsig.fmap.dal.feature.FeatureType;
38
import org.gvsig.fmap.dal.store.jdbc.JDBCIterator;
39
import org.gvsig.fmap.dal.store.jdbc.JDBCSetProvider;
40
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreProvider;
41
import org.gvsig.fmap.geom.Geometry;
42
import org.gvsig.fmap.geom.GeometryException;
43
import org.gvsig.fmap.geom.GeometryLocator;
44
import org.gvsig.fmap.geom.GeometryManager;
45
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
46
import org.gvsig.fmap.geom.aggregate.impl.MultiSurface2D;
47
import org.gvsig.fmap.geom.primitive.Envelope;
48
import org.gvsig.fmap.geom.primitive.NullGeometry;
49
import org.gvsig.fmap.geom.primitive.impl.Circle2D;
50
import org.gvsig.fmap.mapcontext.layers.vectorial.IntersectsEnvelopeEvaluator;
51
import org.gvsig.fmap.mapcontext.layers.vectorial.IntersectsGeometryEvaluator;
52
import org.gvsig.tools.evaluator.Evaluator;
53
import org.gvsig.tools.evaluator.EvaluatorFieldValueMatch;
54
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
56

    
57
/**
58
 * @author jmvivo
59
 * 
60
 */
61
public class OracleSetProvider extends JDBCSetProvider {
62
        
63
        private static Logger logger = LoggerFactory.getLogger(OracleSetProvider.class);
64

    
65
        public OracleSetProvider(JDBCStoreProvider store, FeatureQuery query,
66
                        FeatureType featureType) throws DataException {
67
                super(store, query, featureType);
68
        }
69

    
70
        /*
71
         * (non-Javadoc)
72
         * 
73
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canFilter()
74
         */
75
        public boolean canFilter() {
76
                // TODO more checks
77
                // return true;
78
                return true;
79
        }
80
        
81
        protected JDBCIterator createFastIterator(long index) throws DataException {
82
                return super.createFastIterator(index);
83
        }
84
        
85
        protected JDBCIterator createDefaultFastIterator(int resultSetID)
86
        throws DataException {
87
                
88
                // super(store, set, featureType, resultsetID);
89
                // this.featureProvider = super.createFeatureProvider();
90

    
91
                return new OracleJdbcFastIterator((JDBCStoreProvider) getStore(), this,
92
                getFeatureType(), resultSetID);
93
}
94

    
95
        
96
        protected String getSqlForEvaluator(Evaluator filter) {
97
            
98
            String gfld = getFeatureType().getDefaultGeometryAttributeName();
99
            Object envGeoOrNull = null;
100
            
101
            boolean isFilterApplicable = false;
102
            try {
103
                if (filter == null
104
                || filter instanceof IntersectsGeometryEvaluator
105
                || filter instanceof IntersectsEnvelopeEvaluator) {
106
                    isFilterApplicable = true;
107
                    envGeoOrNull = getGeomFilterObject(filter, (OracleStoreParameters) getStore().getParameters(), gfld);
108
                } else {
109
                    //If the filter is not null, the filterarea parameter has to be also applied
110
                    envGeoOrNull = getStore().getParameters().getDynValue(OracleStoreParameters.ORA_AREA_OF_INT_KEY);
111
                }
112
                
113
            } catch (Exception ex) {
114
                logger.error("While getting filter object: " + ex.getMessage());
115
            }
116

    
117
            Envelope env = null;
118
            Geometry geom = null;
119
            String filterString = null;
120
            String srs = "";
121
            boolean is_geo = false;
122

    
123
                if (envGeoOrNull != null) {                   
124
                    if (envGeoOrNull instanceof Envelope) {
125
                        
126
                        srs = (String) getStore().getDynValue(OracleStoreParameters.ORA_TABLE_SRID_KEY);
127
                        is_geo = OracleUtils.getIsGCS(srs, srs != null && srs.length() > 0);
128
                        env = (Envelope) envGeoOrNull;
129
                        filterString = OracleUtils.getIntersectsEnvelopeSelect(
130
                    getFeatureType().getDefaultGeometryAttributeName(),
131
                    env, srs, is_geo);
132
                        
133
                    } else {
134
                    if (envGeoOrNull instanceof Geometry) {
135
                        
136
                        geom = (Geometry) envGeoOrNull; 
137
                        if (geom instanceof NullGeometry) {
138
                            // no intersection
139
                            filterString = "(ROWID is null)";
140
                        } else {
141
                            if (envGeoOrNull instanceof Circle2D) {
142
                                env = geom.getEnvelope();
143
                                srs = (String) getStore().getDynValue(OracleStoreParameters.ORA_TABLE_SRID_KEY);
144
                                is_geo = OracleUtils.getIsGCS(srs, srs != null && srs.length() > 0);
145
                                filterString = OracleUtils.getIntersectsEnvelopeSelect(
146
                                    getFeatureType().getDefaultGeometryAttributeName(),
147
                                    env, srs, is_geo);
148
                                
149
                            } else {
150

    
151
                                // need conn
152
                                Connection conn = null;
153
                                try {
154
                                    conn = ((OracleStoreProvider) getStore()).getOraHelper().getConnection();
155
                                } catch (Exception ex) {
156
                                    logger.error("While getting connection: " + ex.getMessage());
157
                                    return null;
158
                                }
159
                                srs = (String) getStore().getDynValue(OracleStoreParameters.ORA_TABLE_SRID_KEY);
160
                                is_geo = OracleUtils.getIsGCS(srs, srs != null && srs.length() > 0);
161
                                filterString = OracleUtils.getIntersectsMultiRectSelect(
162
                                    getFeatureType().getDefaultGeometryAttributeName(),
163
                                    geom, srs, is_geo, conn);
164
                            }
165
                        }
166
                    } else {
167
                        // unknwon
168
                        logger.warn("Found unexpected object: " + envGeoOrNull.getClass().getName());
169
                        filterString = "(ROWID is null)";
170
                    }
171
                    }
172
                }
173
                
174
                //If the filter has not been completely applied
175
                if (!isFilterApplicable) {
176
                    if (filterString == null) {
177
                        filterString = super.getSqlForEvaluator(filter);
178
                    }else{
179
                        filterString = filterString + " AND " + super.getSqlForEvaluator(filter);
180
                    }
181
                }                
182
                
183
                return filterString;
184
        }
185

    
186
    /**
187
     * @param filter
188
     * @param parameters
189
     * @return
190
     */
191
    private Object getGeomFilterObject(
192
        Evaluator filter,
193
        OracleStoreParameters ora_pars,
194
        String gfname) throws Exception {
195

    
196
        Geometry filter_geom = null;
197
        Envelope filter_env = null;
198
        Envelope working_env = ora_pars.getWorkingArea();
199
        Geometry aoi_geom = (Geometry) ora_pars.getDynValue(OracleStoreParameters.ORA_AREA_OF_INT_KEY);
200

    
201
        // ==============================================================
202
        GeometryManager gm = GeometryLocator.getGeometryManager();
203

    
204
        // ==============================================================
205
        if (filter instanceof IntersectsGeometryEvaluator) {
206
            IntersectsGeometryEvaluator geo_filt = (IntersectsGeometryEvaluator) filter; 
207
            EvaluatorFieldValueMatch em =
208
                (EvaluatorFieldValueMatch) geo_filt.getFieldsInfo().getFieldValues(gfname)[0]; 
209
            filter_geom = (Geometry) em.getValue();
210
            
211
            if (filter_geom.getEnvelope().getLength(0) == 0
212
                || filter_geom.getEnvelope().getLength(1) == 0) {
213
                return gm.createNullGeometry(SUBTYPES.GEOM2D);
214
            }
215
            
216
        } else {
217
            if (filter instanceof IntersectsEnvelopeEvaluator) {
218
                IntersectsEnvelopeEvaluator geo_filt = (IntersectsEnvelopeEvaluator) filter; 
219
                EvaluatorFieldValueMatch em =
220
                    (EvaluatorFieldValueMatch) geo_filt.getFieldsInfo().getFieldValues(gfname)[0]; 
221
                filter_env = (Envelope) em.getValue();
222
                
223
                if (filter_env.getLength(0) == 0
224
                    || filter_env.getLength(1) == 0) {
225
                    return gm.createNullGeometry(SUBTYPES.GEOM2D);
226
                }
227

    
228
            }
229
        }
230
        // ==============================================================
231
        // envelope area == 0
232
        
233
        // ==============================================================
234
        
235
        
236
        
237
        if (filter_geom == null && filter_env == null) {
238
            if (working_env == null && aoi_geom == null) {
239
                return null;
240
            } else {
241
                if (working_env != null) {
242
                    if (aoi_geom == null) {
243
                        return working_env;
244
                    } else {
245
                        return intersectEnvMultiRect(working_env, aoi_geom, gm);
246
                    }
247
                } else {
248
                    return aoi_geom;
249
                }
250
            }
251
        } else {
252
            if (filter_geom != null) {
253
                if (working_env == null && aoi_geom == null) {
254
                    return filter_geom;
255
                } else {
256
                    if (working_env != null) {
257
                        if (aoi_geom == null) {
258
                            return interSecEnv(filter_geom.getEnvelope(), working_env, gm);
259
                        } else {
260
                            Object aux = interSecEnv(filter_geom.getEnvelope(), working_env, gm);
261
                            if (aux instanceof Envelope) {
262
                                Envelope aux_env = (Envelope) aux;
263
                                return intersectEnvMultiRect(aux_env, aoi_geom, gm);
264
                            } else {
265
                                // null geometry
266
                                return aux;
267
                            }
268
                        }
269
                    } else {
270
                        return intersectEnvMultiRect(filter_geom.getEnvelope(), aoi_geom, gm);
271
                    }
272
                }
273
            } else {
274
                // filter_env
275
                if (working_env == null && aoi_geom == null) {
276
                    return filter_env;
277
                } else {
278
                    if (working_env != null) {
279
                        if (aoi_geom == null) {
280
                            return interSecEnv(filter_env, working_env, gm);
281
                        } else {
282
                            Object aux = interSecEnv(filter_env, working_env, gm);
283
                            if (aux instanceof Envelope) {
284
                                Envelope aux_env = (Envelope) aux;
285
                                return intersectEnvMultiRect(aux_env, aoi_geom, gm);
286
                            } else {
287
                                // null geometry
288
                                return aux;
289
                            }
290
                        }
291
                    } else {
292
                        return intersectEnvMultiRect(filter_env, aoi_geom, gm);
293
                    }
294
                }
295
            }
296
        }
297
        
298
        // =============================================================
299
    }
300

    
301
    /**
302
     * @param working_env
303
     * @param aoi_geom
304
     * @return
305
     */
306
    private Object intersectEnvMultiRect(Envelope env, Geometry aoi, GeometryManager gma) throws Exception {
307
        if (env == null || aoi == null || aoi instanceof NullGeometry) {
308
            return gma.createNullGeometry(SUBTYPES.GEOM2D);
309
        } else {
310
            return OracleUtils.roughIntersection(aoi, env);
311
        }
312
    }
313

    
314
    /**
315
     * @param filter_env
316
     * @param working_env
317
     * @return
318
     */
319
    private Object interSecEnv(Envelope enva, Envelope envb, GeometryManager gma) throws Exception  {
320
        
321
        if (enva == null || envb == null) {
322
            return gma.createNullGeometry(SUBTYPES.GEOM2D);
323
        }
324
        
325
        if (enva.intersects(envb)) {
326
            // intersect envs
327
            return enva.getGeometry().intersection(envb.getGeometry()).getEnvelope();
328
        } else {
329
            return gma.createNullGeometry(SUBTYPES.GEOM2D); 
330
        }
331
    }
332

    
333
}