vue/uniapp 使用高德地图定位(地理逆编码)+ 定位当前城市/搜索功能/点标记/事件/窗体

3,524 阅读2分钟

第一次接触高德,真的是头大,熬了小一个通宵,学了点皮毛,记录下来,方便后面使用(纯原生高德,没有使用vue-amap)

参考 高德api官网

效果图:

F8D%)~QLMHOM}J0KLU0M3JW.png

下面几种不同的引进方法共有的大概就是:注册账号,添加key,然后是这三步:

第一步. 如果是移动端开发,请在head标签内添加如下代码:

<meta name="viewport" content="initial-scale=1.0, user-scalable=no">

第二步. 添加div标签作为地图容器,同时为该div指定id属性:

<div id="container"></div>

第二点要注意一定是id选择器,哪怕在uniapp项目上也要用id选择器

第三步. 通过css 为地图容器指定高度、宽度:

#container {width:300px; height: 180px; }

前面的步骤分别连接下面的步骤,下面是我使用不同的引入方式用在不同方式创建的项目上:

  • 第一种引入方式(用在了HbuilderX 创建的项目上):

第四步: 官网中JSAPI 的加载 是按 NPM 方式使用 Loader :下载 npm i @amap/amap-jsapi-loader --save 然后再使用的地方引入。

注意: 必须要写密钥且必须写在要引入的地方,否则 高德地图 geocoder.getAddress逆地理编码执行失败

<script>
	// 注意1.  必须要写密钥且必须写在要引入的地方,否则 高德地图 geocoder.getAddress逆地理编码执行失败
	window._AMapSecurityConfig = {
	    securityJsCode:'密钥',
	}
	import AMapLoader from '@amap/amap-jsapi-loader';
	export default {
		data() {
			return {
				mylon:'',
				mylat:'',
				title:'上班打卡',
				time:0,
				currentAddress:'浙江省嘉兴市海盐县',
			}
		},
		onShow() {
			//获得当前定位
			this.getaddress();
		},
		methods: {
			
			// 获得当前定位
			getaddress() {
                   var that=this
			   uni.getLocation({
                      type: 'wgs84',
				geocode:true,//设置该参数为true可直接获取经纬度及城市信息
			   	success: function (res) {
			   		console.log('当前位置的经度:' + res.longitude);
			   		console.log('当前位置的纬度:' + res.latitude);
					
					AMapLoader.load({
					    key:"我的key",             // 申请好的Web端开发者Key,首次调用 load 时必填
					    version:"2.0",      // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
					    plugins:['AMap.Geocoder','AMap.Geolocation',"AMap.CitySearch"],       // 需要使用的的插件列表,如比例尺'AMap.Scale'等
					}).then((AMap)=>{
					    this.map = new AMap.Map("container",{  //设置地图容器id
					        viewMode:"3D",    //是否为3D地图模式
					        zoom:10,           //初始化地图级别
					        center:[116.4,39.9], //初始化地图中心点位置
					    });
					    var geocoder = new AMap.Geocoder({
					      // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
					      city: '010'
					    })
					    var lnglat = [res.longitude,res.latitude]
						// 高德根据经纬度逆推地理位置信息
					   geocoder.getAddress(lnglat, function(status, result) {
					       if (status === 'complete' && result.info === 'OK') {
					           // result为对应的地理位置详细信息
							   console.log(result.regeocode.formattedAddress);
								that.currentAddress=result.regeocode.formattedAddress
						   }
					     })
						
						// 高德获取经纬度
						AMap.plugin('AMap.Geolocation', function() {
						  var geolocation = new AMap.Geolocation({
						    // 是否使用高精度定位,默认:true
						    enableHighAccuracy: true,
						    // 设置定位超时时间,默认:无穷大
						    timeout: 10000,
						    // 定位按钮的停靠位置的偏移量
						    offset: [10, 20],
						    //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
						    zoomToAccuracy: true,     
						    //  定位按钮的排放位置,  RB表示右下
						    position: 'RB'
						  })
						
						  geolocation.getCurrentPosition(function(status,result){
						        if(status=='complete'){
						            console.log(result);
						        }else{
						            console.log(result);
						        }
						  });
						
						  function onComplete (data) {
						    // data是具体的定位信息
							console.log(data);
						  }
						
						  function onError (data) {
						    // 定位出错
						  }
						})
                                                
                                                
						// 高德获取大致位置
						AMap.plugin('AMap.CitySearch', function () {
						  var citySearch = new AMap.CitySearch()
						  citySearch.getLocalCity(function (status, result) {
						    if (status === 'complete' && result.info === 'OK') {
						      // 查询成功,result即为当前所在城市信息
							  console.log(result);
						    }
						  })
						})
					}).catch(e=>{
					    console.log(e);
					})
			   	},
			   });  
			},
			
		},
		
	}
</script>
  • 第二种引入方式(使用在 脚手架创建的uniapp项目上):

注意: 地图加载的时候dom结构还没生成,把渲染地图的 getlan 函数放到 mounted 生命周期中加载

第四步: 在public/index.html 中head标签中 script 标签之前 添加:

<script type="text/javascript">
            window._AMapSecurityConfig = {
                securityJsCode:'密钥',
            }
    </script>
    //同步预加载要使用的多个插件(看官网插件的使用)
<script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=您申请的key值&plugin=AMap.ToolBar,AMap.Driving"></script>

在需要使用的页面:

<script>
export default {
	data() {
		return {
			title: "Hello",
		};
	},
	mounted() {
		// 地图加载的时候dom结构还没生成,把getlan函数放到mounted生命周期中加载
		this.getlan();
	},
	methods: {
		getlan() {
			var map = new AMap.Map("container", {
				//设置地图容器id
				viewMode: "3D", //是否为3D地图模式
				zoom: 10, //初始化地图级别
				center: [116.4, 39.9], //初始化地图中心点位置
			});
			uni.getLocation({
				type: "gcj02",
				geocode: true, //设置该参数为true可直接获取经纬度及城市信息
				success: function(res) {
					console.log("当前位置的经度:" + res.longitude);
					console.log("当前位置的纬度:" + res.latitude);

					var geocoder = new AMap.Geocoder({
						// city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
						city: "010",
					});
					var lnglat = [res.longitude, res.latitude];
					// 高德根据经纬度逆推地理位置信息
					geocoder.getAddress(lnglat, function(status, result) {
						if (status === "complete" && result.info === "OK") {
							// result为对应的地理位置详细信息
							console.log(result.regeocode.formattedAddress);
						}
					});
				},
			});
			// 高德获取经纬度
			AMap.plugin("AMap.Geolocation", function() {
				var geolocation = new AMap.Geolocation({
					// 是否使用高精度定位,默认:true
					enableHighAccuracy: true,
					// 设置定位超时时间,默认:无穷大
					timeout: 10000,
					// 定位按钮的停靠位置的偏移量
					offset: [10, 20],
					//  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
					zoomToAccuracy: true,
					//  定位按钮的排放位置,  RB表示右下
					position: "RB",
				});

				geolocation.getCurrentPosition(function(status, result) {
					if (status == "complete") {
						console.log(result);
					} else {
						console.log(result);
					}
				});

				function onComplete(data) {
					// data是具体的定位信息
					console.log(data);
				}

				function onError(data) {
					// 定位出错
				}
			});
		},
	},
};
</script>
  • 第三种引入方式(vue2.0项目上):

注意: loader.js在两个地方都要引入,否则报错

第四步: 官网中JSAPI 的加载 是按普通 JS 方式使用 Loader ;在public/index.html 中head标签中 script 标签之前 添加:

    <!-- 引入高德的文件后记得重启项目 -->
 <script type="text/javascript">
            window._AMapSecurityConfig = {
                securityJsCode:'密钥',
            }
   </script>
 <script src="https://webapi.amap.com/loader.js"></script>

在需要使用的页面:

// 注意使用的地方也引入了loader.js
<script src="https://webapi.amap.com/loader.js"></script>
<script>
//loader.js 文件哪里使用放哪里
export default {
	mounted() {
		this.getlan();
	},
	methods: {
		getlan() {
			AMapLoader.load({
				key: "我的key", // 申请好的Web端开发者Key,首次调用 load 时必填
				version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
				plugins: ["AMap.Geolocation", "AMap.Scale", "AMap.Geocoder"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
				AMapUI: {
					// 是否加载 AMapUI,缺省不加载
					version: "1.1", // AMapUI 版本
					plugins: ["overlay/SimpleMarker"], // 需要加载的 AMapUI ui插件
				},
				Loca: {
					// 是否加载 Loca, 缺省不加载
					version: "2.0", // Loca 版本
				},
			})
				.then((AMap) => {
					var map = new AMap.Map("container");
					map.addControl(new AMap.Scale());

					AMap.plugin("AMap.Geolocation", function() {
						var geolocation = new AMap.Geolocation({
							// 是否使用高精度定位,默认:true
							enableHighAccuracy: true,
							// 设置定位超时时间,默认:无穷大
							timeout: 10000,
							// 定位按钮的停靠位置的偏移量
							offset: [10, 20],
							//  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
							zoomToAccuracy: true,
							//  定位按钮的排放位置,  RB表示右下
							position: "RB",
						});

						geolocation.getCurrentPosition(function(status, result) {
							if (status == "complete") {
								onComplete(result);
							} else {
								onError(result);
							}
						});

						function onComplete(data) {
							// data是具体的定位信息
							console.log(data);
						}

						function onError(data) {
							// 定位出错
						}
					});
				})
				.catch((e) => {
					console.error(e); //加载错误提示
				});
		},
	},
};
</script>

补充内容:(第三种引入方式的延伸,更全面)

<script src="https://webapi.amap.com/loader.js"></script>
<script>
// 引进form表单rules规则校验
import { required, phone, len, email } from "../assets/FromRules";
export default {
  data() {
    return {
      imgddd: require("../assets/logo.png"), //地图标记图标
      ruleForm: {
        address: "", // 地图搜索  驿站地址
      },
      mylat: 0,
      mylng: 0,
      mymap: null, //地图实例
      // 地图标记点数组
      lnglats: [
        { lng: 104.350264, lat: 30.634319 },
        { lng: 104.064619, lat: 30.681572 },
        { lng: 103.91905, lat: 30.572854 },
      ],
      //   窗体
      infoWindow: null,
    };
  },
  mounted() {
    this.getlan();
  },
  methods: {
    
    // 地图
    getlan() {
      let that = this;
      AMapLoader.load({
        key: "我的key", // 申请好的Web端开发者Key,首次调用 load 时必填
        version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
        plugins: [
          "AMap.Geolocation",
          "AMap.Scale",
          "AMap.Geocoder",
          "AMap.PlaceSearch",
        ], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        AMapUI: {
          // 是否加载 AMapUI,缺省不加载
          version: "1.1", // AMapUI 版本
          plugins: ["overlay/SimpleMarker"], // 需要加载的 AMapUI ui插件
        },
        Loca: {
          // 是否加载 Loca, 缺省不加载
          version: "2.0", // Loca 版本
        },
      })
        .then((AMap) => {
          // 创建AMap.Map对象时如果没有传入center参数,您会发现地图将自动定位到您所在城市并显示
          that.mymap = new AMap.Map("container", {
            zoom: 9,
          });

          // 注册 地图点击事件
          var clickHandler = function (e) {
            console.log(
              "您在[ " +
                e.lnglat.getLng() +
                "," +
                e.lnglat.getLat() +
                " ]的位置点击了地图!"
            );
          };
          // 绑定地图点击事件
          that.mymap.on("click", clickHandler);

          that.mymap.addControl(new AMap.Scale());
          AMap.plugin("AMap.Geolocation", function () {
            var geolocation = new AMap.Geolocation({
              // 是否使用高精度定位,默认:true
              enableHighAccuracy: true,
              // 设置定位超时时间,默认:无穷大
              timeout: 10000,
              // 定位按钮的停靠位置的偏移量
              offset: [10, 20],
              //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
              zoomToAccuracy: true,
              //  定位按钮的排放位置,  RB表示右下
              position: "RB",
              buttonOffset: new AMap.Pixel(10, 20),
              showMarker: true, //定位成功后在定位到的位置显示点标记,默认:true
              showCircle: true, //定位成功后用圆圈表示定位精度范围,默认:true
              panToLocation: true, //定位成功后将定位到的位置作为地图中心点,默认:true
            });

            geolocation.getCurrentPosition(function (status, result) {
              if (status == "complete") {
                onComplete(result);
              } else {
                onError(result);
              }
            });
            function onComplete(data) {
              // data是具体的定位信息
              console.log(data.position.lat);
              console.log(data.position.lng);
              that.mylat = data.position.lat;
              that.mylng = data.position.lng;
              that.getocation(that.mylng, that.mylat);
            }
            function onError(data) {
              // 定位出错
              console.log(data);
            }
          });

          //  法1. 标记点
          // var marker = new AMap.Marker({
          //     position: new AMap.LngLat(104.066067, 30.572919),   // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
          //     icon: '//vdata.amap.com/icons/b18/1/2.png',//可以使用自己的图标
          //     title: '成都市人民政府'
          // });
          //  将创建的点标记添加到已有的地图实例:
          // that.mymap.add(marker);

          // 法2.标记点 并创建自己的图标
          var icon = new AMap.Icon({
            size: new AMap.Size(20, 20), // 图标尺寸,不要太大,否则层级遮挡其他点位
            image: that.imgddd, // Icon的图像 可以使用自己的图标
            // imageOffset: new AMap.Pixel(0, -60),  // 图像相对展示区域的偏移量,适于雪碧图等
            imageSize: new AMap.Size(20, 20), // 根据所设置的大小拉伸或压缩图片
          });

          // 将 Icon 实例添加到 marker 上:
          var marker = new AMap.Marker({
            position: new AMap.LngLat(104.066067, 30.572919),
            offset: new AMap.Pixel(-10, -10),
            icon: icon, // 添加 Icon 实例
            title: "成都市人民政府",
            zoom: 13,
          });
          //  将创建的点标记添加到已有的地图实例:
          that.mymap.add(marker);

          //给标记点 添加点击事件(添加事件用 on )  放大地图
          let a = 10;
          marker.on("click", markerClick);
          function markerClick(e) {
            console.log(e);
            //放大地图
            // 第一个参数14  (a) 是地图显示的缩放级别 第二个参数是高德的自带的函数getPosition,拿到当前标记点的经纬度
            if (a > 19) {
              a = 10;
            }
            a += 1;
            that.mymap.setZoomAndCenter(a, e.target.getPosition());
          }

          // 法3  遍历生成多个标记点
          setTimeout(() => {
            for (let i = 0; i < that.lnglats.length; i++) {
              var marker_2 = new AMap.Marker({
                position: new AMap.LngLat(
                  that.lnglats[i].lng,
                  that.lnglats[i].lat
                ),
                offset: new AMap.Pixel(-10, -10),
                icon: icon, // 添加 Icon 实例
                title: "成都市", //鼠标移入显示的内容
                zoom: 13,
              });

              //   给循环的标记点添加点击事件
              marker_2.on("click", that.marker_2_Click);
              //  将创建的点标记添加到已有的地图实例:
              that.mymap.add(marker_2);
            }
          }, 1000);

          //实例化信息窗体
          that.infoWindow = new AMap.InfoWindow({
            isCustom: true, //使用自定义窗体
            content: self.winInfo,
            offset: new AMap.Pixel(15, -35),
          });
        })
        .catch((e) => {
          console.error(e); //加载错误提示
        });
    },
    // 获取当前具体位置信息
    getocation(a, b) {
      // 地图编码
      AMap.plugin("AMap.Geocoder", function () {
        var geocoder = new AMap.Geocoder({
          // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
          city: "010",
        });

        var lnglat = [a, b];
        console.log(111);
        geocoder.getAddress(lnglat, function (status, result) {
          console.log(1111);
          if (status === "complete" && result.info === "OK") {
            // result为对应的地理位置详细信息
            console.log(result.regeocode.formattedAddress);
          }
        });
      });
    },
    //搜索
    seachAddress() {
      console.log(this.mymap);
      let that = this;
      if (this.ruleForm.address != "") {
        //清除地图上的覆盖物
        that.mymap.clearMap();
        // console.log("搜索");
        that.mymap.plugin("AMap.PlaceSearch", () => {
          let placeSearch = new AMap.PlaceSearch({
            // city 指定搜索所在城市,支持传入格式有:城市名、citycode和adcode
            city: "0797",
            map: that.mymap,
          });

          placeSearch.search(this.ruleForm.address, function (status, result) {
            // 查询成功时,result即对应匹配的POI信息
            console.log(result);
            var pois = result.poiList.pois;
            for (var i = 0; i < pois.length; i++) {
              var poi = pois[i];
              var marker = [];
              marker[i] = new AMap.Marker({
                position: poi.location, // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
                title: poi.name,
              });
              // 将创建的点标记添加到已有的地图实例:
              // that.mymap.add(marker[i]);
            }
            // 地图自适应
            that.mymap.setFitView();
          });
        });
      }
    },
    // 循环标记点 点击事件
    marker_2_Click(e) {
      console.log(e.target);
      if (this.infoWindow) {
        this.infoWindow.close(); // 关闭提示
      }
      let markerTipContent = `<div id='#btn'>自定义内容</div>`; // 自定义窗体内容
      this.infoWindow = new AMap.InfoWindow({
        // 提示插件
        // position: new AMap.LngLat(104.066067, 30.572919), // 经纬度
        content: markerTipContent,
        offset: new AMap.Pixel(2, -6), // 便宜位置
      });
      //打开窗体
      this.infoWindow.open(this.mymap, e.target.getPosition());
    },
  },
};
</script>

<style lang='scss' scoped>
@import "../mystyle/AddPost";

// 清除左下角的高德地图的logo
::v-deep .amap-logo {
  display: none;
  opacity: 0 !important;  //去掉高德地图logo
}
::v-deep .amap-copyright {
  opacity: 0; //去掉高德的版本号
}
::v-deep .amap-control  {
  opacity: 0; //去掉比例尺控件
}
</style>

最后一点:引入高德的文件后记得重启项目 , uni.getlocation  无法拿到位置信息,方法根本就没反应或者没执行,高德地图AMap.Geolocation拿不到位置信息 的问题用 edge 浏览器即可解决

欢迎大家批评指正