Statistics
| Revision:

root / trunk / extensions / extAnnotations / src / com / iver / cit / gvsig / fmap / edition / Annotation_EditableAdapter.java @ 13881

History | View | Annotate | Download (13.9 KB)

1

    
2
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
3
 *
4
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 *
22
 *  Generalitat Valenciana
23
 *   Conselleria d'Infraestructures i Transport
24
 *   Av. Blasco Ib??ez, 50
25
 *   46010 VALENCIA
26
 *   SPAIN
27
 *
28
 *      +34 963862235
29
 *   gvsig@gva.es
30
 *      www.gvsig.gva.es
31
 *
32
 *    or
33
 *
34
 *   IVER T.I. S.A
35
 *   Salamanca 50
36
 *   46005 Valencia
37
 *   Spain
38
 *
39
 *   +34 963163400
40
 *   dac@iver.es
41
 */
42

    
43
package com.iver.cit.gvsig.fmap.edition;
44

    
45
import java.awt.Shape;
46
import java.awt.geom.NoninvertibleTransformException;
47
import java.awt.geom.Point2D;
48
import java.awt.geom.Rectangle2D;
49
import java.io.IOException;
50
import java.util.List;
51

    
52
import org.cresques.cts.ICoordTrans;
53

    
54
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
55
import com.hardcode.gdbms.engine.values.NullValue;
56
import com.hardcode.gdbms.engine.values.NumericValue;
57
import com.hardcode.gdbms.engine.values.StringValue;
58
import com.hardcode.gdbms.engine.values.Value;
59
import com.hardcode.gdbms.engine.values.ValueFactory;
60
import com.iver.andami.PluginServices;
61
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
62
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileWriteException;
63
import com.iver.cit.gvsig.fmap.ViewPort;
64
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
65
import com.iver.cit.gvsig.fmap.core.FPoint2D;
66
import com.iver.cit.gvsig.fmap.core.Handler;
67
import com.iver.cit.gvsig.fmap.core.IFeature;
68
import com.iver.cit.gvsig.fmap.core.IGeometry;
69
import com.iver.cit.gvsig.fmap.core.IRow;
70
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
71
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
72
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
73
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
74
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
75
import com.iver.cit.gvsig.fmap.layers.Annotation_Layer;
76
import com.iver.cit.gvsig.fmap.layers.Annotation_Mapping;
77
import com.iver.utiles.StringUtilities;
78
import com.iver.utiles.XMLEntity;
79
import com.vividsolutions.jts.geom.Envelope;
80

    
81

    
82
/**
83
 * Annotation Editable Adapter
84
 *
85
 * @author Vicente Caballero Navarro
86
 */
87
public class Annotation_EditableAdapter extends VectorialEditableAdapter {
88
        private static String DEFAULT_ANNOTATION_TEXT = "default_annotation_text";
89

    
90
        private static String DEFAULT_ANNOTATION_TYPEFONT = "default_annotation_typefont";
91

    
92
        private static String DEFAULT_ANNOTATION_ROTATE = "default_annotation_rotate";
93

    
94
        private static String DEFAULT_ANNOTATION_STYLEFONT = "default_annotation_stylefont";
95

    
96
        private static String DEFAULT_ANNOTATION_HEIGHT = "default_annotation_height";
97

    
98
        private static String DEFAULT_ANNOTATION_COLOR = "default_annotation_color";
99

    
100

    
101

    
102
        private Annotation_Mapping mapping;
103

    
104
    private Annotation_Layer lyrAnnotation;
105

    
106
     public int doAddRow(IRow feat, int sourceType) throws ExpansionFileWriteException, ReadDriverException {
107
                int position = super.doAddRow(feat, sourceType);
108
                PluginServices ps = PluginServices
109
                                .getPluginServices("com.iver.cit.gvsig.annotation");
110
                XMLEntity xml = ps.getPersistentXML();
111
                String newFID=getNewFID();
112
                boolean cancel = fireBeforeRowAdded(sourceType,newFID);
113
                if (cancel)
114
                        return -1;
115
                Value[] values = feat.getAttributes();
116
                if (!(values[0] instanceof NullValue &&
117
                                values[1] instanceof NullValue &&
118
                                values[2] instanceof NullValue &&
119
                                values[3] instanceof NullValue &&
120
                                values[4] instanceof NullValue &&
121
                                values[5] instanceof NullValue)) {
122
                        IGeometry geom;
123
                        geom=((DefaultFeature)feat).getGeometry();
124
                        Shape shape=geom.getInternalShape();
125
                        Handler[] handlers=geom.getHandlers(IGeometry.SELECTHANDLER);
126
                        Point2D h0=handlers[0].getPoint();
127
                        if (!(shape instanceof FPoint2D)) {
128
                                Point2D h1=handlers[1].getPoint();
129
                                double rotation=Math.toDegrees(UtilFunctions.getAngle(h0,h1));
130
                                values[mapping.getColumnRotate()] = ValueFactory.createValue(rotation);
131
                        }
132
                        geom = ShapeFactory.createPoint2D(h0.getX(),h0.getY());
133
                        ((DefaultFeature)feat).setGeometry(geom);
134
                        return position;
135
                }
136

    
137
                int intColor = Annotation_Mapping.DEFAULTCOLOR;
138
                String text = Annotation_Mapping.DEFAULTTEXT;
139
                String type = Annotation_Mapping.DEFAULTTYPEFONT;
140
                int style = Annotation_Mapping.DEFAULTSTYLEFONT;
141
                int height = Annotation_Mapping.DEFAULTHEIGHT;
142
                int rotate = Annotation_Mapping.DEFAULTROTATE;
143

    
144
                if (xml.contains(DEFAULT_ANNOTATION_COLOR)){
145
                        intColor = StringUtilities.string2Color(xml.getStringProperty(DEFAULT_ANNOTATION_COLOR)).getRGB();
146
                        text = xml.getStringProperty(DEFAULT_ANNOTATION_TEXT);
147
                        type = xml.getStringProperty(DEFAULT_ANNOTATION_TYPEFONT);
148
                        style = xml.getIntProperty(DEFAULT_ANNOTATION_STYLEFONT);
149
                        height = xml.getIntProperty(DEFAULT_ANNOTATION_HEIGHT);
150
                        rotate = xml.getIntProperty(DEFAULT_ANNOTATION_ROTATE);
151
                }
152
                values[mapping.getColumnText()] = ValueFactory.createValue(text);
153
                values[mapping.getColumnTypeFont()] = ValueFactory.createValue(type);
154
                values[mapping.getColumnStyleFont()] = ValueFactory.createValue(style);
155
                values[mapping.getColumnHeight()] = ValueFactory.createValue(height);
156
                values[mapping.getColumnRotate()] = ValueFactory.createValue(rotate);
157
                values[mapping.getColumnColor()] = ValueFactory.createValue(intColor);
158
//                IGeometry geom;
159
//                ViewPort vp=lyrAnnotation.getMapContext().getViewPort();
160
//                geom = lyrAnnotation.getTextWrappingGeometry(height, text, rotate,
161
//                                        position,vp);
162
//                feat = new DefaultFeature(geom, values, feat.getID());
163
                return position;
164
        }
165

    
166
    public Annotation_EditableAdapter(Annotation_Layer lyrAnnotation) {
167
        super();
168
        this.mapping = lyrAnnotation.getAnnotatonMapping();
169
        this.lyrAnnotation = lyrAnnotation;
170
    }
171

    
172
    public IRowEdited[] getFeatures(Rectangle2D r, String strEPSG) throws ReadDriverException, ExpansionFileReadException{
173
        // En esta clase suponemos random access.
174
        // Luego tendremos otra clase que sea VectorialEditableDBAdapter
175
        // que reescribir? este m?todo.
176
        Envelope e = FConverter.convertRectangle2DtoEnvelope(r);
177
        List l = index.query(e);
178
        IRowEdited[] feats = new IRowEdited[l.size()];
179

    
180
        try {
181
            for (int index = 0; index < l.size(); index++) {
182
                Integer i = (Integer) l.get(index);
183
                int inverse = getInversedIndex(i.intValue());
184
                feats[index] = getRowAnnotation(inverse);
185
            }
186
        } catch (DriverIOException ex) {
187
                 throw new ReadDriverException(lyrAnnotation.getName(),ex);
188
        }
189

    
190
        return feats;
191
    }
192

    
193
    /*
194
     * (non-Javadoc)
195
     *
196
     * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getRow(int)
197
     */
198
    public IRowEdited getRowAnnotation(int index) throws DriverIOException, ExpansionFileReadException, ReadDriverException {
199
        int calculatedIndex = getCalculatedIndex(index);
200
        Integer integer = new Integer(calculatedIndex);
201

    
202
        // Si no est? en el fichero de expansi?n
203
        DefaultRowEdited edRow = null;
204
        ViewPort vp=lyrAnnotation.getMapContext().getViewPort();
205
               IFeature f = null;
206
        if (!relations.containsKey(integer)) {
207
            f = ova.getFeature(calculatedIndex);
208
        } else {
209
            int num = ((Integer) relations.get(integer)).intValue();
210
            IRowEdited aux = expansionFile.getRow(num);
211
            f = (IFeature) aux.getLinkedRow().cloneRow();
212
        }
213
        String s = f.getID();
214
        Annotation_Mapping mapping = lyrAnnotation.getAnnotatonMapping();
215
        NumericValue vRotation = (NumericValue) f.getAttribute(mapping.getColumnRotate());
216
        NumericValue vHeight = (NumericValue) f.getAttribute(mapping.getColumnHeight());
217
        NumericValue vStyle = (NumericValue) f.getAttribute(mapping.getColumnStyleFont());
218
        StringValue vType = (StringValue) f.getAttribute(mapping.getColumnTypeFont());
219
        Value vText = f.getAttribute(mapping.getColumnText());
220
        start();
221
        IGeometry geom = getShape(index);
222
        stop();
223
        ICoordTrans ct = lyrAnnotation.getCoordTrans();
224
        boolean bMustClone = false;
225
        if (ct != null) {
226
            if (bMustClone) {
227
                geom = geom.cloneGeometry();
228
            }
229
            geom.reProject(ct);
230
        }
231
        geom.transform(vp.getAffineTransform());
232
        IGeometry geom1 = lyrAnnotation.getTextWrappingGeometryInPixels(vHeight.floatValue()*FConstant.FONT_HEIGHT_SCALE_FACTOR,
233
               vText.toString(), vRotation.doubleValue(),vType.getValue(),vStyle.intValue(), index, vp,geom);
234
              try {
235
                        geom1.transform(vp.getAffineTransform().createInverse());
236
                } catch (NoninvertibleTransformException e) {
237
                         throw new ReadDriverException(lyrAnnotation.getName(),e);
238
                }
239
              f = new DefaultFeature(geom1, f.getAttributes(), s);
240
        edRow = new DefaultRowEdited(f,
241
               DefaultRowEdited.STATUS_ORIGINAL, index);
242

    
243
        return edRow;
244

    
245
    }
246
        /**
247
         * Si se intenta modificar una geometr?a original de la capa en edici?n se
248
         * a?ade al fichero de expansi?n y se registra la posici?n en la que se
249
         * a?adi?. Si se intenta modificar una geometria que se encuentra en el
250
         * fichero de expansi?n (por ser nueva o original pero modificada) se invoca
251
         * el m?todo modifyGeometry y se actualiza el ?ndice de la geometria en el
252
         * fichero.
253
         *
254
         * @param calculatedIndex
255
         *            DOCUMENT ME!
256
         * @param feat
257
         *            DOCUMENT ME!
258
         *
259
         * @return position inside ExpansionFile
260
         * @throws ReadDriverException
261
         * @throws ExpansionFileWriteException
262
         * @throws ExpansionFileReadException
263
         *
264
         * @throws IOException
265
         * @throws DriverIOException
266
         */
267
        public int doModifyRow(int calculatedIndex, IRow feat, int sourceType) throws ReadDriverException, ExpansionFileWriteException, ExpansionFileReadException {
268
                boolean cancel = fireBeforeModifyRow(feat, calculatedIndex, sourceType);
269
                if (cancel)
270
                        return -1;
271
                int posAnteriorInExpansionFile = -1;
272
                Integer integer = new Integer(calculatedIndex);
273

    
274
                IFeature featAnt = null;
275
                IGeometry geom;
276
                Value[] values=feat.getAttributes();
277
                geom=((DefaultFeature)feat).getGeometry();
278
                Shape shape=geom.getInternalShape();
279
                Handler[] handlers=geom.getHandlers(IGeometry.SELECTHANDLER);
280
                Point2D h0=handlers[0].getPoint();
281
                if (!(shape instanceof FPoint2D)) {
282
                        Point2D h1=handlers[1].getPoint();
283
                        double rotation=Math.toDegrees(UtilFunctions.getAngle(h0,h1));
284
                        boolean rotate=false;
285
                        if (((NumericValue)values[mapping.getColumnRotate()]).intValue() != (int)rotation ) {
286
                                values[mapping.getColumnRotate()] = ValueFactory.createValue(rotation);
287
                                rotate=true;
288
                        }
289

    
290
                        Point2D h2=handlers[2].getPoint();
291
                        if (!rotate) {
292
                                double height=Math.sqrt(Math.pow(h2.getX()-h1.getX(),2D)+Math.pow(h2.getY()-h1.getY(),2D));
293
//                                double height=Math.abs(h1.getY()-h2.getY());
294
                                boolean isInPixels=((FSymbol)lyrAnnotation.getLegend().getDefaultSymbol()).isFontSizeInPixels();
295
                                double distance=height;
296
                                if (isInPixels) {
297
                                        distance=lyrAnnotation.getMapContext().getViewPort().fromMapDistance(distance);
298
                                }
299
                                values[mapping.getColumnHeight()] = ValueFactory.createValue(distance);
300
                        }
301
                        Point2D h3=handlers[3].getPoint();
302
                        geom = ShapeFactory.createPoint2D(h3.getX(),h3.getY());
303
                }else {
304
                        geom = ShapeFactory.createPoint2D(h0.getX(),h0.getY());
305
                }
306

    
307
                feat = new DefaultFeature(geom, values, feat.getID());
308
                if (!relations.containsKey(integer)) {
309
                        int newPosition = expansionFile.addRow(feat,
310
                                        IRowEdited.STATUS_MODIFIED, actualIndexFields);
311
                        relations.put(integer, new Integer(newPosition));
312

    
313
                        if (sourceType == EditionEvent.GRAPHIC) {
314
                                // Se actualiza el ?ndice espacial
315
                                featAnt = (DefaultFeature) (ova.getFeature(calculatedIndex));
316
                                IGeometry g = featAnt.getGeometry();
317
                                Rectangle2D rAnt = g.getBounds2D();
318
                                Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
319
                                this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
320
                                                + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
321
                                                + rAnt.getHeight()), new Integer(calculatedIndex));
322
                                this.index.insert(new Envelope(r.getX(), r.getX()
323
                                                + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
324
                                                new Integer(calculatedIndex));
325
                        }
326
                } else {
327
                        // Obtenemos el ?ndice en el fichero de expansi?n
328
                        int num = ((Integer) relations.get(integer)).intValue();
329
                        posAnteriorInExpansionFile = num;
330

    
331
                        // Obtenemos la geometr?a para actualiza el ?ndice
332
                        // espacialposteriormente
333
                        featAnt = (IFeature) expansionFile.getRow(num).getLinkedRow();
334

    
335
                        /*
336
                         * Se modifica la geometr?a y nos guardamos el ?ndice dentro del
337
                         * fichero de expansi?n en el que se encuentra la geometr?a
338
                         * modificada
339
                         */
340
                        num = expansionFile.modifyRow(num, feat, actualIndexFields);
341

    
342
                        /*
343
                         * Actualiza la relaci?n del ?ndice de la geometr?a al ?ndice en el
344
                         * fichero de expansi?n.
345
                         */
346
                        relations.put(integer, new Integer(num));
347
                        if (sourceType == EditionEvent.GRAPHIC) {
348
                                // Se modifica el ?ndice espacial
349
                                Rectangle2D rAnt = featAnt.getGeometry().getBounds2D();
350
                                Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
351
                                this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
352
                                                + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
353
                                                + rAnt.getHeight()), new Integer(calculatedIndex));
354
                                this.index.insert(new Envelope(r.getX(), r.getX()
355
                                                + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
356
                                                new Integer(calculatedIndex));
357
                        }
358
                }
359
                isFullExtentDirty = true;
360
                fireAfterModifyRow(calculatedIndex, sourceType);
361
                return posAnteriorInExpansionFile;
362
        }
363

    
364
}