Add 2 fingers rotation

This commit is contained in:
vshcherb 2013-10-06 13:23:35 +03:00
parent 3752cd25ab
commit 2d6ce8c5ca
4 changed files with 154 additions and 153 deletions

View file

@ -363,10 +363,10 @@ public class MapUtils {
* @return
*/
public static float unifyRotationTo360(float rotate) {
while(rotate < 0){
while(rotate < -180){
rotate += 360;
}
while(rotate > 360){
while(rotate > +180){
rotate -= 360;
}
return rotate;

View file

@ -276,152 +276,153 @@ public class MapRenderRepositories {
long now = System.currentTimeMillis();
try {
System.gc(); // to clear previous objects
int count = 0;
ArrayList<BinaryMapDataObject> tempResult = new ArrayList<BinaryMapDataObject>();
ArrayList<BinaryMapDataObject> basemapResult = new ArrayList<BinaryMapDataObject>();
TLongSet ids = new TLongHashSet();
List<BinaryMapDataObject> coastLines = new ArrayList<BinaryMapDataObject>();
List<BinaryMapDataObject> basemapCoastLines = new ArrayList<BinaryMapDataObject>();
int leftX = MapUtils.get31TileNumberX(cLeftLongitude);
int rightX = MapUtils.get31TileNumberX(cRightLongitude);
int bottomY = MapUtils.get31TileNumberY(cBottomLatitude);
int topY = MapUtils.get31TileNumberY(cTopLatitude);
BinaryMapIndexReader.SearchFilter searchFilter = new BinaryMapIndexReader.SearchFilter() {
System.gc(); // to clear previous objects
int count = 0;
ArrayList<BinaryMapDataObject> tempResult = new ArrayList<BinaryMapDataObject>();
ArrayList<BinaryMapDataObject> basemapResult = new ArrayList<BinaryMapDataObject>();
TLongSet ids = new TLongHashSet();
List<BinaryMapDataObject> coastLines = new ArrayList<BinaryMapDataObject>();
List<BinaryMapDataObject> basemapCoastLines = new ArrayList<BinaryMapDataObject>();
int leftX = MapUtils.get31TileNumberX(cLeftLongitude);
int rightX = MapUtils.get31TileNumberX(cRightLongitude);
int bottomY = MapUtils.get31TileNumberY(cBottomLatitude);
int topY = MapUtils.get31TileNumberY(cTopLatitude);
BinaryMapIndexReader.SearchFilter searchFilter = new BinaryMapIndexReader.SearchFilter() {
@Override
public boolean accept(TIntArrayList types, BinaryMapIndexReader.MapIndex root) {
for (int j = 0; j < types.size(); j++) {
int type = types.get(j);
TagValuePair pair = root.decodeType(type);
if (pair != null) {
// TODO is it fast enough ?
for (int i = 1; i <= 3; i++) {
renderingReq.setIntFilter(renderingReq.ALL.R_MINZOOM, zoom);
renderingReq.setStringFilter(renderingReq.ALL.R_TAG, pair.tag);
renderingReq.setStringFilter(renderingReq.ALL.R_VALUE, pair.value);
if (renderingReq.search(i, false)) {
return true;
}
}
@Override
public boolean accept(TIntArrayList types, BinaryMapIndexReader.MapIndex root) {
for (int j = 0; j < types.size(); j++) {
int type = types.get(j);
TagValuePair pair = root.decodeType(type);
if (pair != null) {
// TODO is it fast enough ?
for (int i = 1; i <= 3; i++) {
renderingReq.setIntFilter(renderingReq.ALL.R_MINZOOM, zoom);
renderingReq.setStringFilter(renderingReq.ALL.R_TAG, pair.tag);
renderingReq.setStringFilter(renderingReq.ALL.R_VALUE, pair.value);
if (renderingReq.search(RenderingRulesStorage.TEXT_RULES, false)) {
if (renderingReq.search(i, false)) {
return true;
}
}
renderingReq.setStringFilter(renderingReq.ALL.R_TAG, pair.tag);
renderingReq.setStringFilter(renderingReq.ALL.R_VALUE, pair.value);
if (renderingReq.search(RenderingRulesStorage.TEXT_RULES, false)) {
return true;
}
}
}
return false;
}
};
if (zoom > 16) {
searchFilter = null;
}
boolean ocean = false;
boolean land = false;
MapIndex mi = null;
searchRequest = BinaryMapIndexReader.buildSearchRequest(leftX, rightX, topY, bottomY, zoom, searchFilter);
for (BinaryMapIndexReader c : files.values()) {
searchRequest.clearSearchResults();
List<BinaryMapDataObject> res;
try {
res = c.searchMapIndex(searchRequest);
} catch (IOException e) {
res = new ArrayList<BinaryMapDataObject>();
log.debug("Search failed " + c.getRegionNames(), e); //$NON-NLS-1$
}
for (BinaryMapDataObject r : res) {
if (checkForDuplicateObjectIds) {
if (ids.contains(r.getId()) && r.getId() > 0) {
// do not add object twice
continue;
}
ids.add(r.getId());
}
count++;
if (r.containsType(r.getMapIndex().coastlineEncodingType)) {
if (c.isBasemap()) {
basemapCoastLines.add(r);
} else {
coastLines.add(r);
}
} else {
// do not mess coastline and other types
if (c.isBasemap()) {
basemapResult.add(r);
} else {
tempResult.add(r);
}
}
if (checkWhetherInterrupted()) {
return false;
}
};
if (zoom > 16) {
searchFilter = null;
}
boolean ocean = false;
boolean land = false;
MapIndex mi = null;
searchRequest = BinaryMapIndexReader.buildSearchRequest(leftX, rightX, topY, bottomY, zoom, searchFilter);
for (BinaryMapIndexReader c : files.values()) {
searchRequest.clearSearchResults();
List<BinaryMapDataObject> res = c.searchMapIndex(searchRequest);
for (BinaryMapDataObject r : res) {
if (checkForDuplicateObjectIds) {
if (ids.contains(r.getId()) && r.getId() > 0) {
// do not add object twice
continue;
}
ids.add(r.getId());
}
count++;
if (r.containsType(r.getMapIndex().coastlineEncodingType)) {
if (c.isBasemap()) {
basemapCoastLines.add(r);
} else {
coastLines.add(r);
}
} else {
// do not mess coastline and other types
if (c.isBasemap()) {
basemapResult.add(r);
} else {
tempResult.add(r);
}
}
if (checkWhetherInterrupted()) {
return false;
}
}
if (searchRequest.isOcean()) {
mi = c.getMapIndexes().get(0);
ocean = true;
}
if (searchRequest.isLand()) {
mi = c.getMapIndexes().get(0);
land = true;
}
}
String coastlineTime = "";
boolean addBasemapCoastlines = true;
boolean emptyData = zoom > BASEMAP_ZOOM && tempResult.isEmpty() && coastLines.isEmpty();
boolean basemapMissing = zoom <= BASEMAP_ZOOM && basemapCoastLines.isEmpty() && mi == null;
boolean detailedLandData = zoom >= 14 && tempResult.size() > 0;
if(!coastLines.isEmpty()) {
long ms = System.currentTimeMillis();
boolean coastlinesWereAdded = processCoastlines(coastLines, leftX, rightX, bottomY, topY, zoom,
basemapCoastLines.isEmpty(), true, tempResult);
addBasemapCoastlines = (!coastlinesWereAdded && !detailedLandData) || zoom <= BASEMAP_ZOOM;
coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )";
} else {
addBasemapCoastlines = !detailedLandData;
if (searchRequest.isOcean()) {
mi = c.getMapIndexes().get(0);
ocean = true;
}
if(addBasemapCoastlines){
long ms = System.currentTimeMillis();
boolean coastlinesWereAdded = processCoastlines(basemapCoastLines, leftX, rightX, bottomY, topY, zoom,
true, true, tempResult);
addBasemapCoastlines = !coastlinesWereAdded;
coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )";
if (searchRequest.isLand()) {
mi = c.getMapIndexes().get(0);
land = true;
}
if(addBasemapCoastlines && mi != null){
BinaryMapDataObject o = new BinaryMapDataObject(new int[] { leftX, topY, rightX, topY, rightX, bottomY, leftX, bottomY, leftX,
topY }, new int[] { ocean && !land ? mi.coastlineEncodingType : (mi.landEncodingType) }, null, -1);
o.setMapIndex(mi);
tempResult.add(o);
}
if(emptyData || basemapMissing){
// message
MapIndex mapIndex;
if(!tempResult.isEmpty()) {
mapIndex = tempResult.get(0).getMapIndex();
} else {
mapIndex = new MapIndex();
mapIndex.initMapEncodingRule(0, 1, "natural", "coastline");
mapIndex.initMapEncodingRule(0, 2, "name", "");
}
}
if(zoom <= BASEMAP_ZOOM || emptyData) {
tempResult.addAll(basemapResult);
}
if (count > 0) {
log.info(String.format("BLat=%s, TLat=%s, LLong=%s, RLong=%s, zoom=%s", //$NON-NLS-1$
cBottomLatitude, cTopLatitude, cLeftLongitude, cRightLongitude, zoom));
log.info(String.format("Searching: %s ms %s (%s results found)", System.currentTimeMillis() - now, coastlineTime, count)); //$NON-NLS-1$
}
cObjects = tempResult;
cObjectsBox = dataBox;
} catch (IOException e) {
log.debug("Search failed", e); //$NON-NLS-1$
return false;
}
String coastlineTime = "";
boolean addBasemapCoastlines = true;
boolean emptyData = zoom > BASEMAP_ZOOM && tempResult.isEmpty() && coastLines.isEmpty();
boolean basemapMissing = zoom <= BASEMAP_ZOOM && basemapCoastLines.isEmpty() && mi == null;
boolean detailedLandData = zoom >= 14 && tempResult.size() > 0;
if (!coastLines.isEmpty()) {
long ms = System.currentTimeMillis();
boolean coastlinesWereAdded = processCoastlines(coastLines, leftX, rightX, bottomY, topY, zoom,
basemapCoastLines.isEmpty(), true, tempResult);
addBasemapCoastlines = (!coastlinesWereAdded && !detailedLandData) || zoom <= BASEMAP_ZOOM;
coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )";
} else {
addBasemapCoastlines = !detailedLandData;
}
if (addBasemapCoastlines) {
long ms = System.currentTimeMillis();
boolean coastlinesWereAdded = processCoastlines(basemapCoastLines, leftX, rightX, bottomY, topY, zoom,
true, true, tempResult);
addBasemapCoastlines = !coastlinesWereAdded;
coastlineTime = "(coastline " + (System.currentTimeMillis() - ms) + " ms )";
}
if (addBasemapCoastlines && mi != null) {
BinaryMapDataObject o = new BinaryMapDataObject(new int[]{leftX, topY, rightX, topY, rightX, bottomY, leftX, bottomY, leftX,
topY}, new int[]{ocean && !land ? mi.coastlineEncodingType : (mi.landEncodingType)}, null, -1);
o.setMapIndex(mi);
tempResult.add(o);
}
if (emptyData || basemapMissing) {
// message
MapIndex mapIndex;
if (!tempResult.isEmpty()) {
mapIndex = tempResult.get(0).getMapIndex();
} else {
mapIndex = new MapIndex();
mapIndex.initMapEncodingRule(0, 1, "natural", "coastline");
mapIndex.initMapEncodingRule(0, 2, "name", "");
}
}
if (zoom <= BASEMAP_ZOOM || emptyData) {
tempResult.addAll(basemapResult);
}
if (count > 0) {
log.info(String.format("BLat=%s, TLat=%s, LLong=%s, RLong=%s, zoom=%s", //$NON-NLS-1$
cBottomLatitude, cTopLatitude, cLeftLongitude, cRightLongitude, zoom));
log.info(String.format("Searching: %s ms %s (%s results found)", System.currentTimeMillis() - now, coastlineTime, count)); //$NON-NLS-1$
}
cObjects = tempResult;
cObjectsBox = dataBox;
return true;
}
@ -565,7 +566,8 @@ public class MapRenderRepositories {
currentRenderingContext.height = (int) (requestedBox.getPixHeight() / mapDensity);
currentRenderingContext.nightMode = nightMode;
currentRenderingContext.useEnglishNames = prefs.USE_ENGLISH_NAMES.get();
currentRenderingContext.setDensityValue(renderer.getDensity() * prefs.MAP_ZOOM_SCALE_BY_DENSITY.get());
currentRenderingContext.setDensityValue(1.5f);
//currentRenderingContext.setDensityValue(renderer.getDensity() * prefs.MAP_ZOOM_SCALE_BY_DENSITY.get());
// init rendering context
currentRenderingContext.tileDivisor = (float) MapUtils.getPowZoom(31 - requestedBox.getZoom());
if (checkWhetherInterrupted()) {

View file

@ -132,6 +132,8 @@ public class MapInfoLayer extends OsmandMapLayer {
mapInfoControls = new MapWidgetRegistry(map.getMyApplication().getSettings());
monitoringServices = new MonitoringInfoControl();
registerAllControls();
createControls();

View file

@ -10,11 +10,16 @@ import net.osmand.PlatformUtil;
import net.osmand.access.AccessibilityActionsProvider;
import net.osmand.access.AccessibleToast;
import net.osmand.access.MapExplorer;
import net.osmand.data.*;
import net.osmand.data.LatLon;
import net.osmand.data.QuadPoint;
import net.osmand.data.RotatedTileBox;
import net.osmand.map.IMapLocationListener;
import net.osmand.map.MapTileDownloader.DownloadRequest;
import net.osmand.map.MapTileDownloader.IMapDownloaderCallback;
import net.osmand.plus.*;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.views.MultiTouchSupport.MultiTouchZoomListener;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.util.MapUtils;
@ -45,7 +50,7 @@ import android.widget.Toast;
public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCallback, Callback {
protected final static int LOWEST_ZOOM_TO_ROTATE = 10;
protected final static int LOWEST_ZOOM_TO_ROTATE = 9;
private boolean MEASURE_FPS = false;
private int fpsMeasureCount = 0;
private int fpsMeasureMs = 0;
@ -347,10 +352,6 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
return settings;
}
private void refreshMapNonLightweightMap() {
}
private void refreshMapInternal(boolean updateVectorRendering) {
handler.removeMessages(1);
long ms = SystemClock.elapsedRealtime();
@ -625,13 +626,14 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
private float y2;
private LatLon initialCenterLatLon;
private boolean startRotating = false;
private static final float ANGLE_THRESHOLD = 18;
@Override
public void onZoomEnded(double relativeToStart, float angleRelative) {
public void onZoomEnded(double relativeToStart, float angleRelative) {
// 1.5 works better even on dm.density=1 devices
float dz = (float) (Math.log(relativeToStart) / Math.log(2)) * 1.5f;
setIntZoom(Math.round(dz) + initialViewport.getZoom());
if(Math.abs(angleRelative) < 17){
if(Math.abs(angleRelative) < ANGLE_THRESHOLD){
angleRelative = 0;
}
rotateToAnimate(initialViewport.getRotate() + angleRelative);
@ -667,11 +669,11 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
@Override
public void onZoomingOrRotating(double relativeToStart, float relAngle) {
double dz = (Math.log(relativeToStart) / Math.log(2)) * 1.5;
if (Math.abs(dz) <= (startRotating ? 0.05 : 0.05)) {
if (Math.abs(dz) <= 0.1) {
// keep only rotating
dz = 0;
}
if(Math.abs(relAngle) < 17 && !startRotating) {
if(Math.abs(relAngle) < ANGLE_THRESHOLD && !startRotating) {
relAngle = 0;
} else {
startRotating = true;
@ -691,17 +693,12 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
float calcZoom = initialViewport.getZoom() + dz + initialViewport.getZoomScale();
float calcRotate = calc.getRotate() + angle;
calc.setRotate(angle);
calc.setRotate(calcRotate);
calc.setZoomAnimation(dz);
final LatLon r = calc.getLatLonFromPixel(cp.x + dx, cp.y + dy);
setLatLon(r.getLatitude(), r.getLongitude());
if (Math.abs(currentViewport.getZoomAnimation() + currentViewport.getZoom() + currentViewport.getZoomScale() -
calcZoom) > 0.1) {
zoomToAnimate(calcZoom, true);
}
if(currentViewport.getRotate() != calcRotate){
rotateToAnimate(calcRotate);
}
zoomToAnimate(calcZoom, true);
rotateToAnimate(calcRotate);
}
}