root / branches / v2_0_0_prep / libraries / libFMap_dalfile / src / org / gvsig / fmap / dal / store / dgn / DGNStoreProvider.java @ 29106
History | View | Annotate | Download (30.9 KB)
1 | 29106 | jmvivo | package org.gvsig.fmap.dal.store.dgn; |
---|---|---|---|
2 | |||
3 | import java.awt.geom.AffineTransform; |
||
4 | import java.awt.geom.Arc2D; |
||
5 | import java.io.File; |
||
6 | import java.util.ArrayList; |
||
7 | import java.util.HashMap; |
||
8 | import java.util.Iterator; |
||
9 | import java.util.List; |
||
10 | import java.util.Map; |
||
11 | |||
12 | import org.cresques.cts.IProjection; |
||
13 | import org.gvsig.fmap.dal.DALLocator; |
||
14 | import org.gvsig.fmap.dal.DataManager; |
||
15 | import org.gvsig.fmap.dal.DataServerExplorer; |
||
16 | import org.gvsig.fmap.dal.DataStoreNotification; |
||
17 | import org.gvsig.fmap.dal.DataTypes; |
||
18 | import org.gvsig.fmap.dal.exception.DataException; |
||
19 | import org.gvsig.fmap.dal.exception.InitializeException; |
||
20 | import org.gvsig.fmap.dal.exception.OpenException; |
||
21 | import org.gvsig.fmap.dal.exception.ReadException; |
||
22 | import org.gvsig.fmap.dal.exception.ValidateDataParametersException; |
||
23 | import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor; |
||
24 | import org.gvsig.fmap.dal.feature.EditableFeatureType; |
||
25 | import org.gvsig.fmap.dal.feature.FeatureStore; |
||
26 | import org.gvsig.fmap.dal.feature.FeatureType; |
||
27 | import org.gvsig.fmap.dal.feature.exception.PerformEditingException; |
||
28 | import org.gvsig.fmap.dal.feature.spi.FeatureData; |
||
29 | import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider; |
||
30 | import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices; |
||
31 | import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider; |
||
32 | import org.gvsig.fmap.dal.resource.exception.AccessResourceException; |
||
33 | import org.gvsig.fmap.dal.resource.exception.ResourceBeginException; |
||
34 | import org.gvsig.fmap.dal.resource.file.FileResource; |
||
35 | import org.gvsig.fmap.dal.resource.spi.ResourceConsumer; |
||
36 | import org.gvsig.fmap.dal.resource.spi.ResourceProvider; |
||
37 | import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer; |
||
38 | import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters; |
||
39 | import org.gvsig.fmap.dal.store.dgn.lib.DGNElemArc; |
||
40 | import org.gvsig.fmap.dal.store.dgn.lib.DGNElemCellHeader; |
||
41 | import org.gvsig.fmap.dal.store.dgn.lib.DGNElemComplexHeader; |
||
42 | import org.gvsig.fmap.dal.store.dgn.lib.DGNElemCore; |
||
43 | import org.gvsig.fmap.dal.store.dgn.lib.DGNElemMultiPoint; |
||
44 | import org.gvsig.fmap.dal.store.dgn.lib.DGNElemText; |
||
45 | import org.gvsig.fmap.dal.store.dgn.lib.DGNFileHeader; |
||
46 | import org.gvsig.fmap.dal.store.dgn.lib.DGNReader; |
||
47 | import org.gvsig.fmap.geom.Geometry; |
||
48 | import org.gvsig.fmap.geom.GeometryLocator; |
||
49 | import org.gvsig.fmap.geom.GeometryManager; |
||
50 | import org.gvsig.fmap.geom.Geometry.SUBTYPES; |
||
51 | import org.gvsig.fmap.geom.Geometry.TYPES; |
||
52 | import org.gvsig.fmap.geom.exception.CreateEnvelopeException; |
||
53 | import org.gvsig.fmap.geom.exception.CreateGeometryException; |
||
54 | import org.gvsig.fmap.geom.primitive.Envelope; |
||
55 | import org.gvsig.fmap.geom.primitive.GeneralPathX; |
||
56 | import org.gvsig.fmap.geom.primitive.Point; |
||
57 | import org.gvsig.tools.ToolsLocator; |
||
58 | import org.gvsig.tools.dynobject.DelegatedDynObject; |
||
59 | import org.gvsig.tools.dynobject.DynClass; |
||
60 | import org.gvsig.tools.dynobject.DynField; |
||
61 | import org.gvsig.tools.dynobject.DynObjectManager; |
||
62 | import org.gvsig.tools.dynobject.exception.DynMethodException; |
||
63 | import org.gvsig.tools.exception.NotYetImplemented; |
||
64 | import org.gvsig.tools.persistence.PersistenceException; |
||
65 | import org.gvsig.tools.persistence.PersistentState; |
||
66 | import org.slf4j.Logger; |
||
67 | import org.slf4j.LoggerFactory; |
||
68 | |||
69 | public class DGNStoreProvider extends AbstractMemoryStoreProvider implements |
||
70 | ResourceConsumer { |
||
71 | private static final Logger logger = LoggerFactory.getLogger(DGNStoreProvider.class); |
||
72 | |||
73 | public static final String NAME = "DGN"; |
||
74 | public static final String DESCRIPTION = "DGN file"; |
||
75 | public static final String DYNCLASS_NAME = "DGNFile"; |
||
76 | protected static DynClass DYNCLASS = null; |
||
77 | |||
78 | public static final String NAME_FIELD_ID = "ID"; |
||
79 | public static final String NAME_FIELD_GEOMETRY = "Geometry"; |
||
80 | public static final String NAME_FIELD_ENTITY = "Entity"; |
||
81 | public static final String NAME_FIELD_LAYER = "Layer"; |
||
82 | public static final String NAME_FIELD_COLOR = "Color"; |
||
83 | public static final String NAME_FIELD_ELEVATION = "Elevation"; |
||
84 | public static final String NAME_FIELD_THICKNESS = "Thickness"; |
||
85 | public static final String NAME_FIELD_TEXT = "Text"; |
||
86 | public static final String NAME_FIELD_HEIGHTTEXT = "HeightText"; |
||
87 | public static final String NAME_FIELD_ROTATIONTEXT = "Rotation"; |
||
88 | |||
89 | private int ID_FIELD_ID = 0; |
||
90 | private int ID_FIELD_ENTITY = 1; |
||
91 | private int ID_FIELD_LAYER = 2; |
||
92 | private int ID_FIELD_COLOR = 3; |
||
93 | private int ID_FIELD_ELEVATION = 4; |
||
94 | private int ID_FIELD_THICKNESS = 5; |
||
95 | private int ID_FIELD_TEXT = 6; |
||
96 | private int ID_FIELD_HEIGHTTEXT = 7; |
||
97 | private int ID_FIELD_ROTATIONTEXT = 8; |
||
98 | private int ID_FIELD_GEOMETRY = 9; |
||
99 | |||
100 | private IProjection projection;
|
||
101 | private ResourceProvider resource;
|
||
102 | private LegendBuilder legendBuilder;
|
||
103 | |||
104 | private long counterNewsOIDs = 0; |
||
105 | protected GeometryManager geomManager = GeometryLocator.getGeometryManager();
|
||
106 | |||
107 | |||
108 | |||
109 | private DGNStoreParameters getParameters() {
|
||
110 | return (DGNStoreParameters) this.parameters; |
||
111 | } |
||
112 | |||
113 | public DGNStoreProvider(DGNStoreParameters parameters) {
|
||
114 | super(parameters);
|
||
115 | } |
||
116 | |||
117 | public FeatureStoreProvider initialize(FeatureStoreProviderServices store)
|
||
118 | throws InitializeException {
|
||
119 | super.initialize(store);
|
||
120 | |||
121 | this.dynObject = (DelegatedDynObject) ToolsLocator
|
||
122 | .getDynObjectManager().createDynObject(DYNCLASS); |
||
123 | |||
124 | counterNewsOIDs = 0;
|
||
125 | // projection = CRSFactory.getCRS(getParameters().getSRSID());
|
||
126 | |||
127 | File file = getParameters().getFile();
|
||
128 | resource = this.createResource(
|
||
129 | FileResource.NAME, |
||
130 | new Object[] { file.getAbsolutePath() } |
||
131 | ); |
||
132 | |||
133 | resource.addConsumer(this);
|
||
134 | |||
135 | this.projection = this.getParameters().getSRS(); |
||
136 | |||
137 | |||
138 | try {
|
||
139 | legendBuilder = (LegendBuilder) this.invokeDynMethod(
|
||
140 | LegendBuilder.DYNMETHOD_BUILDER_NAME, null);
|
||
141 | } catch (DynMethodException e) {
|
||
142 | legendBuilder = null;
|
||
143 | } catch (Exception e) { |
||
144 | throw new InitializeException(e); |
||
145 | } |
||
146 | |||
147 | this.initializeFeatureTypes();
|
||
148 | return this; |
||
149 | } |
||
150 | |||
151 | public String getName() { |
||
152 | return NAME;
|
||
153 | } |
||
154 | |||
155 | public boolean allowWrite() { |
||
156 | return true; |
||
157 | } |
||
158 | |||
159 | public Object getLegend() throws OpenException { |
||
160 | this.open();
|
||
161 | if (legendBuilder == null) { |
||
162 | return null; |
||
163 | } |
||
164 | return legendBuilder.getLegend();
|
||
165 | } |
||
166 | |||
167 | public Object getLabeling() throws OpenException { |
||
168 | this.open();
|
||
169 | if (legendBuilder == null) { |
||
170 | return null; |
||
171 | } |
||
172 | return legendBuilder.getLabeling();
|
||
173 | } |
||
174 | |||
175 | private class DGNData { |
||
176 | public ArrayList data = null; |
||
177 | public FeatureType defaultFType = null; |
||
178 | public List fTypes = null; |
||
179 | public Envelope envelope = null; |
||
180 | public IProjection projection;
|
||
181 | public LegendBuilder legendBuilder;
|
||
182 | public Envelope getEnvelopeCopy() throws CreateEnvelopeException { |
||
183 | if (envelope == null) { |
||
184 | return null; |
||
185 | } |
||
186 | Envelope newEnvelope; |
||
187 | if (envelope.getDimension() == 2) { |
||
188 | newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM2D); |
||
189 | } else {
|
||
190 | newEnvelope = geomManager.createEnvelope(SUBTYPES.GEOM3D); |
||
191 | |||
192 | } |
||
193 | newEnvelope.setLowerCorner(envelope.getLowerCorner()); |
||
194 | newEnvelope.setUpperCorner(envelope.getUpperCorner()); |
||
195 | return newEnvelope;
|
||
196 | } |
||
197 | } |
||
198 | |||
199 | public void open() throws OpenException { |
||
200 | if (this.data != null) { |
||
201 | return;
|
||
202 | } |
||
203 | try {
|
||
204 | this.resource.begin();
|
||
205 | } catch (ResourceBeginException e2) {
|
||
206 | try {
|
||
207 | throw new OpenException(resource.getName(), e2); |
||
208 | } catch (AccessResourceException e1) {
|
||
209 | throw new OpenException(this.getName(), e2); |
||
210 | } |
||
211 | |||
212 | } |
||
213 | try {
|
||
214 | DGNData DGNData = null;
|
||
215 | if (this.resource.getData() != null) { |
||
216 | DGNData = (DGNData) ((Map) this.resource.getData()) |
||
217 | .get(this.projection
|
||
218 | .getAbrev()); // OJO no es del todo correcto (puede
|
||
219 | // llevar reproyeccion)
|
||
220 | } else {
|
||
221 | this.resource.setData(new HashMap()); |
||
222 | } |
||
223 | if (DGNData == null) { |
||
224 | DGNData = new DGNData();
|
||
225 | DGNData.data = new ArrayList(); |
||
226 | this.data = DGNData.data;
|
||
227 | this.counterNewsOIDs = 0; |
||
228 | Reader reader = new Reader().initialice( |
||
229 | this,
|
||
230 | new File((String) this.resource.get()), |
||
231 | projection, |
||
232 | this.legendBuilder
|
||
233 | ); |
||
234 | reader.begin(this.store);
|
||
235 | DGNData.defaultFType = reader.getDefaultType() |
||
236 | .getNotEditableCopy(); |
||
237 | ArrayList types = new ArrayList(); |
||
238 | Iterator it = reader.getTypes().iterator();
|
||
239 | EditableFeatureType fType; |
||
240 | while (it.hasNext()) {
|
||
241 | fType = (EditableFeatureType) it.next(); |
||
242 | if (fType.getId().equals(DGNData.defaultFType.getId())) {
|
||
243 | types.add(DGNData.defaultFType); |
||
244 | } else {
|
||
245 | types.add(fType.getNotEditableCopy()); |
||
246 | } |
||
247 | } |
||
248 | DGNData.fTypes = types; |
||
249 | |||
250 | resource.notifyOpen(); |
||
251 | this.store
|
||
252 | .setFeatureTypes(DGNData.fTypes, DGNData.defaultFType); |
||
253 | reader.load(); |
||
254 | // this.envelope = reader.getEnvelope();
|
||
255 | |||
256 | DGNData.envelope = reader.getEnvelope(); |
||
257 | |||
258 | DGNData.legendBuilder = this.legendBuilder;
|
||
259 | |||
260 | DGNData.projection = this.projection;
|
||
261 | |||
262 | reader.end(); |
||
263 | resource.notifyClose(); |
||
264 | ((Map) this.resource.getData()).put(this.projection.getAbrev(), |
||
265 | DGNData); // OJO la reproyeccion
|
||
266 | } |
||
267 | |||
268 | this.data = DGNData.data;
|
||
269 | this.store.setFeatureTypes(DGNData.fTypes, DGNData.defaultFType);
|
||
270 | this.legendBuilder = DGNData.legendBuilder;
|
||
271 | this.dynObject.setDynValue("Envelope", DGNData.getEnvelopeCopy()); |
||
272 | this.dynObject
|
||
273 | .setDynValue("DefaultSRS", this.projection.getAbrev()); |
||
274 | this.counterNewsOIDs = this.data.size(); |
||
275 | } catch (Exception e) { |
||
276 | this.data = null; |
||
277 | try {
|
||
278 | throw new OpenException(resource.getName(), e); |
||
279 | } catch (AccessResourceException e1) {
|
||
280 | throw new OpenException(this.getName(), e); |
||
281 | } |
||
282 | } finally {
|
||
283 | this.resource.end();
|
||
284 | } |
||
285 | } |
||
286 | |||
287 | |||
288 | public DataServerExplorer getExplorer() throws ReadException { |
||
289 | DataManager manager = DALLocator.getDataManager(); |
||
290 | FilesystemServerExplorerParameters params; |
||
291 | try {
|
||
292 | params = (FilesystemServerExplorerParameters) manager |
||
293 | .createServerExplorerParameters(FilesystemServerExplorer.NAME); |
||
294 | params.setRoot(this.getParameters().getFile().getParent());
|
||
295 | return manager.createServerExplorer(params);
|
||
296 | } catch (DataException e) {
|
||
297 | throw new ReadException(this.getName(), e); |
||
298 | } catch (ValidateDataParametersException e) {
|
||
299 | throw new ReadException(this.getName(), e); |
||
300 | } |
||
301 | |||
302 | } |
||
303 | |||
304 | |||
305 | |||
306 | public void performEditing(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException { |
||
307 | // FIXME Exception
|
||
308 | throw new UnsupportedOperationException(); |
||
309 | } |
||
310 | |||
311 | public class Reader { |
||
312 | private File file; |
||
313 | private String fileName; |
||
314 | private IProjection projection;
|
||
315 | private List types; |
||
316 | private LegendBuilder leyendBuilder;
|
||
317 | private AbstractMemoryStoreProvider store;
|
||
318 | private Envelope envelope;
|
||
319 | |||
320 | public Reader initialice(AbstractMemoryStoreProvider store, File file, |
||
321 | IProjection projection, |
||
322 | LegendBuilder leyendBuilder) { |
||
323 | this.store = store;
|
||
324 | this.file = file;
|
||
325 | this.fileName = file.getAbsolutePath();
|
||
326 | this.projection = projection;
|
||
327 | this.leyendBuilder = leyendBuilder;
|
||
328 | if (leyendBuilder != null) { |
||
329 | leyendBuilder.initialize(store); |
||
330 | } |
||
331 | return this; |
||
332 | } |
||
333 | |||
334 | public Envelope getEnvelope() {
|
||
335 | return this.envelope; |
||
336 | } |
||
337 | |||
338 | public void begin(FeatureStoreProviderServices store) { |
||
339 | |||
340 | EditableFeatureType featureType = store.createFeatureType(); |
||
341 | |||
342 | featureType.setHasOID(true);
|
||
343 | |||
344 | ID_FIELD_ID = featureType.add(NAME_FIELD_ID, DataTypes.INT) |
||
345 | .setDefaultValue(Integer.valueOf(0)) |
||
346 | .getIndex(); |
||
347 | |||
348 | // FIXME: Cual es el size y el valor por defecto para Entity ?
|
||
349 | ID_FIELD_ENTITY = featureType.add(NAME_FIELD_ENTITY, |
||
350 | DataTypes.STRING, 100)
|
||
351 | .setDefaultValue("")
|
||
352 | .getIndex(); |
||
353 | |||
354 | // FIXME: Cual es el size de Layer ?
|
||
355 | ID_FIELD_LAYER = featureType.add(NAME_FIELD_LAYER, |
||
356 | DataTypes.STRING, 100)
|
||
357 | .setDefaultValue( |
||
358 | "default").getIndex();
|
||
359 | |||
360 | ID_FIELD_COLOR = featureType.add(NAME_FIELD_COLOR, |
||
361 | DataTypes.INT) |
||
362 | .setDefaultValue( |
||
363 | Integer.valueOf(0)).getIndex(); |
||
364 | |||
365 | ID_FIELD_ELEVATION = featureType.add(NAME_FIELD_ELEVATION, |
||
366 | DataTypes.DOUBLE) |
||
367 | .setDefaultValue( |
||
368 | Double.valueOf(0)).getIndex(); |
||
369 | |||
370 | ID_FIELD_THICKNESS = featureType.add(NAME_FIELD_THICKNESS, |
||
371 | DataTypes.DOUBLE) |
||
372 | .setDefaultValue( |
||
373 | Double.valueOf(0)).getIndex(); |
||
374 | |||
375 | // FIXME: Cual es el size de Text ?
|
||
376 | ID_FIELD_TEXT = featureType.add(NAME_FIELD_TEXT, |
||
377 | DataTypes.STRING, 100)
|
||
378 | .setDefaultValue("")
|
||
379 | .getIndex(); |
||
380 | |||
381 | ID_FIELD_HEIGHTTEXT = featureType.add(NAME_FIELD_HEIGHTTEXT, |
||
382 | DataTypes.DOUBLE).setDefaultValue( |
||
383 | Double.valueOf(10)).getIndex(); |
||
384 | |||
385 | ID_FIELD_ROTATIONTEXT = featureType.add(NAME_FIELD_ROTATIONTEXT, |
||
386 | DataTypes.DOUBLE).setDefaultValue( |
||
387 | Double.valueOf(0)).getIndex(); |
||
388 | |||
389 | |||
390 | EditableFeatureAttributeDescriptor attr = featureType.add( |
||
391 | NAME_FIELD_GEOMETRY, DataTypes.GEOMETRY); |
||
392 | attr.setSRS(this.projection);
|
||
393 | attr.setGeometryType(Geometry.TYPES.GEOMETRY); |
||
394 | ID_FIELD_GEOMETRY = attr.getIndex(); |
||
395 | |||
396 | featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY); |
||
397 | |||
398 | |||
399 | // FIXME: Parece que el DGN puede tener mas atributos opcionales.
|
||
400 | // Habria que ver de pillarlos ?
|
||
401 | |||
402 | types = new ArrayList(); |
||
403 | types.add(featureType); |
||
404 | |||
405 | if (leyendBuilder != null) { |
||
406 | leyendBuilder.begin(); |
||
407 | } |
||
408 | |||
409 | } |
||
410 | |||
411 | public void end() { |
||
412 | if (leyendBuilder != null) { |
||
413 | leyendBuilder.end(); |
||
414 | } |
||
415 | } |
||
416 | |||
417 | public List getTypes() { |
||
418 | return types;
|
||
419 | } |
||
420 | |||
421 | public EditableFeatureType getDefaultType() {
|
||
422 | return (EditableFeatureType) types.get(0); |
||
423 | } |
||
424 | |||
425 | private Double toDouble(String value) { |
||
426 | if (value == null) { |
||
427 | return Double.valueOf(0); |
||
428 | } |
||
429 | return Double.valueOf(value); |
||
430 | } |
||
431 | |||
432 | public void load() throws DataException { |
||
433 | |||
434 | this.envelope = null; |
||
435 | |||
436 | DGNReader dgnReader = new DGNReader(file.getAbsolutePath());
|
||
437 | |||
438 | FeatureType type = getDefaultType().getNotEditableCopy(); |
||
439 | int fTypeSize = type.size();
|
||
440 | Object[] auxRow = new Object[fTypeSize]; |
||
441 | Object[] cellRow = new Object[fTypeSize]; |
||
442 | Object[] complexRow = new Object[fTypeSize]; |
||
443 | |||
444 | boolean bElementoCompuesto = false; |
||
445 | boolean bEsPoligono = false; |
||
446 | boolean bInsideCell = false; |
||
447 | boolean bFirstHoleEntity = false; |
||
448 | boolean bConnect = false; // Se usa para que los pol?gonos cierren |
||
449 | // bien cuando son formas compuestas
|
||
450 | int contadorSubElementos = 0; |
||
451 | int numSubElementos = 0; |
||
452 | int complex_index_fill_color = -1; |
||
453 | int nClass; // Para filtrar los elementos de construcci?n, etc. |
||
454 | GeneralPathX elementoCompuesto = new GeneralPathX(
|
||
455 | GeneralPathX.WIND_EVEN_ODD); |
||
456 | |||
457 | for (int id = 0; id < dgnReader.getNumEntities(); id++) { |
||
458 | // System.out.println("Elemento " + id + " de " +
|
||
459 | // dgnReader.getNumEntities());
|
||
460 | dgnReader.DGNGotoElement(id); |
||
461 | |||
462 | DGNElemCore elemento = dgnReader.DGNReadElement(); |
||
463 | nClass = 0;
|
||
464 | auxRow[ID_FIELD_HEIGHTTEXT] = new Double(0); |
||
465 | auxRow[ID_FIELD_ROTATIONTEXT] = new Double(0); |
||
466 | auxRow[ID_FIELD_TEXT] = null;
|
||
467 | |||
468 | if (elemento.properties != 0) { |
||
469 | nClass = elemento.properties & DGNFileHeader.DGNPF_CLASS; |
||
470 | } |
||
471 | |||
472 | if ((elemento != null) && (elemento.deleted == 0) |
||
473 | && (nClass == 0)) // Leer un elemento |
||
474 | { |
||
475 | |||
476 | // if ((elemento.element_id > 3800) && (elemento.element_id
|
||
477 | // < 3850))
|
||
478 | // dgnReader.DGNDumpElement(dgnReader.getInfo(),elemento,"");
|
||
479 | if ((elemento.stype == DGNFileHeader.DGNST_MULTIPOINT)
|
||
480 | || (elemento.stype == DGNFileHeader.DGNST_ARC) |
||
481 | || (elemento.stype == DGNFileHeader.DGNST_CELL_HEADER) |
||
482 | || (elemento.stype == DGNFileHeader.DGNST_SHARED_CELL_DEFN) |
||
483 | || (elemento.stype == DGNFileHeader.DGNST_COMPLEX_HEADER)) { |
||
484 | if (elemento.complex != 0) { |
||
485 | bElementoCompuesto = true;
|
||
486 | } else {
|
||
487 | if (bElementoCompuesto) {
|
||
488 | if (bInsideCell) {
|
||
489 | auxRow[ID_FIELD_ENTITY] = cellRow[ID_FIELD_ENTITY]; |
||
490 | } else {
|
||
491 | auxRow = complexRow; |
||
492 | } |
||
493 | |||
494 | // System.err.println("Entidad compuesta. bInsideCell = "
|
||
495 | // + bInsideCell + " auxRow = " +
|
||
496 | // auxRow[ID_FIELD_ENTITY]);
|
||
497 | // addShape(new FPolyline2D(elementoCompuesto),
|
||
498 | // auxRow);
|
||
499 | addShape(createMultiCurve(elementoCompuesto), |
||
500 | auxRow, type, dgnReader); |
||
501 | |||
502 | if (bEsPoligono) {
|
||
503 | if (complex_index_fill_color != -1) { |
||
504 | auxRow[ID_FIELD_COLOR] = complex_index_fill_color; |
||
505 | } |
||
506 | |||
507 | addShape( |
||
508 | createMultiSurface(elementoCompuesto), |
||
509 | auxRow, type, dgnReader); |
||
510 | } |
||
511 | |||
512 | elementoCompuesto = new GeneralPathX(
|
||
513 | GeneralPathX.WIND_EVEN_ODD); |
||
514 | } |
||
515 | |||
516 | // System.err.println("Entidad simple");
|
||
517 | bElementoCompuesto = false;
|
||
518 | bEsPoligono = false;
|
||
519 | bConnect = false;
|
||
520 | |||
521 | // elementoCompuesto = new GeneralPathX();
|
||
522 | bInsideCell = false;
|
||
523 | } |
||
524 | } |
||
525 | |||
526 | switch (elemento.stype) {
|
||
527 | case DGNFileHeader.DGNST_SHARED_CELL_DEFN:
|
||
528 | bInsideCell = true;
|
||
529 | cellRow[ID_FIELD_ID] = elemento.element_id; |
||
530 | cellRow[ID_FIELD_LAYER] = String
|
||
531 | .valueOf(elemento.level); |
||
532 | cellRow[ID_FIELD_COLOR] = elemento.color; |
||
533 | cellRow[ID_FIELD_ENTITY] = "Shared Cell";
|
||
534 | |||
535 | break;
|
||
536 | |||
537 | case DGNFileHeader.DGNST_CELL_HEADER:
|
||
538 | bInsideCell = true;
|
||
539 | |||
540 | DGNElemCellHeader psCellHeader = (DGNElemCellHeader) elemento; |
||
541 | cellRow[ID_FIELD_ID] = elemento.element_id; |
||
542 | cellRow[ID_FIELD_LAYER] = String
|
||
543 | .valueOf(elemento.level); |
||
544 | cellRow[ID_FIELD_COLOR] = elemento.color; |
||
545 | cellRow[ID_FIELD_ENTITY] = "Cell";
|
||
546 | complex_index_fill_color = dgnReader |
||
547 | .DGNGetShapeFillInfo(elemento); |
||
548 | |||
549 | // System.err.println("Cell Header " +
|
||
550 | // complex_index_fill_color);
|
||
551 | break;
|
||
552 | |||
553 | case DGNFileHeader.DGNST_COMPLEX_HEADER:
|
||
554 | |||
555 | // bElementoCompuesto = true;
|
||
556 | // System.err.println("Complex Header");
|
||
557 | contadorSubElementos = 0;
|
||
558 | |||
559 | DGNElemComplexHeader psComplexHeader = (DGNElemComplexHeader) elemento; |
||
560 | numSubElementos = psComplexHeader.numelems; |
||
561 | complexRow[ID_FIELD_ID] = elemento.element_id; |
||
562 | complexRow[ID_FIELD_LAYER] = String
|
||
563 | .valueOf(elemento.level); |
||
564 | complexRow[ID_FIELD_COLOR] = elemento.color; |
||
565 | complexRow[ID_FIELD_ENTITY] = "Complex";
|
||
566 | |||
567 | if (psComplexHeader.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER) {
|
||
568 | bEsPoligono = true;
|
||
569 | |||
570 | // Si es un agujero, no conectamos con el anterior
|
||
571 | if ((psComplexHeader.properties & 0x8000) != 0) { |
||
572 | bFirstHoleEntity = true;
|
||
573 | } else {
|
||
574 | // Miramos si tiene color de relleno
|
||
575 | // complex_index_fill_color = -1;
|
||
576 | // if (elemento.attr_bytes > 0) {
|
||
577 | complex_index_fill_color = dgnReader |
||
578 | .DGNGetShapeFillInfo(elemento); |
||
579 | |||
580 | // System.err.println("complex shape fill color = "
|
||
581 | // + elemento.color);
|
||
582 | // }
|
||
583 | } |
||
584 | |||
585 | bConnect = true;
|
||
586 | } else {
|
||
587 | bEsPoligono = false;
|
||
588 | bConnect = false;
|
||
589 | } |
||
590 | |||
591 | break;
|
||
592 | |||
593 | case DGNFileHeader.DGNST_MULTIPOINT:
|
||
594 | |||
595 | // OJO: Si lo que viene en este multipoint es un
|
||
596 | // elemento con type=11 (curve), se trata de una
|
||
597 | // "parametric
|
||
598 | // spline curve". La vamos a tratar como si no fuera
|
||
599 | // curva, pero seg?n la documentaci?n, los 2 primeros
|
||
600 | // puntos
|
||
601 | // y los 2 ?ltimos puntos definen "endpoint derivatives"
|
||
602 | // y NO se muestran.
|
||
603 | // TODAV?A HAY UN PEQUE?O FALLO CON EL FICHERO
|
||
604 | // dgn-sample.dgn, pero lo dejo por ahora.
|
||
605 | // Es posible que tenga que ver con lo de los arcos
|
||
606 | // (arco distorsionado), que
|
||
607 | // todav?a no est? metido.
|
||
608 | DGNElemMultiPoint psLine = (DGNElemMultiPoint) elemento; |
||
609 | auxRow[ID_FIELD_ID] = elemento.element_id; |
||
610 | auxRow[ID_FIELD_ENTITY] = "Multipoint";
|
||
611 | auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
|
||
612 | auxRow[ID_FIELD_COLOR] = elemento.color; |
||
613 | |||
614 | if ((psLine.num_vertices == 2) |
||
615 | && (psLine.vertices[0].x == psLine.vertices[1].x) |
||
616 | && (psLine.vertices[0].y == psLine.vertices[1].y)) { |
||
617 | auxRow[ID_FIELD_ENTITY] = "Point";
|
||
618 | addShape( |
||
619 | createPoint3D(psLine.vertices[0].x,
|
||
620 | psLine.vertices[0].y,
|
||
621 | psLine.vertices[0].z), auxRow,
|
||
622 | type, dgnReader); |
||
623 | } else {
|
||
624 | GeneralPathX elShape = new GeneralPathX(
|
||
625 | GeneralPathX.WIND_EVEN_ODD); |
||
626 | |||
627 | if (psLine.type == DGNFileHeader.DGNT_CURVE) {
|
||
628 | psLine.num_vertices = psLine.num_vertices - 4;
|
||
629 | |||
630 | for (int aux_n = 0; aux_n < psLine.num_vertices; aux_n++) { |
||
631 | psLine.vertices[aux_n] = psLine.vertices[aux_n + 2];
|
||
632 | } |
||
633 | } |
||
634 | |||
635 | if ((psLine.type == DGNFileHeader.DGNT_SHAPE)
|
||
636 | && ((psLine.properties & 0x8000) != 0)) { |
||
637 | // Invertimos el orden porque es un agujero
|
||
638 | elShape |
||
639 | .moveTo( |
||
640 | psLine.vertices[psLine.num_vertices - 1].x,
|
||
641 | psLine.vertices[psLine.num_vertices - 1].y);
|
||
642 | |||
643 | for (int i = psLine.num_vertices - 2; i >= 0; i--) { |
||
644 | elShape.lineTo(psLine.vertices[i].x, |
||
645 | psLine.vertices[i].y); |
||
646 | } |
||
647 | } else {
|
||
648 | elShape.moveTo(psLine.vertices[0].x,
|
||
649 | psLine.vertices[0].y);
|
||
650 | |||
651 | for (int i = 1; i < psLine.num_vertices; i++) { |
||
652 | elShape.lineTo(psLine.vertices[i].x, |
||
653 | psLine.vertices[i].y); |
||
654 | } |
||
655 | } |
||
656 | |||
657 | if ((psLine.vertices[0].x == psLine.vertices[psLine.num_vertices - 1].x) |
||
658 | && (psLine.vertices[0].y == psLine.vertices[psLine.num_vertices - 1].y)) { |
||
659 | // Lo a?adimos tambi?n como pol?gono
|
||
660 | bEsPoligono = true;
|
||
661 | |||
662 | // Miramos si tiene color de relleno
|
||
663 | if (elemento.attr_bytes > 0) { |
||
664 | elemento.color = dgnReader |
||
665 | .DGNGetShapeFillInfo(elemento); |
||
666 | |||
667 | // System.err.println("fill color = " +
|
||
668 | // elemento.color);
|
||
669 | if (elemento.color != -1) { |
||
670 | auxRow[ID_FIELD_COLOR] = elemento.color; |
||
671 | } |
||
672 | } |
||
673 | |||
674 | if (elemento.complex == 0) { |
||
675 | addShape(createSurface(elShape), auxRow, |
||
676 | type, dgnReader); |
||
677 | } |
||
678 | } |
||
679 | |||
680 | if (elemento.complex != 0) { |
||
681 | // Si es un agujero o
|
||
682 | // es la primera entidad del agujero, lo
|
||
683 | // a?adimos sin unir al anterior
|
||
684 | if (bFirstHoleEntity
|
||
685 | || ((psLine.type == DGNFileHeader.DGNT_SHAPE) && ((psLine.properties & 0x8000) != 0))) { |
||
686 | elementoCompuesto.append(elShape, false);
|
||
687 | bFirstHoleEntity = false;
|
||
688 | } else {
|
||
689 | elementoCompuesto.append(elShape, bConnect); |
||
690 | } |
||
691 | } else {
|
||
692 | addShape(createMultiCurve(elShape), auxRow, |
||
693 | type, dgnReader); |
||
694 | } |
||
695 | } |
||
696 | |||
697 | break;
|
||
698 | |||
699 | case DGNFileHeader.DGNST_ARC:
|
||
700 | |||
701 | // dgnReader.DGNDumpElement(dgnReader.getInfo(),
|
||
702 | // elemento,"");
|
||
703 | DGNElemArc psArc = (DGNElemArc) elemento; |
||
704 | |||
705 | // La definici?n de arco de MicroStation es distinta a
|
||
706 | // la de Java.
|
||
707 | // En el dgn el origin se entiende que es el centro del
|
||
708 | // arco,
|
||
709 | // y a la hora de crear un Arc2D las 2 primeras
|
||
710 | // coordenadas son
|
||
711 | // la esquina inferior izquierda del rect?ngulo que
|
||
712 | // rodea al arco.
|
||
713 | // 1.- Creamos la elipse sin rotaci?n.
|
||
714 | // 2.- Creamos el arco
|
||
715 | // 3.- Rotamos el resultado
|
||
716 | |||
717 | /*
|
||
718 | * System.out.println("Arco con primari axis: " +
|
||
719 | * psArc.primary_axis + " start angle: " +
|
||
720 | * psArc.startang + " sweepang = " + psArc.sweepang);
|
||
721 | * System.out.println("secondaria axis: " +
|
||
722 | * psArc.secondary_axis + " rotation = " +
|
||
723 | * psArc.rotation);
|
||
724 | */
|
||
725 | AffineTransform mT = AffineTransform.getRotateInstance( |
||
726 | Math.toRadians(psArc.rotation), psArc.origin.x,
|
||
727 | psArc.origin.y); |
||
728 | |||
729 | // mT.preConcatenate(AffineTransform.getScaleInstance(100.0,100.0));
|
||
730 | Arc2D.Double elArco = new Arc2D.Double(psArc.origin.x |
||
731 | - psArc.primary_axis, psArc.origin.y |
||
732 | - psArc.secondary_axis, |
||
733 | 2.0 * psArc.primary_axis,
|
||
734 | 2.0 * psArc.secondary_axis, -psArc.startang,
|
||
735 | -psArc.sweepang, Arc2D.OPEN);
|
||
736 | |||
737 | // Ellipse2D.Double elArco = new
|
||
738 | // Ellipse2D.Double(psArc.origin.x - psArc.primary_axis,
|
||
739 | // psArc.origin.y - psArc.secondary_axis,2.0 *
|
||
740 | // psArc.primary_axis, 2.0 * psArc.secondary_axis);
|
||
741 | GeneralPathX elShapeArc = new GeneralPathX(elArco);
|
||
742 | |||
743 | // Transformamos el GeneralPahtX porque si transformamos
|
||
744 | // elArco nos lo convierte
|
||
745 | // a GeneralPath y nos guarda las coordenadas en float,
|
||
746 | // con la correspondiente p?rdida de precisi?n
|
||
747 | elShapeArc.transform(mT); |
||
748 | |||
749 | if (dgnReader.getInfo().dimension == 3) { |
||
750 | // Aqu? podr?amos hacer cosas con la coordenada Z
|
||
751 | } |
||
752 | |||
753 | auxRow[ID_FIELD_ID] = elemento.element_id; |
||
754 | auxRow[ID_FIELD_ENTITY] = "Arc";
|
||
755 | auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
|
||
756 | auxRow[ID_FIELD_COLOR] = elemento.color; |
||
757 | |||
758 | /*
|
||
759 | * Line2D.Double ejeMayor = new
|
||
760 | * Line2D.Double(psArc.origin.x - psArc.primary_axis,
|
||
761 | * psArc.origin.y, psArc.origin.x + psArc.primary_axis,
|
||
762 | * psArc.origin.y);
|
||
763 | *
|
||
764 | * lyrLines.addShape(new
|
||
765 | * FShape(FConstant.SHAPE_TYPE_POLYLINE, new
|
||
766 | * GeneralPathX(ejeMayor)), auxRow);
|
||
767 | */
|
||
768 | |||
769 | // lyrLines.addShape(new
|
||
770 | // FShape(FConstant.SHAPE_TYPE_POLYLINE, elShapeArc),
|
||
771 | // auxRow);
|
||
772 | if (elemento.complex != 0) { |
||
773 | // Esto es una posible fuente de fallos si detr?s de
|
||
774 | // una
|
||
775 | // elipse vienen m?s cosas pegadas. Deber?amos
|
||
776 | // volver
|
||
777 | // a conectar una vez pasada la elipse.
|
||
778 | if (elemento.type == DGNFileHeader.DGNT_ELLIPSE) {
|
||
779 | bConnect = false;
|
||
780 | } |
||
781 | |||
782 | // SI LA ELIPSE ES UN AGUJERO, SE A?ADE SIN PEGAR
|
||
783 | // Y EL ELEMENTO ES UN POLIGONO
|
||
784 | if (bFirstHoleEntity
|
||
785 | || ((elemento.type == DGNFileHeader.DGNT_SHAPE) && ((elemento.properties & 0x8000) != 0))) { |
||
786 | elementoCompuesto.append(elShapeArc, false);
|
||
787 | bFirstHoleEntity = false;
|
||
788 | } else {
|
||
789 | elementoCompuesto.append(elShapeArc, bConnect); |
||
790 | } |
||
791 | } else {
|
||
792 | addShape(createMultiCurve(elShapeArc), auxRow, |
||
793 | type, dgnReader); |
||
794 | |||
795 | if (psArc.type == DGNFileHeader.DGNT_ELLIPSE) {
|
||
796 | addShape(createSurface(elShapeArc), auxRow, |
||
797 | type, dgnReader); |
||
798 | } |
||
799 | } |
||
800 | |||
801 | // System.err.println("Entra un Arco");
|
||
802 | break;
|
||
803 | |||
804 | case DGNFileHeader.DGNST_TEXT:
|
||
805 | |||
806 | DGNElemText psText = (DGNElemText) elemento; |
||
807 | Geometry elShapeTxt = createPoint3D(psText.origin.x, |
||
808 | psText.origin.y, psText.origin.z); |
||
809 | |||
810 | auxRow[ID_FIELD_ID] = elemento.element_id; |
||
811 | auxRow[ID_FIELD_ENTITY] = "Text";
|
||
812 | auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
|
||
813 | auxRow[ID_FIELD_COLOR] = elemento.color; |
||
814 | auxRow[ID_FIELD_HEIGHTTEXT] = psText.height_mult; |
||
815 | auxRow[ID_FIELD_ROTATIONTEXT] = psText.rotation; |
||
816 | auxRow[ID_FIELD_TEXT] = psText.string; // .trim();
|
||
817 | addShape(elShapeTxt, auxRow, type, dgnReader); |
||
818 | |||
819 | // System.out.println("Rotaci?n texto: " +
|
||
820 | // psText.rotation + "Altura Texto = " + heightText);
|
||
821 | |||
822 | /*
|
||
823 | * System.out.println(" origin=(" + psText.origin.x +
|
||
824 | * ", " + psText.origin.y + ") rotation=" +
|
||
825 | * psText.rotation + "\n" + " font=" + psText.font_id +
|
||
826 | * " just=" + psText.justification + "length_mult=" +
|
||
827 | * psText.length_mult + " height_mult=" +
|
||
828 | * psText.height_mult + "\n" + " string =" + new
|
||
829 | * String(psText.string).toString().trim() + "\n");
|
||
830 | */
|
||
831 | break;
|
||
832 | |||
833 | /*
|
||
834 | * default:
|
||
835 | * dgnReader.DGNDumpElement(dgnReader.getInfo(),
|
||
836 | * elemento, "");
|
||
837 | */
|
||
838 | } // switch
|
||
839 | } // if
|
||
840 | } // for
|
||
841 | |||
842 | if (bElementoCompuesto) {
|
||
843 | if (bInsideCell) {
|
||
844 | auxRow = cellRow; |
||
845 | } else {
|
||
846 | auxRow = complexRow; |
||
847 | } |
||
848 | |||
849 | // System.err.println("Entidad compuesta. bInsideCell = " +
|
||
850 | // bInsideCell + " auxRow = " + auxRow[ID_FIELD_ENTITY]);
|
||
851 | addShape(createMultiCurve(elementoCompuesto), auxRow, type, |
||
852 | dgnReader); |
||
853 | |||
854 | if (bEsPoligono) {
|
||
855 | if (complex_index_fill_color != -1) { |
||
856 | auxRow[ID_FIELD_COLOR] = complex_index_fill_color; |
||
857 | } |
||
858 | |||
859 | addShape(createSurface(elementoCompuesto), auxRow, type, |
||
860 | dgnReader); |
||
861 | } |
||
862 | } |
||
863 | |||
864 | } |
||
865 | |||
866 | private Geometry createMultiSurface(GeneralPathX elementoCompuesto)
|
||
867 | throws DataException {
|
||
868 | try {
|
||
869 | return geomManager.createMultiSurface(elementoCompuesto,
|
||
870 | SUBTYPES.GEOM2D); |
||
871 | } catch (CreateGeometryException e) {
|
||
872 | throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException( |
||
873 | e); |
||
874 | } |
||
875 | |||
876 | } |
||
877 | |||
878 | private Geometry createPoint3D(double x, double y, double z) |
||
879 | throws DataException {
|
||
880 | Point point;
|
||
881 | try {
|
||
882 | // point = (Point) geomManager.create(TYPES.POINT,
|
||
883 | // SUBTYPES.GEOM3D);
|
||
884 | point = (Point) geomManager.create(TYPES.POINT,
|
||
885 | SUBTYPES.GEOM2DZ); |
||
886 | } catch (CreateGeometryException e) {
|
||
887 | throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException( |
||
888 | e); |
||
889 | } |
||
890 | point.setCoordinates(new double[] { x, y, z }); |
||
891 | |||
892 | return point;
|
||
893 | } |
||
894 | |||
895 | private void addShape(Geometry geometry, Object[] auxRow, |
||
896 | FeatureType type, DGNReader dgnReader) throws DataException {
|
||
897 | FeatureData data = createFeatureData(type); |
||
898 | for (int i=0;i<type.size();i++){ |
||
899 | data.set(i, auxRow[i]); |
||
900 | } |
||
901 | data.setDefaultGeometry(geometry); |
||
902 | addFeatureData(data); |
||
903 | if (this.leyendBuilder != null) { |
||
904 | this.leyendBuilder.process(data, dgnReader);
|
||
905 | } |
||
906 | } |
||
907 | |||
908 | private Geometry createMultiCurve(GeneralPathX elementoCompuesto)
|
||
909 | throws DataException {
|
||
910 | try {
|
||
911 | return geomManager.createMultiCurve(elementoCompuesto,
|
||
912 | SUBTYPES.GEOM2D); |
||
913 | } catch (CreateGeometryException e) {
|
||
914 | throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException( |
||
915 | e); |
||
916 | } |
||
917 | } |
||
918 | |||
919 | private Geometry createSurface(GeneralPathX elementoCompuesto)
|
||
920 | throws DataException {
|
||
921 | try {
|
||
922 | return geomManager.createCurve(elementoCompuesto,
|
||
923 | SUBTYPES.GEOM2D); |
||
924 | } catch (CreateGeometryException e) {
|
||
925 | throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException( |
||
926 | e); |
||
927 | } |
||
928 | |||
929 | } |
||
930 | |||
931 | } |
||
932 | |||
933 | public boolean closeResourceRequested(ResourceProvider resource) { |
||
934 | return true; |
||
935 | } |
||
936 | |||
937 | public int getFeatureReferenceOIDType() { |
||
938 | return DataTypes.LONG;
|
||
939 | } |
||
940 | |||
941 | public boolean supportsAppendMode() { |
||
942 | return false; |
||
943 | } |
||
944 | |||
945 | public void append(FeatureData featureData) { |
||
946 | // FIXME Exception
|
||
947 | throw new UnsupportedOperationException(); |
||
948 | } |
||
949 | |||
950 | public void beginAppend() { |
||
951 | // FIXME Exception
|
||
952 | throw new UnsupportedOperationException(); |
||
953 | } |
||
954 | |||
955 | public void endAppend() { |
||
956 | // FIXME Exception
|
||
957 | throw new UnsupportedOperationException(); |
||
958 | } |
||
959 | |||
960 | public void saveToState(PersistentState state) throws PersistenceException { |
||
961 | // TODO Auto-generated method stub
|
||
962 | throw new NotYetImplemented(); |
||
963 | } |
||
964 | |||
965 | public void loadFromState(PersistentState state) throws PersistenceException { |
||
966 | // TODO Auto-generated method stub
|
||
967 | throw new NotYetImplemented(); |
||
968 | } |
||
969 | |||
970 | public Object createNewOID() { |
||
971 | return new Long(counterNewsOIDs++); |
||
972 | } |
||
973 | |||
974 | protected void initializeFeatureTypes() throws InitializeException { |
||
975 | try {
|
||
976 | this.open();
|
||
977 | } catch (OpenException e) {
|
||
978 | throw new InitializeException(this.getName(), e); |
||
979 | } |
||
980 | } |
||
981 | |||
982 | public Envelope getEnvelope() throws DataException { |
||
983 | this.open();
|
||
984 | return (Envelope) this.dynObject.getDynValue("Envelope"); |
||
985 | } |
||
986 | |||
987 | public Iterator getChilds() { |
||
988 | // TODO Auto-generated method stub
|
||
989 | return null; |
||
990 | } |
||
991 | |||
992 | |||
993 | /*
|
||
994 | * (non-Javadoc)
|
||
995 | *
|
||
996 | * @see
|
||
997 | * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
|
||
998 | * gvsig.fmap.dal.resource.spi.ResourceProvider)
|
||
999 | */
|
||
1000 | public void resourceChanged(ResourceProvider resource) { |
||
1001 | this.store.notifyChange(DataStoreNotification.RESOURCE_CHANGED,
|
||
1002 | resource); |
||
1003 | } |
||
1004 | |||
1005 | protected static void registerDynClass() { |
||
1006 | DynObjectManager dynman = ToolsLocator.getDynObjectManager(); |
||
1007 | DynClass dynClass; |
||
1008 | DynField field; |
||
1009 | if (DYNCLASS == null) { |
||
1010 | dynClass = dynman.add(DYNCLASS_NAME, "DGN File Store");
|
||
1011 | dynClass.extend(dynman.get(FeatureStore.DYNCLASS_NAME)); |
||
1012 | |||
1013 | DYNCLASS = dynClass; |
||
1014 | } |
||
1015 | |||
1016 | } |
||
1017 | |||
1018 | public Object getSourceId() { |
||
1019 | return this.getParameters().getFile(); |
||
1020 | } |
||
1021 | |||
1022 | } |