changtong 6 months ago
parent
commit
16cf849e2f
  1. 8
      build/webpack.base.conf.js
  2. 2
      index.html
  3. 1
      package.json
  4. 35
      src/assets/geojson/town_boundaries.geojson
  5. 238
      src/views/screen/components/gisMapOfCounty.vue
  6. 23
      src/views/screen/county-screen.vue
  7. 185
      src/views/screen/global-travel.vue

8
build/webpack.base.conf.js

@ -92,7 +92,11 @@ const webpackConfig = {
}
}
]
}
},
{
test: /\.geojson$/,
use: 'json-loader'
},
],
// unknownContextRegExp: /^.\/.*$/,
unknownContextCritical: false
@ -111,4 +115,4 @@ const webpackConfig = {
}
}
module.exports = vuxLoader.merge(webpackConfig, {plugins: ['vux-ui']})
module.exports = vuxLoader.merge(webpackConfig, { plugins: ['vux-ui'] })

2
index.html

@ -20,7 +20,7 @@
<script type="text/javascript" src="./static/liveplayer/liveplayer-lib.min.js"></script>
<script type="text/javascript" src="./static/yjgb/recordmp3.js"></script>
<script type="text/javascript"
src="https://webapi.amap.com/maps?v=2.0&key=3a3db11b089ab8bbb3c4894e650dc077&plugin=AMap.MouseTool,AMap.PolyEditor,AMap.MapType,AMap.ControlBar,AMap.ToolBar,AMap.ElasticMarker,AMap.HawkEye,AMap.DistrictSearch,AMap.MarkerCluster,AMap.Driving,AMap.AutoComplete,AMap.PlaceSearch,AMap.ImageLayer"></script>
src="https://webapi.amap.com/maps?v=2.0&key=3a3db11b089ab8bbb3c4894e650dc077&plugin=AMap.MouseTool,AMap.PolyEditor,AMap.MapType,AMap.ControlBar,AMap.ToolBar,AMap.ElasticMarker,AMap.HawkEye,AMap.DistrictSearch,AMap.MarkerCluster,AMap.Driving,AMap.AutoComplete,AMap.PlaceSearch,AMap.ImageLayer,AMap.GeoJSON"></script>
</head>
<body>
<div id="app"></div>

1
package.json

@ -59,6 +59,7 @@
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"json-loader": "^0.5.7",
"less-loader": "^4.0.5",
"node-notifier": "^5.1.2",
"optimize-css-assets-webpack-plugin": "^3.2.0",

35
src/assets/geojson/town_boundaries.geojson

File diff suppressed because one or more lines are too long

238
src/views/screen/components/gisMapOfCounty.vue

@ -4,12 +4,7 @@
<slot name="content" class="content"></slot>
<commonModal v-model="pointsState" width="800" title="聚合列表">
<div class="points">
<div
class="item"
v-for="(item, index) in points"
:key="index"
@click="getPoint(item.point)"
>
<div class="item" v-for="(item, index) in points" :key="index" @click="getPoint(item.point)">
{{ item.point[listItemKey] }}
</div>
</div>
@ -90,6 +85,8 @@ export default {
pointsState: false,
points: [],
tags: [],
geojsonPath: "@/assets/geojson/town_boundaries.geojson", // GeoJSON
polygons: [], //
};
},
props: {
@ -176,6 +173,7 @@ export default {
}
});
},
initMap() {
const imgLayer = new AMap.TileLayer({
zIndex: 0,
@ -183,49 +181,210 @@ export default {
`http://t0.tianditu.gov.cn/DataServer?T=img_w&tk=${this.common.mapKey}&x=${x}&y=${y}&l=${z}`,
});
const district = new AMap.DistrictSearch({
subdistrict: 3,
this.map = new AMap.Map("center-map", {
layers: this.common.isSkyMap ? [imgLayer] : [new AMap.TileLayer.RoadNet()],
zoom: this.zoom,
zooms: [3, 16],
scrollWheel: true,
center: this.center || [104.62, 28.77], //
viewMode: "3D",
resizeEnable: true,
mapStyle: "amap://styles/darkblue",
features: ["bg", "road", "building", "point"],
});
this.map.on("complete", () => {
if (this.aggregationPoint) {
this.aggregationPoint(this.pointList);
}
this.addPoints(); //
});
// GeoJSON
this.loadGeoJSON();
//
this.loadCuiPingDistrict();
//
// this.map.on('click', this.handleMapClick);
},
handleMapClick(e) {
const lngLat = e.lnglat;
console.log('点击坐标:', lngLat);
this.polygons.forEach(polygon => {
const path = polygon.getPath();
const isInPolygon = AMap.GeometryUtil.isPointInRing(lngLat.toArray(), path.map(p => p.toArray()));
console.log('多边形:', isInPolygon);
if (isInPolygon) {
const name = polygon.getExtData().name;
console.log('点击:', name);
this.map.setZoomAndCenter(10, lngLat); //
alert(`您点击了乡镇:${name}`);
}
});
},
loadCuiPingDistrict() {
const districtSearch = new AMap.DistrictSearch({
subdistrict: 3, //
extensions: "all",
level: "district",
});
district.search(this.districtLocation, (status, result) => {
const bounds = result.districtList[0].boundaries;
const mask = bounds.map((bound) => [bound]);
const polygons = bounds.map(
(bound) =>
new AMap.Polygon({
strokeWeight: 5,
path: bound,
fillOpacity: 0.8,
fillColor: "rgba(67, 112, 122,0.55)",
strokeColor: "#94c4ce",
})
);
const self = this; // 便使
districtSearch.search(this.districtLocation, function (status, result) {
if (status === "complete" && result.districtList && result.districtList.length) {
const district = result.districtList[0];
const boundaries = district.boundaries;
this.map = new AMap.Map("center-map", {
mask,
layers: this.common.isSkyMap
? [imgLayer]
: [new AMap.TileLayer.RoadNet],
zoom: this.zoom,
zooms: [3, 16],
scrollWheel: true,
center: that.center,
// pitch: 10, // 0 - 83
viewMode: "3D", //
resizeEnable: true, //
mapStyle: "amap://styles/darkblue",
features: ["bg", "road", "building", "point"]
if (boundaries) {
//
self.drawCuiPingBase(boundaries);
} else {
console.warn("翠屏区无边界数据");
}
} else {
console.error("行政区查询失败: " + status);
}
});
},
drawCuiPingBase(boundaries) {
const mask = boundaries.map((boundary) => [boundary]);
boundaries.forEach((boundary) => {
const polygon = new AMap.Polygon({
path: boundary,
strokeColor: "#333", // 线
strokeWeight: 3, // 线
fillColor: "#102C4F", //
fillOpacity: 0.7, //
});
this.map.add(polygon);
});
this.map.on("complete", () => {
this.aggregationPoint(this.pointList);
//
this.map.setMask(mask);
},
debounce(func, wait) {
let timeout;
return function (...args) {
const context = this;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
},
loadGeoJSON() {
// 使 require GeoJSON
const geojsonData = require('@/assets/geojson/town_boundaries.geojson');
const colors = ['#33FFD450']; //
// GeoJSON
geojsonData.features.forEach((feature, index) => {
const { properties, geometry } = feature;
const name = properties.name; //
const coordinates = geometry.coordinates[0]; //
const center = this.getPolygonCenter(coordinates); //
console.log('多边形中心点:', center);
//
const polygon = new AMap.Polygon({
zIndex: 100,
path: coordinates[0].map((coord) => new AMap.LngLat(coord[0], coord[1])), // AMap
strokeColor: colors[index % colors.length], // 线
strokeWeight: 2, // 线
fillColor: '#0A7EA8', //
fillOpacity: 0.5, //
bubble: true, //
});
this.map.add(polygons);
//
polygon.setMap(this.map);
// Marker
if (name && center) {
const labelMarker = new AMap.Marker({
position: center,
zIndex: 2000,
clickable: true,
content: `
<div style="
font-size: 20px;
font-weight: bold;
color: #fff;
width: max-content;
">
${name}
</div>
`,
offset: new AMap.Pixel(-25, -25), //
});
// hover
labelMarker.on('mouseover', () => {
labelMarker.setContent(`
<div style="
font-size: 20px;
font-weight: bold;
color: #C6E1CA;
width: max-content;
">
${name}
</div>
`);
});
labelMarker.on('mouseout', () => {
labelMarker.setContent(`
<div style="
font-size: 20px;
font-weight: bold;
color: #fff;
width: max-content;
">
${name}
</div>
`);
});
//
labelMarker.on('click', () => {
this.$emit('enterTown', name); //
});
labelMarker.setMap(this.map);
}
});
},
//
addPoints() {
this.pointList.forEach((point) => {
const marker = new AMap.Marker({
position: point.position,
title: point.name,
});
marker.setMap(this.map);
});
},
//
getPolygonCenter(coordinates) {
if (!coordinates || !coordinates.length) return null;
let [lngSum, latSum] = [0, 0];
coordinates[0].forEach((coord, index) => {
if (Array.isArray(coord) && coord.length >= 2) {
const [lng, lat] = coord;
lngSum += lng;
latSum += lat;
} else {
console.warn(`无效的坐标 ${index}:`, coord); //
}
});
return [lngSum / coordinates[0].length, latSum / coordinates[0].length];
},
aggregationPoint(pointList) {
const gridSize = 60;
const countIcon = require("@/assets/mapIcon/count.png");
@ -346,6 +505,9 @@ export default {
this.$emit("currentPoint", data);
},
},
mounted() {
this.initMap();
},
};
</script>

23
src/views/screen/county-screen.vue

@ -2,7 +2,19 @@
<!-- 县级大屏 -->
<div class="eb-container" ref="appRef">
<MainTitle class="title" :title="title" :show-menu="false"></MainTitle>
<div class="left">
<gis-map
ref="gisMapRef"
class="gismap"
pointType="全域旅游"
:point-list="dataList"
@currentPoint="currentPointFn"
@enterTown="enterTown"
:lngLat="lngLat"
list-item-key="name"
>
<template v-slot:content>
<div class="left">
<div class="min-title">
<span>基本概况</span>
</div>
@ -126,7 +138,9 @@
<!-- 各乡镇应急广播建设情况统计 -->
<div class="emergency-broadcast" id="pieChart2"></div>
</div>
<img class="map-center" :src="require('@/assets/map.png')" />
</template>
</gis-map>
<!-- <img class="map-center" :src="require('@/assets/map.png')" /> -->
<div class="page-bottom-bg"></div>
<div class="page-left-bg"></div>
<div class="page-right-bg"></div>
@ -242,6 +256,7 @@
<script>
import { useIndex } from "../../utils/utilsDramAdmin";
import MainTitle from "./components/MainTitle.vue";
import gisMap from "./components/gisMapOfCounty.vue";
import ThreeView from "./components/three/three-view.vue";
import Rotation3D from "@/utils/rotation3D";
import vueSeamlessScroll from "vue-seamless-scroll";
@ -259,6 +274,7 @@ export default {
Swiper,
SwiperSlide,
CommonModal,
gisMap
},
data() {
let self = this;
@ -615,6 +631,9 @@ export default {
this.getTownMemu();
},
methods: {
enterTown(name) {
console.log(name);
},
toWarring(item) {
switch (this.currentType) {
case "person":

185
src/views/screen/global-travel.vue

@ -2,32 +2,16 @@
<!-- 全域旅游 -->
<div class="eb-container" ref="appRef">
<MainTitle class="title" :title="title"></MainTitle>
<gis-map
ref="gisMapRef"
class="gismap"
pointType="全域旅游"
:point-list="dataList"
@currentPoint="currentPointFn"
:lngLat="lngLat"
list-item-key="name"
>
<gis-map ref="gisMapRef" class="gismap" pointType="全域旅游" :point-list="dataList" @currentPoint="currentPointFn"
:lngLat="lngLat" list-item-key="name">
<template v-slot:content>
<div class="center-window">
<div
class="top-title"
v-for="(item, index) in iconList"
@click="changeType(item, index)"
>
<img :src="item.icon"/>
<div class="top-title" v-for="(item, index) in iconList" @click="changeType(item, index)">
<img :src="item.icon" />
<div class="text">
<p class="text-name">{{ item.label }}</p>
<p class="text-type">
<CountTo
:startVal="0"
:endVal="item.count"
:duration="2000"
/>
<CountTo :startVal="0" :endVal="item.count" :duration="2000" />
</p>
</div>
</div>
@ -38,16 +22,9 @@
</div>
<div class="content-info">
<div class="content-inof-list">
<div
class="content-info-item"
v-for="(item, index) in travleList"
:key="index"
@click="selectTravelInfoById(item.id, item)"
>
<div
class="content-info-item-title"
style="font-size: 20px; color: #fff"
>
<div class="content-info-item" v-for="(item, index) in travleList" :key="index"
@click="selectTravelInfoById(item.id, item)">
<div class="content-info-item-title" style="font-size: 20px; color: #fff">
{{ item.name }}
</div>
</div>
@ -61,77 +38,55 @@
<div class="content-info">
<!-- title -->
<div class="content-info-title">
<span
style="
<span style="
font-size: 24px;
color: #fff;
font-weight: bold;
"
>{{ detailInfo.name }}</span
>
">{{ detailInfo.name }}</span>
<span style="font-size: 18px; color: #c9c9c9">{{
typeList[detailInfo.type]
}}</span>
typeList[detailInfo.type]
}}</span>
</div>
<!-- content -->
<div
class="content-info-content"
style="margin-top: 20px"
>
<span style="font-size: 24px; color: #fff"
>基础信息</span
>
<div class="content-info-content" style="margin-top: 20px">
<span style="font-size: 24px; color: #fff">基础信息</span>
<div style="margin-top: 10px" v-if="detailInfo.address">
<span style="font-size: 18px; color: #c9c9c9"
>地址:
<span style="font-size: 18px; color: #c9c9c9">地址:
</span>
<span style="font-size: 18px; color: #fff">{{
detailInfo.address
}}</span>
detailInfo.address
}}</span>
</div>
<!-- 工作时间 -->
<div style="margin-top: 10px" v-if="detailInfo.openHours">
<span style="font-size: 18px; color: #c9c9c9"
>工作时间:
<span style="font-size: 18px; color: #c9c9c9">工作时间:
</span>
<span style="font-size: 18px; color: #fff">{{
detailInfo.openHours
}}</span>
detailInfo.openHours
}}</span>
</div>
<!-- 简介 -->
<div style="margin-top: 10px" v-if="detailInfo.remark">
<span style="font-size: 18px; color: #c9c9c9"
>简介:
<span style="font-size: 18px; color: #c9c9c9">简介:
</span>
<span style="font-size: 18px; color: #fff">{{
detailInfo.remark
}}</span>
detailInfo.remark
}}</span>
</div>
<!-- 图片 -->
<div style="margin-top: 10px" v-if="detailInfo.coverImage">
<span style="font-size: 18px; color: #c9c9c9"
>图片:
<span style="font-size: 18px; color: #c9c9c9">图片:
</span>
<img
:src="detailInfo.coverImage"
alt=""
style="width: 100%; height: 200px"
/>
<img :src="detailInfo.coverImage" alt="" style="width: 100%; height: 200px" />
</div>
<div
style="
<div style="
display: flex;
align-items: center;
margin-top: 20px;
"
>
<Button
type="text"
class="text-button"
@click="
openLineOrPlayAudio(detailInfo.type)
"
>
">
<Button type="text" class="text-button" @click="
openLineOrPlayAudio(detailInfo.type)
">
{{
detailInfo.type == 4
? "播放音频"
@ -141,13 +96,8 @@
}}
</Button>
<!-- 音频播放 -->
<audio
ref="audioRef"
class="audio-controls"
v-if="detailInfo.type == 4"
:src="detailInfo.audioList"
controls
></audio>
<audio ref="audioRef" class="audio-controls" v-if="detailInfo.type == 4"
:src="detailInfo.audioList" controls></audio>
</div>
</div>
</div>
@ -155,20 +105,13 @@
</template>
</gis-map>
<div class="page-bottom-bg"></div>
<div class="page-left-bg"></div>
<div class="page-right-bg"></div>
<div class="page-left-bg"></div>
<div class="page-right-bg"></div>
<commonModal v-model="lineVisible" title="相关路线" width="600">
<div class="line-box">
<div
class="line-item"
v-for="(item, index) in lineList"
@click="openLine(item)"
:key="index"
>
<span class="line-title"
>线路名称{{ item.lineName }}</span
>
<div class="line-item" v-for="(item, index) in lineList" @click="openLine(item)" :key="index">
<span class="line-title">线路名称{{ item.lineName }}</span>
<div class="line-content">
<span>线路途经{{ item.lineText }}</span>
</div>
@ -179,14 +122,14 @@
</template>
<script>
import {useIndex} from "../../utils/utilsDramAdmin";
import { useIndex } from "../../utils/utilsDramAdmin";
import MainTitle from "./components/MainTitle.vue";
import gisMap from "./components/gisMapOfCounty.vue";
import commonModal from "@/views/common-components/common-modal.vue";
export default {
name: "GlobalTravel",
components: {MainTitle, gisMap, commonModal},
components: { MainTitle, gisMap, commonModal },
data() {
return {
title: "全域旅游",
@ -235,14 +178,14 @@ export default {
type: "",
iconList: [
// 1 2 3 4 5 6
{icon: require("@/assets/mapIcon/jd.png"), label: "住宿", count: 0, type: "1"},
{icon: require("@/assets/mapIcon/jq.png"), label: "景点", count: 0, type: "2"},
{icon: require("@/assets/mapIcon/fd.png"), label: "美食", count: 0, type: "3"},
{icon: require("@/assets/mapIcon/jj.png"), label: "讲解", count: 0, type: "4"},
{icon: require("@/assets/mapIcon/sd.png"), label: "商店", count: 0, type: "5"},
{icon: require("@/assets/mapIcon/wsj.png"), label: "卫生间", count: 0, type: "6"},
{icon: require("@/assets/mapIcon/fwq.png"), label: "停车场", count: 0, type: "7"},
{icon: require("@/assets/mapIcon/ykzx.png"), label: "游客服务", count: 0, type: "8"},
{ icon: require("@/assets/mapIcon/jd.png"), label: "住宿", count: 0, type: "1" },
{ icon: require("@/assets/mapIcon/jq.png"), label: "景点", count: 0, type: "2" },
{ icon: require("@/assets/mapIcon/fd.png"), label: "美食", count: 0, type: "3" },
{ icon: require("@/assets/mapIcon/jj.png"), label: "讲解", count: 0, type: "4" },
{ icon: require("@/assets/mapIcon/sd.png"), label: "商店", count: 0, type: "5" },
{ icon: require("@/assets/mapIcon/wsj.png"), label: "卫生间", count: 0, type: "6" },
{ icon: require("@/assets/mapIcon/fwq.png"), label: "停车场", count: 0, type: "7" },
{ icon: require("@/assets/mapIcon/ykzx.png"), label: "游客服务", count: 0, type: "8" },
],
travleList: [],
detailInfo: {},
@ -262,7 +205,7 @@ export default {
},
mounted() {
const {calcRate, windowDraw} = useIndex(this.$refs.appRef);
const { calcRate, windowDraw } = useIndex(this.$refs.appRef);
calcRate();
windowDraw();
this.$nextTick(() => {
@ -277,7 +220,7 @@ export default {
this.$http
.post(
"/travel/selectTravelLineById",
this.common.request({id})
this.common.request({ id })
)
.then((res) => {
if (res.data.code == 200 && res.data.data) {
@ -334,12 +277,12 @@ export default {
this.driving.search(
lngList[0],
lngList[lngLength - 1],
{waypoints: this.trimmedLngList},
{ waypoints: this.trimmedLngList },
(status, result) => {
console.log(status, "status");
if (status === "complete") {
const {routes = []} = result;
const {steps = []} = routes[0];
const { routes = [] } = result;
const { steps = [] } = routes[0];
const pathArr = [];
steps.map((i) => {
pathArr.push(i.path);
@ -445,7 +388,7 @@ export default {
if (item.children && item.children.length > 0) {
this.assembleData(item.children);
} else {
let dataItem = {...item};
let dataItem = { ...item };
dataItem.lnglat = [item.lng, item.lat];
try {
dataItem.imageList = eval(dataItem.imageList);
@ -488,7 +431,7 @@ export default {
this.$http
.post(
"/travel/selectTravelInfoById",
this.common.request({id})
this.common.request({ id })
)
.then((res) => {
if (res.data.code == 200) {
@ -619,10 +562,11 @@ export default {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&:hover {
background-image: linear-gradient(90deg,
#12181f 0%,
#293240 100%);
#12181f 0%,
#293240 100%);
}
}
}
@ -666,8 +610,8 @@ export default {
height: 140px;
border-radius: 8px;
background: linear-gradient(180deg,
rgba(0, 125, 165, 0.24) 0%,
rgba(1, 10, 43, 0) 100%);
rgba(0, 125, 165, 0.24) 0%,
rgba(1, 10, 43, 0) 100%);
display: flex;
flex-direction: column;
justify-content: space-between;
@ -736,9 +680,12 @@ export default {
width: 80px;
font-size: 16px;
display: inline-block;
overflow: hidden; /*超出部分隐藏*/
white-space: nowrap; /*禁止换行*/
text-overflow: ellipsis; /*省略号*/
overflow: hidden;
/*超出部分隐藏*/
white-space: nowrap;
/*禁止换行*/
text-overflow: ellipsis;
/*省略号*/
}
.text-type {
@ -794,8 +741,8 @@ export default {
height: 140px;
border-radius: 8px;
background: linear-gradient(180deg,
rgba(0, 125, 165, 0.24) 0%,
rgba(1, 10, 43, 0) 100%);
rgba(0, 125, 165, 0.24) 0%,
rgba(1, 10, 43, 0) 100%);
display: flex;
flex-direction: column;
justify-content: space-between;

Loading…
Cancel
Save