package org.geotools.data.dxf.parser; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.PrecisionModel; import java.io.EOFException; import java.io.IOException; import java.util.Vector; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Collections; import org.geotools.data.GeometryType; import org.geotools.data.dxf.entities.DXFEntity; import org.geotools.data.dxf.entities.DXFInsert; import org.geotools.data.dxf.entities.DXFPoint; import org.geotools.data.dxf.header.DXFBlock; import org.geotools.data.dxf.header.DXFBlockReference; import org.geotools.data.dxf.header.DXFBlocks; import org.geotools.data.dxf.header.DXFEntities; import org.geotools.data.dxf.header.DXFHeader; import org.geotools.data.dxf.header.DXFLayer; import org.geotools.data.dxf.header.DXFLineType; import org.geotools.data.dxf.header.DXFTables; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class DXFUnivers implements DXFConstants { private static final Log log = LogFactory.getLog(DXFUnivers.class); public static final PrecisionModel precisionModel = new PrecisionModel(PrecisionModel.FLOATING); public static final int NUM_OF_SEGMENTS = 16; // Minimum number of segments for a circle (also used for arc) public static final double MIN_ANGLE = 2 * Math.PI / NUM_OF_SEGMENTS; // Minimum number of segments for a circle (also used for arc) private Vector<DXFBlockReference> _entForUpdate = new Vector<DXFBlockReference>(); public Vector<DXFTables> theTables = new Vector<DXFTables>(); public Vector<DXFBlock> theBlocks = new Vector<DXFBlock>(); public Vector<DXFEntity> theEntities = new Vector<DXFEntity>(); private DXFHeader _header; private GeometryFactory geometryFactory = null; private Geometry errorGeometry = null; private HashMap insertsFound = new HashMap(); private ArrayList dxfInsertsFilter; private String info = ""; // Used for getInfo(); returns this string with information about the file public DXFUnivers(ArrayList dxfInsertsFilter) { this.dxfInsertsFilter = dxfInsertsFilter; } public boolean isFilteredInsert(String blockName) { return dxfInsertsFilter.contains(blockName); } public void read(DXFLineNumberReader br) throws IOException { DXFCodeValuePair cvp = null; DXFGroupCode gc = null; boolean doLoop = true; while (doLoop) { cvp = new DXFCodeValuePair(); try { gc = cvp.read(br); } catch (DXFParseException ex) { throw new IOException("DXF parse error" + ex.getLocalizedMessage()); } catch (EOFException e) { doLoop = false; break; } switch (gc) { case TYPE: String type = cvp.getStringValue(); if (type.equals(SECTION)) { readSection(br); } break; default: break; } } updateRefBlock(); } public void readSection(DXFLineNumberReader br) throws IOException { DXFCodeValuePair cvp = null; DXFGroupCode gc = null; boolean doLoop = true; while (doLoop) { cvp = new DXFCodeValuePair(); try { gc = cvp.read(br); } catch (DXFParseException ex) { throw new IOException("DXF parse error" + ex.getLocalizedMessage()); } catch (EOFException e) { doLoop = false; break; } switch (gc) { case TYPE: String type = cvp.getStringValue(); if (type.equals(ENDSEC)) { doLoop = false; break; } break; case NAME: String name = cvp.getStringValue(); if (name.equals(HEADER)) { _header = DXFHeader.read(br); if (_header._EXTMAX == null || _header._EXTMIN == null) { _header = new DXFHeader(); } /* construct geometry factory */ geometryFactory = new GeometryFactory(precisionModel, _header._SRID); } else if (name.equals(TABLES)) { DXFTables at = DXFTables.readTables(br, this); theTables.add(at); } else if (name.equals(BLOCKS)) { DXFBlocks ab = DXFBlocks.readBlocks(br, this); theBlocks.addAll(ab.theBlocks); } else if (name.equals(ENTITIES)) { DXFEntities dxfes = DXFEntities.readEntities(br, this); theEntities.addAll(dxfes.theEntities); // toevoegen aan layer doen we even niet, waarschijnlijk niet nodig //if (o != null && o._refLayer != null) { // o._refLayer.theEnt.add(o); //} } break; default: break; } } } public DXFBlock findBlock(String nom) { DXFBlock b = null; for (int i = 0; i < theBlocks.size(); i++) { if (theBlocks.elementAt(i)._name.equals(nom)) { insertsFound.put(nom, true); return theBlocks.elementAt(i); } } return b; } public DXFLayer findLayer(String nom) { DXFLayer l = null; for (int i = 0; i < theTables.size(); i++) { for (int j = 0; j < theTables.elementAt(i).theLayers.size(); j++) { if (theTables.elementAt(i).theLayers.elementAt(j).getName().equals(nom)) { l = theTables.elementAt(i).theLayers.elementAt(j); return l; } } } l = new DXFLayer(nom, DXFColor.getDefaultColorIndex()); if (theTables.size() < 1) { theTables.add(new DXFTables()); } theTables.elementAt(0).theLayers.add(l); return l; } public DXFLineType findLType(String name) { for (int i = 0; i < theTables.size(); i++) { for (int j = 0; j < theTables.elementAt(i).theLineTypes.size(); j++) { if (theTables.elementAt(i).theLineTypes.elementAt(j)._name.equals(name)) { return theTables.elementAt(i).theLineTypes.elementAt(j); } } } return null; } public void addRefBlockForUpdate(DXFBlockReference obj) { _entForUpdate.add(obj); } // Use only once! public void updateRefBlock() { DXFBlockReference bro = null; int numInserts = 0; for (int i = 0; i < _entForUpdate.size(); i++) { bro = _entForUpdate.get(i); boolean isInsert = false; if (bro instanceof DXFInsert) { numInserts++; isInsert = true; } if (!insertsFound.containsKey(bro._blockName)) { insertsFound.put(bro._blockName, false); } DXFBlock b = findBlock(bro._blockName); if (b != null && bro.getType() != GeometryType.UNSUPPORTED) { double x = b._point.X(); double y = b._point.Y(); if (isInsert) { DXFPoint entPoint = ((DXFInsert) bro)._point; x = entPoint._point.getX(); y = entPoint._point.getY(); } Vector<DXFEntity> refBlockEntities = b.theEntities; if (refBlockEntities != null) { Iterator it = refBlockEntities.iterator(); while (it.hasNext()) { // Create clone if blockEntity is a insert DXFEntity e = ((isInsert) ? ((DXFEntity) it.next()).clone() : (DXFEntity) it.next()); if (isInsert) { e.setBase(((DXFInsert) bro)._point.toCoordinate()); e.setAngle(((DXFInsert) bro)._angle); } e.updateGeometry(); theEntities.add(e); } } } else { log.error("Can not update refblock: " + bro.getName() + " - " + bro._blockName + " at " + bro.getStartingLineNumber()); } if (!isInsert) { theEntities.remove(bro); } } // Set information if (_entForUpdate.size() > 0) { info += "Num of Blocks: " + _entForUpdate.size() + " of which Inserts: " + numInserts + "\n"; java.util.HashMap list = new java.util.HashMap(); // Count inserts in updateList for (int i = 0; i < _entForUpdate.size(); i++) { if (_entForUpdate.get(i) instanceof DXFInsert) { DXFInsert fg = (DXFInsert) _entForUpdate.get(i); String name = fg._blockName; if (!list.containsKey(name)) { list.put(name, 1); } else { list.put(name, ((Integer) list.get(name)) + 1); } } } ArrayList arrayList = new ArrayList(list.keySet()); Collections.sort(arrayList); for (java.util.Iterator iter = arrayList.iterator(); iter.hasNext();) { String key = (String) iter.next(); String value = Integer.toString((Integer) list.get(key)); String found = ((Boolean) insertsFound.get(key) ? "" : (isFilteredInsert(key) ? "Filtered" : "Missing")); key = makeTabs(key, 31); value = makeTabs(value, 12); info += key + value + found + "\n"; } } _entForUpdate.removeAllElements(); } public String getInfo() { return info; } public GeometryFactory getGeometryFactory() { if (geometryFactory == null) { geometryFactory = new GeometryFactory(precisionModel); } return geometryFactory; } public void setGeometryFactory(GeometryFactory geometryFactory) { this.geometryFactory = geometryFactory; } public Geometry getErrorGeometry() { if (errorGeometry == null && geometryFactory != null) { errorGeometry = geometryFactory.createPoint(new Coordinate(0.0, 0.0)); } return errorGeometry; } public void setErrorGeometry(Geometry errorGeometry) { this.errorGeometry = errorGeometry; } public static String makeTabs(String text, int length) { for (int i = text.length() - 1; i < length; i++) { text += " "; } return text; } }