MapView base layer is now a TileLayer
- extract MapView base layer into TileLayer - extract MapTile loading from GLRenderer - move all tile layer related classes to layers.tile.* - make Overlay subclass of InputLayer, which extends Layer
This commit is contained in:
parent
1c779f2f60
commit
6eb3b9221b
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.database;
|
package org.oscim.database;
|
||||||
|
|
||||||
import org.oscim.generator.JobTile;
|
import org.oscim.layers.tile.JobTile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@ -27,7 +27,7 @@ import org.oscim.database.MapOptions;
|
|||||||
import org.oscim.database.mapfile.header.MapFileHeader;
|
import org.oscim.database.mapfile.header.MapFileHeader;
|
||||||
import org.oscim.database.mapfile.header.MapFileInfo;
|
import org.oscim.database.mapfile.header.MapFileInfo;
|
||||||
import org.oscim.database.mapfile.header.SubFileParameter;
|
import org.oscim.database.mapfile.header.SubFileParameter;
|
||||||
import org.oscim.generator.JobTile;
|
import org.oscim.layers.tile.JobTile;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import org.oscim.database.IMapDatabase;
|
|||||||
import org.oscim.database.IMapDatabaseCallback;
|
import org.oscim.database.IMapDatabaseCallback;
|
||||||
import org.oscim.database.MapInfo;
|
import org.oscim.database.MapInfo;
|
||||||
import org.oscim.database.MapOptions;
|
import org.oscim.database.MapOptions;
|
||||||
import org.oscim.generator.JobTile;
|
import org.oscim.layers.tile.JobTile;
|
||||||
|
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|||||||
@ -43,7 +43,7 @@ import org.oscim.database.IMapDatabase;
|
|||||||
import org.oscim.database.IMapDatabaseCallback;
|
import org.oscim.database.IMapDatabaseCallback;
|
||||||
import org.oscim.database.MapInfo;
|
import org.oscim.database.MapInfo;
|
||||||
import org.oscim.database.MapOptions;
|
import org.oscim.database.MapOptions;
|
||||||
import org.oscim.generator.JobTile;
|
import org.oscim.layers.tile.JobTile;
|
||||||
|
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import org.oscim.database.IMapDatabase;
|
|||||||
import org.oscim.database.IMapDatabaseCallback;
|
import org.oscim.database.IMapDatabaseCallback;
|
||||||
import org.oscim.database.MapInfo;
|
import org.oscim.database.MapInfo;
|
||||||
import org.oscim.database.MapOptions;
|
import org.oscim.database.MapOptions;
|
||||||
import org.oscim.generator.JobTile;
|
import org.oscim.layers.tile.JobTile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
228
src/org/oscim/layers/InputLayer.java
Normal file
228
src/org/oscim/layers/InputLayer.java
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 osmdroid authors
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.layers;
|
||||||
|
|
||||||
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
public abstract class InputLayer extends Layer {
|
||||||
|
|
||||||
|
public InputLayer(MapView mapView) {
|
||||||
|
super(mapView);
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param keyCode
|
||||||
|
* ...
|
||||||
|
* @param event
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param keyCode
|
||||||
|
* ...
|
||||||
|
* @param event
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>You can prevent all(!) other Touch-related events from happening!</b><br />
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onTouchEvent(MotionEvent e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onTrackballEvent(MotionEvent e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** GestureDetector.OnDoubleTapListener **/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onDoubleTap(MotionEvent e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onDoubleTapEvent(MotionEvent e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** OnGestureListener **/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onDown(MotionEvent e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param pEvent1
|
||||||
|
* ...
|
||||||
|
* @param pEvent2
|
||||||
|
* ...
|
||||||
|
* @param pVelocityX
|
||||||
|
* ...
|
||||||
|
* @param pVelocityY
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onFling(MotionEvent pEvent1, MotionEvent pEvent2,
|
||||||
|
float pVelocityX, float pVelocityY) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onLongPress(MotionEvent e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param pEvent1
|
||||||
|
* ...
|
||||||
|
* @param pEvent2
|
||||||
|
* ...
|
||||||
|
* @param pDistanceX
|
||||||
|
* ...
|
||||||
|
* @param pDistanceY
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onScroll(MotionEvent pEvent1, MotionEvent pEvent2,
|
||||||
|
float pDistanceX, float pDistanceY) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pEvent
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
public void onShowPress(MotionEvent pEvent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default does nothing (<code>return false</code>). If you handled the
|
||||||
|
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
||||||
|
* you returned <code>true</code> none of the following Overlays or the
|
||||||
|
* underlying {@link MapView} has the chance to handle this event.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* ...
|
||||||
|
* @return ...
|
||||||
|
*/
|
||||||
|
public boolean onSingleTapUp(MotionEvent e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
74
src/org/oscim/layers/Layer.java
Normal file
74
src/org/oscim/layers/Layer.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.layers;
|
||||||
|
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.renderer.overlays.RenderOverlay;
|
||||||
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
|
public class Layer {
|
||||||
|
public Layer(MapView mapView) {
|
||||||
|
mMapView = mapView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean mEnabled = true;
|
||||||
|
protected final MapView mMapView;
|
||||||
|
|
||||||
|
/** RenderOverlay used to draw this layer. To be implemented by sub-classes */
|
||||||
|
protected RenderOverlay mLayer;
|
||||||
|
|
||||||
|
public RenderOverlay getLayer() {
|
||||||
|
return mLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public void setEnabled(boolean pEnabled) {
|
||||||
|
mEnabled = pEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return mEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called before each frame render request (on main thread).
|
||||||
|
*
|
||||||
|
* @param mapPosition
|
||||||
|
* current MapPosition
|
||||||
|
* @param changed
|
||||||
|
* true when MapPosition has changed since last call
|
||||||
|
*/
|
||||||
|
public void onUpdate(MapPosition mapPosition, boolean changed) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override to perform clean up of resources before shutdown. By default
|
||||||
|
* does nothing.
|
||||||
|
*/
|
||||||
|
public void onDetach() {
|
||||||
|
// FIXME call to this function is not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,10 +13,10 @@
|
|||||||
* 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.generator;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
import static org.oscim.generator.JobTile.STATE_LOADING;
|
import static org.oscim.layers.tile.JobTile.STATE_LOADING;
|
||||||
import static org.oscim.generator.JobTile.STATE_NONE;
|
import static org.oscim.layers.tile.JobTile.STATE_NONE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
|
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
|
||||||
@ -12,7 +12,7 @@
|
|||||||
* 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.generator;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
|
|
||||||
@ -12,11 +12,11 @@
|
|||||||
* You should have received a copy of the GNU Lesser General License along with
|
* You should have received a copy of the GNU Lesser General 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.renderer;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
import org.oscim.generator.JobTile;
|
|
||||||
import org.oscim.renderer.layer.Layers;
|
import org.oscim.renderer.layer.Layers;
|
||||||
import org.oscim.renderer.layer.TextItem;
|
import org.oscim.renderer.layer.TextItem;
|
||||||
|
import org.oscim.utils.quadtree.QuadTree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends Tile class for concurrent use in TileManager,
|
* Extends Tile class for concurrent use in TileManager,
|
||||||
@ -41,7 +41,7 @@ public final class MapTile extends JobTile {
|
|||||||
/**
|
/**
|
||||||
* Pointer to access relatives in QuadTree
|
* Pointer to access relatives in QuadTree
|
||||||
*/
|
*/
|
||||||
public QuadTree rel;
|
public QuadTree<MapTile> rel;
|
||||||
|
|
||||||
int lastDraw = 0;
|
int lastDraw = 0;
|
||||||
|
|
||||||
@ -92,42 +92,40 @@ public final class MapTile extends JobTile {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// lock all tiles that could serve as proxy
|
// lock all tiles that could serve as proxy
|
||||||
MapTile p = rel.parent.tile;
|
MapTile p = rel.parent.item;
|
||||||
if (p != null && (p.state != 0)) {
|
if (p != null && (p.state != 0)) {
|
||||||
proxies |= PROXY_PARENT;
|
proxies |= PROXY_PARENT;
|
||||||
p.refs++;
|
p.refs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = rel.parent.parent.tile;
|
p = rel.parent.parent.item;
|
||||||
if (p != null && (p.state != 0)) {
|
if (p != null && (p.state != 0)) {
|
||||||
proxies |= PROXY_GRAMPA;
|
proxies |= PROXY_GRAMPA;
|
||||||
p.refs++;
|
p.refs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; j++) {
|
||||||
if (rel.child[j] != null) {
|
if ((p = rel.get(j)) == null || p.state == 0)
|
||||||
p = rel.child[j].tile;
|
continue;
|
||||||
if (p != null && (p.state != 0)) {
|
|
||||||
proxies |= (1 << j);
|
proxies |= (1 << j);
|
||||||
p.refs++;
|
p.refs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void unlock() {
|
void unlock() {
|
||||||
if (--locked > 0 || proxies == 0)
|
if (--locked > 0 || proxies == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((proxies & PROXY_PARENT) != 0)
|
if ((proxies & PROXY_PARENT) != 0)
|
||||||
rel.parent.tile.refs--;
|
rel.parent.item.refs--;
|
||||||
|
|
||||||
if ((proxies & PROXY_GRAMPA) != 0)
|
if ((proxies & PROXY_GRAMPA) != 0)
|
||||||
rel.parent.parent.tile.refs--;
|
rel.parent.parent.item.refs--;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if ((proxies & (1 << i)) != 0)
|
if ((proxies & (1 << i)) != 0)
|
||||||
rel.child[i].tile.refs--;
|
rel.get(i).refs--;
|
||||||
}
|
}
|
||||||
proxies = 0;
|
proxies = 0;
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
*
|
* Copyright 2013 Hannes Hannes Janetzek
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
@ -12,9 +12,8 @@
|
|||||||
* 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.generator;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
import org.oscim.renderer.TileManager;
|
|
||||||
import org.oscim.utils.PausableThread;
|
import org.oscim.utils.PausableThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,6 +38,7 @@ public class MapWorker extends PausableThread {
|
|||||||
*/
|
*/
|
||||||
public MapWorker(int id, JobQueue jobQueue, TileGenerator tileGenerator,
|
public MapWorker(int id, JobQueue jobQueue, TileGenerator tileGenerator,
|
||||||
TileManager tileManager) {
|
TileManager tileManager) {
|
||||||
|
|
||||||
super();
|
super();
|
||||||
mJobQueue = jobQueue;
|
mJobQueue = jobQueue;
|
||||||
mMapGenerator = tileGenerator;
|
mMapGenerator = tileGenerator;
|
||||||
@ -12,7 +12,7 @@
|
|||||||
* 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.generator;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort Tiles by 'distance' value.
|
* Sort Tiles by 'distance' value.
|
||||||
@ -12,11 +12,12 @@
|
|||||||
* 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.generator;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
import static org.oscim.core.MapElement.GEOM_LINE;
|
import static org.oscim.core.MapElement.GEOM_LINE;
|
||||||
import static org.oscim.core.MapElement.GEOM_POINT;
|
import static org.oscim.core.MapElement.GEOM_POINT;
|
||||||
import static org.oscim.core.MapElement.GEOM_POLY;
|
import static org.oscim.core.MapElement.GEOM_POLY;
|
||||||
import static org.oscim.generator.JobTile.STATE_NONE;
|
import static org.oscim.layers.tile.JobTile.STATE_NONE;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@ -25,9 +26,8 @@ import org.oscim.core.MercatorProjection;
|
|||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.database.IMapDatabase;
|
import org.oscim.database.IMapDatabase;
|
||||||
|
import org.oscim.database.IMapDatabase.QueryResult;
|
||||||
import org.oscim.database.IMapDatabaseCallback;
|
import org.oscim.database.IMapDatabaseCallback;
|
||||||
import org.oscim.database.QueryResult;
|
|
||||||
import org.oscim.renderer.MapTile;
|
|
||||||
import org.oscim.renderer.layer.ExtrusionLayer;
|
import org.oscim.renderer.layer.ExtrusionLayer;
|
||||||
import org.oscim.renderer.layer.Layers;
|
import org.oscim.renderer.layer.Layers;
|
||||||
import org.oscim.renderer.layer.LineLayer;
|
import org.oscim.renderer.layer.LineLayer;
|
||||||
@ -71,12 +71,18 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
private static final Tag[] debugTagWay = { new Tag("debug", "way") };
|
private static final Tag[] debugTagWay = { new Tag("debug", "way") };
|
||||||
private static final Tag[] debugTagArea = { new Tag("debug", "area") };
|
private static final Tag[] debugTagArea = { new Tag("debug", "area") };
|
||||||
|
|
||||||
|
// replacement for variable value tags that should not be matched by RenderTheme
|
||||||
|
// FIXME make this general, maybe subclass tags
|
||||||
|
private static final Tag mTagEmptyName = new Tag(Tag.TAG_KEY_NAME, null, false);
|
||||||
|
private static final Tag mTagEmptyHouseNr = new Tag(Tag.TAG_KEY_HOUSE_NUMBER, null, false);
|
||||||
|
|
||||||
private final MapElement mDebugWay, mDebugPoint;
|
private final MapElement mDebugWay, mDebugPoint;
|
||||||
|
|
||||||
private static RenderTheme renderTheme;
|
|
||||||
private static int renderLevels;
|
|
||||||
private static DebugSettings debug;
|
private static DebugSettings debug;
|
||||||
|
|
||||||
|
private RenderTheme renderTheme;
|
||||||
|
private int renderLevels;
|
||||||
|
|
||||||
// current MapDatabase used by this TileGenerator
|
// current MapDatabase used by this TileGenerator
|
||||||
private IMapDatabase mMapDatabase;
|
private IMapDatabase mMapDatabase;
|
||||||
|
|
||||||
@ -95,16 +101,12 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
private float mLatScaleFactor;
|
private float mLatScaleFactor;
|
||||||
private float mGroundResolution;
|
private float mGroundResolution;
|
||||||
|
|
||||||
// replacement for variable value tags that should not be matched by RenderTheme
|
|
||||||
// FIXME make this general, maybe subclass tags
|
|
||||||
private final static Tag mTagEmptyName = new Tag(Tag.TAG_KEY_NAME, null, false);
|
|
||||||
private final static Tag mTagEmptyHouseNr = new Tag(Tag.TAG_KEY_HOUSE_NUMBER, null, false);
|
|
||||||
private Tag mTagName;
|
private Tag mTagName;
|
||||||
private Tag mTagHouseNr;
|
private Tag mTagHouseNr;
|
||||||
|
|
||||||
private final LineClipper mClipper;
|
private final LineClipper mClipper;
|
||||||
|
|
||||||
public static void setRenderTheme(RenderTheme theme) {
|
public void setRenderTheme(RenderTheme theme) {
|
||||||
renderTheme = theme;
|
renderTheme = theme;
|
||||||
renderLevels = theme.getLevels();
|
renderLevels = theme.getLevels();
|
||||||
}
|
}
|
||||||
@ -129,7 +131,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
m.tags = new Tag[] { new Tag("debug", "box") };
|
m.tags = new Tag[] { new Tag("debug", "box") };
|
||||||
m.geometryType = GEOM_LINE;
|
m.geometryType = GEOM_LINE;
|
||||||
|
|
||||||
m = mDebugPoint= new MapElement();
|
m = mDebugPoint = new MapElement();
|
||||||
m.startPoints();
|
m.startPoints();
|
||||||
m.addPoint(s >> 1, 10);
|
m.addPoint(s >> 1, 10);
|
||||||
m.geometryType = GEOM_POINT;
|
m.geometryType = GEOM_POINT;
|
||||||
@ -309,7 +311,6 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
mElement = null;
|
mElement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void debugUnmatched(boolean closed, Tag[] tags) {
|
private void debugUnmatched(boolean closed, Tag[] tags) {
|
||||||
Log.d(TAG, "DBG way not matched: " + closed + " "
|
Log.d(TAG, "DBG way not matched: " + closed + " "
|
||||||
+ Arrays.deepToString(tags));
|
+ Arrays.deepToString(tags));
|
||||||
332
src/org/oscim/layers/tile/TileLayer.java
Normal file
332
src/org/oscim/layers/tile/TileLayer.java
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.oscim.core.GeoPoint;
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.database.IMapDatabase;
|
||||||
|
import org.oscim.database.IMapDatabase.OpenResult;
|
||||||
|
import org.oscim.database.MapDatabaseFactory;
|
||||||
|
import org.oscim.database.MapDatabases;
|
||||||
|
import org.oscim.database.MapInfo;
|
||||||
|
import org.oscim.database.MapOptions;
|
||||||
|
import org.oscim.layers.Layer;
|
||||||
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
import org.oscim.theme.ExternalRenderTheme;
|
||||||
|
import org.oscim.theme.InternalRenderTheme;
|
||||||
|
import org.oscim.theme.RenderTheme;
|
||||||
|
import org.oscim.theme.RenderThemeHandler;
|
||||||
|
import org.oscim.theme.Theme;
|
||||||
|
import org.oscim.view.MapView;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class TileLayer extends Layer {
|
||||||
|
private final static String TAG = TileLayer.class.getName();
|
||||||
|
|
||||||
|
private boolean mClearMap = true;
|
||||||
|
|
||||||
|
private final TileManager mTileManager;
|
||||||
|
|
||||||
|
private final JobQueue mJobQueue;
|
||||||
|
// TODO use 1 download and 1 generator thread instead
|
||||||
|
private final MapWorker mMapWorkers[];
|
||||||
|
private final int mNumMapWorkers = 4;
|
||||||
|
private final TileGenerator mTileGenerators[];
|
||||||
|
|
||||||
|
public TileLayer(MapView mapView) {
|
||||||
|
super(mapView);
|
||||||
|
mTileManager = new TileManager(mapView, this);
|
||||||
|
mJobQueue = new JobQueue();
|
||||||
|
mMapWorkers = new MapWorker[mNumMapWorkers];
|
||||||
|
mTileGenerators = new TileGenerator[mNumMapWorkers];
|
||||||
|
|
||||||
|
TileGenerator.setDebugSettings(mapView.getDebugSettings());
|
||||||
|
|
||||||
|
for (int i = 0; i < mNumMapWorkers; i++) {
|
||||||
|
mTileGenerators[i] = new TileGenerator();
|
||||||
|
mMapWorkers[i] = new MapWorker(i, mJobQueue, mTileGenerators[i], mTileManager);
|
||||||
|
mMapWorkers[i].start();
|
||||||
|
}
|
||||||
|
|
||||||
|
mLayer = new TileRenderLayer(mapView, mTileManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TileRenderLayer getTileLayer(){
|
||||||
|
return (TileRenderLayer)mLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate(MapPosition mapPosition, boolean changed) {
|
||||||
|
|
||||||
|
if (mClearMap){
|
||||||
|
mTileManager.init(mMapView.getWidth(), mMapView.getHeight());
|
||||||
|
mClearMap = false;
|
||||||
|
changed = true;
|
||||||
|
Log.d(TAG, "init TileManager ----- ");
|
||||||
|
}
|
||||||
|
if (changed)
|
||||||
|
mTileManager.update(mapPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy(){
|
||||||
|
mTileManager.destroy();
|
||||||
|
|
||||||
|
for (MapWorker mapWorker : mMapWorkers) {
|
||||||
|
mapWorker.pause();
|
||||||
|
mapWorker.interrupt();
|
||||||
|
|
||||||
|
mapWorker.getTileGenerator().getMapDatabase().close();
|
||||||
|
|
||||||
|
try {
|
||||||
|
mapWorker.join(10000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// restore the interrupted status
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearMap() {
|
||||||
|
// clear tile and overlay data before next draw
|
||||||
|
mClearMap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapOptions mMapOptions;
|
||||||
|
private IMapDatabase mMapDatabase;
|
||||||
|
private String mRenderTheme;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the MapDatabase for this MapView.
|
||||||
|
*
|
||||||
|
* @param options
|
||||||
|
* the new MapDatabase options.
|
||||||
|
* @return true if MapDatabase changed
|
||||||
|
*/
|
||||||
|
public boolean setMapDatabase(MapOptions options) {
|
||||||
|
Log.i(TAG, "setMapDatabase: " + options.db.name());
|
||||||
|
|
||||||
|
if (mMapOptions != null && mMapOptions.equals(options))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
mapWorkersPause(true);
|
||||||
|
|
||||||
|
mJobQueue.clear();
|
||||||
|
mMapOptions = options;
|
||||||
|
|
||||||
|
mMapDatabase = null;
|
||||||
|
|
||||||
|
for (int i = 0; i < mNumMapWorkers; i++) {
|
||||||
|
MapWorker mapWorker = mMapWorkers[i];
|
||||||
|
|
||||||
|
IMapDatabase mapDatabase = MapDatabaseFactory
|
||||||
|
.createMapDatabase(options.db);
|
||||||
|
|
||||||
|
OpenResult result = mapDatabase.open(options);
|
||||||
|
|
||||||
|
if (result != OpenResult.SUCCESS) {
|
||||||
|
Log.d(TAG, "failed open db: " + result.getErrorMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
TileGenerator tileGenerator = mapWorker.getTileGenerator();
|
||||||
|
tileGenerator.setMapDatabase(mapDatabase);
|
||||||
|
|
||||||
|
// TODO this could be done in a cleaner way..
|
||||||
|
if (mMapDatabase == null)
|
||||||
|
mMapDatabase = mapDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.db == MapDatabases.OSCIMAP_READER ||
|
||||||
|
options.db == MapDatabases.MAP_READER ||
|
||||||
|
options.db == MapDatabases.TEST_READER)
|
||||||
|
MapView.enableClosePolygons = true;
|
||||||
|
else
|
||||||
|
MapView.enableClosePolygons = false;
|
||||||
|
|
||||||
|
clearMap();
|
||||||
|
|
||||||
|
mapWorkersProceed();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getMapOptions() {
|
||||||
|
return mMapOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapPosition getMapFileCenter() {
|
||||||
|
if (mMapDatabase == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
MapInfo mapInfo = mMapDatabase.getMapInfo();
|
||||||
|
if (mapInfo == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
GeoPoint startPos = mapInfo.startPosition;
|
||||||
|
|
||||||
|
if (startPos == null)
|
||||||
|
startPos = mapInfo.mapCenter;
|
||||||
|
|
||||||
|
if (startPos == null)
|
||||||
|
startPos = new GeoPoint(0, 0);
|
||||||
|
|
||||||
|
MapPosition mapPosition = new MapPosition();
|
||||||
|
mapPosition.setPosition(startPos);
|
||||||
|
|
||||||
|
if (mapInfo.startZoomLevel == null)
|
||||||
|
mapPosition.setZoomLevel(12);
|
||||||
|
else
|
||||||
|
mapPosition.setZoomLevel((mapInfo.startZoomLevel).byteValue());
|
||||||
|
|
||||||
|
return mapPosition;
|
||||||
|
}
|
||||||
|
public String getRenderTheme() {
|
||||||
|
return mRenderTheme;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the internal theme which is used for rendering the map.
|
||||||
|
*
|
||||||
|
* @param internalRenderTheme
|
||||||
|
* the internal rendering theme.
|
||||||
|
* @return ...
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if the supplied internalRenderTheme is null.
|
||||||
|
*/
|
||||||
|
public boolean setRenderTheme(InternalRenderTheme internalRenderTheme) {
|
||||||
|
if (internalRenderTheme == null) {
|
||||||
|
throw new IllegalArgumentException("render theme must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (internalRenderTheme.name() == mRenderTheme)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
boolean ret = setRenderTheme((Theme) internalRenderTheme);
|
||||||
|
if (ret) {
|
||||||
|
mRenderTheme = internalRenderTheme.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
clearMap();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the theme file which is used for rendering the map.
|
||||||
|
*
|
||||||
|
* @param renderThemePath
|
||||||
|
* the path to the XML file which defines the rendering theme.
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if the supplied internalRenderTheme is null.
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* if the supplied file does not exist, is a directory or cannot
|
||||||
|
* be read.
|
||||||
|
*/
|
||||||
|
public void setRenderTheme(String renderThemePath) throws FileNotFoundException {
|
||||||
|
if (renderThemePath == null) {
|
||||||
|
throw new IllegalArgumentException("render theme path must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ret = setRenderTheme(new ExternalRenderTheme(renderThemePath));
|
||||||
|
if (ret) {
|
||||||
|
mRenderTheme = renderThemePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean setRenderTheme(Theme theme) {
|
||||||
|
|
||||||
|
mapWorkersPause(true);
|
||||||
|
|
||||||
|
InputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
inputStream = theme.getRenderThemeAsStream();
|
||||||
|
RenderTheme t = RenderThemeHandler.getRenderTheme(inputStream);
|
||||||
|
t.scaleTextSize(1 + (MapView.dpi / 240 - 1) * 0.5f);
|
||||||
|
|
||||||
|
// FIXME !!!
|
||||||
|
GLRenderer.setRenderTheme(t);
|
||||||
|
|
||||||
|
for (TileGenerator g : mTileGenerators)
|
||||||
|
g.setRenderTheme(t);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (ParserConfigurationException e) {
|
||||||
|
Log.e(TAG, e.getMessage());
|
||||||
|
} catch (SAXException e) {
|
||||||
|
Log.e(TAG, e.getMessage());
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (inputStream != null) {
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, e.getMessage());
|
||||||
|
}
|
||||||
|
mapWorkersProceed();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* add jobs and remember MapWorkers that stuff needs to be done
|
||||||
|
*
|
||||||
|
* @param jobs
|
||||||
|
* tile jobs
|
||||||
|
*/
|
||||||
|
public void addJobs(JobTile[] jobs) {
|
||||||
|
if (jobs == null) {
|
||||||
|
mJobQueue.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mJobQueue.setJobs(jobs);
|
||||||
|
|
||||||
|
for (int i = 0; i < mNumMapWorkers; i++) {
|
||||||
|
MapWorker m = mMapWorkers[i];
|
||||||
|
synchronized (m) {
|
||||||
|
m.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mapWorkersPause(boolean wait) {
|
||||||
|
for (MapWorker mapWorker : mMapWorkers) {
|
||||||
|
if (!mapWorker.isPausing())
|
||||||
|
mapWorker.pause();
|
||||||
|
}
|
||||||
|
if (wait) {
|
||||||
|
for (MapWorker mapWorker : mMapWorkers) {
|
||||||
|
if (!mapWorker.isPausing())
|
||||||
|
mapWorker.awaitPausing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mapWorkersProceed() {
|
||||||
|
for (MapWorker mapWorker : mMapWorkers)
|
||||||
|
mapWorker.proceed();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,21 +13,24 @@
|
|||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oscim.renderer;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
import static org.oscim.generator.JobTile.STATE_LOADING;
|
import static org.oscim.layers.tile.JobTile.STATE_LOADING;
|
||||||
import static org.oscim.generator.JobTile.STATE_NEW_DATA;
|
import static org.oscim.layers.tile.JobTile.STATE_NEW_DATA;
|
||||||
import static org.oscim.generator.JobTile.STATE_NONE;
|
import static org.oscim.layers.tile.JobTile.STATE_NONE;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.generator.JobTile;
|
import org.oscim.renderer.BufferObject;
|
||||||
import org.oscim.generator.TileDistanceSort;
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
import org.oscim.renderer.ScanBox;
|
||||||
import org.oscim.renderer.layer.TextItem;
|
import org.oscim.renderer.layer.TextItem;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
|
import org.oscim.utils.quadtree.QuadTree;
|
||||||
|
import org.oscim.utils.quadtree.QuadTreeIndex;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
import org.oscim.view.MapViewPosition;
|
import org.oscim.view.MapViewPosition;
|
||||||
|
|
||||||
@ -40,6 +43,8 @@ import android.util.Log;
|
|||||||
* - make it general for reuse in tile-overlays
|
* - make it general for reuse in tile-overlays
|
||||||
*/
|
*/
|
||||||
public class TileManager {
|
public class TileManager {
|
||||||
|
private static final int CACHE_TILES_MAX = 250;
|
||||||
|
|
||||||
static final String TAG = TileManager.class.getSimpleName();
|
static final String TAG = TileManager.class.getSimpleName();
|
||||||
private final static int MAX_ZOOMLEVEL = 17;
|
private final static int MAX_ZOOMLEVEL = 17;
|
||||||
private final static int MIN_ZOOMLEVEL = 2;
|
private final static int MIN_ZOOMLEVEL = 2;
|
||||||
@ -71,21 +76,53 @@ public class TileManager {
|
|||||||
private final ArrayList<JobTile> mJobs;
|
private final ArrayList<JobTile> mJobs;
|
||||||
|
|
||||||
// counter to check whether current TileSet has changed
|
// counter to check whether current TileSet has changed
|
||||||
private static int mUpdateSerial;
|
private int mUpdateSerial;
|
||||||
|
|
||||||
// lock for TileSets while updating MapTile locks
|
// lock for TileSets while updating MapTile locks
|
||||||
private final Object mTilelock = new Object();
|
private final Object mTilelock = new Object();
|
||||||
|
|
||||||
|
// need to keep track of TileSets to clear on reset...
|
||||||
|
private final ArrayList<TileSet> mTileSets = new ArrayList<TileSet>(4);
|
||||||
|
|
||||||
private TileSet mCurrentTiles;
|
private TileSet mCurrentTiles;
|
||||||
/* package */TileSet mNewTiles;
|
/* package */TileSet mNewTiles;
|
||||||
|
|
||||||
private final float[] mBoxCoords = new float[8];
|
|
||||||
|
|
||||||
public TileManager(MapView mapView) {
|
private final QuadTreeIndex<MapTile> mIndex = new QuadTreeIndex<MapTile>(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapTile create(int x, int y, int z) {
|
||||||
|
QuadTree<MapTile> t = super.add(x, y, z);
|
||||||
|
t.item = new MapTile(x, y, (byte)z);
|
||||||
|
t.item.rel = t;
|
||||||
|
|
||||||
|
return t.item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(MapTile t) {
|
||||||
|
if (t.rel == null) {
|
||||||
|
Log.d(TAG, "BUG already removed " + t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.remove(t.rel);
|
||||||
|
|
||||||
|
t.rel.item = null;
|
||||||
|
t.rel = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final float[] mBoxCoords = new float[8];
|
||||||
|
private final TileLayer mTileLayer;
|
||||||
|
|
||||||
|
public TileManager(MapView mapView, TileLayer tileLayer) {
|
||||||
mMapView = mapView;
|
mMapView = mapView;
|
||||||
|
mTileLayer = tileLayer;
|
||||||
|
|
||||||
mMapViewPosition = mapView.getMapViewPosition();
|
mMapViewPosition = mapView.getMapViewPosition();
|
||||||
mJobs = new ArrayList<JobTile>();
|
mJobs = new ArrayList<JobTile>();
|
||||||
mTiles = new MapTile[GLRenderer.CACHE_TILES];
|
mTiles = new MapTile[CACHE_TILES_MAX];
|
||||||
|
|
||||||
mTilesSize = 0;
|
mTilesSize = 0;
|
||||||
mTilesForUpload = 0;
|
mTilesForUpload = 0;
|
||||||
@ -119,7 +156,7 @@ public class TileManager {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
// clear cache index
|
// clear cache index
|
||||||
QuadTree.init();
|
//QuadTree.init();
|
||||||
|
|
||||||
// clear references to cached MapTiles
|
// clear references to cached MapTiles
|
||||||
Arrays.fill(mTiles, null);
|
Arrays.fill(mTiles, null);
|
||||||
@ -160,7 +197,7 @@ public class TileManager {
|
|||||||
// start with old jobs while new jobs are calculated, which
|
// start with old jobs while new jobs are calculated, which
|
||||||
// should increase the chance that they are free when new
|
// should increase the chance that they are free when new
|
||||||
// jobs come in.
|
// jobs come in.
|
||||||
mMapView.addJobs(null);
|
mTileLayer.addJobs(null);
|
||||||
|
|
||||||
// load some tiles more than currently visible (* 0.75)
|
// load some tiles more than currently visible (* 0.75)
|
||||||
double scale = pos.scale * 0.9f;
|
double scale = pos.scale * 0.9f;
|
||||||
@ -223,11 +260,11 @@ public class TileManager {
|
|||||||
updateTileDistances(jobs, jobs.length, pos);
|
updateTileDistances(jobs, jobs.length, pos);
|
||||||
|
|
||||||
// sets tiles to state == LOADING
|
// sets tiles to state == LOADING
|
||||||
mMapView.addJobs(jobs);
|
mTileLayer.addJobs(jobs);
|
||||||
mJobs.clear();
|
mJobs.clear();
|
||||||
|
|
||||||
/* limit cache items */
|
/* limit cache items */
|
||||||
int remove = mTilesCount - GLRenderer.CACHE_TILES;
|
int remove = mTilesCount - CACHE_TILES_MAX;
|
||||||
|
|
||||||
if (remove > CACHE_THRESHOLD ||
|
if (remove > CACHE_THRESHOLD ||
|
||||||
mTilesForUpload > MAX_TILES_IN_QUEUE)
|
mTilesForUpload > MAX_TILES_IN_QUEUE)
|
||||||
@ -235,9 +272,13 @@ public class TileManager {
|
|||||||
limitCache(pos, remove);
|
limitCache(pos, remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to keep track of TileSets to clear on reset...
|
|
||||||
private static ArrayList<TileSet> mTileSets = new ArrayList<TileSet>(2);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrive a TileSet of current tiles.
|
||||||
|
* Tiles remain locked in cache until the set is unlocked by either passing
|
||||||
|
* it again to this function or to releaseTiles. If passed TileSet is null
|
||||||
|
* it will be allocated.
|
||||||
|
*/
|
||||||
public TileSet getActiveTiles(TileSet td) {
|
public TileSet getActiveTiles(TileSet td) {
|
||||||
if (mCurrentTiles == null)
|
if (mCurrentTiles == null)
|
||||||
return td;
|
return td;
|
||||||
@ -287,11 +328,11 @@ public class TileManager {
|
|||||||
/* package */MapTile addTile(int x, int y, int zoomLevel) {
|
/* package */MapTile addTile(int x, int y, int zoomLevel) {
|
||||||
MapTile tile;
|
MapTile tile;
|
||||||
|
|
||||||
tile = QuadTree.getTile(x, y, zoomLevel);
|
//tile = QuadTree.getTile(x, y, zoomLevel);
|
||||||
|
tile = mIndex.getTile(x, y, zoomLevel);
|
||||||
|
|
||||||
if (tile == null) {
|
if (tile == null) {
|
||||||
tile = new MapTile(x, y, (byte) zoomLevel);
|
tile = mIndex.create(x, y, zoomLevel);
|
||||||
QuadTree.add(tile);
|
|
||||||
mJobs.add(tile);
|
mJobs.add(tile);
|
||||||
addToCache(tile);
|
addToCache(tile);
|
||||||
} else if (!tile.isActive()) {
|
} else if (!tile.isActive()) {
|
||||||
@ -302,11 +343,11 @@ public class TileManager {
|
|||||||
boolean add = false;
|
boolean add = false;
|
||||||
|
|
||||||
// prefetch parent
|
// prefetch parent
|
||||||
MapTile p = tile.rel.parent.tile;
|
MapTile p = tile.rel.parent.item;
|
||||||
|
|
||||||
if (p == null) {
|
if (p == null) {
|
||||||
p = new MapTile(x >> 1, y >> 1, (byte) (zoomLevel - 1));
|
p = mIndex.create(x >> 1, y >> 1, zoomLevel - 1);
|
||||||
QuadTree.add(p);
|
|
||||||
addToCache(p);
|
addToCache(p);
|
||||||
add = true;
|
add = true;
|
||||||
}
|
}
|
||||||
@ -319,11 +360,10 @@ public class TileManager {
|
|||||||
|
|
||||||
if (zoomLevel > 3) {
|
if (zoomLevel > 3) {
|
||||||
// prefetch grand parent
|
// prefetch grand parent
|
||||||
p = tile.rel.parent.parent.tile;
|
p = tile.rel.parent.parent.item;
|
||||||
add = false;
|
add = false;
|
||||||
if (p == null) {
|
if (p == null) {
|
||||||
p = new MapTile(x >> 2, y >> 2, (byte) (zoomLevel - 2));
|
p = mIndex.create(x >> 2, y >> 2, zoomLevel - 2);
|
||||||
QuadTree.add(p);
|
|
||||||
addToCache(p);
|
addToCache(p);
|
||||||
add = true;
|
add = true;
|
||||||
}
|
}
|
||||||
@ -376,7 +416,9 @@ public class TileManager {
|
|||||||
|
|
||||||
TextItem.pool.releaseAll(t.labels);
|
TextItem.pool.releaseAll(t.labels);
|
||||||
|
|
||||||
QuadTree.remove(t);
|
mIndex.remove(t);
|
||||||
|
|
||||||
|
//QuadTree.remove(t);
|
||||||
t.state = STATE_NONE;
|
t.state = STATE_NONE;
|
||||||
|
|
||||||
mTilesCount--;
|
mTilesCount--;
|
||||||
@ -555,7 +597,7 @@ public class TileManager {
|
|||||||
private final ScanBox mScanBox = new ScanBox() {
|
private final ScanBox mScanBox = new ScanBox() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVisible(int y, int x1, int x2) {
|
protected void setVisible(int y, int x1, int x2) {
|
||||||
MapTile[] tiles = mNewTiles.tiles;
|
MapTile[] tiles = mNewTiles.tiles;
|
||||||
int cnt = mNewTiles.cnt;
|
int cnt = mNewTiles.cnt;
|
||||||
int maxTiles = tiles.length;
|
int maxTiles = tiles.length;
|
||||||
310
src/org/oscim/layers/tile/TileRenderLayer.java
Normal file
310
src/org/oscim/layers/tile/TileRenderLayer.java
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
|
import static org.oscim.layers.tile.JobTile.STATE_NEW_DATA;
|
||||||
|
import static org.oscim.layers.tile.JobTile.STATE_READY;
|
||||||
|
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.renderer.BufferObject;
|
||||||
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
import org.oscim.renderer.GLRenderer.Matrices;
|
||||||
|
import org.oscim.renderer.ScanBox;
|
||||||
|
import org.oscim.renderer.overlays.RenderOverlay;
|
||||||
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
public class TileRenderLayer extends RenderOverlay {
|
||||||
|
private final static String TAG = TileRenderLayer.class.getName();
|
||||||
|
|
||||||
|
private final float[] mBoxCoords;
|
||||||
|
private final TileManager mTileManager;
|
||||||
|
public TileRenderLayer(MapView mapView, TileManager tileManager) {
|
||||||
|
super(mapView);
|
||||||
|
mTileManager = tileManager;
|
||||||
|
mBoxCoords = new float[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(MapPosition curPos, boolean positionChanged, boolean tilesChanged,
|
||||||
|
Matrices matrices) {
|
||||||
|
int serial = 0;
|
||||||
|
|
||||||
|
mMapPosition.copy(curPos);
|
||||||
|
|
||||||
|
if (mDrawTiles != null)
|
||||||
|
serial = mDrawTiles.getSerial();
|
||||||
|
|
||||||
|
synchronized (tilelock) {
|
||||||
|
// get current tiles to draw
|
||||||
|
mDrawTiles = mTileManager.getActiveTiles(mDrawTiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mDrawTiles == null || mDrawTiles.cnt == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (positionChanged)
|
||||||
|
mMapView.getMapViewPosition().getMapViewProjection(mBoxCoords);
|
||||||
|
|
||||||
|
boolean changed = false;
|
||||||
|
//boolean positionChanged = false;
|
||||||
|
|
||||||
|
// check if the tiles have changed...
|
||||||
|
if (serial != mDrawTiles.getSerial()) {
|
||||||
|
changed = true;
|
||||||
|
// FIXME needed?
|
||||||
|
//positionChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tileCnt = mDrawTiles.cnt;
|
||||||
|
MapTile[] tiles = mDrawTiles.tiles;
|
||||||
|
|
||||||
|
if (changed || positionChanged)
|
||||||
|
updateTileVisibility();
|
||||||
|
|
||||||
|
tileCnt += mNumTileHolder;
|
||||||
|
|
||||||
|
/* prepare tile for rendering */
|
||||||
|
int uploadCnt = compileTileLayers(tiles, tileCnt);
|
||||||
|
|
||||||
|
tilesChanged |= (uploadCnt > 0);
|
||||||
|
|
||||||
|
TileRenderer.draw(tiles, tileCnt, curPos, matrices);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void compile() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(MapPosition pos, Matrices m) {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** compile tile layer data and upload to VBOs */
|
||||||
|
private static int compileTileLayers(MapTile[] tiles, int tileCnt) {
|
||||||
|
int uploadCnt = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
|
MapTile tile = tiles[i];
|
||||||
|
|
||||||
|
if (!tile.isVisible)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tile.state == STATE_READY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tile.state == STATE_NEW_DATA) {
|
||||||
|
uploadTileData(tile);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile.holder != null) {
|
||||||
|
// load tile that is referenced by this holder
|
||||||
|
if (tile.holder.state == STATE_NEW_DATA)
|
||||||
|
uploadTileData(tile.holder);
|
||||||
|
|
||||||
|
tile.state = tile.holder.state;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check near relatives than can serve as proxy
|
||||||
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
|
MapTile rel = tile.rel.parent.item;
|
||||||
|
if (rel.state == STATE_NEW_DATA)
|
||||||
|
uploadTileData(rel);
|
||||||
|
|
||||||
|
// dont load child proxies
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int c = 0; c < 4; c++) {
|
||||||
|
if ((tile.proxies & 1 << c) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MapTile rel = tile.rel.get(i);
|
||||||
|
if (rel != null && rel.state == STATE_NEW_DATA)
|
||||||
|
uploadTileData(rel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uploadCnt > 0)
|
||||||
|
GLRenderer.checkBufferUsage(false);
|
||||||
|
|
||||||
|
return uploadCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void uploadTileData(MapTile tile) {
|
||||||
|
tile.state = STATE_READY;
|
||||||
|
|
||||||
|
if (tile.layers == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int newSize = tile.layers.getSize();
|
||||||
|
if (newSize > 0) {
|
||||||
|
|
||||||
|
if (tile.layers.vbo == null)
|
||||||
|
tile.layers.vbo = BufferObject.get(newSize);
|
||||||
|
|
||||||
|
if (!GLRenderer.uploadLayers(tile.layers, newSize, true)) {
|
||||||
|
Log.d(TAG, "BUG uploadTileData " + tile + " failed!");
|
||||||
|
|
||||||
|
BufferObject.release(tile.layers.vbo);
|
||||||
|
tile.layers.vbo = null;
|
||||||
|
tile.layers.clear();
|
||||||
|
tile.layers = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Object tilelock = new Object();
|
||||||
|
|
||||||
|
/** set tile isVisible flag true for tiles that intersect view */
|
||||||
|
private void updateTileVisibility() {
|
||||||
|
|
||||||
|
// lock tiles while updating isVisible state
|
||||||
|
synchronized (tilelock) {
|
||||||
|
MapPosition pos = mMapPosition;
|
||||||
|
MapTile[] tiles = mDrawTiles.tiles;
|
||||||
|
|
||||||
|
int tileZoom = tiles[0].zoomLevel;
|
||||||
|
|
||||||
|
for (int i = 0; i < mDrawTiles.cnt; i++)
|
||||||
|
tiles[i].isVisible = false;
|
||||||
|
|
||||||
|
// count placeholder tiles
|
||||||
|
mNumTileHolder = 0;
|
||||||
|
|
||||||
|
// check visibile tiles
|
||||||
|
mScanBox.scan(pos.x, pos.y, pos.scale, tileZoom, mBoxCoords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a TileSet of currently visible tiles
|
||||||
|
public TileSet getVisibleTiles(TileSet td) {
|
||||||
|
if (mDrawTiles == null)
|
||||||
|
return td;
|
||||||
|
|
||||||
|
// ensure tiles keep visible state
|
||||||
|
synchronized (tilelock) {
|
||||||
|
|
||||||
|
MapTile[] newTiles = mDrawTiles.tiles;
|
||||||
|
int cnt = mDrawTiles.cnt;
|
||||||
|
|
||||||
|
if (td == null)
|
||||||
|
td = new TileSet(newTiles.length);
|
||||||
|
|
||||||
|
// unlock previous tiles
|
||||||
|
for (int i = 0; i < td.cnt; i++)
|
||||||
|
td.tiles[i].unlock();
|
||||||
|
|
||||||
|
// lock tiles to not be removed from cache
|
||||||
|
td.cnt = 0;
|
||||||
|
for (int i = 0; i < cnt; i++) {
|
||||||
|
MapTile t = newTiles[i];
|
||||||
|
if (t.isVisible && t.state == STATE_READY) {
|
||||||
|
t.lock();
|
||||||
|
td.tiles[td.cnt++] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return td;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void releaseTiles(TileSet td) {
|
||||||
|
for (int i = 0; i < td.cnt; i++) {
|
||||||
|
td.tiles[i].unlock();
|
||||||
|
td.tiles[i] = null;
|
||||||
|
}
|
||||||
|
td.cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add additional tiles that serve as placeholer when flipping
|
||||||
|
// over date-line.
|
||||||
|
// I dont really like this but cannot think of a better solution:
|
||||||
|
// the other option would be to run scanbox each time for upload,
|
||||||
|
// drawing, proxies and text layer. needing to add placeholder only
|
||||||
|
// happens rarely, unless you live on Fidschi
|
||||||
|
|
||||||
|
/* package */int mNumTileHolder;
|
||||||
|
/* package */TileSet mDrawTiles;
|
||||||
|
|
||||||
|
// scanline fill class used to check tile visibility
|
||||||
|
private final ScanBox mScanBox = new ScanBox() {
|
||||||
|
@Override
|
||||||
|
protected void setVisible(int y, int x1, int x2) {
|
||||||
|
int cnt = mDrawTiles.cnt;
|
||||||
|
|
||||||
|
MapTile[] tiles = mDrawTiles.tiles;
|
||||||
|
|
||||||
|
for (int i = 0; i < cnt; i++) {
|
||||||
|
MapTile t = tiles[i];
|
||||||
|
if (t.tileY == y && t.tileX >= x1 && t.tileX < x2)
|
||||||
|
t.isVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xmax = 1 << mZoom;
|
||||||
|
if (x1 >= 0 && x2 < xmax)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// add placeholder tiles to show both sides
|
||||||
|
// of date line. a little too complicated...
|
||||||
|
for (int x = x1; x < x2; x++) {
|
||||||
|
MapTile holder = null;
|
||||||
|
MapTile tile = null;
|
||||||
|
boolean found = false;
|
||||||
|
|
||||||
|
if (x >= 0 && x < xmax)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int xx = x;
|
||||||
|
if (x < 0)
|
||||||
|
xx = xmax + x;
|
||||||
|
else
|
||||||
|
xx = x - xmax;
|
||||||
|
|
||||||
|
if (xx < 0 || xx >= xmax)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int i = cnt; i < cnt + mNumTileHolder; i++)
|
||||||
|
if (tiles[i].tileX == x && tiles[i].tileY == y) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int i = 0; i < cnt; i++)
|
||||||
|
if (tiles[i].tileX == xx && tiles[i].tileY == y) {
|
||||||
|
tile = tiles[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
holder = new MapTile(x, y, (byte) mZoom);
|
||||||
|
holder.isVisible = true;
|
||||||
|
holder.holder = tile;
|
||||||
|
tile.isVisible = true;
|
||||||
|
tiles[cnt + mNumTileHolder++] = holder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -12,18 +12,23 @@
|
|||||||
* 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.renderer;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
||||||
import static android.opengl.GLES20.glStencilMask;
|
import static android.opengl.GLES20.glStencilMask;
|
||||||
import static org.oscim.generator.JobTile.STATE_READY;
|
import static org.oscim.layers.tile.JobTile.STATE_READY;
|
||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
|
import org.oscim.renderer.GLRenderer;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.GLRenderer.Matrices;
|
||||||
|
import org.oscim.renderer.LineRenderer;
|
||||||
|
import org.oscim.renderer.LineTexRenderer;
|
||||||
|
import org.oscim.renderer.PolygonRenderer;
|
||||||
import org.oscim.renderer.layer.Layer;
|
import org.oscim.renderer.layer.Layer;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.utils.Matrix4;
|
import org.oscim.utils.Matrix4;
|
||||||
|
import org.oscim.utils.quadtree.QuadTree;
|
||||||
|
|
||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
|
|
||||||
@ -56,6 +61,8 @@ public class TileRenderer {
|
|||||||
// discard z projection from tilt
|
// discard z projection from tilt
|
||||||
mProjMatrix.setValue(10, 0);
|
mProjMatrix.setValue(10, 0);
|
||||||
mProjMatrix.setValue(14, 0);
|
mProjMatrix.setValue(14, 0);
|
||||||
|
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
|
||||||
|
//GLES20.GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||||
|
|
||||||
@ -188,7 +195,7 @@ public class TileRenderer {
|
|||||||
if ((tile.proxies & 1 << i) == 0)
|
if ((tile.proxies & 1 << i) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MapTile c = tile.rel.child[i].tile;
|
MapTile c = tile.rel.get(i);
|
||||||
|
|
||||||
if (c.state == STATE_READY) {
|
if (c.state == STATE_READY) {
|
||||||
drawTile(c, pos);
|
drawTile(c, pos);
|
||||||
@ -200,10 +207,9 @@ public class TileRenderer {
|
|||||||
|
|
||||||
// just FIXME!
|
// just FIXME!
|
||||||
private static void drawProxyTile(MapTile tile, MapPosition pos, boolean parent, boolean preferParent) {
|
private static void drawProxyTile(MapTile tile, MapPosition pos, boolean parent, boolean preferParent) {
|
||||||
//int diff = pos.zoomLevel - tile.zoomLevel;
|
|
||||||
QuadTree r = tile.rel;
|
|
||||||
MapTile proxy;
|
|
||||||
|
|
||||||
|
QuadTree<MapTile> r = tile.rel;
|
||||||
|
MapTile proxy;
|
||||||
|
|
||||||
if (!preferParent) {
|
if (!preferParent) {
|
||||||
// prefer drawing children
|
// prefer drawing children
|
||||||
@ -213,7 +219,7 @@ public class TileRenderer {
|
|||||||
if (parent) {
|
if (parent) {
|
||||||
// draw parent proxy
|
// draw parent proxy
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
proxy = r.parent.tile;
|
proxy = r.parent.item;
|
||||||
if (proxy.state == STATE_READY) {
|
if (proxy.state == STATE_READY) {
|
||||||
//Log.d(TAG, "1. draw parent " + proxy);
|
//Log.d(TAG, "1. draw parent " + proxy);
|
||||||
drawTile(proxy, pos);
|
drawTile(proxy, pos);
|
||||||
@ -222,12 +228,12 @@ public class TileRenderer {
|
|||||||
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
||||||
// check if parent was already drawn
|
// check if parent was already drawn
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
proxy = r.parent.tile;
|
proxy = r.parent.item;
|
||||||
if (proxy.state == STATE_READY)
|
if (proxy.state == STATE_READY)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy = r.parent.parent.tile;
|
proxy = r.parent.parent.item;
|
||||||
if (proxy.state == STATE_READY)
|
if (proxy.state == STATE_READY)
|
||||||
drawTile(proxy, pos);
|
drawTile(proxy, pos);
|
||||||
}
|
}
|
||||||
@ -235,7 +241,7 @@ public class TileRenderer {
|
|||||||
// prefer drawing parent
|
// prefer drawing parent
|
||||||
if (parent) {
|
if (parent) {
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
proxy = r.parent.tile;
|
proxy = r.parent.item;
|
||||||
if (proxy != null && proxy.state == STATE_READY) {
|
if (proxy != null && proxy.state == STATE_READY) {
|
||||||
//Log.d(TAG, "2. draw parent " + proxy);
|
//Log.d(TAG, "2. draw parent " + proxy);
|
||||||
drawTile(proxy, pos);
|
drawTile(proxy, pos);
|
||||||
@ -248,7 +254,7 @@ public class TileRenderer {
|
|||||||
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
||||||
// check if parent was already drawn
|
// check if parent was already drawn
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
proxy = r.parent.tile;
|
proxy = r.parent.item;
|
||||||
if (proxy.state == STATE_READY)
|
if (proxy.state == STATE_READY)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -256,7 +262,7 @@ public class TileRenderer {
|
|||||||
if (drawProxyChild(tile, pos) > 0)
|
if (drawProxyChild(tile, pos) > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
proxy = r.parent.parent.tile;
|
proxy = r.parent.parent.item;
|
||||||
if (proxy.state == STATE_READY)
|
if (proxy.state == STATE_READY)
|
||||||
drawTile(proxy, pos);
|
drawTile(proxy, pos);
|
||||||
}
|
}
|
||||||
@ -12,10 +12,11 @@
|
|||||||
* 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.renderer;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* use with TileManager.getActiveTiles(TileSet) to get the current tiles. tiles
|
* use with TileManager.getActiveTiles(TileSet) to get the current tiles. tiles
|
||||||
* are locked to not be modifed until getActiveTiles passes them back on a
|
* are locked to not be modifed until getActiveTiles passes them back on a
|
||||||
@ -27,10 +28,14 @@ public final class TileSet {
|
|||||||
|
|
||||||
int serial;
|
int serial;
|
||||||
|
|
||||||
|
public int getSerial(){
|
||||||
|
return serial;
|
||||||
|
}
|
||||||
|
|
||||||
TileSet() {
|
TileSet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TileSet(int numTiles) {
|
public TileSet(int numTiles) {
|
||||||
tiles = new MapTile[numTiles];
|
tiles = new MapTile[numTiles];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,10 +13,9 @@
|
|||||||
* 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.generator;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.MapTile;
|
|
||||||
import org.oscim.renderer.layer.TextItem;
|
import org.oscim.renderer.layer.TextItem;
|
||||||
import org.oscim.theme.renderinstruction.Text;
|
import org.oscim.theme.renderinstruction.Text;
|
||||||
import org.oscim.utils.GeometryUtils;
|
import org.oscim.utils.GeometryUtils;
|
||||||
@ -30,9 +30,9 @@ public class BuildingOverlay extends Overlay {
|
|||||||
|
|
||||||
final ExtrusionOverlay mExtLayer;
|
final ExtrusionOverlay mExtLayer;
|
||||||
|
|
||||||
public BuildingOverlay(MapView mapView) {
|
public BuildingOverlay(MapView mapView, org.oscim.layers.tile.TileRenderLayer tileRenderLayer) {
|
||||||
super(mapView);
|
super(mapView);
|
||||||
mExtLayer = new ExtrusionOverlay(mapView);
|
mExtLayer = new ExtrusionOverlay(mapView, tileRenderLayer);
|
||||||
mLayer = mExtLayer;
|
mLayer = mExtLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.overlay;
|
package org.oscim.overlay;
|
||||||
|
|
||||||
|
import org.oscim.layers.tile.TileRenderLayer;
|
||||||
import org.oscim.renderer.overlays.TextOverlay;
|
import org.oscim.renderer.overlays.TextOverlay;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
@ -27,9 +28,9 @@ public class LabelingOverlay extends Overlay {
|
|||||||
private final static String TAG = LabelingOverlay.class.getName();
|
private final static String TAG = LabelingOverlay.class.getName();
|
||||||
final TextOverlay mTextLayer;
|
final TextOverlay mTextLayer;
|
||||||
|
|
||||||
public LabelingOverlay(MapView mapView) {
|
public LabelingOverlay(MapView mapView, TileRenderLayer tileRenderLayer) {
|
||||||
super(mapView);
|
super(mapView);
|
||||||
mTextLayer = new TextOverlay(mapView);
|
mTextLayer = new TextOverlay(mapView, tileRenderLayer);
|
||||||
mLayer = mTextLayer;
|
mLayer = mTextLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,14 +16,10 @@
|
|||||||
|
|
||||||
package org.oscim.overlay;
|
package org.oscim.overlay;
|
||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
|
||||||
import org.oscim.core.PointF;
|
import org.oscim.core.PointF;
|
||||||
import org.oscim.renderer.overlays.RenderOverlay;
|
import org.oscim.layers.InputLayer;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class representing an overlay which may be displayed on top of a
|
* Base class representing an overlay which may be displayed on top of a
|
||||||
* {@link MapView}. To add an overlay, subclass this class, create an instance,
|
* {@link MapView}. To add an overlay, subclass this class, create an instance,
|
||||||
@ -34,85 +30,37 @@ import android.view.MotionEvent;
|
|||||||
*
|
*
|
||||||
* @author Nicolas Gramlich
|
* @author Nicolas Gramlich
|
||||||
*/
|
*/
|
||||||
public abstract class Overlay {
|
public abstract class Overlay extends InputLayer {
|
||||||
|
|
||||||
// ===========================================================
|
|
||||||
// Constants
|
|
||||||
// ===========================================================
|
|
||||||
|
|
||||||
//private static AtomicInteger sOrdinal = new AtomicInteger();
|
|
||||||
|
|
||||||
// From Google Maps API
|
|
||||||
//protected static final float SHADOW_X_SKEW = -0.8999999761581421f;
|
|
||||||
//protected static final float SHADOW_Y_SCALE = 0.5f;
|
|
||||||
|
|
||||||
// ===========================================================
|
|
||||||
// Fields
|
|
||||||
// ===========================================================
|
|
||||||
|
|
||||||
private boolean mEnabled = true;
|
|
||||||
private boolean mReceiveEvents = true;
|
|
||||||
|
|
||||||
protected final MapView mMapView;
|
|
||||||
|
|
||||||
/** RenderOverlay used to draw this layer. To be implemented by sub-classes */
|
|
||||||
protected RenderOverlay mLayer;
|
|
||||||
|
|
||||||
public RenderOverlay getLayer() {
|
|
||||||
return mLayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================
|
|
||||||
// Constructors
|
|
||||||
// ===========================================================
|
|
||||||
|
|
||||||
public Overlay(MapView mapView) {
|
public Overlay(MapView mapView) {
|
||||||
mMapView = mapView;
|
super(mapView);
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================
|
|
||||||
// Getter & Setter
|
|
||||||
// ===========================================================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets whether the Overlay is marked to be enabled. This setting does
|
|
||||||
* nothing by default, but should be checked before calling draw().
|
|
||||||
*
|
|
||||||
* @param pEnabled
|
|
||||||
* ...
|
|
||||||
*/
|
|
||||||
public void setEnabled(boolean pEnabled) {
|
|
||||||
mEnabled = pEnabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies if the Overlay is marked to be enabled. This should be checked
|
* TBD
|
||||||
* before calling draw().
|
*
|
||||||
|
* Interface definition for overlays that contain items that can be snapped
|
||||||
|
* to (for example, when the user invokes a zoom, this could be called
|
||||||
|
* allowing the user to snap the zoom to an interesting point.)
|
||||||
*
|
*
|
||||||
* @return true if the Overlay is marked enabled, false otherwise
|
|
||||||
*/
|
*/
|
||||||
public boolean isEnabled() {
|
public interface Snappable {
|
||||||
return mEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the Overlay is marked to be receive touch exents.
|
* Checks to see if the given x and y are close enough to an item
|
||||||
|
* resulting in snapping the current action (e.g. zoom) to the item.
|
||||||
*
|
*
|
||||||
* @param pEnabled
|
* @param x
|
||||||
* ...
|
* The x in screen coordinates.
|
||||||
|
* @param y
|
||||||
|
* The y in screen coordinates.
|
||||||
|
* @param snapPoint
|
||||||
|
* To be filled with the the interesting point (in screen
|
||||||
|
* coordinates) that is closest to the given x and y. Can be
|
||||||
|
* untouched if not snapping.
|
||||||
|
* @return Whether or not to snap to the interesting point.
|
||||||
*/
|
*/
|
||||||
public void setEnableEvents(boolean pEnabled) {
|
boolean onSnapToItem(int x, int y, PointF snapPoint);
|
||||||
mReceiveEvents = pEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies if the Overlay is marked to be enabled. This should be checked
|
|
||||||
* before calling draw().
|
|
||||||
*
|
|
||||||
* @return true if the Overlay is marked enabled, false otherwise
|
|
||||||
*/
|
|
||||||
public boolean eventsEnabled() {
|
|
||||||
return mReceiveEvents;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///**
|
///**
|
||||||
@ -139,256 +87,4 @@ public abstract class Overlay {
|
|||||||
//protected final static int getSafeMenuIdSequence(int count) {
|
//protected final static int getSafeMenuIdSequence(int count) {
|
||||||
// return sOrdinal.getAndAdd(count);
|
// return sOrdinal.getAndAdd(count);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// ===========================================================
|
|
||||||
// Methods
|
|
||||||
// ===========================================================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called before each frame render request.
|
|
||||||
*
|
|
||||||
* @param mapPosition
|
|
||||||
* current MapPosition
|
|
||||||
* @param changed
|
|
||||||
* true when MapPosition has changed since last call
|
|
||||||
*/
|
|
||||||
public void onUpdate(MapPosition mapPosition, boolean changed) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override to perform clean up of resources before shutdown. By default
|
|
||||||
* does nothing.
|
|
||||||
*/
|
|
||||||
public void onDetach() {
|
|
||||||
// FIXME call to this function is not implemented
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param keyCode
|
|
||||||
* ...
|
|
||||||
* @param event
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param keyCode
|
|
||||||
* ...
|
|
||||||
* @param event
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <b>You can prevent all(!) other Touch-related events from happening!</b><br />
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onTouchEvent(MotionEvent e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onTrackballEvent(MotionEvent e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** GestureDetector.OnDoubleTapListener **/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onDoubleTap(MotionEvent e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onDoubleTapEvent(MotionEvent e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onSingleTapConfirmed(MotionEvent e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** OnGestureListener **/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onDown(MotionEvent e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param pEvent1
|
|
||||||
* ...
|
|
||||||
* @param pEvent2
|
|
||||||
* ...
|
|
||||||
* @param pVelocityX
|
|
||||||
* ...
|
|
||||||
* @param pVelocityY
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onFling(MotionEvent pEvent1, MotionEvent pEvent2,
|
|
||||||
float pVelocityX, float pVelocityY) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onLongPress(MotionEvent e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param pEvent1
|
|
||||||
* ...
|
|
||||||
* @param pEvent2
|
|
||||||
* ...
|
|
||||||
* @param pDistanceX
|
|
||||||
* ...
|
|
||||||
* @param pDistanceY
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onScroll(MotionEvent pEvent1, MotionEvent pEvent2,
|
|
||||||
float pDistanceX, float pDistanceY) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param pEvent
|
|
||||||
* ...
|
|
||||||
*/
|
|
||||||
public void onShowPress(MotionEvent pEvent) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default does nothing (<code>return false</code>). If you handled the
|
|
||||||
* Event, return <code>true</code>, otherwise return <code>false</code>. If
|
|
||||||
* you returned <code>true</code> none of the following Overlays or the
|
|
||||||
* underlying {@link MapView} has the chance to handle this event.
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
* ...
|
|
||||||
* @return ...
|
|
||||||
*/
|
|
||||||
public boolean onSingleTapUp(MotionEvent e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===========================================================
|
|
||||||
// Inner and Anonymous Classes
|
|
||||||
// ===========================================================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface definition for overlays that contain items that can be snapped
|
|
||||||
* to (for example, when the user invokes a zoom, this could be called
|
|
||||||
* allowing the user to snap the zoom to an interesting point.)
|
|
||||||
*/
|
|
||||||
public interface Snappable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks to see if the given x and y are close enough to an item
|
|
||||||
* resulting in snapping the current action (e.g. zoom) to the item.
|
|
||||||
*
|
|
||||||
* @param x
|
|
||||||
* The x in screen coordinates.
|
|
||||||
* @param y
|
|
||||||
* The y in screen coordinates.
|
|
||||||
* @param snapPoint
|
|
||||||
* To be filled with the the interesting point (in screen
|
|
||||||
* coordinates) that is closest to the given x and y. Can be
|
|
||||||
* untouched if not snapping.
|
|
||||||
* @return Whether or not to snap to the interesting point.
|
|
||||||
*/
|
|
||||||
boolean onSnapToItem(int x, int y, PointF snapPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import org.oscim.core.MercatorProjection;
|
|||||||
import org.oscim.core.PointD;
|
import org.oscim.core.PointD;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.graphics.Paint.Cap;
|
import org.oscim.graphics.Paint.Cap;
|
||||||
|
import org.oscim.layers.Layer;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.GLRenderer.Matrices;
|
||||||
import org.oscim.renderer.layer.LineLayer;
|
import org.oscim.renderer.layer.LineLayer;
|
||||||
import org.oscim.renderer.overlays.BasicOverlay;
|
import org.oscim.renderer.overlays.BasicOverlay;
|
||||||
@ -34,7 +35,7 @@ import org.oscim.utils.LineClipper;
|
|||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
/** This class draws a path line in given color. */
|
/** This class draws a path line in given color. */
|
||||||
public class PathOverlay extends Overlay {
|
public class PathOverlay extends Layer {
|
||||||
|
|
||||||
/** Stores points, converted to the map projection. */
|
/** Stores points, converted to the map projection. */
|
||||||
/* package */protected final ArrayList<GeoPoint> mPoints;
|
/* package */protected final ArrayList<GeoPoint> mPoints;
|
||||||
|
|||||||
@ -18,8 +18,6 @@ import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
|||||||
import static android.opengl.GLES20.GL_DYNAMIC_DRAW;
|
import static android.opengl.GLES20.GL_DYNAMIC_DRAW;
|
||||||
import static android.opengl.GLES20.GL_ONE;
|
import static android.opengl.GLES20.GL_ONE;
|
||||||
import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
|
import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
|
||||||
import static org.oscim.generator.JobTile.STATE_NEW_DATA;
|
|
||||||
import static org.oscim.generator.JobTile.STATE_READY;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
@ -31,6 +29,7 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
|
import org.oscim.layers.tile.MapTile;
|
||||||
import org.oscim.renderer.layer.Layers;
|
import org.oscim.renderer.layer.Layers;
|
||||||
import org.oscim.renderer.layer.TextureItem;
|
import org.oscim.renderer.layer.TextureItem;
|
||||||
import org.oscim.renderer.overlays.RenderOverlay;
|
import org.oscim.renderer.overlays.RenderOverlay;
|
||||||
@ -62,7 +61,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
static int CACHE_TILES = CACHE_TILES_MAX;
|
static int CACHE_TILES = CACHE_TILES_MAX;
|
||||||
|
|
||||||
private static MapView mMapView;
|
private static MapView mMapView;
|
||||||
static int screenWidth, screenHeight;
|
public static int screenWidth, screenHeight;
|
||||||
|
|
||||||
private static MapViewPosition mMapViewPosition;
|
private static MapViewPosition mMapViewPosition;
|
||||||
private static MapPosition mMapPosition;
|
private static MapPosition mMapPosition;
|
||||||
@ -76,6 +75,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
private static float[] mBoxCoords;
|
private static float[] mBoxCoords;
|
||||||
|
|
||||||
public class Matrices {
|
public class Matrices {
|
||||||
|
// do not modify any of these
|
||||||
public final Matrix4 viewproj = new Matrix4();
|
public final Matrix4 viewproj = new Matrix4();
|
||||||
public final Matrix4 proj = new Matrix4();
|
public final Matrix4 proj = new Matrix4();
|
||||||
public final Matrix4 view = new Matrix4();
|
public final Matrix4 view = new Matrix4();
|
||||||
@ -89,88 +89,14 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
//private
|
//private
|
||||||
static float[] mClearColor = null;
|
static float[] mClearColor = null;
|
||||||
|
|
||||||
static int mQuadIndicesID;
|
public static int mQuadIndicesID;
|
||||||
final static int maxQuads = 64;
|
public final static int maxQuads = 64;
|
||||||
|
|
||||||
private static boolean mUpdateColor = false;
|
private static boolean mUpdateColor = false;
|
||||||
|
|
||||||
// drawlock to synchronize Main- and GL-Thread
|
// drawlock to synchronize Main- and GL-Thread
|
||||||
// static ReentrantLock tilelock = new ReentrantLock();
|
// static ReentrantLock tilelock = new ReentrantLock();
|
||||||
static ReentrantLock drawlock = new ReentrantLock();
|
public static ReentrantLock drawlock = new ReentrantLock();
|
||||||
|
|
||||||
// Add additional tiles that serve as placeholer when flipping
|
|
||||||
// over date-line.
|
|
||||||
// I dont really like this but cannot think of a better solution:
|
|
||||||
// the other option would be to run scanbox each time for upload,
|
|
||||||
// drawing, proxies and text layer. needing to add placeholder only
|
|
||||||
// happens rarely, unless you live on Fidschi
|
|
||||||
|
|
||||||
/* package */static int mNumTileHolder;
|
|
||||||
/* package */static TileSet mDrawTiles;
|
|
||||||
|
|
||||||
// scanline fill class used to check tile visibility
|
|
||||||
private static ScanBox mScanBox = new ScanBox() {
|
|
||||||
@Override
|
|
||||||
void setVisible(int y, int x1, int x2) {
|
|
||||||
int cnt = mDrawTiles.cnt;
|
|
||||||
|
|
||||||
MapTile[] tiles = mDrawTiles.tiles;
|
|
||||||
|
|
||||||
for (int i = 0; i < cnt; i++) {
|
|
||||||
MapTile t = tiles[i];
|
|
||||||
if (t.tileY == y && t.tileX >= x1 && t.tileX < x2)
|
|
||||||
t.isVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xmax = 1 << mZoom;
|
|
||||||
if (x1 >= 0 && x2 < xmax)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// add placeholder tiles to show both sides
|
|
||||||
// of date line. a little too complicated...
|
|
||||||
for (int x = x1; x < x2; x++) {
|
|
||||||
MapTile holder = null;
|
|
||||||
MapTile tile = null;
|
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
if (x >= 0 && x < xmax)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int xx = x;
|
|
||||||
if (x < 0)
|
|
||||||
xx = xmax + x;
|
|
||||||
else
|
|
||||||
xx = x - xmax;
|
|
||||||
|
|
||||||
if (xx < 0 || xx >= xmax)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (int i = cnt; i < cnt + mNumTileHolder; i++)
|
|
||||||
if (tiles[i].tileX == x && tiles[i].tileY == y) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (int i = 0; i < cnt; i++)
|
|
||||||
if (tiles[i].tileX == xx && tiles[i].tileY == y) {
|
|
||||||
tile = tiles[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
holder = new MapTile(x, y, (byte) mZoom);
|
|
||||||
holder.isVisible = true;
|
|
||||||
holder.holder = tile;
|
|
||||||
tile.isVisible = true;
|
|
||||||
tiles[cnt + mNumTileHolder++] = holder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mapView
|
* @param mapView
|
||||||
@ -204,8 +130,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
mUpdateColor = true;
|
mUpdateColor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int uploadCnt = 0;
|
|
||||||
|
|
||||||
public static boolean uploadLayers(Layers layers, int newSize,
|
public static boolean uploadLayers(Layers layers, int newSize,
|
||||||
boolean addFill) {
|
boolean addFill) {
|
||||||
|
|
||||||
@ -258,7 +182,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkBufferUsage(boolean force) {
|
public static void checkBufferUsage(boolean force) {
|
||||||
// try to clear some unused vbo when exceding limit
|
// try to clear some unused vbo when exceding limit
|
||||||
|
|
||||||
if (!force && mBufferMemoryUsage < LIMIT_BUFFERS) {
|
if (!force && mBufferMemoryUsage < LIMIT_BUFFERS) {
|
||||||
@ -300,100 +224,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object tilelock = new Object();
|
|
||||||
|
|
||||||
/** set tile isVisible flag true for tiles that intersect view */
|
|
||||||
private static void updateTileVisibility() {
|
|
||||||
MapPosition pos = mMapPosition;
|
|
||||||
MapTile[] tiles = mDrawTiles.tiles;
|
|
||||||
|
|
||||||
// lock tiles while updating isVisible state
|
|
||||||
synchronized (GLRenderer.tilelock) {
|
|
||||||
int tileZoom = tiles[0].zoomLevel;
|
|
||||||
|
|
||||||
for (int i = 0; i < mDrawTiles.cnt; i++)
|
|
||||||
tiles[i].isVisible = false;
|
|
||||||
|
|
||||||
// count placeholder tiles
|
|
||||||
mNumTileHolder = 0;
|
|
||||||
|
|
||||||
// check visibile tiles
|
|
||||||
mScanBox.scan(pos.x, pos.y, pos.scale, tileZoom, mBoxCoords);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void uploadTileData(MapTile tile) {
|
|
||||||
tile.state = STATE_READY;
|
|
||||||
|
|
||||||
if (tile.layers == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int newSize = tile.layers.getSize();
|
|
||||||
if (newSize > 0) {
|
|
||||||
|
|
||||||
if (tile.layers.vbo == null)
|
|
||||||
tile.layers.vbo = BufferObject.get(newSize);
|
|
||||||
|
|
||||||
if (!uploadLayers(tile.layers, newSize, true)) {
|
|
||||||
Log.d(TAG, "BUG uploadTileData " + tile + " failed!");
|
|
||||||
|
|
||||||
BufferObject.release(tile.layers.vbo);
|
|
||||||
tile.layers.vbo = null;
|
|
||||||
tile.layers.clear();
|
|
||||||
tile.layers = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** compile tile layer data and upload to VBOs */
|
|
||||||
private static void compileTileLayers(MapTile[] tiles, int tileCnt) {
|
|
||||||
uploadCnt = 0;
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
|
||||||
MapTile tile = tiles[i];
|
|
||||||
|
|
||||||
if (!tile.isVisible)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tile.state == STATE_READY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tile.state == STATE_NEW_DATA) {
|
|
||||||
uploadTileData(tile);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile.holder != null) {
|
|
||||||
// load tile that is referenced by this holder
|
|
||||||
if (tile.holder.state == STATE_NEW_DATA)
|
|
||||||
uploadTileData(tile.holder);
|
|
||||||
|
|
||||||
tile.state = tile.holder.state;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check near relatives than can serve as proxy
|
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
|
||||||
MapTile rel = tile.rel.parent.tile;
|
|
||||||
if (rel.state == STATE_NEW_DATA)
|
|
||||||
uploadTileData(rel);
|
|
||||||
|
|
||||||
// dont load child proxies
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int c = 0; c < 4; c++) {
|
|
||||||
if ((tile.proxies & 1 << c) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MapTile rel = tile.rel.child[c].tile;
|
|
||||||
if (rel != null && rel.state == STATE_NEW_DATA)
|
|
||||||
uploadTileData(rel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uploadCnt > 0)
|
|
||||||
checkBufferUsage(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void draw() {
|
private static void draw() {
|
||||||
long start = 0;
|
long start = 0;
|
||||||
@ -407,35 +238,14 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
mUpdateColor = false;
|
mUpdateColor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: it seems faster to also clear the stencil buffer even
|
|
||||||
// when not needed. probaly otherwise it is masked out from the
|
|
||||||
// depth buffer as they share the same memory region afaik
|
|
||||||
// or for a better reason see OpenGL Insights chapter 23.
|
|
||||||
GLES20.glDepthMask(true);
|
GLES20.glDepthMask(true);
|
||||||
GLES20.glStencilMask(0xFF);
|
GLES20.glStencilMask(0xFF);
|
||||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT
|
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT
|
||||||
| GLES20.GL_DEPTH_BUFFER_BIT
|
| GLES20.GL_DEPTH_BUFFER_BIT
|
||||||
| GLES20.GL_STENCIL_BUFFER_BIT);
|
| GLES20.GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
int serial = 0;
|
boolean tilesChanged = true;
|
||||||
if (mDrawTiles != null)
|
boolean positionChanged = true;
|
||||||
serial = mDrawTiles.serial;
|
|
||||||
|
|
||||||
// get current tiles to draw
|
|
||||||
mDrawTiles = mMapView.getTileManager().getActiveTiles(mDrawTiles);
|
|
||||||
|
|
||||||
if (mDrawTiles == null || mDrawTiles.cnt == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
boolean tilesChanged = false;
|
|
||||||
boolean positionChanged = false;
|
|
||||||
|
|
||||||
// check if the tiles have changed...
|
|
||||||
if (serial != mDrawTiles.serial) {
|
|
||||||
tilesChanged = true;
|
|
||||||
// FIXME needed?
|
|
||||||
positionChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get current MapPosition, set mBoxCoords (mapping of screen to model
|
// get current MapPosition, set mBoxCoords (mapping of screen to model
|
||||||
// coordinates)
|
// coordinates)
|
||||||
@ -457,38 +267,22 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int tileCnt = mDrawTiles.cnt;
|
|
||||||
MapTile[] tiles = mDrawTiles.tiles;
|
|
||||||
|
|
||||||
if (positionChanged)
|
|
||||||
updateTileVisibility();
|
|
||||||
|
|
||||||
tileCnt += mNumTileHolder;
|
|
||||||
|
|
||||||
/* prepare tile for rendering */
|
|
||||||
compileTileLayers(tiles, tileCnt);
|
|
||||||
|
|
||||||
tilesChanged |= (uploadCnt > 0);
|
|
||||||
|
|
||||||
/* update overlays */
|
/* update overlays */
|
||||||
RenderOverlay[] overlays = mMapView.getOverlayManager().getRenderLayers();
|
RenderOverlay[] overlays = mMapView.getOverlayManager().getRenderLayers();
|
||||||
|
|
||||||
for (int i = 0, n = overlays.length; i < n; i++)
|
for (int i = 0, n = overlays.length; i < n; i++)
|
||||||
overlays[i].update(mMapPosition, positionChanged, tilesChanged, mMatrices);
|
overlays[i].update(mMapPosition, positionChanged, tilesChanged, mMatrices);
|
||||||
|
|
||||||
/* draw base layer */
|
|
||||||
TileRenderer.draw(tiles, tileCnt, pos, mMatrices);
|
|
||||||
|
|
||||||
/* draw overlays */
|
/* draw overlays */
|
||||||
for (int i = 0, n = overlays.length; i < n; i++) {
|
for (int i = 0, n = overlays.length; i < n; i++) {
|
||||||
RenderOverlay renderOverlay = overlays[i];
|
RenderOverlay renderLayer = overlays[i];
|
||||||
|
|
||||||
if (renderOverlay.newData) {
|
if (renderLayer.newData) {
|
||||||
renderOverlay.compile();
|
renderLayer.compile();
|
||||||
renderOverlay.newData = false;
|
renderLayer.newData = false;
|
||||||
}
|
}
|
||||||
if (renderOverlay.isReady)
|
if (renderLayer.isReady)
|
||||||
renderOverlay.render(mMapPosition, mMatrices);
|
renderLayer.render(mMapPosition, mMatrices);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MapView.debugFrameTime) {
|
if (MapView.debugFrameTime) {
|
||||||
@ -506,44 +300,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
return ((t.tileX % 4) + (t.tileY % 4 * 4) + 1);
|
return ((t.tileX % 4) + (t.tileY % 4 * 4) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a TileSet of currently visible tiles
|
|
||||||
public static TileSet getVisibleTiles(TileSet td) {
|
|
||||||
if (mDrawTiles == null)
|
|
||||||
return td;
|
|
||||||
|
|
||||||
// ensure tiles keep visible state
|
|
||||||
synchronized (GLRenderer.tilelock) {
|
|
||||||
MapTile[] newTiles = mDrawTiles.tiles;
|
|
||||||
int cnt = mDrawTiles.cnt;
|
|
||||||
|
|
||||||
if (td == null)
|
|
||||||
td = new TileSet(newTiles.length);
|
|
||||||
|
|
||||||
// unlock previous tiles
|
|
||||||
for (int i = 0; i < td.cnt; i++)
|
|
||||||
td.tiles[i].unlock();
|
|
||||||
|
|
||||||
// lock tiles to not be removed from cache
|
|
||||||
td.cnt = 0;
|
|
||||||
for (int i = 0; i < cnt; i++) {
|
|
||||||
MapTile t = newTiles[i];
|
|
||||||
if (t.isVisible && t.state == STATE_READY) {
|
|
||||||
t.lock();
|
|
||||||
td.tiles[td.cnt++] = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return td;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void releaseTiles(TileSet td) {
|
|
||||||
for (int i = 0; i < td.cnt; i++) {
|
|
||||||
td.tiles[i].unlock();
|
|
||||||
td.tiles[i] = null;
|
|
||||||
}
|
|
||||||
td.cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
|
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
|
||||||
Log.d(TAG, "SurfaceChanged:" + mNewSurface + " " + width + "x" + height);
|
Log.d(TAG, "SurfaceChanged:" + mNewSurface + " " + width + "x" + height);
|
||||||
@ -608,7 +364,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
mBufferMemoryUsage = 0;
|
mBufferMemoryUsage = 0;
|
||||||
mDrawTiles = null;
|
//mDrawTiles = null;
|
||||||
|
|
||||||
int numTiles = (screenWidth / (Tile.SIZE / 2) + 2)
|
int numTiles = (screenWidth / (Tile.SIZE / 2) + 2)
|
||||||
* (screenHeight / (Tile.SIZE / 2) + 2);
|
* (screenHeight / (Tile.SIZE / 2) + 2);
|
||||||
@ -624,18 +380,21 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
|
|
||||||
mMapView.redrawMap(true);
|
mMapView.redrawMap(true);
|
||||||
}
|
}
|
||||||
|
public static void initRenderer() {
|
||||||
@Override
|
|
||||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
|
||||||
// String ext = GLES20.glGetString(GLES20.GL_EXTENSIONS);
|
|
||||||
// Log.d(TAG, "Extensions: " + ext);
|
|
||||||
|
|
||||||
// classes that require GL context for initialization
|
|
||||||
LineRenderer.init();
|
LineRenderer.init();
|
||||||
LineTexRenderer.init();
|
LineTexRenderer.init();
|
||||||
PolygonRenderer.init();
|
PolygonRenderer.init();
|
||||||
TextureRenderer.init();
|
TextureRenderer.init();
|
||||||
|
|
||||||
TextureItem.init(10);
|
TextureItem.init(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||||
|
// Log.d(TAG, GLES20.glGetString(GLES20.GL_EXTENSIONS));
|
||||||
|
|
||||||
|
// classes that require GL context for initialization
|
||||||
|
initRenderer();
|
||||||
|
|
||||||
mNewSurface = true;
|
mNewSurface = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,148 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.renderer;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class QuadTree {
|
|
||||||
private static String TAG = QuadTree.class.getName();
|
|
||||||
|
|
||||||
// pointer to tile 0/0/0
|
|
||||||
private static QuadTree root;
|
|
||||||
|
|
||||||
// parent pointer is used to link pool items
|
|
||||||
private static QuadTree pool;
|
|
||||||
|
|
||||||
public QuadTree parent;
|
|
||||||
// .... x y
|
|
||||||
// 0 => 0 0
|
|
||||||
// 1 => 1 0
|
|
||||||
// 2 => 0 1
|
|
||||||
// 3 => 1 1
|
|
||||||
public final QuadTree[] child = new QuadTree[4];
|
|
||||||
int refs = 0;
|
|
||||||
byte id;
|
|
||||||
public MapTile tile;
|
|
||||||
|
|
||||||
static void init() {
|
|
||||||
pool = null;
|
|
||||||
root = new QuadTree();
|
|
||||||
root.parent = root;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean remove(MapTile t) {
|
|
||||||
if (t.rel == null) {
|
|
||||||
// Bad Things(tm) happened
|
|
||||||
Log.d(TAG, "BUG already removed " + t);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QuadTree cur = t.rel;
|
|
||||||
QuadTree next;
|
|
||||||
|
|
||||||
for (; cur != root;) {
|
|
||||||
// keep pointer to parent
|
|
||||||
next = cur.parent;
|
|
||||||
cur.refs--;
|
|
||||||
|
|
||||||
// if current node has no children
|
|
||||||
if (cur.refs == 0) {
|
|
||||||
// unhook from parent
|
|
||||||
next.child[cur.id] = null;
|
|
||||||
|
|
||||||
// add item back to pool
|
|
||||||
cur.parent = pool;
|
|
||||||
pool = cur;
|
|
||||||
}
|
|
||||||
cur = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
root.refs--;
|
|
||||||
|
|
||||||
t.rel.tile = null;
|
|
||||||
t.rel = null;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QuadTree add(MapTile tile) {
|
|
||||||
|
|
||||||
int x = tile.tileX;
|
|
||||||
int y = tile.tileY;
|
|
||||||
int z = tile.zoomLevel;
|
|
||||||
|
|
||||||
// if (x < 0 || x >= 1 << z) {
|
|
||||||
// Log.d(TAG, "invalid position");
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// if (y < 0 || y >= 1 << z) {
|
|
||||||
// Log.d(TAG, "invalid position");
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
|
|
||||||
QuadTree leaf = root;
|
|
||||||
|
|
||||||
for (int level = z - 1; level >= 0; level--) {
|
|
||||||
|
|
||||||
int id = ((x >> level) & 1) | ((y >> level) & 1) << 1;
|
|
||||||
|
|
||||||
leaf.refs++;
|
|
||||||
|
|
||||||
QuadTree cur = leaf.child[id];
|
|
||||||
|
|
||||||
if (cur != null) {
|
|
||||||
leaf = cur;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pool != null) {
|
|
||||||
cur = pool;
|
|
||||||
pool = pool.parent;
|
|
||||||
} else {
|
|
||||||
cur = new QuadTree();
|
|
||||||
}
|
|
||||||
|
|
||||||
cur.refs = 0;
|
|
||||||
cur.id = (byte) id;
|
|
||||||
cur.parent = leaf;
|
|
||||||
cur.parent.child[id] = cur;
|
|
||||||
|
|
||||||
leaf = cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
leaf.refs++;
|
|
||||||
leaf.tile = tile;
|
|
||||||
tile.rel = leaf;
|
|
||||||
|
|
||||||
return leaf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MapTile getTile(int x, int y, int z) {
|
|
||||||
QuadTree leaf = root;
|
|
||||||
|
|
||||||
for (int level = z - 1; level >= 0; level--) {
|
|
||||||
|
|
||||||
leaf = leaf.child[((x >> level) & 1) | ((y >> level) & 1) << 1];
|
|
||||||
|
|
||||||
if (leaf == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (level == 0) {
|
|
||||||
return leaf.tile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -78,7 +78,7 @@ public abstract class ScanBox {
|
|||||||
|
|
||||||
protected int mZoom;
|
protected int mZoom;
|
||||||
|
|
||||||
abstract void setVisible(int y, int x1, int x2);
|
protected abstract void setVisible(int y, int x1, int x2);
|
||||||
|
|
||||||
public void scan(double x, double y, double scale, int zoom, float[] box) {
|
public void scan(double x, double y, double scale, int zoom, float[] box) {
|
||||||
mZoom = zoom;
|
mZoom = zoom;
|
||||||
|
|||||||
@ -20,12 +20,13 @@ import java.nio.ShortBuffer;
|
|||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.generator.JobTile;
|
import org.oscim.layers.tile.JobTile;
|
||||||
|
import org.oscim.layers.tile.MapTile;
|
||||||
|
import org.oscim.layers.tile.TileRenderLayer;
|
||||||
|
import org.oscim.layers.tile.TileSet;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.GLRenderer;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.GLRenderer.Matrices;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.MapTile;
|
|
||||||
import org.oscim.renderer.TileSet;
|
|
||||||
import org.oscim.renderer.layer.ExtrusionLayer;
|
import org.oscim.renderer.layer.ExtrusionLayer;
|
||||||
import org.oscim.utils.GlUtils;
|
import org.oscim.utils.GlUtils;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
@ -39,8 +40,11 @@ import android.util.Log;
|
|||||||
public class ExtrusionOverlay extends RenderOverlay {
|
public class ExtrusionOverlay extends RenderOverlay {
|
||||||
private final static String TAG = ExtrusionOverlay.class.getName();
|
private final static String TAG = ExtrusionOverlay.class.getName();
|
||||||
|
|
||||||
public ExtrusionOverlay(MapView mapView) {
|
private final TileRenderLayer mTileLayer;
|
||||||
|
|
||||||
|
public ExtrusionOverlay(MapView mapView, org.oscim.layers.tile.TileRenderLayer tileRenderLayer) {
|
||||||
super(mapView);
|
super(mapView);
|
||||||
|
mTileLayer = tileRenderLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] shaderProgram = new int[2];
|
private static int[] shaderProgram = new int[2];
|
||||||
@ -92,7 +96,10 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ready = 0;
|
int ready = 0;
|
||||||
mTileSet = mMapView.getTileManager().getActiveTiles(mTileSet);
|
mTileSet = mTileLayer.getVisibleTiles(mTileSet);
|
||||||
|
if (mTileSet == null)
|
||||||
|
return;
|
||||||
|
|
||||||
MapTile[] tiles = mTileSet.tiles;
|
MapTile[] tiles = mTileSet.tiles;
|
||||||
// FIXME just release tiles in this case
|
// FIXME just release tiles in this case
|
||||||
if (mAlpha == 0 || curPos.zoomLevel < 16) {
|
if (mAlpha == 0 || curPos.zoomLevel < 16) {
|
||||||
@ -135,11 +142,12 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
for (int i = 0; i < mTileSet.cnt; i++) {
|
for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
if (!tiles[i].isVisible)
|
if (!tiles[i].isVisible)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
|
|
||||||
for (byte j = 0; j < 4; j++) {
|
for (byte j = 0; j < 4; j++) {
|
||||||
if ((t.proxies & (1 << j)) != 0) {
|
if ((t.proxies & (1 << j)) != 0) {
|
||||||
MapTile c = t.rel.child[j].tile;
|
MapTile c = t.rel.get(j);
|
||||||
el = getLayer(c);
|
el = getLayer(c);
|
||||||
|
|
||||||
if (el == null || !el.compiled)
|
if (el == null || !el.compiled)
|
||||||
|
|||||||
@ -32,18 +32,19 @@ import java.util.HashMap;
|
|||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.generator.JobTile;
|
|
||||||
import org.oscim.graphics.Color;
|
import org.oscim.graphics.Color;
|
||||||
import org.oscim.graphics.Paint.Cap;
|
import org.oscim.graphics.Paint.Cap;
|
||||||
|
import org.oscim.layers.tile.JobTile;
|
||||||
|
import org.oscim.layers.tile.MapTile;
|
||||||
|
import org.oscim.layers.tile.TileRenderLayer;
|
||||||
|
import org.oscim.layers.tile.TileSet;
|
||||||
import org.oscim.renderer.BufferObject;
|
import org.oscim.renderer.BufferObject;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.GLRenderer;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.GLRenderer.Matrices;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.LineRenderer;
|
import org.oscim.renderer.LineRenderer;
|
||||||
import org.oscim.renderer.MapTile;
|
|
||||||
import org.oscim.renderer.PolygonRenderer;
|
import org.oscim.renderer.PolygonRenderer;
|
||||||
import org.oscim.renderer.TextureRenderer;
|
import org.oscim.renderer.TextureRenderer;
|
||||||
import org.oscim.renderer.TileSet;
|
|
||||||
import org.oscim.renderer.layer.Layer;
|
import org.oscim.renderer.layer.Layer;
|
||||||
import org.oscim.renderer.layer.Layers;
|
import org.oscim.renderer.layer.Layers;
|
||||||
import org.oscim.renderer.layer.LineLayer;
|
import org.oscim.renderer.layer.LineLayer;
|
||||||
@ -199,11 +200,13 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
|
|
||||||
private float mSquareRadius;
|
private float mSquareRadius;
|
||||||
private int mRelabelCnt;
|
private int mRelabelCnt;
|
||||||
|
private final TileRenderLayer mTileLayer;
|
||||||
|
|
||||||
public TextOverlay(MapView mapView) {
|
public TextOverlay(MapView mapView, TileRenderLayer baseLayer) {
|
||||||
super(mapView);
|
super(mapView);
|
||||||
mMapViewPosition = mapView.getMapViewPosition();
|
|
||||||
|
|
||||||
|
mMapViewPosition = mapView.getMapViewPosition();
|
||||||
|
mTileLayer = baseLayer;
|
||||||
layers.textureLayers = new TextLayer();
|
layers.textureLayers = new TextLayer();
|
||||||
mTmpLayer = new TextLayer();
|
mTmpLayer = new TextLayer();
|
||||||
mActiveTiles = new HashMap<MapTile, LabelTile>();
|
mActiveTiles = new HashMap<MapTile, LabelTile>();
|
||||||
@ -350,7 +353,9 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// get current tiles
|
// get current tiles
|
||||||
mTileSet = GLRenderer.getVisibleTiles(mTileSet);
|
mTileSet = mTileLayer.getVisibleTiles(mTileSet);
|
||||||
|
if (mTileSet == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (mTileSet.cnt == 0)
|
if (mTileSet.cnt == 0)
|
||||||
return false;
|
return false;
|
||||||
@ -605,7 +610,7 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
tl.labels = null;
|
tl.labels = null;
|
||||||
|
|
||||||
// remove tile locks
|
// remove tile locks
|
||||||
GLRenderer.releaseTiles(mTileSet);
|
mTileLayer.releaseTiles(mTileSet);
|
||||||
|
|
||||||
// pass new labels for rendering
|
// pass new labels for rendering
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
|||||||
@ -117,6 +117,8 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
private int mLevel;
|
private int mLevel;
|
||||||
private RenderTheme mRenderTheme;
|
private RenderTheme mRenderTheme;
|
||||||
private final Stack<Rule> mRuleStack = new Stack<Rule>();
|
private final Stack<Rule> mRuleStack = new Stack<Rule>();
|
||||||
|
private final HashMap<String, RenderInstruction> tmpStyleHash =
|
||||||
|
new HashMap<String, RenderInstruction>(10);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endDocument() {
|
public void endDocument() {
|
||||||
@ -148,8 +150,6 @@ public class RenderThemeHandler extends DefaultHandler {
|
|||||||
Log.d(TAG, exception.getMessage());
|
Log.d(TAG, exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HashMap<String, RenderInstruction> tmpStyleHash =
|
|
||||||
new HashMap<String, RenderInstruction>(10);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startElement(String uri, String localName, String qName,
|
public void startElement(String uri, String localName, String qName,
|
||||||
|
|||||||
@ -21,7 +21,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.PointF;
|
import org.oscim.core.PointF;
|
||||||
import org.oscim.overlay.Overlay;
|
import org.oscim.layers.InputLayer;
|
||||||
|
import org.oscim.layers.Layer;
|
||||||
import org.oscim.overlay.Overlay.Snappable;
|
import org.oscim.overlay.Overlay.Snappable;
|
||||||
import org.oscim.renderer.overlays.RenderOverlay;
|
import org.oscim.renderer.overlays.RenderOverlay;
|
||||||
|
|
||||||
@ -32,45 +33,45 @@ import android.view.GestureDetector.OnGestureListener;
|
|||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
public class LayerManager extends AbstractList<Overlay> implements OnGestureListener,
|
public class LayerManager extends AbstractList<Layer> implements OnGestureListener,
|
||||||
OnDoubleTapListener {
|
OnDoubleTapListener {
|
||||||
|
|
||||||
private final GestureDetector mGestureDetector;
|
private final GestureDetector mGestureDetector;
|
||||||
|
|
||||||
private final CopyOnWriteArrayList<Overlay> mOverlayList;
|
private final CopyOnWriteArrayList<Layer> mLayerList;
|
||||||
|
|
||||||
LayerManager(Context context) {
|
LayerManager(Context context) {
|
||||||
mOverlayList = new CopyOnWriteArrayList<Overlay>();
|
mLayerList = new CopyOnWriteArrayList<Layer>();
|
||||||
mGestureDetector = new GestureDetector(context, this);
|
mGestureDetector = new GestureDetector(context, this);
|
||||||
mGestureDetector.setOnDoubleTapListener(this);
|
mGestureDetector.setOnDoubleTapListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized Overlay get(final int pIndex) {
|
public synchronized Layer get(final int pIndex) {
|
||||||
return mOverlayList.get(pIndex);
|
return mLayerList.get(pIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized int size() {
|
public synchronized int size() {
|
||||||
return mOverlayList.size();
|
return mLayerList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void add(final int pIndex, final Overlay pElement) {
|
public synchronized void add(final int pIndex, final Layer pElement) {
|
||||||
mOverlayList.add(pIndex, pElement);
|
mLayerList.add(pIndex, pElement);
|
||||||
mDirtyOverlays = true;
|
mDirtyLayers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized Overlay remove(final int pIndex) {
|
public synchronized Layer remove(final int pIndex) {
|
||||||
mDirtyOverlays = true;
|
mDirtyLayers = true;
|
||||||
return mOverlayList.remove(pIndex);
|
return mLayerList.remove(pIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized Overlay set(final int pIndex, final Overlay pElement) {
|
public synchronized Layer set(final int pIndex, final Layer pElement) {
|
||||||
mDirtyOverlays = true;
|
mDirtyLayers = true;
|
||||||
return mOverlayList.set(pIndex, pElement);
|
return mLayerList.set(pIndex, pElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean handleMotionEvent(MotionEvent e) {
|
public boolean handleMotionEvent(MotionEvent e) {
|
||||||
@ -84,59 +85,68 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean mDirtyOverlays;
|
private boolean mDirtyLayers;
|
||||||
private RenderOverlay[] mDrawLayers;
|
private RenderOverlay[] mDrawLayers;
|
||||||
|
|
||||||
public RenderOverlay[] getRenderLayers() {
|
public RenderOverlay[] getRenderLayers() {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
return mDrawLayers;
|
return mDrawLayers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDetach() {
|
public void onDetach() {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (Layer o : mLayers)
|
||||||
o.onDetach();
|
o.onDetach();
|
||||||
}
|
}
|
||||||
|
|
||||||
Overlay[] mOverlays;
|
Layer[] mLayers;
|
||||||
|
InputLayer[] mInputLayer;
|
||||||
|
|
||||||
private synchronized void updateOverlays() {
|
private synchronized void updateLayers() {
|
||||||
if (!mDirtyOverlays)
|
if (!mDirtyLayers)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mOverlays = new Overlay[mOverlayList.size()];
|
mLayers = new Layer[mLayerList.size()];
|
||||||
|
|
||||||
int numRenderLayers = 0;
|
int numRenderLayers = 0;
|
||||||
|
int numInputLayers = 0;
|
||||||
|
|
||||||
for (int i = 0, n = mOverlayList.size(); i < n; i++) {
|
for (int i = 0, n = mLayerList.size(); i < n; i++) {
|
||||||
Overlay o = mOverlayList.get(i);
|
Layer o = mLayerList.get(i);
|
||||||
if (o.getLayer() != null)
|
if (o.getLayer() != null)
|
||||||
numRenderLayers++;
|
numRenderLayers++;
|
||||||
|
|
||||||
mOverlays[n - i - 1] = o;
|
if (o instanceof InputLayer)
|
||||||
|
numInputLayers++;
|
||||||
|
|
||||||
|
mLayers[n - i - 1] = o;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDrawLayers = new RenderOverlay[numRenderLayers];
|
mDrawLayers = new RenderOverlay[numRenderLayers];
|
||||||
|
mInputLayer = new InputLayer[numInputLayers];
|
||||||
|
|
||||||
for (int i = 0, cnt = 0, n = mOverlayList.size(); i < n; i++) {
|
for (int i = 0, cntR = 0, cntI = 0, n = mLayerList.size(); i < n; i++) {
|
||||||
Overlay o = mOverlayList.get(i);
|
Layer o = mLayerList.get(i);
|
||||||
RenderOverlay l = o.getLayer();
|
RenderOverlay l = o.getLayer();
|
||||||
if (l != null)
|
if (l != null)
|
||||||
mDrawLayers[cnt++] = l;
|
mDrawLayers[cntR++] = l;
|
||||||
|
|
||||||
|
if (o instanceof InputLayer)
|
||||||
|
mInputLayer[cntI++] = (InputLayer)o;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDirtyOverlays = false;
|
mDirtyLayers = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onTouchEvent(final MotionEvent event) {
|
public boolean onTouchEvent(final MotionEvent event) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onTouchEvent(event))
|
if (o.onTouchEvent(event))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -144,10 +154,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean onKeyDown(final int keyCode, final KeyEvent event) {
|
public boolean onKeyDown(final int keyCode, final KeyEvent event) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onKeyDown(keyCode, event))
|
if (o.onKeyDown(keyCode, event))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -155,10 +165,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean onKeyUp(final int keyCode, final KeyEvent event) {
|
public boolean onKeyUp(final int keyCode, final KeyEvent event) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onKeyUp(keyCode, event))
|
if (o.onKeyUp(keyCode, event))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -166,10 +176,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean onTrackballEvent(final MotionEvent event) {
|
public boolean onTrackballEvent(final MotionEvent event) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onTrackballEvent(event))
|
if (o.onTrackballEvent(event))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -177,10 +187,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean onSnapToItem(final int x, final int y, final PointF snapPoint) {
|
public boolean onSnapToItem(final int x, final int y, final PointF snapPoint) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o instanceof Snappable)
|
if (o instanceof Snappable)
|
||||||
if (((Snappable) o).onSnapToItem(x, y, snapPoint))
|
if (((Snappable) o).onSnapToItem(x, y, snapPoint))
|
||||||
return true;
|
return true;
|
||||||
@ -192,10 +202,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onDoubleTap(final MotionEvent e) {
|
public boolean onDoubleTap(final MotionEvent e) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onDoubleTap(e))
|
if (o.onDoubleTap(e))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -204,10 +214,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onDoubleTapEvent(final MotionEvent e) {
|
public boolean onDoubleTapEvent(final MotionEvent e) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onDoubleTapEvent(e))
|
if (o.onDoubleTapEvent(e))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -216,10 +226,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onSingleTapConfirmed(final MotionEvent e) {
|
public boolean onSingleTapConfirmed(final MotionEvent e) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onSingleTapConfirmed(e))
|
if (o.onSingleTapConfirmed(e))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -230,10 +240,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onDown(final MotionEvent pEvent) {
|
public boolean onDown(final MotionEvent pEvent) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onDown(pEvent))
|
if (o.onDown(pEvent))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -243,10 +253,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
@Override
|
@Override
|
||||||
public boolean onFling(final MotionEvent pEvent1, final MotionEvent pEvent2,
|
public boolean onFling(final MotionEvent pEvent1, final MotionEvent pEvent2,
|
||||||
final float pVelocityX, final float pVelocityY) {
|
final float pVelocityX, final float pVelocityY) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onFling(pEvent1, pEvent2, pVelocityX, pVelocityY))
|
if (o.onFling(pEvent1, pEvent2, pVelocityX, pVelocityY))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -255,10 +265,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLongPress(final MotionEvent pEvent) {
|
public void onLongPress(final MotionEvent pEvent) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onLongPress(pEvent))
|
if (o.onLongPress(pEvent))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -266,10 +276,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
@Override
|
@Override
|
||||||
public boolean onScroll(final MotionEvent pEvent1, final MotionEvent pEvent2,
|
public boolean onScroll(final MotionEvent pEvent1, final MotionEvent pEvent2,
|
||||||
final float pDistanceX, final float pDistanceY) {
|
final float pDistanceX, final float pDistanceY) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onScroll(pEvent1, pEvent2, pDistanceX, pDistanceY))
|
if (o.onScroll(pEvent1, pEvent2, pDistanceX, pDistanceY))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -278,20 +288,20 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onShowPress(final MotionEvent pEvent) {
|
public void onShowPress(final MotionEvent pEvent) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
o.onShowPress(pEvent);
|
o.onShowPress(pEvent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onSingleTapUp(final MotionEvent pEvent) {
|
public boolean onSingleTapUp(final MotionEvent pEvent) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (InputLayer o : mInputLayer)
|
||||||
if (o.onSingleTapUp(pEvent))
|
if (o.onSingleTapUp(pEvent))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -299,52 +309,62 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onUpdate(MapPosition mapPosition, boolean changed) {
|
public void onUpdate(MapPosition mapPosition, boolean changed) {
|
||||||
if (mDirtyOverlays)
|
if (mDirtyLayers)
|
||||||
updateOverlays();
|
updateLayers();
|
||||||
|
|
||||||
for (Overlay o : mOverlays)
|
for (Layer l : mLayers)
|
||||||
o.onUpdate(mapPosition, changed);
|
l.onUpdate(mapPosition, changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
if (mDirtyLayers)
|
||||||
|
updateLayers();
|
||||||
|
|
||||||
|
for (Layer l : mLayers){
|
||||||
|
l.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Gets the optional TilesOverlay class.
|
// * Gets the optional TilesLayer class.
|
||||||
// *
|
// *
|
||||||
// * @return the tilesOverlay
|
// * @return the tilesLayer
|
||||||
// */
|
// */
|
||||||
// public TilesOverlay getTilesOverlay() {
|
// public TilesLayer getTilesLayer() {
|
||||||
// return mTilesOverlay;
|
// return mTilesLayer;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// /**
|
// /**
|
||||||
// * Sets the optional TilesOverlay class. If set, this overlay will be
|
// * Sets the optional TilesLayer class. If set, this overlay will be
|
||||||
// drawn before all other
|
// drawn before all other
|
||||||
// * overlays and will not be included in the editable list of overlays and
|
// * overlays and will not be included in the editable list of overlays and
|
||||||
// can't be cleared
|
// can't be cleared
|
||||||
// * except by a subsequent call to setTilesOverlay().
|
// * except by a subsequent call to setTilesLayer().
|
||||||
// *
|
// *
|
||||||
// * @param tilesOverlay
|
// * @param tilesLayer
|
||||||
// * the tilesOverlay to set
|
// * the tilesLayer to set
|
||||||
// */
|
// */
|
||||||
// public void setTilesOverlay(final TilesOverlay tilesOverlay) {
|
// public void setTilesLayer(final TilesLayer tilesLayer) {
|
||||||
// mTilesOverlay = tilesOverlay;
|
// mTilesLayer = tilesLayer;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// public void onDraw(final Canvas c, final MapView pMapView) {
|
// public void onDraw(final Canvas c, final MapView pMapView) {
|
||||||
// // if ((mTilesOverlay != null) && mTilesOverlay.isEnabled()) {
|
// // if ((mTilesLayer != null) && mTilesLayer.isEnabled()) {
|
||||||
// // mTilesOverlay.draw(c, pMapView, true);
|
// // mTilesLayer.draw(c, pMapView, true);
|
||||||
// // }
|
// // }
|
||||||
// //
|
// //
|
||||||
// // if ((mTilesOverlay != null) && mTilesOverlay.isEnabled()) {
|
// // if ((mTilesLayer != null) && mTilesLayer.isEnabled()) {
|
||||||
// // mTilesOverlay.draw(c, pMapView, false);
|
// // mTilesLayer.draw(c, pMapView, false);
|
||||||
// // }
|
// // }
|
||||||
//
|
//
|
||||||
// for (final Overlay overlay : mOverlayList) {
|
// for (final Layer overlay : mLayerList) {
|
||||||
// if (overlay.isEnabled()) {
|
// if (overlay.isEnabled()) {
|
||||||
// overlay.draw(c, pMapView, true);
|
// overlay.draw(c, pMapView, true);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// for (final Overlay overlay : mOverlayList) {
|
// for (final Layer overlay : mLayerList) {
|
||||||
// if (overlay.isEnabled()) {
|
// if (overlay.isEnabled()) {
|
||||||
// overlay.draw(c, pMapView, false);
|
// overlay.draw(c, pMapView, false);
|
||||||
// }
|
// }
|
||||||
@ -355,10 +375,10 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
// ** Options Menu **//
|
// ** Options Menu **//
|
||||||
|
|
||||||
// public void setOptionsMenusEnabled(final boolean pEnabled) {
|
// public void setOptionsMenusEnabled(final boolean pEnabled) {
|
||||||
// for (final Overlay overlay : mOverlayList) {
|
// for (final Layer overlay : mLayerList) {
|
||||||
// if ((overlay instanceof IOverlayMenuProvider)
|
// if ((overlay instanceof ILayerMenuProvider)
|
||||||
// && ((IOverlayMenuProvider) overlay).isOptionsMenuEnabled()) {
|
// && ((ILayerMenuProvider) overlay).isOptionsMenuEnabled()) {
|
||||||
// ((IOverlayMenuProvider) overlay).setOptionsMenuEnabled(pEnabled);
|
// ((ILayerMenuProvider) overlay).setOptionsMenuEnabled(pEnabled);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
@ -367,19 +387,19 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
// menuIdOffset,
|
// menuIdOffset,
|
||||||
// final MapView mapView) {
|
// final MapView mapView) {
|
||||||
// boolean result = true;
|
// boolean result = true;
|
||||||
// for (final Overlay overlay : this.overlaysReversed()) {
|
// for (final Layer overlay : this.overlaysReversed()) {
|
||||||
// if ((overlay instanceof IOverlayMenuProvider)
|
// if ((overlay instanceof ILayerMenuProvider)
|
||||||
// && ((IOverlayMenuProvider) overlay).isOptionsMenuEnabled()) {
|
// && ((ILayerMenuProvider) overlay).isOptionsMenuEnabled()) {
|
||||||
// result &= ((IOverlayMenuProvider) overlay).onCreateOptionsMenu(pMenu,
|
// result &= ((ILayerMenuProvider) overlay).onCreateOptionsMenu(pMenu,
|
||||||
// menuIdOffset,
|
// menuIdOffset,
|
||||||
// mapView);
|
// mapView);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// if ((mTilesOverlay != null) && (mTilesOverlay instanceof
|
// if ((mTilesLayer != null) && (mTilesLayer instanceof
|
||||||
// IOverlayMenuProvider)
|
// ILayerMenuProvider)
|
||||||
// && ((IOverlayMenuProvider) mTilesOverlay).isOptionsMenuEnabled()) {
|
// && ((ILayerMenuProvider) mTilesLayer).isOptionsMenuEnabled()) {
|
||||||
// result &= mTilesOverlay.onCreateOptionsMenu(pMenu, menuIdOffset,
|
// result &= mTilesLayer.onCreateOptionsMenu(pMenu, menuIdOffset,
|
||||||
// mapView);
|
// mapView);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
@ -389,18 +409,18 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
// public boolean onPrepareOptionsMenu(final Menu pMenu, final int
|
// public boolean onPrepareOptionsMenu(final Menu pMenu, final int
|
||||||
// menuIdOffset,
|
// menuIdOffset,
|
||||||
// final MapView mapView) {
|
// final MapView mapView) {
|
||||||
// for (final Overlay overlay : this.overlaysReversed()) {
|
// for (final Layer overlay : this.overlaysReversed()) {
|
||||||
// if ((overlay instanceof IOverlayMenuProvider)
|
// if ((overlay instanceof ILayerMenuProvider)
|
||||||
// && ((IOverlayMenuProvider) overlay).isOptionsMenuEnabled()) {
|
// && ((ILayerMenuProvider) overlay).isOptionsMenuEnabled()) {
|
||||||
// ((IOverlayMenuProvider) overlay).onPrepareOptionsMenu(pMenu,
|
// ((ILayerMenuProvider) overlay).onPrepareOptionsMenu(pMenu,
|
||||||
// menuIdOffset, mapView);
|
// menuIdOffset, mapView);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// if ((mTilesOverlay != null) && (mTilesOverlay instanceof
|
// if ((mTilesLayer != null) && (mTilesLayer instanceof
|
||||||
// IOverlayMenuProvider)
|
// ILayerMenuProvider)
|
||||||
// && ((IOverlayMenuProvider) mTilesOverlay).isOptionsMenuEnabled()) {
|
// && ((ILayerMenuProvider) mTilesLayer).isOptionsMenuEnabled()) {
|
||||||
// mTilesOverlay.onPrepareOptionsMenu(pMenu, menuIdOffset, mapView);
|
// mTilesLayer.onPrepareOptionsMenu(pMenu, menuIdOffset, mapView);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// return true;
|
// return true;
|
||||||
@ -409,20 +429,20 @@ public class LayerManager extends AbstractList<Overlay> implements OnGestureList
|
|||||||
// public boolean onOptionsItemSelected(final MenuItem item, final int
|
// public boolean onOptionsItemSelected(final MenuItem item, final int
|
||||||
// menuIdOffset,
|
// menuIdOffset,
|
||||||
// final MapView mapView) {
|
// final MapView mapView) {
|
||||||
// for (final Overlay overlay : this.overlaysReversed()) {
|
// for (final Layer overlay : this.overlaysReversed()) {
|
||||||
// if ((overlay instanceof IOverlayMenuProvider)
|
// if ((overlay instanceof ILayerMenuProvider)
|
||||||
// && ((IOverlayMenuProvider) overlay).isOptionsMenuEnabled()
|
// && ((ILayerMenuProvider) overlay).isOptionsMenuEnabled()
|
||||||
// && ((IOverlayMenuProvider) overlay).onOptionsItemSelected(item,
|
// && ((ILayerMenuProvider) overlay).onOptionsItemSelected(item,
|
||||||
// menuIdOffset,
|
// menuIdOffset,
|
||||||
// mapView)) {
|
// mapView)) {
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// if ((mTilesOverlay != null)
|
// if ((mTilesLayer != null)
|
||||||
// && (mTilesOverlay instanceof IOverlayMenuProvider)
|
// && (mTilesLayer instanceof ILayerMenuProvider)
|
||||||
// && ((IOverlayMenuProvider) mTilesOverlay).isOptionsMenuEnabled()
|
// && ((ILayerMenuProvider) mTilesLayer).isOptionsMenuEnabled()
|
||||||
// && ((IOverlayMenuProvider) mTilesOverlay).onOptionsItemSelected(item,
|
// && ((ILayerMenuProvider) mTilesLayer).onOptionsItemSelected(item,
|
||||||
// menuIdOffset,
|
// menuIdOffset,
|
||||||
// mapView)) {
|
// mapView)) {
|
||||||
// return true;
|
// return true;
|
||||||
|
|||||||
@ -14,11 +14,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.view;
|
package org.oscim.view;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
|
|
||||||
import org.oscim.core.GeoPoint;
|
import org.oscim.core.GeoPoint;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.theme.InternalRenderTheme;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
@ -78,7 +75,7 @@ public abstract class MapActivity extends Activity {
|
|||||||
editor.putInt(KEY_LONGITUDE, geoPoint.longitudeE6);
|
editor.putInt(KEY_LONGITUDE, geoPoint.longitudeE6);
|
||||||
editor.putFloat(KEY_MAP_SCALE, (float)mapPosition.scale);
|
editor.putFloat(KEY_MAP_SCALE, (float)mapPosition.scale);
|
||||||
|
|
||||||
editor.putString(KEY_THEME, mMapView.getRenderTheme());
|
//editor.putString(KEY_THEME, mMapView.getRenderTheme());
|
||||||
|
|
||||||
editor.commit();
|
editor.commit();
|
||||||
}
|
}
|
||||||
@ -121,21 +118,21 @@ public abstract class MapActivity extends Activity {
|
|||||||
mMapView.getMapViewPosition().setMapPosition(mapPosition);
|
mMapView.getMapViewPosition().setMapPosition(mapPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
String theme = sharedPreferences.getString(KEY_THEME,
|
//String theme = sharedPreferences.getString(KEY_THEME,
|
||||||
InternalRenderTheme.DEFAULT.name());
|
// InternalRenderTheme.DEFAULT.name());
|
||||||
|
|
||||||
if (theme.startsWith("/")) {
|
// if (theme.startsWith("/")) {
|
||||||
try {
|
// try {
|
||||||
mapView.setRenderTheme(theme);
|
// mapView.setRenderTheme(theme);
|
||||||
} catch (FileNotFoundException e) {
|
// } catch (FileNotFoundException e) {
|
||||||
mapView.setRenderTheme(InternalRenderTheme.DEFAULT);
|
// mapView.setRenderTheme(InternalRenderTheme.DEFAULT);
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
try {
|
// try {
|
||||||
mapView.setRenderTheme(InternalRenderTheme.valueOf(theme));
|
// mapView.setRenderTheme(InternalRenderTheme.valueOf(theme));
|
||||||
} catch (IllegalArgumentException e) {
|
// } catch (IllegalArgumentException e) {
|
||||||
mapView.setRenderTheme(InternalRenderTheme.DEFAULT);
|
// mapView.setRenderTheme(InternalRenderTheme.DEFAULT);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,41 +15,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.view;
|
package org.oscim.view;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
import org.oscim.core.BoundingBox;
|
import org.oscim.core.BoundingBox;
|
||||||
import org.oscim.core.GeoPoint;
|
import org.oscim.core.GeoPoint;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.database.IMapDatabase;
|
|
||||||
import org.oscim.database.MapDatabaseFactory;
|
|
||||||
import org.oscim.database.MapDatabases;
|
|
||||||
import org.oscim.database.MapInfo;
|
|
||||||
import org.oscim.database.MapOptions;
|
import org.oscim.database.MapOptions;
|
||||||
import org.oscim.database.OpenResult;
|
import org.oscim.layers.Layer;
|
||||||
import org.oscim.generator.JobQueue;
|
import org.oscim.layers.tile.TileGenerator;
|
||||||
import org.oscim.generator.JobTile;
|
import org.oscim.layers.tile.TileLayer;
|
||||||
import org.oscim.generator.MapWorker;
|
|
||||||
import org.oscim.generator.TileGenerator;
|
|
||||||
import org.oscim.overlay.BuildingOverlay;
|
import org.oscim.overlay.BuildingOverlay;
|
||||||
import org.oscim.overlay.LabelingOverlay;
|
import org.oscim.overlay.LabelingOverlay;
|
||||||
import org.oscim.overlay.Overlay;
|
import org.oscim.overlay.Overlay;
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.renderer.GLView;
|
import org.oscim.renderer.GLView;
|
||||||
import org.oscim.renderer.TileManager;
|
|
||||||
import org.oscim.theme.ExternalRenderTheme;
|
|
||||||
import org.oscim.theme.InternalRenderTheme;
|
|
||||||
import org.oscim.theme.RenderTheme;
|
|
||||||
import org.oscim.theme.RenderThemeHandler;
|
|
||||||
import org.oscim.theme.Theme;
|
|
||||||
import org.oscim.utils.AndroidUtils;
|
import org.oscim.utils.AndroidUtils;
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@ -68,43 +48,28 @@ public class MapView extends RelativeLayout {
|
|||||||
|
|
||||||
public static final boolean debugFrameTime = false;
|
public static final boolean debugFrameTime = false;
|
||||||
public static final boolean testRegionZoom = false;
|
public static final boolean testRegionZoom = false;
|
||||||
private static final boolean debugDatabase = false;
|
|
||||||
|
|
||||||
public boolean mRotationEnabled = false;
|
public boolean mRotationEnabled = false;
|
||||||
public boolean mCompassEnabled = false;
|
public boolean mCompassEnabled = false;
|
||||||
public boolean enablePagedFling = false;
|
public boolean enablePagedFling = false;
|
||||||
|
|
||||||
|
private final GLView mGLView;
|
||||||
|
|
||||||
|
private final LayerManager mLayerManager;
|
||||||
private final MapViewPosition mMapViewPosition;
|
private final MapViewPosition mMapViewPosition;
|
||||||
private final MapPosition mMapPosition;
|
private final MapPosition mMapPosition;
|
||||||
|
|
||||||
//private final MapZoomControls mMapZoomControls;
|
|
||||||
|
|
||||||
private final Compass mCompass;
|
private final Compass mCompass;
|
||||||
|
|
||||||
private final TileManager mTileManager;
|
|
||||||
private final LayerManager mLayerManager;
|
|
||||||
|
|
||||||
final GLView mGLView;
|
|
||||||
private final JobQueue mJobQueue;
|
|
||||||
|
|
||||||
// TODO use 1 download and 1 generator thread instead
|
|
||||||
private final MapWorker mMapWorkers[];
|
|
||||||
private final int mNumMapWorkers = 4;
|
|
||||||
|
|
||||||
private MapOptions mMapOptions;
|
|
||||||
private IMapDatabase mMapDatabase;
|
|
||||||
private String mRenderTheme;
|
|
||||||
private DebugSettings mDebugSettings;
|
private DebugSettings mDebugSettings;
|
||||||
|
|
||||||
private boolean mClearMap;
|
|
||||||
|
|
||||||
private int mWidth;
|
private int mWidth;
|
||||||
private int mHeight;
|
private int mHeight;
|
||||||
|
|
||||||
// FIXME: keep until old pbmap reader is removed
|
// FIXME: keep until old pbmap reader is removed
|
||||||
public static boolean enableClosePolygons = false;
|
public static boolean enableClosePolygons = false;
|
||||||
|
|
||||||
public final float dpi;
|
public static float dpi;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param context
|
* @param context
|
||||||
@ -152,21 +117,12 @@ public class MapView extends RelativeLayout {
|
|||||||
|
|
||||||
mCompass = new Compass(mapActivity, this);
|
mCompass = new Compass(mapActivity, this);
|
||||||
|
|
||||||
mJobQueue = new JobQueue();
|
|
||||||
|
|
||||||
mTileManager = new TileManager(this);
|
|
||||||
|
|
||||||
mGLView = new GLView(context, this);
|
mGLView = new GLView(context, this);
|
||||||
mMapWorkers = new MapWorker[mNumMapWorkers];
|
|
||||||
|
|
||||||
mDebugSettings = new DebugSettings();
|
mDebugSettings = new DebugSettings();
|
||||||
TileGenerator.setDebugSettings(mDebugSettings);
|
|
||||||
|
|
||||||
for (int i = 0; i < mNumMapWorkers; i++) {
|
// FIXME
|
||||||
TileGenerator tileGenerator = new TileGenerator();
|
TileGenerator.setDebugSettings(mDebugSettings);
|
||||||
mMapWorkers[i] = new MapWorker(i, mJobQueue, tileGenerator, mTileManager);
|
|
||||||
mMapWorkers[i].start();
|
|
||||||
}
|
|
||||||
|
|
||||||
mapActivity.registerMapView(this);
|
mapActivity.registerMapView(this);
|
||||||
|
|
||||||
@ -176,7 +132,19 @@ public class MapView extends RelativeLayout {
|
|||||||
|
|
||||||
addView(mGLView, params);
|
addView(mGLView, params);
|
||||||
|
|
||||||
mLayerManager.add(new MapEventLayer(this));
|
requestRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public TileLayer setBaseMap(MapOptions options){
|
||||||
|
TileLayer baseLayer = new TileLayer(this);
|
||||||
|
|
||||||
|
baseLayer.setMapDatabase(options);
|
||||||
|
|
||||||
|
|
||||||
|
mLayerManager.add(0,new MapEventLayer(this));
|
||||||
|
|
||||||
|
mLayerManager.add(1,baseLayer);
|
||||||
|
|
||||||
//mMapZoomControls = new MapZoomControls(mapActivity, this);
|
//mMapZoomControls = new MapZoomControls(mapActivity, this);
|
||||||
//mMapZoomControls.setShowMapZoomControls(true);
|
//mMapZoomControls.setShowMapZoomControls(true);
|
||||||
@ -184,41 +152,14 @@ public class MapView extends RelativeLayout {
|
|||||||
|
|
||||||
//mLayerManager.add(new GenericOverlay(this, new GridOverlay(this)));
|
//mLayerManager.add(new GenericOverlay(this, new GridOverlay(this)));
|
||||||
|
|
||||||
mLayerManager.add(new BuildingOverlay(this));
|
mLayerManager.add(new BuildingOverlay(this, baseLayer.getTileLayer()));
|
||||||
mLayerManager.add(new LabelingOverlay(this));
|
mLayerManager.add(new LabelingOverlay(this, baseLayer.getTileLayer()));
|
||||||
|
|
||||||
//mLayerManager.add(new GenericOverlay(this, new TileOverlay(this)));
|
return baseLayer;
|
||||||
//mLayerManager.add(new GenericOverlay(this, new CustomOverlay(this)));
|
|
||||||
//mLayerManager.add(new MapLensOverlay(this));
|
|
||||||
|
|
||||||
//PathOverlay path = new PathOverlay(this, Color.RED);
|
|
||||||
//path.addGreatCircle(new GeoPoint(53.1, 8.8), new GeoPoint(53.1, -110.0));
|
|
||||||
//mLayerManager.add(path);
|
|
||||||
//path = new PathOverlay(this, Color.GREEN);
|
|
||||||
//path.addGreatCircle(new GeoPoint(53.1, 140), new GeoPoint(53.1, -110.0));
|
|
||||||
//mLayerManager.add(path);
|
|
||||||
|
|
||||||
//mLayerManager.add(new GenericOverlay(this, new AtlasTest(this)));
|
|
||||||
|
|
||||||
clearMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
mTileManager.destroy();
|
mLayerManager.destroy();
|
||||||
|
|
||||||
for (MapWorker mapWorker : mMapWorkers) {
|
|
||||||
mapWorker.pause();
|
|
||||||
mapWorker.interrupt();
|
|
||||||
|
|
||||||
mapWorker.getTileGenerator().getMapDatabase().close();
|
|
||||||
|
|
||||||
try {
|
|
||||||
mapWorker.join(10000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// restore the interrupted status
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean mPausing = false;
|
private boolean mPausing = false;
|
||||||
@ -226,18 +167,12 @@ public class MapView extends RelativeLayout {
|
|||||||
void onPause() {
|
void onPause() {
|
||||||
mPausing = true;
|
mPausing = true;
|
||||||
|
|
||||||
Log.d(TAG, "onPause");
|
|
||||||
mJobQueue.clear();
|
|
||||||
mapWorkersPause(true);
|
|
||||||
|
|
||||||
if (this.mCompassEnabled)
|
if (this.mCompassEnabled)
|
||||||
mCompass.disable();
|
mCompass.disable();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onResume() {
|
void onResume() {
|
||||||
Log.d(TAG, "onResume");
|
|
||||||
mapWorkersProceed();
|
|
||||||
|
|
||||||
if (this.mCompassEnabled)
|
if (this.mCompassEnabled)
|
||||||
mCompass.enable();
|
mCompass.enable();
|
||||||
@ -247,7 +182,7 @@ public class MapView extends RelativeLayout {
|
|||||||
|
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
Log.d(TAG, "onStop");
|
Log.d(TAG, "onStop");
|
||||||
//mTileManager.destroy();
|
//mLayerManager.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -264,9 +199,6 @@ public class MapView extends RelativeLayout {
|
|||||||
int oldWidth, int oldHeight) {
|
int oldWidth, int oldHeight) {
|
||||||
Log.d(TAG, "onSizeChanged: " + width + "x" + height);
|
Log.d(TAG, "onSizeChanged: " + width + "x" + height);
|
||||||
|
|
||||||
mJobQueue.clear();
|
|
||||||
mapWorkersPause(true);
|
|
||||||
|
|
||||||
super.onSizeChanged(width, height, oldWidth, oldHeight);
|
super.onSizeChanged(width, height, oldWidth, oldHeight);
|
||||||
|
|
||||||
mWidth = width;
|
mWidth = width;
|
||||||
@ -274,9 +206,6 @@ public class MapView extends RelativeLayout {
|
|||||||
|
|
||||||
if (width != 0 && height != 0)
|
if (width != 0 && height != 0)
|
||||||
mMapViewPosition.setViewport(width, height);
|
mMapViewPosition.setViewport(width, height);
|
||||||
|
|
||||||
clearMap();
|
|
||||||
mapWorkersProceed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
@ -315,6 +244,24 @@ public class MapView extends RelativeLayout {
|
|||||||
return mRotationEnabled;
|
return mRotationEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean mWaitRedraw;
|
||||||
|
|
||||||
|
Runnable mRedrawRequest = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mWaitRedraw = false;
|
||||||
|
redrawMap(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void requestRedraw(){
|
||||||
|
if (!mWaitRedraw){
|
||||||
|
mWaitRedraw = true;
|
||||||
|
post(mRedrawRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates all necessary tiles and adds jobs accordingly.
|
* Calculates all necessary tiles and adds jobs accordingly.
|
||||||
*
|
*
|
||||||
@ -324,33 +271,27 @@ public class MapView extends RelativeLayout {
|
|||||||
if (mPausing || mWidth == 0 || mHeight == 0)
|
if (mPausing || mWidth == 0 || mHeight == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (forceRedraw)
|
boolean changed = false;
|
||||||
|
|
||||||
|
if (forceRedraw){
|
||||||
render();
|
render();
|
||||||
|
changed = true;
|
||||||
if (mClearMap) {
|
|
||||||
mTileManager.init(mWidth, mHeight);
|
|
||||||
mClearMap = false;
|
|
||||||
|
|
||||||
// make sure mMapPosition will be updated
|
|
||||||
mMapPosition.zoomLevel = -1;
|
|
||||||
|
|
||||||
// TODO clear overlays
|
|
||||||
}
|
}
|
||||||
|
// if (mClearMap) {
|
||||||
|
// mTileManager.init(mWidth, mHeight);
|
||||||
|
// mClearMap = false;
|
||||||
|
//
|
||||||
|
// // make sure mMapPosition will be updated
|
||||||
|
// mMapPosition.zoomLevel = -1;
|
||||||
|
//
|
||||||
|
// // TODO clear overlays
|
||||||
|
// }
|
||||||
|
|
||||||
boolean changed = mMapViewPosition.getMapPosition(mMapPosition);
|
changed |= mMapViewPosition.getMapPosition(mMapPosition);
|
||||||
|
|
||||||
// required when not changed?
|
// required when not changed?
|
||||||
if (AndroidUtils.currentThreadIsUiThread())
|
if (AndroidUtils.currentThreadIsUiThread())
|
||||||
mLayerManager.onUpdate(mMapPosition, changed);
|
mLayerManager.onUpdate(mMapPosition, changed);
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
mTileManager.update(mMapPosition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearMap() {
|
|
||||||
// clear tile and overlay data before next draw
|
|
||||||
mClearMap = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -360,7 +301,7 @@ public class MapView extends RelativeLayout {
|
|||||||
public void setDebugSettings(DebugSettings debugSettings) {
|
public void setDebugSettings(DebugSettings debugSettings) {
|
||||||
mDebugSettings = debugSettings;
|
mDebugSettings = debugSettings;
|
||||||
TileGenerator.setDebugSettings(debugSettings);
|
TileGenerator.setDebugSettings(debugSettings);
|
||||||
clearMap();
|
//clearMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -370,184 +311,10 @@ public class MapView extends RelativeLayout {
|
|||||||
return mDebugSettings;
|
return mDebugSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getMapOptions() {
|
|
||||||
return mMapOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MapPosition getMapFileCenter() {
|
|
||||||
if (mMapDatabase == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
MapInfo mapInfo = mMapDatabase.getMapInfo();
|
|
||||||
if (mapInfo == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
GeoPoint startPos = mapInfo.startPosition;
|
|
||||||
|
|
||||||
if (startPos == null)
|
|
||||||
startPos = mapInfo.mapCenter;
|
|
||||||
|
|
||||||
if (startPos == null)
|
|
||||||
startPos = new GeoPoint(0, 0);
|
|
||||||
|
|
||||||
MapPosition mapPosition = new MapPosition();
|
|
||||||
mapPosition.setPosition(startPos);
|
|
||||||
|
|
||||||
if (mapInfo.startZoomLevel == null)
|
|
||||||
mapPosition.setZoomLevel(12);
|
|
||||||
else
|
|
||||||
mapPosition.setZoomLevel((mapInfo.startZoomLevel).byteValue());
|
|
||||||
|
|
||||||
return mapPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMapPosition(MapPosition mapPosition) {
|
public void setMapPosition(MapPosition mapPosition) {
|
||||||
mMapViewPosition.setMapPosition(mapPosition);
|
mMapViewPosition.setMapPosition(mapPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the MapDatabase for this MapView.
|
|
||||||
*
|
|
||||||
* @param options
|
|
||||||
* the new MapDatabase options.
|
|
||||||
* @return true if MapDatabase changed
|
|
||||||
*/
|
|
||||||
public boolean setMapDatabase(MapOptions options) {
|
|
||||||
if (debugDatabase)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Log.i(TAG, "setMapDatabase: " + options.db.name());
|
|
||||||
|
|
||||||
if (mMapOptions != null && mMapOptions.equals(options))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
mapWorkersPause(true);
|
|
||||||
|
|
||||||
mJobQueue.clear();
|
|
||||||
mMapOptions = options;
|
|
||||||
|
|
||||||
mMapDatabase = null;
|
|
||||||
|
|
||||||
for (int i = 0; i < mNumMapWorkers; i++) {
|
|
||||||
MapWorker mapWorker = mMapWorkers[i];
|
|
||||||
|
|
||||||
IMapDatabase mapDatabase = MapDatabaseFactory
|
|
||||||
.createMapDatabase(options.db);
|
|
||||||
|
|
||||||
OpenResult result = mapDatabase.open(options);
|
|
||||||
|
|
||||||
if (result != OpenResult.SUCCESS) {
|
|
||||||
Log.d(TAG, "failed open db: " + result.getErrorMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
TileGenerator tileGenerator = mapWorker.getTileGenerator();
|
|
||||||
tileGenerator.setMapDatabase(mapDatabase);
|
|
||||||
|
|
||||||
// TODO this could be done in a cleaner way..
|
|
||||||
if (mMapDatabase == null)
|
|
||||||
mMapDatabase = mapDatabase;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.db == MapDatabases.OSCIMAP_READER ||
|
|
||||||
options.db == MapDatabases.MAP_READER)
|
|
||||||
MapView.enableClosePolygons = true;
|
|
||||||
else
|
|
||||||
MapView.enableClosePolygons = false;
|
|
||||||
|
|
||||||
clearMap();
|
|
||||||
|
|
||||||
mapWorkersProceed();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRenderTheme() {
|
|
||||||
return mRenderTheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the internal theme which is used for rendering the map.
|
|
||||||
*
|
|
||||||
* @param internalRenderTheme
|
|
||||||
* the internal rendering theme.
|
|
||||||
* @return ...
|
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* if the supplied internalRenderTheme is null.
|
|
||||||
*/
|
|
||||||
public boolean setRenderTheme(InternalRenderTheme internalRenderTheme) {
|
|
||||||
if (internalRenderTheme == null) {
|
|
||||||
throw new IllegalArgumentException("render theme must not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (internalRenderTheme.name() == mRenderTheme)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
boolean ret = setRenderTheme((Theme) internalRenderTheme);
|
|
||||||
if (ret) {
|
|
||||||
mRenderTheme = internalRenderTheme.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
clearMap();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the theme file which is used for rendering the map.
|
|
||||||
*
|
|
||||||
* @param renderThemePath
|
|
||||||
* the path to the XML file which defines the rendering theme.
|
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* if the supplied internalRenderTheme is null.
|
|
||||||
* @throws FileNotFoundException
|
|
||||||
* if the supplied file does not exist, is a directory or cannot
|
|
||||||
* be read.
|
|
||||||
*/
|
|
||||||
public void setRenderTheme(String renderThemePath) throws FileNotFoundException {
|
|
||||||
if (renderThemePath == null) {
|
|
||||||
throw new IllegalArgumentException("render theme path must not be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean ret = setRenderTheme(new ExternalRenderTheme(renderThemePath));
|
|
||||||
if (ret) {
|
|
||||||
mRenderTheme = renderThemePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean setRenderTheme(Theme theme) {
|
|
||||||
|
|
||||||
mapWorkersPause(true);
|
|
||||||
|
|
||||||
InputStream inputStream = null;
|
|
||||||
try {
|
|
||||||
inputStream = theme.getRenderThemeAsStream();
|
|
||||||
RenderTheme t = RenderThemeHandler.getRenderTheme(inputStream);
|
|
||||||
t.scaleTextSize(1 + (dpi / 240 - 1) * 0.5f);
|
|
||||||
// FIXME
|
|
||||||
GLRenderer.setRenderTheme(t);
|
|
||||||
TileGenerator.setRenderTheme(t);
|
|
||||||
return true;
|
|
||||||
} catch (ParserConfigurationException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
} catch (SAXException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (inputStream != null) {
|
|
||||||
inputStream.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, e.getMessage());
|
|
||||||
}
|
|
||||||
mapWorkersProceed();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the center of the MapView and triggers a redraw.
|
* Sets the center of the MapView and triggers a redraw.
|
||||||
*
|
*
|
||||||
@ -567,45 +334,6 @@ public class MapView extends RelativeLayout {
|
|||||||
return mMapViewPosition;
|
return mMapViewPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* add jobs and remember MapWorkers that stuff needs to be done
|
|
||||||
*
|
|
||||||
* @param jobs
|
|
||||||
* tile jobs
|
|
||||||
*/
|
|
||||||
public void addJobs(JobTile[] jobs) {
|
|
||||||
if (jobs == null) {
|
|
||||||
mJobQueue.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mJobQueue.setJobs(jobs);
|
|
||||||
|
|
||||||
for (int i = 0; i < mNumMapWorkers; i++) {
|
|
||||||
MapWorker m = mMapWorkers[i];
|
|
||||||
synchronized (m) {
|
|
||||||
m.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void mapWorkersPause(boolean wait) {
|
|
||||||
for (MapWorker mapWorker : mMapWorkers) {
|
|
||||||
if (!mapWorker.isPausing())
|
|
||||||
mapWorker.pause();
|
|
||||||
}
|
|
||||||
if (wait) {
|
|
||||||
for (MapWorker mapWorker : mMapWorkers) {
|
|
||||||
if (!mapWorker.isPausing())
|
|
||||||
mapWorker.awaitPausing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void mapWorkersProceed() {
|
|
||||||
for (MapWorker mapWorker : mMapWorkers)
|
|
||||||
mapWorker.proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You can add/remove/reorder your Overlays using the List of
|
* You can add/remove/reorder your Overlays using the List of
|
||||||
* {@link Overlay}. The first (index 0) Overlay gets drawn first, the one
|
* {@link Overlay}. The first (index 0) Overlay gets drawn first, the one
|
||||||
@ -613,7 +341,7 @@ public class MapView extends RelativeLayout {
|
|||||||
*
|
*
|
||||||
* @return ...
|
* @return ...
|
||||||
*/
|
*/
|
||||||
public List<Overlay> getOverlays() {
|
public List<Layer> getOverlays() {
|
||||||
return this.getOverlayManager();
|
return this.getOverlayManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,10 +349,6 @@ public class MapView extends RelativeLayout {
|
|||||||
return mLayerManager;
|
return mLayerManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileManager getTileManager() {
|
|
||||||
return mTileManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return estimated visible axis aligned bounding box
|
* @return estimated visible axis aligned bounding box
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user