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 | 766 | llmarques | 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 | 767 | llmarques | import org.cresques.cts.ICoordTrans; |
9 | 766 | llmarques | |
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 | 772 | llmarques | super(parameters, featureStore, legend);
|
43 | 766 | llmarques | } |
44 | |||
45 | @Override
|
||
46 | 767 | llmarques | protected List<Renderable> getRenderables(Feature feature) { |
47 | 766 | llmarques | |
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 | 767 | llmarques | ICoordTrans coordTrans = getCoordTrans(this.parameters.getLayer().getProjection());
|
103 | List<Position> verticesList = getVertices(polygon, h, hasZ, coordTrans); |
||
104 | 766 | llmarques | renderable.setOuterBoundary(verticesList); |
105 | 767 | llmarques | |
106 | 766 | llmarques | 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 | 772 | llmarques | renderable.setAttributes(getNormalShapeAttributes(legend)); |
112 | renderable.setSideAttributes(getSideShapeAttributes(legend)); |
||
113 | 766 | llmarques | 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 | 772 | llmarques | |
133 | if(this.sideShapeAttributes != null) { |
||
134 | return this.sideShapeAttributes; |
||
135 | } |
||
136 | |||
137 | 766 | llmarques | 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 | 772 | llmarques | sideShapeAttributes = new BasicShapeAttributes();
|
153 | sideShapeAttributes.setInteriorMaterial(sideFillMaterial); |
||
154 | sideShapeAttributes.setInteriorOpacity(fillOpacity); |
||
155 | return sideShapeAttributes;
|
||
156 | 766 | llmarques | } |
157 | |||
158 | private BasicShapeAttributes getNormalShapeAttributes(IVectorLegend legend) {
|
||
159 | 772 | llmarques | |
160 | if(this.normalShapeAttributes != null) { |
||
161 | return this.normalShapeAttributes; |
||
162 | } |
||
163 | |||
164 | 766 | llmarques | 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 | 772 | llmarques | normalShapeAttributes = new BasicShapeAttributes();
|
187 | normalShapeAttributes.setInteriorMaterial(fillMaterial); |
||
188 | normalShapeAttributes.setInteriorOpacity(fillOpacity); |
||
189 | normalShapeAttributes.setOutlineMaterial(outlineMaterial); |
||
190 | normalShapeAttributes.setOutlineWidth(outlineWidth); |
||
191 | return normalShapeAttributes;
|
||
192 | 766 | llmarques | } |
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 | 772 | llmarques | return new Color(Math.max((int) (r * factor), 0), Math.max((int) (g * factor), 0), |
207 | 766 | llmarques | Math.max((int) (b * factor), 0)); |
208 | } |
||
209 | 772 | llmarques | |
210 | @Override
|
||
211 | protected void clearRenderAttributes() { |
||
212 | this.normalShapeAttributes = null; |
||
213 | this.sideShapeAttributes = null; |
||
214 | } |
||
215 | 766 | llmarques | } |