/* eslint-disable no-undef */
|
<template>
|
<Popup
|
ref="pop"
|
:title="form.title"
|
width="410px"
|
maxHeight="430px"
|
left="calc(100% - 420px)"
|
@close="clearAll"
|
>
|
<div class="POISearch">
|
<el-form ref="form" :model="form" label-width="80px" :rules="rules">
|
<el-form-item label="范围">
|
<el-radio-group v-model="form.area" @change="changeType">
|
<el-radio label="0">指定城市</el-radio>
|
<el-radio label="1">当前视角</el-radio>
|
<el-radio label="2">指定范围</el-radio>
|
</el-radio-group>
|
</el-form-item>
|
<el-form-item label="城市" v-if="form.area == 0" prop="location">
|
<el-cascader
|
:options="form.areaSelectData"
|
@change="cascaderChange"
|
class="full-width"
|
size="large"
|
v-model="form.location"
|
>
|
</el-cascader>
|
</el-form-item>
|
<el-form-item v-if="form.area == 2">
|
<el-button @click="drawSearchPolygon" type="primary" class="areaBtn">
|
多边形范围
|
</el-button>
|
<el-button @click="drawSearchCircle" type="primary" class="areaBtn">
|
圆形范围
|
</el-button>
|
</el-form-item>
|
<el-form-item label="关键字" prop="keyword">
|
<el-input
|
v-model="form.keyword"
|
placeholder="请输入关键字"
|
@input="keywordSearch"
|
>
|
</el-input>
|
</el-form-item>
|
</el-form>
|
<div class="resultDivs scrollbar" v-if="IsResultShow">
|
<div
|
class="eachResultDiv"
|
v-for="r in poiResults"
|
:key="r.resultId"
|
:id="r.resultId"
|
@click="flyTo"
|
>
|
{{ r.name }}
|
</div>
|
</div>
|
</div>
|
</Popup>
|
</template>
|
<script>
|
import Popup from "@tools/Popup.vue";
|
import { provinceAndCityData, CodeToText } from "element-china-area-data";
|
import coordtransform from "coordtransform";
|
import axios from "axios";
|
export default {
|
name: "POISearch",
|
components: {
|
Popup,
|
},
|
data() {
|
return {
|
//表单元素
|
form: {
|
title: "POI查询",
|
area: "0",
|
areaSelectData: provinceAndCityData, //地址数据源
|
location: [], //地址框结果
|
province: "",
|
city: "",
|
keyword: "",
|
},
|
//表单验证规则
|
rules: {
|
location: [
|
{ required: true, message: "请选择地址", trigger: "change" },
|
],
|
keyword: [{ required: true, message: "请输入关键字", trigger: "blur" }],
|
},
|
// 查询结果列表
|
poiResults: [
|
// {
|
// name: "name",
|
// resultId:'',
|
// },
|
],
|
IsResultShow: false, //结果div显示与否
|
drawAreaData: {}, // 绘制的多边形
|
poiPoint: [], //POI点
|
allPoiShow: [], //所有展示出来的点
|
key: "fe80f2290b380cfed86c62e3edec169e"
|
};
|
},
|
methods: {
|
// 清空所有
|
clearAll() {
|
this.clearSearch();
|
this.removeDrawArea();
|
},
|
// 清空当前搜索结果
|
clearSearch() {
|
if (this.poiResults !== []) {
|
this.poiResults = [];
|
this.IsResultShow = false;
|
}
|
this.allPoiShow = [];
|
this.removePOI();
|
},
|
// 切换类型
|
changeType() {
|
this.clearAll();
|
this.searchPOI(true);
|
},
|
// 输入框修改时直接搜索
|
keywordSearch(value = true) {
|
if (!value) {
|
this.clearAll();
|
} else {
|
this.searchPOI(true);
|
}
|
},
|
// 查询结果点击跳转视角
|
flyTo(e) {
|
let id = e.currentTarget.id; //获取当前id
|
window.Viewer.flyTo(window.Viewer.entities.getById(id));
|
},
|
// 打开弹窗
|
open() {
|
this.$refs.pop.open();
|
},
|
// 地区修改
|
cascaderChange() {
|
let provinceCode = this.form.location[0];
|
let cityCode = this.form.location[1];
|
this.form.province = CodeToText[provinceCode];
|
this.form.city = CodeToText[cityCode];
|
|
this.form.keyword && this.searchPOI(true);
|
},
|
// 表单提交 - 查询
|
searchPOI(flyTo = false) {
|
this.$refs.form.validate((valid) => {
|
if (valid) {
|
// 清除搜索内容
|
this.clearSearch();
|
|
let url = ""; // 存储URL地址
|
let value = this.form.keyword; // 关键字输入框中的内容
|
//当前视角
|
if (this.form.area == 1) {
|
try {
|
let polygon = this.getViewRectangle();
|
url = `https://restapi.amap.com/v3/place/polygon?key=${this.key}&output=json&page=1&offset=25&types=&polygon=${polygon}&keywords=${value}`;
|
} catch (err) {
|
this.$message({
|
message: "请调整视角范围",
|
duration: "1000",
|
});
|
return;
|
}
|
} else if (this.form.area == 2) {
|
//指定范围
|
if (!this.drawAreaData) {
|
this.$message({
|
message: "请绘制搜索范围",
|
duration: "1000",
|
});
|
return;
|
}
|
url = this.drawAreaData.url;
|
url += `&key=${this.key}&output=json&page=1&offset=25&types=&keywords=${value}`;
|
} else {
|
// 指定城市
|
if (this.form.city == "市辖区") {
|
url = `https://restapi.amap.com/v3/place/text?key=${this.key}&output=json&page=1&offset=25&types=&city=${this.form.province}&citylimit=true&keywords=${value}`;
|
} else {
|
url = `https://restapi.amap.com/v3/place/text?key=${this.key}&output=json&page=1&offset=25&types=&city=${this.form.city}&citylimit=true&keywords=${value}`;
|
}
|
}
|
//Ajax提交数据
|
axios({
|
method: "get",
|
url: url,
|
}).then((data) => {
|
if (this.poiResults !== []) {
|
this.poiResults = [];
|
this.IsResultShow = false;
|
}
|
this.removePOI();
|
if (typeof data === "string") {
|
data = JSON.parse(data);
|
}
|
if (data.data.pois && data.data.pois.length) {
|
let position;
|
data.data.pois.forEach((item) => {
|
position = item.location.split(",");
|
// 火星坐标转wgs84
|
position = coordtransform.gcj02towgs84(
|
position[0],
|
position[1]
|
);
|
this.IsResultShow = true;
|
|
let positon = Cesium.Cartesian3.fromDegrees(
|
position[0],
|
position[1]
|
);
|
//判断是否在圆形区域内
|
let inCircle = true;
|
if (this.drawAreaData && this.drawAreaData.radius) {
|
console.log(this.form.area);
|
inCircle =
|
Cesium.Cartesian3.distance(
|
this.drawAreaData.position,
|
positon
|
) <= this.drawAreaData.radius;
|
}
|
|
if (inCircle) {
|
window.Viewer.entities.add({
|
id: item.id,
|
position: positon,
|
label: {
|
text: item.name, //文本
|
font: "20px 微软雅黑",
|
style: 2,
|
fillColor: Cesium.Color.WHITE,
|
outlineColor: Cesium.Color.BLACK,
|
outlineWidth: 2,
|
heightReference: 1,
|
pixelOffset: {
|
x: 0,
|
y: -50,
|
},
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
distanceDisplayCondition:
|
new Cesium.DistanceDisplayCondition(0.0, 10000),
|
},
|
billboard: {
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
image: SmartEarthRootUrl + "Workers/image/mark1.png",
|
scale: 0.8,
|
heightReference: 1,
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
},
|
});
|
this.poiResults.push({ name: item.name, resultId: item.id });
|
this.allPoiShow.push(positon);
|
this.poiPoint.push(item.id);
|
}
|
});
|
clearTimeout(this.flyToTime);
|
this.flyToTime = setTimeout(() => {
|
// 若有搜索到的展示poi,则跳转
|
if (this.allPoiShow.length && flyTo) {
|
let Bounding = Cesium.BoundingSphere.fromPoints(
|
this.allPoiShow
|
);
|
Viewer.camera.flyToBoundingSphere(Bounding);
|
}
|
}, 1000);
|
}
|
});
|
}
|
});
|
},
|
//清除POI
|
removePOI(removeArea) {
|
this.poiPoint.forEach((id) => {
|
window.Viewer.entities.removeById(id);
|
});
|
this.poiPoint = [];
|
if (removeArea) {
|
this.removeDrawArea();
|
}
|
},
|
//清除绘制区域
|
removeDrawArea() {
|
if (this.drawAreaData) {
|
window.Viewer.entities.removeById(this.drawAreaData.id);
|
this.drawAreaData = undefined;
|
}
|
},
|
// 获取视角范围
|
getViewRectangle() {
|
let rectangle = sgworld.Core.getViewRectangle(Viewer);
|
let degrees = [
|
{ lon: rectangle.west, lat: rectangle.south },
|
{ lon: rectangle.east, lat: rectangle.south },
|
{ lon: rectangle.east, lat: rectangle.north },
|
{ lon: rectangle.west, lat: rectangle.north },
|
];
|
let polygon = "";
|
degrees.forEach((item, index) => {
|
if (index > 0) {
|
polygon += ";";
|
}
|
polygon += `${item.lon},${item.lat}`;
|
});
|
return polygon;
|
},
|
//绘制查询多边形区域
|
drawSearchPolygon() {
|
this.removePOI(true);
|
window.sgworld.Creator.createSimpleGraphic(
|
"polygon",
|
{
|
removeEdit: true,
|
},
|
(entity) => {
|
let positions = entity.polygon.hierarchy.getValue().positions;
|
let degrees;
|
let polygon = "polygon=";
|
positions.forEach((p, i) => {
|
degrees = window.sgworld.Core.toDegrees(p);
|
degrees = coordtransform.wgs84togcj02(degrees.lon, degrees.lat);
|
if (i > 0) {
|
polygon += ";";
|
}
|
polygon += `${degrees[0]},${degrees[1]}`;
|
});
|
this.drawAreaData = {
|
url: `https://restapi.amap.com/v3/place/polygon?${polygon}`,
|
id: entity.id,
|
};
|
this.form.keyword && this.searchPOI(true);
|
}
|
);
|
},
|
// 绘制圆形区域
|
drawSearchCircle() {
|
this.removePOI(true);
|
window.sgworld.Creator.createSimpleGraphic(
|
"circle",
|
{
|
removeEdit: true,
|
},
|
(entity) => {
|
let position = entity.position.getValue();
|
let degrees = window.sgworld.Core.toDegrees(position);
|
degrees = coordtransform.wgs84togcj02(degrees.lon, degrees.lat);
|
let radius = entity.ellipse.semiMajorAxis.getValue();
|
this.drawAreaData = {
|
url: `https://restapi.amap.com/v3/place/around?radius=${radius}&location=${degrees[0]},${degrees[1]}`,
|
id: entity.id,
|
position: position,
|
radius: radius,
|
};
|
this.form.keyword && this.searchPOI(true);
|
}
|
);
|
},
|
},
|
};
|
</script>
|
<style lang="less">
|
.POISearch {
|
margin-top: 20px;
|
.el-form-item__label {
|
color: white;
|
}
|
.searchBtn {
|
position: relative;
|
left: 40%;
|
}
|
.el-radio {
|
width: 100px;
|
margin-right: 0px;
|
}
|
.el-input {
|
width: 300px;
|
}
|
/deep/ .el-input__inner {
|
width: 95%;
|
}
|
}
|
.resultDivs {
|
height: 200px;
|
}
|
.eachResultDiv {
|
padding-left: 25px;
|
height: 30px;
|
margin-top: 10px;
|
font-size: 16px;
|
cursor: pointer;
|
}
|
.eachResultDiv:hover {
|
background-color: rgba(0, 0, 0, 0.5);
|
}
|
</style>
|