带有自定义图块的动态谷歌地图可防止重复平移

2024-01-21

我有一个动态图块集,我不想允许平移超出其范围。

下面的代码让我很接近,但用户仍然可以在严格边界之外水平滚动,因为它使用地图中心进行比较

var strictBounds = new google.maps.LatLngBounds(
 new google.maps.LatLng(sw_lat, sw_lon), 
 new google.maps.LatLng(ne_lat, ne_lon)
);

google.maps.event.addListener(map, 'drag', function() 
{
  if (strictBounds.contains(map.getCenter())) return;

 // We're out of bounds - Move the map back within the bounds

 var c = map.getCenter(),
     x = c.lng(),
     y = c.lat(),
     maxX = strictBounds.getNorthEast().lng(),
     maxY = strictBounds.getNorthEast().lat(),
     minX = strictBounds.getSouthWest().lng(),
     minY = strictBounds.getSouthWest().lat();

 if (x < minX) x = minX;
 if (x > maxX) x = maxX;
 if (y < minY) y = minY;
 if (y > maxY) y = maxY;

 map.setCenter(new google.maps.LatLng(y, x));
});

为了快速访问,这里是此解决方案的 jsfiddle:http://jsfiddle.net/nYz6k/ http://jsfiddle.net/nYz6k/


假设您对当前检测中心边界的解决方案感到满意,您所要做的就是根据当前地图画布大小限制边界。

您现在得到的结果是,当完全限制时(即纬度和经度都超过边界角),限制边界的每个角都会出现在地图的中心。

解决方案是实际上从边界中删除 x 和 y 偏移,并且仍然能够检查中心(与其他基于边界的检查解决方案相比,这是最有效的解决方案)。

此外,只有在初始化地图和调整窗口大小时才必须限制边界,这意味着当您平移时,除了已经提供的检查方法之外,没有额外的处理开销。

不要忘记设置maxZoom地图的属性(根据需要调整它),因为在确定的缩放级别之上,限制边界本身会适合视口,并且没有解决方案。

重要的!使用“center_changed”而不是“drag”,因为“drag”具有滑动行为,当您完成拖动并设置中心时,地图仍会沿平移方向滑动。


在实现该解决方案之前,我建议您检查一下 Maps API 坐标系和投影的工作原理,因为该解决方案很大程度上基于它,如果您想对其进行调整,了解此信息很有用。

https://developers.google.com/maps/documentation/javascript/maptypes https://developers.google.com/maps/documentation/javascript/maptypes并查看自定义地图类型 -> 地图坐标部分。


这就是你需要做的。首先,您需要实现 2 个在地理坐标 (LatLng) 和像素坐标之间进行转换的简短方法。

var fromLatLngToPixel = function (latLng) {
  var point = map.getProjection().fromLatLngToPoint(latLng);
  var zoom = map.getZoom();
  return new google.maps.Point(
    Math.floor(point.x * Math.pow(2, zoom)),
    Math.floor(point.y * Math.pow(2, zoom))
  );
}

var fromPixelToLatLng = function (pixel) {
  var zoom = map.getZoom();
  var point = new google.maps.Point(
    pixel.x / Math.pow(2, zoom),
    pixel.y / Math.pow(2, zoom)
  );
  return map.getProjection().fromPointToLatLng(point);
}

接下来,实现有效限制边界的方法。请注意,您始终必须保留一个存储原始边界的变量,因为每次调整地图画布大小时,结果边界都会发生变化。

为此,我们说原始边界保留您通过 sw_lat、sw_long 等提供的界限,并且收缩边界通过该方法进行修改。您可以将其重命名为 strictBounds 以仍然在您的方法中工作,但这取决于您。这使用 jQuery 来获取画布对象的宽度和高度。

var shrinkBounds = function () {
  zoom = map.getZoom();

  // The x and y offset will always be half the current map canvas
  // width and height respectively
  xoffset = $('#map_canvas').width() / 2;
  yoffset = $('#map_canvas').height() / 2;

  // Convert the bounds extremities to global pixel coordinates
  var pixswOriginal = fromLatLngToPixel(originalBounds.getSouthWest());
  var pixneOriginal = fromLatLngToPixel(originalBounds.getNorthEast());

  // Shrink the original bounds with the x and y offset
  var pixswShrinked = new google.maps.Point(pixswOriginal.x + xoffset, pixswOriginal.y - yoffset);
  var pixneShrinked = new google.maps.Point(pixneOriginal.x - xoffset, pixneOriginal.y + yoffset);

  // Rebuild the shrinkedBounds object with the modified 
  shrinkedBounds = new google.maps.LatLngBounds(
    fromPixelToLatLng(pixswShrinked),
    fromPixelToLatLng(pixneShrinked));
}

接下来,您所要做的就是调用这个方法:

  • 地图初始化时一次。请注意,根据您调用该方法的时间,您可能会收到一些奇怪的错误,因为地图可能尚未初始化其所有属性。最好的方法是使用projection_changed事件。

    google.maps.event.addListener(map, 'projection_changed', function (e) {
      shrinkBounds();
    });
    
  • 每次调整地图画布大小时

     google.maps.event.addListener(map, 'resize', function (e) {
       shrinkBounds();
     });
    

但其中最重要的部分是,以编程方式调整地图容器的大小永远不会触发“调整大小”事件,因此每次以编程方式调整画布大小时都必须手动触发它(如果您这样做,但我怀疑您这样做) 。

最常见的方法是在调整窗口大小时触发它:

$(window).resize(function () {
  google.maps.event.trigger(map, 'resize');
});

完成所有这些之后,您现在可以安全地使用您的方法,但作为“center_changed”的处理程序,而不是我之前提到的“drag”的处理程序。


我用完整的工作代码设置了一个jsfiddle。

http://jsfiddle.net/nYz6k/ http://jsfiddle.net/nYz6k/

您可以在左下角看到限制,并显示一个小半标记,该标记位于边界的西南角。西北角也有一个,但你自然看不到它,因为它显示在位置上方。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带有自定义图块的动态谷歌地图可防止重复平移 的相关文章

  • 缩放更改后获取谷歌地图 v3 的边界

    我试图在缩放更改后获取地图的边界 但是 Zoom changed 事件会触发before边界已被重新计算 因此 在 Zoom changed 处理程序中 您将获得之前的边界 而不是新的边界 有没有办法获得缩放变化的正确范围 这是一个bug
  • 地理位置邻近搜索

    应用程序中有一个要求 要求在谷歌地图中找出与特定国家和 或城市绑定的所有对象 我们使用谷歌地图 API 预先计算了具有各自纬度和经度的对象并将其存储在数据库中 有时 这些对象在它们可以提供服务的特定服务范围 半径内提供服务 例如现在的情况就
  • 谷歌地图标记被削减了一半 互联网浏览器

    我在 Internet Explorer 中的谷歌地图标记图标遇到了一个奇怪的问题 我的所有标记都显示为一半 两倍且偏移超过 50 这是使用谷歌的演示代码 所以我在其他地方用样式或 jquery 做的事情一定很奇怪 但我不知道是什么 以前有
  • 为什么我无法将动态事件处理程序附加到该元素?

    My code http jsfiddle net arEWv 7 HTML div style width 500px height 500px div div div
  • 在 iOS 中对 Google 地图标记进行聚类

    我有一个基于地图的应用程序 使用 Google 地图的 iOS SDK 我需要在核心数据数据库中存储多达数千个项目 并在地图上用标记显示它们 出于性能和可用性的原因 我需要在用户缩小时对这些标记进行聚类 但我需要确保放置代表性标记 以便用户
  • Android Google 地图:隐藏整个地图的多边形或形状

    我试图隐藏除一个区域之外的整个地图 因为我使用的多边形在我想要显示的区域中有一个洞 问题在于 根据缩放的不同 空白区域会被多边形的颜色覆盖 或者多边形会失去其颜色 这是代码 polygon hide all world map float
  • 通过 HTTPS 的 Google 地图 API v3?

    谷歌地图 API v3 是否有 https 版本 我有一个使用 https 的网站 并且在 IE 中遇到烦人的混合安全和非安全内容错误 我在 v2 中读到你必须付费才能获得此内容 但在 v3 中没有看到任何内容 昨天 Google 宣布网站
  • 让 Google 地图在刷新后保留缩放和居中?

    如何让 Google 地图保留用户的视图 缩放级别和 HTTP 刷新后 现在 它会在每次刷新后重置视图 我可以调整代码吗 下面说 zoom 当前缩放级别 和 center 当前中心 位置 以某种方式 function initialize
  • 如何删除 Google 地图自动完成下拉列表中的“Powered by Google”徽标?

    文档表明 如果我们要使用 Google 地图的自动完成功能 我们可以删除底部的 Powered by Google 徽标 知道该怎么做吗 阿尼梅什 南迪的答案有点旧了 实际上 要删除 由谷歌提供支持 徽标我必须使用以下代码 pac cont
  • 从 Chrome 应用程序使用 Google 地图 API

    我正在尝试在 Chrome 应用程序中使用 Google 地图 每当我尝试加载 JavaScript 时 都会收到错误 Refused to load the script https maps googleapis com maps ap
  • Fragment 中的 android MapView

    我希望有MapView在我的里面Fragment 这是我的FragmentLayoutxml文件
  • 加载谷歌地图时接收模糊的天空屏幕

    while loading google map on device i am receiving below screen sometimes it comes on second load as shown below otherwis
  • 尝试在 android 中使用 Google Maps Android API v2 显示 StreetView 但无法使其正常工作

    我很长时间以来一直在尝试在 Android 中显示特定位置的街景 但不幸的是未能成功 我需要的是 如果我向地图提供位置 LAT LONG 它应该显示该特定位置的街景 以下是显示地图 3D 地图 混合地图 卫星视图等的工作代码 但不显示街景
  • Google 地图地点详细信息 API 不返回电话号码

    我正在拨打 地点详细信息 电话 我想取回电话号码 formatted phone number 该字段没有被返回 并且我在响应中没有看到任何电话号码 我将 fields 属性设置为null获取所有可用的属性 const placeDetai
  • Android Maps Utils 聚类显示 InfoWindow

    我计划使用 utils 库中提供的谷歌地图标记聚类 但谷歌示例应用程序仅显示标记集群 没有任何信息窗口 我现在想知道 我是否无法显示信息窗口 我希望 InfoWindow 显示在标记上 就像普通的谷歌地图标记一样 而不是显示在集群上 我的代
  • 无法从 Google Direction Service api 获取优化路线

    我试图通过提供航点来使用 google Direction api 找到优化路线 以下是我使用过的航点 起始点 LHR 第一个路径点 豪恩斯洛 第二个路径点 哈灵顿 When I tried to find the optimized tr
  • Android Google 地图无法在当前主题中找到样式“mapViewStyle”

    添加谷歌地图视图时 我扩展了MapView 使用xml编辑器将其添加到活动中 并将我的谷歌地图api密钥手动添加到布局xml文件中 我的权限在清单文件中允许互联网 我想知道的是 在 xml 编辑器中 我收到错误 无法在当前主题中找到样式 m
  • Google Maps API v3:在 Firefox 中未触发自定义标记的点击事件

    创建了一个地图 我试图使其具有类似于 我的地图 的功能 我的右侧有两个下拉列表 根据这些 ddl 中的选择 您可以添加自定义标记 图标 您选择标记类型 然后单击地图右上角的 按钮 然后单击要添加标记的位置 我的问题是 这在 IE Safar
  • Android Google 地图:在 2 个位置设置边界并以其中一个位置为中心

    我知道如何在两个位置设置边界 以便两个位置都以最大缩放显示 使用LatLngBounds 我知道如何以某个位置为中心 请问我该如何同时做这两件事 在 2 个位置设置边界AND将地图置于 2 个位置之一的中心 googleMap setCen
  • 在 GeoJson 数据接收到的 Google 地图多边形上放置标签

    我想将带有信息的标签 或带有标签的 div 放在由下面的代码片段绘制的多边形上 样式属性已成功应用于要素 多边形类型 有谁知道如何向该特征添加文本并将其显示在多边形的中心 function handleGeoJson data map da

随机推荐

  • 您建议使用哪种 Java 嵌入式 VM 进行 ARM 开发? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有很多 Java 嵌入式 VM 您对 ARM 开发有何建议 http www cacaovm org http www cacaovm o
  • ttl 在 cassandra 创建墓碑

    我只对 cassandra 进行插入 插入时 仅插入非空值以避免墓碑 但插入 TTL 的记录很少 但是然后从表中执行 select count 会出现以下错误 读取 76 个活动行和 1324 个逻辑删除单元以进行查询 SELECT FRO
  • Vue test-utils 如何测试 router.push()

    在我的组件中 我有一个方法将执行router push import router from router export default methods closeAlert function if this msgTypeContactF
  • 这是 iOS14 中预期的 @State var 行为还是一个错误?

    当我在 iOS14 sim 或设备上运行为 iOS14 编译的以下代码时 更新的 State 变量 选择 不会传递到显示为 sheet 确切的代码在 iOS 13 5 sim 或 13 6 设备上运行正常 如果我在视图中的某个位置放置一个文
  • Android 操作栏标签栏分隔线

    我在设置分隔线的可绘制对象时遇到问题 我的 style xml 如下所示
  • dtruss 在 OS X 10.11 上的 ps 上失败

    我想看看是哪个系统调用ps用于获取 OS X 10 11 El Capitan 上进程的命令行 并遇到以下错误 dtruss ps p 43520 o args dtrace failed to execute ps dtrace cann
  • 运行时错误:无法创建链接(名称已存在)Keras

    当我保存模型时 出现以下错误 RuntimeError Traceback most recent call last
  • 在旋转动画期间更新属性

    我正在 Kotlin 中制作旋转动画 并且在每个动画之后我想设置一个净rotationStart和rotationEnd 其中rotationStart值最初应设置为 0 然后假设每次旋转后的rotationEnd值 val rand Ra
  • NSWindow 中的底部栏

    我正在 Cocoa 中开发一个应用程序 我需要在窗口的底部栏显示进度 但我正在寻找一种解决方案 将底部栏放入NSWindow 期待解决方案 这是在窗口底部放置一个栏的代码 就像在取景器中一样 theWindow setContentBord
  • 使用中的 Gunicorn 连接:('0.0.0.0', 5000)

    我今天下午安装了 redis 它导致了一些错误 所以我卸载了它 但是当我使用以下命令启动应用程序时 此错误仍然存 在foreman start 关于修复有什么想法吗 foreman start 22 46 26 web 1 started
  • .net 4.0 中并行网络爬虫的最佳实践

    我需要通过代理下载很多页面 构建多线程网络爬虫的最佳实践是什么 Parallel For Foreach 是否足够好 还是对于繁重的 CPU 任务更好 您对以下代码有何看法 var multyProxy new MultyProxy mul
  • 如何在 IBM Worklight 中设置 MySQL

    我刚刚了解了IBM Worklight 我想知道如何设置和配置MySQL数据库 我已经设置了Worklight Adapter 但是 我不知道如何用MySQL创建数据库 您应该通过IBM Worklight 入门 http www ibm
  • Python+BeautifulSoup:从网页中抓取特定的表

    我正在尝试从以下位置抓取特定的表格 这个网页 http biz yahoo com c s html 我想要抓取的是股票信息 日期 公司名称 比例以及是否可选 这是我到目前为止所拥有的 from bs4 import BeautifulSo
  • 在模糊功能上获取 jquery 自动完成中的选定值

    我想要具有自动完成功能 当存在模糊事件时 文本框应填充值列表作为第一项 我希望具有与此链接中实现的功能相同的功能link http www redbus in 我有下面的代码 它填充在选项卡和输入键上 但不知道如何在模糊事件上实现相同的功能
  • .net4 中仍然存在内存泄漏 - 将内存 BitmapImage 绑定到 Image-Source

    我知道过去曾在这里提出过非常类似的问题 但都没有解决我的问题 我将内存中的图像加载到 BitmapImage 中 private static BitmapImage LoadImage byte imageData if imageDat
  • mini-css-extract-plugin 模块的 chunkFilename 的用途是什么?

    我现在使用 mini css extract plugin 模块 并设置其 chunkFilename 值并确保值 id css 通过运行它 但是 我看不到该文件 参考如下 https webpack js org plugins mini
  • JavaScript 新函数作用域 ReferenceError

    有什么办法可以让下面的代码工作吗 function var n abc new Function return alert n 如果我在浏览器中运行代码结果是 未捕获的引用错误 n 未定义 另外 我还需要在 新函数 中访问一些其他变量 例如
  • 将图像中的所有白色像素转换为黑色像素

    我有这张图片rand walk 2 png 我想将所有白色像素转换为黑色像素 这样就有了一张图片红色随机游走在黑色背景上 这意味着我不能仅仅反转图像的颜色 我当前的代码只是找到白色像素并将它们设置为黑色 from PIL import Im
  • ADO.NET 中具有 GROUP BY 功能的聚合函数

    这是一个更直接的问题 源于较早的问题我之前有过更普遍的问题 https stackoverflow com questions 828356 allowing a user to create a custom query of a tab
  • 带有自定义图块的动态谷歌地图可防止重复平移

    我有一个动态图块集 我不想允许平移超出其范围 下面的代码让我很接近 但用户仍然可以在严格边界之外水平滚动 因为它使用地图中心进行比较 var strictBounds new google maps LatLngBounds new goo