Statistics
| Revision:

gvsig-3d / 2.1 / trunk / org.gvsig.view3d / org.gvsig.view3d.vector / org.gvsig.view3d.vector.lib / org.gvsig.view3d.vector.lib.impl / src / main / java / org / gvsig / view3d / vector / lib / impl / extrusion / DefaultVectorExtrusionPolygonRenderableLayer.java @ 772

History | View | Annotate | Download (8.69 KB)

1
package org.gvsig.view3d.vector.lib.impl.extrusion;
2

    
3
import java.awt.Color;
4
import java.util.ArrayList;
5
import java.util.List;
6

    
7
import org.apache.commons.lang3.StringUtils;
8
import org.cresques.cts.ICoordTrans;
9

    
10
import org.gvsig.fmap.dal.exception.DataException;
11
import org.gvsig.fmap.dal.feature.Feature;
12
import org.gvsig.fmap.dal.feature.FeatureQuery;
13
import org.gvsig.fmap.dal.feature.FeatureStore;
14
import org.gvsig.fmap.geom.Geometry;
15
import org.gvsig.fmap.geom.Geometry.TYPES;
16
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
17
import org.gvsig.fmap.geom.primitive.Point;
18
import org.gvsig.fmap.geom.primitive.Polygon;
19
import org.gvsig.fmap.geom.primitive.Ring;
20
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
21
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
22
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
23
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
24
import org.gvsig.view3d.vector.lib.api.VectorElevationMode;
25
import org.gvsig.view3d.vector.lib.api.VectorExtrusionLoaderParameters;
26
import org.gvsig.view3d.vector.lib.api.VectorLoaderParameters;
27
import org.gvsig.view3d.vector.lib.impl.AbstractRenderableLayer;
28

    
29
import gov.nasa.worldwind.geom.Position;
30
import gov.nasa.worldwind.render.BasicShapeAttributes;
31
import gov.nasa.worldwind.render.ExtrudedPolygon;
32
import gov.nasa.worldwind.render.Material;
33
import gov.nasa.worldwind.render.Renderable;
34

    
35
public class DefaultVectorExtrusionPolygonRenderableLayer extends AbstractRenderableLayer {
36

    
37
    private BasicShapeAttributes normalShapeAttributes;
38
    private BasicShapeAttributes sideShapeAttributes;
39

    
40
    public DefaultVectorExtrusionPolygonRenderableLayer(VectorLoaderParameters parameters, FeatureStore featureStore,
41
        IVectorLegend legend) {
42
        super(parameters, featureStore, legend);
43
    }
44

    
45
    @Override
46
    protected List<Renderable> getRenderables(Feature feature) {
47

    
48
        double heightFieldValue = 0;
49
        String heightField = ((VectorExtrusionLoaderParameters) parameters).getHeightField();
50
        if (StringUtils.isNoneBlank(heightField)) {
51
            heightFieldValue = feature.getDouble(heightField);
52
        }
53

    
54
        Geometry geom = feature.getDefaultGeometry();
55
        List<Renderable> renderables = new ArrayList<>();
56
        if (geom.getGeometryType().isTypeOf(TYPES.MULTIPOLYGON)) {
57
            MultiPolygon multiPolygon = (MultiPolygon) geom;
58
            for (int i = 0; i < multiPolygon.getPrimitivesNumber(); i++) {
59
                Polygon polygon = (Polygon) multiPolygon.getSurfaceAt(i);
60
                if (polygon.getNumVertices() >= 4) {
61
                    renderables.add(getRenderable(polygon, heightFieldValue));
62
                }
63
            }
64
        } else {
65
            Polygon polygon = (Polygon) geom;
66
            if (polygon.getNumVertices() >= 4) {
67
                renderables.add(getRenderable(polygon, heightFieldValue));
68
            }
69
        }
70
        return renderables;
71
    }
72
    
73
    @Override
74
    protected FeatureQuery getFeatureQuery() throws DataException {
75
        FeatureQuery featureQuery = super.getFeatureQuery();
76
        // Add field height to feature query
77
        String fieldHeight = ((VectorExtrusionLoaderParameters) parameters).getHeightField();
78
        if (StringUtils.isNotBlank(fieldHeight)) {
79
            featureQuery.addAttributeName(fieldHeight);
80
        }
81
        return featureQuery;
82
    }
83

    
84
    private ExtrudedPolygon getRenderable(Polygon polygon, double heightFieldValue) {
85
        ExtrudedPolygon renderable = new ExtrudedPolygon();
86
        boolean hasZ = polygon.getDimension() > 2;
87
        double h = 0.0;
88

    
89
        if (VectorElevationMode.CLAMP_TO_GROUND.equals(parameters.getVectorElevationMode())) {
90
            hasZ = false;
91
        } else {
92
            if (VectorElevationMode.RELATIVE_TO_GROUND.equals(parameters.getVectorElevationMode())) {
93
                hasZ = false;
94
            }
95
            if (parameters.getConstantHeight() != null) {
96
                h = parameters.getConstantHeight();
97
            }
98
        }
99
        h += heightFieldValue;
100
        h *= ((VectorExtrusionLoaderParameters) parameters).getVerticalExaggeration();
101

    
102
        ICoordTrans coordTrans = getCoordTrans(this.parameters.getLayer().getProjection());
103
        List<Position> verticesList = getVertices(polygon, h, hasZ, coordTrans);
104
        renderable.setOuterBoundary(verticesList);
105
        
106
        int numInteriorRings = polygon.getNumInteriorRings();
107
        for (int i = 0; i < numInteriorRings; i++) {
108
            renderable.addInnerBoundary(getInteriorRing(polygon.getInteriorRing(i), hasZ, h));
109
        }
110
        renderable.setAltitudeMode(getAltitudeMode(this.parameters.getVectorElevationMode()));
111
        renderable.setAttributes(getNormalShapeAttributes(legend));
112
        renderable.setSideAttributes(getSideShapeAttributes(legend));
113
        return renderable;
114
    }
115

    
116
    private List<Position> getInteriorRing(Ring interiorRing, boolean hasZ, double h) {
117
        int internalNumVertices = interiorRing.getNumVertices();
118
        List<Position> internalVerticesList = new ArrayList<>(internalNumVertices);
119
        for (int j = 0; j < internalNumVertices; j++) {
120
            Point vertex = interiorRing.getVertex(j);
121
            if (hasZ) {
122
                double z = vertex.getCoordinateAt(2);
123
                internalVerticesList.add(Position.fromDegrees(vertex.getY(), vertex.getX(), z + h));
124
            } else {
125
                internalVerticesList.add(Position.fromDegrees(vertex.getY(), vertex.getX(), h));
126
            }
127
        }
128
        return internalVerticesList;
129
    }
130

    
131
    private BasicShapeAttributes getSideShapeAttributes(IVectorLegend legend) {
132
        
133
        if(this.sideShapeAttributes != null) {
134
            return this.sideShapeAttributes;
135
        }
136
        
137
        Material sideFillMaterial = Material.GRAY;
138
        double fillOpacity = 0.7;
139

    
140
        ISymbol symbol = legend.getDefaultSymbol();
141
        if (symbol instanceof IFillSymbol) {
142
            IFillSymbol fillSymbol = (IFillSymbol) symbol;
143
            Color fillColor = fillSymbol.getFillColor();
144
            int fillAlpha = fillSymbol.getFillAlpha();
145
            Color sideFillColor = darkenColor(fillColor);
146
            sideFillMaterial = new Material(sideFillColor);
147
            fillOpacity = fillAlpha / 255.0;
148
        } else {
149
            sideFillMaterial = new Material(this.parameters.getDefaultColor());
150
            fillOpacity = 0.7;
151
        }
152
        sideShapeAttributes = new BasicShapeAttributes();
153
        sideShapeAttributes.setInteriorMaterial(sideFillMaterial);
154
        sideShapeAttributes.setInteriorOpacity(fillOpacity);
155
        return sideShapeAttributes;
156
    }
157

    
158
    private BasicShapeAttributes getNormalShapeAttributes(IVectorLegend legend) {
159
        
160
        if(this.normalShapeAttributes != null) {
161
            return this.normalShapeAttributes;
162
        }
163
        
164
        Material fillMaterial = Material.LIGHT_GRAY;
165
        Material outlineMaterial = Material.BLACK;
166
        double fillOpacity = 0.7;
167
        double outlineWidth = 2;
168

    
169
        ISymbol symbol = legend.getDefaultSymbol();
170
        if (symbol instanceof IFillSymbol) {
171
            IFillSymbol fillSymbol = (IFillSymbol) symbol;
172
            Color fillColor = fillSymbol.getFillColor();
173
            int fillAlpha = fillSymbol.getFillAlpha();
174
            ILineSymbol outline = fillSymbol.getOutline();
175
            Color lineColor = outline.getColor();
176
            fillMaterial = new Material(fillColor);
177
            outlineMaterial = new Material(lineColor);
178
            fillOpacity = fillAlpha / 255.0;
179
            outlineWidth = outline.getLineWidth();
180
        } else {
181
            outlineMaterial = new Material(this.parameters.getDefaultColor());
182
            fillMaterial = new Material(this.parameters.getDefaultColor());
183
            fillOpacity = 0.7;
184
            outlineWidth = 2;
185
        }
186
        normalShapeAttributes = new BasicShapeAttributes();
187
        normalShapeAttributes.setInteriorMaterial(fillMaterial);
188
        normalShapeAttributes.setInteriorOpacity(fillOpacity);
189
        normalShapeAttributes.setOutlineMaterial(outlineMaterial);
190
        normalShapeAttributes.setOutlineWidth(outlineWidth);
191
        return normalShapeAttributes;
192
    }
193

    
194
    /**
195
     * Slightly darken the supplied color.
196
     * 
197
     * @param color
198
     *            the color to make darker.
199
     * @return the darker color.
200
     */
201
    private Color darkenColor(Color color) {
202
        float factor = 0.8f;
203
        int r = color.getRed();
204
        int g = color.getGreen();
205
        int b = color.getBlue();
206
        return new Color(Math.max((int) (r * factor), 0), Math.max((int) (g * factor), 0),
207
            Math.max((int) (b * factor), 0));
208
    }
209

    
210
    @Override
211
    protected void clearRenderAttributes() {
212
        this.normalShapeAttributes = null;
213
        this.sideShapeAttributes = null;
214
    }
215
}