summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
blob: 5a28d0c7a093a657a024ea549a9529bd0d916911 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package com.mapbox.mapboxsdk.maps;

import android.graphics.PointF;
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;

import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.geometry.VisibleRegion;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;

/**
 * A projection is used to translate between on screen location and geographic coordinates on
 * the surface of the Earth. Screen location is in screen pixels (not display pixels)
 * with respect to the top left corner of the map (and not necessarily of the whole screen).
 */
public class Projection {

    private final NativeMapView nativeMapView;
    private int[] contentPadding;

    Projection(@NonNull NativeMapView nativeMapView) {
        this.nativeMapView = nativeMapView;
        this.contentPadding = new int[]{0, 0, 0, 0};
    }

    void setContentPadding(int[] contentPadding, int[] userLocationViewPadding) {
        this.contentPadding = contentPadding;

        int[] padding = new int[]{
                contentPadding[0] + userLocationViewPadding[0],
                contentPadding[1] + userLocationViewPadding[1],
                contentPadding[2] + userLocationViewPadding[2],
                contentPadding[3] + userLocationViewPadding[3]
        };

        nativeMapView.setContentPadding(padding);
    }

    int[] getContentPadding() {
        return contentPadding;
    }

    public void invalidateContentPadding(int[] userLocationViewPadding) {
        setContentPadding(contentPadding, userLocationViewPadding);
    }

    /**
     * <p>
     * Returns the distance spanned by one pixel at the specified latitude and current zoom level.
     * </p>
     * The distance between pixels decreases as the latitude approaches the poles.
     * This relationship parallels the relationship between longitudinal coordinates at different latitudes.
     *
     * @param latitude The latitude for which to return the value.
     * @return The distance measured in meters.
     */
    public double getMetersPerPixelAtLatitude(@FloatRange(from = -90, to = 90) double latitude) {
        return nativeMapView.getMetersPerPixelAtLatitude(latitude);
    }

    /**
     * Returns the geographic location that corresponds to a screen location.
     * The screen location is specified in screen pixels (not display pixels) relative to the
     * top left of the map (not the top left of the whole screen).
     *
     * @param point A Point on the screen in screen pixels.
     * @return The LatLng corresponding to the point on the screen, or null if the ray through
     * the given screen point does not intersect the ground plane.
     */
    public LatLng fromScreenLocation(PointF point) {
        return nativeMapView.latLngForPixel(point);
    }

    /**
     * Gets a projection of the viewing frustum for converting between screen coordinates and
     * geo-latitude/longitude coordinates.
     *
     * @return The projection of the viewing frustum in its current state.
     */
    public VisibleRegion getVisibleRegion() {
        LatLngBounds.Builder builder = new LatLngBounds.Builder();

        float left = contentPadding[0];
        float right = nativeMapView.getWidth() - contentPadding[2];
        float top = contentPadding[1];
        float bottom = nativeMapView.getHeight() - contentPadding[3];

        LatLng topLeft = fromScreenLocation(new PointF(left, top));
        LatLng topRight = fromScreenLocation(new PointF(right, top));
        LatLng bottomRight = fromScreenLocation(new PointF(right, bottom));
        LatLng bottomLeft = fromScreenLocation(new PointF(left, bottom));

        builder.include(topLeft)
                .include(topRight)
                .include(bottomRight)
                .include(bottomLeft);

        return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, builder.build());
    }

    /**
     * Returns a screen location that corresponds to a geographical coordinate (LatLng).
     * The screen location is in screen pixels (not display pixels) relative to the top left
     * of the map (not of the whole screen).
     *
     * @param location A LatLng on the map to convert to a screen location.
     * @return A Point representing the screen location in screen pixels.
     */
    public PointF toScreenLocation(LatLng location) {
        return nativeMapView.pixelForLatLng(location);
    }

    float getHeight() {
        return nativeMapView.getHeight();
    }

    float getWidth() {
        return nativeMapView.getWidth();
    }
}