Statistics
| Revision:

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

History | View | Annotate | Download (11.5 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.ICoordTrans;
30
import org.cresques.cts.IProjection;
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

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

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

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

    
74
    private static final Logger LOG = LoggerFactory.getLogger(DefaultPointPMLayer.class);
75

    
76
    private FLyrVect vectorLayer;
77

    
78
    private PointPlacemarkAttributes basicMarkerAttributes;
79

    
80
    private LayerProperties3D mLayerProperties;
81

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

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

    
92
    private E3DElevationModes elevationMode = E3DElevationModes.CLAMP_TO_GROUND;
93

    
94
    private ICoordTrans data2NwwCT;
95

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

    
103
        if (this.getValue(AVKey.CONSTRUCTION_PARAMETERS) == null) {
104
            this.setValue(AVKey.CONSTRUCTION_PARAMETERS, params.copy());
105
            params = (AVList) this.getValue(AVKey.CONSTRUCTION_PARAMETERS);
106
        }
107

    
108
        // if (params.getValue(AVKey.FILE_STORE) == null) {
109
        // setDataFileStore(WorldWind.getDataFileStore());
110
        // }
111

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

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

    
129
        FLayer layer = (FLayer) params.getValue(E3DLayerLoadingModes.GVSIG_LAYER);
130
        if (layer instanceof FLyrVect) {
131
            vectorLayer = (FLyrVect) layer;
132
            IProjection sourcePrj = vectorLayer.getProjection();
133
            if (!sourcePrj.equals(getNwwPrj())) {
134
                data2NwwCT = sourcePrj.getCT(getNwwPrj());
135
            }
136
        } else {
137
            LOG.error("Can not load vector data, missing layer or invalid layer type.");
138
            throw new IllegalArgumentException();
139
        }
140

    
141
        View3DManager manager = View3DLocator.getManager();
142
        mLayerProperties = manager.getLayerProperties(layer, null);
143
        if (mLayerProperties instanceof VectorLayerProperties3D) {
144
            VectorLayerProperties3D properties = (VectorLayerProperties3D) mLayerProperties;
145
            defaultColor = properties.getDefaultColor();
146
            elevationMode = E3DElevationModes.getModeFromValue(properties.getElevationMode());
147

    
148
            Double constantExtrusionHeight = properties.getConstantHeight();
149
            if (constantExtrusionHeight != null) {
150
                // apply constant height
151
                hasConstantHeight = true;
152
                constantHeight = constantExtrusionHeight;
153
            }
154
        }
155
        if (mLayerProperties instanceof ExtrudedVectorLayerProperties3D) {
156
            ExtrudedVectorLayerProperties3D properties = (ExtrudedVectorLayerProperties3D) mLayerProperties;
157
            heightFieldName = properties.getExtrusionHeightField();
158
            applyExtrusion = true;
159
            if (heightFieldName != null) {
160
                verticalExageration = properties.getVerticalExaggeration();
161
            }
162
        }
163

    
164
        updateLegend();
165

    
166
        try {
167
            Thread t = new WorkerThread();
168
            t.start();
169
        } catch (Exception e) {
170
            LOG.error("Error loading the data...", e);
171
        }
172
    }
173

    
174
    public class WorkerThread extends Thread {
175

    
176
        public void run() {
177
            addPointsToRender();
178
        }
179
    }
180

    
181
    private void addPointsToRender() {
182
        try {
183

    
184
            ArrayList<Renderable> renderablesList = new ArrayList<>();
185
            FeatureStore pointsStore = vectorLayer.getFeatureStore();
186
            FeatureSet pointsSet = null;
187
            DisposableIterator pointsIterator = null;
188
            try {
189
                pointsSet = pointsStore.getFeatureSet();
190
                pointsIterator = pointsSet.fastIterator();
191

    
192
                while( pointsIterator.hasNext() ) {
193
                    Feature pointFeature;
194
                    synchronized (pointsStore) {
195
                        pointFeature = (Feature) pointsIterator.next();
196
                    }
197
                    makeShape(renderablesList, pointFeature);
198
                }
199
            } finally {
200
                DisposeUtils.dispose(pointsIterator);
201
                DisposeUtils.dispose(pointsSet);
202
            }
203
            setRenderables(renderablesList);
204
        } catch (DataException e) {
205
            LOG.error("Can not load vector data, missing layer or invalid layer type.");
206
            e.printStackTrace();
207
        }
208
    }
209

    
210
    private void makeShape( ArrayList<Renderable> renderablesList, Feature pointFeature ) {
211
        try {
212
            Geometry geometry = pointFeature.getDefaultGeometry().cloneGeometry();
213
            geometry.reProject(data2NwwCT);
214
            if (geometry instanceof Point) {
215
                Point point = (Point) geometry;
216
                addPointPlaceMark(renderablesList, pointFeature, point);
217
            } else if (geometry instanceof MultiPoint) {
218
                MultiPoint multiPoint = (MultiPoint) geometry;
219
                int pointsCount = multiPoint.getPrimitivesNumber();
220
                for( int i = 0; i < pointsCount; i++ ) {
221
                    Point point = multiPoint.getPointAt(i);
222
                    addPointPlaceMark(renderablesList, pointFeature, point);
223
                }
224
            }
225
        } catch (Exception e) {
226
            e.printStackTrace();
227
        }
228
    }
229

    
230
    private void addPointPlaceMark( ArrayList<Renderable> renderablesList, Feature pointFeature, Point point ) {
231
        boolean hasZ = point.getDimension() > 2;
232

    
233
        double h = 0.0;
234
        double y = point.getY();
235
        double x = point.getX();
236
        switch( elevationMode ) {
237
        case CLAMP_TO_GROUND:
238
            hasZ = false;
239
            break;
240
        case RELATIVE_TO_GROUND:
241
            /*
242
             * we ignore the 3rd coordinate in that case and continue.
243
             * The altitude mode will the handle the passed values
244
             * properly as absolute or relative. 
245
             */
246
            hasZ = false;
247
        case ABSOLUTE:
248
        default:
249
            if (hasConstantHeight) {
250
                h = constantHeight;
251
            }
252
            if (heightFieldName != null) {
253
                double tmpH = pointFeature.getDouble(heightFieldName);
254
                h += tmpH;
255
            }
256
            break;
257
        }
258
        h *= verticalExageration;
259

    
260
        PointPlacemark marker;
261
        if (hasZ) {
262
            double z = point.getCoordinateAt(2);
263
            marker = new PointPlacemark(Position.fromDegrees(y, x, z + h));
264
        } else {
265
            Position position = Position.fromDegrees(y, x, h);
266
            marker = new PointPlacemark(position);
267
        }
268

    
269
        marker.setAltitudeMode(elevationMode.getValue());
270
        marker.setLineEnabled(applyExtrusion);
271
        marker.setAttributes(basicMarkerAttributes);
272
        renderablesList.add(marker);
273
    }
274

    
275
    @Override
276
    public void updateLegend( ) {
277
        ILegend legend = vectorLayer.getLegend();
278
        ISymbol symbol = legend.getDefaultSymbol();
279
        if (symbol instanceof ISimpleMarkerSymbol) {
280
            ISimpleMarkerSymbol markerSymbol = (ISimpleMarkerSymbol) symbol;
281
            Color fillColor = markerSymbol.getColor();
282
            markerSize = markerSymbol.getSize();
283
            fillMaterial = new Material(fillColor);
284
            // fillOpacity = fillAlpha / 255.0;
285
        } else {
286
            fillMaterial = new Material(defaultColor);
287
            markerSize = 0.3;
288

    
289
        }
290
        if (basicMarkerAttributes == null) {
291
            basicMarkerAttributes = new PointPlacemarkAttributes();
292
        }
293
        Color color = fillMaterial.getDiffuse();
294
        basicMarkerAttributes.setImageColor(color);
295
        Color darkenColor = darkenColor(color);
296
        basicMarkerAttributes.setLineMaterial(new Material(darkenColor));
297
        basicMarkerAttributes.setLineWidth(1d);
298
        basicMarkerAttributes.setUsePointAsDefaultImage(true);
299
        basicMarkerAttributes.setScale(markerSize);
300
    }
301

    
302
}