当前位置: 首页 > 知识库问答 >
问题:

从点和填充创建CameraUpdate,以很好地显示标记

江坚成
2023-03-14

我有一个要在GoogleMap上显示为标记的LatLng点列表。我目前正在通过以下方式计算适合我所有点的相机视图:

>

  • 首先,我用我所有的点计算一个LatLngBound。

    Iterator<LatLng> i = items.iterator();
    LatLngBounds.Builder builder = LatLngBounds.builder();
    while (i.hasNext()) {
        builder.include(i.next());
    }
    LatLngBounds bounds = builder.build();
    

    然后我使用适当的方法:

    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, padding);
    

    更新提供了对我所有观点的良好视图,并添加了一些很好的填充。

    问题

    我想为paddingTop、paddingBottom、padding左和paddingright应用不同的值。也就是说,我两边都没有,然后我在顶部有一个浮动工具栏(大约50dp)和底部有一个浮动卡(大约200dp)。

    如果我不添加填充,一些点将被顶部工具栏或底部卡片覆盖。

    如果我添加最大填充(200dp),那么顶部、左侧和右侧都有巨大的间隙。有什么想法吗?

    __________________________
    | ___________o__________ |
    | |                    | |
    | |____________________|o|
    |         o              |
    |                  o     |
    |    o                   |
    |          MAP           |
    |     o                  |
    |                   o    |
    | ______________________ |
    | |                    | |
    |o|                    | |
    | |                    |o|
    | |____________________| |
    |____________________o___|
    

    我现在唯一的想法是,以像素为单位获取贴图宽度,以Lng为单位获取贴图宽度(未明确定义),找到像素/Lng比率,将所需的填充从像素转换为Lng,然后重新计算LatLngBounds,添加一个假点(每边一个),该点距离我的原始边界那么远。


  • 共有3个答案

    吕成业
    2023-03-14

    您可以使用
    公共静态相机更新newLatLngBound(LatLngBound边界、int宽度、int高度、int填充)

    返回一个CameraUpdate,用于变换相机,使指定的纬度/经度边界以最大可能的缩放级别在指定尺寸的边界框内的屏幕上居中。可以指定其他填充,以进一步限制边界框的大小。

    参见参考

    您将定义一个框,其宽度和高度将位于地图可用区域的中心。然后边界将在该框内居中并尽可能放大。

    您可以通过该框“模拟”填充,而无需将填充应用于地图(然后没有移动地图覆盖,例如水印等)。如果您想要16dp的水平填充,您可以将框的宽度设置为:mapWidth-dpToPx(2*16)

    1. 需要2*,因为您的长方体将在地图内居中。因此,如果只移除16dp,则两侧将有8dp
    2. 我跳过了转换dpToPx的方法,但您很容易在上面找到它

    该方法的局限性在于,由于框居中,所以左右填充必须相同。(顶部和底部相同)。

    最后的想法:当地图上有填充物时,奇怪的事情就会发生。要么将贴图的填充应用于正在定义的框,要么发生其他情况
    当我将框的高度定义为mapHeight-verticalPaddingOfTheMap时,结果并不像预期的那样。我终于把地图的高度写下来了,一切都很好
    如果操作具有填充的贴图,请记住这一点

    韦俊英
    2023-03-14

    这似乎有效,但如果有更好的解决方案,我会等待。

    您需要传递持有地图的视图的宽度和高度(以像素为单位),以便计算像素到投影坐标的系数。然后在Rect对象中传递所需的填充。

    如果您有很多点,这可能最适合在后台任务中运行。

    public static CameraUpdate computeCameraView(final List<LatLng> items,
                                                 final GoogleMap map, final Rect padding,
                                                 final int viewWidth, final int viewHeight) {
    
        // Compute bounds without padding
        Iterator<LatLng> i = items.iterator();
        LatLngBounds.Builder builder = LatLngBounds.builder();
        while (i.hasNext()) {
            builder.include(i.next());
        }
        LatLngBounds bounds = builder.build();
    
        // Create a first CameraUpdate and apply
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 0);
        map.moveCamera(cameraUpdate);
    
        // Convert padding to lat/lng based on current projection
        bounds = map.getProjection().getVisibleRegion().latLngBounds;
        double mapWidth = bounds.northeast.longitude - bounds.southwest.longitude;
        double mapHeight = bounds.northeast.latitude - bounds.southwest.latitude;
        double pixelToLng = mapWidth / viewWidth;
        double pixelToLat = mapHeight / viewHeight;
        padding.top = (int) (padding.top * pixelToLat);
        padding.bottom = (int) (padding.bottom * pixelToLat);
        padding.left = (int) (padding.left * pixelToLng);
        padding.right = (int) (padding.right * pixelToLng);
    
        // Now padding holds insets in lat/lng values.
        // Let's create two fake points and bound
        LatLng northEast = new LatLng(bounds.northeast.latitude + padding.top,
                bounds.northeast.longitude + padding.right);
        LatLng southWest = new LatLng(bounds.southwest.latitude - padding.bottom,
                bounds.southwest.longitude - padding.left);
        LatLngBounds newBounds = new LatLngBounds.Builder()
                .include(northEast).include(southWest).build();
    
        return CameraUpdateFactory.newLatLngBounds(newBounds, 0);
    }
    

    这里的弱点是双重贴图宽度=边界。东北经度-边界。西南经度 。你不能这样计算经度,因为它是一个循环变量(也就是说,如果可见区域穿过180子午线,就会出现问题)。 <罢工> 我会调查的。

    这应该足够了:

    public static double computeLngDistance(LatLng east, LatLng west) {
        if (east.longitude <= 0 && west.longitude >= 0) {
            // We are crossing the 180 line.
            return (east.longitude + 180d) + (180d - west.longitude);
        } else {
            return east.longitude - west.longitude;
        }
    }
    
    锺博耘
    2023-03-14

    实际上有一个更简单、更短的解决方案,只需要三行代码。谢谢https://stackoverflow.com/a/27937256/10035225对于解决方案。

    首先,将工具栏和底部卡的大小转换为像素。

    然后,添加以下三行代码:

    map.setPadding(left, top, right, bottom);
    map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0));
    map.setPadding(0,0,0,0);
    

    第一行:顶部和底部的填充物是您的工具栏和底部卡片大小加上一些额外的填充物,左侧和右侧可以是任何填充物,只要看起来不错。

    第二行:将相机移动/动画到边界并记住将填充设置为0,因为您不需要任何额外的填充,因为您已经在第一行设置了它。

    第三行:将贴图填充设置回原始填充(对于我的情况为0),因为第一行中设置的贴图填充是永久的。

    就这样,你来了!希望有帮助!

     类似资料:
    • 问题内容: 我想将浮点数表示为四舍五入到一定位数的字符串,并且从不使用指数格式。本质上,我想显示任何浮点数并确保它“看起来不错”。 这个问题有几个部分: 我需要能够指定有效位数。 有效位数必须是可变的,而字符串格式化运算符不能做到这一点。[编辑]我已经改正了;字符串格式化操作符可以做到这一点。 我需要将其四舍五入到一个人期望的方式,而不是像1.999999999999 我想出了一种方法来完成此任务

    • 我在HTML正文中有一个名为RecipeContainer的div。我正在尝试使用一个API来根据用户的关键字搜索菜谱。最初,我在一个HTML中有6个DIV,它们被填充在我的javascript中,并使用CSS样式,但我认为这不再是一个有效的解决方案。 下面是我当前的代码,它试图将功能转移到完全在JS中创建的每个菜谱的平铺中: 这是每当用户点击Submit时执行的循环。实际上,我有两个问题与此相关

    • 我使用iReport创建了一个报告模板。 我也想在Jaspersoft Studio中显示该报告模板。 问题是printWhenExpress标签在Jaspersoft Studio中无法正常工作,因此没有过滤任何内容。 这正常吗?

    • 第一个类称为FileReader,它读取一个逐行写入的txt文件,我们需要的每个字段都用“;”分隔,例如(“哥伦比亚大学”;“美国”;78.86;2012)。每行包含2个字符串(大学名和国家)和2个数字(分数和年份)。FileReader类在读取txt文件后,在ArrayList中返回其内容。 该作业的第二个类称为UniversityScores,它有4个字段(uniname、country、sc

    • 问题内容: 我已经为此工作了好几个小时,试图弄清楚为什么没有出现所谓的简单自动完成功能。 事实证明,在我的代码中,input元素被设置为,而pac-container上的样式为。 我可以在DevTools中更改这些值,并且效果很好,但是我不知道如何或为什么将这些值设置为这些值。 我的自动完成功能是在这样的Angular Directive中设置的,其中loadGmaps获取google api。

    • 问题内容: 我正在创建一个要在网页上显示的表,并且该表是由MySQL数据库中的数据填充的。我正在尝试做一些让我感到困难的事情。 首先,我试图通过JavaScript调用HTML中单独文件中存在的PHP代码。我认为我的工作正常,但是我不确定100%是否正确(因为表格不会显示)。我认为它工作正常,因为该表的 某些 代码(在PHP文件中)显示在FireBug中。 其次,我正在尝试使行交替显示颜色以便于查