root / org.gvsig.dgn / trunk / org.gvsig.dgn / org.gvsig.dgn.provider / src / main / java / org / gvsig / fmap / dal / store / dgn / DGNStoreProvider.java @ 163
History | View | Annotate | Download (68.5 KB)
1 |
package org.gvsig.fmap.dal.store.dgn; |
---|---|
2 |
|
3 |
import java.awt.geom.AffineTransform; |
4 |
import java.awt.geom.Arc2D; |
5 |
import java.awt.geom.PathIterator; |
6 |
import java.io.BufferedWriter; |
7 |
import java.io.File; |
8 |
import java.io.FileWriter; |
9 |
import java.io.IOException; |
10 |
import java.util.ArrayList; |
11 |
import java.util.Date; |
12 |
import java.util.HashMap; |
13 |
import java.util.Iterator; |
14 |
import java.util.List; |
15 |
import java.util.Map; |
16 |
|
17 |
import org.apache.commons.io.IOUtils; |
18 |
import org.cresques.cts.IProjection; |
19 |
import org.slf4j.Logger; |
20 |
import org.slf4j.LoggerFactory; |
21 |
|
22 |
import org.gvsig.fmap.dal.DALLocator; |
23 |
import org.gvsig.fmap.dal.DataManager; |
24 |
import org.gvsig.fmap.dal.DataServerExplorer; |
25 |
import org.gvsig.fmap.dal.DataStoreNotification; |
26 |
import org.gvsig.fmap.dal.DataTypes; |
27 |
import org.gvsig.fmap.dal.FileHelper; |
28 |
import org.gvsig.fmap.dal.exception.DataException; |
29 |
import org.gvsig.fmap.dal.exception.InitializeException; |
30 |
import org.gvsig.fmap.dal.exception.LoadException; |
31 |
import org.gvsig.fmap.dal.exception.OpenException; |
32 |
import org.gvsig.fmap.dal.exception.ReadException; |
33 |
import org.gvsig.fmap.dal.exception.ValidateDataParametersException; |
34 |
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor; |
35 |
import org.gvsig.fmap.dal.feature.EditableFeatureType; |
36 |
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
37 |
import org.gvsig.fmap.dal.feature.FeatureType; |
38 |
import org.gvsig.fmap.dal.feature.exception.PerformEditingException; |
39 |
import org.gvsig.fmap.dal.feature.spi.FeatureProvider; |
40 |
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices; |
41 |
import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider; |
42 |
import org.gvsig.fmap.dal.resource.ResourceAction; |
43 |
import org.gvsig.fmap.dal.resource.exception.AccessResourceException; |
44 |
import org.gvsig.fmap.dal.resource.file.FileResource; |
45 |
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer; |
46 |
import org.gvsig.fmap.dal.resource.spi.ResourceProvider; |
47 |
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer; |
48 |
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters; |
49 |
import org.gvsig.fmap.dal.spi.DataStoreProviderServices; |
50 |
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemArc; |
51 |
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemComplexHeader; |
52 |
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemCore; |
53 |
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemMultiPoint; |
54 |
import org.gvsig.fmap.dal.store.dgn.lib.DGNElemText; |
55 |
import org.gvsig.fmap.dal.store.dgn.lib.DGNFileHeader; |
56 |
import org.gvsig.fmap.dal.store.dgn.lib.DGNLink; |
57 |
import org.gvsig.fmap.dal.store.dgn.lib.DGNPoint; |
58 |
import org.gvsig.fmap.dal.store.dgn.lib.DGNReader; |
59 |
import org.gvsig.fmap.geom.Geometry; |
60 |
import org.gvsig.fmap.geom.Geometry.SUBTYPES; |
61 |
import org.gvsig.fmap.geom.Geometry.TYPES; |
62 |
import org.gvsig.fmap.geom.GeometryLocator; |
63 |
import org.gvsig.fmap.geom.GeometryManager; |
64 |
import org.gvsig.fmap.geom.exception.CreateEnvelopeException; |
65 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
66 |
import org.gvsig.fmap.geom.primitive.Envelope; |
67 |
import org.gvsig.fmap.geom.primitive.GeneralPathX; |
68 |
import org.gvsig.fmap.geom.primitive.IGeneralPathX; |
69 |
import org.gvsig.fmap.geom.primitive.OrientablePrimitive; |
70 |
import org.gvsig.fmap.geom.primitive.Point; |
71 |
import org.gvsig.fmap.geom.type.GeometryType; |
72 |
import org.gvsig.tools.dynobject.exception.DynMethodException; |
73 |
|
74 |
public class DGNStoreProvider extends AbstractMemoryStoreProvider implements |
75 |
ResourceConsumer { |
76 |
|
77 |
private static final Logger logger = LoggerFactory.getLogger(DGNStoreProvider.class); |
78 |
|
79 |
public static final String NAME = "DGN"; |
80 |
public static final String DESCRIPTION = "DGN file"; |
81 |
|
82 |
public static final String METADATA_DEFINITION_NAME = NAME; |
83 |
public static final String METADATA_DEFINITION_DESCRIPTION = "DGN File Store"; |
84 |
|
85 |
public static final int LOAD_MODE_PLAIN = 0; |
86 |
public static final int LOAD_MODE_GROUP1 = 1; |
87 |
|
88 |
public static final int CROP_OPERATION_NONE = 0; |
89 |
public static final int CROP_OPERATION_CONTAINS = 1; |
90 |
public static final int CROP_OPERATION_COVERS = 2; |
91 |
public static final int CROP_OPERATION_COVEREDBY = 3; |
92 |
public static final int CROP_OPERATION_CROSSES = 4; |
93 |
public static final int CROP_OPERATION_DISJOINT = 5; |
94 |
public static final int CROP_OPERATION_INTERSECT = 6; |
95 |
public static final int CROP_OPERATION_OVERLAPS = 7; |
96 |
public static final int CROP_OPERATION_TOUCHES = 8; |
97 |
public static final int CROP_OPERATION_WITHIN = 9; |
98 |
|
99 |
public static final int GROUP_GEOMETRIES_NONE = 0; |
100 |
public static final int GROUP_GEOMETRIES_CONVEXHULL = 1; |
101 |
public static final int GROUP_GEOMETRIES_UNION = 2; |
102 |
public static final int GROUP_GEOMETRIES_INTERSECTION = 3; |
103 |
public static final int GROUP_GEOMETRIES_TOPOINTS = 4; |
104 |
public static final int GROUP_GEOMETRIES_TOLINES = 5; |
105 |
public static final int GROUP_GEOMETRIES_TOPOLYGONS = 6; |
106 |
public static final int GROUP_GEOMETRIES_TOPOLYGONS_FIX = 7; |
107 |
|
108 |
public static final String NAME_FIELD_ID = "ID"; |
109 |
public static final String NAME_FIELD_GEOMETRY = "Geometry"; |
110 |
public static final String NAME_FIELD_TYPE = "Type"; |
111 |
public static final String NAME_FIELD_STYPE = "SType"; |
112 |
public static final String NAME_FIELD_ENTITY = "Entity"; |
113 |
public static final String NAME_FIELD_LEVEL = "Layer"; |
114 |
public static final String NAME_FIELD_COLOR = "Color"; |
115 |
public static final String NAME_FIELD_FILLCOLOR = "FillColor"; |
116 |
public static final String NAME_FIELD_ELEVATION = "Elevation"; |
117 |
public static final String NAME_FIELD_WEIGHT = "Weight"; |
118 |
public static final String NAME_FIELD_TEXT = "Text"; |
119 |
public static final String NAME_FIELD_HEIGHTTEXT = "HeightText"; |
120 |
public static final String NAME_FIELD_HEIGHTTEXTRAW = "HeightTextRaw"; |
121 |
public static final String NAME_FIELD_ROTATIONTEXT = "Rotation"; |
122 |
public static final String NAME_FIELD_STYLE = "Style"; |
123 |
public static final String NAME_FIELD_GROUP = "Group"; |
124 |
public static final String NAME_FIELD_ISSHAPE = "IsShape"; |
125 |
public static final String NAME_FIELD_ISCOMPLEXSHAPEHEADER = "IsComplexShapeHeader"; |
126 |
public static final String NAME_FIELD_ISHOLE = "IsHole"; |
127 |
public static final String NAME_FIELD_ISCOMPLEX = "IsComplex"; |
128 |
public static final String NAME_FIELD_PARENTID = "ParentId"; |
129 |
public static final String NAME_FIELD_SCALE = "Scale"; |
130 |
public static final String NAME_FIELD_LINKS_COUNT = "LinksCount"; |
131 |
public static final String NAME_FIELD_LINK_INDEX = "LinkIndex"; |
132 |
public static final String NAME_FIELD_LINK_TYPE = "LinkType"; |
133 |
public static final String NAME_FIELD_LINK_ENTITY = "LinkEntity"; |
134 |
public static final String NAME_FIELD_LINK_MS = "LinkMS"; |
135 |
public static final String NAME_FIELD_LINK_LENGTH = "LinkLength"; |
136 |
public static final String NAME_FIELD_LINK_DATA = "LinkData"; |
137 |
public static final String NAME_FIELD_DATA = "Data"; |
138 |
|
139 |
private int ID_FIELD_ID; |
140 |
private int ID_FIELD_TYPE; |
141 |
private int ID_FIELD_STYPE; |
142 |
private int ID_FIELD_ENTITY; |
143 |
private int ID_FIELD_LEVEL; |
144 |
private int ID_FIELD_COLOR; |
145 |
private int ID_FIELD_FILLCOLOR; |
146 |
private int ID_FIELD_ELEVATION; |
147 |
private int ID_FIELD_WEIGHT; |
148 |
private int ID_FIELD_TEXT; |
149 |
private int ID_FIELD_HEIGHTTEXT; |
150 |
private int ID_FIELD_HEIGHTTEXTRAW; |
151 |
private int ID_FIELD_ROTATIONTEXT; |
152 |
private int ID_FIELD_STYLE; |
153 |
private int ID_FIELD_GROUP; |
154 |
private int ID_FIELD_LAYER; |
155 |
private int ID_FIELD_ISCOMPLEXSHAPEHEADER; |
156 |
private int ID_FIELD_ISSHAPE; |
157 |
private int ID_FIELD_ISHOLE; |
158 |
private int ID_FIELD_ISCOMPLEX; |
159 |
private int ID_FIELD_PARENT; |
160 |
private int ID_FIELD_SCALE; |
161 |
private int ID_FIELD_LINKS_COUNT; |
162 |
private int ID_FIELD_LINK_INDEX; |
163 |
private int ID_FIELD_LINK_TYPE; |
164 |
private int ID_FIELD_LINK_ENTITY; |
165 |
private int ID_FIELD_LINK_MS; |
166 |
private int ID_FIELD_LINK_LENGTH; |
167 |
private int ID_FIELD_LINK_DATA; |
168 |
private int ID_FIELD_DATA; |
169 |
private int ID_FIELD_GEOMETRY; |
170 |
private int MAX_FIELD_ID; |
171 |
|
172 |
private IProjection projection;
|
173 |
private ResourceProvider resource;
|
174 |
private LegendBuilder legendBuilder;
|
175 |
|
176 |
private long counterNewsOIDs = 0; |
177 |
protected GeometryManager geomManager = GeometryLocator
|
178 |
.getGeometryManager(); |
179 |
|
180 |
private int groupByFieldIndex = -2; |
181 |
private Map<Object, FeatureProvider> groupedFeatures = null; |
182 |
|
183 |
DGNData dgndata = null;
|
184 |
|
185 |
public DGNStoreProvider(DGNStoreParameters parameters,
|
186 |
DataStoreProviderServices storeServices) throws InitializeException {
|
187 |
super(parameters, storeServices, FileHelper
|
188 |
.newMetadataContainer(METADATA_DEFINITION_NAME)); |
189 |
|
190 |
counterNewsOIDs = 0;
|
191 |
// projection = CRSFactory.getCRS(getParameters().getSRSID());
|
192 |
|
193 |
File file = getDGNParameters().getFile();
|
194 |
resource = |
195 |
this.createResource(FileResource.NAME,
|
196 |
new Object[] { file.getAbsolutePath() }); |
197 |
|
198 |
resource.addConsumer(this);
|
199 |
|
200 |
this.projection = this.getDGNParameters().getCRS(); |
201 |
|
202 |
try {
|
203 |
legendBuilder = |
204 |
(LegendBuilder) this.invokeDynMethod(
|
205 |
LegendBuilder.DYNMETHOD_BUILDER_NAME, null);
|
206 |
} catch (DynMethodException e) {
|
207 |
legendBuilder = null;
|
208 |
} catch (Exception e) { |
209 |
throw new InitializeException(e); |
210 |
} |
211 |
|
212 |
this.initializeFeatureTypes();
|
213 |
|
214 |
} |
215 |
|
216 |
private DGNStoreParameters getDGNParameters() {
|
217 |
return (DGNStoreParameters) this.getParameters(); |
218 |
} |
219 |
|
220 |
public String getProviderName() { |
221 |
return NAME;
|
222 |
} |
223 |
|
224 |
public boolean allowWrite() { |
225 |
// not yet
|
226 |
return false; |
227 |
} |
228 |
|
229 |
public Object getLegend() throws OpenException { |
230 |
this.open();
|
231 |
if (legendBuilder == null) { |
232 |
return null; |
233 |
} |
234 |
return legendBuilder.getLegend();
|
235 |
} |
236 |
|
237 |
public Object getLabeling() throws OpenException { |
238 |
this.open();
|
239 |
if (legendBuilder == null) { |
240 |
return null; |
241 |
} |
242 |
return legendBuilder.getLabeling();
|
243 |
} |
244 |
|
245 |
private class DGNData { |
246 |
|
247 |
public List<FeatureProvider> data = null; |
248 |
public FeatureType defaultFType = null; |
249 |
public List<FeatureType> fTypes = null; |
250 |
public Envelope envelope = null; |
251 |
public IProjection projection;
|
252 |
public LegendBuilder legendBuilder;
|
253 |
|
254 |
public Envelope getEnvelopeCopy() throws CreateEnvelopeException { |
255 |
if (envelope == null) { |
256 |
return null; |
257 |
} |
258 |
try {
|
259 |
return (Envelope) envelope.clone();
|
260 |
} catch (CloneNotSupportedException ex) { |
261 |
logger.warn("Can't clone envelope.", ex);
|
262 |
return null; |
263 |
} |
264 |
} |
265 |
} |
266 |
|
267 |
public static class TimeCounter { |
268 |
|
269 |
private static final Logger logger = LoggerFactory |
270 |
.getLogger(TimeCounter.class); |
271 |
|
272 |
private long counter = 0; |
273 |
private Date t1; |
274 |
private Date t2; |
275 |
|
276 |
public void start() { |
277 |
this.t1 = new Date(); |
278 |
this.t2 = this.t1; |
279 |
} |
280 |
|
281 |
public void restart() { |
282 |
this.t1 = new Date(); |
283 |
this.t2 = this.t1; |
284 |
this.counter = 0; |
285 |
} |
286 |
|
287 |
public void stop() { |
288 |
this.t2 = new Date(); |
289 |
this.counter += this.t2.getTime() - this.t1.getTime(); |
290 |
} |
291 |
|
292 |
public long get() { |
293 |
return this.counter; |
294 |
} |
295 |
|
296 |
public void log(String msg) { |
297 |
logger.debug("Time " + get() + " ms. " + msg); |
298 |
} |
299 |
|
300 |
public void restart(String msg) { |
301 |
this.stop();
|
302 |
this.log(msg);
|
303 |
this.restart();
|
304 |
} |
305 |
} |
306 |
|
307 |
public void open() throws OpenException { |
308 |
if (this.data != null) { |
309 |
return;
|
310 |
} |
311 |
try {
|
312 |
getResource().execute(new ResourceAction() {
|
313 |
|
314 |
public Object run() throws Exception { |
315 |
|
316 |
TimeCounter tc = new TimeCounter();
|
317 |
tc.start(); |
318 |
|
319 |
FeatureStoreProviderServices storeProviderServices = getStoreServices(); |
320 |
if (dgndata == null && !(getDGNParameters().useReload())) { |
321 |
if (resource.getData() != null) { |
322 |
dgndata = |
323 |
(DGNData) ((Map) resource.getData())
|
324 |
.get(projection.getAbrev()); // OJO no es del todo correcto (puede llevar reproyeccion)
|
325 |
} else {
|
326 |
resource.setData(new HashMap()); |
327 |
} |
328 |
} |
329 |
tc.restart("Retrive data from resource (data=" + dgndata + ")"); |
330 |
|
331 |
if (dgndata == null) { |
332 |
dgndata = new DGNData();
|
333 |
dgndata.data = new ArrayList(); |
334 |
data = dgndata.data; |
335 |
counterNewsOIDs = 0;
|
336 |
Reader reader = new Reader().initialice(getMemoryProvider(), (File) resource.get(), projection, legendBuilder); |
337 |
reader.begin(storeProviderServices); |
338 |
dgndata.defaultFType = reader.getDefaultType().getNotEditableCopy(); |
339 |
List types = new ArrayList(); |
340 |
Iterator it = reader.getTypes().iterator();
|
341 |
EditableFeatureType fType; |
342 |
while (it.hasNext()) {
|
343 |
fType = (EditableFeatureType) it.next(); |
344 |
if (fType.getId().equals(dgndata.defaultFType.getId())) {
|
345 |
types.add(dgndata.defaultFType); |
346 |
} else {
|
347 |
types.add(fType.getNotEditableCopy()); |
348 |
} |
349 |
} |
350 |
dgndata.fTypes = types; |
351 |
|
352 |
resource.notifyOpen(); |
353 |
storeProviderServices.setFeatureTypes(dgndata.fTypes, dgndata.defaultFType); |
354 |
reader.load(); |
355 |
dgndata.envelope = reader.getEnvelope(); |
356 |
dgndata.legendBuilder = legendBuilder; |
357 |
dgndata.projection = projection; |
358 |
reader.end(); |
359 |
if (resource.getData() == null) { |
360 |
resource.setData(new HashMap()); |
361 |
} |
362 |
((Map) resource.getData()).put(projection.getAbrev(),dgndata); // OJO la reproyeccion |
363 |
tc.restart("Loaded data from file (data=" + dgndata + ")"); |
364 |
resource.notifyClose(); |
365 |
} |
366 |
// El feature type no lo compartimos entre las instancias del
|
367 |
// mismo resource ya que puede cambiar en funcion del filtro.
|
368 |
// Por lo menos el geometry-type.
|
369 |
List<FeatureType> featureTypes = getFeatureTypes(storeProviderServices);
|
370 |
|
371 |
tc.restart("Created featuretype (featureTypes=" + featureTypes + ")"); |
372 |
|
373 |
PostProcessFeatures postProcess = new PostProcessFeatures(getDGNParameters(), featureTypes.get(0)); |
374 |
if (postProcess.hasOperations()) {
|
375 |
data = postProcess.apply(dgndata.data); |
376 |
setDynValue("Envelope", postProcess.getEnvelope());
|
377 |
} else {
|
378 |
data = dgndata.data; |
379 |
setDynValue("Envelope", dgndata.getEnvelopeCopy());
|
380 |
} |
381 |
tc.restart("PostProcessFeatures");
|
382 |
|
383 |
legendBuilder = dgndata.legendBuilder; |
384 |
storeProviderServices.setFeatureTypes(featureTypes, featureTypes.get(0));
|
385 |
setDynValue("CRS", projection);
|
386 |
counterNewsOIDs = data.size(); |
387 |
tc.restart("load finished.");
|
388 |
return null; |
389 |
} |
390 |
}); |
391 |
} catch (Exception e) { |
392 |
data = null;
|
393 |
try {
|
394 |
throw new OpenException(resource.getName(), e); |
395 |
} catch (AccessResourceException e1) {
|
396 |
throw new OpenException(getProviderName(), e); |
397 |
} |
398 |
} |
399 |
} |
400 |
|
401 |
public DataServerExplorer getExplorer() throws ReadException { |
402 |
DataManager manager = DALLocator.getDataManager(); |
403 |
FilesystemServerExplorerParameters params; |
404 |
try {
|
405 |
params = (FilesystemServerExplorerParameters) manager.createServerExplorerParameters(FilesystemServerExplorer.NAME); |
406 |
params.setRoot(this.getDGNParameters().getFile().getParent());
|
407 |
return manager.openServerExplorer(FilesystemServerExplorer.NAME, params);
|
408 |
} catch (DataException e) {
|
409 |
throw new ReadException(this.getProviderName(), e); |
410 |
} catch (ValidateDataParametersException e) {
|
411 |
throw new ReadException(this.getProviderName(), e); |
412 |
} |
413 |
|
414 |
} |
415 |
|
416 |
public void performChanges(Iterator deleteds, Iterator inserteds, |
417 |
Iterator updateds, Iterator originalFeatureTypesUpdated) |
418 |
throws PerformEditingException {
|
419 |
// FIXME Exception
|
420 |
throw new UnsupportedOperationException(); |
421 |
} |
422 |
|
423 |
public List getFeatureTypes(FeatureStoreProviderServices store) { |
424 |
//FIXME: Habr?a que distinguir cuando se va a crear un DGN 3D o 2D, de momento siempre 3D
|
425 |
return getFeatureTypes(store, Geometry.SUBTYPES.GEOM3D);
|
426 |
} |
427 |
|
428 |
private List getFeatureTypes(FeatureStoreProviderServices store, int subtype) { |
429 |
EditableFeatureType featureType = store.createFeatureType(getName()); |
430 |
|
431 |
featureType.setHasOID(true);
|
432 |
|
433 |
ID_FIELD_ID = featureType.add(NAME_FIELD_ID, DataTypes.INT) |
434 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
435 |
|
436 |
ID_FIELD_PARENT = featureType.add(NAME_FIELD_PARENTID, DataTypes.INT) |
437 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
438 |
|
439 |
// FIXME: Cual es el size y el valor por defecto para Entity ?
|
440 |
ID_FIELD_ENTITY = featureType.add(NAME_FIELD_ENTITY, DataTypes.STRING, 100)
|
441 |
.setDefaultValue("").getIndex();
|
442 |
|
443 |
// FIXME: Cual es el size de Layer ?
|
444 |
ID_FIELD_LEVEL = featureType.add(NAME_FIELD_LEVEL, DataTypes.STRING, 100)
|
445 |
.setDefaultValue("default").getIndex();
|
446 |
ID_FIELD_LAYER = ID_FIELD_LEVEL; |
447 |
|
448 |
ID_FIELD_COLOR = featureType.add(NAME_FIELD_COLOR, DataTypes.INT) |
449 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
450 |
|
451 |
// FIXME: Cual es el size de Text ?
|
452 |
ID_FIELD_TEXT = featureType.add(NAME_FIELD_TEXT, DataTypes.STRING, 100)
|
453 |
.setDefaultValue("").getIndex();
|
454 |
|
455 |
ID_FIELD_HEIGHTTEXT = featureType.add(NAME_FIELD_HEIGHTTEXT, DataTypes.DOUBLE) |
456 |
.setDefaultValue(Double.valueOf(10)).getIndex(); |
457 |
|
458 |
ID_FIELD_HEIGHTTEXTRAW = featureType.add(NAME_FIELD_HEIGHTTEXTRAW, DataTypes.DOUBLE) |
459 |
.setDefaultValue(Double.valueOf(10)).getIndex(); |
460 |
|
461 |
ID_FIELD_ROTATIONTEXT = featureType.add(NAME_FIELD_ROTATIONTEXT, DataTypes.DOUBLE) |
462 |
.setDefaultValue(Double.valueOf(0)).getIndex(); |
463 |
|
464 |
ID_FIELD_TYPE = featureType.add(NAME_FIELD_TYPE, DataTypes.INT) |
465 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
466 |
|
467 |
ID_FIELD_STYPE = featureType.add(NAME_FIELD_STYPE, DataTypes.INT) |
468 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
469 |
|
470 |
ID_FIELD_FILLCOLOR = featureType.add(NAME_FIELD_FILLCOLOR, DataTypes.INT) |
471 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
472 |
|
473 |
ID_FIELD_STYLE = featureType.add(NAME_FIELD_STYLE, DataTypes.INT) |
474 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
475 |
|
476 |
ID_FIELD_ELEVATION = featureType.add(NAME_FIELD_ELEVATION, DataTypes.DOUBLE) |
477 |
.setDefaultValue(Double.valueOf(0)).getIndex(); |
478 |
|
479 |
ID_FIELD_WEIGHT = featureType.add(NAME_FIELD_WEIGHT, DataTypes.DOUBLE) |
480 |
.setDefaultValue(Double.valueOf(0)).getIndex(); |
481 |
|
482 |
ID_FIELD_GROUP = featureType.add(NAME_FIELD_GROUP, DataTypes.INT) |
483 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
484 |
|
485 |
ID_FIELD_ISSHAPE = featureType.add(NAME_FIELD_ISSHAPE, DataTypes.BOOLEAN) |
486 |
.setDefaultValue(Boolean.FALSE).getIndex();
|
487 |
|
488 |
ID_FIELD_ISCOMPLEXSHAPEHEADER = featureType.add(NAME_FIELD_ISCOMPLEXSHAPEHEADER, DataTypes.BOOLEAN) |
489 |
.setDefaultValue(Boolean.FALSE).getIndex();
|
490 |
|
491 |
ID_FIELD_ISHOLE = featureType.add(NAME_FIELD_ISHOLE, DataTypes.BOOLEAN) |
492 |
.setDefaultValue(Boolean.FALSE).getIndex();
|
493 |
|
494 |
ID_FIELD_ISCOMPLEX = featureType.add(NAME_FIELD_ISCOMPLEX, DataTypes.BOOLEAN) |
495 |
.setDefaultValue(Boolean.FALSE).getIndex();
|
496 |
|
497 |
ID_FIELD_SCALE = featureType.add(NAME_FIELD_SCALE, DataTypes.INT) |
498 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
499 |
|
500 |
ID_FIELD_LINKS_COUNT = featureType.add(NAME_FIELD_LINKS_COUNT, DataTypes.INT) |
501 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
502 |
|
503 |
ID_FIELD_LINK_INDEX = featureType.add(NAME_FIELD_LINK_INDEX, DataTypes.INT) |
504 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
505 |
|
506 |
ID_FIELD_LINK_ENTITY = featureType.add(NAME_FIELD_LINK_ENTITY, DataTypes.INT) |
507 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
508 |
|
509 |
ID_FIELD_LINK_TYPE = featureType.add(NAME_FIELD_LINK_TYPE, DataTypes.INT) |
510 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
511 |
|
512 |
ID_FIELD_LINK_MS = featureType.add(NAME_FIELD_LINK_MS, DataTypes.INT) |
513 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
514 |
|
515 |
ID_FIELD_LINK_LENGTH = featureType.add(NAME_FIELD_LINK_LENGTH, DataTypes.INT) |
516 |
.setDefaultValue(Integer.valueOf(0)).getIndex(); |
517 |
|
518 |
ID_FIELD_LINK_DATA = featureType.add(NAME_FIELD_LINK_DATA, DataTypes.STRING, 512)
|
519 |
.setDefaultValue("").getIndex();
|
520 |
|
521 |
ID_FIELD_DATA = featureType.add(NAME_FIELD_DATA, DataTypes.STRING, 512)
|
522 |
.setDefaultValue("").getIndex();
|
523 |
|
524 |
EditableFeatureAttributeDescriptor attr = featureType.add(NAME_FIELD_GEOMETRY, DataTypes.GEOMETRY); |
525 |
attr.setSRS(this.projection);
|
526 |
int geometryTypeToUse = getDGNParameters().getGeometryTypeFilter();
|
527 |
if (getDGNParameters().getGroupBy() != null) { |
528 |
switch (getDGNParameters().getGroupGeometriesOperation()) {
|
529 |
case GROUP_GEOMETRIES_NONE:
|
530 |
case GROUP_GEOMETRIES_UNION:
|
531 |
case GROUP_GEOMETRIES_INTERSECTION:
|
532 |
break;
|
533 |
case GROUP_GEOMETRIES_TOPOINTS:
|
534 |
geometryTypeToUse = Geometry.TYPES.MULTIPOINT; |
535 |
break;
|
536 |
case GROUP_GEOMETRIES_TOLINES:
|
537 |
geometryTypeToUse = Geometry.TYPES.MULTICURVE; |
538 |
break;
|
539 |
case GROUP_GEOMETRIES_TOPOLYGONS:
|
540 |
case GROUP_GEOMETRIES_TOPOLYGONS_FIX:
|
541 |
case GROUP_GEOMETRIES_CONVEXHULL:
|
542 |
geometryTypeToUse = Geometry.TYPES.MULTISURFACE; |
543 |
break;
|
544 |
} |
545 |
} |
546 |
try {
|
547 |
attr.setGeometryType(GeometryLocator.getGeometryManager() |
548 |
.getGeometryType(geometryTypeToUse, subtype)); |
549 |
} catch (Exception e) { |
550 |
attr.setGeometryType(geometryTypeToUse); |
551 |
attr.setGeometrySubType(subtype); |
552 |
} |
553 |
ID_FIELD_GEOMETRY = attr.getIndex(); |
554 |
|
555 |
featureType.setDefaultGeometryAttributeName(NAME_FIELD_GEOMETRY); |
556 |
|
557 |
MAX_FIELD_ID = featureType.size() - 1;
|
558 |
|
559 |
List types = new ArrayList(); |
560 |
types.add(featureType); |
561 |
|
562 |
return types;
|
563 |
} |
564 |
|
565 |
public class Reader { |
566 |
|
567 |
private File file; |
568 |
private IProjection projection;
|
569 |
private List types; |
570 |
private LegendBuilder leyendBuilder;
|
571 |
private AbstractMemoryStoreProvider storeProvider;
|
572 |
private Envelope envelope;
|
573 |
|
574 |
public Reader initialice(AbstractMemoryStoreProvider storeProvider, File file, |
575 |
IProjection projection, LegendBuilder leyendBuilder) { |
576 |
this.storeProvider = storeProvider;
|
577 |
this.file = file;
|
578 |
this.projection = projection;
|
579 |
this.leyendBuilder = leyendBuilder;
|
580 |
if (leyendBuilder != null) { |
581 |
leyendBuilder.initialize(storeProvider); |
582 |
} |
583 |
return this; |
584 |
} |
585 |
|
586 |
public Envelope getEnvelope() {
|
587 |
return this.envelope; |
588 |
} |
589 |
|
590 |
public void begin(FeatureStoreProviderServices storeProviderServices) { |
591 |
|
592 |
types = getFeatureTypes(storeProviderServices); |
593 |
|
594 |
if (leyendBuilder != null) { |
595 |
leyendBuilder.begin(); |
596 |
} |
597 |
|
598 |
} |
599 |
|
600 |
public void end() { |
601 |
if (leyendBuilder != null) { |
602 |
leyendBuilder.end(); |
603 |
} |
604 |
} |
605 |
|
606 |
public List getTypes() { |
607 |
return types;
|
608 |
} |
609 |
|
610 |
public EditableFeatureType getDefaultType() {
|
611 |
return (EditableFeatureType) types.get(0); |
612 |
} |
613 |
|
614 |
public void load() throws DataException, CreateEnvelopeException { |
615 |
switch (getDGNParameters().getLoadMode()) {
|
616 |
case LOAD_MODE_PLAIN:
|
617 |
default:
|
618 |
load_plain(); |
619 |
break;
|
620 |
case LOAD_MODE_GROUP1:
|
621 |
load_group1(); |
622 |
break;
|
623 |
} |
624 |
} |
625 |
|
626 |
public void load_plain() throws DataException { |
627 |
|
628 |
FileWriter xmlfw = null; |
629 |
BufferedWriter xmlbfw = null; |
630 |
|
631 |
this.envelope = null; |
632 |
|
633 |
boolean ignoreZs = getDGNParameters().ignoreZs();
|
634 |
boolean useZAsElevation = getDGNParameters().useZAsElevation();
|
635 |
boolean applyRoundToElevation = getDGNParameters().getApplyRoundToElevation();
|
636 |
double elevationFactor = getDGNParameters().geElevationFactor();
|
637 |
|
638 |
try {
|
639 |
if (getDGNParameters().getXMLFile() != null) { |
640 |
File xmlfile = getDGNParameters().getXMLFile();
|
641 |
try {
|
642 |
xmlfw = new FileWriter(xmlfile); |
643 |
xmlbfw = new BufferedWriter(xmlfw); |
644 |
|
645 |
} catch (Exception ex) { |
646 |
xmlfw = null;
|
647 |
xmlbfw = null;
|
648 |
logger.warn("Can't open xmfile for output (" + xmlfile.getAbsolutePath() + "'.", ex); |
649 |
} |
650 |
if (xmlbfw != null) { |
651 |
try {
|
652 |
xmlbfw.write("<DGN>\n");
|
653 |
} catch (IOException ex) { |
654 |
logger.warn("Can't write to the xml file.", ex);
|
655 |
} |
656 |
} |
657 |
|
658 |
} |
659 |
|
660 |
DGNReader dgnReader = new DGNReader(file.getAbsolutePath(), getDGNParameters().logErrors());
|
661 |
|
662 |
// FIXME: De momento forzamos a que todas las geometr?as que se
|
663 |
// creen sean 3D porque el m?todo getFeatureTypes solo puede
|
664 |
// crear los geometryAttributes como 3D
|
665 |
int subtypeHeader;
|
666 |
subtypeHeader = Geometry.SUBTYPES.GEOM3D; |
667 |
|
668 |
envelope = geomManager.createEnvelope(subtypeHeader); |
669 |
|
670 |
FeatureType type = getDefaultType().getNotEditableCopy(); |
671 |
|
672 |
int counterOfElement = 0; |
673 |
DGNElemComplexHeader parentElement = null;
|
674 |
|
675 |
double zvalue = 0; |
676 |
|
677 |
for (int id = 0; id < dgnReader.getNumEntities(); id++) { |
678 |
dgnReader.DGNGotoElement(id); |
679 |
|
680 |
DGNElemCore elemento = dgnReader.DGNReadElement(); |
681 |
if (elemento == null) { |
682 |
continue;
|
683 |
} |
684 |
|
685 |
if (parentElement != null) { |
686 |
counterOfElement++; |
687 |
if (parentElement.getNumElements() < counterOfElement) {
|
688 |
// Ya hemos terminado de recorrer el elemento complejo.
|
689 |
parentElement = null;
|
690 |
} |
691 |
} |
692 |
|
693 |
if (xmlbfw != null) { |
694 |
// Volcamos el elemnto del DGN a fichero en formato XML
|
695 |
try {
|
696 |
xmlbfw.write(dgnReader.DGNDumpElement(dgnReader.getInfo(), elemento)); |
697 |
} catch (IOException ex) { |
698 |
logger.warn("Can't write to the xml file.", ex);
|
699 |
} |
700 |
} |
701 |
|
702 |
if (elemento.isDeleted()) {
|
703 |
// Saltamos los elementos borrados.
|
704 |
continue;
|
705 |
} |
706 |
|
707 |
FeatureProvider data = createFeatureProvider(type); |
708 |
|
709 |
data.set(ID_FIELD_ID, elemento.getID()); |
710 |
data.set(ID_FIELD_TYPE, elemento.getType()); |
711 |
data.set(ID_FIELD_STYPE, elemento.getSType()); |
712 |
data.set(ID_FIELD_LEVEL, elemento.getLevelAsString()); |
713 |
data.set(ID_FIELD_COLOR, elemento.getColor()); |
714 |
data.set(ID_FIELD_FILLCOLOR, elemento.getShapeFillColor()); |
715 |
data.set(ID_FIELD_ENTITY, elemento.getEntityName()); |
716 |
data.set(ID_FIELD_STYLE, elemento.getStyle()); |
717 |
data.set(ID_FIELD_WEIGHT, elemento.getWeight()); |
718 |
data.set(ID_FIELD_GROUP, elemento.getGroup()); |
719 |
data.set(ID_FIELD_ELEVATION, elemento.getElevation()); |
720 |
data.set(ID_FIELD_ISCOMPLEXSHAPEHEADER,elemento.isComplexShapeHeader()); |
721 |
data.set(ID_FIELD_ISSHAPE, elemento.isShape()); |
722 |
data.set(ID_FIELD_ISHOLE, elemento.isHole()); |
723 |
data.set(ID_FIELD_ISCOMPLEX, elemento.isComplex()); |
724 |
data.set(ID_FIELD_HEIGHTTEXT, 0);
|
725 |
data.set(ID_FIELD_HEIGHTTEXTRAW, 0);
|
726 |
data.set(ID_FIELD_ROTATIONTEXT, 0);
|
727 |
data.set(ID_FIELD_TEXT, null);
|
728 |
data.set(ID_FIELD_SCALE, dgnReader.getInfo().scale); |
729 |
data.set(ID_FIELD_DATA, elemento.getDataAsHexadecimal()); |
730 |
|
731 |
if (parentElement == null) { |
732 |
data.set(ID_FIELD_PARENT, elemento.getID()); |
733 |
} else {
|
734 |
data.set(ID_FIELD_PARENT, parentElement.getID()); |
735 |
} |
736 |
data.set(ID_FIELD_LINKS_COUNT,dgnReader.DGNGetLinkageCount(elemento)); |
737 |
|
738 |
DGNLink dgnlink = dgnReader.DGNGetLinkage(elemento, |
739 |
getDGNParameters().getLinkFilterIndex(), |
740 |
getDGNParameters().getLinkFilterType(), |
741 |
getDGNParameters().getLinkFilterEntity(), |
742 |
getDGNParameters().getLinkFilterMS(), |
743 |
getDGNParameters().getLinkFilterDataAsPattern() |
744 |
); |
745 |
if (dgnlink != null) { |
746 |
data.set(ID_FIELD_LINK_INDEX, dgnlink.getIndex()); |
747 |
data.set(ID_FIELD_LINK_TYPE, dgnlink.getType()); |
748 |
data.set(ID_FIELD_LINK_ENTITY, dgnlink.getEntityCode()); |
749 |
data.set(ID_FIELD_LINK_MS, dgnlink.getMSLink()); |
750 |
data.set(ID_FIELD_LINK_LENGTH, dgnlink.getLength()); |
751 |
data.set(ID_FIELD_LINK_DATA,dgnlink.getDataAsHexadecimal()); |
752 |
} else {
|
753 |
data.set(ID_FIELD_LINK_INDEX, -1);
|
754 |
data.set(ID_FIELD_LINK_TYPE, 0);
|
755 |
data.set(ID_FIELD_LINK_ENTITY, 0);
|
756 |
data.set(ID_FIELD_LINK_MS, 0);
|
757 |
data.set(ID_FIELD_LINK_LENGTH, 0);
|
758 |
data.set(ID_FIELD_LINK_DATA, "");
|
759 |
} |
760 |
|
761 |
zvalue = 0;
|
762 |
try {
|
763 |
int subtypeElement;
|
764 |
switch (elemento.stype) {
|
765 |
case DGNFileHeader.DGNST_COMPLEX_HEADER:
|
766 |
parentElement = (DGNElemComplexHeader) elemento; |
767 |
counterOfElement = 0;
|
768 |
break;
|
769 |
|
770 |
case DGNFileHeader.DGNST_MULTIPOINT:
|
771 |
DGNElemMultiPoint dgnmultipoint = (DGNElemMultiPoint) elemento; |
772 |
if (dgnmultipoint.isPoint()) {
|
773 |
DGNPoint p = dgnmultipoint.getPoint(0);
|
774 |
Point point = createPoint(p.getX(), p.getY(), ignoreZs ? 0 : p.getZ()); |
775 |
data.setDefaultGeometry(point); |
776 |
zvalue = p.getZ(); |
777 |
} else {
|
778 |
OrientablePrimitive geom = null;
|
779 |
subtypeElement = getGeometrySubType(dgnmultipoint); |
780 |
if (dgnmultipoint.isPolygon()) {
|
781 |
geom = geomManager.createPolygon(subtypeHeader); |
782 |
} else {
|
783 |
geom = geomManager.createLine(subtypeHeader); |
784 |
} |
785 |
|
786 |
// Si es una curva nos saltamos los dos primeros y los dos ultimos vertices.
|
787 |
int first = 0; |
788 |
int numVertices = dgnmultipoint.getNumVertices();
|
789 |
if (dgnmultipoint.isCurve()) {
|
790 |
first = 2;
|
791 |
numVertices = dgnmultipoint.getNumVertices() - 2;
|
792 |
} |
793 |
|
794 |
if (dgnmultipoint.isHole()) {
|
795 |
// Invertimos el orden porque es un agujero
|
796 |
for (int i = numVertices - 2; i >= first; i--) { |
797 |
DGNPoint p = dgnmultipoint.getVertex(i); |
798 |
zvalue = p.getZ(); |
799 |
addVertex(geom, p.getX(), p.getY(), ignoreZs ? 0 : zvalue);
|
800 |
} |
801 |
} else {
|
802 |
for (int i = first; i < numVertices; i++) { |
803 |
DGNPoint p = dgnmultipoint.getVertex(i); |
804 |
zvalue = p.getZ(); |
805 |
addVertex(geom, p.getX(), p.getY(), ignoreZs ? 0 : zvalue);
|
806 |
} |
807 |
} |
808 |
data.setDefaultGeometry(geom); |
809 |
} |
810 |
break;
|
811 |
|
812 |
case DGNFileHeader.DGNST_ARC:
|
813 |
DGNElemArc dgnarc = (DGNElemArc) elemento; |
814 |
|
815 |
// La definici?n de arco de MicroStation es distinta a la de Java.
|
816 |
// En el dgn el origen se entiende que es el centro del arco,
|
817 |
// y a la hora de crear un Arc2D las 2 primeras coordenadas son
|
818 |
// la esquina inferior izquierda del rect?ngulo que rodea al arco.
|
819 |
// 1.- Creamos la elipse sin rotaci?n.
|
820 |
// 2.- Creamos el arco
|
821 |
// 3.- Rotamos el resultado
|
822 |
AffineTransform mT =
|
823 |
AffineTransform.getRotateInstance(
|
824 |
Math.toRadians(dgnarc.rotation),
|
825 |
dgnarc.origin.x, dgnarc.origin.y); |
826 |
|
827 |
Arc2D.Double elArco = new Arc2D.Double( |
828 |
dgnarc.origin.x - dgnarc.primary_axis, |
829 |
dgnarc.origin.y - dgnarc.secondary_axis, |
830 |
2.0 * dgnarc.primary_axis,
|
831 |
2.0 * dgnarc.secondary_axis,
|
832 |
-dgnarc.startang, -dgnarc.sweepang, |
833 |
Arc2D.OPEN);
|
834 |
|
835 |
zvalue = dgnarc.origin.getZ(); |
836 |
|
837 |
PathIterator pathIterator = elArco.getPathIterator(null); |
838 |
IGeneralPathX elShapeArc = geomManager.createGeneralPath( |
839 |
IGeneralPathX.WIND_EVEN_ODD, |
840 |
pathIterator |
841 |
); |
842 |
|
843 |
// Transformamos el GeneralPahtX porque si transformamos
|
844 |
// elArco nos lo convierte a GeneralPath y nos guarda las coordenadas en float,
|
845 |
// con la correspondiente p?rdida de precisi?n
|
846 |
elShapeArc.transform(mT); |
847 |
|
848 |
OrientablePrimitive geom = null;
|
849 |
subtypeElement = getGeometrySubType(dgnarc); |
850 |
if (dgnarc.isSurface()) {
|
851 |
geom = geomManager.createPolygon(subtypeElement); |
852 |
} else {
|
853 |
geom = geomManager.createLine(subtypeElement); |
854 |
} |
855 |
for( int i=0; i<elShapeArc.getNumCoords(); i++ ) { |
856 |
double[] coords = elShapeArc.getCoordinatesAt(i); |
857 |
if( ignoreZs || subtypeElement == Geometry.SUBTYPES.GEOM2D || subtypeElement == Geometry.SUBTYPES.GEOM2DM) {
|
858 |
geom.addVertex(coords[0], coords[1]); |
859 |
} else {
|
860 |
geom.addVertex(coords[0], coords[1],zvalue); |
861 |
} |
862 |
|
863 |
} |
864 |
data.setDefaultGeometry(geom); |
865 |
break;
|
866 |
|
867 |
case DGNFileHeader.DGNST_TEXT:
|
868 |
DGNElemText dgntext = (DGNElemText) elemento; |
869 |
subtypeElement = getGeometrySubType(dgntext); |
870 |
Point point = (Point) geomManager.create(TYPES.POINT, subtypeHeader); |
871 |
point.setCoordinateAt(0, dgntext.getPoint().getX());
|
872 |
point.setCoordinateAt(1, dgntext.getPoint().getY());
|
873 |
if (subtypeHeader == Geometry.SUBTYPES.GEOM3D) {
|
874 |
if(subtypeElement == Geometry.SUBTYPES.GEOM2D){
|
875 |
point.setCoordinateAt(2, 0); |
876 |
} else {
|
877 |
point.setCoordinateAt(2, dgntext.getPoint().getZ());
|
878 |
} |
879 |
} |
880 |
|
881 |
data.set(ID_FIELD_HEIGHTTEXT, dgntext.getHeight()); |
882 |
data.set(ID_FIELD_HEIGHTTEXTRAW,dgntext.getRawHeight()); |
883 |
data.set(ID_FIELD_ROTATIONTEXT,dgntext.getRotation()); |
884 |
data.set(ID_FIELD_TEXT, dgntext.getText()); |
885 |
|
886 |
data.setDefaultGeometry(point); |
887 |
break;
|
888 |
|
889 |
default:
|
890 |
break;
|
891 |
|
892 |
} // switch
|
893 |
} catch (Exception ex) { |
894 |
logger.warn("Can't process element", ex);
|
895 |
} |
896 |
if (useZAsElevation) {
|
897 |
if (!DGNStoreProvider.equals(elevationFactor, 1, 0.00001)) { |
898 |
zvalue = zvalue * elevationFactor; |
899 |
} |
900 |
if (applyRoundToElevation) {
|
901 |
zvalue = Math.round(zvalue);
|
902 |
} |
903 |
data.set(ID_FIELD_ELEVATION, zvalue); |
904 |
} |
905 |
addFeature(data, dgnReader); |
906 |
} // for
|
907 |
|
908 |
EditableFeatureType featureType = storeProvider.getFeatureStore().getDefaultFeatureType().getCopy().getEditable(); |
909 |
FeatureAttributeDescriptor fad = (FeatureAttributeDescriptor) featureType.get(featureType.getDefaultGeometryAttributeName()); |
910 |
featureType.remove(fad.getName()); |
911 |
EditableFeatureAttributeDescriptor efad = featureType.add(fad.getName(), fad.getType(), fad.getSize()); |
912 |
efad.setDefaultValue(fad.getDefaultValue()); |
913 |
|
914 |
GeometryType gty = null;
|
915 |
|
916 |
gty = geomManager.getGeometryType(fad.getGeomType().getType(),subtypeHeader); |
917 |
|
918 |
efad.setGeometryType(gty); |
919 |
|
920 |
efad.setPrecision(fad.getPrecision()); |
921 |
featureType.setDefaultGeometryAttributeName(fad.getName()); |
922 |
|
923 |
|
924 |
if (xmlbfw != null) { |
925 |
try {
|
926 |
xmlbfw.write("</DGN>\n");
|
927 |
} catch (IOException ex) { |
928 |
logger.warn("Can't write to the xml file.", ex);
|
929 |
} |
930 |
} |
931 |
|
932 |
} catch (Exception ex) { |
933 |
logger.warn("Can't process DGN file '" + getFullName() + ".",ex); |
934 |
throw new LoadException(ex, getFullName()); |
935 |
} finally {
|
936 |
IOUtils.closeQuietly(xmlbfw); |
937 |
IOUtils.closeQuietly(xmlfw); |
938 |
} |
939 |
|
940 |
} |
941 |
|
942 |
private int getGeometrySubType(DGNElemCore element) { |
943 |
if (getDGNParameters().force2D()) {
|
944 |
return Geometry.SUBTYPES.GEOM2D;
|
945 |
} |
946 |
return element.is3D() ? Geometry.SUBTYPES.GEOM3D : Geometry.SUBTYPES.GEOM2D;
|
947 |
} |
948 |
|
949 |
private void addVertex(OrientablePrimitive geom, double x, double y, |
950 |
double z) {
|
951 |
if (geom.getDimension() == 2) { |
952 |
geom.addVertex(x, y); |
953 |
} else {
|
954 |
geom.addVertex(x, y, z); |
955 |
} |
956 |
} |
957 |
|
958 |
private void fillRow(Object[] row, DGNElemCore elemento, DGNElemComplexHeader parentElement, DGNReader dgnReader) { |
959 |
row[ID_FIELD_HEIGHTTEXT] = new Double(0); |
960 |
row[ID_FIELD_HEIGHTTEXTRAW] = new Double(0); |
961 |
row[ID_FIELD_ROTATIONTEXT] = new Double(0); |
962 |
row[ID_FIELD_TEXT] = null;
|
963 |
|
964 |
row[ID_FIELD_ID] = elemento.getID(); |
965 |
row[ID_FIELD_TYPE] = elemento.getType(); |
966 |
row[ID_FIELD_STYPE] = elemento.getSType(); |
967 |
row[ID_FIELD_LEVEL] = elemento.getLevelAsString(); |
968 |
row[ID_FIELD_COLOR] = elemento.getColor(); |
969 |
row[ID_FIELD_FILLCOLOR] = elemento.getShapeFillColor(); |
970 |
row[ID_FIELD_ENTITY] = elemento.getEntityName(); |
971 |
row[ID_FIELD_STYLE] = elemento.getStyle(); |
972 |
row[ID_FIELD_WEIGHT] = elemento.getWeight(); |
973 |
row[ID_FIELD_GROUP] = elemento.getGroup(); |
974 |
row[ID_FIELD_ELEVATION] = elemento.getElevation(); |
975 |
row[ID_FIELD_ISCOMPLEXSHAPEHEADER] = elemento.isComplexShapeHeader(); |
976 |
row[ID_FIELD_ISSHAPE] = elemento.isShape(); |
977 |
row[ID_FIELD_ISHOLE] = elemento.isHole(); |
978 |
row[ID_FIELD_ISCOMPLEX] = elemento.isComplex(); |
979 |
row[ID_FIELD_PARENT] = elemento.getID(); |
980 |
if (parentElement != null) { |
981 |
row[ID_FIELD_PARENT] = parentElement.getID(); |
982 |
} |
983 |
row[ID_FIELD_SCALE] = dgnReader.getInfo().scale; |
984 |
|
985 |
} |
986 |
|
987 |
public void load_group1() throws DataException, CreateEnvelopeException { |
988 |
|
989 |
this.envelope = null; |
990 |
|
991 |
FileWriter xmlfw = null; |
992 |
BufferedWriter xmlbfw = null; |
993 |
if (getDGNParameters().getXMLFile() != null) { |
994 |
File xmlfile = getDGNParameters().getXMLFile();
|
995 |
try {
|
996 |
xmlfw = new FileWriter(xmlfile); |
997 |
xmlbfw = new BufferedWriter(xmlfw); |
998 |
|
999 |
} catch (Exception ex) { |
1000 |
xmlfw = null;
|
1001 |
xmlbfw = null;
|
1002 |
logger.warn("Can't open xmfile for output ("+ xmlfile.getAbsolutePath() + "'.", ex); |
1003 |
} |
1004 |
if (xmlbfw != null) { |
1005 |
try {
|
1006 |
xmlbfw.write("<DGN>\n");
|
1007 |
} catch (IOException ex) { |
1008 |
logger.warn("Can't write to the xml file.", ex);
|
1009 |
} |
1010 |
} |
1011 |
|
1012 |
} |
1013 |
DGNReader dgnReader = new DGNReader(file.getAbsolutePath());
|
1014 |
if (dgnReader.getInfo().dimension == 2) { |
1015 |
envelope = geomManager.createEnvelope(Geometry.SUBTYPES.GEOM2D); |
1016 |
} else {
|
1017 |
envelope = geomManager.createEnvelope(SUBTYPES.GEOM3D); |
1018 |
} |
1019 |
|
1020 |
FeatureType type = getDefaultType().getNotEditableCopy(); |
1021 |
int fTypeSize = type.size();
|
1022 |
Object[] auxRow = new Object[fTypeSize]; |
1023 |
Object[] cellRow = new Object[fTypeSize]; |
1024 |
Object[] complexRow = new Object[fTypeSize]; |
1025 |
|
1026 |
boolean bElementoCompuesto = false; |
1027 |
boolean bEsPoligono = false; |
1028 |
boolean bInsideCell = false; |
1029 |
boolean bFirstHoleEntity = false; |
1030 |
boolean bConnect = false; // Se usa para que los pol?gonos cierren |
1031 |
// bien cuando son formas compuestas
|
1032 |
// int contadorSubElementos = 0;
|
1033 |
// int numSubElementos = 0;
|
1034 |
int complex_index_fill_color = -1; |
1035 |
int nClass; // Para filtrar los elementos de construcci?n, etc. |
1036 |
IGeneralPathX elementoCompuesto = geomManager.createGeneralPath(IGeneralPathX.WIND_EVEN_ODD, null);
|
1037 |
|
1038 |
int counterOfElement = 0; |
1039 |
DGNElemComplexHeader parentElement = null;
|
1040 |
|
1041 |
for (int id = 0; id < dgnReader.getNumEntities(); id++) { |
1042 |
dgnReader.DGNGotoElement(id); |
1043 |
|
1044 |
DGNElemCore elemento = dgnReader.DGNReadElement(); |
1045 |
if (parentElement != null) { |
1046 |
counterOfElement++; |
1047 |
if (parentElement.getNumElements() < counterOfElement) {
|
1048 |
// Ya hemos terminado de recorrer el elemento complejo.
|
1049 |
parentElement = null;
|
1050 |
} |
1051 |
} |
1052 |
|
1053 |
if (xmlbfw != null && elemento != null) { |
1054 |
// Volcamos el elemnto del DGN a fichero en formato XML
|
1055 |
try {
|
1056 |
xmlbfw.write(dgnReader.DGNDumpElement(dgnReader.getInfo(), elemento)); |
1057 |
} catch (IOException ex) { |
1058 |
logger.warn("Can't write to the xml file.", ex);
|
1059 |
} |
1060 |
} |
1061 |
|
1062 |
nClass = 0;
|
1063 |
fillRow(auxRow, elemento, parentElement, dgnReader); |
1064 |
auxRow[ID_FIELD_HEIGHTTEXT] = new Double(0); |
1065 |
auxRow[ID_FIELD_ROTATIONTEXT] = new Double(0); |
1066 |
auxRow[ID_FIELD_TEXT] = null;
|
1067 |
|
1068 |
if (elemento.properties != 0) { |
1069 |
nClass = elemento.properties & DGNFileHeader.DGNPF_CLASS; |
1070 |
} |
1071 |
|
1072 |
if ((elemento != null) && (elemento.deleted == 0) |
1073 |
&& (nClass == 0)) // Leer un elemento |
1074 |
{ |
1075 |
|
1076 |
// if ((elemento.element_id > 3800) && (elemento.element_id < 3850))
|
1077 |
// dgnReader.DGNDumpElement(dgnReader.getInfo(),elemento,"");
|
1078 |
if ((elemento.stype == DGNFileHeader.DGNST_MULTIPOINT)
|
1079 |
|| (elemento.stype == DGNFileHeader.DGNST_ARC) |
1080 |
|| (elemento.stype == DGNFileHeader.DGNST_CELL_HEADER) |
1081 |
|| (elemento.stype == DGNFileHeader.DGNST_SHARED_CELL_DEFN) |
1082 |
|| (elemento.stype == DGNFileHeader.DGNST_COMPLEX_HEADER)) { |
1083 |
if (elemento.complex != 0) { |
1084 |
bElementoCompuesto = true;
|
1085 |
} else {
|
1086 |
if (bElementoCompuesto) {
|
1087 |
if (bInsideCell) {
|
1088 |
auxRow[ID_FIELD_ENTITY] = cellRow[ID_FIELD_ENTITY]; |
1089 |
} else {
|
1090 |
auxRow = complexRow; |
1091 |
} |
1092 |
addShape(createMultiCurve(elementoCompuesto), |
1093 |
auxRow, type, dgnReader); |
1094 |
|
1095 |
if (bEsPoligono) {
|
1096 |
if (complex_index_fill_color != -1) { |
1097 |
auxRow[ID_FIELD_COLOR] = complex_index_fill_color; |
1098 |
} |
1099 |
|
1100 |
addShape( |
1101 |
createMultiSurface(elementoCompuesto), |
1102 |
auxRow, type, dgnReader); |
1103 |
} |
1104 |
|
1105 |
elementoCompuesto = geomManager.createGeneralPath(IGeneralPathX.WIND_EVEN_ODD, null);
|
1106 |
} |
1107 |
|
1108 |
bElementoCompuesto = false;
|
1109 |
bEsPoligono = false;
|
1110 |
bConnect = false;
|
1111 |
|
1112 |
bInsideCell = false;
|
1113 |
} |
1114 |
} |
1115 |
|
1116 |
switch (elemento.stype) {
|
1117 |
case DGNFileHeader.DGNST_SHARED_CELL_DEFN:
|
1118 |
bInsideCell = true;
|
1119 |
fillRow(cellRow, elemento, parentElement, dgnReader); |
1120 |
cellRow[ID_FIELD_ID] = elemento.element_id; |
1121 |
cellRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
|
1122 |
cellRow[ID_FIELD_COLOR] = elemento.color; |
1123 |
cellRow[ID_FIELD_ENTITY] = "Shared Cell";
|
1124 |
|
1125 |
break;
|
1126 |
|
1127 |
case DGNFileHeader.DGNST_CELL_HEADER:
|
1128 |
bInsideCell = true;
|
1129 |
|
1130 |
fillRow(cellRow, elemento, parentElement, dgnReader); |
1131 |
cellRow[ID_FIELD_ID] = elemento.element_id; |
1132 |
cellRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
|
1133 |
cellRow[ID_FIELD_COLOR] = elemento.color; |
1134 |
cellRow[ID_FIELD_ENTITY] = "Cell";
|
1135 |
complex_index_fill_color = dgnReader.DGNGetShapeFillInfo(elemento); |
1136 |
break;
|
1137 |
|
1138 |
case DGNFileHeader.DGNST_COMPLEX_HEADER:
|
1139 |
|
1140 |
// bElementoCompuesto = true;
|
1141 |
// contadorSubElementos = 0;
|
1142 |
DGNElemComplexHeader psComplexHeader = (DGNElemComplexHeader) elemento; |
1143 |
|
1144 |
parentElement = psComplexHeader; |
1145 |
counterOfElement = parentElement.getNumElements(); |
1146 |
|
1147 |
// numSubElementos = psComplexHeader.numelems;
|
1148 |
fillRow(complexRow, elemento, parentElement, dgnReader); |
1149 |
complexRow[ID_FIELD_ID] = elemento.element_id; |
1150 |
complexRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
|
1151 |
complexRow[ID_FIELD_COLOR] = elemento.color; |
1152 |
complexRow[ID_FIELD_ENTITY] = "Complex";
|
1153 |
|
1154 |
if (psComplexHeader.type == DGNFileHeader.DGNT_COMPLEX_SHAPE_HEADER) {
|
1155 |
bEsPoligono = true;
|
1156 |
|
1157 |
// Si es un agujero, no conectamos con el anterior
|
1158 |
if ((psComplexHeader.properties & 0x8000) != 0) { |
1159 |
bFirstHoleEntity = true;
|
1160 |
} else {
|
1161 |
// Miramos si tiene color de relleno
|
1162 |
// complex_index_fill_color = -1;
|
1163 |
// if (elemento.attr_bytes > 0) {
|
1164 |
complex_index_fill_color = dgnReader.DGNGetShapeFillInfo(elemento); |
1165 |
|
1166 |
// }
|
1167 |
} |
1168 |
|
1169 |
bConnect = true;
|
1170 |
} else {
|
1171 |
bEsPoligono = false;
|
1172 |
bConnect = false;
|
1173 |
} |
1174 |
|
1175 |
break;
|
1176 |
|
1177 |
case DGNFileHeader.DGNST_MULTIPOINT:
|
1178 |
|
1179 |
// OJO: Si lo que viene en este multipoint es un
|
1180 |
// elemento con type=11 (curve), se trata de una "parametric
|
1181 |
// spline curve". La vamos a tratar como si no fuera
|
1182 |
// curva, pero seg?n la documentaci?n, los 2 primeros puntos
|
1183 |
// y los 2 ?ltimos puntos definen "endpoint derivatives" y NO se muestran.
|
1184 |
// TODAV?A HAY UN PEQUE?O FALLO CON EL FICHERO
|
1185 |
// dgn-sample.dgn, pero lo dejo por ahora.
|
1186 |
// Es posible que tenga que ver con lo de los arcos
|
1187 |
// (arco distorsionado), que todav?a no est? metido.
|
1188 |
DGNElemMultiPoint psLine = (DGNElemMultiPoint) elemento; |
1189 |
fillRow(auxRow, elemento, parentElement, dgnReader); |
1190 |
auxRow[ID_FIELD_ID] = elemento.element_id; |
1191 |
auxRow[ID_FIELD_ENTITY] = "Multipoint";
|
1192 |
auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
|
1193 |
auxRow[ID_FIELD_COLOR] = elemento.color; |
1194 |
|
1195 |
if ((psLine.num_vertices == 2) |
1196 |
&& (psLine.vertices[0].x == psLine.vertices[1].x) |
1197 |
&& (psLine.vertices[0].y == psLine.vertices[1].y)) { |
1198 |
auxRow[ID_FIELD_ENTITY] = "Point";
|
1199 |
addShape( |
1200 |
createPoint(psLine.vertices[0].x,
|
1201 |
psLine.vertices[0].y,
|
1202 |
psLine.vertices[0].z),
|
1203 |
auxRow, |
1204 |
type, dgnReader); |
1205 |
} else {
|
1206 |
IGeneralPathX elShape = geomManager.createGeneralPath(IGeneralPathX.WIND_EVEN_ODD, null);
|
1207 |
|
1208 |
if (psLine.type == DGNFileHeader.DGNT_CURVE) {
|
1209 |
psLine.num_vertices = psLine.num_vertices - 4;
|
1210 |
|
1211 |
for (int aux_n = 0; aux_n < psLine.num_vertices; aux_n++) { |
1212 |
psLine.vertices[aux_n] = psLine.vertices[aux_n + 2];
|
1213 |
} |
1214 |
} |
1215 |
|
1216 |
if ((psLine.type == DGNFileHeader.DGNT_SHAPE)
|
1217 |
&& ((psLine.properties & 0x8000) != 0)) { |
1218 |
// Invertimos el orden porque es un agujero
|
1219 |
elShape.moveTo( |
1220 |
psLine.vertices[psLine.num_vertices - 1].x,
|
1221 |
psLine.vertices[psLine.num_vertices - 1].y);
|
1222 |
|
1223 |
for (int i = psLine.num_vertices - 2; i >= 0; i--) { |
1224 |
elShape.lineTo(psLine.vertices[i].x, |
1225 |
psLine.vertices[i].y); |
1226 |
} |
1227 |
} else {
|
1228 |
elShape.moveTo(psLine.vertices[0].x,
|
1229 |
psLine.vertices[0].y);
|
1230 |
|
1231 |
for (int i = 1; i < psLine.num_vertices; i++) { |
1232 |
elShape.lineTo(psLine.vertices[i].x, |
1233 |
psLine.vertices[i].y); |
1234 |
} |
1235 |
} |
1236 |
|
1237 |
if ((psLine.vertices[0].x == psLine.vertices[psLine.num_vertices - 1].x) |
1238 |
&& (psLine.vertices[0].y == psLine.vertices[psLine.num_vertices - 1].y)) { |
1239 |
// Lo a?adimos tambi?n como pol?gono
|
1240 |
bEsPoligono = true;
|
1241 |
|
1242 |
// Miramos si tiene color de relleno
|
1243 |
if (elemento.attr_bytes > 0) { |
1244 |
elemento.color = dgnReader.DGNGetShapeFillInfo(elemento); |
1245 |
|
1246 |
if (elemento.color != -1) { |
1247 |
auxRow[ID_FIELD_COLOR] = elemento.color; |
1248 |
} |
1249 |
} |
1250 |
|
1251 |
if (elemento.complex == 0) { |
1252 |
addShape(createSurface(elShape), auxRow, |
1253 |
type, dgnReader); |
1254 |
} |
1255 |
} |
1256 |
|
1257 |
if (elemento.complex != 0) { |
1258 |
// Si es un agujero o
|
1259 |
// es la primera entidad del agujero, lo
|
1260 |
// a?adimos sin unir al anterior
|
1261 |
if (bFirstHoleEntity
|
1262 |
|| ((psLine.type == DGNFileHeader.DGNT_SHAPE) && ((psLine.properties & 0x8000) != 0))) { |
1263 |
elementoCompuesto.append(elShape.getPathIterator(null), false); |
1264 |
bFirstHoleEntity = false;
|
1265 |
} else {
|
1266 |
elementoCompuesto.append(elShape.getPathIterator(null),
|
1267 |
bConnect); |
1268 |
} |
1269 |
} else {
|
1270 |
addShape(createMultiCurve(elShape), auxRow, |
1271 |
type, dgnReader); |
1272 |
} |
1273 |
} |
1274 |
|
1275 |
break;
|
1276 |
|
1277 |
case DGNFileHeader.DGNST_ARC:
|
1278 |
|
1279 |
// dgnReader.DGNDumpElement(dgnReader.getInfo(),
|
1280 |
// elemento,"");
|
1281 |
DGNElemArc psArc = (DGNElemArc) elemento; |
1282 |
|
1283 |
// La definici?n de arco de MicroStation es distinta a
|
1284 |
// la de Java.
|
1285 |
// En el dgn el origin se entiende que es el centro del
|
1286 |
// arco,
|
1287 |
// y a la hora de crear un Arc2D las 2 primeras
|
1288 |
// coordenadas son
|
1289 |
// la esquina inferior izquierda del rect?ngulo que
|
1290 |
// rodea al arco.
|
1291 |
// 1.- Creamos la elipse sin rotaci?n.
|
1292 |
// 2.- Creamos el arco
|
1293 |
// 3.- Rotamos el resultado
|
1294 |
AffineTransform mT = AffineTransform.getRotateInstance( |
1295 |
Math.toRadians(psArc.rotation), psArc.origin.x,
|
1296 |
psArc.origin.y); |
1297 |
|
1298 |
// mT.preConcatenate(AffineTransform.getScaleInstance(100.0,100.0));
|
1299 |
Arc2D.Double elArco = new Arc2D.Double(psArc.origin.x |
1300 |
- psArc.primary_axis, psArc.origin.y |
1301 |
- psArc.secondary_axis, |
1302 |
2.0 * psArc.primary_axis,
|
1303 |
2.0 * psArc.secondary_axis, -psArc.startang,
|
1304 |
-psArc.sweepang, Arc2D.OPEN);
|
1305 |
|
1306 |
// Ellipse2D.Double elArco = new
|
1307 |
// Ellipse2D.Double(psArc.origin.x - psArc.primary_axis,
|
1308 |
// psArc.origin.y - psArc.secondary_axis,2.0 *
|
1309 |
// psArc.primary_axis, 2.0 * psArc.secondary_axis);
|
1310 |
IGeneralPathX elShapeArc = geomManager.createGeneralPath( |
1311 |
IGeneralPathX.WIND_EVEN_ODD, |
1312 |
elArco.getPathIterator(null)
|
1313 |
); |
1314 |
|
1315 |
// Transformamos el GeneralPahtX porque si transformamos
|
1316 |
// elArco nos lo convierte
|
1317 |
// a GeneralPath y nos guarda las coordenadas en float,
|
1318 |
// con la correspondiente p?rdida de precisi?n
|
1319 |
elShapeArc.transform(mT); |
1320 |
|
1321 |
if (dgnReader.getInfo().dimension == 3) { |
1322 |
// Aqu? podr?amos hacer cosas con la coordenada Z
|
1323 |
} |
1324 |
|
1325 |
fillRow(auxRow, elemento, parentElement, dgnReader); |
1326 |
auxRow[ID_FIELD_ID] = elemento.element_id; |
1327 |
auxRow[ID_FIELD_ENTITY] = "Arc";
|
1328 |
auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
|
1329 |
auxRow[ID_FIELD_COLOR] = elemento.color; |
1330 |
|
1331 |
/*
|
1332 |
* Line2D.Double ejeMayor = new
|
1333 |
* Line2D.Double(psArc.origin.x - psArc.primary_axis,
|
1334 |
* psArc.origin.y, psArc.origin.x + psArc.primary_axis,
|
1335 |
* psArc.origin.y);
|
1336 |
*
|
1337 |
* lyrLines.addShape(new
|
1338 |
* FShape(FConstant.SHAPE_TYPE_POLYLINE, new
|
1339 |
* GeneralPathX(ejeMayor)), auxRow);
|
1340 |
*/
|
1341 |
// lyrLines.addShape(new
|
1342 |
// FShape(FConstant.SHAPE_TYPE_POLYLINE, elShapeArc),
|
1343 |
// auxRow);
|
1344 |
if (elemento.complex != 0) { |
1345 |
// Esto es una posible fuente de fallos si detr?s de
|
1346 |
// una elipse vienen m?s cosas pegadas. Deber?amos
|
1347 |
// volver a conectar una vez pasada la elipse.
|
1348 |
if (elemento.type == DGNFileHeader.DGNT_ELLIPSE) {
|
1349 |
bConnect = false;
|
1350 |
} |
1351 |
|
1352 |
// SI LA ELIPSE ES UN AGUJERO, SE A?ADE SIN PEGAR
|
1353 |
// Y EL ELEMENTO ES UN POLIGONO
|
1354 |
if (bFirstHoleEntity
|
1355 |
|| ((elemento.type == DGNFileHeader.DGNT_SHAPE) && ((elemento.properties & 0x8000) != 0))) { |
1356 |
elementoCompuesto.append(elShapeArc.getPathIterator(null), false); |
1357 |
bFirstHoleEntity = false;
|
1358 |
} else {
|
1359 |
elementoCompuesto.append(elShapeArc.getPathIterator(null), bConnect);
|
1360 |
} |
1361 |
} else {
|
1362 |
addShape(createMultiCurve(elShapeArc), auxRow, |
1363 |
type, dgnReader); |
1364 |
|
1365 |
if (psArc.type == DGNFileHeader.DGNT_ELLIPSE) {
|
1366 |
addShape(createSurface(elShapeArc), auxRow, |
1367 |
type, dgnReader); |
1368 |
} |
1369 |
} |
1370 |
|
1371 |
break;
|
1372 |
|
1373 |
case DGNFileHeader.DGNST_TEXT:
|
1374 |
|
1375 |
DGNElemText psText = (DGNElemText) elemento; |
1376 |
Geometry elShapeTxt = createPoint(psText.origin.x, psText.origin.y, |
1377 |
psText.origin.z); |
1378 |
|
1379 |
fillRow(auxRow, elemento, parentElement, dgnReader); |
1380 |
auxRow[ID_FIELD_ID] = elemento.element_id; |
1381 |
auxRow[ID_FIELD_ENTITY] = "Text";
|
1382 |
auxRow[ID_FIELD_LAYER] = String.valueOf(elemento.level);
|
1383 |
auxRow[ID_FIELD_COLOR] = elemento.color; |
1384 |
auxRow[ID_FIELD_HEIGHTTEXT] = psText.height_mult; |
1385 |
auxRow[ID_FIELD_HEIGHTTEXTRAW] = psText.height_raw; |
1386 |
auxRow[ID_FIELD_ROTATIONTEXT] = psText.rotation; |
1387 |
auxRow[ID_FIELD_TEXT] = psText.string; // .trim();
|
1388 |
addShape(elShapeTxt, auxRow, type, dgnReader); |
1389 |
break;
|
1390 |
|
1391 |
/*
|
1392 |
* default:
|
1393 |
* dgnReader.DGNDumpElement(dgnReader.getInfo(),
|
1394 |
* elemento, "");
|
1395 |
*/
|
1396 |
} // switch
|
1397 |
} // if
|
1398 |
} // for
|
1399 |
|
1400 |
if (bElementoCompuesto) {
|
1401 |
if (bInsideCell) {
|
1402 |
auxRow = cellRow; |
1403 |
} else {
|
1404 |
auxRow = complexRow; |
1405 |
} |
1406 |
|
1407 |
addShape(createMultiCurve(elementoCompuesto), auxRow, type, |
1408 |
dgnReader); |
1409 |
|
1410 |
if (bEsPoligono) {
|
1411 |
if (complex_index_fill_color != -1) { |
1412 |
auxRow[ID_FIELD_COLOR] = complex_index_fill_color; |
1413 |
} |
1414 |
|
1415 |
addShape(createSurface(elementoCompuesto), auxRow, type, |
1416 |
dgnReader); |
1417 |
} |
1418 |
} |
1419 |
|
1420 |
if (xmlbfw != null) { |
1421 |
try {
|
1422 |
xmlbfw.write("</DGN>\n");
|
1423 |
} catch (IOException ex) { |
1424 |
logger.warn("Can't write to the xml file.", ex);
|
1425 |
} |
1426 |
IOUtils.closeQuietly(xmlbfw); |
1427 |
IOUtils.closeQuietly(xmlfw); |
1428 |
} |
1429 |
|
1430 |
} |
1431 |
|
1432 |
private Geometry createMultiSurface(IGeneralPathX elementoCompuesto)
|
1433 |
throws DataException {
|
1434 |
try {
|
1435 |
return geomManager.createMultiSurface(
|
1436 |
(GeneralPathX) elementoCompuesto, |
1437 |
SUBTYPES.GEOM2D |
1438 |
); |
1439 |
} catch (CreateGeometryException e) {
|
1440 |
throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException( |
1441 |
e); |
1442 |
} |
1443 |
|
1444 |
} |
1445 |
|
1446 |
private Point createPoint(double x, double y, double z) |
1447 |
throws DataException {
|
1448 |
Point point;
|
1449 |
int subtype = SUBTYPES.GEOM3D;
|
1450 |
if (getDGNParameters().force2D()) {
|
1451 |
subtype = SUBTYPES.GEOM2D; |
1452 |
} |
1453 |
try {
|
1454 |
point = (Point) geomManager.create(TYPES.POINT, subtype);
|
1455 |
} catch (CreateGeometryException e) {
|
1456 |
throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(e); |
1457 |
} |
1458 |
point.setCoordinates(new double[] { x, y, z }); |
1459 |
|
1460 |
return point;
|
1461 |
} |
1462 |
|
1463 |
private void addFeature(FeatureProvider data, DGNReader dgnReader) throws DataException { |
1464 |
|
1465 |
addFeatureProvider(data); |
1466 |
Geometry geometry = data.getDefaultGeometry(); |
1467 |
if (geometry != null) { |
1468 |
if (this.envelope == null) { |
1469 |
this.envelope = geometry.getEnvelope();
|
1470 |
} else {
|
1471 |
this.envelope.add(geometry.getEnvelope());
|
1472 |
} |
1473 |
} |
1474 |
if (this.leyendBuilder != null) { |
1475 |
this.leyendBuilder.process(data, dgnReader);
|
1476 |
} |
1477 |
} |
1478 |
|
1479 |
private void addShape(Geometry geometry, Object[] auxRow, |
1480 |
FeatureType type, DGNReader dgnReader) throws DataException {
|
1481 |
|
1482 |
FeatureProvider data = createFeatureProvider(type); |
1483 |
for (int i = 0; i < type.size(); i++) { |
1484 |
data.set(i, auxRow[i]); |
1485 |
} |
1486 |
data.setDefaultGeometry(geometry); |
1487 |
addFeature(data, dgnReader); |
1488 |
} |
1489 |
|
1490 |
private Geometry createMultiCurve(IGeneralPathX elementoCompuesto)
|
1491 |
throws DataException {
|
1492 |
try {
|
1493 |
return geomManager.createMultiCurve((GeneralPathX) elementoCompuesto,
|
1494 |
SUBTYPES.GEOM2D); |
1495 |
} catch (CreateGeometryException e) {
|
1496 |
throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException( |
1497 |
e); |
1498 |
} |
1499 |
} |
1500 |
|
1501 |
private Geometry createSurface(IGeneralPathX elementoCompuesto)
|
1502 |
throws DataException {
|
1503 |
try {
|
1504 |
return geomManager.createCurve((GeneralPathX) elementoCompuesto,
|
1505 |
SUBTYPES.GEOM2D); |
1506 |
} catch (CreateGeometryException e) {
|
1507 |
throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException( |
1508 |
e); |
1509 |
} |
1510 |
|
1511 |
} |
1512 |
|
1513 |
} |
1514 |
|
1515 |
public boolean closeResourceRequested(ResourceProvider resource) { |
1516 |
return true; |
1517 |
} |
1518 |
|
1519 |
public int getOIDType() { |
1520 |
return DataTypes.LONG;
|
1521 |
} |
1522 |
|
1523 |
public boolean supportsAppendMode() { |
1524 |
return false; |
1525 |
} |
1526 |
|
1527 |
public void append(FeatureProvider featureProvider) { |
1528 |
throw new UnsupportedOperationException(); |
1529 |
} |
1530 |
|
1531 |
public void beginAppend() { |
1532 |
throw new UnsupportedOperationException(); |
1533 |
} |
1534 |
|
1535 |
public void endAppend() { |
1536 |
throw new UnsupportedOperationException(); |
1537 |
} |
1538 |
|
1539 |
public Object createNewOID() { |
1540 |
return new Long(counterNewsOIDs++); |
1541 |
} |
1542 |
|
1543 |
protected void initializeFeatureTypes() throws InitializeException { |
1544 |
try {
|
1545 |
this.open();
|
1546 |
} catch (OpenException e) {
|
1547 |
throw new InitializeException(this.getProviderName(), e); |
1548 |
} |
1549 |
} |
1550 |
|
1551 |
public Envelope getEnvelope() throws DataException { |
1552 |
this.open();
|
1553 |
return (Envelope) this.getDynValue("Envelope"); |
1554 |
} |
1555 |
|
1556 |
/*
|
1557 |
* (non-Javadoc)
|
1558 |
*
|
1559 |
* @see
|
1560 |
* org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
|
1561 |
* gvsig.fmap.dal.resource.spi.ResourceProvider)
|
1562 |
*/
|
1563 |
public void resourceChanged(ResourceProvider resource) { |
1564 |
this.getStoreServices().notifyChange(
|
1565 |
DataStoreNotification.RESOURCE_CHANGED, resource); |
1566 |
} |
1567 |
|
1568 |
public Object getSourceId() { |
1569 |
return this.getDGNParameters().getFile(); |
1570 |
} |
1571 |
|
1572 |
public String getName() { |
1573 |
String name = this.getDGNParameters().getFile().getName(); |
1574 |
int n = name.lastIndexOf("."); |
1575 |
if (n < 1) { |
1576 |
return name;
|
1577 |
} |
1578 |
return name.substring(0, n); |
1579 |
} |
1580 |
|
1581 |
public String getFullName() { |
1582 |
return this.getDGNParameters().getFile().getAbsolutePath(); |
1583 |
} |
1584 |
|
1585 |
public ResourceProvider getResource() {
|
1586 |
return resource;
|
1587 |
} |
1588 |
|
1589 |
public static boolean equals(double a, double b, double precision) { |
1590 |
double v = Math.abs(a - b); |
1591 |
return v < precision;
|
1592 |
} |
1593 |
} |