|
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)
|