root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / VectorialAdapter.java @ 25274
History | View | Annotate | Download (9.01 KB)
1 | 1100 | fjp | /* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
|
||
4 | *
|
||
5 | * This program is free software; you can redistribute it and/or
|
||
6 | * modify it under the terms of the GNU General Public License
|
||
7 | * as published by the Free Software Foundation; either version 2
|
||
8 | * of the License, or (at your option) any later version.
|
||
9 | *
|
||
10 | * This program is distributed in the hope that it will be useful,
|
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
13 | * GNU General Public License for more details.
|
||
14 | *
|
||
15 | * You should have received a copy of the GNU General Public License
|
||
16 | * along with this program; if not, write to the Free Software
|
||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
18 | *
|
||
19 | * For more information, contact:
|
||
20 | *
|
||
21 | * Generalitat Valenciana
|
||
22 | * Conselleria d'Infraestructures i Transport
|
||
23 | * Av. Blasco Ib??ez, 50
|
||
24 | * 46010 VALENCIA
|
||
25 | * SPAIN
|
||
26 | *
|
||
27 | * +34 963862235
|
||
28 | * gvsig@gva.es
|
||
29 | * www.gvsig.gva.es
|
||
30 | *
|
||
31 | * or
|
||
32 | *
|
||
33 | * IVER T.I. S.A
|
||
34 | * Salamanca 50
|
||
35 | * 46005 Valencia
|
||
36 | * Spain
|
||
37 | *
|
||
38 | * +34 963163400
|
||
39 | * dac@iver.es
|
||
40 | */
|
||
41 | 214 | fernando | package com.iver.cit.gvsig.fmap.layers; |
42 | |||
43 | 3601 | fjp | import java.awt.Image; |
44 | 3936 | fjp | import java.awt.geom.Rectangle2D; |
45 | 214 | fernando | |
46 | 11287 | azabala | import org.cresques.cts.IProjection; |
47 | |||
48 | 10627 | caballero | import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
49 | 408 | fernando | import com.hardcode.gdbms.engine.data.DataSource; |
50 | 3207 | fjp | import com.hardcode.gdbms.engine.values.Value; |
51 | 10627 | caballero | import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException; |
52 | 3207 | fjp | import com.iver.cit.gvsig.fmap.core.DefaultFeature; |
53 | import com.iver.cit.gvsig.fmap.core.IFeature; |
||
54 | import com.iver.cit.gvsig.fmap.core.IGeometry; |
||
55 | 1233 | fjp | import com.iver.cit.gvsig.fmap.drivers.DriverAttributes; |
56 | 11287 | azabala | import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator; |
57 | 214 | fernando | import com.iver.cit.gvsig.fmap.drivers.VectorialDriver; |
58 | 11881 | azabala | import com.iver.cit.gvsig.fmap.drivers.featureiterators.AttrQueryFeatureIterator; |
59 | 24223 | vcaballero | import com.iver.cit.gvsig.fmap.drivers.featureiterators.AttrQuerySelectionFeatureIterator; |
60 | 11881 | azabala | import com.iver.cit.gvsig.fmap.drivers.featureiterators.DefaultFeatureIterator; |
61 | import com.iver.cit.gvsig.fmap.drivers.featureiterators.IndexedSptQueryFeatureIterator; |
||
62 | import com.iver.cit.gvsig.fmap.drivers.featureiterators.SpatialQueryFeatureIterator; |
||
63 | 11287 | azabala | import com.iver.cit.gvsig.fmap.spatialindex.ISpatialIndex; |
64 | 1034 | vcaballero | |
65 | 214 | fernando | /**
|
66 | 1034 | vcaballero | * Clase padre de los adaptadores de los drivers. De momento mantiene solo el
|
67 | * ?ndice creado sobre la capa
|
||
68 | 214 | fernando | */
|
69 | 1691 | fjp | public abstract class VectorialAdapter implements ReadableVectorial { |
70 | protected VectorialDriver driver;
|
||
71 | 11287 | azabala | /**
|
72 | * Spatial index of the driver's data source
|
||
73 | * */
|
||
74 | protected ISpatialIndex spatialIndex;
|
||
75 | /**
|
||
76 | * Projection of the data in the data source
|
||
77 | */
|
||
78 | protected IProjection projection;
|
||
79 | 4085 | fjp | |
80 | 214 | fernando | /**
|
81 | 1034 | vcaballero | * Establece el driver sobre el que act?a el adaptador
|
82 | 10627 | caballero | *
|
83 | 1034 | vcaballero | * @param driver
|
84 | */
|
||
85 | public void setDriver(VectorialDriver driver) { |
||
86 | this.driver = driver;
|
||
87 | } |
||
88 | 214 | fernando | |
89 | 1034 | vcaballero | /**
|
90 | 4085 | fjp | * Obtiene una referencia al objeto que implementa la interfaz vectorial con
|
91 | * el fin de que las Strategy puedan optimizar en funci?n del driver.
|
||
92 | 10627 | caballero | *
|
93 | 1034 | vcaballero | * @return VectorialDriver
|
94 | */
|
||
95 | public VectorialDriver getDriver() {
|
||
96 | return driver;
|
||
97 | } |
||
98 | 214 | fernando | |
99 | 1034 | vcaballero | /**
|
100 | * Devuelve el DataSource a pasrtir del nombre.
|
||
101 | 10627 | caballero | *
|
102 | 1034 | vcaballero | * @return DataSource.
|
103 | 10627 | caballero | *
|
104 | * @throws ReadDriverException
|
||
105 | 217 | fernando | */
|
106 | 3959 | caballero | public abstract SelectableDataSource getRecordset() |
107 | 10665 | caballero | throws ReadDriverException;
|
108 | 1034 | vcaballero | |
109 | 309 | fernando | /**
|
110 | 4085 | fjp | * Por defecto devuelve null, y se le pone el icono por defecto. Si el
|
111 | * driver reescribe este m?todo, se usar? este icono en el TOC.
|
||
112 | 10627 | caballero | *
|
113 | 1233 | fjp | * @return
|
114 | */
|
||
115 | 4085 | fjp | public Image getImageIcon() { |
116 | return null; |
||
117 | 1233 | fjp | } |
118 | 3959 | caballero | |
119 | 4085 | fjp | public DriverAttributes getDriverAttributes() {
|
120 | if (driver != null) |
||
121 | return driver.getDriverAttributes();
|
||
122 | return null; |
||
123 | 1233 | fjp | } |
124 | 3959 | caballero | |
125 | 3943 | fjp | /**
|
126 | * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeCount()
|
||
127 | */
|
||
128 | 10627 | caballero | public int getShapeCount() throws ReadDriverException { |
129 | return getDriver().getShapeCount();
|
||
130 | 3943 | fjp | } |
131 | |||
132 | /**
|
||
133 | * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
|
||
134 | */
|
||
135 | 10627 | caballero | public Rectangle2D getFullExtent() throws ReadDriverException { |
136 | 3943 | fjp | try {
|
137 | 5400 | fjp | Rectangle2D aux = getDriver().getFullExtent();
|
138 | // Para evitar que una nueva capa a?adida a una vista vac?a no
|
||
139 | // tenga un lienzo para pintar.
|
||
140 | if (aux == null) |
||
141 | aux = new Rectangle2D.Double(1,1,10,10); |
||
142 | return aux;
|
||
143 | 10627 | caballero | } catch (ExpansionFileReadException e) {
|
144 | throw new ReadDriverException(getDriver().getName(),e); |
||
145 | 3943 | fjp | } |
146 | } |
||
147 | 3959 | caballero | |
148 | 4085 | fjp | /**
|
149 | * En la implementaci?n por defecto podemos hacer que cada feature tenga ID =
|
||
150 | * numero de registro. En el DBAdapter podr?amos "overrride" este m?todo y
|
||
151 | * poner como ID de la Feature el campo ?nico escogido en la base de datos.
|
||
152 | 10627 | caballero | *
|
153 | 4085 | fjp | * @param numReg
|
154 | * @return
|
||
155 | */
|
||
156 | 10627 | caballero | public IFeature getFeature(int numReg) throws ReadDriverException { |
157 | 4085 | fjp | IGeometry geom; |
158 | IFeature feat = null;
|
||
159 | try {
|
||
160 | geom = getShape(numReg); |
||
161 | DataSource rs = getRecordset();
|
||
162 | Value[] regAtt = new Value[rs.getFieldCount()]; |
||
163 | for (int fieldId = 0; fieldId < rs.getFieldCount(); fieldId++) { |
||
164 | regAtt[fieldId] = rs.getFieldValue(numReg, fieldId); |
||
165 | } |
||
166 | 3959 | caballero | |
167 | 4085 | fjp | feat = new DefaultFeature(geom, regAtt, numReg + ""); |
168 | 10627 | caballero | } catch (ExpansionFileReadException e) {
|
169 | throw new ReadDriverException(getDriver().getName(),e); |
||
170 | 4085 | fjp | } |
171 | return feat;
|
||
172 | } |
||
173 | 24223 | vcaballero | |
174 | 11287 | azabala | public IFeatureIterator getFeatureIterator() throws ReadDriverException{ |
175 | return new DefaultFeatureIterator(this, projection, null, null); |
||
176 | } |
||
177 | 24223 | vcaballero | |
178 | public IFeatureIterator getFeatureIterator(String[] fields, IProjection newProjection) |
||
179 | 11287 | azabala | throws ReadDriverException{
|
180 | return new DefaultFeatureIterator(this, projection, newProjection, fields); |
||
181 | } |
||
182 | 24223 | vcaballero | |
183 | 11287 | azabala | /**
|
184 | * Return a feature iterator from a given sql statement.
|
||
185 | * <br>
|
||
186 | * In this case, the statement will have the "projection" operator
|
||
187 | * (select campo1, campo2, ...etc) and the "selection" operator (where ....)
|
||
188 | * @param sql statement which define a filter
|
||
189 | * @return feature iterator
|
||
190 | * */
|
||
191 | 24223 | vcaballero | public IFeatureIterator getFeatureIterator(String sql, |
192 | 11287 | azabala | IProjection newProjection) throws ReadDriverException{
|
193 | 24223 | vcaballero | |
194 | 11287 | azabala | return new AttrQueryFeatureIterator(this, projection, newProjection, sql); |
195 | } |
||
196 | 24223 | vcaballero | |
197 | |||
198 | 11287 | azabala | /**
|
199 | * Makes an spatial query returning a feature iterator over the features which intersects
|
||
200 | * or are contained in the rectangle query. Applies a restriction to the alphanumeric fields
|
||
201 | * returned by the iterator.
|
||
202 | * @param rect
|
||
203 | * @param fields
|
||
204 | * @return
|
||
205 | 24223 | vcaballero | * @throws ReadDriverException
|
206 | */
|
||
207 | public IFeatureIterator getFeatureIterator(Rectangle2D rect, String[] fields, |
||
208 | IProjection newProjection, |
||
209 | 11881 | azabala | boolean fastIteration) throws ReadDriverException{ |
210 | if(spatialIndex != null){ |
||
211 | try {
|
||
212 | if(isSpatialIndexNecessary(rect))
|
||
213 | return new IndexedSptQueryFeatureIterator(this, projection, newProjection, fields, rect, spatialIndex, fastIteration); |
||
214 | } catch (ExpansionFileReadException e) {
|
||
215 | e.printStackTrace(); |
||
216 | throw new ReadDriverException("Error al iterar la capa", e); |
||
217 | 24223 | vcaballero | } |
218 | 11881 | azabala | }//if
|
219 | return new SpatialQueryFeatureIterator(this, projection, newProjection, fields, rect, fastIteration); |
||
220 | 24223 | vcaballero | |
221 | |||
222 | 11287 | azabala | } |
223 | 24223 | vcaballero | |
224 | |||
225 | 11881 | azabala | /*
|
226 | * this method is copied from ShpStrategy
|
||
227 | * */
|
||
228 | /**
|
||
229 | * Decides if for a given Rectangle2D extent, is worthy to use an spatial index
|
||
230 | * (or a secuential scan)
|
||
231 | * @param extent Rectangle2D used to filter features
|
||
232 | * @return true if spatial index search is worthy, or false
|
||
233 | */
|
||
234 | protected boolean isSpatialIndexNecessary(Rectangle2D extent) throws ReadDriverException, ExpansionFileReadException { |
||
235 | Rectangle2D driverExtent = getFullExtent();
|
||
236 | double areaExtent = extent.getWidth() * extent.getHeight();
|
||
237 | double areaFullExtent = driverExtent.getWidth() *
|
||
238 | driverExtent.getHeight(); |
||
239 | return areaExtent < (areaFullExtent / 4.0); |
||
240 | |||
241 | } |
||
242 | 24223 | vcaballero | |
243 | 11287 | azabala | public ISpatialIndex getSpatialIndex(){
|
244 | return spatialIndex;
|
||
245 | 24223 | vcaballero | |
246 | 11287 | azabala | } |
247 | public void setSpatialIndex(ISpatialIndex spatialIndex){ |
||
248 | this.spatialIndex = spatialIndex;
|
||
249 | } |
||
250 | 24223 | vcaballero | |
251 | 11287 | azabala | public void setProjection(IProjection projection){ |
252 | this.projection = projection;
|
||
253 | } |
||
254 | 24223 | vcaballero | |
255 | 11287 | azabala | public IProjection getProjection(){
|
256 | return projection;
|
||
257 | } |
||
258 | 3248 | fjp | |
259 | 24223 | vcaballero | public IFeatureIterator getFeatureIterator(String sql, IProjection newProjection, boolean withSelection) throws ReadDriverException { |
260 | if (withSelection)
|
||
261 | return new AttrQuerySelectionFeatureIterator(this, projection, newProjection, sql); |
||
262 | else
|
||
263 | return getFeatureIterator(sql,newProjection);
|
||
264 | } |
||
265 | 4085 | fjp | /*
|
266 | * (non-Javadoc)
|
||
267 | 10627 | caballero | *
|
268 | 4085 | fjp | * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFeatureIterator(java.awt.geom.Rectangle2D,
|
269 | * java.lang.String) Lo sobreescribir?n los adapters para base de datos
|
||
270 | * espacial. Por defecto, suponemos un buen acceso aleatorio y usamos
|
||
271 | * getFeature(i)
|
||
272 | */
|
||
273 | 4115 | fjp | /* public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG)
|
274 | 4085 | fjp | throws DriverException {
|
275 | try {
|
||
276 | return new RandomAccessFeatureIterator(driver, getRecordset(), r,
|
||
277 | strEPSG);
|
||
278 | } catch (DriverLoadException e) {
|
||
279 | throw new DriverException(e);
|
||
280 | }
|
||
281 | }
|
||
282 | 3959 | caballero | |
283 | 4085 | fjp | public IFeatureIterator getFeatureIterator(String strEPSG)
|
284 | throws DriverException {
|
||
285 | try {
|
||
286 | return new RandomAccessFeatureIterator(driver, getRecordset(), strEPSG);
|
||
287 | } catch (DriverLoadException e) {
|
||
288 | throw new DriverException(e);
|
||
289 | }
|
||
290 | 4115 | fjp | } */
|
291 | 3959 | caballero | |
292 | 214 | fernando | } |