|
@@ -0,0 +1,376 @@
|
|
|
+import { defineComponent, onMounted, ref, reactive, watch } from 'vue';
|
|
|
+import { useRoute, useRouter } from 'vue-router';
|
|
|
+import './index.scss';
|
|
|
+import Map from '@/components/MapView';
|
|
|
+import { ElButton } from 'element-plus';
|
|
|
+
|
|
|
+/** @ts-ignore */
|
|
|
+import icon_location_svg1 from "@/assets/images/location1.png";
|
|
|
+
|
|
|
+/** @ts-ignore */
|
|
|
+import icon_location from '@/assets/images/icon_map_location@2x.png';
|
|
|
+import { cloneDeep } from 'lodash';
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'MapSelect',
|
|
|
+ props: {
|
|
|
+ formv: {
|
|
|
+ type: Object,
|
|
|
+ default: { addr: '', locations: '' },
|
|
|
+ },
|
|
|
+ editable: {
|
|
|
+ type: String,
|
|
|
+ default:true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setup(props, ctx) {
|
|
|
+
|
|
|
+ const form = ref({ addr: '', locations: '' });
|
|
|
+ const route = useRoute();
|
|
|
+
|
|
|
+ const map = ref(null);
|
|
|
+ const state = reactive({
|
|
|
+ // map: map.value,
|
|
|
+ _marker: null ,
|
|
|
+ loading: false,
|
|
|
+ });
|
|
|
+ const mapselect = ref(false);
|
|
|
+
|
|
|
+ watch(
|
|
|
+ () => props.formv.locations,
|
|
|
+ () => {
|
|
|
+ form.value = props.formv;
|
|
|
+ setpoint(
|
|
|
+ Number(form.value.locations.split(',')[0]),
|
|
|
+ Number(form.value.locations.split(',')[1]),
|
|
|
+ form.value.addr);
|
|
|
+ },
|
|
|
+ );
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+
|
|
|
+ if (props.formv.locations) {
|
|
|
+ mapselect.value = false;
|
|
|
+ // form.value = cloneDeep(props.formv);
|
|
|
+ // console.log(form.value);
|
|
|
+ // setpoint(
|
|
|
+ // Number(form.value.locations.split(',')[0]),
|
|
|
+ // Number(form.value.locations.split(',')[1]),
|
|
|
+ // form.value.addr,
|
|
|
+ // );
|
|
|
+ } else {
|
|
|
+ mapselect.value = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ let allmark = [];
|
|
|
+
|
|
|
+ const selectpoint = () => {
|
|
|
+ if (mapselect.value) {
|
|
|
+ var center = window.map.getCenter();
|
|
|
+ getlocalname(center.lng.toFixed(6) + ',' + center.lat.toFixed(6));
|
|
|
+ } else {
|
|
|
+ mapselect.value = true;
|
|
|
+ state._marker?.remove();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const setpoint = (longitude, latitude, name) => {
|
|
|
+ if (state._marker) {
|
|
|
+ state._marker.remove();
|
|
|
+ }
|
|
|
+
|
|
|
+ // var el = document.createElement('div');
|
|
|
+ // el.id = 'marker';
|
|
|
+ // el.style.backgroundImage = `url(${icon_location})`;
|
|
|
+ // el.style.backgroundSize = 'cover';
|
|
|
+ // el.style.width = '24px';
|
|
|
+ // el.style.height = '24px';
|
|
|
+ // el.style.borderRadius = '50%';
|
|
|
+
|
|
|
+ var icon = new AMap.Icon({
|
|
|
+ size: new AMap.Size(40, 50), // 图标尺寸
|
|
|
+ image: '/icon_map_location@2x.png', // Icon的图像
|
|
|
+ imageSize: new AMap.Size(20, 20) // 根据所设置的大小拉伸或压缩图片
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ state._marker = new AMap.Marker({
|
|
|
+
|
|
|
+ position: new AMap.LngLat(longitude, latitude),
|
|
|
+ offset: new AMap.Pixel(-10, -10),
|
|
|
+ icon: icon,
|
|
|
+
|
|
|
+ })
|
|
|
+ state._marker.setLabel({
|
|
|
+ direction:'top',
|
|
|
+ offset: new AMap.Pixel(0, -10), //设置文本标注偏移量
|
|
|
+ content: `<div class='info'>${name}</div>`, //设置文本标注内容
|
|
|
+ });
|
|
|
+ window.map.add(state._marker)
|
|
|
+ window.map.setZoomAndCenter(14,
|
|
|
+ [longitude, latitude]
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // .setLngLat([longitude, latitude])
|
|
|
+ // .setPopup(popup)
|
|
|
+ // .addTo(map.value);
|
|
|
+ // map.value.flyTo({
|
|
|
+ // center: [longitude, latitude],
|
|
|
+ // zoom: 14,
|
|
|
+ // bearing: 0,
|
|
|
+ // pitch: 0,
|
|
|
+ // duration: 2000,
|
|
|
+ // });
|
|
|
+ // state._marker.togglePopup();
|
|
|
+ form.value.addr = name;
|
|
|
+ form.value.locations = longitude + ',' + latitude;
|
|
|
+ // whdata.value.longitude = longitude;
|
|
|
+ mapselect.value = false;
|
|
|
+ props.formv = form.value;
|
|
|
+ ctx.emit('update:formv', form.value);
|
|
|
+ };
|
|
|
+ const searchaddr = (name) => {
|
|
|
+ mapselect.value = false;
|
|
|
+ fetch(
|
|
|
+ `https://restapi.amap.com/v5/place/text?region=南宁市&keywords=${name}&key=${"1c7f1c8eda2ccbe7d0e125a7e2fc2a61"}`,
|
|
|
+ // `${
|
|
|
+ // import.meta.env.VITE_MAP_SERVER
|
|
|
+ // }/service/lbs/search/v1/keywords?keywords=${name}&city=宿迁&citylimit=true&page_idx=1&page_size=10&key=${
|
|
|
+ // window.key
|
|
|
+ // }`,
|
|
|
+ )
|
|
|
+ .then((res) => res.json())
|
|
|
+ .then((data) => {
|
|
|
+ // console.log(data.pois)
|
|
|
+ var clearallmark = () => {
|
|
|
+ state._marker?.remove();
|
|
|
+ if (allmark.length > 0) {
|
|
|
+ allmark.map((item) => {
|
|
|
+ item.remove();
|
|
|
+ });
|
|
|
+ allmark = [];
|
|
|
+ }
|
|
|
+ };
|
|
|
+ clearallmark();
|
|
|
+ var top = [];
|
|
|
+ var bottom = [];
|
|
|
+
|
|
|
+ data.pois.map((item) => {
|
|
|
+ if (top.length < 1) {
|
|
|
+ top = [
|
|
|
+ Number(item.location.split(',')[0]),
|
|
|
+ Number(item.location.split(',')[1]),
|
|
|
+ ];
|
|
|
+ bottom = [
|
|
|
+ Number(item.location.split(',')[0]),
|
|
|
+ Number(item.location.split(',')[1]),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ var icon = new AMap.Icon({
|
|
|
+ size: new AMap.Size(40, 50), // 图标尺寸
|
|
|
+ image: '/icon_map_location@2x.png', // Icon的图像
|
|
|
+ imageSize: new AMap.Size(20, 20) // 根据所设置的大小拉伸或压缩图片
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ var marker = new AMap.Marker({
|
|
|
+ position: new AMap.LngLat( Number(item.location.split(',')[0]), Number(item.location.split(',')[1])),
|
|
|
+ offset: new AMap.Pixel(-10, -10),
|
|
|
+ icon: icon,
|
|
|
+ })
|
|
|
+ var address = item.pname+item.cityname+item.adname+item.address+`(${item.name})`
|
|
|
+
|
|
|
+ marker.setLabel({
|
|
|
+ direction:'top',
|
|
|
+ offset: new AMap.Pixel(0, -10), //设置文本标注偏移量
|
|
|
+ content: `<div class='info'>${address}</div>`, //设置文本标注内容
|
|
|
+ });
|
|
|
+ marker.on("click", () => {
|
|
|
+ clearallmark();
|
|
|
+ setpoint(
|
|
|
+ Number(item.location.split(',')[0]),
|
|
|
+ Number(item.location.split(',')[1]),
|
|
|
+ address,
|
|
|
+ );
|
|
|
+
|
|
|
+ })
|
|
|
+ window.map.add(marker)
|
|
|
+ // window.map.setZoomAndCenter(14,
|
|
|
+ // [longitude, latitude]
|
|
|
+ // )
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ allmark.push(marker);
|
|
|
+
|
|
|
+ if (top[0] < Number(item.location.split(',')[0])) {
|
|
|
+ top[0] = Number(item.location.split(',')[0]);
|
|
|
+ }
|
|
|
+ if (top[1] > Number(item.location.split(',')[1])) {
|
|
|
+ top[1] = Number(item.location.split(',')[1]);
|
|
|
+ }
|
|
|
+ if (bottom[0] > Number(item.location.split(',')[0])) {
|
|
|
+ bottom[0] = Number(item.location.split(',')[0]);
|
|
|
+ }
|
|
|
+ if (bottom[1] < Number(item.location.split(',')[1])) {
|
|
|
+ bottom[1] = Number(item.location.split(',')[1]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ window.map.setBounds( new AMap.Bounds(top, bottom));
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const getlocalname = (location) => {
|
|
|
+ fetch(
|
|
|
+ `https://restapi.amap.com/v3/geocode/regeo?location=${location}&key=1c7f1c8eda2ccbe7d0e125a7e2fc2a61`,
|
|
|
+ // `${
|
|
|
+ // import.meta.env.VITE_MAP_SERVER as string
|
|
|
+ // }/service/lbs/reverse/v1/regeo?location=${location}&key=${window.key}`,
|
|
|
+ )
|
|
|
+ .then((res) => res.json())
|
|
|
+ .then((data) => {
|
|
|
+ setpoint(
|
|
|
+ Number(location.split(',')[0]),
|
|
|
+ Number(location.split(',')[1]),
|
|
|
+ data.regeocode.formatted_address,
|
|
|
+ );
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const getLocation = () => {
|
|
|
+
|
|
|
+ if (navigator.geolocation) {
|
|
|
+ navigator.geolocation.getCurrentPosition(
|
|
|
+ (location1) => {
|
|
|
+ var lat = null;
|
|
|
+ var lon = null;
|
|
|
+ var iserror = false;
|
|
|
+ try {
|
|
|
+ lat = location1.coords.latitude;
|
|
|
+ lon = location1.coords.longitude;
|
|
|
+ if (lat === null || lat === undefined) iserror = true;
|
|
|
+ } catch (e) {
|
|
|
+ iserror = true;
|
|
|
+ }
|
|
|
+ if (!iserror) {
|
|
|
+ // debugger
|
|
|
+ var location = `${lon},${lat}`;
|
|
|
+ getlocalname(location);
|
|
|
+ // setpoint(lon,lat,data.regeocodes[0].formatted_address)
|
|
|
+ } else {
|
|
|
+ // Notify({
|
|
|
+ // type: 'danger',
|
|
|
+ // message: 'App不支持地理定位。',
|
|
|
+ // });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ (error) => {
|
|
|
+ switch (error.code) {
|
|
|
+ case error.PERMISSION_DENIED:
|
|
|
+ alert('定位失败,用户拒绝请求地理定位');
|
|
|
+ break;
|
|
|
+ case error.POSITION_UNAVAILABLE:
|
|
|
+ alert('定位失败,位置信息是不可用');
|
|
|
+ break;
|
|
|
+ case error.TIMEOUT:
|
|
|
+ alert('定位失败,请求获取用户位置超时');
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ alert('浏览器不支持地理定位。');
|
|
|
+ }
|
|
|
+ // api_getusergps().then((res) => {
|
|
|
+ // var lat = null;
|
|
|
+ // var lon = null;
|
|
|
+ // var iserror = false;
|
|
|
+ // try {
|
|
|
+ // lat = res.result[0].lat;
|
|
|
+ // lon = res.result[0].lon;
|
|
|
+ // if (lat === null || lat === undefined) iserror = true;
|
|
|
+ // } catch (e) {
|
|
|
+ // iserror = true;
|
|
|
+ // }
|
|
|
+ // if (!iserror) {
|
|
|
+ // // debugger
|
|
|
+ // var location = `${lon},${lat}`;
|
|
|
+ // getlocalname(location);
|
|
|
+ // // setpoint(lon,lat,data.regeocodes[0].formatted_address)
|
|
|
+ // } else {
|
|
|
+ // // Notify({
|
|
|
+ // // type: 'danger',
|
|
|
+ // // message: 'App不支持地理定位。',
|
|
|
+ // // });
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ return {
|
|
|
+ map,
|
|
|
+ mapselect,
|
|
|
+ searchaddr,
|
|
|
+ selectpoint,
|
|
|
+ getLocation,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ render() {
|
|
|
+ return (
|
|
|
+ <div class={"mapselect-c"}>
|
|
|
+ <Map
|
|
|
+ v-model:map={this.map}
|
|
|
+ style={{
|
|
|
+ borderRadius: "2px",
|
|
|
+ boxShadow: "0px 0px 0px 1px #d9d9d9;",
|
|
|
+ height: "300px",
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <ElButton
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ onClick={this.selectpoint}
|
|
|
+ style={`position:absolute;right:10px;top:10px;${
|
|
|
+ this.editable ? "" : "display:none"
|
|
|
+ }`}
|
|
|
+ >
|
|
|
+ {this.mapselect ? "确定" : "选点"}
|
|
|
+ </ElButton>
|
|
|
+ <ElButton
|
|
|
+ type="text"
|
|
|
+ // size="large"
|
|
|
+ onClick={this.getLocation}
|
|
|
+ style={`position:absolute;right:10px;bottom:10px;${
|
|
|
+ this.editable ? "" : "display:none"
|
|
|
+ }`}
|
|
|
+ >
|
|
|
+ <el-icon size="25">
|
|
|
+ <img src={icon_location_svg1} style={ 'width:30px'}></img>
|
|
|
+ </el-icon>
|
|
|
+ </ElButton>
|
|
|
+
|
|
|
+ <img
|
|
|
+ style={
|
|
|
+ "width:20px;position:absolute;top:48%;left:48%;" +
|
|
|
+ `${this.mapselect ? "" : "display:none"}`
|
|
|
+ }
|
|
|
+ src={icon_location}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|