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

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(使用前将#替换为@)

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

  • 有没有办法避开 Google 路线中的特定道路或坐标?

    API 有一个航路点参数 以便 API 计算经过指定航路点的路线 有什么方法可以给出要避开的航路点而不是要经过的航路点 它 目前 尚未实施 有一个开放的功能请求 问题 214 影响方向的能力 例如 避免 路障 https code goog
  • (angularjs-google-maps) ng-click 内部标记

    这个问题是关于angularjs google maps https github com allenhwkim angularjs google maps https github com allenhwkim angularjs goo
  • 为什么我在谷歌地图上时收到此错误“无法加载 DynamiteLoader:java.lang.ClassNotFoundException:未找到类?

    我正在尝试绘制两个纬度 经度之间的路径 这是我的 MapsActivity java protected void onCreate Bundle savedInstanceState super onCreate savedInstanc
  • 查找地图 API 密钥的所有者

    我一直在开发一个已实现 Google 地图 API 密钥的网站 但我需要知道 API 密钥的所有者是谁 有什么办法可以查到吗 任何帮助表示赞赏 Thanks 密钥的所有者是受 Google 保护的私人信息 最终用户无法找到密钥的所有者 如果
  • rvm + Rails3 + gmaps4rails -acts_as_gmappable

    我是一个红宝石导轨之类的菜鸟 抱歉 如果我的问题很愚蠢 我设置了一个运行 ruby 1 8 7 p334 的 rvm 作为用户 环境 我已经为我的 应用程序 创建了一个 gemset 现在我想在页面上显示地址的地图 我四处寻找 发现了 gm
  • Google 地图 - 如何获取空白底图

    我想要一个空白的谷歌地图 没有任何显示路线图 地形 混合或卫星数据的底图 只有一个白色背景来仅显示我的图层 那可能吗 hexblot 的建议是正确的 即查看自定义地图类型文档 这是我在没有任何控制的情况下获得空白地图 白色背景 所做的事情
  • 转换 google.maps.Point 中的 (x, y) 像素坐标

    我试图根据我的 x y 像素坐标 当然还有地图选项 例如缩放和中心 找出 LatLng 为了做到这一点 我发布了另一个question https stackoverflow com questions 25219346 how to co
  • 谷歌地图及其标记

    我有一个标记位置的 JSON 数组被拉入 Google 地图 这工作正常 我还将 infoWindows 链接到每个标记 这些也工作得很好 但是 当我单击标记 在任何浏览器中 时 信息窗口仅出现在最后添加的标记上方 这是一个小提琴 http
  • 根据已知的纬度和经度点在图像上放置点的尝试失败

    我为这个含糊的标题道歉 我真的想不出更好的方法来总结它 非常欢迎提出建议 我正在开发一个实际上不需要谷歌地图的项目 它只会为这个项目带来额外的开销 但是 到目前为止 我不知道如何在没有谷歌地图的情况下做到这一点 如果我要将平面图的图形叠加层
  • Android 在谷歌地图上绘制带箭头的折线和方向路径

    I have added polylines but not able to add arrow with direction on google map should be display as below And when it zoo
  • Font Awesome 图标作为 Google Maps API V3 中的标记

    我想使用一个很棒的字体图标作为 Google 地图标记 这是我的代码 function addMarker marker marker1 new google maps Marker position new google maps Lat
  • 根据城市名称谷歌地图获取坐标

    我正在尝试使用谷歌地图创建基于城市的坐标 这是我现在拥有的示例 我总是收到错误 var address Zurich Ch var geocoder new google maps Geocoder geocoder geocode add
  • 更新标记文本谷歌地图API

    因此 我在我的网站上使用 Google 地图 API 并且希望标记文本等于另一个 html 元素的值 这里有人知道如何更新 google 地图 API 中标记的文本属性的值吗 这是我关于该问题的代码 var map marker var i
  • 修复了 Google 地图混搭中的图例

    我有一个带有 Google 地图混搭的页面 其中的图钉按日期 周一 周二等 进行颜色编码 包含地图的 IFrame 是动态调整大小的 因此当浏览器窗口调整大小时 它也会调整大小 我想在地图窗口的一角放置一个图例 告诉用户每种颜色的含义 Go
  • 以编程方式设置谷歌地图片段可见性(API2)

    xml
  • 使用 Selenium 放置嵌入的谷歌地图标记

    我有一个 asp net 网站 作为向导的一部分 它使用嵌入式谷歌地图通过单击地图放置标记来选择位置 我如何使用 Selenium 实现自动化 我特别尝试过 ClickAt 双击 鼠标按下 鼠标按下 在所有情况下 传递地图 div id 作
  • 如何在android中的地图上显示当前位置标记?

    我正在开发一个应用程序 我想在地图中使用标记显示当前位置 我正在使用谷歌地图 v2 在这里 当 GPS 关闭时 我可以显示地图和标记 但当 GPS 打开时 地图上看不到任何标记 我的要求是在地图上显示当前位置的标记 我尝试这样 Overri
  • infoWindow(谷歌地图)捕获关闭窗口的事件

    当信息窗口关闭时 您触发操作的方式是什么 我找不到任何听众 我正在考虑运行一些后台 Runnable 检查marker isInfoWindowShown 是否 我想要做的 在我的地图上显示按钮 当用户单击点 出现信息窗口 时 屏幕底部也有
  • 设置反向地理编码 Gmaps v.3 的语言

    现在有人如何设置反向地理编码 php 响应的语言吗 始终设置 en Here is the code code api key url http maps google com maps geo q 49 8411860 30 106658
  • Google 地理编码——解析可能返回不同结果的地址组件

    我正在使用 Google 地图 V3 api 我正在提交地址搜索以返回正确的地理编码结果 包括地址 机构名称和纬度 经度 我的问题是地理编码器的响应可以采用不同的格式 它始终遵循相同的结构 但某些响应对地址组件数据结构使用不同的键 例如 某

随机推荐

  • 您建议使用哪种 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