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