refactor BitmapTileLayer:

- move to layer.tile.bitmap
- extract BitmapTileLoader
- bring back GWT BitmapTileLayer to life
This commit is contained in:
Hannes Janetzek 2014-02-25 23:13:38 +01:00
parent ec7f75cf67
commit ae808dce2e
11 changed files with 269 additions and 75 deletions

@ -1 +1 @@
Subproject commit 92d16812200c396536bbfd5a5aa34ee08084e26c Subproject commit 0bf68282155798f3884a4635e52fbbc90a0e5cc6

View File

@ -19,7 +19,7 @@ import org.oscim.android.MapView;
import org.oscim.android.cache.TileCache; import org.oscim.android.cache.TileCache;
import org.oscim.backend.canvas.Color; import org.oscim.backend.canvas.Color;
import org.oscim.layers.TileGridLayer; import org.oscim.layers.TileGridLayer;
import org.oscim.layers.tile.BitmapTileLayer; import org.oscim.layers.tile.bitmap.BitmapTileLayer;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.tiling.TileSource; import org.oscim.tiling.TileSource;
import org.oscim.tiling.source.bitmap.DefaultSources; import org.oscim.tiling.source.bitmap.DefaultSources;

View File

@ -60,7 +60,11 @@ public class GwtBitmap implements Bitmap {
@Override @Override
public void recycle() { public void recycle() {
// FIXME this should be called at some point in time
pixmap.dispose(); pixmap.dispose();
if (image != null)
RootPanel.get().remove(image);
} }
@Override @Override

View File

@ -22,7 +22,7 @@ import org.oscim.backend.GLAdapter;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.MercatorProjection; import org.oscim.core.MercatorProjection;
import org.oscim.gdx.GdxMap; import org.oscim.gdx.GdxMap;
import org.oscim.layers.tile.BitmapTileLayer; import org.oscim.layers.tile.bitmap.BitmapTileLayer;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.tiling.TileSource; import org.oscim.tiling.TileSource;
import org.oscim.tiling.source.bitmap.DefaultSources.NaturalEarth; import org.oscim.tiling.source.bitmap.DefaultSources.NaturalEarth;

View File

@ -0,0 +1,82 @@
package org.oscim.layers.tile.bitmap;
import static org.oscim.layers.tile.MapTile.State.CANCEL;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.MapElement;
import org.oscim.core.Tile;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
import org.oscim.renderer.elements.BitmapLayer;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.ITileDataSource.QueryResult;
import org.oscim.tiling.TileSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BitmapTileLoader extends TileLoader implements ITileDataSink {
protected static final Logger log = LoggerFactory.getLogger(BitmapTileLoader.class);
private final ITileDataSource mTileDataSource;
private MapTile mTile;
public BitmapTileLoader(TileManager tileManager, TileSource tileSource) {
super(tileManager);
mTileDataSource = tileSource.getDataSource();
}
@Override
public void cleanup() {
mTile = null;
}
@Override
protected boolean executeJob(MapTile tile) {
mTile = tile;
//QueryResult result = null;
//try {
if (mTileDataSource.executeQuery(tile, this) != QueryResult.SUCCESS) {
return false;
}
//}
// catch (CancellationException e) {
// log.debug("{} was canceled", mTile);
// } catch (Exception e) {
// log.debug("{} {}", mTile, e.getMessage());
// } finally {
// mTile = null;
// }
return true;
//return result == QueryResult.SUCCESS;
}
@Override
public void setTileImage(Bitmap bitmap) {
if (isCanceled() || mTile.state(CANCEL))
return;
//throw new CancellationException();
BitmapLayer l = new BitmapLayer(false);
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
mTile.layers = new ElementLayers();
mTile.layers.setTextureLayers(l);
}
@Override
public void process(MapElement element) {
}
@Override
public void completed(boolean success) {
if (success) {
mTile.loader.jobCompleted(mTile, true);
mTile = null;
return;
}
}
}

View File

@ -0,0 +1,95 @@
package org.oscim.tiling.source.bitmap;
import org.oscim.gdx.client.GwtBitmap;
import org.oscim.layers.tile.MapTile;
import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.source.LwHttp;
import org.oscim.tiling.source.UrlTileSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gwt.event.dom.client.ErrorEvent;
import com.google.gwt.event.dom.client.ErrorHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.safehtml.shared.SafeUri;
import com.google.gwt.safehtml.shared.UriUtils;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
public abstract class BitmapTileSource extends UrlTileSource {
static final Logger log = LoggerFactory.getLogger(LwHttp.class);
/**
* Create BitmapTileSource for 'url'
*
* By default path will be formatted as: url/z/x/y.png
* Use e.g. setExtension(".jpg") to overide ending or
* implement getUrlString() for custom formatting.
*/
public BitmapTileSource(String url, int zoomMin, int zoomMax) {
super(url, zoomMin, zoomMax);
setExtension(".png");
}
@Override
public ITileDataSource getDataSource() {
return new BitmapTileDataSource(this);
}
public static class BitmapTileDataSource implements ITileDataSource {
protected final UrlTileSource mTileSource;
private final byte[] mRequestBuffer = new byte[1024];
public BitmapTileDataSource(BitmapTileSource bitmapTileSource) {
mTileSource = bitmapTileSource;
}
@Override
public QueryResult executeQuery(final MapTile tile, final ITileDataSink sink) {
int pos = mTileSource.formatTilePath(tile, mRequestBuffer, 0);
String url = mTileSource.getUrl()
+ (new String(mRequestBuffer, 0, pos));
SafeUri uri = UriUtils.fromTrustedString(url);
final Image img = new Image();
img.setVisible(false);
/* As if researching CORS issues doesnt result in
* enough headache...
*
* Here are some more special Chrome/Webkit quirks:
* MUST SET CORS BEFORE URL! */
img.getElement().setAttribute("crossorigin", "anonymous");
img.setUrl(uri);
RootPanel.get().add(img);
img.addLoadHandler(new LoadHandler() {
public void onLoad(LoadEvent event) {
sink.setTileImage(new GwtBitmap(img));
tile.loader.jobCompleted(tile, true);
}
});
img.addErrorHandler(new ErrorHandler() {
@Override
public void onError(ErrorEvent event) {
tile.loader.jobCompleted(tile, false);
RootPanel.get().remove(img);
}
});
return QueryResult.SUCCESS;
}
@Override
public void destroy() {
}
}
}

View File

@ -14,23 +14,15 @@
* You should have received a copy of the GNU Lesser General Public License along with * You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.oscim.layers.tile; package org.oscim.layers.tile.bitmap;
import static org.oscim.layers.tile.MapTile.State.CANCEL;
import java.util.concurrent.CancellationException;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.MapElement;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.event.Event; import org.oscim.event.Event;
import org.oscim.layers.tile.TileLayer;
import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
import org.oscim.layers.tile.VectorTileRenderer;
import org.oscim.map.Map; import org.oscim.map.Map;
import org.oscim.renderer.elements.BitmapLayer;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.ITileDataSource.QueryResult;
import org.oscim.tiling.TileSource; import org.oscim.tiling.TileSource;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -110,58 +102,4 @@ public class BitmapTileLayer extends TileLayer {
protected TileLoader createLoader(TileManager tm) { protected TileLoader createLoader(TileManager tm) {
return new BitmapTileLoader(tm, mTileSource); return new BitmapTileLoader(tm, mTileSource);
} }
class BitmapTileLoader extends TileLoader implements ITileDataSink {
private final ITileDataSource mTileDataSource;
private MapTile mTile;
public BitmapTileLoader(TileManager tileManager, TileSource tileSource) {
super(tileManager);
mTileDataSource = tileSource.getDataSource();
}
@Override
public void cleanup() {
mTile = null;
}
@Override
protected boolean executeJob(MapTile tile) {
mTile = tile;
QueryResult result = null;
try {
result = mTileDataSource.executeQuery(tile, this);
} catch (CancellationException e) {
log.debug("{} was canceled", mTile);
} catch (Exception e) {
log.debug("{} {}", mTile, e.getMessage());
} finally {
mTile = null;
}
return result == QueryResult.SUCCESS;
}
@Override
public void setTileImage(Bitmap bitmap) {
if (isCanceled() || mTile.state(CANCEL))
throw new CancellationException();
BitmapLayer l = new BitmapLayer(false);
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
mTile.layers = new ElementLayers();
mTile.layers.setTextureLayers(l);
}
@Override
public void process(MapElement element) {
}
@Override
public void completed(boolean success) {
}
}
} }

View File

@ -0,0 +1,75 @@
package org.oscim.layers.tile.bitmap;
import static org.oscim.layers.tile.MapTile.State.CANCEL;
import java.util.concurrent.CancellationException;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.MapElement;
import org.oscim.core.Tile;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
import org.oscim.renderer.elements.BitmapLayer;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.tiling.ITileDataSink;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.ITileDataSource.QueryResult;
import org.oscim.tiling.TileSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BitmapTileLoader extends TileLoader implements ITileDataSink {
protected static final Logger log = LoggerFactory.getLogger(BitmapTileLoader.class);
private final ITileDataSource mTileDataSource;
private MapTile mTile;
public BitmapTileLoader(TileManager tileManager, TileSource tileSource) {
super(tileManager);
mTileDataSource = tileSource.getDataSource();
}
@Override
public void cleanup() {
mTile = null;
}
@Override
protected boolean executeJob(MapTile tile) {
mTile = tile;
QueryResult result = null;
try {
result = mTileDataSource.executeQuery(tile, this);
} catch (CancellationException e) {
log.debug("{} was canceled", mTile);
} catch (Exception e) {
log.debug("{} {}", mTile, e.getMessage());
} finally {
mTile = null;
}
return result == QueryResult.SUCCESS;
}
@Override
public void setTileImage(Bitmap bitmap) {
if (isCanceled() || mTile.state(CANCEL))
throw new CancellationException();
BitmapLayer l = new BitmapLayer(false);
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
mTile.layers = new ElementLayers();
mTile.layers.setTextureLayers(l);
}
@Override
public void process(MapElement element) {
}
@Override
public void completed(boolean success) {
}
}

View File

@ -24,7 +24,7 @@ import org.oscim.event.Gesture;
import org.oscim.event.GestureDetector; import org.oscim.event.GestureDetector;
import org.oscim.event.MotionEvent; import org.oscim.event.MotionEvent;
import org.oscim.layers.MapEventLayer; import org.oscim.layers.MapEventLayer;
import org.oscim.layers.tile.BitmapTileLayer; import org.oscim.layers.tile.bitmap.BitmapTileLayer;
import org.oscim.layers.tile.vector.OsmTileLayer; import org.oscim.layers.tile.vector.OsmTileLayer;
import org.oscim.layers.tile.vector.VectorTileLayer; import org.oscim.layers.tile.vector.VectorTileLayer;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;

View File

@ -18,7 +18,7 @@ package org.oscim.tiling;
import java.util.HashMap; import java.util.HashMap;
import org.oscim.layers.tile.BitmapTileLayer.FadeStep; import org.oscim.layers.tile.bitmap.BitmapTileLayer.FadeStep;
public abstract class TileSource { public abstract class TileSource {

View File

@ -1,7 +1,7 @@
package org.oscim.tiling.source.bitmap; package org.oscim.tiling.source.bitmap;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.layers.tile.BitmapTileLayer.FadeStep; import org.oscim.layers.tile.bitmap.BitmapTileLayer.FadeStep;
/** /**
* Do not use in applications unless you read through and comply to * Do not use in applications unless you read through and comply to
@ -23,7 +23,7 @@ public class DefaultSources {
public static class StamenToner extends BitmapTileSource { public static class StamenToner extends BitmapTileSource {
public StamenToner() { public StamenToner() {
super("http://a.tile.stamen.com/toner", 0, 16); super("http://opensciencemap.org/cors-stamen/toner", 0, 16);
} }
} }
@ -67,7 +67,7 @@ public class DefaultSources {
private final StringBuilder sb = new StringBuilder(32); private final StringBuilder sb = new StringBuilder(32);
public ArcGISWorldShaded() { public ArcGISWorldShaded() {
super("http://server.arcgisonline.com/ArcGIS/rest/services", 0, 6); super("http://server.arcgisonline.com/ArcGIS/rest/services", 0, 13);
} }
@Override @Override