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