Revision 457 2.1/trunk/org.gvsig.view3d/org.gvsig.view3d.swing/org.gvsig.view3d.swing.impl/src/main/java/org/gvsig/view3d/swing/impl/data/DefaultLayerConverter.java
DefaultLayerConverter.java | ||
---|---|---|
24 | 24 |
|
25 | 25 |
package org.gvsig.view3d.swing.impl.data; |
26 | 26 |
|
27 |
import gov.nasa.worldwind.WorldWind; |
|
28 | 27 |
import gov.nasa.worldwind.avlist.AVKey; |
29 | 28 |
import gov.nasa.worldwind.avlist.AVList; |
30 | 29 |
import gov.nasa.worldwind.avlist.AVListImpl; |
30 |
import gov.nasa.worldwind.geom.Angle; |
|
31 |
import gov.nasa.worldwind.geom.LatLon; |
|
31 | 32 |
import gov.nasa.worldwind.geom.Sector; |
32 | 33 |
import gov.nasa.worldwind.globes.ElevationModel; |
33 | 34 |
import gov.nasa.worldwind.layers.Layer; |
34 | 35 |
import gov.nasa.worldwind.layers.TiledImageLayer; |
35 |
import gov.nasa.worldwindx.examples.dataimport.DataInstallUtil;
|
|
36 |
import gov.nasa.worldwind.util.WWMath;
|
|
36 | 37 |
|
37 | 38 |
import java.awt.geom.Point2D; |
38 |
import java.io.File; |
|
39 | 39 |
import java.security.MessageDigest; |
40 | 40 |
import java.security.NoSuchAlgorithmException; |
41 | 41 |
|
... | ... | |
46 | 46 |
import org.w3c.dom.Document; |
47 | 47 |
|
48 | 48 |
import org.gvsig.fmap.crs.CRSFactory; |
49 |
import org.gvsig.fmap.dal.coverage.datastruct.Extent; |
|
50 | 49 |
import org.gvsig.fmap.dal.exception.DataException; |
51 |
import org.gvsig.fmap.dal.exception.ReadException; |
|
52 | 50 |
import org.gvsig.fmap.geom.primitive.Envelope; |
53 | 51 |
import org.gvsig.fmap.mapcontext.MapContext; |
54 |
import org.gvsig.fmap.mapcontext.ViewPort; |
|
55 | 52 |
import org.gvsig.fmap.mapcontext.layers.FLayer; |
56 |
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect; |
|
57 |
import org.gvsig.raster.fmap.layers.FLyrRaster; |
|
58 |
import org.gvsig.view3d.swing.api.MapControl3D; |
|
59 | 53 |
import org.gvsig.view3d.swing.impl.DefaultMapControl3D; |
60 | 54 |
|
61 | 55 |
/** |
... | ... | |
64 | 58 |
*/ |
65 | 59 |
public class DefaultLayerConverter implements LayerConverter { |
66 | 60 |
|
67 |
private static final Logger logger = LoggerFactory
|
|
61 |
private static final Logger LOG = LoggerFactory
|
|
68 | 62 |
.getLogger(DefaultLayerConverter.class); |
69 | 63 |
|
70 | 64 |
public Layer convertToLayer(MapContext mapContext, FLayer layer) |
71 | 65 |
throws DataException { |
72 | 66 |
|
73 | 67 |
AVList params = new AVListImpl(); |
74 |
|
|
75 |
// Add Layer MapContext to parameters.
|
|
68 |
|
|
69 |
// Add Layer and MapContext to parameters.
|
|
76 | 70 |
params.setValue(DefaultMapControl3D.GVSIG_MAPCONTEXT, mapContext); |
71 |
params.setValue(DefaultMapControl3D.GVSIG_LAYER, layer); |
|
72 |
|
|
77 | 73 |
createRasterTiledImageLayerParams(layer, params); |
78 |
|
|
74 |
|
|
79 | 75 |
// Create configuration document from parameters. |
80 | 76 |
Document doc = |
81 | 77 |
TiledImageLayer.createTiledImageLayerConfigDocument(params); |
82 |
|
|
78 |
|
|
83 | 79 |
// Copy parameters to avoid problems |
84 | 80 |
AVList paramsLayer = params.copy(); |
85 | 81 |
|
... | ... | |
95 | 91 |
} |
96 | 92 |
|
97 | 93 |
private String getUniqueCacheId(String name) { |
98 |
// TODO Esto es insuficiente. Tener en cuenta m?s propiedades para la generaci?n
|
|
99 |
// del id.
|
|
94 |
// TODO This is not valid. We have to take in account more properties
|
|
95 |
// to get unique cache id
|
|
100 | 96 |
try { |
101 | 97 |
// Create MD5 Hash |
102 | 98 |
MessageDigest digest = |
... | ... | |
113 | 109 |
return hexString.toString(); |
114 | 110 |
|
115 | 111 |
} catch (NoSuchAlgorithmException e) { |
116 |
logger.info("MD5 algorith is not available", e);
|
|
112 |
LOG.warn("MD5 algorith is not available", e);
|
|
117 | 113 |
return name; |
118 | 114 |
} |
119 | 115 |
} |
120 | 116 |
|
121 | 117 |
private void createRasterTiledImageLayerParams(FLayer layer, AVList params) { |
122 | 118 |
|
123 |
// TODO Obtener las propiedades 3D de la capa mediane |
|
124 |
// View3DManager.getProperties3D(layer) |
|
125 |
// y rellenar los parametros con las propiedades definidas. |
|
126 |
|
|
119 |
// TODO Get 3D propeties of layer with View3DManager.getProperties3D(layer) |
|
120 |
// and fill parameters with properties |
|
121 |
|
|
127 | 122 |
if (params == null) { |
128 | 123 |
params = new AVListImpl(); |
129 | 124 |
} |
... | ... | |
131 | 126 |
params.setValue(AVKey.DATASET_NAME, layer.getName()); |
132 | 127 |
params.setValue(AVKey.DATA_CACHE_NAME, |
133 | 128 |
getUniqueCacheId(layer.getName())); |
129 |
params.setValue(AVKey.DISPLAY_NAME, layer.getName()); |
|
130 |
params.setValue(AVKey.SERVICE_NAME, "Offline"); |
|
134 | 131 |
|
135 |
File installLocation = |
|
136 |
DataInstallUtil.getDefaultInstallLocation(WorldWind |
|
137 |
.getDataFileStore()); |
|
138 |
params.setValue(AVKey.FILE_STORE_LOCATION, |
|
139 |
installLocation.getAbsolutePath()); |
|
140 |
|
|
141 | 132 |
MapContext mapContext = |
142 | 133 |
(MapContext) params.getValue(DefaultMapControl3D.GVSIG_MAPCONTEXT); |
143 | 134 |
|
... | ... | |
145 | 136 |
try { |
146 | 137 |
sector = getSector(layer, mapContext.getProjection()); |
147 | 138 |
} catch (DataException e) { |
148 |
logger.info("Can't create sector from layer and projection", e);
|
|
139 |
LOG.info("Can't create sector from layer and projection", e);
|
|
149 | 140 |
return; |
150 | 141 |
} |
151 | 142 |
|
152 | 143 |
params.setValue(AVKey.SECTOR, sector); |
144 |
|
|
145 |
// Set resolution of layer |
|
146 |
double[] degreesArray = sector.asDegreesArray(); |
|
147 |
|
|
148 |
// TODO Make configurable by user |
|
149 |
params.setValue(AVKey.WIDTH, |
|
150 |
(int) Math.ceil(((degreesArray[1] - degreesArray[0]) * 360000))); |
|
151 |
params.setValue(AVKey.HEIGHT, |
|
152 |
(int) Math.ceil(((degreesArray[3] - degreesArray[2]) * 360000))); |
|
153 | 153 |
|
154 |
if (layer instanceof FLyrRaster) { |
|
154 |
params.setValue(AVKey.IMAGE_FORMAT, "image/png"); |
|
155 |
params.setValue(AVKey.PIXEL_FORMAT, AVKey.IMAGE); |
|
156 |
params.setValue(AVKey.TEXTURE_FORMAT, "image/dds"); |
|
157 |
params.setValue(AVKey.FORMAT_SUFFIX, ".png"); |
|
158 |
params.setValue(AVKey.AVAILABLE_IMAGE_FORMATS, new String[] { params |
|
159 |
.getValue(AVKey.IMAGE_FORMAT).toString() }); |
|
160 |
params.setValue(AVKey.TILE_ORIGIN, new LatLon(sector.getMinLatitude(), |
|
161 |
sector.getMinLongitude())); |
|
162 |
params.setValue(AVKey.TILE_WIDTH, 512); |
|
163 |
params.setValue(AVKey.TILE_HEIGHT, 512); |
|
155 | 164 |
|
156 |
params.setValue(AVKey.WIDTH, (int) ((FLyrRaster) layer) |
|
157 |
.getDataStore().getWidth()); |
|
158 |
params.setValue(AVKey.HEIGHT, (int) ((FLyrRaster) layer) |
|
159 |
.getDataStore().getHeight()); |
|
165 |
LatLon rasterTileDelta = this.computeRasterTileDelta(params); |
|
166 |
LatLon desiredLevelZeroDelta = this.computeDesiredTileDelta(sector); |
|
167 |
int numLevels = computeNumLevels(desiredLevelZeroDelta, rasterTileDelta); |
|
160 | 168 |
|
161 |
} else if (layer instanceof FLyrVect) { |
|
169 |
params.setValue(AVKey.NUM_LEVELS, numLevels); |
|
170 |
|
|
171 |
double scale = Math.pow(2d, numLevels - 1); |
|
172 |
LatLon levelZeroTileDelta = LatLon.fromDegrees( |
|
173 |
scale * rasterTileDelta.getLatitude().degrees, |
|
174 |
scale * rasterTileDelta.getLongitude().degrees); |
|
175 |
params.setValue(AVKey.LEVEL_ZERO_TILE_DELTA, levelZeroTileDelta); |
|
162 | 176 |
|
163 |
ViewPort viewPort = null; |
|
164 |
try { |
|
165 |
viewPort = (ViewPort) mapContext.getViewPort().clone(); |
|
166 |
viewPort.setEnvelope(((FLyrVect) layer).getFullEnvelope()); |
|
167 |
// viewPort.setImageSize(new Dimension(50000, 50000)); |
|
168 |
} catch (CloneNotSupportedException e) { |
|
169 |
logger.info("Can't clone MapContext viewport: " |
|
170 |
+ mapContext.getViewPort().toString(), e); |
|
171 |
return; |
|
172 |
} catch (ReadException e) { |
|
173 |
logger.info( |
|
174 |
"Can't get full envelope of " + layer.getInfoString(), e); |
|
175 |
return; |
|
176 |
} |
|
177 |
params.setValue(AVKey.NETWORK_RETRIEVAL_ENABLED, false); |
|
178 |
params.setValue(AVKey.USE_MIP_MAPS, true); |
|
179 |
params.setValue(AVKey.USE_TRANSPARENT_TEXTURES, true); |
|
177 | 180 |
|
178 |
params.setValue(AVKey.WIDTH, (int) viewPort.getImageWidth()); |
|
179 |
params.setValue(AVKey.HEIGHT, (int) viewPort.getImageHeight()); |
|
180 |
} |
|
181 | 181 |
} |
182 | 182 |
|
183 | 183 |
private Sector getSector(FLayer layer, IProjection projection) |
... | ... | |
186 | 186 |
ICoordTrans ct = projection.getCT(CRSFactory.getCRS("EPSG:4326")); |
187 | 187 |
Point2D p1 = null; |
188 | 188 |
Point2D p2 = null; |
189 |
Envelope envelope = layer.getFullEnvelope(); |
|
189 | 190 |
|
190 |
if (layer instanceof FLyrVect) { |
|
191 |
p1 = |
|
192 |
convert( |
|
193 |
ct, |
|
194 |
new Point2D.Double(envelope.getMinimum(0), envelope |
|
195 |
.getMinimum(1))); |
|
196 |
p2 = |
|
197 |
convert( |
|
198 |
ct, |
|
199 |
new Point2D.Double(envelope.getMaximum(0), envelope |
|
200 |
.getMaximum(1))); |
|
201 |
|
|
202 |
double minLatitude = Double.isInfinite(p1.getY()) ? Angle.NEG90.degrees : p1.getY(); |
|
203 |
double maxLatitude = Double.isInfinite(p2.getY()) ? Angle.POS90.degrees : p2.getY(); |
|
204 |
double minLongitude = Double.isInfinite(p1.getX()) ? Angle.NEG180.degrees : p1.getX(); |
|
205 |
double maxLongitude = Double.isInfinite(p2.getX()) ? Angle.POS180.degrees : p2.getX(); |
|
191 | 206 |
|
192 |
Envelope envelope = |
|
193 |
((FLyrVect) layer).getFeatureStore().getEnvelope(); |
|
194 |
p1 = |
|
195 |
ct.convert( |
|
196 |
new Point2D.Double(envelope.getMinimum(0), envelope |
|
197 |
.getMinimum(1)), null); |
|
198 |
p2 = |
|
199 |
ct.convert( |
|
200 |
new Point2D.Double(envelope.getMaximum(0), envelope |
|
201 |
.getMaximum(1)), null); |
|
202 |
|
|
203 |
} else if (layer instanceof FLyrRaster) { |
|
204 |
|
|
205 |
Extent extent = ((FLyrRaster) layer).getDataStore().getExtent(); |
|
206 |
p1 = |
|
207 |
ct.convert( |
|
208 |
new Point2D.Double(extent.getLLX(), extent.getLLY()), null); |
|
209 |
p2 = |
|
210 |
ct.convert( |
|
211 |
new Point2D.Double(extent.getURX(), extent.getURY()), null); |
|
212 |
} |
|
213 |
|
|
214 |
double minLatitude = p1.getY(); |
|
215 |
double maxLatitude = p2.getY(); |
|
216 |
double minLongitude = p1.getX(); |
|
217 |
double maxLongitude = p2.getX(); |
|
218 |
|
|
219 | 207 |
Sector sector = |
220 | 208 |
new Sector(Sector.fromDegrees(minLatitude, maxLatitude, |
221 | 209 |
minLongitude, maxLongitude)); |
222 | 210 |
|
223 | 211 |
return sector; |
224 | 212 |
} |
213 |
|
|
214 |
private int computeNumLevels(LatLon levelZeroDelta, LatLon lastLevelDelta) { |
|
215 |
// Compute the number of levels needed to achieve the given last level |
|
216 |
// tile delta, starting from the given |
|
217 |
// level zero tile delta. |
|
218 |
double numLatLevels = |
|
219 |
WWMath.logBase2(levelZeroDelta.getLatitude().getDegrees()) |
|
220 |
- WWMath.logBase2(lastLevelDelta.getLatitude().getDegrees()); |
|
221 |
double numLonLevels = |
|
222 |
WWMath.logBase2(levelZeroDelta.getLongitude().getDegrees()) |
|
223 |
- WWMath.logBase2(lastLevelDelta.getLongitude().getDegrees()); |
|
224 |
|
|
225 |
// Compute the maximum number of levels needed, but limit the number of |
|
226 |
// levels to positive integers greater |
|
227 |
// than or equal to one. |
|
228 |
int numLevels = (int) Math.ceil(Math.max(numLatLevels, numLonLevels)); |
|
229 |
if (numLevels < 1) |
|
230 |
numLevels = 1; |
|
231 |
|
|
232 |
return numLevels; |
|
233 |
} |
|
234 |
|
|
235 |
private LatLon computeRasterTileDelta(AVList parameters) { |
|
236 |
|
|
237 |
Sector sector = (Sector) parameters.getValue(AVKey.SECTOR); |
|
238 |
int width = (Integer) parameters.getValue(AVKey.WIDTH); |
|
239 |
int height = (Integer) parameters.getValue(AVKey.HEIGHT); |
|
240 |
int tileWidth = (Integer) parameters.getValue(AVKey.TILE_WIDTH); |
|
241 |
int tileHeight = (Integer) parameters.getValue(AVKey.TILE_HEIGHT); |
|
242 |
|
|
243 |
LatLon pixelSize = this.computeRasterPixelSize(sector, width, height); |
|
244 |
// Compute the tile size in latitude and longitude, given a raster's |
|
245 |
// sector and dimension, and the tile |
|
246 |
// dimensions. In this computation a pixel is assumed to cover a finite |
|
247 |
// area. |
|
248 |
double latDelta = tileHeight * pixelSize.getLatitude().degrees; |
|
249 |
double lonDelta = tileWidth * pixelSize.getLongitude().degrees; |
|
250 |
return LatLon.fromDegrees(latDelta, lonDelta); |
|
251 |
} |
|
252 |
|
|
253 |
private LatLon computeRasterPixelSize(Sector sector, int width, int height) { |
|
254 |
// Compute the raster's pixel dimension in latitude and longitude. In |
|
255 |
// this computation a pixel is assumed to |
|
256 |
// cover a finite area. |
|
257 |
return LatLon.fromDegrees(sector.getDeltaLatDegrees() / height, |
|
258 |
sector.getDeltaLonDegrees() / width); |
|
259 |
} |
|
260 |
|
|
261 |
private LatLon computeDesiredTileDelta(Sector sector) { |
|
262 |
return LatLon.fromDegrees(sector.getDeltaLatDegrees(), sector.getDeltaLonDegrees()); |
|
263 |
} |
|
264 |
|
|
265 |
private Point2D convert(ICoordTrans ct, Point2D point){ |
|
266 |
if(ct == null){ |
|
267 |
return point; |
|
268 |
} |
|
269 |
|
|
270 |
return ct.convert(point, null); |
|
271 |
} |
|
272 |
|
|
225 | 273 |
} |
Also available in: Unified diff