Statistics
| Revision:

gvsig-3d / 2.1 / branches / extrusion / org.gvsig.view3d.lib / org.gvsig.view3d.lib.impl / src / main / java / org / gvsig / view3d / lib / impl / layers / vector / DefaultPointPMLayer.java @ 657

History | View | Annotate | Download (11.1 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright © 2007-2016 gvSIG Association
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., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.view3d.lib.impl.layers.vector;
25

    
26
import java.awt.Color;
27
import java.util.ArrayList;
28

    
29
import org.cresques.cts.IProjection;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

    
33
import org.gvsig.fmap.dal.DataStore;
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureSet;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.geom.Geometry;
39
import org.gvsig.fmap.geom.primitive.Point;
40
import org.gvsig.fmap.mapcontext.layers.FLayer;
41
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
42
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
43
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
44
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.ISimpleMarkerSymbol;
45
import org.gvsig.tools.dispose.DisposableIterator;
46
import org.gvsig.tools.dispose.DisposeUtils;
47
import org.gvsig.view3d.lib.api.E3DElevationModes;
48
import org.gvsig.view3d.lib.api.View3DLocator;
49
import org.gvsig.view3d.lib.api.View3DManager;
50
import org.gvsig.view3d.lib.api.layers.NwwVectorLayer;
51
import org.gvsig.view3d.lib.api.properties.E3DLayerLoadingModes;
52
import org.gvsig.view3d.lib.api.properties.ExtrudedVectorLayerProperties3D;
53
import org.gvsig.view3d.lib.api.properties.LayerProperties3D;
54
import org.gvsig.view3d.lib.api.properties.VectorLayerProperties3D;
55

    
56
import gov.nasa.worldwind.avlist.AVKey;
57
import gov.nasa.worldwind.avlist.AVList;
58
import gov.nasa.worldwind.geom.Position;
59
import gov.nasa.worldwind.render.Material;
60
import gov.nasa.worldwind.render.PointPlacemark;
61
import gov.nasa.worldwind.render.PointPlacemarkAttributes;
62
import gov.nasa.worldwind.render.Renderable;
63
import gov.nasa.worldwind.util.WWUtil;
64

    
65
/**
66
 * A default vector points layer created from a gvisg layer.
67
 * 
68
 * @author Andrea Antonello andrea.antonello@gmail.com
69
 */
70
public class DefaultPointPMLayer extends NwwVectorLayer {
71

    
72
    private static final Logger LOG = LoggerFactory.getLogger(DefaultPointPMLayer.class);
73

    
74
    private FLyrVect vectorLayer;
75

    
76
    private PointPlacemarkAttributes basicMarkerAttributes;
77

    
78
    private LayerProperties3D mLayerProperties;
79

    
80
    private String heightFieldName;
81
    private double verticalExageration = 1.0;
82
    private double constantHeight = 1.0;
83
    private boolean hasConstantHeight = false;
84
    private boolean applyExtrusion = false;
85

    
86
    private Color defaultColor = Color.RED;
87
    private Material fillMaterial = Material.LIGHT_GRAY;
88
    private double markerSize = 1d;
89

    
90
    private E3DElevationModes elevationMode = E3DElevationModes.CLAMP_TO_GROUND;
91

    
92
    public DefaultPointPMLayer(AVList params) {
93
        params = params != null ? params : (AVList) this.getValue(AVKey.CONSTRUCTION_PARAMETERS);
94
        if (params == null) {
95
            LOG.error("Can not load data, no parameters supplied");
96
            throw new IllegalArgumentException();
97
        }
98

    
99
        if (this.getValue(AVKey.CONSTRUCTION_PARAMETERS) == null) {
100
            this.setValue(AVKey.CONSTRUCTION_PARAMETERS, params.copy());
101
            params = (AVList) this.getValue(AVKey.CONSTRUCTION_PARAMETERS);
102
        }
103

    
104
        // if (params.getValue(AVKey.FILE_STORE) == null) {
105
        // setDataFileStore(WorldWind.getDataFileStore());
106
        // }
107

    
108
        String datasetName = params.getStringValue(AVKey.DATASET_NAME);
109
        if (WWUtil.isEmpty(datasetName)) {
110
            LOG.error("Can not load vector data, missing required parameter: {}", AVKey.DATASET_NAME);
111
            throw new IllegalArgumentException();
112
        }
113

    
114
        //   TODO this should be checked in the environment that creates this object: to be removed after review
115
        //
116
        //        mapControl3D = (MapControl3D) params.getValue(DefaultMapControl3D.GVSIG_MAPCONTROL3D);
117
        //
118
        //        if (mapControl3D == null) {
119
        //            LOG.error("Can not load vector data, missing required parameter: {}",
120
        //                DefaultMapControl3D.GVSIG_MAPCONTROL3D);
121
        //            throw new IllegalArgumentException();
122
        //        }
123

    
124
        FLayer layer = (FLayer) params.getValue(E3DLayerLoadingModes.GVSIG_LAYER);
125
        if (layer instanceof FLyrVect) {
126
            vectorLayer = (FLyrVect) layer;
127
            IProjection crsObject = (IProjection) vectorLayer.getFeatureStore().getDynValue(DataStore.METADATA_CRS);
128
            // TODO check CRS compatibility
129

    
130
        } else {
131
            LOG.error("Can not load vector data, missing layer or invalid layer type.");
132
            throw new IllegalArgumentException();
133
        }
134

    
135
        View3DManager manager = View3DLocator.getManager();
136
        mLayerProperties = manager.getLayerProperties(layer, null);
137
        if (mLayerProperties instanceof VectorLayerProperties3D) {
138
            VectorLayerProperties3D properties = (VectorLayerProperties3D) mLayerProperties;
139
            defaultColor = properties.getDefaultColor();
140
            elevationMode = E3DElevationModes.getModeFromValue(properties.getElevationMode());
141

    
142
            Double constantExtrusionHeight = properties.getConstantHeight();
143
            if (constantExtrusionHeight != null) {
144
                // apply constant height
145
                hasConstantHeight = true;
146
                constantHeight = constantExtrusionHeight;
147
            }
148
        }
149
        if (mLayerProperties instanceof ExtrudedVectorLayerProperties3D) {
150
            ExtrudedVectorLayerProperties3D properties = (ExtrudedVectorLayerProperties3D) mLayerProperties;
151
            heightFieldName = properties.getExtrusionHeightField();
152
            applyExtrusion = true;
153
            if (heightFieldName != null) {
154
                verticalExageration = properties.getVerticalExaggeration();
155
            }
156
        }
157

    
158
        ILegend legend = vectorLayer.getLegend();
159
        changeLegend(legend);
160

    
161
        try {
162
            Thread t = new WorkerThread();
163
            t.start();
164
        } catch (Exception e) {
165
            LOG.error("Error loading the data...", e);
166
        }
167
    }
168

    
169
    public class WorkerThread extends Thread {
170

    
171
        public void run() {
172
            addPointsToRender();
173
        }
174
    }
175

    
176
    private void addPointsToRender() {
177
        try {
178

    
179
            ArrayList<Renderable> renderablesList = new ArrayList<>();
180
            FeatureStore pointsStore = vectorLayer.getFeatureStore();
181
            FeatureSet pointsSet = null;
182
            DisposableIterator pointsIterator = null;
183
            try {
184
                pointsSet = pointsStore.getFeatureSet();
185
                pointsIterator = pointsSet.fastIterator();
186

    
187
                while (pointsIterator.hasNext()) {
188
                    Feature pointFeature;
189
                    synchronized (pointsStore) {
190
                        pointFeature = (Feature) pointsIterator.next();
191
                    }
192
                    PointPlacemark marker = makeShape(pointFeature);
193
                    if (marker != null)
194
                        renderablesList.add(marker);
195
                }
196
            } finally {
197
                DisposeUtils.dispose(pointsIterator);
198
                DisposeUtils.dispose(pointsSet);
199
            }
200
            setRenderables(renderablesList);
201
        } catch (DataException e) {
202
            LOG.error("Can not load vector data, missing layer or invalid layer type.");
203
            e.printStackTrace();
204
        }
205
    }
206

    
207
    private PointPlacemark makeShape(Feature pointFeature) {
208
        try {
209
            Geometry geometry = pointFeature.getDefaultGeometry();
210
            if (geometry instanceof Point) {
211
                Point point = (Point) geometry;
212

    
213
                boolean hasZ = point.getDimension() > 2;
214

    
215
                double h = 0.0;
216
                double y = point.getY();
217
                double x = point.getX();
218
                switch (elevationMode) {
219
                case CLAMP_TO_GROUND:
220
                    hasZ = false;
221
                    break;
222
                case RELATIVE_TO_GROUND:
223
                    /*
224
                     * we ignore the 3rd coordinate in that case and continue.
225
                     * The altitude mode will the handle the passed values
226
                     * properly as absolute or relative. 
227
                     */
228
                    hasZ = false;
229
                case ABSOLUTE:
230
                default:
231
                    if (hasConstantHeight) {
232
                        h = constantHeight;
233
                    }
234
                    if (heightFieldName != null) {
235
                        double tmpH = pointFeature.getDouble(heightFieldName);
236
                        h += tmpH;
237
                    }
238
                    break;
239
                }
240
                h *= verticalExageration;
241

    
242
                PointPlacemark marker;
243
                if (hasZ) {
244
                    double z = point.getCoordinateAt(2);
245
                    marker = new PointPlacemark(Position.fromDegrees(y, x, z + h));
246
                } else {
247
                    Position position = Position.fromDegrees(y, x, h);
248
                    marker = new PointPlacemark(position);
249
                }
250

    
251
                marker.setAltitudeMode(elevationMode.getValue());
252
                marker.setLineEnabled(applyExtrusion);
253
                marker.setAttributes(basicMarkerAttributes);
254

    
255
                return marker;
256
            }
257
        } catch (Exception e) {
258
            e.printStackTrace();
259
        }
260
        return null;
261
    }
262

    
263
    @Override
264
    public void changeLegend(ILegend legend) {
265
        ISymbol symbol = legend.getDefaultSymbol();
266
        if (symbol instanceof ISimpleMarkerSymbol) {
267
            ISimpleMarkerSymbol markerSymbol = (ISimpleMarkerSymbol) symbol;
268
            Color fillColor = markerSymbol.getColor();
269
            markerSize = markerSymbol.getSize();
270
            fillMaterial = new Material(fillColor);
271
            // fillOpacity = fillAlpha / 255.0;
272
        } else {
273
            fillMaterial = new Material(defaultColor);
274
            markerSize = 0.3;
275

    
276
        }
277
        if (basicMarkerAttributes == null) {
278
            basicMarkerAttributes = new PointPlacemarkAttributes();
279
        }
280
        Color color = fillMaterial.getDiffuse();
281
        basicMarkerAttributes.setImageColor(color);
282
        Color darkenColor = darkenColor(color);
283
        basicMarkerAttributes.setLineMaterial(new Material(darkenColor));
284
        basicMarkerAttributes.setLineWidth(1d);
285
        basicMarkerAttributes.setUsePointAsDefaultImage(true);
286
        basicMarkerAttributes.setScale(markerSize);
287
    }
288

    
289
}