Skip to content

Commit

Permalink
Merge pull request #17743 from osmandapp/fix_fit_map
Browse files Browse the repository at this point in the history
Fix fitting rect/point to map #17553
  • Loading branch information
vshcherb committed Jul 28, 2023
2 parents 068a93d + a20f1de commit 974c87e
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 12 deletions.
33 changes: 32 additions & 1 deletion OsmAnd-java/src/main/java/net/osmand/data/RotatedTileBox.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package net.osmand.data;

import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;

import java.util.ArrayList;
import java.util.List;

public class RotatedTileBox {

/// primary fields
Expand Down Expand Up @@ -30,6 +34,7 @@ public class RotatedTileBox {
private double oyTile;
private QuadRect tileBounds;
private QuadRect latLonBounds;
private List<LatLon> rotatedLatLonBounds;
private QuadPointDouble tileLT;
private QuadPointDouble tileRT;
private QuadPointDouble tileRB;
Expand Down Expand Up @@ -63,13 +68,18 @@ private void copyDerivedFields(RotatedTileBox r) {
rotateSin = r.rotateSin;
oxTile = r.oxTile;
oyTile = r.oyTile;
if (r.tileBounds != null && r.latLonBounds != null) {
if (r.tileBounds != null && r.latLonBounds != null && !Algorithms.isEmpty(r.rotatedLatLonBounds)) {
tileBounds = new QuadRect(r.tileBounds);
latLonBounds = new QuadRect(r.latLonBounds);
tileLT = new QuadPointDouble(r.tileLT);
tileRT = new QuadPointDouble(r.tileRT);
tileRB = new QuadPointDouble(r.tileRB);
tileLB = new QuadPointDouble(r.tileLB);

rotatedLatLonBounds = new ArrayList<>();
for (LatLon latLon : r.rotatedLatLonBounds) {
rotatedLatLonBounds.add(new LatLon(latLon.getLatitude(), latLon.getLongitude()));
}
}
}

Expand Down Expand Up @@ -193,6 +203,12 @@ public void calculateTileRectangle() {
float right = (float) MapUtils.getLongitudeFromTile(zoom, alignTile(bounds.right));
tileBounds = bounds;
latLonBounds = new QuadRect(left, top, right, bottom);

rotatedLatLonBounds = new ArrayList<>();
rotatedLatLonBounds.add(new LatLon(MapUtils.getLatitudeFromTile(zoom, alignTile(y1)), MapUtils.getLongitudeFromTile(zoom, alignTile(x1))));
rotatedLatLonBounds.add(new LatLon(MapUtils.getLatitudeFromTile(zoom, alignTile(y2)), MapUtils.getLongitudeFromTile(zoom, alignTile(x2))));
rotatedLatLonBounds.add(new LatLon(MapUtils.getLatitudeFromTile(zoom, alignTile(y3)), MapUtils.getLongitudeFromTile(zoom, alignTile(x3))));
rotatedLatLonBounds.add(new LatLon(MapUtils.getLatitudeFromTile(zoom, alignTile(y4)), MapUtils.getLongitudeFromTile(zoom, alignTile(x4))));
}

private double alignTile(double tile) {
Expand Down Expand Up @@ -506,6 +522,21 @@ public boolean containsTilePoint(QuadPointDouble qp) {
return tx >= 0 && tx <= pixWidth && ty >= 0 && ty <= pixHeight;
}

public boolean containsRectInRotatedRect(double left, double top, double right, double bottom) {
List<LatLon> rect = new ArrayList<>();
rect.add(new LatLon(top, left));
rect.add(new LatLon(top, right));
rect.add(new LatLon(bottom, right));
rect.add(new LatLon(bottom, left));
rect.add(rect.get(0));

checkTileRectangleCalculated();
List<LatLon> rotatedLatLonRect = new ArrayList<>(this.rotatedLatLonBounds);
rotatedLatLonRect.add(rotatedLatLonRect.get(0));

return Algorithms.isFirstPolygonInsideSecond(rect, rotatedLatLonRect);
}

public boolean containsLatLon(double lat, double lon) {
double tx = getPixXFromLatLon(lat, lon);
double ty = getPixYFromLatLon(lat, lon);
Expand Down
38 changes: 27 additions & 11 deletions OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java
Original file line number Diff line number Diff line change
Expand Up @@ -1550,17 +1550,29 @@ public void fitRectToMap(double left, double right, double top, double bottom,
double clat = bottom / 2 + top / 2;
double clon = left / 2 + right / 2;
tb.setLatLonCenter(clat, clon);
while (tb.getZoom() < MAX_ZOOM_LIMIT && tb.containsLatLon(top, left) && tb.containsLatLon(bottom, right)) {
tb.setZoom(tb.getZoom() + 1);

int minZoom = Math.max(getMinZoom(), MIN_ZOOM_LIMIT);
int maxZoom = Math.min(getMaxZoom(), MAX_ZOOM_LIMIT);
Zoom zoom = new Zoom(tb.getZoom(), (float) tb.getZoomFloatPart(), minZoom, maxZoom);

while (zoom.isZoomInAllowed() && tb.containsRectInRotatedRect(left, top, right, bottom)) {
zoom.zoomIn();
tb.setZoomAndAnimation(zoom.getBaseZoom(), 0, zoom.getZoomFloatPart());
}
while (tb.getZoom() >= MIN_ZOOM_LIMIT && (!tb.containsLatLon(top, left) || !tb.containsLatLon(bottom, right))) {
tb.setZoom(tb.getZoom() - 1);
while (zoom.isZoomOutAllowed() && !tb.containsRectInRotatedRect(left, top, right, bottom)) {
zoom.zoomOut();
tb.setZoomAndAnimation(zoom.getBaseZoom(), 0, zoom.getZoomFloatPart());
}

if (dy != 0 || dx != 0) {
clat = tb.getLatFromPixel(tb.getPixWidth() / 2f, tb.getPixHeight() / 2f + dy);
clon = tb.getLonFromPixel(tb.getPixWidth() / 2f + dx, tb.getPixHeight() / 2f);
float x = tb.getPixWidth() / 2f + dx;
float y = tb.getPixHeight() / 2f + dy;
clat = tb.getLatFromPixel(x, y);
clon = tb.getLonFromPixel(x, y);
}
animatedDraggingThread.startMoving(clat, clon, tb.getZoom(), true);

animatedDraggingThread.startMoving(clat, clon, zoom.getBaseZoom(), zoom.getZoomFloatPart(),
true, false, null, null);
}

public RotatedTileBox getTileBox(int tileBoxWidthPx, int tileBoxHeightPx, int marginTopPx) {
Expand All @@ -1580,8 +1592,10 @@ public RotatedTileBox getTileBox(int tileBoxWidthPx, int tileBoxHeightPx, int ma
tb.setPixelDimensions(tbw, tbh);

if (dy != 0) {
double clat = tb.getLatFromPixel(tb.getPixWidth() / 2, tb.getPixHeight() / 2 - dy);
double clon = tb.getLonFromPixel(tb.getPixWidth() / 2, tb.getPixHeight() / 2);
float x = tb.getPixWidth() / 2f;
float y = tb.getPixHeight() / 2f - dy;
double clat = tb.getLatFromPixel(x, y);
double clon = tb.getLonFromPixel(x, y);
tb.setLatLonCenter(clat, clon);
}
return tb;
Expand All @@ -1603,8 +1617,10 @@ public void fitLocationToMap(double clat, double clon, int zoom,
tb.setLatLonCenter(clat, clon);
tb.setZoom(zoom);
if (dy != 0) {
clat = tb.getLatFromPixel(tb.getPixWidth() / 2, tb.getPixHeight() / 2 + dy);
clon = tb.getLonFromPixel(tb.getPixWidth() / 2, tb.getPixHeight() / 2);
float x = tb.getPixWidth() / 2f;
float y = tb.getPixHeight() / 2f - dy;
clat = tb.getLatFromPixel(x, y);
clon = tb.getLonFromPixel(x, y);
}
if (animated) {
animatedDraggingThread.startMoving(clat, clon, tb.getZoom(), true);
Expand Down

0 comments on commit 974c87e

Please sign in to comment.