package org.geotools.data.dxf.entities; import java.io.EOFException; import java.io.IOException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.geotools.data.dxf.parser.DXFCodeValuePair; import org.geotools.data.dxf.parser.DXFGroupCode; import org.geotools.data.dxf.parser.DXFLineNumberReader; import org.geotools.data.dxf.parser.DXFParseException; /** * Obtain all the Extended Data from dxf entities * * @author rui.travassos * * @see http://www.autodesk.com/techpubs/autocad/acad2000/dxf/index.htm */ public class DXFExtendedData { private static final Log log = LogFactory.getLog(DXFExtendedData.class); protected String appName; protected String layerName; protected List<Object> attributes; protected Double distance, scaleFactor; public DXFExtendedData(String appName, String layerName, List<Object> attributes, Double distance, Double scaleFactor) { this.appName = appName; this.layerName = layerName; this.attributes = attributes; this.distance = distance; this.scaleFactor = scaleFactor; } public DXFExtendedData() { } public static DXFExtendedData getExtendedData(DXFLineNumberReader lnr) throws IOException { DXFExtendedData data = null; String appName = null, layerName = null; List<Object> attributes = new LinkedList<Object>(); Double[] wsDisplacement = new Double[3], wsPostion = new Double[3], reals = new Double[3], wDirection = new Double[3]; Double distance = null, scaleFactor = null; DXFCodeValuePair cvp = null; DXFGroupCode gc = null; int sln = lnr.getLineNumber(); log.debug(">>Enter at line: " + sln); boolean attribute = false; boolean loop = true; while (loop) { cvp = new DXFCodeValuePair(); try { lnr.mark(); gc = cvp.read(lnr); } catch (DXFParseException ex) { throw new IOException("DXF Extended Data parse error" + ex.getLocalizedMessage()); } catch (EOFException e) { loop = false; break; } switch (gc) { case XDATA_APPLICATION_NAME: appName = cvp.getStringValue(); break; case XDATA_LAYER_NAME: appName = cvp.getStringValue(); break; case XDATA_CONTROL_STRING: // start or end the attributes list attribute = !attribute; break; case XDATA_ASCII_STRING: if (attribute) attributes.add(cvp.getStringValue()); break; case XDATA_CHUNK_OF_BYTES: if (attribute) attributes.add(cvp.getBinHexValue()); break; case XDATA_DOUBLE: if (attribute) attributes.add(cvp.getDoubleValue()); break; case XDATA_INT16: if (attribute) attributes.add(cvp.getShortValue()); break; case XDATA_INT32: if (attribute) attributes.add(cvp.getIntValue()); break; case XDATA_DISTANCE: distance = cvp.getDoubleValue(); break; case XDATA_SCALE_FACTOR: scaleFactor = cvp.getDoubleValue(); break; // reals case XDATA_X_1: reals[0] = cvp.getDoubleValue(); break; case XDATA_Y_1: reals[1] = cvp.getDoubleValue(); break; case XDATA_Z_1: reals[2] = cvp.getDoubleValue(); break; // World space position case XDATA_X_2: wsPostion[0] = cvp.getDoubleValue(); break; case XDATA_Y_2: wsPostion[1] = cvp.getDoubleValue(); break; case XDATA_Z_2: wsPostion[2] = cvp.getDoubleValue(); break; // World space displacement case XDATA_X_3: wsDisplacement[0] = cvp.getDoubleValue(); break; case XDATA_Y_3: wsDisplacement[1] = cvp.getDoubleValue(); break; case XDATA_Z_3: wsDisplacement[2] = cvp.getDoubleValue(); break; // World direction case XDATA_X_4: wDirection[0] = cvp.getDoubleValue(); break; case XDATA_Y_4: wDirection[1] = cvp.getDoubleValue(); break; case XDATA_Z_4: wDirection[2] = cvp.getDoubleValue(); break; default: lnr.reset(); int lineNumber = lnr.getLineNumber(); data = new DXFExtendedData(appName, layerName, attributes, distance, scaleFactor); log.debug("Extended data -> " + data.toString()); log.debug(">>Exit at line: " + lineNumber); return data; } } lnr.reset(); data = new DXFExtendedData(appName, layerName, attributes, distance, scaleFactor); log.debug("Extended data -> " + data.toString()); log.debug(">>Exit at line: " + lnr.getLineNumber()); return data; } public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } public String getLayerName() { return layerName; } public void setLayerName(String layerName) { this.layerName = layerName; } public List<Object> getAttributes() { return attributes; } public void setAttributes(List<Object> attributes) { this.attributes = attributes; } public Double getDistance() { return distance; } public void setDistance(Double distance) { this.distance = distance; } public Double getScaleFactor() { return scaleFactor; } public void setScaleFactor(Double scaleFactor) { this.scaleFactor = scaleFactor; } @Override public String toString() { return "DXFExtendedData [appName=" + appName + ", layerName=" + layerName + ", attributes=" + this.toStringAttributes() + ", distance=" + distance + ", scaleFactor=" + scaleFactor + "]"; } public String toStringAttributes() { StringBuilder sb = new StringBuilder(); sb.append("{"); for (Object o : attributes) { try { if (o instanceof String) sb.append((String) o); else if (o instanceof Number) sb.append((Number) o); else sb.append(o.toString()); } catch (Exception e) { log.warn("Parse to string attribute problem. Skipping..."); } finally { sb.append(";"); } } sb.append("}"); return sb.toString(); } public static Map<String, Object> toMap(DXFExtendedData extData) { Map<String, Object> map = null; if (extData != null) { map = new HashMap<String, Object>(); map.put("layerName", extData.layerName); map.put("appName", extData.appName); map.put("attributes", extData.attributes); map.put("distance", extData.distance); map.put("scaleFactor", extData.scaleFactor); } return map; } }