Statistics
| Revision:

gvsig-gdal / trunk / org.gvsig.gdal / org.gvsig.gdal.prov / org.gvsig.gdal.prov.ogr / src / main / java / org / gvsig / gdal / prov / ogr / OGRFetureSetProvider.java @ 209

History | View | Annotate | Download (9.05 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2016 gvSIG Association
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.gdal.prov.ogr;
25

    
26
import java.util.regex.Matcher;
27
import java.util.regex.Pattern;
28

    
29
import org.cresques.cts.ICRSFactory;
30
import org.cresques.cts.IProjection;
31
import org.gdal.ogr.DataSource;
32
import org.gdal.ogr.Feature;
33
import org.gdal.ogr.Geometry;
34
import org.gdal.ogr.Layer;
35
import org.gdal.ogr.ogr;
36
import org.gdal.ogr.ogrConstants;
37
import org.gdal.osr.SpatialReference;
38
import org.gvsig.fmap.crs.CRSFactory;
39
import org.gvsig.fmap.dal.DataStore;
40
import org.gvsig.fmap.dal.exception.DataException;
41
import org.gvsig.fmap.dal.feature.FeatureQuery;
42
import org.gvsig.fmap.dal.feature.FeatureType;
43
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
44
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureProviderIterator;
45
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureSetProvider;
46
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
47
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
48
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
49
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
50
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
51
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
52
import org.gvsig.tools.ToolsLocator;
53
import org.gvsig.tools.exception.BaseException;
54
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
56

    
57
/**
58
 *
59
 * @author <a href="mailto:lmarques@disid.com">Lluis Marques</a>
60
 *
61
 */
62
public class OGRFetureSetProvider extends AbstractFeatureSetProvider implements FeatureSetProvider,
63
    ResourceConsumer {
64

    
65
    private static final Logger LOG = LoggerFactory.getLogger(OGRFetureSetProvider.class);
66

    
67
    private static final String regularExpresion =
68
        "\\s*ST_intersects[(]\\s*ST_GeomFromText[(]\\s*'([^']*)'\\s*,\\s*'([^']*)'\\s*[)],\\s*(?s).*";
69

    
70
    /**
71
     * @param store
72
     *            Source of this feature set
73
     * @param query
74
     *            Query
75
     * @param featureType
76
     *            Featuretype requested
77
     */
78
    public OGRFetureSetProvider(AbstractFeatureStoreProvider store, FeatureQuery query,
79
        FeatureType featureType) {
80
        super(store, query, featureType);
81

    
82
        getStore().getResource().addConsumer(this);
83
    }
84

    
85
    @Override
86
    public boolean canFilter() {
87
        return false;
88
    }
89

    
90
    @Override
91
    public boolean canOrder() {
92
        return true;
93
    }
94

    
95
    @Override
96
    public boolean canIterateFromIndex() {
97
        return true;
98
    }
99

    
100
    @Override
101
    public long getSize() throws DataException {
102
        return getStore().getFeatureCount();
103
    }
104

    
105
    @Override
106
    public boolean isEmpty() throws DataException {
107
        return getSize() == 0;
108
    }
109

    
110
    @Override
111
    protected AbstractFeatureProviderIterator createIterator(long index) throws DataException {
112
        return createFastIterator(index);
113
    }
114

    
115
    @Override
116
    protected AbstractFeatureProviderIterator createFastIterator(long index) throws DataException {
117
        String sql =
118
            getOGRStoreProvider().compoundSelect(getFeatureType(), getQuery().getFilter(),
119
                getQuery().getOrder());
120

    
121
        DataSource dataSource = getOGRStoreProvider().getDataSource();
122
        LOG.debug("Running query {} over {}", new Object[] { sql, dataSource.getName() });
123

    
124
        Layer layer = null;
125
        boolean ignoreSpatialFilter = (boolean) getStore().getParameters().getDynValue(OGRDataStoreParameters.IGNORE_SPATIAL_FILTER);
126
        if (!ignoreSpatialFilter && getOGRStoreProvider().getLayer().TestCapability(ogrConstants.OLCFastSpatialFilter)
127
            && getQuery().hasFilter()) {
128

    
129
            String evaluatorSQL = getQuery().getFilter().getSQL();
130
            Pattern pattern = Pattern.compile(regularExpresion);
131
            Matcher matcher = pattern.matcher(evaluatorSQL);
132

    
133
            if (matcher.matches()) {
134
                String wktGeometry = matcher.group(1);
135
                String crsCode = matcher.group(2);
136

    
137
                IProjection projection = CRSFactory.getCRS(crsCode);
138
                SpatialReference srs =
139
                    new SpatialReference(projection.export(ICRSFactory.FORMAT_WKT));
140
                Geometry ogrGeometry = ogr.CreateGeometryFromWkt(wktGeometry, srs);
141

    
142
                if (getOGRStoreProvider().getDynValue(DataStore.METADATA_CRS) != null) {
143

    
144
                    IProjection projectionProvider =
145
                        (IProjection) getOGRStoreProvider().getDynValue(DataStore.METADATA_CRS);
146
                    if (!crsCode.equals(projectionProvider.getAbrev())) {
147
                        SpatialReference srsDst =
148
                            new SpatialReference(projectionProvider.export(ICRSFactory.FORMAT_WKT));
149
                        ogrGeometry.TransformTo(srsDst);
150
                    }
151
                }
152
                layer = dataSource.ExecuteSQL(sql, ogrGeometry);
153
            }
154
        } else {
155
            layer = dataSource.ExecuteSQL(sql);
156
        }
157

    
158
        if(layer == null){
159
            LOG.warn("The result of query is null. SQL {} FeatureType {}", sql, getFeatureType());
160
            LOG.warn("Getting data without SQL filter");
161
            OGRDataStoreParameters ogrParameters = (OGRDataStoreParameters) getOGRStoreProvider().getParameters();
162
            layer = dataSource.ExecuteSQL("SELECT * FROM ".concat(ogrParameters.getLayerName()));
163
        }
164

    
165
        return new OGRFastIterator(getStore(), layer, index);
166
    }
167

    
168
    @Override
169
    protected void doDispose() throws BaseException {
170
        getStore().getResource().removeConsumer(this);
171
    }
172

    
173
    @Override
174
    public boolean closeResourceRequested(ResourceProvider resource) {
175
        return true;
176
    }
177

    
178
    @Override
179
    public void resourceChanged(ResourceProvider resource) {
180
    }
181

    
182
    class OGRFastIterator extends AbstractFeatureProviderIterator implements ResourceConsumer {
183

    
184
        private long index;
185

    
186
        private Layer layer;
187

    
188
        private OGRConverter converter;
189

    
190
        private FeatureProvider featureProvider;
191

    
192
        private Feature currentOgrFeature;
193
        private Feature nextOgrFeature;
194

    
195
        public OGRFastIterator(FeatureStoreProvider storeProvider, Layer layer, long index)
196
            throws OGRUnsupportedFormatException {
197
            super(storeProvider);
198
            ToolsLocator.getDisposableManager().bind(storeProvider);
199
            getResource().addConsumer(this);
200
            this.converter = new OGRConverter();
201
            this.index = index;
202
            this.layer = layer;
203
            this.layer.GetFeatureCount();
204
            this.layer.ResetReading();
205
            if(index!=0){
206
                this.layer.SetNextByIndex((int) index);
207
            }
208
            this.currentOgrFeature = null;
209
            this.nextOgrFeature =  this.layer.GetNextFeature();
210
        }
211

    
212
        @Override
213
        public void remove() {
214
            if (currentOgrFeature != null) {
215
                this.layer.DeleteFeature(currentOgrFeature.GetFID());
216
                currentOgrFeature=null;
217
            }
218
        }
219

    
220
        @Override
221
        protected Object internalNext() {
222
            this.currentOgrFeature = this.nextOgrFeature;
223
            this.featureProvider = null;
224
            this.featureProvider = converter.convert(featureProvider, getFeatureType(), this.nextOgrFeature);
225
            this.nextOgrFeature =  this.layer.GetNextFeature();
226
            return this.featureProvider;
227
        }
228

    
229
        @Override
230
        protected boolean internalHasNext() {
231
            return nextOgrFeature!=null;
232
        }
233

    
234
        @Override
235
        protected void doDispose() throws BaseException {
236
            ToolsLocator.getDisposableManager().release(getStore());
237
            getOGRStoreProvider().getDataSource().ReleaseResultSet(layer);
238
            getResource().removeConsumer(this);
239
            this.converter = null;
240
            this.featureProvider = null;
241
            this.layer = null;
242
        }
243

    
244
        @Override
245
        public boolean closeResourceRequested(ResourceProvider resource) {
246
            this.featureProvider = null;
247
            return true;
248
        }
249

    
250
        @Override
251
        public void resourceChanged(ResourceProvider resource) {
252
            throw new ConcurrentDataModificationException(getOGRStoreProvider().getName());
253
        }
254
    }
255

    
256
    private OGRDataStoreProvider getOGRStoreProvider() {
257
        return (OGRDataStoreProvider) getStore();
258
    }
259
}