123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- <template>
- <div class="container">
- <div id="mapContainer" class="mapContainer" ref="mapContainer"></div>
- <div class="search-container" v-if="isPoiSearch">
- <div class="input-wrapper">
- <span class="search-label">搜索</span>
- <input id="searchText" type="text" class="search-text" placeholder="请输入搜索词"/>
- </div>
- </div>
- </div>
- </template>
- <script>
- /* eslint-disable */
- import {lazyAMapApiLoaderInstance} from "vue-amap";
- // import { setTimeout } from "timers";
- import {locationMixin} from "@/assets/js/mixin";
- export default {
- mixins: [locationMixin],
- data() {
- return {
- searchText: ""
- };
- },
- props: {
- // 经纬度坐标 [118.31, 37.27]
- position: {
- type: Array,
- default: () => []
- },
- // 圆形半径 (公里)
- radius: {
- type: Number,
- default: 0
- },
- // 缩放级别
- zoom: {
- type: Number,
- default: 16
- },
- // 模式:可选'normal'(显示商店定位)、'positionPicker'(商店位置拖拽选择)
- mode: {
- type: String,
- default: "normal"
- },
- // 是否根据选点搜索周边
- isPlaceSearch: {
- type: Boolean,
- default: false
- },
- // 搜索半径 (公里)
- searchRadius: {
- type: Number,
- default: 2
- },
- // 是否加载POI搜索
- isPoiSearch: {
- type: Boolean,
- default: false
- }
- },
- async mounted() {
- // 初始化加载地图
- console.time("map");
- await lazyAMapApiLoaderInstance.load();
- console.timeEnd("map");
- const option = {};
- if (this.position.length && this.position[0] && this.position[1]) {
- option.center = this.position;
- }
- if (this.zoom) {
- option.zoom = this.zoom;
- }
- option.scrollWheel = true;
- this.map = new AMap.Map(this.$refs.mapContainer, option);
- this.AMap = AMap;
- // 加载poi搜索组件
- if (this.isPoiSearch) {
- this._initPoiPicker(AMapUI);
- }
- if (this.mode === "positionPicker") {
- this._initPositionPicker(AMapUI);
- } else {
- // normal模式 只显示position位置或者设备当前定位位置
- if (!this.position.length) {
- // 未传location定位当前设备位置
- this.getCurrentPositon();
- } else {
- this.addMarker(this.position);
- if (this.radius > 0) {
- this.addCircle(this.position);
- }
- }
- }
- },
- methods: {
- addMarker(position, message) {
- const AMap = this.AMap;
- const map = this.map;
- // 先移除旧的点标记
- if (this.marker) {
- map.remove(this.marker);
- }
- // 创建一个 Marker 实例
- this.marker = new AMap.Marker({
- position: new AMap.LngLat(...position), // 经纬度构成的一维数组[116.39, 39.9]
- title: ""
- });
- // 将创建的点标记添加到已有的地图实例
- map.add(this.marker);
- // 处理InfoWindow
- if (message) {
- const infoWindow = new AMap.InfoWindow({
- position: position,
- offset: new AMap.Pixel(0, -20), // 纵向偏移
- showShadow: true, // 显示阴影
- content: message // 文字内容
- });
- infoWindow.open();
- }
- this.map.setCenter(this.marker.getPosition());
- },
- addCircle(position, radius) {
- const AMap = this.AMap;
- const map = this.map;
- this.circle = new AMap.Circle({
- center: new AMap.LngLat(...position), // 圆心位置
- radius: 1000 * radius, // 圆半径
- fillOpacity: 0.4,
- fillColor: "#1791fc",
- strokeWeight: 0
- });
- this.circle.setMap(map);
- // 缩放地图到合适的视野级别
- map.setFitView([this.circle]);
- // map.add(circleMarker);
- },
- // 初始化拖拽选择
- _initPositionPicker(AMapUI) {
- // 加载拖拽选择插件 positionPicker
- AMapUI.loadUI(["misc/PositionPicker"], PositionPicker => {
- var positionPicker = new PositionPicker({
- mode: "dragMap", // 设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'
- map: this.map // 依赖地图对象
- });
- positionPicker.on("success", positionResult => {
- // 抛出选取点信息
- this.$emit("selectLocation", positionResult);
- //
- if (this.isPlaceSearch) {
- this.searchPlace([
- positionResult.position.lng,
- positionResult.position.lat
- ]);
- }
- });
- positionPicker.on("fail", positionResult => {
- console.error(positionResult);
- });
- // 开始拖拽选择
- positionPicker.start();
- });
- },
- // 初始化poi搜索
- _initPoiPicker(AMapUI) {
- // 加载拖拽选择插件 PoiPicker
- AMapUI.loadUI(["misc/PoiPicker"], PoiPicker => {
- var poiPicker = new PoiPicker({
- input: "searchText" // 输入框id
- });
- // 监听poi选中信息
- poiPicker.on("poiPicked", poiResult => {
- // 用户选中的poi点信息
- const poi = poiResult.item;
- this.addMarker(
- [poi.location.lng, poi.location.lat],
- poi.name
- );
- });
- });
- },
- searchPlace([lng, lat]) {
- const placeSearch = new this.AMap.PlaceSearch({
- pageSize: 20, // 单页显示结果条数
- pageIndex: 1, // 页码
- city: this.city.adcode || "全国", // 兴趣点城市
- citylimit: true, // 是否强制限制在设置的城市内搜索
- extensions: "all"
- // map: this.map, // 展现结果的地图实例
- // autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
- });
- var cpoint = [lng, lat]; // 中心点坐标
- placeSearch.searchNearBy(
- "",
- cpoint,
- 1000 * this.searchRadius,
- (status, result) => {
- if (status === "complete") {
- this.$emit("searchPlace", result.poiList.pois);
- }
- }
- );
- },
- searchByText(text, center) {
- const placeSearch = new this.AMap.PlaceSearch({
- // type:
- // "商务住宅|政府机构及社会团体|科教文化服务|公共设施|交通设施服务", // 兴趣点类别
- pageSize: 20, // 单页显示结果条数
- pageIndex: 1, // 页码
- city: this.city.adcode || "全国", // 兴趣点城市
- citylimit: true, // 是否强制限制在设置的城市内搜索
- extensions: "all"
- // map: this.map, // 展现结果的地图实例
- // autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
- });
- let lng, lat;
- if (center && center.length > 0) {
- lng = center[0];
- lat = center[1];
- } else {
- lng = this.location[0];
- lat = this.location[1];
- }
- placeSearch.search(text, (status, result) => {
- if (status === "complete") {
- // console.log(result.poiList.pois);
- this.$emit("searchByText", result.poiList.pois);
- }
- });
- // if (lng && lat) {
- // var cpoint = [lng, lat]; // 中心点坐标
- // placeSearch.searchNearBy(
- // text,
- // cpoint,
- // 1000 * 50, // 搜索半价50公里 已经是最大值
- // (status, result) => {
- // console.log(result);
- // if (status === "complete") {
- // this.$emit("searchByText", result.poiList.pois);
- // }
- // }
- // );
- // } else {
- // this.$toast("请授权定位权限后搜索");
- // }
- }
- },
- watch: {
- radius(val) {
- if (this.circle) {
- this.circle.hide();
- }
- if (val > 0) {
- this.addCircle(this.position, this.radius);
- }
- },
- position(val) {
- if (val[0] && val[1] && this.map) {
- this.map.setCenter(val);
- this.addMarker(this.position);
- }
- }
- }
- };
- </script>
- <style lang="stylus" scoped>
- @import '~assets/main.styl';
- .container {
- position: relative;
- height: 100%;
- width: 100%;
- .mapContainer {
- position: relative;
- /* height 100vh */
- /* width 100vw */
- height: 100%;
- width: 100%;
- }
- .search-container {
- position: fixed;
- top: vw(20);
- left: vw(20);
- width: vw(250);
- background-color: grayF;
- padding: smallMargin smallMargin;
- border-radius: radius;
- min-width: vw(20);
- border-width: 0;
- box-shadow: 0 2px 6px 0 rgba(114, 124, 245, 0.5);
- .input-wrapper {
- display: flex;
- justify-content: center;
- .search-label {
- line-height: vw(15);
- flex: 0 0 vw(40);
- padding: titleMargin titleMargin;
- display: inline-block;
- font-size: word12;
- font-weight: bold;
- color: grayF;
- background-color: main-color;
- border: 1px solid main-color;
- text-align: center;
- }
- .search-text {
- flex: 0 1 vw(200);
- border: 1px solid main-color;
- padding: titleMargin titleMargin;
- font-size: word12;
- line-height: vw(15);
- }
- }
- }
- }
- </style>
|