123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- <template>
- <div class="search-layout">
- <el-input v-model="keyword" placeholder="输入名称搜索" style="width: 350px" clearable @change="onSearch">
- <!-- <template #append>
- <el-button :icon="Search" />
- </template> -->
- </el-input>
- <div class="rrr">
- <div class="search-result" v-show="keyword">
- <div class="search-list" v-for="item,index in keywordList" @click="hanleItem(item.name)">
- {{ item.name }}
- </div>
- </div>
- <!-- <div class="search-sh" v-show="keyword">
- <el-button style="width: 100%" @click="showSearch = !showSearch">
- {{ showSearch ? "收起" : "展开" }}搜索结果
- </el-button>
- </div> -->
- </div>
- </div>
- <div class="def-select-map-layout">
- <div class="def-select-map" id="mapEl" ref="mapEl"></div>
- </div>
- <div class="def-map-info" v-if="searchInfo">
- <p><span>纬度</span>{{ searchInfo.lat }}</p>
- <p><span>经度</span>{{ searchInfo.lng }}</p>
- <!-- <p><span>缩放级别</span>{{ info.zoom }}</p> -->
- </div>
- </template>
- <script setup lang="ts">
- import AMapLoader from "@amap/amap-jsapi-loader";
- import { Search } from "@element-plus/icons-vue";
- import { wgs84_to_gcj02 } from "./map"
- import { getTipsList, getTipsNames, getCaseInfo } from "@/store/case";
- import { ref, watchEffect, onMounted, computed } from "vue";
- import { QuiskExpose } from "@/helper/mount";
- import { debounce } from "@/util";
- import html2canvas from "html2canvas"
- import L from 'leaflet'
- import 'leaflet/dist/leaflet.css'
- import { router } from "@/router";
- export type MapImage = { blob: Blob | null; search: MapInfo | null };
- type MapInfo = { lat: number; lng: number; zoom: number; text: string; address: string; id: string };
- // const layer = L.tileLayer('http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}')
- const layer = L.tileLayer('http://a.map.jms.gd/tile/osm/{z}/{x}/{y}.png')
- // const layer = L.tileLayer('http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=6&x={x}&y={y}&z={z}&token=YOUR_API_KEY')
- let map: any = {}
- let clickMarker;
- const keyword = ref("");
- const showSearch = ref(true);
- const info = ref<MapInfo>();
- const caseInfoData = ref<any>(null);
- const searchInfo = ref<MapInfo>();
- const mapEl = ref<HTMLDivElement>();
- const keywordList = ref([]);
- watchEffect(() => {
- if (keyword.value) {
- showSearch.value = true;
- }
- });
- const caseId = computed(() => {
- const caseId = router.currentRoute.value.params.caseId;
- if (caseId) {
- return Number(caseId);
- }
- });
- onMounted(async () => {
- caseInfoData.value = await getCaseInfo(caseId.value);
- let center = [22.61, 113.05];
- if(caseInfoData.value.latAndLong){
- center = caseInfoData.value.latAndLong.split(",")
- }
- console.log("caseInfoData", caseInfoData.value.latAndLong, center);
- // 'map'为HTML节点id
- map = L.map(mapEl.value, {
- center: center,//中心坐标
- zoom: 14,//缩放级别
- zoomControl: true, //缩放组件
- attributionControl: false, //去掉右下角logol
- layers: [layer],//图层
- // center: [51.505, -0.09],
- // zoom: 13
- })
-
- map.on("click", function (e) {
- // 获取点击位置的经纬度坐标
- var latitude = e.latlng.lat;
- var longitude = e.latlng.lng;
- console.log('click', e, [longitude, latitude]);
- searchInfo.value = {
- text: "",
- lat: latitude,
- lng: longitude,
- zoom: 0,
- };
- clickMarker && clickMarker.remove();
- clickMarker = null;
- // 在地图上添加标记
- clickMarker = L.marker([latitude, longitude],{
- position: [latitude, longitude],
- title: "点击位置",
- });
- clickMarker.addTo(map);
- map.panTo([latitude, longitude])
- // map.add(clickMarker);
- });
- })
- const resultEl = ref<HTMLDivElement>();
- const searchAMap = ref<any>();
- watchEffect(async (onCleanup) => {
- if (!mapEl.value || !resultEl.value) {
- return;
- }
- // const AMap = await AMapLoader.load({
- // plugins: ["AMap.PlaceSearch", "AMap.Event"],
- // key: "e661b00bdf2c44cccf71ef6070ef41b8",
- // version: "2.0",
- // });
- // const map = new AMap.Map(mapEl.value, {
- // WebGLParams: {
- // preserveDrawingBuffer: true,
- // },
- // resizeEnable: true,
- // });
- // const placeSearch = new AMap.PlaceSearch({
- // pageSize: 5,
- // showCover: false,
- // pageIndex: 1,
- // map: map,
- // panel: resultEl.value,
- // autoFitView: true,
- // });
- // const setSearch = (data) => {
- // console.log('setSearch', data);
- // let city = data.cityname == data.adname? data.cityname : (data.cityname + data.adname);
- // searchInfo.value = {
- // text: data.pname + city + data.address,
- // lat: data.location.lat,
- // lng: data.location.lng,
- // zoom: 0,
- // };
- // };
- // placeSearch.on("listElementClick", (e) => {
- // setSearch(e.data);
- // showSearch.value = false;
- // });
- // placeSearch.on("complete", function (result) {
- // setTimeout(() => {
- // const markers = map.getAllOverlays("marker");
- // for (const marker of markers) {
- // marker.on("click", () => {
- // clickMarker && map.remove(clickMarker);
- // clickMarker = null;
- // setSearch(marker._data);
- // });
- // }
- // }, 500);
- // });
- //绑定地图移动与缩放事件
- map.on("moveend", () => {
- info.value = getMapInfo();
- });
- map.on("zoomend", () => {
- info.value = getMapInfo();
- });
- searchAMap.value = placeSearch;
- onCleanup(() => {
- searchAMap.value = null;
- map.destroy();
- });
- });
- const getMapInfo = (): MapInfo => {
- var zoom = map.getZoom(); //获取当前地图级别
- var center = map.getCenter();
- return {
- text: "",
- zoom,
- lat: center.lat,
- lng: center.lng,
- };
- };
- const onSearch = (val) => {
- getTipsList(val).then((res) => {
- console.log('getTipsList', res);
- keywordList.value = res.data
- });
- console.log('onSearch', val, 'keyword.value', keyword.value);
- };
- const hanleItem = (name) => {
- // keyword.value = item.name;
- getTipsNames(name).then((ress) => {
- let res = ress.data;
- // longlat = wgs84_to_gcj02(Number(res.lng),Number(res.lat))
- keyword.value = '';
- searchInfo.value = {
- ...res,
- // lng: longlat[0],
- // lat: longlat[1],
- text: res.name,
- }
- clickMarker && clickMarker.remove();
- // let icon = L.icon({
- // iconUrl: require('./icon.svg'),
- // iconSize: [25, 30],
- // iconAnchor: [12, 30]
- // });
- clickMarker = null;
- // 在地图上添加标记
- clickMarker = L.marker([res.lat, res.lng],{
- position: [res.lat, res.lng],
- title: "点击位置",
- // icon,
- });
- clickMarker.addTo(map);
- map.panTo([res.lat, res.lng])
- })
- // onSearch(item.name);
- }
- var dataURLtoBlob = function (dataurl){
- var arr = dataurl.split(','),
- mime = arr[0].match(/:(.*?);/)[1],
- bstr = atob(arr[1]),
- n = bstr.length,
- u8arr = new Uint8Array(n);
- while (n--) {
- u8arr[n] = bstr.charCodeAt(n);
- }
- return new Blob([u8arr], { type: mime })
- }
- const search = debounce((keyword: string) => {
- searchAMap.value.search(keyword);
- }, 1000);
- watchEffect(() => {
- searchAMap.value && search(keyword.value);
- });
- defineExpose<QuiskExpose>({
- submit() {
- return new Promise<MapImage>((resolve) => {
- console.log('searchInfo', searchInfo.value, mapEl.value);
- if (mapEl.value) {
- const canvas = mapEl.value.querySelector("canvas") as HTMLCanvasElement;
- console.log(canvas, 'canvas');
- canvas && canvas.toBlob((blob) => resolve({ blob, search: searchInfo.value! }))// || resolve({ search: searchInfo.value! });
- if(!canvas){
- //div内容生成图片
- html2canvas(mapEl.value, {
- useCORS: true, // 添加这个选项以解决跨域问题
- }).then((canvas) => {
- let imgUrl = canvas.toDataURL("image/png");
- let blob = dataURLtoBlob(imgUrl)
- resolve({ blob, search: searchInfo.value! });
- });
- }
- } else {
- resolve({ blob: null, search: null });
- }
- });
- },
- });
- </script>
- <style lang="scss" scoped>
- .search-layout {
- display: inline-block;
- position: relative;
- margin-bottom: 15px;
- z-index: 2;
- }
- .rrr {
- position: absolute;
- left: 0;
- right: 0;
- z-index: 1;
- }
- .search-sh,
- .search-result {
- overflow: hidden;
- &.show {
- max-height: 450px;
- overflow-y: auto;
- }
- .search-list{
- background: #fff;
- padding-left: 10px;
- line-height: 36px;
- }
- }
- .def-map-info {
- margin-top: 10px;
- p {
- font-size: 14px;
- color: rgba(0, 0, 0, 0.85);
- display: inline;
- &:not(:last-child)::after {
- content: ",";
- margin-right: 6px;
- }
- }
- span::after {
- content: ":";
- }
- }
- .def-select-map-layout {
- --scale: 1.5;
- width: 100%;
- padding-top: calc((390 / 540) * 100%);
- position: relative;
- z-index: 1;
- }
- .def-select-map {
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- }
- </style>
|