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