当前位置:   article > 正文

vue使用谷歌地图绘制图形以及地图选点功能_vue谷歌地图选点

vue谷歌地图选点

因做加拿大配送项目得用到谷歌地图

效果图:

第一步:

首先访问谷歌地图以及文档需要加速插件

你得在谷歌浏览器扩展程序里添加一个加速插件(如图):

 最好充值vip,不然免费的加速通道不稳定

本人是在vue项目里使用(跟原生html写法区别不大)

谷歌地图官方文档:Google Maps Platform Documentation  |  Maps JavaScript API  |  Google Developers

第二步:

安装@googlemaps/js-api-loader 依赖包(这里不推荐使用vue2-google-maps,官方推荐使用@googlemaps/js-api-loader这个更好用)

npm i @googlemaps/js-api-loader

安装完成后导入:

import { Loader } from '@googlemaps/js-api-loader' //引入

template html:

  1. <template>
  2. <div class="content">
  3. <input
  4. v-if="mapType == 'selectPoint'"
  5. id="pac-input"
  6. class="controls"
  7. type="text"
  8. :placeholder="L('请输入关键字')"
  9. />
  10. <div :style="googleMapStyle" class="googleMap" :id="mapID"></div>
  11. </div>
  12. </template>

vue props:

  1. <script>
  2. import { Loader } from '@googlemaps/js-api-loader' //引入
  3. export default {
  4. props: {
  5. //mapType属性值为:
  6. //selectPoint时是地图选点
  7. //POLYGON是绘制地图多边形区域
  8. //地图id
  9. mapID: {
  10. type: String,
  11. default: () => {
  12. return 'googleMap'
  13. },
  14. },
  15. //谷歌地图类型
  16. mapType: {
  17. type: String,
  18. default: () => {
  19. return 'default'
  20. },
  21. },
  22. //谷歌地图样式
  23. googleMapStyle: {
  24. type: Object,
  25. default: () => {
  26. return {
  27. wdith: '100%',
  28. height: '500px',
  29. }
  30. },
  31. },
  32. //谷歌地图配置
  33. mapOptions: {
  34. type: Object,
  35. default: () => {
  36. return {
  37. //为了关闭默认控件集,设置地图的disableDefaultUI的属性为true
  38. disableDefaultUI: false,
  39. // 启用缩放和平移
  40. gestureHandling: 'greedy',
  41. panControl: true,
  42. zoomControl: true,
  43. scaleControl: true,
  44. //关闭街景
  45. streetViewControl: false,
  46. }
  47. },
  48. },
  49. //谷歌地图中心点
  50. googleMapCenter: {
  51. type: Object,
  52. default: () => {
  53. return {
  54. lat: 56.13036636210688,
  55. lng: -106.34677112102509,
  56. }
  57. },
  58. },
  59. //谷歌地图缩放级别
  60. zoom: {
  61. type: Number,
  62. default() {
  63. return 11
  64. },
  65. },
  66. //谷歌地图图形path
  67. mapPath: {
  68. type: String,
  69. default: () => {
  70. return ''
  71. },
  72. },
  73. },
  74. }
  75. </script>

逻辑层:

  1. data() {
  2. return {
  3. //地图选点回显值
  4. longlat: this.googleMapCenter.lng + ',' + this.googleMapCenter.lat,
  5. //标记点
  6. marker: [],
  7. //图形实例
  8. graphicalExample: null,
  9. //图形路径经纬度
  10. graphicalPath: [],
  11. apiKey: '你的谷歌地图key'
  12. }
  13. },
  14. created() {
  15. this.$nextTick(() => {
  16. const loader = new Loader({
  17. apiKey: this.apiKey, //之前的key
  18. version: 'weekly', //版本
  19. libraries: ['places', 'drawing'], //插件库places为基础库 drawing为绘制工具库
  20. region: 'Canada',
  21. language: 'en',
  22. })
  23. const mapOptions = {
  24. center: { lat: this.googleMapCenter.lat * 1, lng: this.googleMapCenter.lng * 1 }, //中心点
  25. zoom: this.zoom, //缩放级别
  26. ...this.mapOptions, //其他配置
  27. }
  28. loader
  29. .load()
  30. .then((google) => {
  31. const map = new google.maps.Map(document.getElementById(this.mapID), mapOptions)
  32. this.googleMap = map
  33. this.googleApi = google
  34. console.log(this.googleMap, '谷歌地图实例')
  35. console.log(this.googleApi, '谷歌地图api')
  36. })
  37. .catch((e) => {
  38. // do something
  39. console.log(e)
  40. })
  41. })
  42. }

那么接下来可以试着运行吧!!!

运行如果报这个错,那么就是你的key账号控制台没有开通服务(如下图)

第三步:

开始集成绘制工具

  1. created() {
  2. this.$nextTick(() => {
  3. const loader = new Loader({
  4. apiKey: this.apiKey, //之前的key
  5. version: 'weekly', //版本
  6. libraries: ['places', 'drawing'], //插件库
  7. region: 'Canada',
  8. language: 'en',
  9. })
  10. const mapOptions = {
  11. center: { lat: this.googleMapCenter.lat * 1, lng: this.googleMapCenter.lng * 1 }, //中心点
  12. zoom: this.zoom, //缩放级别
  13. ...this.mapOptions, //其他配置
  14. }
  15. loader
  16. .load()
  17. .then((google) => {
  18. const map = new google.maps.Map(document.getElementById(this.mapID), mapOptions)
  19. this.googleMap = map
  20. this.googleApi = google
  21. console.log(this.googleMap, '谷歌地图实例')
  22. console.log(this.googleApi, '谷歌地图api')
  23. // console.log(this.mapPath, '地图图形经纬度')
  24. if (this.mapType == 'POLYGON') {
  25. //如果是绘制图形类型则开始实例化绘制工具库
  26. let drawingModesList = {
  27. MARKER: this.googleApi.maps.drawing.OverlayType.MARKER,//标记点
  28. CIRCLE: this.googleApi.maps.drawing.OverlayType.CIRCLE,//圆形
  29. POLYGON: this.googleApi.maps.drawing.OverlayType.POLYGON,//多边形
  30. POLYLINE: this.googleApi.maps.drawing.OverlayType.POLYLINE,//折线
  31. RECTANGLE: this.googleApi.maps.drawing.OverlayType.RECTANGLE,//矩形
  32. }
  33. const drawingManager = new this.googleApi.maps.drawing.DrawingManager({
  34. drawingControl: true,
  35. drawingControlOptions: {
  36. position: this.googleApi.maps.ControlPosition.TOP_CENTER,
  37. drawingModes: [drawingModesList[this.mapType]],//这是个数组,因为我只需要多边形的就只传了一个
  38. },
  39. polygonOptions: {
  40. fillColor: 'blue',
  41. strokeColor: 'blue',
  42. strokeOpacity: 0.8,
  43. fillOpacity: 0.4,
  44. strokeWeight: 5,
  45. clickable: false,
  46. editable: true,
  47. zIndex: 1,
  48. },
  49. })
  50. drawingManager.setMap(map)
  51. })
  52. }
  53. })
  54. .catch((e) => {
  55. // do something
  56. console.log(e)
  57. })
  58. })
  59. },

效果图如下:

 第四步(end):

获取多边形图形路径数据和回显图形以及地图搜索选点功能(核心代码)

  1. created() {
  2. this.$nextTick(() => {
  3. const loader = new Loader({
  4. apiKey: this.apiKey, //之前的key
  5. version: 'weekly', //版本
  6. libraries: ['places', 'drawing'], //插件库
  7. region: 'Canada',
  8. language: 'en',
  9. })
  10. const mapOptions = {
  11. center: { lat: this.googleMapCenter.lat * 1, lng: this.googleMapCenter.lng * 1 }, //中心点
  12. zoom: this.zoom, //缩放级别
  13. ...this.mapOptions, //其他配置
  14. }
  15. loader
  16. .load()
  17. .then((google) => {
  18. const map = new google.maps.Map(document.getElementById(this.mapID), mapOptions)
  19. this.googleMap = map
  20. this.googleApi = google
  21. console.log(this.googleMap, '谷歌地图实例')
  22. console.log(this.googleApi, '谷歌地图api')
  23. // console.log(this.mapPath, '地图图形经纬度')
  24. if (this.mapType == 'selectPoint') {
  25. this.selectPoint()
  26. this.addDraggableMarkers(1, true, this.googleMapCenter)
  27. }
  28. if (this.mapType == 'POLYGON') {
  29. this.addDraggableMarkers(1, false, this.googleMapCenter)
  30. //如果是绘制图形类型则开始实例化绘制工具库
  31. let drawingModesList = {
  32. MARKER: this.googleApi.maps.drawing.OverlayType.MARKER,
  33. CIRCLE: this.googleApi.maps.drawing.OverlayType.CIRCLE,
  34. POLYGON: this.googleApi.maps.drawing.OverlayType.POLYGON,
  35. POLYLINE: this.googleApi.maps.drawing.OverlayType.POLYLINE,
  36. RECTANGLE: this.googleApi.maps.drawing.OverlayType.RECTANGLE,
  37. }
  38. const drawingManager = new this.googleApi.maps.drawing.DrawingManager({
  39. drawingControl: true,
  40. drawingControlOptions: {
  41. position: this.googleApi.maps.ControlPosition.TOP_CENTER,
  42. drawingModes: [drawingModesList[this.mapType]],
  43. },
  44. polygonOptions: {
  45. fillColor: 'blue',
  46. strokeColor: 'blue',
  47. strokeOpacity: 0.8,
  48. fillOpacity: 0.4,
  49. strokeWeight: 5,
  50. clickable: false,
  51. editable: true,
  52. zIndex: 1,
  53. },
  54. })
  55. drawingManager.setMap(map)
  56. //监听绘制多边形完成事件事件
  57. this.googleApi.maps.event.addListener(drawingManager, 'polygoncomplete', (e) => {
  58. //存在就清除上一个图形
  59. if (this.graphicalExample) {
  60. this.graphicalExample.setMap(null)
  61. }
  62. //path路径emit传出
  63. this.setPath(e.getPath().Ld)
  64. this.graphicalExample = e
  65. //监听回显图形每一个路径点
  66. this.googleApi.maps.event.addListener(e.getPath(), 'insert_at', (event) => {
  67. //path路径emit传出
  68. this.setPath(e.getPath().Ld)
  69. })
  70. this.googleApi.maps.event.addListener(e.getPath(), 'set_at', (event) => {
  71. this.setPath(e.getPath().Ld)
  72. })
  73. //绘制完成后关闭绘制状态
  74. drawingManager.setDrawingMode(null)
  75. })
  76. //回显图形
  77. if (JSON.parse(this.mapPath).length > 0) {
  78. this.echoGraphical()
  79. }
  80. }
  81. })
  82. .catch((e) => {
  83. // do something
  84. console.log(e)
  85. })
  86. })
  87. },
  88. methods: {
  89. //回显图形
  90. echoGraphical() {
  91. if (this.mapType == 'POLYGON') {
  92. //回显多边形
  93. this.graphicalPath = this.mapPath
  94. let paths = JSON.parse(this.graphicalPath)
  95. // Construct a draggable red triangle with geodesic set to true.
  96. this.graphicalExample = new this.googleApi.maps.Polygon({
  97. paths,
  98. fillColor: 'blue',
  99. strokeColor: 'blue',
  100. strokeOpacity: 0.8,
  101. fillOpacity: 0.4,
  102. strokeWeight: 5,
  103. clickable: true,
  104. editable: true,
  105. zIndex: 1,
  106. })
  107. this.graphicalExample.setMap(this.googleMap)
  108. //监听回显图形每一个路径点
  109. this.googleApi.maps.event.addListener(this.graphicalExample.getPath(), 'insert_at', (event) => {
  110. this.setPath(this.graphicalExample.getPath().Ld)
  111. })
  112. this.googleApi.maps.event.addListener(this.graphicalExample.getPath(), 'set_at', (event) => {
  113. this.setPath(this.graphicalExample.getPath().Ld)
  114. })
  115. }
  116. },
  117. //path路径emit传出
  118. setPath(path) {
  119. this.graphicalPath = []
  120. if (path.length > 0) {
  121. path.forEach((v) => {
  122. this.graphicalPath.push({ lat: v.lat(), lng: v.lng() })
  123. })
  124. this.$emit('getGraphicalPath', this.graphicalPath)
  125. }
  126. },
  127. //搜索地点方法
  128. selectPoint() {
  129. const input = document.getElementById('pac-input')
  130. const searchBox = new this.googleApi.maps.places.SearchBox(input)
  131. const infoWindow = new this.googleApi.maps.InfoWindow()
  132. this.googleMap.controls[this.googleApi.maps.ControlPosition.TOP_LEFT].push(input)
  133. this.googleMap.addListener('click', (e) => {
  134. this.clickGmap(e)
  135. })
  136. this.googleMap.addListener('bounds_changed', () => {
  137. searchBox.setBounds(this.googleMap.getBounds())
  138. let markers = []
  139. searchBox.addListener('places_changed', () => {
  140. const places = searchBox.getPlaces()
  141. if (places.length == 0) {
  142. return
  143. }
  144. // Clear out the old markers.
  145. markers.forEach((marker) => {
  146. marker.setMap(null)
  147. })
  148. markers = []
  149. // For each place, get the icon, name and location.
  150. const bounds = new this.googleApi.maps.LatLngBounds()
  151. places.forEach((place) => {
  152. if (!place.geometry || !place.geometry.location) {
  153. console.log('Returned place contains no geometry')
  154. return
  155. }
  156. const icon = {
  157. url: place.icon,
  158. size: new this.googleApi.maps.Size(71, 71),
  159. origin: new this.googleApi.maps.Point(0, 0),
  160. anchor: new this.googleApi.maps.Point(17, 34),
  161. scaledSize: new this.googleApi.maps.Size(25, 25),
  162. }
  163. // Create a marker for each place.
  164. markers.push(
  165. new this.googleApi.maps.Marker({
  166. map: this.googleMap,
  167. icon,
  168. title: place.name,
  169. position: place.geometry.location,
  170. draggable: false,
  171. })
  172. )
  173. if (place.geometry.viewport) {
  174. // Only geocodes have viewport.
  175. bounds.union(place.geometry.viewport)
  176. } else {
  177. bounds.extend(place.geometry.location)
  178. }
  179. })
  180. this.googleMap.fitBounds(bounds)
  181. })
  182. })
  183. },
  184. //点击地图回调
  185. clickGmap(e) {
  186. this.longlat = e.latLng.lat() + ',' + e.latLng.lng()
  187. this.$emit('setLongLat', this.longlat)
  188. this.addDraggableMarkers(1, true, { lat: e.latLng.lat(), lng: e.latLng.lng() })
  189. },
  190. //移动标记点回调
  191. updateMaker(e) {
  192. this.longlat = e.latLng.lat() + ',' + e.latLng.lng()
  193. this.$emit('setLongLat', this.longlat)
  194. },
  195. //添加可拖动的标记点
  196. addDraggableMarkers(max, draggable, { lat = 0, lng = 0 }) {
  197. if (max != -1) {
  198. this.marker.forEach((marker) => {
  199. marker.setMap(null)
  200. })
  201. this.marker = []
  202. }
  203. this.marker.push(
  204. new this.googleApi.maps.Marker({
  205. map: this.googleMap,
  206. position: { lat: lat, lng: lng },
  207. draggable: draggable,
  208. })
  209. )
  210. if (draggable) {
  211. this.marker[0].addListener('dragend', (e) => {
  212. this.updateMaker(e)
  213. })
  214. }
  215. },
  216. //获取经纬度
  217. getLongLat() {
  218. return this.longlat
  219. },
  220. //设置地图中心点位置
  221. setMapPanBy(e) {
  222. let latlng = new this.googleApi.maps.LatLng(e.lat,e.lng)
  223. this.googleMap.setCenter(latlng)
  224. this.marker[0].setPosition(latlng);
  225. },
  226. }

 绘制多边形效果图:

 地图选点效果(点击地图或者拖动标记点获取经纬度,自带模糊搜索功能):

 补充:如果需要用到绘制图形得知图形内有几个标记点的功能,请看我的另一篇文章,链接是:vue谷歌地图用api获取绘制的图形范围内的标记点

 另一篇的效果图:

至此结束,感谢大家支持!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/215848
推荐阅读
相关标签
  

闽ICP备14008679号