Ejemplo n.º 1
0
public class SHPStoreProvider extends DBFStoreProvider {
  private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
  private static final Logger logger = LoggerFactory.getLogger(GeometryManager.class);
  public static String NAME = "SHP";
  public static String DESCRIPTION = "SHP file";
  private SHPFile shpFile;
  private ResourceProvider shpResource;
  private ResourceProvider shxResource;

  protected static final String GEOMETRY_ATTIBUTE_NAME = "GEOMETRY";
  protected static final String DYNFIELD_SRSORIGINALPARAMETERS_NAME = "SRSOriginalParameters";
  private static final String DYNCLASS_NAME = "SHPStore";
  protected static DynClass DYNCLASS = null;

  private SHPFeatureWriter writer = null;

  public SHPStoreProvider(SHPStoreParameters params, DataStoreProviderServices storeServices)
      throws InitializeException {
    super(params, storeServices, ToolsLocator.getDynObjectManager().createDynObject(DYNCLASS));
  }

  protected void init(DBFStoreParameters params, DataStoreProviderServices storeServices)
      throws InitializeException {

    SHPStoreParameters shpParams = (SHPStoreParameters) params;
    shpResource = this.createResource(FileResource.NAME, new Object[] {shpParams.getSHPFileName()});
    shpResource.addConsumer(this);

    shxResource = this.createResource(FileResource.NAME, new Object[] {shpParams.getSHXFileName()});
    shxResource.addConsumer(this);

    this.shpFile = new SHPFile(shpParams);
    super.init(params, storeServices);
  }

  protected void resourcesBegin() throws ResourceBeginException {
    super.resourcesBegin();
    this.shpResource.begin();
    this.shxResource.begin();
    // TODO .prj

  }

  protected void resourcesEnd() {
    super.resourcesEnd();
    this.shpResource.end();
    this.shxResource.end();
    // TODO .prj

  }

  /** @throws ResourceNotifyChangesException */
  protected void resourcesNotifyChanges() throws ResourceNotifyChangesException {
    super.resourcesNotifyChanges();
    this.shpResource.notifyChanges();
    this.shxResource.notifyChanges();
    // TODO .prj

  }

  /** @throws ResourceNotifyCloseException */
  protected void resourcesNotifyClose() throws ResourceNotifyCloseException {
    super.resourcesNotifyClose();
    this.shpResource.notifyClose();
    this.shxResource.notifyClose();
    // TODO .prj

  }

  public void dispose() throws CloseException {
    super.dispose();
    this.shpResource.removeConsumer(this);
    this.shxResource.removeConsumer(this);
    this.shpResource = null;
    this.shxResource = null;
    this.writer = null;
    this.shpFile = null;
  }

  /** @throws ResourceNotifyOpenException */
  protected void resourcesOpen() throws ResourceNotifyOpenException {
    super.resourcesOpen();
    this.shpResource.notifyOpen();
    this.shxResource.notifyOpen();
  }

  protected static void registerDynClass() {
    DynObjectManager dynman = ToolsLocator.getDynObjectManager();
    DynClass dynClass;
    DynField field;
    if (DYNCLASS == null) {

      DynClass dbfDynClass = DBFStoreProvider.DYNCLASS;
      dynClass = dynman.add(DYNCLASS_NAME);

      field = dynClass.addDynField(DYNFIELD_SRSORIGINALPARAMETERS_NAME);
      field.setType(DataTypes.STRING);
      field.setDescription("SRS original parameters");

      // The SHP store parameters extend the DBF store parameters
      dynClass.extend(dbfDynClass);

      DYNCLASS = dynClass;
    }
  }

  protected static EditableFeatureAttributeDescriptor addGeometryColumn(EditableFeatureType fType) {

    EditableFeatureAttributeDescriptor attrTmp = null;
    EditableFeatureAttributeDescriptor attr = null;
    Iterator iter = fType.iterator();
    while (iter.hasNext()) {
      attrTmp = (EditableFeatureAttributeDescriptor) iter.next();
      if (attrTmp.getDataType() == DataTypes.GEOMETRY) {
        if (attr != null) {
          // Two geom fields not allowed
          fType.remove(attrTmp.getName());
        } else {
          attr = attrTmp;
          attr.setName(GEOMETRY_ATTIBUTE_NAME);
        }
      }
    }

    if (attr == null) {
      attr = fType.add(GEOMETRY_ATTIBUTE_NAME, DataTypes.GEOMETRY);
      try {
        attr.setDefaultValue(geomManager.createNullGeometry(SUBTYPES.GEOM2D));
      } catch (CreateGeometryException e) {
        logger.error("Error creating the envelope", e);
      }
    }

    fType.setDefaultGeometryAttributeName(attr.getName());
    return attr;
  }

  protected static FeatureType removeGeometryColumn(EditableFeatureType fType) {
    Iterator iter = fType.iterator();
    FeatureAttributeDescriptor attr;
    while (iter.hasNext()) {
      attr = (FeatureAttributeDescriptor) iter.next();
      if (attr.getDataType() == DataTypes.GEOMETRY) {
        iter.remove();
      }
    }
    fType.setDefaultGeometryAttributeName(null);
    return fType.getNotEditableCopy();
  }

  protected EditableFeatureType getTheFeatureType() throws InitializeException {
    EditableFeatureType fType = super.getTheFeatureType();
    try {
      this.open();
      this.resourcesBegin();
    } catch (DataException e) {
      throw new InitializeException(this.getName(), e);
    }
    try {

      EditableFeatureAttributeDescriptor attr = addGeometryColumn(fType);
      attr.setGeometryType(this.shpFile.getGeometryType());
      attr.setGeometrySubType(this.shpFile.getGeometrySubType());
      // String srs = this.getSRSFromPrj(this.shpFile.getSRSParameters());
      // if (srs == null){
      // // TODO petar ??
      // srs = "EPSG:23030";
      // }
      IProjection srs = getShpParameters().getSRS();
      if (srs == null) {
        srs = CRSFactory.getCRS("EPSG:23030");
      }

      attr.setSRS(srs);

      return fType;
    } catch (ReadException e) {
      throw new InitializeException(e);
    } finally {
      this.resourcesEnd();
    }
  }

  private String getSRSFromPrj(String srsParameters) {
    // TODO identificar que SRS hay que usar, ya sea
    // el que se recibe de los parametros o el que
    // conicida con el que se ha encontrado en el
    // prg... y si ninguna de las dos que?
    return null;
  }

  protected SHPStoreParameters getShpParameters() {
    return (SHPStoreParameters) getParameters();
  }

  public String getName() {
    return NAME;
  }

  public boolean allowWrite() {
    return super.allowWrite() && this.shpFile.isEditable();
  }

  /**
   * @param index
   * @param featureType
   * @return
   * @throws ReadException
   */
  protected FeatureProvider getFeatureProviderByIndex(long index, FeatureType featureType)
      throws DataException {
    this.open();
    this.resourcesBegin();
    try {

      FeatureProvider featureProvider = super.getFeatureProviderByIndex(index, featureType);
      featureProvider.setDefaultEnvelope(this.shpFile.getBoundingBox(index));
      return featureProvider;
    } catch (DataException e) {
      throw e;
    } catch (CreateEnvelopeException e) {
      throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(e);
    } finally {
      this.resourcesEnd();
    }
  }

  protected void initFeatureProviderByIndex(
      FeatureProvider featureProvider, long index, FeatureType featureType) throws DataException {
    this.open();
    this.resourcesBegin();
    try {
      super.initFeatureProviderByIndex(featureProvider, index, featureType);
      featureProvider.setDefaultEnvelope(this.shpFile.getBoundingBox(index));
    } catch (CreateEnvelopeException e) {
      throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(e);
    } finally {
      this.resourcesEnd();
    }
  }

  /**
   * @param featureProvider
   * @throws DataException
   */
  protected void loadFeatureProviderByIndex(FeatureProvider featureProvider) throws DataException {
    this.open();
    this.resourcesBegin();
    try {
      long index = ((Long) featureProvider.getOID()).longValue();
      super.loadFeatureProviderByIndex(featureProvider);
      if (featureProvider
              .getType()
              .getIndex(featureProvider.getType().getDefaultGeometryAttributeName())
          >= 0) {
        try {
          featureProvider.setDefaultGeometry(this.shpFile.getGeometry(index));
        } catch (CreateGeometryException e) {
          throw new ReadException(getName(), e);
        }
      }

    } finally {
      this.resourcesEnd();
    }
  }

  protected void loadValue(
      FeatureProvider featureProvider, int rowIndex, FeatureAttributeDescriptor descriptor)
      throws ReadException {
    if (descriptor.getDataType() == DataTypes.GEOMETRY) {
      return;
    } else {
      super.loadValue(featureProvider, rowIndex, descriptor);
    }
  }

  public FeatureProvider createFeatureProvider(FeatureType type) throws DataException {
    FeatureProvider data = new SHPFeatureProvider(this, type);
    return data;
  }

  protected void openFile() throws IOException, DataException {
    super.openFile();
    this.shpFile.open();
  }

  protected void loadMetadataValues() throws DynFieldNotFoundException, ReadException {
    super.loadMetadataValues();

    this.setDynValue(DYNFIELD_SRSORIGINALPARAMETERS_NAME, this.shpFile.getSRSParameters());

    this.setDynValue("DefaultSRS", this.getShpParameters().getSRS());

    this.setDynValue("Envelope", shpFile.getFullExtent());
  }

  protected void closeFile() throws CloseException {
    super.closeFile();
    if (!this.shpFile.isOpen()) {
      return;
    }
    this.shpFile.close();
  }

  public boolean canWriteGeometry(int geometryType, int geometrySubType) throws DataException {
    this.open();
    this.resourcesBegin();
    try {
      return this.shpFile.canWriteGeometry(geometryType);

    } finally {
      this.resourcesEnd();
    }
  }

  public void performChanges(
      Iterator deleteds,
      Iterator inserteds,
      Iterator updateds,
      Iterator originalFeatureTypesUpdated)
      throws PerformEditingException {
    FeatureType fType;
    try {
      fType = this.getStoreServices().getDefaultFeatureType();
    } catch (DataException e) {
      throw new PerformEditingException(this.getName(), e);
    }
    // TODO Comprobar el campo de geometria

    EditableFeatureType dbfFtype = fType.getEditable();

    removeGeometryColumn(dbfFtype);

    try {
      this.resourcesBegin();
    } catch (ResourceBeginException e1) {
      throw new PerformEditingException(this.getName(), e1);
    }

    try {

      FeatureSet set = this.getFeatureStore().getFeatureSet();
      writer = new SHPFeatureWriter(this.getName());

      SHPStoreParameters shpParams = this.getShpParameters();
      SHPStoreParameters tmpParams = (SHPStoreParameters) shpParams.getCopy();
      tmpParams.setDBFFileName(tmpParams.getDBFFileName() + ".tmp");
      tmpParams.setSHPFileName(tmpParams.getSHPFileName() + ".tmp");
      tmpParams.setSHXFileName(tmpParams.getSHXFileName() + ".tmp");

      writer.begin(tmpParams, fType, dbfFtype, set.getSize());

      DisposableIterator iter = set.fastIterator();
      while (iter.hasNext()) {
        Feature feature = (Feature) iter.next();
        writer.append(feature);
      }

      writer.end();

      this.close();
      this.resourceCloseRequest();

      if (!shpParams.getDBFFile().delete()) {
        throw new PerformEditingException(
            this.getName(), new IOException(shpParams.getDBFFileName()));
      }
      if (!shpParams.getSHPFile().delete()) {
        throw new PerformEditingException(
            this.getName(), new IOException(shpParams.getSHPFileName()));
      }
      if (!shpParams.getSHXFile().delete()) {
        throw new PerformEditingException(
            this.getName(), new IOException(shpParams.getSHXFileName()));
      }
      if (!tmpParams.getDBFFile().renameTo(shpParams.getDBFFile())) {
        throw new PerformEditingException(
            this.getName(), new IOException(shpParams.getSHPFileName()));
      }
      if (!tmpParams.getSHPFile().renameTo(shpParams.getSHPFile())) {
        throw new PerformEditingException(
            this.getName(), new IOException(shpParams.getSHPFileName()));
      }
      if (!tmpParams.getSHXFile().renameTo(shpParams.getSHXFile())) {
        throw new PerformEditingException(
            this.getName(), new IOException(shpParams.getSHXFileName()));
      }

      this.resourcesNotifyChanges();
      this.initFeatureType();

    } catch (Exception e) {
      throw new PerformEditingException(this.getName(), e);
    } finally {
      this.resourcesEnd();
    }
  }

  protected void resourceCloseRequest() throws ResourceException {
    super.resourceCloseRequest();
    this.shpResource.closeRequest();
    this.shxResource.closeRequest();
  }

  public Envelope getEnvelope() throws DataException {
    this.open();
    return (Envelope) this.getDynValue("Envelope");
  }

  public void append(FeatureProvider featureProvider) throws DataException {
    this.resourcesBegin();
    try {
      writer.append(this.getStoreServices().createFeature(featureProvider));
    } finally {
      this.resourcesEnd();
    }
  }

  public void beginAppend() throws DataException {
    this.resourcesBegin();
    try {

      FeatureStore store = this.getFeatureStore();
      FeatureType fType = store.getDefaultFeatureType();

      // TODO Comprobar el campo de geometria

      EditableFeatureType dbfFtype = fType.getEditable();

      removeGeometryColumn(dbfFtype);
      FeatureSet set = store.getFeatureSet();

      writer = new SHPFeatureWriter(this.getName());

      writer.begin(getShpParameters(), fType, dbfFtype, set.getSize());
    } finally {
      this.resourcesEnd();
    }
  }

  public void endAppend() throws DataException {
    this.resourcesBegin();
    try {
      writer.end();
      this.resourcesNotifyChanges();
    } finally {
      this.resourcesEnd();
    }
  }

  public Object getSourceId() {
    return this.getShpParameters().getFile();
  }
}
/**
 * LabelingStrategy used when the user wants to use label sizes, rotations, etc. from the values
 * included in fields of the datasource's table
 *
 * @author jaume dominguez faus - [email protected]
 */
public class AttrInTableLabelingStrategy implements ILabelingStrategy, CartographicSupport {
  private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
  private static final org.slf4j.Logger logger = LoggerFactory.getLogger(GeometryManager.class);
  public static final double MIN_TEXT_SIZE = 3;
  private ILabelingMethod method = new DefaultLabelingMethod();
  private IZoomConstraints zoom;
  private FLyrVect layer;
  //	private double unitFactor = 1D;
  private double fixedSize = 10;
  private Color fixedColor;
  private int unit = -1; // (pixel)
  private boolean useFixedSize;
  private boolean useFixedColor;
  private int referenceSystem;
  private boolean isPrinting;
  private double printDPI;
  private String[] usedFields = null;
  private Font font;
  private Color colorFont;
  private String textFieldName;
  private String rotationFieldName;
  private String heightFieldName;
  private String colorFieldName;
  private PrintAttributes properties;

  public ILabelingMethod getLabelingMethod() {
    return this.method;
  }

  public void setLabelingMethod(ILabelingMethod method) {
    this.method = method;
  }

  public IPlacementConstraints getPlacementConstraints() {
    return null; // (automatically handled by the driver)
  }

  public void setPlacementConstraints(IPlacementConstraints constraints) {
    // nothing
  }

  public IZoomConstraints getZoomConstraints() {
    return zoom;
  }

  public void setZoomConstraints(IZoomConstraints constraints) {
    this.zoom = constraints;
  }

  public void draw(
      BufferedImage image, Graphics2D g, ViewPort viewPort, Cancellable cancel, double dpi)
      throws ReadException {
    double scale = viewPort.getScale();
    //		double fontScaleFactor = FConstant.FONT_HEIGHT_SCALE_FACTOR;

    SimpleTextSymbol sym = new SimpleTextSymbol();

    sym.setFont(getFont());

    sym.setUnit(unit);
    sym.setReferenceSystem(referenceSystem);
    if (zoom == null
        || (zoom.isUserDefined()
            && (scale >= zoom.getMaxScale())
            && (scale <= zoom.getMinScale()))) {
      FeatureSet set = null;
      DisposableIterator iterator = null;
      try {
        // limit the labeling to the visible extent
        ArrayList fields = new ArrayList();
        int heightPos = -1;
        int rotationPos = -1;
        int textPos = -1;
        int colorPos = -1;
        int geomPos = -1;

        if (!this.usesFixedSize()) {
          if (getHeightField() != null) {
            heightPos = fields.size();
            fields.add(getHeightField());
          }
        }
        if (getRotationField() != null) {
          rotationPos = fields.size();
          fields.add(getRotationField());
        }
        if (getTextField() != null) {
          textPos = fields.size();
          fields.add(getTextField());
        }

        if (!this.usesFixedColor() && getColorField() != null) {
          colorPos = fields.size();
          fields.add(getColorField());
        }

        FeatureStore featureStore = layer.getFeatureStore();

        geomPos = fields.size();
        String geomName = featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
        fields.add(geomName);

        FeatureQuery featureQuery = featureStore.createFeatureQuery();

        featureQuery.setAttributeNames((String[]) fields.toArray(new String[fields.size()]));
        // TODO no set filter y layer is contained totaly in viewPort
        ContainsEnvelopeEvaluator iee =
            new ContainsEnvelopeEvaluator(
                viewPort.getAdjustedExtent(),
                viewPort.getProjection(),
                featureStore.getDefaultFeatureType(),
                geomName);
        featureQuery.setFilter(iee);

        set = featureStore.getFeatureSet(featureQuery);

        //				ReadableVectorial source = layer.getSource();
        //				SelectableDataSource recordSet = source.getRecordset();
        iterator = set.fastIterator();
        CreateLabelsOperationContext cloc = new CreateLabelsOperationContext();
        cloc.setDublicates(true);
        cloc.setPosition(0);
        while (iterator.hasNext()) {
          if (cancel.isCanceled()) {
            return;
          }
          Feature feature = (Feature) iterator.next();
          //				for(int i=bs.nextSetBit(0); i>=0 && !cancel.isCanceled(); i=bs.nextSetBit(i+1)) {
          //					Value[] vv = recordSet.getRow(i);
          double size;
          Color color = null;
          if (useFixedSize) {
            // uses fixed size
            size = fixedSize; // * fontScaleFactor;
            //					} else if (idHeightField != -1) {
          } else if (heightFieldName != null) {
            // text size is defined in the table
            try {
              //							Object obj=feature.get(idHeightField);
              Object obj = feature.get(heightPos);
              if (obj != null) {
                size = ((Number) obj).doubleValue(); // * fontScaleFactor;
              } else {
                size = 0;
              }
            } catch (ClassCastException ccEx) {
              //							if (!NullValue.class.equals(feature.get(idHeightField).getClass())) {
              if (!NullValue.class.equals(feature.get(heightPos).getClass())) {

                throw new ReadException("Unknown", ccEx);
              }
              // a null value
              //							Logger.getAnonymousLogger().
              //								warning("Null text height value for text
              // '"+feature.get(idTextField).toString()+"'");
              Logger.getAnonymousLogger()
                  .warning(
                      "Null text height value for text '" + feature.get(textPos).toString() + "'");

              continue;
            }
          } else {
            // otherwise will use the size in the symbol
            size = sym.getFont().getSize();
          }

          size =
              CartographicSupportToolkit.getCartographicLength(
                  this, size, viewPort, MapContext.getScreenDPI());
          //													  dpi);
          //								toScreenUnitYAxis(this,
          //												  size,
          //												  viewPort
          //												 );

          if (size <= MIN_TEXT_SIZE) {
            // label is too small to be readable, will be skipped
            // this speeds up the rendering in wider zooms
            continue;
          }

          sym.setFontSize(size);

          if (useFixedColor) {
            color = fixedColor;
            //					} else if (idColorField != -1) {
          } else if (colorFieldName != null) {
            // text size is defined in the table
            try {
              //							color = new Color(feature.getInt(idColorField));
              color = new Color(feature.getInt(colorPos));
            } catch (ClassCastException ccEx) {
              //							if (feature.get(idColorField) != null) {
              if (feature.get(colorPos) != null) {
                throw new ReadException("Unknown", ccEx);
              }
              // a null value
              //							Logger.getAnonymousLogger().
              //								warning(
              //									"Null color value for text '"
              //											+ feature.getString(idTextField)
              //											+ "'");
              Logger.getAnonymousLogger()
                  .warning("Null color value for text '" + feature.getString(textFieldName) + "'");

              continue;
            }
          } else {
            color = sym.getTextColor();
          }

          sym.setTextColor(color);

          double rotation = 0D;
          //					if (idRotationField!= -1) {
          if (rotationFieldName != null) {
            // text rotation is defined in the table
            //						rotation = -Math.toRadians(((Number)
            // feature.get(idRotationField)).doubleValue());
            rotation = -Math.toRadians(((Number) feature.get(rotationPos)).doubleValue());
          }

          Geometry geom = feature.getDefaultGeometry();
          //					Object obj=feature.get(idTextField);
          Object obj = feature.get(textPos);
          if (obj != null) {
            sym.setText(obj.toString());
          }
          sym.setRotation(rotation);

          FLabel[] aux = (FLabel[]) geom.invokeOperation(CreateLabels.CODE, cloc);
          //					FLabel[] aux = geom.createLabels(0, true);
          for (int j = 0; j < aux.length; j++) {
            Point p =
                geomManager.createPoint(
                    aux[j].getOrig().getX(), aux[j].getOrig().getY(), SUBTYPES.GEOM2D);
            p.transform(viewPort.getAffineTransform());
            if (properties == null) {
              sym.draw(g, null, p, cancel);
            } else {
              sym.print(g, null, p, properties);
            }
          }
        }

      } catch (GeometryOperationNotSupportedException e) {
        throw new ReadException("Could not draw annotation in the layer.", e);
      } catch (GeometryOperationException e) {
        throw new ReadException("Could not draw annotation in the layer.", e);
      } catch (BaseException e) {
        throw new ReadException("Could not draw annotation in the layer.", e);
      } finally {
        if (iterator != null) {
          iterator.dispose();
        }
        if (set != null) {
          set.dispose();
        }
      }
    }
  }

  public String getClassName() {
    return getClass().getName();
  }

  public XMLEntity getXMLEntity() {
    XMLEntity xml = new XMLEntity();
    xml.putProperty("className", getClassName());
    xml.putProperty("labelingStrategy", "labelingStrategy");

    try {
      if (getHeightField() != null) {
        xml.putProperty("HeightField", getHeightField());
      }
    } catch (DataException e) {
      Logger.getAnonymousLogger()
          .log(Level.SEVERE, "Acessing TextHeight field.\n" + e.getMessage());
    }

    try {
      if (getColorField() != null) {
        xml.putProperty("ColorField", getColorField());
      }
    } catch (DataException e) {
      Logger.getAnonymousLogger()
          .log(Level.SEVERE, "Acessing ColorField field.\n" + e.getMessage());
    }

    try {
      if (getTextField() != null) {
        xml.putProperty("TextField", getTextField());
      }
    } catch (DataException e) {
      Logger.getAnonymousLogger().log(Level.SEVERE, "Acessing TextField field.\n" + e.getMessage());
    }

    try {
      if (getRotationField() != null) {
        xml.putProperty("RotationField", getRotationField());
      }
    } catch (DataException e) {
      Logger.getAnonymousLogger()
          .log(Level.SEVERE, "Acessing RotationField field.\n" + e.getMessage());
    }

    if (getFont() != null) {
      xml.putProperty("fontSize", getFont().getSize());
      xml.putProperty("fontName", getFont().getName());
      xml.putProperty("fontStyle", getFont().getStyle());
    }
    if (getColorFont() != null) {
      xml.putProperty("Color", StringUtilities.color2String(getColorFont()));
    }
    xml.putProperty("useFixedSize", useFixedSize);
    xml.putProperty("useFixedColor", useFixedColor);
    xml.putProperty("fixedColor", StringUtilities.color2String(fixedColor));
    xml.putProperty("fixedSize", fixedSize);
    xml.putProperty("Unit", unit);
    xml.putProperty("referenceSystem", referenceSystem);
    return xml;
  }

  public String getRotationField() throws DataException {
    return this.rotationFieldName;
  }

  public String getTextField() throws DataException {
    return this.textFieldName;
  }

  public String getHeightField() throws DataException {
    return this.heightFieldName;
  }

  public String getColorField() throws DataException {
    return this.colorFieldName;
  }

  public void setXMLEntity(XMLEntity xml) {
    if (xml.contains("TextField")) {
      setTextField(xml.getStringProperty("TextField"));
    }

    if (xml.contains("HeightField")) {
      setHeightField(xml.getStringProperty("HeightField"));
    }

    if (xml.contains("ColorField")) {
      setColorField(xml.getStringProperty("ColorField"));
    }

    if (xml.contains("RotationField")) {
      setRotationField(xml.getStringProperty("RotationField"));
    }

    if (xml.contains("Unit")) {
      setUnit(xml.getIntProperty("Unit"));
    }

    if (xml.contains("fontName")) {
      Font font =
          new Font(
              xml.getStringProperty("fontName"),
              xml.getIntProperty("fontStyle"),
              xml.getIntProperty("fontSize"));
      setFont(font);
    }
    if (xml.contains("useFixedSize")) {
      useFixedSize = xml.getBooleanProperty("useFixedSize");
      fixedSize = xml.getDoubleProperty("fixedSize");
    }
    if (xml.contains("useFixedColor")) {
      useFixedColor = xml.getBooleanProperty("useFixedColor");
      fixedColor = StringUtilities.string2Color(xml.getStringProperty("fixedColor"));
    }
    if (xml.contains("referenceSystem")) {
      referenceSystem = xml.getIntProperty("referenceSystem");
    }
  }

  public void setTextField(String textFieldName) {
    this.textFieldName = textFieldName;
    this.usedFields = null;
  }

  public void setRotationField(String rotationFieldName) {
    this.rotationFieldName = rotationFieldName;
    this.usedFields = null;
  }

  /**
   * Sets the field that contains the size of the text. The size is computed in meters. To use any
   * other unit, call setUnit(int) with the scale factor from meters (for centimeters, call
   * <b>setUnitFactor(0.01))</b>.
   *
   * @param heightFieldName
   */
  public void setHeightField(String heightFieldName) {
    this.heightFieldName = heightFieldName;
    this.usedFields = null;
  }

  public void setColorField(String colorFieldName) {
    this.colorFieldName = colorFieldName;
  }

  public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, PrintAttributes props)
      throws ReadException {
    this.properties = props;
    draw(null, g, viewPort, cancel, printDPI);
    this.properties = null;
  }

  public void setUsesFixedSize(boolean b) {
    useFixedSize = b;
    this.usedFields = null;
  }

  public boolean usesFixedSize() {
    return useFixedSize;
  }

  public double getFixedSize() {
    return fixedSize;
  }

  public void setFixedSize(double fixedSize) {
    this.fixedSize = fixedSize;
    this.usedFields = null;
  }

  public void setUsesFixedColor(boolean b) {
    useFixedColor = b;
    this.usedFields = null;
  }

  public boolean usesFixedColor() {
    return useFixedColor;
  }

  public Color getFixedColor() {
    return fixedColor;
  }

  public void setFixedColor(Color fixedColor) {
    this.fixedColor = fixedColor;
  }

  public void setUnit(int unitIndex) {
    unit = unitIndex;
  }

  public int getUnit() {
    return unit;
  }

  public String[] getUsedFields() {
    if (this.usedFields == null) {
      List v = new ArrayList(4);
      try {
        if (!this.usesFixedSize()) {
          if (getHeightField() != null) {
            v.add(getHeightField());
          }
        }
        if (getRotationField() != null) {
          v.add(getRotationField());
        }
        if (getTextField() != null) {
          v.add(getTextField());
        }

        if (!this.usesFixedColor() && getColorField() != null) {
          v.add(getColorField());
        }
      } catch (DataException e) {
        Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage());
      }
      this.usedFields = (String[]) v.toArray(new String[v.size()]);
    }
    return this.usedFields;
  }

  public int getReferenceSystem() {
    return referenceSystem;
  }

  public void setReferenceSystem(int referenceSystem) {
    this.referenceSystem = referenceSystem;
  }

  public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
    // not required here
    throw new Error("Undefined in this context");
  }

  public void setCartographicSize(double cartographicSize, Geometry geom) {
    // not required here
    throw new Error("Undefined in this context");
  }

  public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
    // not required here
    throw new Error("Undefined in this context");
  }

  public void setLayer(FLayer layer) throws ReadException {
    this.layer = (FLyrVect) layer;
    FeatureType type;
    try {
      type = this.layer.getFeatureStore().getDefaultFeatureType();
    } catch (DataException e) {
      // FIXME Throw DataException
      throw new ReadException(this.getClass().getName(), e);
    }

    if (textFieldName != null) {
      if (type.getIndex(textFieldName) < 0) {
        // FIXME exception ??
      }
    }
    if (rotationFieldName != null) {
      if (type.getIndex(rotationFieldName) < 0) {
        // FIXME exception ??
      }
    }
    if (heightFieldName != null) {
      if (type.getIndex(heightFieldName) < 0) {
        // FIXME exception ??
      }
    }
    if (colorFieldName != null) {
      if (type.getIndex(colorFieldName) < 0) {
        // FIXME exception ??
      }
    }
  }

  public boolean shouldDrawLabels(double scale) {
    return layer.isWithinScale(scale);
  }

  public Color getColorFont() {
    return colorFont;
  }

  public void setColorFont(Color colorFont) {
    this.colorFont = colorFont;
  }

  public Font getFont() {
    return font;
  }

  public void setFont(Font selFont) {
    this.font = selFont;
  }
}