上传代码
This commit is contained in:
14
uniapp04/uni_modules/unicloud-map/changelog.md
Normal file
14
uniapp04/uni_modules/unicloud-map/changelog.md
Normal file
@ -0,0 +1,14 @@
|
||||
## 1.2.0(2024-12-03)
|
||||
新增 `uni_modules/unicloud-map/components/unicloud-map/unicloud-map.uvue` 文件,支持编译到 uni-app x
|
||||
## 1.1.2(2024-07-23)
|
||||
移除属性 layer-style(微信小程序会报错)
|
||||
## 1.1.1(2024-04-18)
|
||||
新增opendb-poi表的索引初始化文件
|
||||
## 1.1.0(2024-03-25)
|
||||
[重要] 支持支付宝小程序云
|
||||
## 1.0.2(2024-03-06)
|
||||
新增 load 事件,在云端poi数据加载完成后触发
|
||||
## 1.0.1(2023-08-02)
|
||||
优化示例
|
||||
## 1.0.0(2023-08-01)
|
||||
初版
|
||||
@ -0,0 +1,522 @@
|
||||
<template>
|
||||
<view class="unicloud-map">
|
||||
<map :ref="mapId" :id="mapId" :style="styleCom" :latitude="latitudeCom" :longitude="longitudeCom" :scale="scale" :min-scale="minScale" :max-scale="maxScale"
|
||||
:markers="markers" :polyline="polyline" :circles="circles" :controls="controls" :include-points="includePoints" :show-compass="showCompass" :enable-zoom="enableZoom"
|
||||
:enable-scroll="enableScroll" :enable-rotate="enableRotate" :rotate="rotate" :enable-overlooking="enableOverlooking" :enable-satellite="enableSatellite"
|
||||
:enable-traffic="enableTraffic" :enable-poi="enablePoi" :enable-building="enableBuilding" :show-location="showLocation" :polygons="polygons"
|
||||
:enable-indoorMap="enableIndoorMap" @markertap="_markertap" @callouttap="_callouttap" @controltap="_controltap" @regionchange="_regionchange" @tap="_tap" @updated="_updated"
|
||||
@poitap="_poitap"></map>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* unicloud-map
|
||||
* @description 云端一体地图组件
|
||||
* @property {String} loadtime = [auto|onready|manual] 数据加载时机
|
||||
* @value auto 页面就绪后或属性变化后加载数据,默认为auto
|
||||
* @value onready 页面就绪后不自动加载数据,属性变化后加载。适合在onready中接收上个页面的参数作为where条件时。
|
||||
* @value manual 手动模式,不自动加载数据。需要手动调用refresh函数加载数据
|
||||
* @property {String} collection 表名
|
||||
* @property {Object} where 查询条件
|
||||
* @property {Number} poiMaximum = 100 最大poi显示数量
|
||||
* @property {Number} poiMaxDistance 查询的最大距离
|
||||
* @property {Number} poiMinDistance 查询的最小距离
|
||||
* @property {Number|String} width 宽度
|
||||
* @property {Number|String} height 高度
|
||||
* @property {String} defaultIcon 默认的POI图标
|
||||
* @property {Array} customIcons 自定义图标,根据POI的type来区分
|
||||
* @property {String|Number} latitude 中心纬度
|
||||
* @property {String|Number} longitude 中心经度
|
||||
* @property {Number} scale 地图缩放等级,部分情况下会自动设置,此参数会失效
|
||||
* @property {Number} minScale 最小缩放等级
|
||||
* @property {Number} maxScale 最大缩放等级
|
||||
* @property {String|Number} layerStyle 个性化地图
|
||||
* @property {Boolean} showCompass 是否显示指南针
|
||||
* @property {Boolean} enableZoom 是否支持缩放
|
||||
* @property {Boolean} enableScroll 是否支持拖动
|
||||
* @property {Boolean} enableRotate 是否支持旋转
|
||||
* @property {Number} rotate 旋转角度,当enableRotate为true时才生效
|
||||
* @property {Boolean} enableOverlooking 是否开启俯视
|
||||
* @property {Boolean} enableSatellite 是否开启卫星图
|
||||
* @property {Boolean} enableTraffic 是否开启实时路况
|
||||
* @property {Boolean} enablePoi 是否展示地图的原生 POI 点
|
||||
* @property {Boolean} enableBuilding 是否展示建筑物
|
||||
* @property {Boolean} showLocation 显示带有方向的当前定位点
|
||||
* @property {Array} polygons 多边形
|
||||
* @property {Boolean} enableIndoorMap 是否展示室内地图
|
||||
* @event {Function} mounted 组件加载完成触发(此时不一定有数据)
|
||||
* @event {Function} load 数据加载完成事件
|
||||
* @event {Function} markertap 点击标记点时触发
|
||||
* @event {Function} labeltap 点击label时触发
|
||||
* @event {Function} callouttap 点击标记点对应的气泡时触发
|
||||
* @event {Function} controltap 点击控件时触发
|
||||
* @event {Function} regionchange 视野发生变化时触发
|
||||
* @event {Function} tap 点击地图时触发; App-nvue、微信小程序2.9支持返回经纬度
|
||||
* @event {Function} updated 在地图渲染更新完成时触发
|
||||
* @event {Function} anchorpointtap 点击定位标时触发
|
||||
* @event {Function} poitap 点击地图原生POI点时触发
|
||||
* @event {Function} custom-poitap 点击自定义POI点时触发
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: "unicloud-map",
|
||||
emits: ["mounted", "load", "markertap", "labeltap", "callouttap", "controltap", "regionchange", "tap", "updated", "anchorpointtap", "poitap", "custom-poitap"],
|
||||
props: {
|
||||
collection: {
|
||||
type: String,
|
||||
default: "opendb-poi"
|
||||
},
|
||||
// 数据加载时机
|
||||
loadtime: {
|
||||
type: String,
|
||||
default: "auto"
|
||||
},
|
||||
where: {
|
||||
type: Object as PropType<UTSJSONObject>,
|
||||
},
|
||||
poiMaximum: {
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
poiMaxDistance: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
poiMinDistance: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 默认的POI图标
|
||||
defaultIcon: {
|
||||
type: String,
|
||||
default: "/static/location.png"
|
||||
},
|
||||
// 自定义图标,根据POI的type来区分
|
||||
customIcons: {
|
||||
type: Array as PropType<Array<UTSJSONObject>>,
|
||||
default: function () : Array<UTSJSONObject> {
|
||||
return [] as Array<UTSJSONObject>
|
||||
}
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 纬度
|
||||
latitude: {
|
||||
type: Number
|
||||
},
|
||||
// 经度
|
||||
longitude: {
|
||||
type: Number
|
||||
},
|
||||
// 默认纬度
|
||||
defaultLatitude: {
|
||||
type: Number,
|
||||
default: 39.908823
|
||||
},
|
||||
// 默认经度
|
||||
defaultLongitude: {
|
||||
type: Number,
|
||||
default: 116.39747
|
||||
},
|
||||
scale: {
|
||||
type: Number,
|
||||
default: 16
|
||||
},
|
||||
minScale: {
|
||||
type: Number,
|
||||
default: 3
|
||||
},
|
||||
maxScale: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
|
||||
showCompass: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
enableZoom: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
enableScroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
enableRotate: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
rotate: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
enableOverlooking: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
enableSatellite: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
enableTraffic: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
enablePoi: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
enableBuilding: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showLocation: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
polygons: {
|
||||
type: Array as PropType<Array<Polygon>>,
|
||||
default: function () : Array<Polygon> {
|
||||
return [] as Array<Polygon>
|
||||
}
|
||||
},
|
||||
enableIndoorMap: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const mapId = `UniCloudMap_${(Math.random() * 10e5).toString(36)}` as string;
|
||||
return {
|
||||
mapId: mapId,
|
||||
mapStyle: "",
|
||||
// 标记点
|
||||
markers: [] as Marker[],
|
||||
// 路线
|
||||
polyline: [] as Polyline[],
|
||||
// 圆
|
||||
circles: [] as Circle[],
|
||||
// 控件
|
||||
controls: [] as Control[],
|
||||
// 缩放视野以包含所有给定的坐标点
|
||||
includePoints: [] as LocationObject[],
|
||||
// 当前pois列表数据
|
||||
pois: [] as UTSJSONObject[]
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
let loadtime = this.loadtime as string;
|
||||
if (loadtime == "auto") {
|
||||
this.getCloudData({
|
||||
needIncludePoints: true
|
||||
});
|
||||
}
|
||||
this.$emit("mounted");
|
||||
},
|
||||
methods: {
|
||||
// 提供给外部调用
|
||||
async refresh(obj ?: UTSJSONObject) {
|
||||
this.getCloudData(obj);
|
||||
},
|
||||
// 获取云端数据
|
||||
async getCloudData(obj ?: UTSJSONObject) {
|
||||
let collection = this.collection as string;
|
||||
let longitude = this.longitudeCom as number;
|
||||
let latitude = this.latitudeCom as number;
|
||||
let poiMaxDistance = this.poiMaxDistance as number;
|
||||
let poiMinDistance = this.poiMinDistance as number;
|
||||
let needIncludePoints = false;
|
||||
if (obj != null) {
|
||||
if (obj['needIncludePoints'] != null) {
|
||||
needIncludePoints = obj['needIncludePoints'] as boolean;
|
||||
}
|
||||
if (obj['longitude'] != null && obj['latitude'] != null) {
|
||||
longitude = obj['longitude'] as number;
|
||||
latitude = obj['latitude'] as number;
|
||||
}
|
||||
}
|
||||
const db = uniCloud.databaseForJQL();
|
||||
let where = Object.assign({
|
||||
visible: true,
|
||||
}, this.where as UTSJSONObject)
|
||||
let geoNearJson = {
|
||||
distanceField: 'distance', // 输出的每个记录中 distance 即是与给定点的距离
|
||||
spherical: true,
|
||||
near: new db.Geo.Point(longitude, latitude),
|
||||
query: where,
|
||||
key: 'location', // 若只有 location 一个地理位置索引的字段,则不需填
|
||||
includeLocs: 'location', // 若只有 location 一个是地理位置,则不需填
|
||||
} as UTSJSONObject;
|
||||
if (poiMaxDistance > 0) {
|
||||
geoNearJson['maxDistance'] = poiMaxDistance;
|
||||
}
|
||||
if (poiMinDistance > 0) {
|
||||
geoNearJson['minDistance'] = poiMinDistance;
|
||||
}
|
||||
let res = await db.collection(collection).aggregate()
|
||||
.geoNear(geoNearJson)
|
||||
.orderBy("distance desc")
|
||||
.limit(this.poiMaximum)
|
||||
.get();
|
||||
let list = res['data'] as UTSJSONObject[];
|
||||
// 根据level手动排序
|
||||
list.sort((a : UTSJSONObject, b : UTSJSONObject) : number => {
|
||||
let levelA = a['level'] != null ? a['level'] as number : 0;
|
||||
let levelB = b['level'] != null ? b['level'] as number : 0;
|
||||
return levelA - levelB;
|
||||
});
|
||||
this.pois = list;
|
||||
let markers = list.map((item : UTSJSONObject, index : number) : Marker => {
|
||||
let location = item['location'] as UTSJSONObject;
|
||||
let coordinates = location['coordinates'] as Array<number>;
|
||||
let data = {
|
||||
id: index,
|
||||
latitude: coordinates[1],
|
||||
longitude: coordinates[0],
|
||||
iconPath: this._getIcon(item),
|
||||
width: 30,
|
||||
height: 30,
|
||||
rotate: item['rotate'] != null ? item['rotate'] as number : 0
|
||||
} as Marker;
|
||||
if (item['title'] != null) {
|
||||
data.title = item['title'] as string;
|
||||
data.callout = {
|
||||
content: item['title'] as string,
|
||||
color: "#000000",
|
||||
fontSize: 12,
|
||||
borderRadius: 5,
|
||||
borderWidth: 1,
|
||||
borderColor: "#f8f8f8",
|
||||
bgColor: "#ffffff",
|
||||
padding: 4,
|
||||
display: "ALWAYS",
|
||||
textAlign: "center"
|
||||
} as MapMarkerCallout;
|
||||
}
|
||||
return data;
|
||||
});
|
||||
this.markers = markers;
|
||||
if (needIncludePoints) {
|
||||
this.calcIncludePoints();
|
||||
}
|
||||
let emitData = {
|
||||
pois: list,
|
||||
markers,
|
||||
};
|
||||
this.$emit("load", emitData);
|
||||
},
|
||||
// 计算一组坐标的边界
|
||||
_calculateBounds(coordinates : LocationObject[]) : LocationObject[] {
|
||||
if (coordinates.length == 0) {
|
||||
return [];
|
||||
}
|
||||
let minLongitude = coordinates[0].longitude;
|
||||
let maxLongitude = coordinates[0].longitude;
|
||||
let minLatitude = coordinates[0].latitude;
|
||||
let maxLatitude = coordinates[0].latitude;
|
||||
|
||||
coordinates.forEach((coord : LocationObject) => {
|
||||
let longitude = coord.longitude;
|
||||
let latitude = coord.latitude;
|
||||
minLongitude = Math.min(minLongitude, longitude);
|
||||
maxLongitude = Math.max(maxLongitude, longitude);
|
||||
minLatitude = Math.min(minLatitude, latitude);
|
||||
maxLatitude = Math.max(maxLatitude, latitude);
|
||||
})
|
||||
let k = 0.008; // 额外偏移0.008,使所有坐标都在一屏中显示
|
||||
const southwest = { longitude: minLongitude - k, latitude: minLatitude - k } as LocationObject;
|
||||
const northeast = { longitude: maxLongitude + k, latitude: maxLatitude + k } as LocationObject;
|
||||
|
||||
return [
|
||||
southwest,
|
||||
northeast
|
||||
] as LocationObject[]
|
||||
},
|
||||
getMarkers() : Marker[] {
|
||||
return this.markers;
|
||||
},
|
||||
setMarkers(markers : Marker[]) {
|
||||
this.markers = markers;
|
||||
},
|
||||
getPolyline() : Polyline[] {
|
||||
return this.polyline;
|
||||
},
|
||||
setPolyline(polyline : Polyline[]) {
|
||||
this.polyline = polyline;
|
||||
this.calcIncludePoints();
|
||||
},
|
||||
calcIncludePoints() {
|
||||
let polyline = this.polyline as Polyline[];
|
||||
let markers = this.markers as Marker[];
|
||||
let points = [] as LocationObject[];
|
||||
if (markers.length > 0) {
|
||||
let list : LocationObject[] = markers.map((item : Marker) => {
|
||||
return {
|
||||
latitude: item.latitude,
|
||||
longitude: item.longitude
|
||||
} as LocationObject
|
||||
});
|
||||
points = points.concat(list);
|
||||
}
|
||||
|
||||
if (polyline.length > 0) {
|
||||
polyline.forEach((item : Polyline) => {
|
||||
points = points.concat(item.points);
|
||||
});
|
||||
}
|
||||
if (points.length > 0) {
|
||||
this.includePoints = this._calculateBounds(points);
|
||||
} else {
|
||||
this.includePoints = [
|
||||
{
|
||||
latitude: this.latitudeCom,
|
||||
longitude: this.longitudeCom
|
||||
} as LocationObject
|
||||
] as LocationObject[];
|
||||
}
|
||||
},
|
||||
getCircles() : Circle[] {
|
||||
return this.circles;
|
||||
},
|
||||
setCircles(circles : Circle[]) {
|
||||
this.circles = circles;
|
||||
},
|
||||
getControls() : Control[] {
|
||||
return this.controls;
|
||||
},
|
||||
setControls(controls : Control[]) {
|
||||
this.controls = controls;
|
||||
},
|
||||
_getIcon(obj : UTSJSONObject) : string {
|
||||
let type = obj['type'] as string;
|
||||
if (obj['icon'] != null) {
|
||||
return obj['icon'] as string;;
|
||||
}
|
||||
let customIcons = this.customIcons as Array<UTSJSONObject>;
|
||||
let defaultIcon = this.defaultIcon as string;
|
||||
let findItem : UTSJSONObject | null = customIcons.find((item : UTSJSONObject) : boolean => {
|
||||
let _type = item['type'] as string;
|
||||
return _type == type ? true : false;
|
||||
});
|
||||
if (findItem == null) {
|
||||
return defaultIcon;
|
||||
}
|
||||
if (findItem['icon'] == null) {
|
||||
return defaultIcon;
|
||||
}
|
||||
return findItem['icon'] as string;
|
||||
},
|
||||
_markertap(e : UniMapMarkerTapEvent) {
|
||||
let markerId = e.detail.markerId;
|
||||
if (markerId != null) {
|
||||
let poi = this.pois[markerId];
|
||||
this.$emit("markertap", e);
|
||||
this.$emit("custom-poitap", { poi });
|
||||
}
|
||||
},
|
||||
_callouttap(e : UniEvent) {
|
||||
this.$emit("callouttap", e);
|
||||
},
|
||||
_controltap(e : UniMapControlTapEvent) {
|
||||
this.$emit("controltap", e);
|
||||
},
|
||||
getMapContext() : MapContext | null {
|
||||
// @ts-expect-error
|
||||
return uni.createMapContext(this.mapId, this);
|
||||
},
|
||||
_regionchange(e : UniMapRegionChangeEvent) {
|
||||
let causedBy = e.causedBy as string | null;
|
||||
// #ifdef WEB
|
||||
if (!causedBy) {
|
||||
// @ts-expect-error
|
||||
causedBy = e.detail.causedBy as string;
|
||||
}
|
||||
// #endif
|
||||
if (e.type !== "end" || causedBy != "drag") {
|
||||
return;
|
||||
}
|
||||
this.$emit("regionchange", e);
|
||||
const mapContext = this.getMapContext();
|
||||
if (mapContext != null) {
|
||||
mapContext.getCenterLocation({
|
||||
success: (res) => {
|
||||
this.getCloudData({
|
||||
latitude: res.latitude,
|
||||
longitude: res.longitude
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
_tap(e : UniMapTapEvent) {
|
||||
this.$emit("tap", e);
|
||||
},
|
||||
_updated(e : UniMapUpdatedEvent) {
|
||||
this.$emit("updated", e);
|
||||
},
|
||||
_poitap(e : UniMapPoiTapEvent) {
|
||||
this.$emit("poitap", e);
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
whereWatchCom() {
|
||||
// 需要重新查询
|
||||
let loadtime = this.loadtime as string;
|
||||
if (loadtime !== "manual") {
|
||||
this.refresh({
|
||||
needIncludePoints: true
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
whereWatchCom() : string {
|
||||
let where = this.where as UTSJSONObject;
|
||||
let collection = this.collection as string;
|
||||
return JSON.stringify({ where, collection })
|
||||
},
|
||||
styleCom() : string {
|
||||
let width = this.width as number;
|
||||
let height = this.height as number
|
||||
let arr = [] as Array<string>;
|
||||
if (width > 0) {
|
||||
arr.push(`width:${width}px;`);
|
||||
} else {
|
||||
arr.push("width:100%;");
|
||||
}
|
||||
if (height > 0) {
|
||||
arr.push(`height:${height}px;`);
|
||||
} else {
|
||||
arr.push("height:100%;");
|
||||
}
|
||||
return arr.join("");
|
||||
},
|
||||
latitudeCom() : number {
|
||||
let latitude = this.latitude as number;
|
||||
let defaultLatitude = this.defaultLatitude as number;
|
||||
return (latitude != 0) ? latitude : defaultLatitude;
|
||||
},
|
||||
longitudeCom() : number {
|
||||
let longitude = this.longitude as number;
|
||||
let defaultLongitude = this.defaultLongitude as number;
|
||||
return (longitude != 0) ? longitude : defaultLongitude;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.unicloud-map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,617 @@
|
||||
<template>
|
||||
<view class="unicloud-map">
|
||||
<map ref="map" :style="styleCom" :latitude="latitudeCom" :longitude="longitudeCom" :scale="scale" :min-scale="minScale" :max-scale="maxScale"
|
||||
:markers="markers" :polyline="polyline" :circles="circles" :controls="controls" :include-points="includePoints" :show-compass="showCompass"
|
||||
:enable-zoom="enableZoom" :enable-scroll="enableScroll" :enable-rotate="enableRotate" :rotate="rotate" :enable-overlooking="enableOverlooking" :enable-satellite="enableSatellite"
|
||||
:enable-traffic="enableTraffic" :enable-poi="enablePoi" :enable-building="enableBuilding" :show-location="showLocation" :polygons="polygons"
|
||||
:enable-indoorMap="enableIndoorMap" @markertap="_markertap" @labeltap="_labeltap" @callouttap="_callouttap" @controltap="_controltap" @regionchange="_regionchange"
|
||||
@tap="_tap" @updated="_updated" @anchorpointtap="_anchorpointtap" @poitap="_poitap"></map>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
let timeoutArr = [];
|
||||
let flagArr = [];
|
||||
let timeout = null;
|
||||
/**
|
||||
* 节流函数
|
||||
* 节流原理:在一定时间内,只能触发一次
|
||||
*/
|
||||
function throttle(fn, time = 500, isImmediate = true, timeoutName = "default") {
|
||||
if(!timeoutArr[timeoutName]) timeoutArr[timeoutName] = null;
|
||||
if (isImmediate) {
|
||||
if (!flagArr[timeoutName]) {
|
||||
flagArr[timeoutName] = true;
|
||||
// 如果是立即执行,则在time毫秒内开始时执行
|
||||
if(typeof fn === 'function') fn();
|
||||
timeoutArr[timeoutName] = setTimeout(() => {
|
||||
flagArr[timeoutName] = false;
|
||||
}, time);
|
||||
}
|
||||
} else {
|
||||
if (!flagArr[timeoutName]) {
|
||||
flagArr[timeoutName] = true;
|
||||
// 如果是非立即执行,则在time毫秒内的结束处执行
|
||||
timeoutArr[timeoutName] = setTimeout(() => {
|
||||
flagArr[timeoutName] = false;
|
||||
if(typeof fn === 'function') fn();
|
||||
}, time);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
|
||||
*/
|
||||
function debounce(func, wait = 500, immediate = false) {
|
||||
// 清除定时器
|
||||
if (timeout !== null) clearTimeout(timeout);
|
||||
// 立即执行,此类情况一般用不到
|
||||
if (immediate) {
|
||||
var callNow = !timeout;
|
||||
timeout = setTimeout(function() {
|
||||
timeout = null;
|
||||
}, wait);
|
||||
if (callNow) typeof func === 'function' && func();
|
||||
} else {
|
||||
// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
|
||||
timeout = setTimeout(function() {
|
||||
typeof func === 'function' && func();
|
||||
}, wait);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* unicloud-map
|
||||
* @description 云端一体地图组件
|
||||
* @property {String} loadtime = [auto|onready|manual] 数据加载时机
|
||||
* @value auto 页面就绪后或属性变化后加载数据,默认为auto
|
||||
* @value onready 页面就绪后不自动加载数据,属性变化后加载。适合在onready中接收上个页面的参数作为where条件时。
|
||||
* @value manual 手动模式,不自动加载数据。需要手动调用refresh函数加载数据
|
||||
* @property {Boolean} debug = [true|false] 是否开启调试模式
|
||||
* @property {String} collection 表名
|
||||
* @property {Object} where 查询条件
|
||||
* @property {Number} poiMaximum = 100 最大poi显示数量
|
||||
* @property {Number} poiMaxDistance 查询的最大距离
|
||||
* @property {Number} poiMinDistance 查询的最小距离
|
||||
* @property {Number|String} width 宽度
|
||||
* @property {Number|String} height 高度
|
||||
* @property {String} defaultIcon 默认的POI图标
|
||||
* @property {Array} customIcons 自定义图标,根据POI的type来区分
|
||||
* @property {String|Number} latitude 中心纬度
|
||||
* @property {String|Number} longitude 中心经度
|
||||
* @property {Number} scale 地图缩放等级,部分情况下会自动设置,此参数会失效
|
||||
* @property {Number} minScale 最小缩放等级
|
||||
* @property {Number} maxScale 最大缩放等级
|
||||
* @property {String|Number} layerStyle 个性化地图
|
||||
* @property {Boolean} showCompass 是否显示指南针
|
||||
* @property {Boolean} enableZoom 是否支持缩放
|
||||
* @property {Boolean} enableScroll 是否支持拖动
|
||||
* @property {Boolean} enableRotate 是否支持旋转
|
||||
* @property {Number} rotate 旋转角度,当enableRotate为true时才生效
|
||||
* @property {Boolean} enableOverlooking 是否开启俯视
|
||||
* @property {Boolean} enableSatellite 是否开启卫星图
|
||||
* @property {Boolean} enableTraffic 是否开启实时路况
|
||||
* @property {Boolean} enablePoi 是否展示地图的原生 POI 点
|
||||
* @property {Boolean} enableBuilding 是否展示建筑物
|
||||
* @property {Boolean} showLocation 显示带有方向的当前定位点
|
||||
* @property {Array} polygons 多边形
|
||||
* @property {Boolean} enableIndoorMap 是否展示室内地图
|
||||
* @property {Function} poiTitleFormat 自定义poi标题的格式化函数
|
||||
* @event {Function} mounted 组件加载完成触发(此时不一定有数据)
|
||||
* @event {Function} load 数据加载完成事件
|
||||
* @event {Function} markertap 点击标记点时触发
|
||||
* @event {Function} labeltap 点击label时触发
|
||||
* @event {Function} callouttap 点击标记点对应的气泡时触发
|
||||
* @event {Function} controltap 点击控件时触发
|
||||
* @event {Function} regionchange 视野发生变化时触发
|
||||
* @event {Function} tap 点击地图时触发; App-nvue、微信小程序2.9支持返回经纬度
|
||||
* @event {Function} updated 在地图渲染更新完成时触发
|
||||
* @event {Function} anchorpointtap 点击定位标时触发
|
||||
* @event {Function} native-poitap 点击地图原生POI点时触发
|
||||
* @event {Function} poitap 点击自定义POI点时触发
|
||||
*
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: "unicloud-map",
|
||||
emits: ["mounted", "load", "markertap", "labeltap","callouttap","controltap","regionchange","tap","updated","anchorpointtap","poitap","native-poitap"],
|
||||
props: {
|
||||
debug: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
collection:{
|
||||
type: String,
|
||||
default: "opendb-poi"
|
||||
},
|
||||
// 数据加载时机
|
||||
loadtime:{
|
||||
type: String,
|
||||
default: "auto"
|
||||
},
|
||||
where: {
|
||||
type: Object
|
||||
},
|
||||
poiMaximum: {
|
||||
type: [String, Number],
|
||||
default: 100
|
||||
},
|
||||
poiMaxDistance: {
|
||||
type: Number
|
||||
},
|
||||
poiMinDistance: {
|
||||
type: Number
|
||||
},
|
||||
width: {
|
||||
type: [String, Number],
|
||||
default: 600
|
||||
},
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: 600
|
||||
},
|
||||
// 默认的POI图标
|
||||
defaultIcon:{
|
||||
type: String,
|
||||
default: "/static/location.png"
|
||||
},
|
||||
// 自定义图标,根据POI的type来区分
|
||||
customIcons:{
|
||||
type: Array,
|
||||
default: function(){
|
||||
return []
|
||||
}
|
||||
},
|
||||
// 纬度
|
||||
latitude: {
|
||||
type: [String, Number]
|
||||
},
|
||||
// 经度
|
||||
longitude: {
|
||||
type: [String, Number]
|
||||
},
|
||||
// 默认纬度
|
||||
defaultLatitude: {
|
||||
type: [String, Number],
|
||||
default: 39.908823
|
||||
},
|
||||
// 默认经度
|
||||
defaultLongitude: {
|
||||
type: [String, Number],
|
||||
default: 116.39747
|
||||
},
|
||||
scale: {
|
||||
type: Number,
|
||||
default: 16
|
||||
},
|
||||
minScale: {
|
||||
type: Number,
|
||||
default: 3
|
||||
},
|
||||
maxScale: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
|
||||
showCompass: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
enableZoom: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
enableScroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
enableRotate: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
rotate: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
enableOverlooking: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
enableSatellite: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
enableTraffic: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
enablePoi: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
enableBuilding: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showLocation: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
polygons: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
enableIndoorMap: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
poiTitleFormat: {
|
||||
type: Function,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 标记点
|
||||
markers: [],
|
||||
// 路线
|
||||
polyline: [],
|
||||
// 圆
|
||||
circles: [],
|
||||
// 控件
|
||||
controls: [],
|
||||
// 缩放视野以包含所有给定的坐标点
|
||||
includePoints: [],
|
||||
// 当前pois列表数据
|
||||
pois:[],
|
||||
needIncludePoints: true,
|
||||
calcIncludePointsLastTime: 0
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
let { loadtime } = this;
|
||||
if (loadtime === "auto") {
|
||||
this.getCloudData();
|
||||
}
|
||||
this.$emit("mounted");
|
||||
},
|
||||
methods: {
|
||||
// 提供给外部调用
|
||||
async refresh(obj={}){
|
||||
return this.getCloudData(obj);
|
||||
},
|
||||
// 获取云端数据
|
||||
async getCloudData(obj={}){
|
||||
let {
|
||||
longitude: myLongitude,
|
||||
latitude: myLatitude,
|
||||
scale,
|
||||
needIncludePoints
|
||||
} = obj;
|
||||
|
||||
let {
|
||||
collection,
|
||||
defaultIcon,
|
||||
longitudeCom: longitude,
|
||||
latitudeCom: latitude,
|
||||
showLocation,
|
||||
} = this;
|
||||
|
||||
if (typeof myLongitude != "undefined" && typeof myLatitude != "undefined") {
|
||||
longitude = myLongitude;
|
||||
latitude = myLatitude;
|
||||
}
|
||||
|
||||
if (this.debug) console.log('longitude, latitude: ', longitude, latitude)
|
||||
let geoNearJson = {};
|
||||
if (typeof this.poiMaxDistance === "number" && this.poiMaxDistance > 0) {
|
||||
geoNearJson.maxDistance = this.poiMaxDistance;
|
||||
}
|
||||
if (typeof this.poiMinDistance === "number" && this.poiMinDistance > 0) {
|
||||
geoNearJson.minDistance = this.poiMinDistance;
|
||||
}
|
||||
if (scale) {
|
||||
delete geoNearJson.maxDistance;
|
||||
}
|
||||
let where = {
|
||||
visible: true,
|
||||
...Object.assign({}, this.where)
|
||||
};
|
||||
if (this.debug) console.log('geoNearJson: ', geoNearJson)
|
||||
if (this.debug) console.log('where: ', where)
|
||||
const db = uniCloud.database();
|
||||
let res = await db.collection(collection).aggregate()
|
||||
.geoNear({
|
||||
...geoNearJson,
|
||||
distanceField: 'distance', // 输出的每个记录中 distance 即是与给定点的距离
|
||||
spherical: true,
|
||||
near: new db.Geo.Point(longitude, latitude),
|
||||
query: where,
|
||||
key: 'location', // 若只有 location 一个地理位置索引的字段,则不需填
|
||||
includeLocs: 'location', // 若只有 location 一个是地理位置,则不需填
|
||||
})
|
||||
.sort({
|
||||
distance: 1,
|
||||
})
|
||||
.limit(Number(this.poiMaximum))
|
||||
.end();
|
||||
|
||||
// 根据level手动排序
|
||||
|
||||
if (this.debug) console.log('res.result.data: ', res.result.data)
|
||||
res.result.data.sort((a, b) => {
|
||||
let { level: levelA = 0 } = a;
|
||||
let { level: levelB = 0 } = b;
|
||||
return levelA - levelB;
|
||||
});
|
||||
this.pois = res.result.data;
|
||||
let markers = res.result.data.map((item, index) => {
|
||||
let data = {
|
||||
id: index,
|
||||
latitude: item.location.coordinates[1],
|
||||
longitude: item.location.coordinates[0],
|
||||
iconPath: this._getIcon(item),
|
||||
width: 30,
|
||||
height: 30,
|
||||
rotate: item.rotate || 0
|
||||
};
|
||||
if (item.title) {
|
||||
data.title = this._getPoiTitle(item);
|
||||
data.callout = {
|
||||
content: this._getPoiTitle(item),
|
||||
color: "#000000",
|
||||
fontSize: 12,
|
||||
borderRadius: 5,
|
||||
borderWidth: 1,
|
||||
borderColor: "#f8f8f8",
|
||||
bgColor: "#ffffff",
|
||||
padding: 4,
|
||||
display: "ALWAYS",
|
||||
textAlign: "center"
|
||||
};
|
||||
}
|
||||
return data;
|
||||
});
|
||||
if (this.debug) console.log('markers: ', markers)
|
||||
this.markers = markers;
|
||||
if (this.needIncludePoints || needIncludePoints) {
|
||||
this.calcIncludePoints();
|
||||
}
|
||||
let emitData = {
|
||||
pois: res.result.data,
|
||||
markers,
|
||||
};
|
||||
this.$emit("load", emitData);
|
||||
// console.log('markers: ', markers)
|
||||
// console.log('res: ', res.result.data)
|
||||
},
|
||||
// 计算一组坐标的边界
|
||||
_calculateBounds(coordinates){
|
||||
if (!Array.isArray(coordinates) || coordinates.length === 0) {
|
||||
return [];
|
||||
}
|
||||
let minLongitude = coordinates[0].longitude;
|
||||
let maxLongitude = coordinates[0].longitude;
|
||||
let minLatitude = coordinates[0].latitude;
|
||||
let maxLatitude = coordinates[0].latitude;
|
||||
|
||||
for (const coord of coordinates) {
|
||||
const { longitude, latitude } = coord;
|
||||
|
||||
minLongitude = Math.min(minLongitude, longitude);
|
||||
maxLongitude = Math.max(maxLongitude, longitude);
|
||||
minLatitude = Math.min(minLatitude, latitude);
|
||||
maxLatitude = Math.max(maxLatitude, latitude);
|
||||
}
|
||||
let k = 0.002; // 额外偏移0.002,使所有坐标都在一屏中显示
|
||||
const southwest = { longitude: minLongitude-k, latitude: minLatitude-k };
|
||||
const northeast = { longitude: maxLongitude+k, latitude: maxLatitude+k };
|
||||
|
||||
return [
|
||||
southwest,
|
||||
northeast
|
||||
]
|
||||
},
|
||||
getMarkers(){
|
||||
return this.markers;
|
||||
},
|
||||
setMarkers(markers){
|
||||
this.markers = markers;
|
||||
},
|
||||
getPolyline(){
|
||||
return this.polyline;
|
||||
},
|
||||
setPolyline(polyline){
|
||||
this.polyline = polyline;
|
||||
this.calcIncludePoints();
|
||||
},
|
||||
calcIncludePoints(){
|
||||
let { polyline=[], markers=[], calcIncludePointsLastTime = 0 } = this;
|
||||
// uni.showToast({
|
||||
// title: `${Date.now() - calcIncludePointsLastTime}`,
|
||||
// icon: "none"
|
||||
// })
|
||||
if (Date.now() - calcIncludePointsLastTime < 5000) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let points = [];
|
||||
if (markers.length > 0) {
|
||||
let list = markers.map((item, index) => {
|
||||
return {
|
||||
latitude: item.latitude,
|
||||
longitude: item.longitude
|
||||
}
|
||||
});
|
||||
points = points.concat(list);
|
||||
}
|
||||
|
||||
if (polyline.length > 0) {
|
||||
polyline.map((item, index) => {
|
||||
points = points.concat(item.points);
|
||||
});
|
||||
}
|
||||
if (points.length > 0) {
|
||||
this.includePoints = this._calculateBounds(points);
|
||||
} else {
|
||||
this.includePoints = [
|
||||
{
|
||||
latitude: this.latitude,
|
||||
longitude: this.longitude
|
||||
}
|
||||
];
|
||||
}
|
||||
},
|
||||
getCircles(){
|
||||
return this.circles;
|
||||
},
|
||||
setCircles(circles){
|
||||
this.circles = circles;
|
||||
},
|
||||
getControls(){
|
||||
return this.controls;
|
||||
},
|
||||
setControls(controls){
|
||||
this.controls = controls;
|
||||
},
|
||||
_getPoiTitle(poi={}){
|
||||
let { poiTitleFormat } = this;
|
||||
if (typeof poiTitleFormat === "function") {
|
||||
return poiTitleFormat(poi);
|
||||
} else {
|
||||
return poi.title;
|
||||
}
|
||||
},
|
||||
_getIcon(obj={}){
|
||||
let { type, icon } = obj;
|
||||
if (icon) {
|
||||
return icon;
|
||||
}
|
||||
let { customIcons=[], defaultIcon } = this;
|
||||
let findItem = customIcons.find((item) => {
|
||||
return item.type === type;
|
||||
});
|
||||
return findItem && findItem.icon ? findItem.icon : defaultIcon;
|
||||
},
|
||||
// 触发监听 - 点击poi
|
||||
_emitPoi(type, e){
|
||||
let markerId = e.detail.markerId;
|
||||
let poi = this.pois[markerId];
|
||||
e.poi = poi;
|
||||
this.$emit(type, e);
|
||||
this.$emit("poitap", e);
|
||||
},
|
||||
_markertap(e) {
|
||||
if (this.debug) console.log('markertap: ', e)
|
||||
this._emitPoi("markertap", e);
|
||||
},
|
||||
_callouttap(e) {
|
||||
if (this.debug) console.log('callouttap: ', e)
|
||||
this._emitPoi("callouttap", e);
|
||||
},
|
||||
_labeltap(e) {
|
||||
if (this.debug) console.log('labeltap: ', e)
|
||||
this.$emit("labeltap", e);
|
||||
},
|
||||
_controltap(e) {
|
||||
if (this.debug) console.log('controltap: ', e)
|
||||
this.$emit("controltap", e);
|
||||
},
|
||||
_regionchange(e) {
|
||||
if (this.debug) console.log('regionchange: ', e)
|
||||
this.$emit("regionchange", e);
|
||||
if (e.detail.causedBy === "gesture") {
|
||||
this.calcIncludePointsLastTime = Date.now();
|
||||
}
|
||||
if (e.detail.centerLocation) {
|
||||
const getCloudData = () =>{
|
||||
this.getCloudData({
|
||||
latitude: e.detail.centerLocation.latitude,
|
||||
longitude: e.detail.centerLocation.longitude,
|
||||
scale: e.detail.scale
|
||||
});
|
||||
}
|
||||
// 当用户手动拖动地图时,5秒内不再自动变更地图可视范围
|
||||
this.needIncludePoints = false;
|
||||
throttle(getCloudData, 2000);
|
||||
}
|
||||
},
|
||||
_tap(e) {
|
||||
if (this.debug) console.log('tap: ', e)
|
||||
this.$emit("tap", e);
|
||||
},
|
||||
_updated(e) {
|
||||
if (this.debug) console.log('updated: ', e)
|
||||
this.$emit("updated", e);
|
||||
},
|
||||
_anchorpointtap(e) {
|
||||
if (this.debug) console.log('anchorpointtap: ', e)
|
||||
this.$emit("anchorpointtap", e);
|
||||
},
|
||||
_poitap(e) {
|
||||
if (this.debug) console.log('poitap: ', e)
|
||||
this.$emit("native-poitap", e);
|
||||
}
|
||||
|
||||
},
|
||||
watch: {
|
||||
whereWatchCom(){
|
||||
// 需要重新查询
|
||||
let { loadtime } = this;
|
||||
if (loadtime !== "manual") {
|
||||
let getCloudDataDebounce = () =>{
|
||||
this.refresh({
|
||||
needIncludePoints: true
|
||||
});
|
||||
}
|
||||
debounce(getCloudDataDebounce, 200);
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
whereWatchCom(){
|
||||
let { where, collection } = this;
|
||||
return JSON.stringify({ where, collection })
|
||||
},
|
||||
widthCom() {
|
||||
let { width } = this;
|
||||
return !isNaN(width) ? `${width}rpx` : width;
|
||||
},
|
||||
heightCom() {
|
||||
let { height } = this;
|
||||
return !isNaN(height) ? `${height}rpx` : height;
|
||||
},
|
||||
styleCom() {
|
||||
let {
|
||||
widthCom,
|
||||
heightCom
|
||||
} = this;
|
||||
let style = "";
|
||||
if (widthCom) {
|
||||
style += `width:${widthCom};`;
|
||||
}
|
||||
if (heightCom) {
|
||||
style += `height:${heightCom};`;
|
||||
}
|
||||
return style;
|
||||
},
|
||||
latitudeCom(){
|
||||
let { latitude, defaultLatitude } = this;
|
||||
return (latitude || latitude === 0) ? latitude : defaultLatitude;
|
||||
},
|
||||
longitudeCom(){
|
||||
let { longitude, defaultLongitude } = this;
|
||||
return (longitude || longitude === 0) ? longitude : defaultLongitude;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
87
uniapp04/uni_modules/unicloud-map/package.json
Normal file
87
uniapp04/uni_modules/unicloud-map/package.json
Normal file
@ -0,0 +1,87 @@
|
||||
{
|
||||
"id": "unicloud-map",
|
||||
"displayName": "unicloud-map 云端一体地图组件",
|
||||
"version": "1.2.0",
|
||||
"description": "主要用于显示数据库里的自定义POI,渲染在地图上,支持静态POI和动态POI",
|
||||
"keywords": [
|
||||
"unicloud-map",
|
||||
"自定义POI"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "unicloud-template-page",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "插件不采集任何数据",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [
|
||||
"uni-map-common"
|
||||
],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y",
|
||||
"alipay": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y",
|
||||
"app-harmony": "u",
|
||||
"app-uvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "n",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "u",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
uniapp04/uni_modules/unicloud-map/pages/index/index.vue
Normal file
9
uniapp04/uni_modules/unicloud-map/pages/index/index.vue
Normal file
@ -0,0 +1,9 @@
|
||||
<!-- 此页面仅为发布插件时强制需要一个页面,无其他作用 -->
|
||||
<template>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
29
uniapp04/uni_modules/unicloud-map/readme.md
Normal file
29
uniapp04/uni_modules/unicloud-map/readme.md
Normal file
@ -0,0 +1,29 @@
|
||||
# unicloud-map
|
||||
|
||||
unicloud-map是云端一体组件,主要用于显示数据库里的自定义POI,渲染在地图上。具体可以实现如下功能:
|
||||
|
||||
1. 显示门店位置、景点位置、个人位置、车辆位置、活动举办地点等各种静态POI
|
||||
2. 外卖软件显示外卖员实时配送路线
|
||||
3. 打车软件显示司机到乘客上车点的实时路线
|
||||
4. 更多基于自定义POI实现的功能
|
||||
|
||||
## 使用教程
|
||||
|
||||
> 文档地址:[uni-app](https://uniapp.dcloud.net.cn/uniCloud/unicloud-map.html)
|
||||
|
||||
> 文档地址:[uni-app x](https://uniapp.dcloud.net.cn/uniCloud/unicloud-map-x.html)
|
||||
|
||||
## bug反馈地址
|
||||
|
||||
> 加群:[uni-map交流群](https://im.dcloud.net.cn/#/?joinGroup=64d62b106823de10406ad72f)
|
||||
|
||||
## 运行效果图:
|
||||
|
||||
静态POI
|
||||
|
||||

|
||||
|
||||
动态POI
|
||||
|
||||

|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"IndexName": "location",
|
||||
"MgoKeySchema": { "MgoIndexKeys": [{ "Name": "location", "Direction": "2dsphere" }], "MgoIsUnique": false }
|
||||
},
|
||||
{
|
||||
"IndexName": "visible",
|
||||
"MgoKeySchema": {"MgoIndexKeys": [{"Name": "visible","Direction": "1"}],"MgoIsUnique": false}
|
||||
},
|
||||
{
|
||||
"IndexName": "province-city-district",
|
||||
"MgoKeySchema": {"MgoIndexKeys": [{"Name": "province","Direction": "1"},{"Name": "city","Direction": "1"},{"Name": "district","Direction": "1"}],"MgoIsUnique": false}
|
||||
},
|
||||
{
|
||||
"IndexName": "create_date",
|
||||
"MgoKeySchema": {"MgoIndexKeys": [{"Name": "create_date","Direction": "1"}],"MgoIsUnique": false}
|
||||
},
|
||||
{
|
||||
"IndexName": "category",
|
||||
"MgoKeySchema": {"MgoIndexKeys": [{"Name": "category","Direction": "1"}],"MgoIsUnique": false}
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,88 @@
|
||||
{
|
||||
"bsonType": "object",
|
||||
"required": ["location", "title"],
|
||||
"permission": {
|
||||
"read": "doc.visible == true",
|
||||
"create": false,
|
||||
"update": false,
|
||||
"delete": false
|
||||
},
|
||||
"properties": {
|
||||
"_id": {
|
||||
"description": "ID,系统自动生成"
|
||||
},
|
||||
"visible": {
|
||||
"title": "是否显示",
|
||||
"bsonType": "bool",
|
||||
"description": "为true代表前端clientDB可直接查询 false则clientDB不可以查询"
|
||||
},
|
||||
"category": {
|
||||
"bsonType": "string",
|
||||
"title": "分类",
|
||||
"description": "用于区分显示在不同的场景地图下"
|
||||
},
|
||||
"type": {
|
||||
"bsonType": "string",
|
||||
"title": "类型",
|
||||
"description": "POI类型,可根据type自动匹配对应的icon,支持直接输入中文"
|
||||
},
|
||||
"icon": {
|
||||
"bsonType": "string",
|
||||
"title": "图标",
|
||||
"description": "支持https网络路径或本地绝对路径,如果传了icon则不再根据type去匹配icon"
|
||||
},
|
||||
"rotate": {
|
||||
"bsonType": "number",
|
||||
"title": "图标角度",
|
||||
"description": "POI图标的角度,需保证0°的图片方向应朝左(西) 故可得90° 朝上(北) 180° 朝右(东) 270° 朝下(南)"
|
||||
},
|
||||
"level": {
|
||||
"bsonType": "number",
|
||||
"title": "图标显示的层级",
|
||||
"description": "POI图标显示的层级,越高越现在在上面"
|
||||
},
|
||||
"location": {
|
||||
"title": "地理位置",
|
||||
"bsonType": "object",
|
||||
"description": "地理位置(包含经纬度)"
|
||||
},
|
||||
"title": {
|
||||
"bsonType": "string",
|
||||
"title": "名称",
|
||||
"description": "名称"
|
||||
},
|
||||
"address": {
|
||||
"bsonType": "string",
|
||||
"title": "地址",
|
||||
"description": "地址"
|
||||
},
|
||||
"tel": {
|
||||
"bsonType": "string",
|
||||
"title": "电话",
|
||||
"description": "电话"
|
||||
},
|
||||
"province": {
|
||||
"bsonType": "string",
|
||||
"title": "省",
|
||||
"description": "省"
|
||||
},
|
||||
"city": {
|
||||
"bsonType": "string",
|
||||
"title": "市",
|
||||
"description": "市"
|
||||
},
|
||||
"district": {
|
||||
"bsonType": "string",
|
||||
"title": "区/县",
|
||||
"description": "区/县"
|
||||
},
|
||||
"create_date": {
|
||||
"title": "创建时间",
|
||||
"bsonType": "timestamp",
|
||||
"description": "创建时间",
|
||||
"forceDefaultValue": {
|
||||
"$env": "now"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "database",
|
||||
"origin-plugin-dev-name": "unicloud-map",
|
||||
"origin-plugin-version": "1.2.0",
|
||||
"plugin-dev-name": "unicloud-map",
|
||||
"plugin-version": "1.2.0",
|
||||
"description": ""
|
||||
}
|
||||
Reference in New Issue
Block a user