|
|
@@ -0,0 +1,256 @@
|
|
|
+<template>
|
|
|
+ <div class="map-wrapper">
|
|
|
+ <el-amap
|
|
|
+ ref="map"
|
|
|
+ :center="mapCenter"
|
|
|
+ :zoom="zoom"
|
|
|
+ class="map-view"
|
|
|
+ :events="mapEvents"
|
|
|
+ :expandZoomRange="true"
|
|
|
+ >
|
|
|
+ <el-amap-marker
|
|
|
+ v-if="myPosition"
|
|
|
+ :position="myPosition"
|
|
|
+ content="<div class='my-position'><div>"
|
|
|
+ cursor="default"
|
|
|
+ >
|
|
|
+ </el-amap-marker>
|
|
|
+ <el-amap-marker
|
|
|
+ v-if="marker"
|
|
|
+ :position="marker"
|
|
|
+ :draggable="true"
|
|
|
+ :events="markerEvents"
|
|
|
+ cursor="default"
|
|
|
+ >
|
|
|
+ </el-amap-marker>
|
|
|
+ </el-amap>
|
|
|
+ <el-amap-search-box
|
|
|
+ class="search-box"
|
|
|
+ :search-option="searchOption"
|
|
|
+ :on-search-result="onSearchResult"
|
|
|
+ >
|
|
|
+ </el-amap-search-box>
|
|
|
+ <div class="btn-locate" @click="locate">
|
|
|
+ <i
|
|
|
+ :class="{
|
|
|
+ 'el-icon-loading': locating,
|
|
|
+ 'el-icon-location-outline': !locating
|
|
|
+ }"
|
|
|
+ ></i>
|
|
|
+ </div>
|
|
|
+ <div class="btn-minus" @click="setZoom(-1)">
|
|
|
+ <i class="el-icon-minus"></i>
|
|
|
+ </div>
|
|
|
+ <div class="btn-plus" @click="setZoom(1)">
|
|
|
+ <i class="el-icon-plus"></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+ export default {
|
|
|
+ props: {
|
|
|
+ searchOption: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {
|
|
|
+ city: "全国",
|
|
|
+ citylimit: false
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ center: {
|
|
|
+ type: Array
|
|
|
+ },
|
|
|
+ zoom: {
|
|
|
+ type: Number,
|
|
|
+ default: 15
|
|
|
+ },
|
|
|
+ value: {
|
|
|
+ type: Array
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ let self = this;
|
|
|
+ return {
|
|
|
+ locating: false,
|
|
|
+ myPosition: null,
|
|
|
+ marker: null,
|
|
|
+ mapEvents: {
|
|
|
+ complete() {
|
|
|
+ self.$refs.map.$$getInstance().setDefaultCursor("default");
|
|
|
+ },
|
|
|
+ click(e) {
|
|
|
+ self.marker = [e.lnglat.O, e.lnglat.P];
|
|
|
+ self.mapCenter = [e.lnglat.O, e.lnglat.P];
|
|
|
+ self.getGeolocation();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ markerEvents: {
|
|
|
+ dragend(e) {
|
|
|
+ self.marker = [e.lnglat.O, e.lnglat.P];
|
|
|
+ self.mapCenter = [e.lnglat.O, e.lnglat.P];
|
|
|
+ self.getGeolocation();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mapCenter: [121.480342, 31.236339]
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ if (this.center) {
|
|
|
+ this.mapCenter = this.center;
|
|
|
+ }
|
|
|
+ if (this.value) {
|
|
|
+ this.mapCenter = this.value;
|
|
|
+ this.marker = this.value;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ locate() {
|
|
|
+ this.locating = true;
|
|
|
+ let geolocation = new AMap.Geolocation({
|
|
|
+ enableHighAccuracy: true,
|
|
|
+ timeout: 10000
|
|
|
+ });
|
|
|
+ geolocation.getCurrentPosition();
|
|
|
+ AMap.event.addListener(geolocation, "complete", data => {
|
|
|
+ this.locating = false;
|
|
|
+ this.mapCenter = [data.position.O, data.position.P];
|
|
|
+ this.myPosition = [data.position.O, data.position.P];
|
|
|
+ });
|
|
|
+ AMap.event.addListener(geolocation, "error", err => {
|
|
|
+ this.locating = false;
|
|
|
+ console.log(err);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onSearchResult(pois) {
|
|
|
+ let latSum = 0;
|
|
|
+ let lngSum = 0;
|
|
|
+ if (pois.length > 0) {
|
|
|
+ pois.forEach(poi => {
|
|
|
+ let { lng, lat } = poi;
|
|
|
+ lngSum += lng;
|
|
|
+ latSum += lat;
|
|
|
+ });
|
|
|
+ let center = {
|
|
|
+ lng: lngSum / pois.length,
|
|
|
+ lat: latSum / pois.length
|
|
|
+ };
|
|
|
+ this.mapCenter = [center.lng, center.lat];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setZoom(d) {
|
|
|
+ this.$refs.map
|
|
|
+ .$$getInstance()
|
|
|
+ .setZoom(this.$refs.map.$$getInstance().getZoom() + d);
|
|
|
+ },
|
|
|
+ getGeolocation() {
|
|
|
+ let lnglat = this.marker;
|
|
|
+ AMap.plugin("AMap.Geocoder", () => {
|
|
|
+ let geocoder = new AMap.Geocoder();
|
|
|
+ geocoder.getAddress(lnglat, (status, result) => {
|
|
|
+ if (status === "complete" && result.info === "OK") {
|
|
|
+ this.$emit("selected", {
|
|
|
+ lnglat: {
|
|
|
+ lng: lnglat[0],
|
|
|
+ lat: lnglat[1]
|
|
|
+ },
|
|
|
+ ...result.regeocode
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ value(val) {
|
|
|
+ this.mapCenter = val;
|
|
|
+ this.marker = val;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+<style lang="less" scoped>
|
|
|
+ .map-wrapper {
|
|
|
+ position: relative;
|
|
|
+ .map-view {
|
|
|
+ width: 100%;
|
|
|
+ height: 400px;
|
|
|
+ }
|
|
|
+ .btn-locate {
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #666;
|
|
|
+ position: absolute;
|
|
|
+ left: 10px;
|
|
|
+ bottom: 10px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 2px;
|
|
|
+ box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
|
|
|
+ &:active {
|
|
|
+ background: #f2f3f4;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .btn-minus {
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ font-size: 16px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ color: #666;
|
|
|
+ position: absolute;
|
|
|
+ left: 10px;
|
|
|
+ bottom: 50px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 2px;
|
|
|
+ box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
|
|
|
+ &:active {
|
|
|
+ background: #f2f3f4;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .btn-plus {
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #666;
|
|
|
+ position: absolute;
|
|
|
+ left: 10px;
|
|
|
+ bottom: 90px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 2px;
|
|
|
+ box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
|
|
|
+ &:active {
|
|
|
+ background: #f2f3f4;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .search-box {
|
|
|
+ position: absolute;
|
|
|
+ top: 10px;
|
|
|
+ left: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|
|
|
+<style lang="less">
|
|
|
+ .anchorBL,
|
|
|
+ .amap-logo,
|
|
|
+ .amap-copyright {
|
|
|
+ display: none !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .my-position {
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ border-radius: 50%;
|
|
|
+ border: 3px solid #fff;
|
|
|
+ background: #20a0ff;
|
|
|
+ box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+</style>
|