VirtualEarthLayer

  1 import gov.nasa.worldwind.avlist.AVKey;
  2 import gov.nasa.worldwind.avlist.AVList;
  3 import gov.nasa.worldwind.avlist.AVListImpl;
  4 import gov.nasa.worldwind.geom.Angle;
  5 import gov.nasa.worldwind.geom.LatLon;
  6 import gov.nasa.worldwind.render.DrawContext;
  7 import gov.nasa.worldwind.util.LevelSet;
  8 import gov.nasa.worldwind.util.Tile;
  9 import gov.nasa.worldwind.util.TileUrlBuilder;
 10 import gov.nasa.worldwind.layers.Mercator.*;
 11 
 12 import java.awt.image.BufferedImage;
 13 import java.net.MalformedURLException;
 14 import java.net.URL;
 15 
 16 public class VirtualEarthLayer extends BasicMercatorTiledImageLayer
 17 {
 18         public static enum Dataset
 19         {
 20                 AERIAL("Aerial", "a", ".jpg"),
 21                 HYBRID("Hybrid", "h", ".jpg"),
 22                 ROAD("Road", "r", ".png");
 23 
 24                 public final String label;
 25                 public final String dataset;
 26                 public final String formatSuffix;
 27 
 28                 private Dataset(String label, String dataset, String formatSuffix)
 29                 {
 30                         this.label = label;
 31                         this.dataset = dataset;
 32                         this.formatSuffix = formatSuffix;
 33                 }
 34         }
 35 
 36         // private VirtualEarthLogo logo = new VirtualEarthLogo();
 37         private final Dataset dataset;
 38 
 39         public VirtualEarthLayer()
 40         {
 41                 this(Dataset.HYBRID);
 42         }
 43 
 44         public VirtualEarthLayer(Dataset dataset)
 45         {
 46                 super(makeLevels(dataset));
 47                 if (dataset == null)
 48                         throw new NullPointerException("Dataset cannot be null");
 49                 this.dataset = dataset;
 50                 this.setValue(AVKey.DISPLAY_NAME, "Microsoft Virtual Earth "
 51                                 + dataset.label);
 52                 // this.setSplitScale(1.3);
 53         }
 54 
 55         protected static LevelSet makeLevels(Dataset dataset)
 56         {
 57                 AVList params = new AVListImpl();
 58 
 59                 params.setValue(AVKey.TILE_WIDTH, 256);
 60                 params.setValue(AVKey.TILE_HEIGHT, 256);
 61                 params.setValue(AVKey.DATA_CACHE_NAME, "Earth/MS Virtual Earth Mercator/MSVE "
 62                                 + dataset.label);
 63                 params.setValue(AVKey.SERVICE,
 64                                 "http://a0.ortho.tiles.virtualearth.net/tiles/");
 65                 params.setValue(AVKey.DATASET_NAME, dataset.dataset);
 66                 params.setValue(AVKey.FORMAT_SUFFIX, dataset.formatSuffix);
 67                 params.setValue(AVKey.NUM_LEVELS, 16);
 68                 params.setValue(AVKey.NUM_EMPTY_LEVELS, 0);
 69                 params.setValue(AVKey.LEVEL_ZERO_TILE_DELTA, new LatLon(Angle
 70                                 .fromDegrees(22.5d), Angle.fromDegrees(45d)));
 71                 params.setValue(AVKey.SECTOR, new MercatorSector(-1.0, 1.0,
 72                                 Angle.NEG180, Angle.POS180));
 73                 params.setValue(AVKey.TILE_URL_BUILDER, new URLBuilder());
 74                 params.setValue(AVKey.DISPLAY_NAME, "Microsoft Virtual Earth "
 75                                 + dataset.label);
 76 
 77                 return new LevelSet(params);
 78         }
 79 
 80         private static class URLBuilder implements TileUrlBuilder
 81         {
 82                 public URL getURL(Tile tile, String imageFormat)
 83                                 throws MalformedURLException
 84                 {
 85                         String quadkey = tileToQuadKey(tile.getColumn(), tile.getRow(),
 86                                         tile.getLevelNumber() + 2);
 87                         return new URL(tile.getLevel().getService()
 88                                         + tile.getLevel().getDataset() + quadkey + ".jpeg?g=1");
 89                 }
 90         }
 91 
 92         protected static String tileToQuadKey(int col, int row, int level)
 93         {
 94                 String quad = "";
 95                 for (int i = level; i >= 0; i--)
 96                 {
 97                         int mask = 1 << i;
 98                         int cell = 0;
 99                         if ((col & mask) != 0)
100                         {
101                                 cell++;
102                         }
103                         if ((row & mask) == 0)
104                         {
105                                 cell += 2;
106                         }
107                         quad += cell;
108                 }
109                 return quad;
110         }
111 
112         @Override
113         public void render(DrawContext dc)
114         {
115                 super.render(dc);
116                 /*
117                 if (isEnabled())
118                 {
119                         dc.addOrderedRenderable(logo);
120                 }
121                 */
122         }
123 
124         @Override
125         protected boolean isTileValid(BufferedImage image)
126         {
127                 //return false if the tile is white (this will mark the tile as absent)
128                 boolean white = true;
129                 //JPEG compression will cause white to be not quite white
130                 String lowercaseFormat = getDataset().formatSuffix.toLowerCase();
131                 int threshold = lowercaseFormat.contains("jpg")
132                                 || lowercaseFormat.contains("jpeg") ? 200 : 250;
133                 for (int x = 0; x < image.getWidth(); x++)
134                 {
135                         for (int y = 0; y < image.getHeight(); y++)
136                         {
137                                 int rgb = image.getRGB(x, y);
138                                 white = isWhite(rgb, threshold);
139                                 if (!white)
140                                         break;
141                         }
142                         if (!white)
143                                 break;
144                 }
145                 return !white;
146         }
147 
148         private boolean isWhite(int rgb, int threshold)
149         {
150                 int r = (rgb >> 16) & 0xff;
151                 int g = (rgb >> 8) & 0xff;
152                 int b = (rgb >> 0) & 0xff;
153                 return r + b + g > threshold * 3;
154         }
155 
156         public Dataset getDataset()
157         {
158                 return dataset;
159         }
160 }

 

posted @ 2014-09-19 14:36  zhh  阅读(357)  评论(0编辑  收藏  举报