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