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