Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / org.gvsig.oracle / src / org / gvsig / fmap / dal / store / oracle / OracleSetProvider.java @ 38055

History | View | Annotate | Download (13.5 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.feature.spi.AbstractFeatureStoreProvider;
39
import org.gvsig.fmap.dal.store.jdbc.JDBCIterator;
40
import org.gvsig.fmap.dal.store.jdbc.JDBCSetProvider;
41
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreProvider;
42
import org.gvsig.fmap.geom.Geometry;
43
import org.gvsig.fmap.geom.GeometryException;
44
import org.gvsig.fmap.geom.GeometryLocator;
45
import org.gvsig.fmap.geom.GeometryManager;
46
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
47
import org.gvsig.fmap.geom.aggregate.impl.MultiSurface2D;
48
import org.gvsig.fmap.geom.primitive.Envelope;
49
import org.gvsig.fmap.geom.primitive.NullGeometry;
50
import org.gvsig.fmap.geom.primitive.impl.Circle2D;
51
import org.gvsig.fmap.mapcontext.layers.vectorial.IntersectsEnvelopeEvaluator;
52
import org.gvsig.fmap.mapcontext.layers.vectorial.IntersectsGeometryEvaluator;
53
import org.gvsig.tools.evaluator.Evaluator;
54
import org.gvsig.tools.evaluator.EvaluatorFieldValueMatch;
55
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
57

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

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

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

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

    
95
        }
96

    
97
        
98
        protected String getSqlForEvaluator(Evaluator filter) {
99
            
100
            String gfld = getFeatureType().getDefaultGeometryAttributeName();
101
            if (gfld == null) {
102
                    try {
103
                            gfld = findGeometryName(getStore());
104
                    } catch (Exception ex) {
105
                            logger.error("While getting geom field name: "
106
                                            + ex.getMessage() + ". Assumed: " + OracleValues.DEFAULT_CARTOCIUDAD_GEO_FIELD);
107
                            gfld = OracleValues.DEFAULT_CARTOCIUDAD_GEO_FIELD;
108
                    }
109
            }
110
            
111
            Object envGeoOrNull = null;
112
            
113
            boolean isFilterApplicable = false;
114
            try {
115
                if (filter == null
116
                || filter instanceof IntersectsGeometryEvaluator
117
                || filter instanceof IntersectsEnvelopeEvaluator) {
118
                    isFilterApplicable = true;
119
                    envGeoOrNull = getGeomFilterObject(filter, (OracleStoreParameters) getStore().getParameters(), gfld);
120
                } else {
121
                    //If the filter is not null, the filterarea parameter has to be also applied
122
                    envGeoOrNull = getStore().getParameters().getDynValue(OracleStoreParameters.ORA_AREA_OF_INT_KEY);
123
                }
124
                
125
            } catch (Exception ex) {
126
                logger.error("While getting filter object: " + ex.getMessage());
127
            }
128

    
129
            Envelope env = null;
130
            Geometry geom = null;
131
            String filterString = null;
132
            String srs = "";
133
            boolean is_geo = false;
134

    
135
                if (envGeoOrNull != null) {                   
136
                    if (envGeoOrNull instanceof Envelope) {
137
                        
138
                        srs = (String) getStore().getDynValue(OracleStoreParameters.ORA_TABLE_SRID_KEY);
139
                        is_geo = OracleUtils.getIsGCS(srs, srs != null && srs.length() > 0);
140
                        env = (Envelope) envGeoOrNull;
141
                        filterString = OracleUtils.getIntersectsEnvelopeSelect(
142
                                        gfld, env, srs, is_geo);
143
                        
144
                    } else {
145
                    if (envGeoOrNull instanceof Geometry) {
146
                        
147
                        geom = (Geometry) envGeoOrNull; 
148
                        if (geom instanceof NullGeometry) {
149
                            // no intersection
150
                            filterString = "(ROWID is null)";
151
                        } else {
152
                            if (envGeoOrNull instanceof Circle2D) {
153
                                env = geom.getEnvelope();
154
                                srs = (String) getStore().getDynValue(OracleStoreParameters.ORA_TABLE_SRID_KEY);
155
                                is_geo = OracleUtils.getIsGCS(srs, srs != null && srs.length() > 0);
156
                                filterString = OracleUtils.getIntersectsEnvelopeSelect(
157
                                                gfld, env, srs, is_geo);
158
                                
159
                            } else {
160

    
161
                                // need conn
162
                                Connection conn = null;
163
                                try {
164
                                    conn = ((OracleStoreProvider) getStore()).getOraHelper().getConnection();
165
                                } catch (Exception ex) {
166
                                    logger.error("While getting connection: " + ex.getMessage());
167
                                    return null;
168
                                }
169
                                srs = (String) getStore().getDynValue(OracleStoreParameters.ORA_TABLE_SRID_KEY);
170
                                is_geo = OracleUtils.getIsGCS(srs, srs != null && srs.length() > 0);
171
                                filterString = OracleUtils.getIntersectsMultiRectSelect(
172
                                                gfld, geom, srs, is_geo, conn);
173
                            }
174
                        }
175
                    } else {
176
                        // unknwon
177
                        logger.warn("Found unexpected object: " + envGeoOrNull.getClass().getName());
178
                        filterString = "(ROWID is null)";
179
                    }
180
                    }
181
                }
182

    
183
                //If the filter has not been completely applied
184
                if (!isFilterApplicable) {
185
                    if (filterString == null) {
186
                        filterString = super.getSqlForEvaluator(filter);
187
                    }else{
188
                        filterString = filterString + " AND " + super.getSqlForEvaluator(filter);
189
                    }
190
                }                
191
                
192
                return filterString;
193
        }
194

    
195
    private String findGeometryName(AbstractFeatureStoreProvider store) throws Exception {
196
            
197
            if (store instanceof OracleStoreProvider) {
198
                    
199
                    OracleStoreProvider osp = (OracleStoreProvider) store;
200
                    FeatureType ft = osp.getFeatureStore().getDefaultFeatureType(); 
201
                    return ft.getDefaultGeometryAttributeName();
202
                    
203
            } else {
204
                    logger.error("Unable to get geometry field name! Assumed: " +
205
                                    OracleValues.DEFAULT_CARTOCIUDAD_GEO_FIELD);
206
                    return OracleValues.DEFAULT_CARTOCIUDAD_GEO_FIELD;
207
            }
208
                
209
        }
210

    
211
        /**
212
     * @param filter
213
     * @param parameters
214
     * @return
215
     */
216
    private Object getGeomFilterObject(
217
        Evaluator filter,
218
        OracleStoreParameters ora_pars,
219
        String gfname) throws Exception {
220

    
221
        Geometry filter_geom = null;
222
        Envelope filter_env = null;
223
        Envelope working_env = ora_pars.getWorkingArea();
224
        Geometry aoi_geom = (Geometry) ora_pars.getDynValue(OracleStoreParameters.ORA_AREA_OF_INT_KEY);
225

    
226
        // ==============================================================
227
        GeometryManager gm = GeometryLocator.getGeometryManager();
228

    
229
        // ==============================================================
230
        if (filter instanceof IntersectsGeometryEvaluator) {
231
            IntersectsGeometryEvaluator geo_filt = (IntersectsGeometryEvaluator) filter; 
232
            EvaluatorFieldValueMatch em =
233
                (EvaluatorFieldValueMatch) geo_filt.getFieldsInfo().getFieldValues(gfname)[0]; 
234
            filter_geom = (Geometry) em.getValue();
235
            
236
            if (filter_geom.getEnvelope().getLength(0) == 0
237
                || filter_geom.getEnvelope().getLength(1) == 0) {
238
                return gm.createNullGeometry(SUBTYPES.GEOM2D);
239
            }
240
            
241
        } else {
242
            if (filter instanceof IntersectsEnvelopeEvaluator) {
243
                IntersectsEnvelopeEvaluator geo_filt = (IntersectsEnvelopeEvaluator) filter; 
244
                EvaluatorFieldValueMatch em =
245
                    (EvaluatorFieldValueMatch) geo_filt.getFieldsInfo().getFieldValues(gfname)[0]; 
246
                filter_env = (Envelope) em.getValue();
247
                
248
                if (filter_env.getLength(0) == 0
249
                    || filter_env.getLength(1) == 0) {
250
                    return gm.createNullGeometry(SUBTYPES.GEOM2D);
251
                }
252

    
253
            }
254
        }
255
        // ==============================================================
256
        // envelope area == 0
257
        
258
        // ==============================================================
259
        
260
        
261
        
262
        if (filter_geom == null && filter_env == null) {
263
            if (working_env == null && aoi_geom == null) {
264
                return null;
265
            } else {
266
                if (working_env != null) {
267
                    if (aoi_geom == null) {
268
                        return working_env;
269
                    } else {
270
                        return intersectEnvMultiRect(working_env, aoi_geom, gm);
271
                    }
272
                } else {
273
                    return aoi_geom;
274
                }
275
            }
276
        } else {
277
            if (filter_geom != null) {
278
                if (working_env == null && aoi_geom == null) {
279
                    return filter_geom;
280
                } else {
281
                    if (working_env != null) {
282
                        if (aoi_geom == null) {
283
                            return interSecEnv(filter_geom.getEnvelope(), working_env, gm);
284
                        } else {
285
                            Object aux = interSecEnv(filter_geom.getEnvelope(), working_env, gm);
286
                            if (aux instanceof Envelope) {
287
                                Envelope aux_env = (Envelope) aux;
288
                                return intersectEnvMultiRect(aux_env, aoi_geom, gm);
289
                            } else {
290
                                // null geometry
291
                                return aux;
292
                            }
293
                        }
294
                    } else {
295
                        return intersectEnvMultiRect(filter_geom.getEnvelope(), aoi_geom, gm);
296
                    }
297
                }
298
            } else {
299
                // filter_env
300
                if (working_env == null && aoi_geom == null) {
301
                    return filter_env;
302
                } else {
303
                    if (working_env != null) {
304
                        if (aoi_geom == null) {
305
                            return interSecEnv(filter_env, working_env, gm);
306
                        } else {
307
                            Object aux = interSecEnv(filter_env, working_env, gm);
308
                            if (aux instanceof Envelope) {
309
                                Envelope aux_env = (Envelope) aux;
310
                                return intersectEnvMultiRect(aux_env, aoi_geom, gm);
311
                            } else {
312
                                // null geometry
313
                                return aux;
314
                            }
315
                        }
316
                    } else {
317
                        return intersectEnvMultiRect(filter_env, aoi_geom, gm);
318
                    }
319
                }
320
            }
321
        }
322
        
323
        // =============================================================
324
    }
325

    
326
    /**
327
     * @param working_env
328
     * @param aoi_geom
329
     * @return
330
     */
331
    private Object intersectEnvMultiRect(Envelope env, Geometry aoi, GeometryManager gma) throws Exception {
332
        if (env == null || aoi == null || aoi instanceof NullGeometry) {
333
            return gma.createNullGeometry(SUBTYPES.GEOM2D);
334
        } else {
335
            return OracleUtils.roughIntersection(aoi, env);
336
        }
337
    }
338

    
339
    /**
340
     * @param filter_env
341
     * @param working_env
342
     * @return
343
     */
344
    private Object interSecEnv(Envelope enva, Envelope envb, GeometryManager gma) throws Exception  {
345
        
346
        if (enva == null || envb == null) {
347
            return gma.createNullGeometry(SUBTYPES.GEOM2D);
348
        }
349
        
350
        if (enva.intersects(envb)) {
351
            // intersect envs
352
            return enva.getGeometry().intersection(envb.getGeometry()).getEnvelope();
353
        } else {
354
            return gma.createNullGeometry(SUBTYPES.GEOM2D); 
355
        }
356
    }
357

    
358
}