Android Google地图 - 所有标记背后的自定义背景

swa*_*ner 11 android google-maps

我试图在地图和我的标记之间加上背景; 此图像应始终(!)留在所有标记后面.

我尝试了几种方法,例如showInfoWindow()我的所有标记除了背景图像,但似乎这只会对最后一个有帮助.

然后我尝试使用解决方案GroundOverlay,但我需要我的图像始终保持相同的大小(例如设备大小的一半),与缩放系数无关.

Android上有解决方案吗?

ˆᵛˆ*_*ˆᵛˆ 5

这很容易做到.

添加两个标记而不是一个.首先在lat_lng中将背景添加为位图.

像这样的东西:

map.addMarker(new MarkerOptions()
      .position(lat_lng)
      .anchor(0.5f, 0.5f)
      .icon(BitmapDescriptorFactory.fromBitmap(bitmap)));
Run Code Online (Sandbox Code Playgroud)

然后像往常一样在同一个lat_lng中添加你的标记.

对每个标记执行上述操作.


ant*_*nio -1

最好的选择是使用 aGroundOverlay来显示背景,在视图更改时添加和删除它,并根据VisibleRegion地图计算其尺寸,以便在缩放之间保持正确的尺寸。

从文档中:

位置

有两种方法可以指定地面叠加层的位置:

  • 使用位置:您必须提供地面覆盖层的图像、锚点将固定到的 LatLng 以及覆盖层的宽度(以米为单位)。默认情况下,锚点距图像顶部 50%,距图像左侧 50%。这是可以改变的。您可以选择提供覆盖层的高度(以米为单位)。如果您不提供叠加层的高度,系统会自动计算该高度以保留图像的比例。

  • 使用边界:您必须提供包含图像的 LatLngBounds。

以下示例使用 aOnCameraChangeListener来删除和添加 a,GroundOverlay该 a 显示ic_launcher地图中心的可绘制对象,即地图宽度的 75%(GroundOverlay在onCameraChange事件中删除和添加 可以确保图像的大小始终相同,独立于缩放级别)。

public class MyMapActivity extends Activity implements OnCameraChangeListener {
    GroundOverlay backgroundOverlay = null;
    GoogleMap map;

    // ...

    @Override
    public void onCameraChange(final CameraPosition cameraPosition) {
        if (backgroundOverlay != null) {
            backgroundOverlay.remove();
        }

        VisibleRegion visibleRegion = map.getProjection()
                .getVisibleRegion();

        Location nearLeftLocation = new Location("nearLeftLocation");
        nearLeftLocation.setLatitude(visibleRegion.nearLeft.latitude);
        nearLeftLocation.setLongitude(visibleRegion.nearLeft.longitude);

        Location nearRightLocation = new Location("nearRightLocation");
        nearRightLocation.setLatitude(visibleRegion.nearRight.latitude);
        nearRightLocation.setLongitude(visibleRegion.nearRight.longitude);

        float width = nearLeftLocation.distanceTo(nearRightLocation);

        GroundOverlayOptions background = new GroundOverlayOptions()
                .image(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))
                .position(cameraPosition.target, width * 0.75f);

        backgroundOverlay = map.addGroundOverlay(background);
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:

正如我在评论中所说,我们可以setPosition在setDimensions现有的基础上GroundOverlay,而不是在每次相机更改时添加/删除它。

我已经在多种设备上进行了测试,它似乎减少了低端设备上的闪烁,但仍然不是一个完美的解决方案(图像在缩放之间调整大小)。我非常确定这是我们可以使用GroundOverlays 得到的最好结果。

public class MyMapActivity extends Activity implements OnCameraChangeListener {
    GroundOverlay backgroundOverlay = null;
    GoogleMap map;

    // ...

    @Override
    public void onCameraChange(final CameraPosition cameraPosition) {
        VisibleRegion visibleRegion = map.getProjection().getVisibleRegion();

        Location nearLeftLocation = new Location("nearLeftLocation");
        nearLeftLocation.setLatitude(visibleRegion.nearLeft.latitude);
        nearLeftLocation.setLongitude(visibleRegion.nearLeft.longitude);

        Location nearRightLocation = new Location("nearRightLocation");
        nearRightLocation.setLatitude(visibleRegion.nearRight.latitude);
        nearRightLocation.setLongitude(visibleRegion.nearRight.longitude);

        float width = nearLeftLocation.distanceTo(nearRightLocation);

        if (backgroundOverlay == null) {
            GroundOverlayOptions background = new GroundOverlayOptions()
                    .image(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))
                    .position(cameraPosition.target, width * 0.75f);

            backgroundOverlay = map.addGroundOverlay(background);
        } else {
            backgroundOverlay.setPosition(cameraPosition.target);
            backgroundOverlay.setDimensions(width * 0.75f);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新

我找到了另一个解决方案。如果您的背景是纯色、半透明颜色,则可以使用 TileOverlay 将其设置在所有标记下方。

这个想法是创建一个 TileProvider,它始终返回一个非常小的(在我的示例中为 2x2 像素)图像,该图像将绘制在所有标记下方。为了确保性能,Tile返回的值TileProvider将始终相同。

这是代码:

public class BackgroundTileProvider implements TileProvider {
    private Tile tile;

    @Override
    public Tile getTile(int x, int y, int zoom) {
        if (tile == null) {
            // Create a very small (for performance) bitmap with alpha
            Bitmap bmp = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);

            // Draw the desired color to use as background
            Canvas canvas = new Canvas(bmp);
            canvas.drawColor(Color.argb(150, 255, 0, 0));

            // Get the bytes and create the Tile
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);

            tile = new Tile(2, 2, stream.toByteArray());
        }

        return tile;
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要将 TileOverlay 添加到地图中,如下所示:

TileProvider tileProvider = new BackgroundTileProvider();
TileOverlay tileOverlay = map.addTileOverlay(
    new TileOverlayOptions().tileProvider(tileProvider));
Run Code Online (Sandbox Code Playgroud)

结果将如下所示:

在此输入图像描述