gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster.googlemaps / org.gvsig.raster.googlemaps.provider / src / main / java / org / gvsig / raster / googlemaps / provider / GoogleMapsRasterProvider.java @ 8836
History | View | Annotate | Download (13.4 KB)
1 |
package org.gvsig.raster.googlemaps.provider; |
---|---|
2 |
|
3 |
import java.util.ArrayList; |
4 |
import java.util.HashMap; |
5 |
import java.util.Iterator; |
6 |
import java.util.List; |
7 |
import java.util.Map; |
8 |
import java.util.Map.Entry; |
9 |
|
10 |
import org.apache.commons.lang3.StringUtils; |
11 |
import org.cresques.cts.IProjection; |
12 |
import org.slf4j.Logger; |
13 |
import org.slf4j.LoggerFactory; |
14 |
|
15 |
import org.gvsig.fmap.crs.CRSFactory; |
16 |
import org.gvsig.fmap.dal.DataServerExplorer; |
17 |
import org.gvsig.fmap.dal.DataStore; |
18 |
import org.gvsig.fmap.dal.DataStoreParameters; |
19 |
import org.gvsig.fmap.dal.FileHelper; |
20 |
import org.gvsig.fmap.dal.exception.DataException; |
21 |
import org.gvsig.fmap.dal.exception.InitializeException; |
22 |
import org.gvsig.fmap.dal.exception.OpenException; |
23 |
import org.gvsig.fmap.dal.exception.ReadException; |
24 |
import org.gvsig.fmap.dal.exception.ValidateDataParametersException; |
25 |
import org.gvsig.fmap.dal.raster.api.BandQuery; |
26 |
import org.gvsig.fmap.dal.raster.api.RasterQuery; |
27 |
import org.gvsig.fmap.dal.raster.spi.AbstractRasterStoreProvider; |
28 |
import org.gvsig.fmap.dal.raster.spi.BandDescriptorServices; |
29 |
import org.gvsig.fmap.dal.resource.spi.ResourceProvider; |
30 |
import org.gvsig.fmap.dal.spi.DataStoreProviderServices; |
31 |
import org.gvsig.fmap.geom.Geometry.DIMENSIONS; |
32 |
import org.gvsig.fmap.geom.Geometry.SUBTYPES; |
33 |
import org.gvsig.fmap.geom.GeometryLocator; |
34 |
import org.gvsig.fmap.geom.exception.CreateEnvelopeException; |
35 |
import org.gvsig.fmap.geom.primitive.Envelope; |
36 |
import org.gvsig.googlemaps.lib.api.MapTypes; |
37 |
import org.gvsig.metadata.MetadataLocator; |
38 |
import org.gvsig.metadata.MetadataManager; |
39 |
import org.gvsig.metadata.exceptions.MetadataException; |
40 |
import org.gvsig.raster.lib.buffer.api.Buffer; |
41 |
import org.gvsig.raster.lib.buffer.api.BufferDimensions; |
42 |
import org.gvsig.raster.lib.buffer.api.BufferLocator; |
43 |
import org.gvsig.raster.lib.buffer.api.BufferManager; |
44 |
import org.gvsig.raster.lib.buffer.api.NoData; |
45 |
import org.gvsig.raster.lib.buffer.api.PageManager; |
46 |
import org.gvsig.raster.lib.buffer.api.TileStruct; |
47 |
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException; |
48 |
import org.gvsig.raster.lib.buffer.spi.DefaultTileStruct; |
49 |
import org.gvsig.tools.ToolsLocator; |
50 |
import org.gvsig.tools.dataTypes.DataTypes; |
51 |
import org.gvsig.tools.dispose.Disposable; |
52 |
import org.gvsig.tools.dispose.DisposeUtils; |
53 |
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException; |
54 |
import org.gvsig.tools.exception.BaseException; |
55 |
import org.gvsig.tools.i18n.I18nManager; |
56 |
import org.gvsig.tools.locator.LocatorException; |
57 |
|
58 |
|
59 |
/**
|
60 |
* @author fdiaz
|
61 |
*
|
62 |
*/
|
63 |
public class GoogleMapsRasterProvider extends AbstractRasterStoreProvider { |
64 |
|
65 |
private static final Logger logger = |
66 |
LoggerFactory.getLogger(GoogleMapsRasterProvider.class); |
67 |
|
68 |
public static String NAME = "GoogleMaps"; |
69 |
public static String DESCRIPTION = "Google Maps"; |
70 |
public static final String METADATA_DEFINITION_NAME = "GoogleMaps"; |
71 |
static IProjection GOOGLE_MAPS_PROJECTION = CRSFactory.getCRS("EPSG:3857"); |
72 |
|
73 |
|
74 |
private GoogleMapsImage image;
|
75 |
TileStruct tileStruct = null;
|
76 |
Map<Integer,List<PageManager>> pageManagersPerZoomLevel = null; |
77 |
|
78 |
private Envelope worldExtent;
|
79 |
|
80 |
protected static void registerMetadataDefinition() throws MetadataException { |
81 |
MetadataManager manager = MetadataLocator.getMetadataManager(); |
82 |
if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) { |
83 |
manager.addDefinition(METADATA_DEFINITION_NAME, |
84 |
GoogleMapsRasterProviderParameters.class.getResourceAsStream("GoogleMapsRasterMetadata.xml"),
|
85 |
GoogleMapsRasterProviderParameters.class.getClassLoader()); |
86 |
} |
87 |
} |
88 |
|
89 |
|
90 |
protected GoogleMapsRasterProvider(DataStoreParameters params, DataStoreProviderServices storeServices) {
|
91 |
super(params, storeServices, FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME));
|
92 |
pageManagersPerZoomLevel = new HashMap<Integer, List<PageManager>>(); |
93 |
} |
94 |
|
95 |
@Override
|
96 |
public Buffer createBuffer(RasterQuery rasterQuery) throws BufferException { |
97 |
|
98 |
BufferManager bufferManager = BufferLocator.getBufferManager(); |
99 |
int[] bandDataTypes; |
100 |
List<PageManager> pageManagers = new ArrayList<PageManager>(); |
101 |
NoData[] bandNoData;
|
102 |
Envelope envelope = getTileStruct().getEnvelope(); |
103 |
double pixelSize = rasterQuery.getPixelSize();
|
104 |
int zoomLevel;
|
105 |
if(pixelSize == 0){ |
106 |
zoomLevel = 0;
|
107 |
} else {
|
108 |
zoomLevel = getZoomLvlForPixelSize(pixelSize); |
109 |
} |
110 |
|
111 |
if (!rasterQuery.getBands().isEmpty()) {
|
112 |
List<BandQuery> bands;
|
113 |
bands = rasterQuery.getBands(); |
114 |
bandDataTypes = new int[bands.size()]; |
115 |
bandNoData = new NoData[bands.size()];
|
116 |
|
117 |
for (BandQuery bandQuery : bands) {
|
118 |
int band = bandQuery.getBand();
|
119 |
bandDataTypes[band] = this.getBandDescriptor(band).getDataType();
|
120 |
bandNoData[band] = this.getNoData(rasterQuery, band);
|
121 |
try {
|
122 |
pageManagers.add(getPageManagersInZoom(zoomLevel).get(band)); |
123 |
} catch (ValidateDataParametersException | CreateEnvelopeException | DataException
|
124 |
| CloneNotSupportedException e) {
|
125 |
// TODO Auto-generated catch block
|
126 |
throw new BufferException(e); |
127 |
} |
128 |
} |
129 |
} else {
|
130 |
int bands = getBands();
|
131 |
bandDataTypes = new int[bands]; |
132 |
bandNoData = new NoData[bands];
|
133 |
for (int i = 0; i < bands; i++) { |
134 |
bandDataTypes[i] = this.getBandDescriptor(i).getDataType();
|
135 |
bandNoData[i] = this.getNoData(rasterQuery, i);
|
136 |
try {
|
137 |
pageManagers.add(getPageManagersInZoom(zoomLevel).get(i)); |
138 |
} catch (ValidateDataParametersException | CreateEnvelopeException | DataException
|
139 |
| CloneNotSupportedException e) {
|
140 |
throw new BufferException(e); |
141 |
} |
142 |
} |
143 |
} |
144 |
|
145 |
Buffer buffer =
|
146 |
bufferManager.createBuffer(getRows(zoomLevel), getColumns(zoomLevel), bandDataTypes, bandNoData, |
147 |
GOOGLE_MAPS_PROJECTION, envelope, pageManagers); |
148 |
|
149 |
if(rasterQuery.getClip()!=null){ |
150 |
Buffer completeBuffer = buffer;
|
151 |
envelope = rasterQuery.getClip(); |
152 |
buffer = completeBuffer.clip(envelope); |
153 |
DisposeUtils.dispose(completeBuffer); |
154 |
} |
155 |
|
156 |
return buffer;
|
157 |
} |
158 |
|
159 |
@Override
|
160 |
public BandDescriptorServices getBandDescriptor(int band) { |
161 |
BandDescriptorServices descriptor = super.getBandDescriptor(band);
|
162 |
switch (band) {
|
163 |
case 0: |
164 |
descriptor.setName("RED");
|
165 |
descriptor.setDescription("RED");
|
166 |
descriptor.setDataType(BufferManager.TYPE_BYTE); |
167 |
case 1: |
168 |
descriptor.setName("GREEN");
|
169 |
descriptor.setDescription("GREEN");
|
170 |
descriptor.setDataType(BufferManager.TYPE_BYTE); |
171 |
case 2: |
172 |
descriptor.setName("BLUE");
|
173 |
descriptor.setDescription("BLUE");
|
174 |
descriptor.setDataType(BufferManager.TYPE_BYTE); |
175 |
case 3: |
176 |
descriptor.setName("ALPHA");
|
177 |
descriptor.setDescription("ALPHA");
|
178 |
descriptor.setDataType(BufferManager.TYPE_BYTE); |
179 |
} |
180 |
return descriptor;
|
181 |
|
182 |
} |
183 |
|
184 |
@Override
|
185 |
public int getBands() { |
186 |
return 4; |
187 |
} |
188 |
|
189 |
@Override
|
190 |
public DataServerExplorer getExplorer() throws ReadException, ValidateDataParametersException { |
191 |
// TODO Auto-generated method stub
|
192 |
return null; |
193 |
} |
194 |
|
195 |
@Override
|
196 |
public void open() throws OpenException { |
197 |
for(int i=0; i<getBands(); i++){ |
198 |
this.getBandDescriptor(i).setDataType(DataTypes.BYTE);
|
199 |
} |
200 |
} |
201 |
|
202 |
@Override
|
203 |
public ResourceProvider getResource() {
|
204 |
return null; |
205 |
} |
206 |
|
207 |
@Override
|
208 |
public Object getSourceId() { |
209 |
return NAME+"-"+getParameters().getDynValue("mapType"); |
210 |
} |
211 |
|
212 |
@Override
|
213 |
public String getProviderName() { |
214 |
return NAME;
|
215 |
} |
216 |
|
217 |
@Override
|
218 |
public String getName() { |
219 |
I18nManager i18nManager = ToolsLocator.getI18nManager(); |
220 |
String mapId = (String) getParameters().getDynValue("mapType"); |
221 |
MapTypes mapType = MapTypes.valueOf(StringUtils.upperCase(mapId)); |
222 |
|
223 |
return i18nManager.getTranslation("_google_maps")+" "+mapType.toString(); |
224 |
} |
225 |
|
226 |
@Override
|
227 |
public String getFullName() { |
228 |
return NAME+"-"+getParameters().getDynValue("mapType"); |
229 |
} |
230 |
|
231 |
public TileStruct getTileStruct() {
|
232 |
if(tileStruct == null){ |
233 |
autoOpen(); |
234 |
tileStruct = new DefaultTileStruct();
|
235 |
tileStruct.setColumnsPerTile(GoogleMapsRasterLibrary.TILE_SIZE); |
236 |
tileStruct.setRowsPerTile(GoogleMapsRasterLibrary.TILE_SIZE); |
237 |
|
238 |
//FIXME: ??
|
239 |
// tileStruct.setProviderName("GTIFF");
|
240 |
|
241 |
try {
|
242 |
worldExtent = GeometryLocator.getGeometryManager().createEnvelope(-20037508, -20037508, 20037508, 20037508, SUBTYPES.GEOM2D); |
243 |
tileStruct.setEnvelope(worldExtent); |
244 |
|
245 |
Map<Integer, Double> zoomLevels = new HashMap<Integer, Double>(); |
246 |
|
247 |
double pixelSize = worldExtent.getLength(DIMENSIONS.X)/GoogleMapsRasterLibrary.GOOGLE_MAPS_TILE_SIZE;
|
248 |
for (int zoomLevel = 0; zoomLevel <= GoogleMapsRasterLibrary.MAX_ZOOM_LEVEL; zoomLevel++) { |
249 |
zoomLevels.put(zoomLevel, pixelSize); |
250 |
pixelSize = pixelSize/2;
|
251 |
} |
252 |
|
253 |
tileStruct.setPixelSizePerZoomLevel(zoomLevels); |
254 |
} catch (LocatorException | CreateEnvelopeException e) {
|
255 |
logger.warn("Can't create world extent of GoogleMaps", e);
|
256 |
} |
257 |
} |
258 |
return this.tileStruct; |
259 |
} |
260 |
|
261 |
private GoogleMapsImage getGoogleMapsImage() {
|
262 |
if(this.image == null){ |
263 |
this.image = new GoogleMapsImage(getTileStruct(), this); |
264 |
} |
265 |
return this.image; |
266 |
} |
267 |
|
268 |
/**
|
269 |
* @param pixelSize
|
270 |
* @return The appropriate zoom level for the pizelSize
|
271 |
*/
|
272 |
private int getZoomLvlForPixelSize(double pixelSize) { |
273 |
int zoom = 0; |
274 |
Map<Integer, Double> pixelSizePerZoomLevel = getTileStruct().getPixelSizePerZoomLevel(); |
275 |
for (int i : pixelSizePerZoomLevel.keySet()) { |
276 |
zoom = i; |
277 |
double levelPixelSize = pixelSizePerZoomLevel.get(zoom);
|
278 |
if (pixelSize >= levelPixelSize) {
|
279 |
return zoom;
|
280 |
} |
281 |
} |
282 |
return zoom;
|
283 |
} |
284 |
|
285 |
private List<PageManager> getPageManagersInZoom(int zoomLevel) throws ValidateDataParametersException, CreateEnvelopeException, BufferException, DataException, CloneNotSupportedException { |
286 |
List<PageManager> pageManagersInZoom = this.pageManagersPerZoomLevel.get(zoomLevel); |
287 |
if (pageManagersInZoom == null) { |
288 |
pageManagersInZoom = new ArrayList<PageManager>(); |
289 |
for (int i = 0; i < getBands(); i++) { |
290 |
pageManagersInZoom.add(new GoogleMapsBandTileManager(getTileStruct(), this.getGoogleMapsImage(), zoomLevel, i, this)); |
291 |
} |
292 |
this.pageManagersPerZoomLevel.put(zoomLevel, pageManagersInZoom);
|
293 |
} |
294 |
return pageManagersInZoom;
|
295 |
} |
296 |
|
297 |
/**
|
298 |
* @param zoomLevel
|
299 |
* @return rows per zoom level
|
300 |
*/
|
301 |
public int getRows(int zoomLevel) { |
302 |
return (int) (Math.round(getTileStruct().getEnvelope().getLength(DIMENSIONS.Y) / this.getTileStruct().getPixelSizePerZoomLevel().get(zoomLevel))); |
303 |
} |
304 |
|
305 |
/**
|
306 |
* @param zoomLevel
|
307 |
* @return columns per zoom level
|
308 |
*/
|
309 |
public int getColumns(int zoomLevel) { |
310 |
return (int) (Math.round(getTileStruct().getEnvelope().getLength(DIMENSIONS.X) / this.getTileStruct().getPixelSizePerZoomLevel().get(zoomLevel))); |
311 |
} |
312 |
|
313 |
@Override
|
314 |
public Object getDynValue(String name) throws DynFieldNotFoundException { |
315 |
if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
|
316 |
return this.getTileStruct().getEnvelope(); //.worldExtent; |
317 |
} else if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) { |
318 |
return GOOGLE_MAPS_PROJECTION;
|
319 |
} |
320 |
return super.getDynValue(name); |
321 |
} |
322 |
|
323 |
@Override
|
324 |
public BufferDimensions getDimensions() throws InitializeException { |
325 |
if(this.dimensions==null){; |
326 |
Double pixelSize = getTileStruct().getPixelSizePerZoomLevel().get(GoogleMapsRasterLibrary.MAX_ZOOM_LEVEL);
|
327 |
Envelope envelope = getTileStruct().getEnvelope(); |
328 |
int rows = (int)Math.round(envelope.getLength(DIMENSIONS.Y)/pixelSize); |
329 |
int columns = rows;
|
330 |
this.dimensions = BufferLocator.getBufferManager().createBufferDimensions(rows, columns, envelope);
|
331 |
} |
332 |
return this.dimensions; |
333 |
} |
334 |
|
335 |
@Override
|
336 |
public void doDispose() throws BaseException { |
337 |
super.doDispose();
|
338 |
|
339 |
for (Iterator<Entry<Integer, List<PageManager>>> iterator = pageManagersPerZoomLevel.entrySet().iterator(); iterator.hasNext();) { |
340 |
Entry<Integer, List<PageManager>> entry = iterator.next(); |
341 |
List<PageManager> pageManagers = entry.getValue();
|
342 |
for(Iterator<PageManager> it = pageManagers.iterator(); it.hasNext();){ |
343 |
PageManager pageManager = it.next(); |
344 |
DisposeUtils.dispose(pageManager); |
345 |
it.remove(); |
346 |
} |
347 |
iterator.remove(); |
348 |
} |
349 |
DisposeUtils.dispose((Disposable) tileStruct); |
350 |
DisposeUtils.dispose(image); |
351 |
tileStruct=null;
|
352 |
image=null;
|
353 |
} |
354 |
} |