svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrVect.java @ 22465
History | View | Annotate | Download (60.2 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 | 1828 | fernando | import java.awt.Graphics2D; |
44 | 5048 | ldiaz | import java.awt.Point; |
45 | 14409 | vcaballero | import java.awt.geom.AffineTransform; |
46 | 1828 | fernando | import java.awt.geom.Point2D; |
47 | import java.awt.geom.Rectangle2D; |
||
48 | import java.awt.image.BufferedImage; |
||
49 | 4977 | azabala | import java.io.File; |
50 | 13558 | evercher | import java.net.URI; |
51 | 11704 | jaume | import java.util.ArrayList; |
52 | 1828 | fernando | |
53 | 9010 | caballero | import javax.print.attribute.PrintRequestAttributeSet; |
54 | 12657 | jaume | import javax.print.attribute.standard.PrintQuality; |
55 | 9010 | caballero | |
56 | 1828 | fernando | import org.apache.log4j.Logger; |
57 | import org.cresques.cts.ICoordTrans; |
||
58 | |||
59 | 10627 | caballero | import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
60 | 22465 | vcaballero | import com.hardcode.gdbms.engine.data.DataSourceFactory; |
61 | 1828 | fernando | import com.hardcode.gdbms.engine.data.NoSuchTableException; |
62 | 10627 | caballero | import com.hardcode.gdbms.engine.data.driver.DriverException; |
63 | 470 | fjp | import com.hardcode.gdbms.engine.instruction.FieldNotFoundException; |
64 | 10627 | caballero | import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException; |
65 | import com.iver.cit.gvsig.exceptions.layers.LegendLayerException; |
||
66 | 16254 | vcaballero | import com.iver.cit.gvsig.exceptions.layers.LoadLayerException; |
67 | 10627 | caballero | import com.iver.cit.gvsig.exceptions.layers.ReloadLayerException; |
68 | import com.iver.cit.gvsig.exceptions.layers.StartEditionLayerException; |
||
69 | import com.iver.cit.gvsig.exceptions.visitors.StartWriterVisitorException; |
||
70 | import com.iver.cit.gvsig.exceptions.visitors.VisitorException; |
||
71 | 12657 | jaume | import com.iver.cit.gvsig.fmap.MapContext; |
72 | 13928 | jaume | import com.iver.cit.gvsig.fmap.MapControl; |
73 | 214 | fernando | import com.iver.cit.gvsig.fmap.ViewPort; |
74 | 12466 | jaume | import com.iver.cit.gvsig.fmap.core.CartographicSupport; |
75 | 12349 | jaume | import com.iver.cit.gvsig.fmap.core.FPoint2D; |
76 | 12466 | jaume | import com.iver.cit.gvsig.fmap.core.FShape; |
77 | 11704 | jaume | import com.iver.cit.gvsig.fmap.core.IFeature; |
78 | 757 | fjp | import com.iver.cit.gvsig.fmap.core.IGeometry; |
79 | 10679 | jaume | import com.iver.cit.gvsig.fmap.core.ILabelable; |
80 | 11807 | jaume | import com.iver.cit.gvsig.fmap.core.symbols.IMultiLayerSymbol; |
81 | 11704 | jaume | import com.iver.cit.gvsig.fmap.core.symbols.ISymbol; |
82 | 14481 | vcaballero | import com.iver.cit.gvsig.fmap.core.v02.FSymbol; |
83 | 2978 | fjp | import com.iver.cit.gvsig.fmap.drivers.BoundedShapes; |
84 | 11704 | jaume | import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator; |
85 | 11971 | caballero | import com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver; |
86 | 3301 | fjp | import com.iver.cit.gvsig.fmap.drivers.VectorialDriver; |
87 | 6534 | jmvivo | import com.iver.cit.gvsig.fmap.drivers.WithDefaultLegend; |
88 | 4256 | caballero | import com.iver.cit.gvsig.fmap.edition.AnnotationEditableAdapter; |
89 | 5184 | caballero | import com.iver.cit.gvsig.fmap.edition.EditionEvent; |
90 | 6856 | fjp | import com.iver.cit.gvsig.fmap.edition.ISpatialWriter; |
91 | import com.iver.cit.gvsig.fmap.edition.IWriteable; |
||
92 | import com.iver.cit.gvsig.fmap.edition.IWriter; |
||
93 | 3981 | caballero | import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter; |
94 | 4159 | fjp | import com.iver.cit.gvsig.fmap.edition.VectorialEditableDBAdapter; |
95 | 562 | fernando | import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData; |
96 | import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial; |
||
97 | 5048 | ldiaz | import com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint; |
98 | 562 | fernando | import com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData; |
99 | import com.iver.cit.gvsig.fmap.layers.layerOperations.SingleLayer; |
||
100 | import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData; |
||
101 | 5057 | ldiaz | import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialXMLItem; |
102 | 5201 | ldiaz | import com.iver.cit.gvsig.fmap.layers.layerOperations.XMLItem; |
103 | 214 | fernando | import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor; |
104 | 231 | fernando | import com.iver.cit.gvsig.fmap.operations.strategies.Strategy; |
105 | import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager; |
||
106 | 13884 | jaume | import com.iver.cit.gvsig.fmap.rendering.IClassifiedVectorLegend; |
107 | 11558 | jaume | import com.iver.cit.gvsig.fmap.rendering.ILegend; |
108 | 13884 | jaume | import com.iver.cit.gvsig.fmap.rendering.IVectorLegend; |
109 | 214 | fernando | import com.iver.cit.gvsig.fmap.rendering.LegendFactory; |
110 | 3035 | fjp | import com.iver.cit.gvsig.fmap.rendering.SingleSymbolLegend; |
111 | 11807 | jaume | import com.iver.cit.gvsig.fmap.rendering.ZSort; |
112 | 18621 | jdominguez | import com.iver.cit.gvsig.fmap.rendering.styling.labeling.AttrInTableLabelingStrategy; |
113 | import com.iver.cit.gvsig.fmap.rendering.styling.labeling.ILabelingStrategy; |
||
114 | import com.iver.cit.gvsig.fmap.rendering.styling.labeling.LabelingFactory; |
||
115 | 4977 | azabala | import com.iver.cit.gvsig.fmap.spatialindex.IPersistentSpatialIndex; |
116 | import com.iver.cit.gvsig.fmap.spatialindex.ISpatialIndex; |
||
117 | 5414 | azabala | import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeGt2; |
118 | 4977 | azabala | import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeJts; |
119 | import com.iver.cit.gvsig.fmap.spatialindex.SpatialIndexException; |
||
120 | import com.iver.utiles.FileUtils; |
||
121 | 13913 | jaume | import com.iver.utiles.IPersistence; |
122 | 10679 | jaume | import com.iver.utiles.NotExistInXMLEntity; |
123 | 2672 | fjp | import com.iver.utiles.PostProcessSupport; |
124 | 415 | fernando | import com.iver.utiles.XMLEntity; |
125 | 5317 | fjp | import com.iver.utiles.swing.threads.Cancellable; |
126 | import com.iver.utiles.swing.threads.CancellableMonitorable; |
||
127 | 214 | fernando | |
128 | 562 | fernando | /**
|
129 | 1034 | vcaballero | * Capa b?sica Vectorial.
|
130 | 5184 | caballero | *
|
131 | 562 | fernando | * @author Fernando Gonz?lez Cort?s
|
132 | */
|
||
133 | 885 | fjp | |
134 | 5152 | fjp | // TODO Cuando no sea para pruebas debe no ser public
|
135 | 10679 | jaume | public class FLyrVect extends FLyrDefault implements ILabelable, |
136 | 12349 | jaume | ClassifiableVectorial, SingleLayer, VectorialData, RandomVectorialData, |
137 | AlphanumericData, InfoByPoint { |
||
138 | private static Logger logger = Logger.getLogger(FLyrVect.class.getName()); |
||
139 | 16254 | vcaballero | /**
|
140 | * @deprecated Don?t use Strategy, you should be use iterators.
|
||
141 | */
|
||
142 | 12787 | jaume | public static boolean forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD = true; |
143 | 16254 | vcaballero | /**
|
144 | * @deprecated Don?t use Strategy, you should be use iterators.
|
||
145 | */
|
||
146 | private boolean useStrategy=false; |
||
147 | 14409 | vcaballero | |
148 | 12349 | jaume | /** Leyenda de la capa vectorial */
|
149 | 13884 | jaume | private IVectorLegend legend;
|
150 | 12349 | jaume | private int typeShape = -1; |
151 | private ReadableVectorial source;
|
||
152 | private SelectableDataSource sds;
|
||
153 | private SelectionSupport selectionSupport = new SelectionSupport(); |
||
154 | private SpatialCache spatialCache = new SpatialCache(); |
||
155 | private boolean spatialCacheEnabled = false; |
||
156 | 3940 | caballero | |
157 | 12349 | jaume | /**
|
158 | * An implementation of gvSIG spatial index
|
||
159 | */
|
||
160 | protected ISpatialIndex spatialIndex = null; |
||
161 | private boolean bHasJoin = false; |
||
162 | private XMLEntity orgXMLEntity = null; |
||
163 | private XMLEntity loadSelection = null; |
||
164 | 13884 | jaume | private IVectorLegend loadLegend = null; |
165 | 461 | fernando | |
166 | 13558 | evercher | //Lo a?ado. Caracter?sticas de HyperEnlace (LINK)
|
167 | private FLyrVectLinkProperties linkProperties=new FLyrVectLinkProperties(); |
||
168 | //private ArrayList linkProperties=null;
|
||
169 | |||
170 | 12349 | jaume | /**
|
171 | * Devuelve el VectorialAdapater de la capa.
|
||
172 | *
|
||
173 | * @return VectorialAdapter.
|
||
174 | */
|
||
175 | public ReadableVectorial getSource() {
|
||
176 | if (!this.isAvailable()) return null; |
||
177 | return source;
|
||
178 | } |
||
179 | 5115 | caballero | |
180 | 12349 | jaume | /**
|
181 | * If we use a persistent spatial index associated with this layer, and the
|
||
182 | * index is not intrisic to the layer (for example spatial databases) this
|
||
183 | * method looks for existent spatial index, and loads it.
|
||
184 | *
|
||
185 | */
|
||
186 | private void loadSpatialIndex() { |
||
187 | //FIXME: Al abrir el indice en fichero...
|
||
188 | //?C?mo lo liberamos? un metodo Layer.shutdown()
|
||
189 | 5484 | caballero | |
190 | |||
191 | 12349 | jaume | ReadableVectorial source = getSource(); |
192 | //REVISAR QUE PASA CON LOS DRIVERS DXF, DGN, etc.
|
||
193 | //PUES SON VECTORIALFILEADAPTER
|
||
194 | if (!(source instanceof VectorialFileAdapter)) { |
||
195 | // we are not interested in db adapters
|
||
196 | return;
|
||
197 | } |
||
198 | VectorialDriver driver = source.getDriver(); |
||
199 | if (!(driver instanceof BoundedShapes)) { |
||
200 | // we dont spatially index layers that are not bounded
|
||
201 | return;
|
||
202 | } |
||
203 | File file = ((VectorialFileAdapter) source).getFile();
|
||
204 | String fileName = file.getAbsolutePath();
|
||
205 | File sptFile = new File(fileName + ".qix"); |
||
206 | if (!sptFile.exists() || (!(sptFile.length() > 0))) { |
||
207 | // before to exit, look for it in temp path
|
||
208 | String tempPath = System.getProperty("java.io.tmpdir"); |
||
209 | fileName = tempPath + File.separator + sptFile.getName();
|
||
210 | sptFile = new File(fileName); |
||
211 | // it doesnt exists, must to create
|
||
212 | if (!sptFile.exists() || (!(sptFile.length() > 0))) { |
||
213 | return;
|
||
214 | }// if
|
||
215 | }// if
|
||
216 | 5484 | caballero | |
217 | 12349 | jaume | try {
|
218 | source.start(); |
||
219 | spatialIndex = new QuadtreeGt2(FileUtils.getFileWithoutExtension(sptFile),
|
||
220 | "NM", source.getFullExtent(), source.getShapeCount(), false); |
||
221 | source.setSpatialIndex(spatialIndex); |
||
222 | } catch (SpatialIndexException e) {
|
||
223 | spatialIndex = null;
|
||
224 | e.printStackTrace(); |
||
225 | return;
|
||
226 | } catch (ReadDriverException e) {
|
||
227 | spatialIndex = null;
|
||
228 | e.printStackTrace(); |
||
229 | return;
|
||
230 | } |
||
231 | 5484 | caballero | |
232 | 12349 | jaume | } |
233 | 5115 | caballero | |
234 | 12349 | jaume | /**
|
235 | * Checks if it has associated an external spatial index
|
||
236 | * (an spatial index file).
|
||
237 | *
|
||
238 | * It looks for it in main file path, or in temp system path.
|
||
239 | * If main file is rivers.shp, it looks for a file called
|
||
240 | * rivers.shp.qix.
|
||
241 | 5484 | caballero | |
242 | 12349 | jaume | * @return
|
243 | */
|
||
244 | public boolean isExternallySpatiallyIndexed() { |
||
245 | /*
|
||
246 | * FIXME (AZABALA): Independizar del tipo de fichero de ?ndice
|
||
247 | * con el que se trabaje (ahora mismo considera la extension .qix,
|
||
248 | * pero esto depender? del tipo de ?ndice)
|
||
249 | * */
|
||
250 | ReadableVectorial source = getSource(); |
||
251 | if (!(source instanceof VectorialFileAdapter)) { |
||
252 | // we are not interested in db adapters.
|
||
253 | // think in non spatial dbs, like HSQLDB
|
||
254 | return false; |
||
255 | } |
||
256 | File file = ((VectorialFileAdapter) source).getFile();
|
||
257 | String fileName = file.getAbsolutePath();
|
||
258 | File sptFile = new File(fileName + ".qix"); |
||
259 | if (!sptFile.exists() || (!(sptFile.length() > 0))) { |
||
260 | // before to exit, look for it in temp path
|
||
261 | // it doesnt exists, must to create
|
||
262 | String tempPath = System.getProperty("java.io.tmpdir"); |
||
263 | fileName = tempPath + File.separator + sptFile.getName();
|
||
264 | sptFile = new File(fileName); |
||
265 | if (!sptFile.exists() || (!(sptFile.length() > 0))) { |
||
266 | return false; |
||
267 | }// if
|
||
268 | }// if
|
||
269 | return true; |
||
270 | } |
||
271 | 472 | fernando | |
272 | 12349 | jaume | /**
|
273 | * Inserta el VectorialAdapter a la capa.
|
||
274 | *
|
||
275 | * @param va
|
||
276 | * VectorialAdapter.
|
||
277 | */
|
||
278 | public void setSource(ReadableVectorial rv) { |
||
279 | source = rv; |
||
280 | // azabala: we check if this layer could have a file spatial index
|
||
281 | // and load it if it exists
|
||
282 | 16542 | vcaballero | loadSpatialIndex(); |
283 | 12349 | jaume | } |
284 | 214 | fernando | |
285 | 12349 | jaume | public Rectangle2D getFullExtent() throws ReadDriverException, ExpansionFileReadException { |
286 | Rectangle2D rAux;
|
||
287 | source.start(); |
||
288 | rAux = (Rectangle2D)source.getFullExtent().clone();
|
||
289 | source.stop(); |
||
290 | 885 | fjp | |
291 | 12349 | jaume | // Si existe reproyecci?n, reproyectar el extent
|
292 | ICoordTrans ct = getCoordTrans(); |
||
293 | 885 | fjp | |
294 | 12349 | jaume | if (ct != null) { |
295 | Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY()); |
||
296 | Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY()); |
||
297 | pt1 = ct.convert(pt1, null);
|
||
298 | pt2 = ct.convert(pt2, null);
|
||
299 | rAux = new Rectangle2D.Double(); |
||
300 | rAux.setFrameFromDiagonal(pt1, pt2); |
||
301 | } |
||
302 | 885 | fjp | |
303 | 12349 | jaume | //Esto es para cuando se crea una capa nueva con el fullExtent de ancho y alto 0.
|
304 | if (rAux.getWidth()==0 && rAux.getHeight()==0) { |
||
305 | rAux=new Rectangle2D.Double(0,0,100,100); |
||
306 | } |
||
307 | 6476 | caballero | |
308 | 12349 | jaume | return rAux;
|
309 | } |
||
310 | 214 | fernando | |
311 | 12466 | jaume | /**
|
312 | * Draws using IFeatureIterator. This method will replace the old draw(...) one.
|
||
313 | * @autor jaume dominguez faus - jaume.dominguez@iver.es
|
||
314 | * @param image
|
||
315 | * @param g
|
||
316 | * @param viewPort
|
||
317 | * @param cancel
|
||
318 | * @param scale
|
||
319 | * @throws ReadDriverException
|
||
320 | */
|
||
321 | 18621 | jdominguez | private void _draw(BufferedImage image, Graphics2D g, ViewPort viewPort, |
322 | 12349 | jaume | Cancellable cancel, double scale) throws ReadDriverException { |
323 | 14369 | jdominguez | boolean bDrawShapes = true; |
324 | if (legend instanceof SingleSymbolLegend) { |
||
325 | bDrawShapes = legend.getDefaultSymbol().isShapeVisible(); |
||
326 | } |
||
327 | 14452 | vcaballero | Point2D offset = viewPort.getOffset();
|
328 | 14369 | jdominguez | double dpi = MapContext.getScreenDPI();
|
329 | 12657 | jaume | |
330 | 15601 | vcaballero | |
331 | |||
332 | 14369 | jdominguez | if (bDrawShapes) {
|
333 | 15601 | vcaballero | boolean cacheFeatures = isSpatialCacheEnabled();
|
334 | SpatialCache cache = null;
|
||
335 | if (cacheFeatures) {
|
||
336 | getSpatialCache().clearAll(); |
||
337 | cache = getSpatialCache(); |
||
338 | } |
||
339 | 11704 | jaume | |
340 | 14369 | jdominguez | try {
|
341 | ArrayList<String> fieldList = new ArrayList<String>(); |
||
342 | 11704 | jaume | |
343 | 14369 | jdominguez | // fields from legend
|
344 | String[] aux = null; |
||
345 | 13445 | caballero | |
346 | 14369 | jdominguez | if (legend instanceof IClassifiedVectorLegend) { |
347 | aux = ((IClassifiedVectorLegend) legend).getClassifyingFieldNames(); |
||
348 | for (int i = 0; i < aux.length; i++) { |
||
349 | fieldList.add(aux[i]); |
||
350 | 13884 | jaume | } |
351 | 14369 | jdominguez | } |
352 | |||
353 | 18621 | jdominguez | // Get the iterator over the visible features
|
354 | IFeatureIterator it = getSource().getFeatureIterator( |
||
355 | viewPort.getAdjustedExtent(), |
||
356 | fieldList.toArray(new String[fieldList.size()]), |
||
357 | viewPort.getProjection(), |
||
358 | true);
|
||
359 | |||
360 | 14369 | jdominguez | ZSort zSort = ((IVectorLegend) getLegend()).getZSort(); |
361 | 18621 | jdominguez | |
362 | boolean bSymbolLevelError = false; |
||
363 | |||
364 | 14369 | jdominguez | // if layer has map levels it will use a ZSort
|
365 | boolean useZSort = zSort != null && zSort.isUsingZSort(); |
||
366 | 12075 | jaume | |
367 | 14369 | jdominguez | // -- visual FX stuff
|
368 | long time = System.currentTimeMillis(); |
||
369 | BufferedImage virtualBim;
|
||
370 | Graphics2D virtualGraphics;
|
||
371 | 11853 | jaume | |
372 | 14369 | jdominguez | // render temporary map each screenRefreshRate milliseconds;
|
373 | int screenRefreshDelay = (int) ((1D/MapControl.getDrawFrameRate())*3*1000); |
||
374 | BufferedImage[] imageLevels = null; |
||
375 | Graphics2D[] graphics = null; |
||
376 | if (useZSort) {
|
||
377 | imageLevels = new BufferedImage[zSort.getLevelCount()]; |
||
378 | graphics = new Graphics2D[imageLevels.length]; |
||
379 | for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) { |
||
380 | imageLevels[i] = new BufferedImage(image.getWidth(), image.getHeight(), image.getType()); |
||
381 | graphics[i] = imageLevels[i].createGraphics(); |
||
382 | 14409 | vcaballero | graphics[i].setTransform(g.getTransform()); |
383 | 20704 | vcaballero | graphics[i].setRenderingHints(g.getRenderingHints()); |
384 | 14369 | jdominguez | } |
385 | } |
||
386 | // -- end visual FX stuff
|
||
387 | 12466 | jaume | |
388 | 18621 | jdominguez | |
389 | 14369 | jdominguez | // Iteration over each feature
|
390 | while ( !cancel.isCanceled() && it.hasNext()) {
|
||
391 | IFeature feat = it.next(); |
||
392 | IGeometry geom = feat.getGeometry(); |
||
393 | 11853 | jaume | |
394 | 15601 | vcaballero | if (cacheFeatures) {
|
395 | if (cache.getMaxFeatures() >= cache.size()) {
|
||
396 | // already reprojected
|
||
397 | cache.insert(geom.getBounds2D(), geom); |
||
398 | } |
||
399 | } |
||
400 | |||
401 | 14369 | jdominguez | // retrieve the symbol associated to such feature
|
402 | ISymbol sym = legend.getSymbolByFeature(feat); |
||
403 | |||
404 | 18621 | jdominguez | if (sym == null) continue; |
405 | |||
406 | 14573 | vcaballero | //C?digo para poder acceder a los ?ndices para ver si est? seleccionado un Feature
|
407 | ReadableVectorial rv=getSource(); |
||
408 | int selectionIndex=-1; |
||
409 | if (rv instanceof ISpatialDB){ |
||
410 | 22465 | vcaballero | selectionIndex = ((ISpatialDB)rv).getRowIndexByFID(feat); |
411 | 14573 | vcaballero | }else{
|
412 | 22465 | vcaballero | selectionIndex = Integer.parseInt(feat.getID());
|
413 | 14369 | jdominguez | } |
414 | 14573 | vcaballero | if (selectionIndex!=-1) { |
415 | if (selectionSupport.isSelected(selectionIndex)) {
|
||
416 | sym = sym.getSymbolForSelection(); |
||
417 | } |
||
418 | } |
||
419 | 14369 | jdominguez | |
420 | // Check if this symbol is sized with CartographicSupport
|
||
421 | CartographicSupport csSym = null;
|
||
422 | int symbolType = sym.getSymbolType();
|
||
423 | boolean bDrawCartographicSupport = false; |
||
424 | |||
425 | if ( symbolType == FShape.POINT
|
||
426 | 12466 | jaume | || symbolType == FShape.LINE |
427 | || sym instanceof CartographicSupport) {
|
||
428 | 11807 | jaume | |
429 | 18621 | jdominguez | // patch
|
430 | 14481 | vcaballero | if (!sym.getClass().equals(FSymbol.class)) {
|
431 | csSym = (CartographicSupport) sym; |
||
432 | bDrawCartographicSupport = (csSym.getUnit() != -1);
|
||
433 | } |
||
434 | 14369 | jdominguez | } |
435 | 11853 | jaume | |
436 | 14369 | jdominguez | int x = -1; |
437 | int y = -1; |
||
438 | int[] xyCoords = new int[2]; |
||
439 | 11853 | jaume | |
440 | 14369 | jdominguez | // Check if size is a pixel
|
441 | boolean onePoint = bDrawCartographicSupport ?
|
||
442 | 14409 | vcaballero | isOnePoint(g.getTransform(), viewPort, MapContext.getScreenDPI(), csSym, geom, xyCoords) : |
443 | isOnePoint(g.getTransform(), viewPort, geom, xyCoords); |
||
444 | 12466 | jaume | |
445 | 14409 | vcaballero | // Avoid out of bounds exceptions
|
446 | if (onePoint) {
|
||
447 | x = xyCoords[0];
|
||
448 | y = xyCoords[1];
|
||
449 | if (x<0 || y<0 || x>= viewPort.getImageWidth() || y>=viewPort.getImageHeight()) continue; |
||
450 | } |
||
451 | 13445 | caballero | |
452 | 14409 | vcaballero | if (useZSort) {
|
453 | // Check if this symbol is a multilayer
|
||
454 | if (sym instanceof IMultiLayerSymbol) { |
||
455 | // if so, treat each of its layers as a single symbol
|
||
456 | // in its corresponding map level
|
||
457 | IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym; |
||
458 | 20704 | vcaballero | for (int i = 0; !cancel.isCanceled() && i < mlSym.getLayerCount(); i++) { |
459 | 14409 | vcaballero | ISymbol mySym = mlSym.getLayer(i); |
460 | 18621 | jdominguez | int symbolLevel = zSort.getSymbolLevel(mySym);
|
461 | |||
462 | if (symbolLevel == -1) { |
||
463 | 21535 | vcaballero | /* an error occured when managing symbol levels.
|
464 | 18621 | jdominguez | * some of the legend changed events regarding the
|
465 | * symbols did not finish satisfactory and the legend
|
||
466 | * is now inconsistent. For this drawing, it will finish
|
||
467 | * as it was at the bottom (level 0) but, when done, the
|
||
468 | * ZSort will be reset to avoid app crashes. This is
|
||
469 | * a bug that has to be fixed.
|
||
470 | */
|
||
471 | bSymbolLevelError = true;
|
||
472 | symbolLevel=0;
|
||
473 | } |
||
474 | |||
475 | 14409 | vcaballero | if (onePoint) {
|
476 | 18621 | jdominguez | if (x<0 || y<0 || x>= imageLevels[symbolLevel].getWidth() || y>=imageLevels[symbolLevel].getHeight()) continue; |
477 | imageLevels[symbolLevel].setRGB(x, y, mySym.getOnePointRgb()); |
||
478 | 14409 | vcaballero | } else {
|
479 | if (!bDrawCartographicSupport) {
|
||
480 | 18621 | jdominguez | geom.drawInts(graphics[symbolLevel], viewPort, mySym, cancel); |
481 | 14409 | vcaballero | } else {
|
482 | 18621 | jdominguez | geom.drawInts(graphics[symbolLevel], viewPort, dpi, (CartographicSupport) mySym, cancel); |
483 | 14409 | vcaballero | } |
484 | } |
||
485 | } |
||
486 | } else {
|
||
487 | // else, just draw the symbol in its level
|
||
488 | if (!bDrawCartographicSupport) {
|
||
489 | geom.drawInts(graphics[zSort.getSymbolLevel(sym)], viewPort, sym, cancel); |
||
490 | } else {
|
||
491 | 18621 | jdominguez | geom.drawInts(graphics[zSort.getSymbolLevel(sym)], viewPort, dpi, (CartographicSupport) csSym, cancel); |
492 | 14409 | vcaballero | } |
493 | } |
||
494 | 214 | fernando | |
495 | 14409 | vcaballero | // -- visual FX stuff
|
496 | 14452 | vcaballero | // Cuando el offset!=0 se est? dibujando sobre el Layout y por tanto no tiene que ejecutar el siguiente c?digo.
|
497 | if (offset.getX()==0 && offset.getY()==0) |
||
498 | if ((System.currentTimeMillis() - time) > screenRefreshDelay) { |
||
499 | virtualBim = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_ARGB); |
||
500 | virtualGraphics = virtualBim.createGraphics(); |
||
501 | virtualGraphics.drawImage(image,0,0, null); |
||
502 | 20704 | vcaballero | for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) { |
503 | 14452 | vcaballero | virtualGraphics.drawImage(imageLevels[i],0,0, null); |
504 | } |
||
505 | g.clearRect(0, 0, image.getWidth(), image.getHeight()); |
||
506 | g.drawImage(virtualBim, 0, 0, null); |
||
507 | time = System.currentTimeMillis();
|
||
508 | } |
||
509 | 14409 | vcaballero | // -- end visual FX stuff
|
510 | 6246 | caballero | |
511 | 14409 | vcaballero | } else {
|
512 | // no ZSort, so there is only a map level, symbols are
|
||
513 | // just drawn.
|
||
514 | if (onePoint) {
|
||
515 | if (x<0 || y<0 || x>= image.getWidth() || y>=image.getHeight()) continue; |
||
516 | image.setRGB(x, y, sym.getOnePointRgb()); |
||
517 | } else {
|
||
518 | if (!bDrawCartographicSupport) {
|
||
519 | geom.drawInts(g, viewPort, sym, cancel); |
||
520 | } else {
|
||
521 | 18621 | jdominguez | geom.drawInts(g, viewPort, dpi, csSym, cancel); |
522 | 14409 | vcaballero | } |
523 | } |
||
524 | } |
||
525 | 14369 | jdominguez | } |
526 | 650 | vcaballero | |
527 | 14369 | jdominguez | if (useZSort) {
|
528 | g.drawImage(image, 0, 0, null); |
||
529 | 14409 | vcaballero | g.translate(offset.getX(), offset.getY()); |
530 | 20704 | vcaballero | for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) { |
531 | 14369 | jdominguez | g.drawImage(imageLevels[i],0,0, null); |
532 | imageLevels[i] = null;
|
||
533 | graphics[i] = null;
|
||
534 | 12349 | jaume | } |
535 | 14409 | vcaballero | g.translate(-offset.getX(), -offset.getY()); |
536 | 14369 | jdominguez | imageLevels = null;
|
537 | graphics = null;
|
||
538 | } |
||
539 | it.closeIterator(); |
||
540 | 18621 | jdominguez | |
541 | if (bSymbolLevelError) {
|
||
542 | ((IVectorLegend) getLegend()).setZSort(null);
|
||
543 | } |
||
544 | |||
545 | 14369 | jdominguez | } catch (ReadDriverException e) {
|
546 | this.setVisible(false); |
||
547 | this.setActive(false); |
||
548 | throw e;
|
||
549 | 14409 | vcaballero | } |
550 | 18621 | jdominguez | |
551 | |||
552 | 14369 | jdominguez | } |
553 | 12349 | jaume | } |
554 | 11807 | jaume | |
555 | 14409 | vcaballero | public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, |
556 | 12349 | jaume | Cancellable cancel, double scale) throws ReadDriverException { |
557 | 16254 | vcaballero | // forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD = true;
|
558 | if (!isUseStrategy()) {
|
||
559 | 12349 | jaume | _draw(image, g, viewPort, cancel, scale); |
560 | } else {
|
||
561 | 12657 | jaume | // moved up to FLayers
|
562 | // if (isWithinScale(scale)) {
|
||
563 | 5484 | caballero | |
564 | |||
565 | 12349 | jaume | // Las que solo tienen etiquetado sin pintar el shape,
|
566 | // no pasamos por ellas
|
||
567 | boolean bDrawShapes = true; |
||
568 | if (legend instanceof SingleSymbolLegend) { |
||
569 | if (legend.getDefaultSymbol().isShapeVisible() == false) |
||
570 | bDrawShapes = false;
|
||
571 | } |
||
572 | if (bDrawShapes) {
|
||
573 | Strategy strategy = StrategyManager.getStrategy(this);
|
||
574 | try {
|
||
575 | prepareDrawing(image, g, viewPort); |
||
576 | strategy.draw(image, g, viewPort, cancel); |
||
577 | } catch (ReadDriverException e) {
|
||
578 | this.setVisible(false); |
||
579 | this.setActive(false); |
||
580 | throw e;
|
||
581 | } |
||
582 | } |
||
583 | if (getVirtualLayers() != null) { |
||
584 | getVirtualLayers().draw(image, g, viewPort, cancel, scale); |
||
585 | } |
||
586 | 12657 | jaume | // }
|
587 | 12349 | jaume | } |
588 | } |
||
589 | 5484 | caballero | |
590 | 12349 | jaume | /**
|
591 | * Se llama antes de empezar a pintar.
|
||
592 | * Es ?til para preparar la cache a emplear, las leyendas, etc.
|
||
593 | * @param image
|
||
594 | * @param g
|
||
595 | * @param viewPort
|
||
596 | */
|
||
597 | private void prepareDrawing(BufferedImage image, Graphics2D g, ViewPort viewPort) { |
||
598 | |||
599 | } |
||
600 | |||
601 | public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel, |
||
602 | 12657 | jaume | double scale, PrintRequestAttributeSet properties) throws ReadDriverException { |
603 | // TEST METHOD
|
||
604 | |||
605 | 18621 | jdominguez | |
606 | /* SVN */
|
||
607 | |||
608 | /* boolean bDrawShapes = true;
|
||
609 | 12657 | jaume | if (legend instanceof SingleSymbolLegend) {
|
610 | bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
|
||
611 | }
|
||
612 | |||
613 | |||
614 | if (bDrawShapes) {
|
||
615 | double dpi = 72;
|
||
616 | |||
617 | PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
|
||
618 | if (resolution.equals(PrintQuality.NORMAL)){
|
||
619 | dpi = 300;
|
||
620 | } else if (resolution.equals(PrintQuality.HIGH)){
|
||
621 | dpi = 600;
|
||
622 | } else if (resolution.equals(PrintQuality.DRAFT)){
|
||
623 | dpi = 72;
|
||
624 | }
|
||
625 | |||
626 | |||
627 | try {
|
||
628 | prepareDrawing(null, g, viewPort);
|
||
629 | 13884 | jaume | ArrayList<String> fieldList = new ArrayList<String>();
|
630 | String[] aux;
|
||
631 | 14409 | vcaballero | |
632 | 12657 | jaume | // fields from legend
|
633 | 13884 | jaume | if (legend instanceof IClassifiedVectorLegend) {
|
634 | aux = ((IClassifiedVectorLegend) legend).
|
||
635 | getClassifyingFieldNames();
|
||
636 | for (int i = 0; i < aux.length; i++) {
|
||
637 | fieldList.add(aux[i]);
|
||
638 | }
|
||
639 | 12657 | jaume | }
|
640 | |||
641 | // fields from labeling
|
||
642 | if (isLabeled()) {
|
||
643 | aux = getLabelingStrategy().getUsedFields();
|
||
644 | for (int i = 0; i < aux.length; i++) {
|
||
645 | fieldList.add(aux[i]);
|
||
646 | }
|
||
647 | }
|
||
648 | |||
649 | 13884 | jaume | ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
|
650 | 12657 | jaume | |
651 | // if layer has map levels it will use a ZSort
|
||
652 | boolean useZSort = zSort != null && zSort.isUsingZSort();
|
||
653 | |||
654 | |||
655 | int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1;
|
||
656 | for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) {
|
||
657 | // Get the iterator over the visible features
|
||
658 | IFeatureIterator it = getSource().getFeatureIterator(
|
||
659 | viewPort.getAdjustedExtent(),
|
||
660 | 13884 | jaume | fieldList.toArray(new String[fieldList.size()]),
|
661 | 12657 | jaume | viewPort.getProjection(),
|
662 | true);
|
||
663 | |||
664 | // Iteration over each feature
|
||
665 | while ( !cancel.isCanceled() && it.hasNext()) {
|
||
666 | IFeature feat = it.next();
|
||
667 | IGeometry geom = feat.getGeometry();
|
||
668 | |||
669 | // retreive the symbol associated to such feature
|
||
670 | ISymbol sym = legend.getSymbolByFeature(feat);
|
||
671 | 14409 | vcaballero | |
672 | 14369 | jdominguez | if (useZSort) {
|
673 | // Check if this symbol is a multilayer
|
||
674 | if (sym instanceof IMultiLayerSymbol) {
|
||
675 | // if so, get the layer corresponding to the current
|
||
676 | // level. If none, continue to next iteration
|
||
677 | IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
|
||
678 | for (int i = 0; i < mlSym.getLayerCount(); i++) {
|
||
679 | ISymbol mySym = mlSym.getLayer(i);
|
||
680 | if (zSort.getSymbolLevel(mySym) == mapPass) {
|
||
681 | sym = mySym;
|
||
682 | break;
|
||
683 | }
|
||
684 | System.out.println("avoided layer "+i+"of symbol '"+mlSym.getDescription()+"' (pass "+mapPass+")");
|
||
685 | }
|
||
686 | 14409 | vcaballero | |
687 | 14369 | jdominguez | if (sym == null) {
|
688 | continue;
|
||
689 | }
|
||
690 | } else {
|
||
691 | // else, just draw the symbol in its level
|
||
692 | if (zSort.getSymbolLevel(sym) != mapPass) {
|
||
693 | System.out.println("avoided single layer symbol '"+sym.getDescription()+"' (pass "+mapPass+")");
|
||
694 | continue;
|
||
695 | }
|
||
696 | }
|
||
697 | }
|
||
698 | 12657 | jaume | |
699 | // Check if this symbol is sized with CartographicSupport
|
||
700 | CartographicSupport csSym = null;
|
||
701 | int symbolType = sym.getSymbolType();
|
||
702 | boolean bDrawCartographicSupport = false;
|
||
703 | |||
704 | if ( symbolType == FShape.POINT
|
||
705 | || symbolType == FShape.LINE
|
||
706 | || sym instanceof CartographicSupport) {
|
||
707 | |||
708 | csSym = (CartographicSupport) sym;
|
||
709 | bDrawCartographicSupport = (csSym.getUnit() != -1);
|
||
710 | }
|
||
711 | 14409 | vcaballero | |
712 | 14369 | jdominguez | System.err.println("passada "+mapPass+" pinte s?mboll "+sym.getDescription());
|
713 | 12657 | jaume | |
714 | if (!bDrawCartographicSupport) {
|
||
715 | 13952 | jaume | geom.drawInts(g, viewPort, sym, null);
|
716 | 12657 | jaume | } else {
|
717 | geom.drawInts(g, viewPort, dpi, (CartographicSupport) csSym);
|
||
718 | }
|
||
719 | |||
720 | }
|
||
721 | it.closeIterator();
|
||
722 | }
|
||
723 | } catch (ReadDriverException e) {
|
||
724 | this.setVisible(false);
|
||
725 | this.setActive(false);
|
||
726 | throw e;
|
||
727 | 14409 | vcaballero | }
|
728 | 18621 | jdominguez | */
|
729 | |||
730 | |||
731 | // TEST METHOD
|
||
732 | boolean bDrawShapes = true; |
||
733 | if (legend instanceof SingleSymbolLegend) { |
||
734 | bDrawShapes = legend.getDefaultSymbol().isShapeVisible(); |
||
735 | 12657 | jaume | } |
736 | 18621 | jdominguez | |
737 | |||
738 | if (bDrawShapes) {
|
||
739 | |||
740 | try {
|
||
741 | double dpi = 72; |
||
742 | |||
743 | PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class); |
||
744 | if (resolution.equals(PrintQuality.NORMAL)){ |
||
745 | dpi = 300;
|
||
746 | } else if (resolution.equals(PrintQuality.HIGH)){ |
||
747 | dpi = 600;
|
||
748 | } else if (resolution.equals(PrintQuality.DRAFT)){ |
||
749 | dpi = 72;
|
||
750 | } |
||
751 | ArrayList<String> fieldList = new ArrayList<String>(); |
||
752 | String[] aux; |
||
753 | |||
754 | // fields from legend
|
||
755 | if (legend instanceof IClassifiedVectorLegend) { |
||
756 | aux = ((IClassifiedVectorLegend) legend). |
||
757 | getClassifyingFieldNames(); |
||
758 | for (int i = 0; i < aux.length; i++) { |
||
759 | fieldList.add(aux[i]); |
||
760 | } |
||
761 | } |
||
762 | //
|
||
763 | // // fields from labeling
|
||
764 | // if (isLabeled()) {
|
||
765 | // aux = getLabelingStrategy().getUsedFields();
|
||
766 | // for (int i = 0; i < aux.length; i++) {
|
||
767 | // fieldList.add(aux[i]);
|
||
768 | // }
|
||
769 | // }
|
||
770 | |||
771 | ZSort zSort = ((IVectorLegend) getLegend()).getZSort(); |
||
772 | |||
773 | // if layer has map levels it will use a ZSort
|
||
774 | boolean useZSort = zSort != null && zSort.isUsingZSort(); |
||
775 | |||
776 | |||
777 | int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1; |
||
778 | for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) { |
||
779 | // Get the iterator over the visible features
|
||
780 | IFeatureIterator it = getSource().getFeatureIterator( |
||
781 | viewPort.getAdjustedExtent(), |
||
782 | fieldList.toArray(new String[fieldList.size()]), |
||
783 | viewPort.getProjection(), |
||
784 | true);
|
||
785 | |||
786 | // Iteration over each feature
|
||
787 | while ( !cancel.isCanceled() && it.hasNext()) {
|
||
788 | IFeature feat = it.next(); |
||
789 | IGeometry geom = feat.getGeometry(); |
||
790 | |||
791 | // retreive the symbol associated to such feature
|
||
792 | ISymbol sym = legend.getSymbolByFeature(feat); |
||
793 | |||
794 | if (useZSort) {
|
||
795 | // Check if this symbol is a multilayer
|
||
796 | if (sym instanceof IMultiLayerSymbol) { |
||
797 | // if so, get the layer corresponding to the current
|
||
798 | // level. If none, continue to next iteration
|
||
799 | IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym; |
||
800 | for (int i = 0; i < mlSym.getLayerCount(); i++) { |
||
801 | ISymbol mySym = mlSym.getLayer(i); |
||
802 | if (zSort.getSymbolLevel(mySym) == mapPass) {
|
||
803 | sym = mySym; |
||
804 | break;
|
||
805 | } |
||
806 | System.out.println("avoided layer "+i+"of symbol '"+mlSym.getDescription()+"' (pass "+mapPass+")"); |
||
807 | } |
||
808 | |||
809 | if (sym == null) { |
||
810 | continue;
|
||
811 | } |
||
812 | } else {
|
||
813 | // else, just draw the symbol in its level
|
||
814 | if (zSort.getSymbolLevel(sym) != mapPass) {
|
||
815 | System.out.println("avoided single layer symbol '"+sym.getDescription()+"' (pass "+mapPass+")"); |
||
816 | continue;
|
||
817 | } |
||
818 | } |
||
819 | } |
||
820 | |||
821 | // Check if this symbol is sized with CartographicSupport
|
||
822 | CartographicSupport csSym = null;
|
||
823 | int symbolType = sym.getSymbolType();
|
||
824 | boolean bDrawCartographicSupport = false; |
||
825 | |||
826 | if ( symbolType == FShape.POINT
|
||
827 | || symbolType == FShape.LINE |
||
828 | || sym instanceof CartographicSupport) {
|
||
829 | |||
830 | csSym = (CartographicSupport) sym; |
||
831 | bDrawCartographicSupport = (csSym.getUnit() != -1);
|
||
832 | } |
||
833 | |||
834 | System.err.println("passada "+mapPass+" pinte s?mboll "+sym.getDescription()); |
||
835 | |||
836 | if (!bDrawCartographicSupport) {
|
||
837 | geom.drawInts(g, viewPort, sym, null);
|
||
838 | } else {
|
||
839 | geom.drawInts(g, viewPort, dpi, (CartographicSupport) csSym, cancel); |
||
840 | } |
||
841 | |||
842 | } |
||
843 | it.closeIterator(); |
||
844 | } |
||
845 | } catch (ReadDriverException e) {
|
||
846 | this.setVisible(false); |
||
847 | this.setActive(false); |
||
848 | throw e;
|
||
849 | } |
||
850 | } |
||
851 | 12349 | jaume | } |
852 | |||
853 | 12657 | jaume | |
854 | 12349 | jaume | public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, |
855 | double scale, PrintRequestAttributeSet properties) throws ReadDriverException { |
||
856 | 12787 | jaume | if (forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD) {
|
857 | 12657 | jaume | _print(g, viewPort, cancel, scale, properties); |
858 | } else {
|
||
859 | // moved up to Flayers
|
||
860 | // if (isVisible() && isWithinScale(scale)) {
|
||
861 | Strategy strategy = StrategyManager.getStrategy(this);
|
||
862 | 12349 | jaume | |
863 | 12657 | jaume | strategy.print(g, viewPort, cancel, properties); |
864 | ILabelingStrategy labeling; |
||
865 | if ( (labeling = getLabelingStrategy() ) != null) { |
||
866 | // contains labels
|
||
867 | labeling.print(g, viewPort, cancel, properties); |
||
868 | } |
||
869 | // }
|
||
870 | } |
||
871 | 12349 | jaume | } |
872 | |||
873 | public void deleteSpatialIndex() { |
||
874 | //must we delete possible spatial indexes files?
|
||
875 | spatialIndex = null;
|
||
876 | } |
||
877 | |||
878 | 5414 | azabala | /**
|
879 | * <p>
|
||
880 | * Creates an spatial index associated to this layer.
|
||
881 | * The spatial index will used
|
||
882 | * the native projection of the layer, so if the layer is reprojected, it will
|
||
883 | * be ignored.
|
||
884 | * </p>
|
||
885 | * @param cancelMonitor instance of CancellableMonitorable that allows
|
||
886 | * to monitor progress of spatial index creation, and cancel the process
|
||
887 | 5484 | caballero | */
|
888 | 5414 | azabala | public void createSpatialIndex(CancellableMonitorable cancelMonitor){ |
889 | 12349 | jaume | // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
|
890 | 5414 | azabala | // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
|
891 | // para que acepten recorrer sin geometria, solo con rectangulos.
|
||
892 | 5484 | caballero | |
893 | 12349 | jaume | //If this vectorial layer is based in a spatial database, the spatial
|
894 | //index is already implicit. We only will index file drivers
|
||
895 | ReadableVectorial va = getSource(); |
||
896 | //We must think in non spatial databases, like HSQLDB
|
||
897 | if(!(va instanceof VectorialFileAdapter)){ |
||
898 | return;
|
||
899 | } |
||
900 | if (!(va.getDriver() instanceof BoundedShapes)) { |
||
901 | return;
|
||
902 | } |
||
903 | File file = ((VectorialFileAdapter) va).getFile();
|
||
904 | String fileName = file.getAbsolutePath();
|
||
905 | ISpatialIndex localCopy = null;
|
||
906 | try {
|
||
907 | va.start(); |
||
908 | localCopy = new QuadtreeGt2(fileName, "NM", va.getFullExtent(), |
||
909 | va.getShapeCount(), true);
|
||
910 | 5484 | caballero | |
911 | 12349 | jaume | } catch (SpatialIndexException e1) {
|
912 | // Probably we dont have writing permissions
|
||
913 | String directoryName = System.getProperty("java.io.tmpdir"); |
||
914 | File newFile = new File(directoryName + |
||
915 | File.separator +
|
||
916 | file.getName()); |
||
917 | String newFileName = newFile.getName();
|
||
918 | try {
|
||
919 | localCopy = new QuadtreeGt2(newFileName, "NM", va.getFullExtent(), |
||
920 | va.getShapeCount(), true);
|
||
921 | } catch (SpatialIndexException e) {
|
||
922 | // if we cant build a file based spatial index, we'll build
|
||
923 | // a pure memory spatial index
|
||
924 | localCopy = new QuadtreeJts();
|
||
925 | } catch (ReadDriverException e) {
|
||
926 | localCopy = new QuadtreeJts();
|
||
927 | } |
||
928 | 5115 | caballero | |
929 | 12787 | jaume | } catch(Exception e){ |
930 | 12349 | jaume | e.printStackTrace(); |
931 | }//try
|
||
932 | 5414 | azabala | BoundedShapes shapeBounds = (BoundedShapes) va.getDriver(); |
933 | try {
|
||
934 | for (int i=0; i < va.getShapeCount(); i++) |
||
935 | { |
||
936 | 12349 | jaume | if(cancelMonitor != null){ |
937 | if(cancelMonitor.isCanceled())
|
||
938 | return;
|
||
939 | cancelMonitor.reportStep(); |
||
940 | } |
||
941 | 5414 | azabala | Rectangle2D r = shapeBounds.getShapeBounds(i);
|
942 | 5916 | azabala | if(r != null) |
943 | 12349 | jaume | localCopy.insert(r, i); |
944 | 5414 | azabala | } // for
|
945 | va.stop(); |
||
946 | if(localCopy instanceof IPersistentSpatialIndex) |
||
947 | 12349 | jaume | ((IPersistentSpatialIndex) localCopy).flush(); |
948 | 5414 | azabala | spatialIndex = localCopy; |
949 | 11286 | azabala | //vectorial adapter needs a reference to the spatial index, to solve
|
950 | //request for feature iteration based in spatial queries
|
||
951 | source.setSpatialIndex(spatialIndex); |
||
952 | 10627 | caballero | } catch (ReadDriverException e) {
|
953 | 12349 | jaume | // TODO Auto-generated catch block
|
954 | e.printStackTrace(); |
||
955 | } |
||
956 | 5414 | azabala | } |
957 | 5484 | caballero | |
958 | 12349 | jaume | public void createSpatialIndex() { |
959 | createSpatialIndex(null);
|
||
960 | } |
||
961 | 214 | fernando | |
962 | 12349 | jaume | public void process(FeatureVisitor visitor, FBitSet subset) |
963 | throws ReadDriverException, ExpansionFileReadException, VisitorException {
|
||
964 | Strategy s = StrategyManager.getStrategy(this);
|
||
965 | s.process(visitor, subset); |
||
966 | } |
||
967 | 228 | fernando | |
968 | 12349 | jaume | public void process(FeatureVisitor visitor) throws ReadDriverException, VisitorException { |
969 | Strategy s = StrategyManager.getStrategy(this);
|
||
970 | s.process(visitor); |
||
971 | } |
||
972 | 4223 | caballero | |
973 | 12349 | jaume | public void process(FeatureVisitor visitor, Rectangle2D rect) |
974 | throws ReadDriverException, ExpansionFileReadException, VisitorException {
|
||
975 | Strategy s = StrategyManager.getStrategy(this);
|
||
976 | s.process(visitor, rect); |
||
977 | } |
||
978 | 562 | fernando | |
979 | 12349 | jaume | public FBitSet queryByRect(Rectangle2D rect) throws ReadDriverException, VisitorException { |
980 | Strategy s = StrategyManager.getStrategy(this);
|
||
981 | 562 | fernando | |
982 | 12349 | jaume | return s.queryByRect(rect);
|
983 | } |
||
984 | 214 | fernando | |
985 | 12349 | jaume | public FBitSet queryByPoint(Point2D p, double tolerance) |
986 | throws ReadDriverException, VisitorException {
|
||
987 | Strategy s = StrategyManager.getStrategy(this);
|
||
988 | return s.queryByPoint(p, tolerance);
|
||
989 | } |
||
990 | 3940 | caballero | |
991 | 12349 | jaume | public FBitSet queryByShape(IGeometry g, int relationship) |
992 | throws ReadDriverException, VisitorException {
|
||
993 | Strategy s = StrategyManager.getStrategy(this);
|
||
994 | return s.queryByShape(g, relationship);
|
||
995 | } |
||
996 | 5048 | ldiaz | |
997 | 12349 | jaume | public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws ReadDriverException, VisitorException { |
998 | Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p); |
||
999 | FBitSet bs = queryByPoint(pReal, tolerance); |
||
1000 | VectorialXMLItem[] item = new VectorialXMLItem[1]; |
||
1001 | item[0] = new VectorialXMLItem(bs, this); |
||
1002 | 5115 | caballero | |
1003 | 12349 | jaume | return item;
|
1004 | } |
||
1005 | 5152 | fjp | |
1006 | 13884 | jaume | public void setLegend(IVectorLegend r) throws LegendLayerException { |
1007 | IVectorLegend oldLegend = legend; |
||
1008 | 12349 | jaume | legend = r; |
1009 | try {
|
||
1010 | legend.setDataSource(getRecordset()); |
||
1011 | } catch (FieldNotFoundException e1) {
|
||
1012 | throw new LegendLayerException(getName(),e1); |
||
1013 | } catch (ReadDriverException e1) {
|
||
1014 | throw new LegendLayerException(getName(),e1); |
||
1015 | } |
||
1016 | LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent( |
||
1017 | oldLegend, legend); |
||
1018 | callLegendChanged(e); |
||
1019 | } |
||
1020 | 303 | fernando | |
1021 | 12349 | jaume | /**
|
1022 | * Devuelve la Leyenda de la capa.
|
||
1023 | *
|
||
1024 | * @return Leyenda.
|
||
1025 | */
|
||
1026 | public ILegend getLegend() {
|
||
1027 | return legend;
|
||
1028 | } |
||
1029 | 373 | fernando | |
1030 | 12349 | jaume | /**
|
1031 | * Devuelve el tipo de shape que contiene la capa.
|
||
1032 | *
|
||
1033 | * @return tipo de shape.
|
||
1034 | *
|
||
1035 | * @throws DriverException
|
||
1036 | */
|
||
1037 | public int getShapeType() throws ReadDriverException { |
||
1038 | if (typeShape == -1) { |
||
1039 | getSource().start(); |
||
1040 | typeShape = getSource().getShapeType(); |
||
1041 | getSource().stop(); |
||
1042 | } |
||
1043 | 562 | fernando | |
1044 | 12349 | jaume | return typeShape;
|
1045 | } |
||
1046 | 435 | vcaballero | |
1047 | 12349 | jaume | public XMLEntity getXMLEntity() throws XMLException { |
1048 | if (!this.isAvailable() && this.orgXMLEntity != null) { |
||
1049 | return this.orgXMLEntity; |
||
1050 | } |
||
1051 | XMLEntity xml = super.getXMLEntity();
|
||
1052 | if (getLegend()!=null) |
||
1053 | xml.addChild(getLegend().getXMLEntity()); |
||
1054 | try {
|
||
1055 | if (getRecordset()!=null) |
||
1056 | xml.addChild(getRecordset().getSelectionSupport().getXMLEntity()); |
||
1057 | } catch (ReadDriverException e1) {
|
||
1058 | e1.printStackTrace(); |
||
1059 | throw new XMLException(e1); |
||
1060 | } |
||
1061 | // Repongo el mismo ReadableVectorial m?s abajo para cuando se guarda el proyecto.
|
||
1062 | ReadableVectorial rv=getSource(); |
||
1063 | xml.putProperty("type", "vectorial"); |
||
1064 | if (source instanceof VectorialEditableAdapter) { |
||
1065 | setSource(((VectorialEditableAdapter) source).getOriginalAdapter()); |
||
1066 | } |
||
1067 | if (source instanceof VectorialFileAdapter) { |
||
1068 | xml.putProperty("type", "vectorial"); |
||
1069 | xml.putProperty("file", ((VectorialFileAdapter) source)
|
||
1070 | .getFile()); |
||
1071 | try {
|
||
1072 | xml.putProperty("recordset-name", source.getRecordset()
|
||
1073 | .getName()); |
||
1074 | } catch (ReadDriverException e) {
|
||
1075 | throw new XMLException(e); |
||
1076 | } catch (RuntimeException e) { |
||
1077 | e.printStackTrace(); |
||
1078 | } |
||
1079 | } else if (source instanceof VectorialDBAdapter) { |
||
1080 | xml.putProperty("type", "vectorial"); |
||
1081 | 3940 | caballero | |
1082 | 12349 | jaume | IVectorialDatabaseDriver dbDriver = (IVectorialDatabaseDriver) source |
1083 | .getDriver(); |
||
1084 | 3940 | caballero | |
1085 | 12349 | jaume | // Guardamos el nombre del driver para poder recuperarlo
|
1086 | // con el DriverManager de Fernando.
|
||
1087 | xml.putProperty("db", dbDriver.getName());
|
||
1088 | try {
|
||
1089 | xml.putProperty("recordset-name", source.getRecordset()
|
||
1090 | .getName()); |
||
1091 | } catch (ReadDriverException e) {
|
||
1092 | throw new XMLException(e); |
||
1093 | } catch (RuntimeException e) { |
||
1094 | e.printStackTrace(); |
||
1095 | } |
||
1096 | xml.addChild(dbDriver.getXMLEntity()); // Tercer child. Antes hemos
|
||
1097 | // metido la leyenda y el
|
||
1098 | // selection support
|
||
1099 | } else if (source instanceof VectorialAdapter) { |
||
1100 | // Se supone que hemos hecho algo gen?rico.
|
||
1101 | xml.putProperty("type", "vectorial"); |
||
1102 | 3940 | caballero | |
1103 | 12349 | jaume | VectorialDriver driver = source.getDriver(); |
1104 | 3940 | caballero | |
1105 | 12349 | jaume | // Guardamos el nombre del driver para poder recuperarlo
|
1106 | // con el DriverManager de Fernando.
|
||
1107 | xml.putProperty("other", driver.getName());
|
||
1108 | // try {
|
||
1109 | try {
|
||
1110 | xml.putProperty("recordset-name", source.getRecordset()
|
||
1111 | .getName()); |
||
1112 | } catch (ReadDriverException e) {
|
||
1113 | throw new XMLException(e); |
||
1114 | } catch (RuntimeException e) { |
||
1115 | e.printStackTrace(); |
||
1116 | } |
||
1117 | 13913 | jaume | if (driver instanceof IPersistence) { |
1118 | 12349 | jaume | // xml.putProperty("className", driver.getClass().getName());
|
1119 | 13913 | jaume | IPersistence persist = (IPersistence) driver; |
1120 | 12349 | jaume | xml.addChild(persist.getXMLEntity()); // Tercer child. Antes
|
1121 | // hemos metido la
|
||
1122 | // leyenda y el
|
||
1123 | // selection support
|
||
1124 | } |
||
1125 | } |
||
1126 | if (rv!=null) |
||
1127 | setSource(rv); |
||
1128 | xml.putProperty("driverName", source.getDriver().getName());
|
||
1129 | if (bHasJoin)
|
||
1130 | xml.putProperty("hasJoin", "true"); |
||
1131 | 3940 | caballero | |
1132 | 12349 | jaume | // properties from ILabelable
|
1133 | xml.putProperty("isLabeled", isLabeled);
|
||
1134 | if (strategy != null) { |
||
1135 | XMLEntity strategyXML = strategy.getXMLEntity(); |
||
1136 | strategyXML.putProperty("Strategy", strategy.getClassName());
|
||
1137 | xml.addChild(strategy.getXMLEntity()); |
||
1138 | } |
||
1139 | 13558 | evercher | xml.addChild(getLinkProperties().getXMLEntity()); |
1140 | 12349 | jaume | return xml;
|
1141 | } |
||
1142 | 435 | vcaballero | |
1143 | 12349 | jaume | /**
|
1144 | * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
|
||
1145 | */
|
||
1146 | public void setXMLEntity03(XMLEntity xml) throws XMLException { |
||
1147 | 3940 | caballero | |
1148 | 12349 | jaume | super.setXMLEntity(xml);
|
1149 | legend = LegendFactory.createFromXML03(xml.getChild(0));
|
||
1150 | 2183 | fernando | |
1151 | 12349 | jaume | try {
|
1152 | setLegend(legend); |
||
1153 | } catch (LegendLayerException e) {
|
||
1154 | throw new XMLException(e); |
||
1155 | } |
||
1156 | 2183 | fernando | |
1157 | 12349 | jaume | try {
|
1158 | getRecordset().getSelectionSupport() |
||
1159 | .setXMLEntity03(xml.getChild(1));
|
||
1160 | } catch (ReadDriverException e) {
|
||
1161 | e.printStackTrace(); |
||
1162 | } |
||
1163 | } |
||
1164 | 2183 | fernando | |
1165 | 12349 | jaume | /*
|
1166 | * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
|
||
1167 | */
|
||
1168 | public void setXMLEntity(XMLEntity xml) throws XMLException { |
||
1169 | try {
|
||
1170 | 18621 | jdominguez | super.setXMLEntity(xml);
|
1171 | XMLEntity legendXML = xml.getChild(0);
|
||
1172 | IVectorLegend leg = LegendFactory.createFromXML(legendXML); |
||
1173 | /* (jaume) begin patch;
|
||
1174 | * for backward compatibility purposes. Since gvSIG v1.1 labeling is
|
||
1175 | * no longer managed by the Legend but by the ILabelingStrategy. The
|
||
1176 | * following allows restoring older projects' labelings.
|
||
1177 | */
|
||
1178 | if (legendXML.contains("labelFieldName")) { |
||
1179 | String labelTextField = legendXML.getStringProperty("labelFieldName"); |
||
1180 | if (labelTextField != null) { |
||
1181 | AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
|
||
1182 | labeling.setLayer(this);
|
||
1183 | labeling.setTextField(legendXML.getStringProperty("labelFieldName"));
|
||
1184 | labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
|
||
1185 | labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
|
||
1186 | this.setLabelingStrategy(labeling);
|
||
1187 | this.setIsLabeled(true); |
||
1188 | } |
||
1189 | } |
||
1190 | /* end patch */
|
||
1191 | try {
|
||
1192 | getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
|
||
1193 | // JMVIVO: Esto sirve para algo????
|
||
1194 | 22465 | vcaballero | /*
|
1195 | * Jaume: si, para restaurar el selectable datasource cuando se
|
||
1196 | * clona la capa, cuando se carga de un proyecto. Si no esta ya
|
||
1197 | * no se puede ni hacer consultas sql, ni hacer selecciones,
|
||
1198 | * ni usar la mayor parte de las herramientas.
|
||
1199 | *
|
||
1200 | * Lo vuelvo a poner.
|
||
1201 | */
|
||
1202 | |||
1203 | 18621 | jdominguez | String recordsetName = xml.getStringProperty("recordset-name"); |
1204 | 6476 | caballero | |
1205 | 22465 | vcaballero | SelectableDataSource sds = new SelectableDataSource(LayerFactory
|
1206 | .getDataSourceFactory().createRandomDataSource( |
||
1207 | recordsetName, DataSourceFactory.AUTOMATIC_OPENING)); |
||
1208 | |||
1209 | 18621 | jdominguez | LayerFactory.getDataSourceFactory().changeDataSourceName( |
1210 | getSource().getRecordset().getName(), recordsetName); |
||
1211 | } catch (NoSuchTableException e1) {
|
||
1212 | this.setAvailable(false); |
||
1213 | throw new XMLException(e1); |
||
1214 | } catch (ReadDriverException e1) {
|
||
1215 | this.setAvailable(false); |
||
1216 | throw new XMLException(e1); |
||
1217 | } |
||
1218 | // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
|
||
1219 | // el final
|
||
1220 | // de la lectura del proyecto
|
||
1221 | if (xml.contains("hasJoin")) { |
||
1222 | setIsJoined(true);
|
||
1223 | PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1); |
||
1224 | } else {
|
||
1225 | try {
|
||
1226 | setLegend(leg); |
||
1227 | } catch (LegendLayerException e) {
|
||
1228 | throw new XMLException(e); |
||
1229 | } |
||
1230 | } |
||
1231 | 17117 | vcaballero | |
1232 | 18621 | jdominguez | // set properties for ILabelable
|
1233 | XMLEntity labelingXML = xml.firstChild("id", "LabelingStrategy"); |
||
1234 | if (labelingXML!= null) { |
||
1235 | isLabeled = true;
|
||
1236 | try {
|
||
1237 | this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this); |
||
1238 | } catch (NotExistInXMLEntity neXMLEX) {
|
||
1239 | // no strategy was set, just continue;
|
||
1240 | logger.warn("Reached what should be unreachable code");
|
||
1241 | } |
||
1242 | } else {
|
||
1243 | isLabeled = false;
|
||
1244 | } |
||
1245 | 10910 | jaume | |
1246 | 18621 | jdominguez | XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties"); |
1247 | if (xmlLinkProperties != null){ |
||
1248 | getLinkProperties().setXMLEntity(xmlLinkProperties); |
||
1249 | } |
||
1250 | 6476 | caballero | |
1251 | 18621 | jdominguez | } catch (XMLException e) {
|
1252 | this.setAvailable(false); |
||
1253 | this.orgXMLEntity = xml;
|
||
1254 | } catch (Exception e) { |
||
1255 | e.printStackTrace(); |
||
1256 | this.setAvailable(false); |
||
1257 | this.orgXMLEntity = xml;
|
||
1258 | 13558 | evercher | |
1259 | 18621 | jdominguez | } |
1260 | 10910 | jaume | |
1261 | 3940 | caballero | |
1262 | 12349 | jaume | } |
1263 | 562 | fernando | |
1264 | 12349 | jaume | public void setXMLEntityNew(XMLEntity xml) throws XMLException { |
1265 | try {
|
||
1266 | super.setXMLEntity(xml);
|
||
1267 | 6768 | jmvivo | |
1268 | 12349 | jaume | XMLEntity legendXML = xml.getChild(0);
|
1269 | 13884 | jaume | IVectorLegend leg = LegendFactory.createFromXML(legendXML); |
1270 | 12349 | jaume | /* (jaume) begin patch;
|
1271 | * for backward compatibility purposes. Since gvSIG v1.1 labeling is
|
||
1272 | * no longer managed by the Legend but by the ILabelingStrategy. The
|
||
1273 | * following allows restoring older projects' labelings.
|
||
1274 | */
|
||
1275 | if (legendXML.contains("labelFieldHeight")) { |
||
1276 | 18621 | jdominguez | AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
|
1277 | 12349 | jaume | labeling.setLayer(this);
|
1278 | labeling.setTextField(legendXML.getStringProperty("labelFieldHeight"));
|
||
1279 | labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
|
||
1280 | this.setLabelingStrategy(labeling);
|
||
1281 | this.setIsLabeled(true); |
||
1282 | } |
||
1283 | /* end patch */
|
||
1284 | try {
|
||
1285 | getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
|
||
1286 | 9010 | caballero | |
1287 | 12349 | jaume | this.setLoadSelection(xml.getChild(1)); |
1288 | } catch (ReadDriverException e1) {
|
||
1289 | this.setAvailable(false); |
||
1290 | throw new XMLException(e1); |
||
1291 | } |
||
1292 | // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
|
||
1293 | // el final
|
||
1294 | // de la lectura del proyecto
|
||
1295 | if (xml.contains("hasJoin")) { |
||
1296 | setIsJoined(true);
|
||
1297 | PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1); |
||
1298 | } else {
|
||
1299 | this.setLoadLegend(leg);
|
||
1300 | } |
||
1301 | 6768 | jmvivo | |
1302 | 12349 | jaume | } catch (XMLException e) {
|
1303 | this.setAvailable(false); |
||
1304 | this.orgXMLEntity = xml;
|
||
1305 | } catch (Exception e) { |
||
1306 | this.setAvailable(false); |
||
1307 | this.orgXMLEntity = xml;
|
||
1308 | } |
||
1309 | 6768 | jmvivo | |
1310 | |||
1311 | 12349 | jaume | } |
1312 | 9010 | caballero | |
1313 | 562 | fernando | |
1314 | 12349 | jaume | /**
|
1315 | * Sobreimplementaci?n del m?todo toString para que las bases de datos
|
||
1316 | * identifiquen la capa.
|
||
1317 | *
|
||
1318 | * @return DOCUMENT ME!
|
||
1319 | */
|
||
1320 | public String toString() { |
||
1321 | /*
|
||
1322 | * Se usa internamente para que la parte de datos identifique de forma
|
||
1323 | * un?voca las tablas
|
||
1324 | */
|
||
1325 | String ret = super.toString(); |
||
1326 | 911 | fernando | |
1327 | 12349 | jaume | return "layer" + ret.substring(ret.indexOf('@') + 1); |
1328 | } |
||
1329 | 2672 | fjp | |
1330 | 12349 | jaume | public boolean isJoined() { |
1331 | return bHasJoin;
|
||
1332 | } |
||
1333 | 5115 | caballero | |
1334 | 12349 | jaume | /**
|
1335 | * Returns if a layer is spatially indexed
|
||
1336 | *
|
||
1337 | * @return if this layer has the ability to proces spatial queries without
|
||
1338 | * secuential scans.
|
||
1339 | */
|
||
1340 | public boolean isSpatiallyIndexed() { |
||
1341 | ReadableVectorial source = getSource(); |
||
1342 | if (source instanceof ISpatialDB) |
||
1343 | return true; |
||
1344 | 6246 | caballero | |
1345 | 5794 | azabala | //FIXME azabala
|
1346 | /*
|
||
1347 | * Esto es muy dudoso, y puede cambiar.
|
||
1348 | * Estoy diciendo que las que no son fichero o no son
|
||
1349 | * BoundedShapes estan indexadas. Esto es mentira, pero
|
||
1350 | * as? quien pregunte no querr? generar el indice.
|
||
1351 | * Esta por ver si interesa generar el indice para capas
|
||
1352 | * HSQLDB, WFS, etc.
|
||
1353 | 6246 | caballero | */
|
1354 | 12349 | jaume | if(!(source instanceof VectorialFileAdapter)){ |
1355 | return true; |
||
1356 | } |
||
1357 | if (!(source.getDriver() instanceof BoundedShapes)) { |
||
1358 | return true; |
||
1359 | } |
||
1360 | 6246 | caballero | |
1361 | 12349 | jaume | if (getISpatialIndex() != null) |
1362 | return true; |
||
1363 | return false; |
||
1364 | } |
||
1365 | 2672 | fjp | |
1366 | 12349 | jaume | public void setIsJoined(boolean hasJoin) { |
1367 | bHasJoin = hasJoin; |
||
1368 | } |
||
1369 | 2978 | fjp | |
1370 | 12349 | jaume | /**
|
1371 | * @return Returns the spatialIndex.
|
||
1372 | */
|
||
1373 | public ISpatialIndex getISpatialIndex() {
|
||
1374 | return spatialIndex;
|
||
1375 | } |
||
1376 | /**
|
||
1377 | * Sets the spatial index. This could be useful if, for some
|
||
1378 | * reasons, you want to work with a distinct spatial index
|
||
1379 | * (for example, a spatial index which could makes nearest
|
||
1380 | * neighbour querys)
|
||
1381 | * @param spatialIndex
|
||
1382 | */
|
||
1383 | public void setISpatialIndex(ISpatialIndex spatialIndex){ |
||
1384 | this.spatialIndex = spatialIndex;
|
||
1385 | } |
||
1386 | 3366 | caballero | |
1387 | 12349 | jaume | public SelectableDataSource getRecordset() throws ReadDriverException { |
1388 | if (!this.isAvailable()) return null; |
||
1389 | if (sds == null) { |
||
1390 | 10910 | jaume | |
1391 | 12349 | jaume | SelectableDataSource ds = source.getRecordset(); |
1392 | 4455 | fjp | |
1393 | 12349 | jaume | if (ds == null) { |
1394 | return null; |
||
1395 | } |
||
1396 | 4455 | fjp | |
1397 | 12349 | jaume | sds = ds; |
1398 | sds.setSelectionSupport(selectionSupport); |
||
1399 | 4523 | caballero | |
1400 | 12349 | jaume | } |
1401 | return sds;
|
||
1402 | } |
||
1403 | 11704 | jaume | |
1404 | 12349 | jaume | public void setEditing(boolean b) throws StartEditionLayerException { |
1405 | super.setEditing(b);
|
||
1406 | try {
|
||
1407 | if (b) {
|
||
1408 | VectorialEditableAdapter vea = null;
|
||
1409 | // TODO: Qu? pasa si hay m?s tipos de adapters?
|
||
1410 | // FJP: Se podr?a pasar como argumento el
|
||
1411 | // VectorialEditableAdapter
|
||
1412 | // que se quiera usar para evitar meter c?digo aqu? de este
|
||
1413 | // estilo.
|
||
1414 | if (getSource() instanceof VectorialDBAdapter) { |
||
1415 | vea = new VectorialEditableDBAdapter();
|
||
1416 | } else if (this instanceof FLyrAnnotation) { |
||
1417 | vea = new AnnotationEditableAdapter(
|
||
1418 | (FLyrAnnotation) this);
|
||
1419 | } else {
|
||
1420 | vea = new VectorialEditableAdapter();
|
||
1421 | } |
||
1422 | vea.setOriginalVectorialAdapter(getSource()); |
||
1423 | 11286 | azabala | // azo: implementations of readablevectorial need
|
1424 | 12349 | jaume | //references of projection and spatial index
|
1425 | vea.setProjection(getProjection()); |
||
1426 | vea.setSpatialIndex(spatialIndex); |
||
1427 | 11704 | jaume | |
1428 | |||
1429 | 12349 | jaume | // /vea.setSpatialIndex(getSpatialIndex());
|
1430 | // /vea.setFullExtent(getFullExtent());
|
||
1431 | 12783 | caballero | vea.setCoordTrans(getCoordTrans()); |
1432 | 12349 | jaume | vea.startEdition(EditionEvent.GRAPHIC); |
1433 | setSource(vea); |
||
1434 | getRecordset().setSelectionSupport( |
||
1435 | vea.getOriginalAdapter().getRecordset() |
||
1436 | .getSelectionSupport()); |
||
1437 | 5152 | fjp | |
1438 | 12349 | jaume | } else {
|
1439 | VectorialEditableAdapter vea = (VectorialEditableAdapter) getSource(); |
||
1440 | setSource(vea.getOriginalAdapter()); |
||
1441 | } |
||
1442 | // Si tenemos una leyenda, hay que pegarle el cambiazo a su
|
||
1443 | // recordset
|
||
1444 | setRecordset(getSource().getRecordset()); |
||
1445 | 13884 | jaume | if (getLegend() instanceof IVectorLegend) { |
1446 | IVectorLegend ley = (IVectorLegend) getLegend(); |
||
1447 | 12349 | jaume | ley.setDataSource(getSource().getRecordset()); |
1448 | // Esto lo pongo para evitar que al dibujar sobre un
|
||
1449 | // dxf, dwg, o dgn no veamos nada. Es debido al checkbox
|
||
1450 | // de la leyenda de textos "dibujar solo textos".
|
||
1451 | 10910 | jaume | //jaume
|
1452 | // if (!(getSource().getDriver() instanceof IndexedShpDriver)){
|
||
1453 | // FSymbol symbol=new FSymbol(getShapeType());
|
||
1454 | // symbol.setFontSizeInPixels(false);
|
||
1455 | // symbol.setFont(new Font("SansSerif", Font.PLAIN, 9));
|
||
1456 | // Color color=symbol.getColor();
|
||
1457 | // int alpha=symbol.getColor().getAlpha();
|
||
1458 | // if (alpha>250) {
|
||
1459 | // symbol.setColor(new Color(color.getRed(),color.getGreen(),color.getBlue(),100));
|
||
1460 | // }
|
||
1461 | // ley.setDefaultSymbol(symbol);
|
||
1462 | // }
|
||
1463 | //jaume//
|
||
1464 | 12349 | jaume | ley.useDefaultSymbol(true);
|
1465 | } |
||
1466 | } catch (ReadDriverException e) {
|
||
1467 | throw new StartEditionLayerException(getName(),e); |
||
1468 | } catch (FieldNotFoundException e) {
|
||
1469 | throw new StartEditionLayerException(getName(),e); |
||
1470 | } catch (StartWriterVisitorException e) {
|
||
1471 | throw new StartEditionLayerException(getName(),e); |
||
1472 | } |
||
1473 | 4223 | caballero | |
1474 | 12349 | jaume | setSpatialCacheEnabled(b); |
1475 | callEditionChanged(LayerEvent |
||
1476 | .createEditionChangedEvent(this, "edition")); |
||
1477 | 5152 | fjp | |
1478 | 12349 | jaume | } |
1479 | 4147 | fjp | |
1480 | 12349 | jaume | /**
|
1481 | * Para cuando haces una uni?n, sustituyes el recorset por el nuevo. De esta
|
||
1482 | * forma, podr?s poner leyendas basadas en el nuevo recordset
|
||
1483 | *
|
||
1484 | * @param newSds
|
||
1485 | */
|
||
1486 | public void setRecordset(SelectableDataSource newSds) { |
||
1487 | sds = newSds; |
||
1488 | sds.setSelectionSupport(selectionSupport); |
||
1489 | } |
||
1490 | 3366 | caballero | |
1491 | 12349 | jaume | public void clearSpatialCache() |
1492 | { |
||
1493 | spatialCache.clearAll(); |
||
1494 | } |
||
1495 | 5223 | fjp | |
1496 | 12349 | jaume | public boolean isSpatialCacheEnabled() { |
1497 | return spatialCacheEnabled;
|
||
1498 | } |
||
1499 | 5223 | fjp | |
1500 | 12349 | jaume | public void setSpatialCacheEnabled(boolean spatialCacheEnabled) { |
1501 | this.spatialCacheEnabled = spatialCacheEnabled;
|
||
1502 | } |
||
1503 | 5223 | fjp | |
1504 | 12349 | jaume | public SpatialCache getSpatialCache() {
|
1505 | return spatialCache;
|
||
1506 | } |
||
1507 | 5226 | fjp | |
1508 | 12349 | jaume | /**
|
1509 | * Siempre es un numero mayor de 1000
|
||
1510 | * @param maxFeatures
|
||
1511 | */
|
||
1512 | public void setMaxFeaturesInEditionCache(int maxFeatures) { |
||
1513 | if (maxFeatures > spatialCache.maxFeatures)
|
||
1514 | spatialCache.setMaxFeatures(maxFeatures); |
||
1515 | 6246 | caballero | |
1516 | 12349 | jaume | } |
1517 | 6246 | caballero | |
1518 | 12349 | jaume | /**
|
1519 | * This method returns a boolean that is used by the FPopMenu
|
||
1520 | * to make visible the properties menu or not. It is visible by
|
||
1521 | * default, and if a later don't have to show this menu only
|
||
1522 | * has to override this method.
|
||
1523 | * @return
|
||
1524 | * If the properties menu is visible (or not)
|
||
1525 | */
|
||
1526 | public boolean isPropertiesMenuVisible(){ |
||
1527 | return true; |
||
1528 | } |
||
1529 | 9010 | caballero | |
1530 | 12349 | jaume | public void reload() throws ReloadLayerException { |
1531 | this.setAvailable(true); |
||
1532 | super.reload();
|
||
1533 | try {
|
||
1534 | this.source.getDriver().reload();
|
||
1535 | if (this.getLegend() == null) { |
||
1536 | if (this.getRecordset().getDriver() instanceof WithDefaultLegend) { |
||
1537 | WithDefaultLegend aux = (WithDefaultLegend) this.getRecordset().getDriver();
|
||
1538 | 13884 | jaume | this.setLegend((IVectorLegend) aux.getDefaultLegend());
|
1539 | 12349 | jaume | this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
|
1540 | } else {
|
||
1541 | this.setLegend(LegendFactory.createSingleSymbolLegend(
|
||
1542 | this.getShapeType()));
|
||
1543 | } |
||
1544 | } |
||
1545 | 9010 | caballero | |
1546 | 12349 | jaume | } catch (LegendLayerException e) {
|
1547 | this.setAvailable(false); |
||
1548 | throw new ReloadLayerException(getName(),e); |
||
1549 | } catch (ReadDriverException e) {
|
||
1550 | this.setAvailable(false); |
||
1551 | throw new ReloadLayerException(getName(),e); |
||
1552 | } |
||
1553 | 9010 | caballero | |
1554 | 12349 | jaume | } |
1555 | 9010 | caballero | |
1556 | 12349 | jaume | protected void setLoadSelection(XMLEntity xml) { |
1557 | this.loadSelection = xml;
|
||
1558 | } |
||
1559 | 5793 | fjp | |
1560 | 13884 | jaume | protected void setLoadLegend(IVectorLegend legend) { |
1561 | 12349 | jaume | this.loadLegend = legend;
|
1562 | } |
||
1563 | 6534 | jmvivo | |
1564 | 12349 | jaume | protected void putLoadSelection() throws XMLException { |
1565 | if (this.loadSelection == null) return; |
||
1566 | try {
|
||
1567 | this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection); |
||
1568 | } catch (ReadDriverException e) {
|
||
1569 | throw new XMLException(e); |
||
1570 | } |
||
1571 | this.loadSelection = null; |
||
1572 | 9010 | caballero | |
1573 | 12349 | jaume | } |
1574 | protected void putLoadLegend() throws LegendLayerException { |
||
1575 | if (this.loadLegend == null) return; |
||
1576 | this.setLegend(this.loadLegend); |
||
1577 | this.loadLegend = null; |
||
1578 | } |
||
1579 | 6761 | jmvivo | |
1580 | 12349 | jaume | protected void cleanLoadOptions() { |
1581 | this.loadLegend = null; |
||
1582 | this.loadSelection = null; |
||
1583 | } |
||
1584 | 6761 | jmvivo | |
1585 | 12349 | jaume | public boolean isWritable() { |
1586 | VectorialDriver drv = getSource().getDriver(); |
||
1587 | if (!drv.isWritable())
|
||
1588 | return false; |
||
1589 | if (drv instanceof IWriteable) |
||
1590 | { |
||
1591 | IWriter writer = ((IWriteable)drv).getWriter(); |
||
1592 | if (writer != null) |
||
1593 | { |
||
1594 | if (writer instanceof ISpatialWriter) |
||
1595 | return true; |
||
1596 | } |
||
1597 | } |
||
1598 | return false; |
||
1599 | 6856 | fjp | |
1600 | 12349 | jaume | } |
1601 | 6856 | fjp | |
1602 | 12349 | jaume | public FLayer cloneLayer() throws Exception { |
1603 | FLyrVect clonedLayer = new FLyrVect();
|
||
1604 | clonedLayer.setSource(getSource()); |
||
1605 | 13445 | caballero | if (isJoined()) {
|
1606 | clonedLayer.setIsJoined(true);
|
||
1607 | clonedLayer.setRecordset(getRecordset()); |
||
1608 | } |
||
1609 | 12349 | jaume | clonedLayer.setVisible(isVisible()); |
1610 | clonedLayer.setISpatialIndex(getISpatialIndex()); |
||
1611 | clonedLayer.setName(getName()); |
||
1612 | clonedLayer.setCoordTrans(getCoordTrans()); |
||
1613 | 10627 | caballero | |
1614 | 13884 | jaume | clonedLayer.setLegend((IVectorLegend)getLegend().cloneLegend()); |
1615 | 10679 | jaume | |
1616 | 12349 | jaume | clonedLayer.setIsLabeled(isLabeled()); |
1617 | clonedLayer.setLabelingStrategy(getLabelingStrategy()); |
||
1618 | 10679 | jaume | |
1619 | 12349 | jaume | return clonedLayer;
|
1620 | } |
||
1621 | 9923 | fjp | |
1622 | 12657 | jaume | |
1623 | 14409 | vcaballero | private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, double dpi, CartographicSupport csSym, IGeometry geom, int[] xyCoords) { |
1624 | return isOnePoint(graphicsTransform, viewPort, geom, xyCoords) && csSym.getCartographicSize(viewPort, dpi, null) <= 1; |
||
1625 | 12466 | jaume | } |
1626 | |||
1627 | 14409 | vcaballero | private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, IGeometry geom, int[] xyCoords) { |
1628 | 12466 | jaume | boolean onePoint = false; |
1629 | 20704 | vcaballero | int type=geom.getGeometryType() % FShape.Z;
|
1630 | 17243 | vcaballero | if (type!=FShape.POINT && type!=FShape.MULTIPOINT) {
|
1631 | 12466 | jaume | |
1632 | Rectangle2D geomBounds = geom.getBounds2D();
|
||
1633 | |||
1634 | 20704 | vcaballero | ICoordTrans ct = getCoordTrans(); |
1635 | 12466 | jaume | |
1636 | 20704 | vcaballero | if (ct!=null) { |
1637 | // geomBounds = ct.getInverted().convert(geomBounds);
|
||
1638 | geomBounds = ct.convert(geomBounds); |
||
1639 | } |
||
1640 | 12466 | jaume | |
1641 | double dist1Pixel = viewPort.getDist1pixel();
|
||
1642 | |||
1643 | onePoint = (geomBounds.getWidth() <= dist1Pixel |
||
1644 | && geomBounds.getHeight() <= dist1Pixel); |
||
1645 | |||
1646 | if (onePoint) {
|
||
1647 | // avoid out of range exceptions
|
||
1648 | FPoint2D p = new FPoint2D(geomBounds.getMinX(), geomBounds.getMinY());
|
||
1649 | p.transform(viewPort.getAffineTransform()); |
||
1650 | 14409 | vcaballero | p.transform(graphicsTransform); |
1651 | 12466 | jaume | xyCoords[0] = (int) p.getX(); |
1652 | xyCoords[1] = (int) p.getY(); |
||
1653 | |||
1654 | } |
||
1655 | |||
1656 | 14409 | vcaballero | } |
1657 | 12466 | jaume | return onePoint;
|
1658 | } |
||
1659 | 12349 | jaume | /*
|
1660 | * jaume. Stuff from ILabeled.
|
||
1661 | */
|
||
1662 | private boolean isLabeled; |
||
1663 | private ILabelingStrategy strategy;
|
||
1664 | 10679 | jaume | |
1665 | 12349 | jaume | public boolean isLabeled() { |
1666 | return isLabeled;
|
||
1667 | } |
||
1668 | 10679 | jaume | |
1669 | 12349 | jaume | public void setIsLabeled(boolean isLabeled) { |
1670 | this.isLabeled = isLabeled;
|
||
1671 | } |
||
1672 | 10679 | jaume | |
1673 | 12349 | jaume | public ILabelingStrategy getLabelingStrategy() {
|
1674 | return strategy;
|
||
1675 | } |
||
1676 | 10679 | jaume | |
1677 | 12349 | jaume | public void setLabelingStrategy(ILabelingStrategy strategy) { |
1678 | this.strategy = strategy;
|
||
1679 | } |
||
1680 | 10679 | jaume | |
1681 | 12820 | jaume | public void drawLabels(BufferedImage image, Graphics2D g, ViewPort viewPort, |
1682 | 18621 | jdominguez | Cancellable cancel, double scale, double dpi) throws ReadDriverException { |
1683 | 14450 | vcaballero | if (strategy!=null && isWithinScale(scale)) { |
1684 | 18621 | jdominguez | strategy.draw(image, g, viewPort, cancel, dpi); |
1685 | 12349 | jaume | } |
1686 | } |
||
1687 | 10679 | jaume | |
1688 | 13558 | evercher | |
1689 | |||
1690 | //M?todos para el uso de HyperLinks en capas FLyerVect
|
||
1691 | |||
1692 | /**
|
||
1693 | * Return true, because a Vectorial Layer supports HyperLink
|
||
1694 | */
|
||
1695 | public boolean allowLinks() |
||
1696 | { |
||
1697 | return true; |
||
1698 | } |
||
1699 | |||
1700 | /**
|
||
1701 | * Returns an instance of AbstractLinkProperties that contains the information
|
||
1702 | * of the HyperLink
|
||
1703 | * @return Abstra
|
||
1704 | */
|
||
1705 | public AbstractLinkProperties getLinkProperties()
|
||
1706 | { |
||
1707 | return linkProperties;
|
||
1708 | } |
||
1709 | |||
1710 | /**
|
||
1711 | * Provides an array with URIs. Returns one URI by geometry that includes the point
|
||
1712 | * in its own geometry limits with a allowed tolerance.
|
||
1713 | * @param layer, the layer
|
||
1714 | * @param point, the point to check that is contained or not in the geometries in the layer
|
||
1715 | * @param tolerance, the tolerance allowed. Allowed margin of error to detect if the point
|
||
1716 | * is contained in some geometries of the layer
|
||
1717 | * @return
|
||
1718 | */
|
||
1719 | public URI[] getLink(Point2D point, double tolerance) |
||
1720 | { |
||
1721 | //return linkProperties.getLink(this)
|
||
1722 | return linkProperties.getLink(this,point,tolerance); |
||
1723 | } |
||
1724 | 16254 | vcaballero | /**
|
1725 | * @deprecated Don?t use Strategy, you should be use iterators.
|
||
1726 | */
|
||
1727 | public boolean isUseStrategy() { |
||
1728 | return useStrategy;
|
||
1729 | } |
||
1730 | /**
|
||
1731 | * @deprecated Don?t use Strategy, you should be use iterators.
|
||
1732 | */
|
||
1733 | public void setUseStrategy(boolean useStrategy) { |
||
1734 | this.useStrategy = useStrategy;
|
||
1735 | } |
||
1736 | 13558 | evercher | |
1737 | 16254 | vcaballero | @Override
|
1738 | public void load() throws LoadLayerException { |
||
1739 | super.load();
|
||
1740 | useStrategy=forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD; |
||
1741 | } |
||
1742 | |||
1743 | 13749 | jaume | } |