├── pages ├── map │ ├── map.json │ ├── map.wxss │ ├── map.wxml │ └── map.js ├── map2 │ ├── map2.json │ ├── map2.wxss │ ├── map2.wxml │ └── map2.js ├── index │ ├── index.json │ ├── index.wxml │ ├── index.wxss │ └── index.js └── logs │ ├── logs.json │ ├── logs.wxss │ ├── logs.wxml │ └── logs.js ├── res ├── selected.png ├── collection.png ├── selected - 副本.png ├── collection - 副本.png ├── introduction-index.png ├── introduction-collect.png ├── introduction-location.png ├── introduction-search.png └── introduction-information.png ├── app.wxss ├── app.json ├── .gitattributes ├── utils └── util.js ├── app.js └── README.md /pages/map/map.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /pages/map2/map2.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /pages/index/index.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /pages/logs/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "查看启动日志" 3 | } -------------------------------------------------------------------------------- /res/selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/The---onE/SearchPOI/HEAD/res/selected.png -------------------------------------------------------------------------------- /res/collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/The---onE/SearchPOI/HEAD/res/collection.png -------------------------------------------------------------------------------- /res/selected - 副本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/The---onE/SearchPOI/HEAD/res/selected - 副本.png -------------------------------------------------------------------------------- /res/collection - 副本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/The---onE/SearchPOI/HEAD/res/collection - 副本.png -------------------------------------------------------------------------------- /res/introduction-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/The---onE/SearchPOI/HEAD/res/introduction-index.png -------------------------------------------------------------------------------- /res/introduction-collect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/The---onE/SearchPOI/HEAD/res/introduction-collect.png -------------------------------------------------------------------------------- /res/introduction-location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/The---onE/SearchPOI/HEAD/res/introduction-location.png -------------------------------------------------------------------------------- /res/introduction-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/The---onE/SearchPOI/HEAD/res/introduction-search.png -------------------------------------------------------------------------------- /res/introduction-information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/The---onE/SearchPOI/HEAD/res/introduction-information.png -------------------------------------------------------------------------------- /pages/logs/logs.wxss: -------------------------------------------------------------------------------- 1 | .log-list { 2 | display: flex; 3 | flex-direction: column; 4 | padding: 40rpx; 5 | } 6 | .log-item { 7 | margin: 10rpx; 8 | } 9 | -------------------------------------------------------------------------------- /pages/logs/logs.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{index + 1}}. {{log}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | .container { 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: space-between; 8 | padding: 200rpx 0; 9 | box-sizing: border-box; 10 | } 11 | -------------------------------------------------------------------------------- /pages/logs/logs.js: -------------------------------------------------------------------------------- 1 | //logs.js 2 | var util = require('../../utils/util.js') 3 | Page({ 4 | data: { 5 | logs: [] 6 | }, 7 | onLoad: function () { 8 | this.setData({ 9 | logs: (wx.getStorageSync('logs') || []).map(function (log) { 10 | return util.formatTime(new Date(log)) 11 | }) 12 | }) 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages":[ 3 | "pages/index/index", 4 | "pages/map/map", 5 | "pages/map2/map2", 6 | "pages/logs/logs" 7 | ], 8 | "window":{ 9 | "backgroundTextStyle":"light", 10 | "navigationBarBackgroundColor": "#fff", 11 | "navigationBarTitleText": "WeChat", 12 | "navigationBarTextStyle":"black" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{userInfo.nickName}} 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /utils/util.js: -------------------------------------------------------------------------------- 1 | function formatTime(date) { 2 | var year = date.getFullYear() 3 | var month = date.getMonth() + 1 4 | var day = date.getDate() 5 | 6 | var hour = date.getHours() 7 | var minute = date.getMinutes() 8 | var second = date.getSeconds() 9 | 10 | 11 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') 12 | } 13 | 14 | function formatNumber(n) { 15 | n = n.toString() 16 | return n[1] ? n : '0' + n 17 | } 18 | 19 | module.exports = { 20 | formatTime: formatTime 21 | } 22 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /**index.wxss**/ 2 | .userinfo { 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | } 7 | 8 | .userinfo-avatar { 9 | width: 128rpx; 10 | height: 128rpx; 11 | margin: 20rpx; 12 | border-radius: 50%; 13 | } 14 | 15 | .userinfo-nickname { 16 | color: #aaa; 17 | } 18 | 19 | .map { 20 | margin-top: 50rpx; 21 | } 22 | 23 | .button-map { 24 | margin-top: 20rpx; 25 | background-color: #09bb07; 26 | color: #ffffff; 27 | } 28 | 29 | .button-map2 { 30 | margin-top: 50rpx; 31 | background-color: #09bb07; 32 | color: #ffffff; 33 | } -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | 3 | //获取LeanCloud对象 4 | const AV = require('../../libs/av-weapp.js'); 5 | 6 | //获取应用实例 7 | var app = getApp() 8 | Page({ 9 | data: { 10 | userInfo: {} 11 | }, 12 | //事件处理函数 13 | bindViewTap: function() { 14 | wx.navigateTo({ 15 | url: '../logs/logs' 16 | }) 17 | }, 18 | //打开地图 19 | openMapTap: function () { 20 | wx.navigateTo({ 21 | url: '../map/map' 22 | }) 23 | }, 24 | //打开地图(旧) 25 | openMap2Tap: function () { 26 | wx.navigateTo({ 27 | url: '../map2/map2' 28 | }) 29 | }, 30 | onLoad: function () { 31 | var that = this 32 | //调用应用实例的方法获取全局数据 33 | app.getUserInfo(function(userInfo){ 34 | //更新数据 35 | that.setData({ 36 | userInfo:userInfo 37 | }) 38 | }) 39 | } 40 | }) 41 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | //调用API从本地缓存中获取数据 5 | var logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | }, 9 | getUserInfo:function(cb){ 10 | var that = this 11 | if(this.globalData.userInfo){ 12 | typeof cb == "function" && cb(this.globalData.userInfo) 13 | }else{ 14 | //调用登录接口 15 | wx.login({ 16 | success: function () { 17 | wx.getUserInfo({ 18 | success: function (res) { 19 | that.globalData.userInfo = res.userInfo 20 | typeof cb == "function" && cb(that.globalData.userInfo) 21 | } 22 | }) 23 | } 24 | }) 25 | } 26 | }, 27 | globalData:{ 28 | userInfo:null 29 | } 30 | }) 31 | 32 | //初始化LeanCloud对象 33 | const AV = require('./libs/av-weapp.js'); 34 | AV.init({ 35 | appId: 'fYrPgAK53LHnhNxkmvuCDNtp-gzGzoHsz', 36 | appKey: 'rjsDBgksFXhcrW7mSXb5nOct', 37 | }); -------------------------------------------------------------------------------- /pages/map2/map2.wxss: -------------------------------------------------------------------------------- 1 | /* pages/map/map.wxss */ 2 | 3 | page { 4 | width: 100%; 5 | height: 100%; 6 | background-color: #e3edcd; 7 | } 8 | 9 | .board { 10 | width: 100%; 11 | height: 100%; 12 | } 13 | 14 | .map { 15 | width: 100%; 16 | height: 88%; 17 | } 18 | 19 | .view-modal { 20 | display: flex; 21 | flex-direction: column; 22 | } 23 | 24 | .input-modal { 25 | text-align: center; 26 | font-size: 20pt; 27 | margin: 32rpx; 28 | } 29 | 30 | .input-modal-s { 31 | font-size: 16pt; 32 | margin: 40rpx; 33 | } 34 | 35 | .text-modal { 36 | text-align: center; 37 | font-size: 20pt; 38 | margin: 16rpx; 39 | } 40 | 41 | .text-modal-s { 42 | font-size: 16pt; 43 | margin: 12rpx; 44 | } 45 | 46 | .radio-group-modal { 47 | text-align: center; 48 | } 49 | 50 | .view-search { 51 | display: flex; 52 | height: 6%; 53 | } 54 | 55 | .view-search { 56 | display: flex; 57 | height: 6%; 58 | } 59 | 60 | .input-search { 61 | flex-basis: 64%; 62 | height: 80rpx; 63 | background-color: #FFFFFF; 64 | } 65 | -------------------------------------------------------------------------------- /pages/map/map.wxss: -------------------------------------------------------------------------------- 1 | /* pages/map/map.wxss */ 2 | 3 | page { 4 | width: 100%; 5 | height: 100%; 6 | background-color: #e3edcd; 7 | } 8 | 9 | .board { 10 | width: 100%; 11 | height: 100%; 12 | } 13 | 14 | .map { 15 | /* width: 100%; 在js中onLoad方法设置 */ 16 | /* height: 88%; 在js中onLoad方法设置 */ 17 | } 18 | 19 | .view-modal { 20 | display: flex; 21 | flex-direction: column; 22 | } 23 | 24 | .input-modal { 25 | text-align: center; 26 | font-size: 20pt; 27 | margin: 32rpx; 28 | } 29 | 30 | .input-modal-s { 31 | font-size: 16pt; 32 | margin: 40rpx; 33 | } 34 | 35 | .text-modal { 36 | text-align: center; 37 | font-size: 20pt; 38 | margin: 16rpx; 39 | } 40 | 41 | .text-modal-s { 42 | font-size: 16pt; 43 | margin: 12rpx; 44 | } 45 | 46 | .radio-group-modal { 47 | text-align: center; 48 | } 49 | 50 | .view-search { 51 | display: flex; 52 | height: 6%; 53 | } 54 | 55 | .view-search { 56 | display: flex; 57 | height: 6%; 58 | } 59 | 60 | .input-search { 61 | flex-basis: 64%; 62 | height: 80rpx; 63 | background-color: #FFFFFF; 64 | } 65 | 66 | button { 67 | background-color: #09bb07; 68 | color: #ffffff; 69 | } 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 微信小程序地图选点收藏Demo 2 | ### 本程序是用于测试微信小程序地图功能及与LeanCloud数据存储管理功能的Demo。 3 | ### 本程序目前未添加AppID无法进行真机调试,欢迎已经申请到资格的朋友测试反馈。 4 | ##### 本程序数据管理功能基于LeanCloud提供的数据存储功能,在开发程序前需要在云端创建应用,并将对应信息初始化到程序中 5 | ## 代码结构 6 | 将本程序代码直接使用微信开发者工具打开即可编译调试 7 | ### 根目录 8 | #### app.js 9 | 初始化小程序,获取用户信息等基本信息,**初始化LeanCloud对象,设置对应的信息** 10 | #### app.json 11 | 设置基本配置项,**pages属性设置程序所有页面** 12 | #### app.wxss 13 | 公共样式库 14 | ### libs目录 15 | 引入的外部文件 16 | ### res目录 17 | 图片等资源文件 18 | ### utils目录 19 | 常用工具文件 20 | ### pages目录 21 | .wxml文件:基本页面,类似html文件 22 | .wxss文件:样式文件,类似css文件 23 | .js文件:脚本文件 24 | .json文件:数据文件 25 | #### index目录 26 | 首页,引导打开地图页面 27 | #### logs目录 28 | 自动生成的用于显示日志的调试文件 29 | #### map目录 30 | 地图功能的主目录,首页选择【打开地图】选项进入,集成程序的主要功能,包括显示地图、定位、选点、收藏等主要功能 31 | 选点方式为地图中心为选定点,拖动地图选点。点击地图打开微信选点工具直接移动到特定点 32 | #### map2目录 33 | 地图页面的备份目录,首页选择【打开地图(旧)】选项进入,基本功能与新地图一致,选点方式为另一方式 34 | 选点方式为点击地图打开微信选点工具选点 35 | ## 实现功能 36 | ### 首页 37 | 可点击按钮进入地图页,两个地图页的选点方式不同,其余功能一致 38 | ![image](https://github.com/The---onE/SearchPOI/blob/master/res/introduction-index.png) 39 | ### 定位 40 | 进入地图页后程序默认直接开始定位,定位成功后在当前位置显示标记,并将地图中心设为当前位置 41 | ![image](https://github.com/The---onE/SearchPOI/blob/master/res/introduction-location.png) 42 | ### 添加收藏 43 | 地图定位成功后可进行选点,新旧版本分别为拖动地图选点和打开微信选点工具选点,选点成功后可点击添加收藏按钮弹出添加收藏对话框,输入对应信息后可将选定点及相关信息添加到收藏,收藏信息转化为LeanStorage对象保存至LeanCloud服务器 44 | ![image](https://github.com/The---onE/SearchPOI/blob/master/res/introduction-collect.png) 45 | ### 搜索收藏 46 | 地图上会为收藏点显示标记,在没有搜索的情况下,会默认显示所有公开的收藏,输入搜索条件并点击搜索按钮后会进行搜索,搜索规则为:可以搜索到所有标题或类型**包含**搜索条件的**公开**收藏**及**所有标题或类型与搜索条件**完全一致**的**私密**收藏 47 | ![image](https://github.com/The---onE/SearchPOI/blob/master/res/introduction-search.png) 48 | ### 收藏信息 49 | 点击地图上的收藏标记会打开收藏信息对话框,其中包含收藏的详细信息 50 | ![image](https://github.com/The---onE/SearchPOI/blob/master/res/introduction-information.png) 51 | -------------------------------------------------------------------------------- /pages/map2/map2.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 24 | 31 | -------------------------------------------------------------------------------- /pages/map/map.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 25 | 32 | -------------------------------------------------------------------------------- /pages/map2/map2.js: -------------------------------------------------------------------------------- 1 | // pages/map/map.js 2 | // 获取应用实例 3 | var app = getApp(); 4 | 5 | // 获取LeanCloud对象 6 | const AV = require('../../libs/av-weapp.js'); 7 | 8 | var LOCATION_TYPE = 'gcj02'; // 定位类型,gcj02 返回可用于地图的坐标,wgs84 返回 gps 坐标 9 | var DEFAULT_SCALA = 16; // 默认缩放,范围5-18 10 | 11 | var location = {}; // 定位坐标 12 | var LOCATION_MARKER_ID = 0; // 定位点ID 13 | var locationMarker = { id: LOCATION_MARKER_ID }; // 定位标记 14 | var LOCATION_MARKER_RES = '/res/location.png'; // 定位标记图标 15 | 16 | var selected; // 选取坐标 17 | var SELECTED_MARKER_ID = 1; // 选取点ID 18 | var selectedMarker = { id: SELECTED_MARKER_ID, }; // 选取标记 19 | var SELECTED_MARKER_RES = '/res/selected.png'; // 选取标记图标 20 | 21 | // 添加收藏对话框 22 | var collectTitle; // 标题 23 | var collectType; // 类型 24 | var collectContent; // 内容 25 | var PRIVACY_PRIVATE = 1; // 私密 26 | var PRIVACY_PUBLIC = 0; // 公开 27 | var privacy = PRIVACY_PRIVATE; // 私密性 28 | 29 | var COLLECTION_MARKER_RES = '/res/collection.png'; // 收藏标记图标 30 | 31 | var search; //搜索框文本 32 | 33 | var markers = [ 34 | // 定位标记 35 | locationMarker, 36 | // 选取点ID 37 | selectedMarker, 38 | ]; // 地图标记 39 | 40 | Page({ 41 | data: { 42 | collectModalHidden: true, // 添加收藏对话框隐藏 43 | collectionModalHidden: true, // 收藏信息对话框隐藏 44 | value: '', // 输入框清空 45 | privacy: [ 46 | { name: '私密', value: PRIVACY_PRIVATE, checked: 'true' }, 47 | { name: '公开', value: PRIVACY_PUBLIC }, 48 | ] // 私密性单选框选项 49 | }, 50 | 51 | // 显示对话框 52 | showPrompt: function (content) { 53 | wx.showModal({ 54 | title: '提示', 55 | content: content, 56 | }); 57 | }, 58 | 59 | // 定位 60 | getLocation: function () { 61 | var that = this; 62 | // 开始定位 63 | wx.getLocation({ 64 | type: LOCATION_TYPE, // 默认为 wgs84 返回 gps 坐标,gcj02 返回可用于 wx.openLocation 的坐标 65 | success: function (res) { 66 | // 定位成功 67 | // 定位坐标 68 | location = { 69 | latitude: res.latitude, 70 | longitude: res.longitude, 71 | } 72 | // // 更新定位标记 73 | // locationMarker = { 74 | // id: LOCATION_MARKER_ID, 75 | // title: 'location', 76 | // iconPath: LOCATION_MARKER_RES, 77 | // latitude: res.latitude, 78 | // longitude: res.longitude, 79 | // width: 100, 80 | // height: 100, 81 | // }; 82 | // markers[LOCATION_MARKER_ID] = locationMarker; 83 | //若尚未选定点,则把当前定位作为选定点 84 | if (!selected) { 85 | selected = location; 86 | } 87 | that.moveSelectedMarker(selected); 88 | // 更新数据 89 | that.setData({ 90 | position: location, // 定位坐标 91 | scala: DEFAULT_SCALA, // 缩放比例[5-18] 92 | markers: markers, // 标记点 93 | }); 94 | }, 95 | fail: function () { 96 | // 定位失败 97 | that.showPrompt('定位失败'); 98 | }, 99 | complete: function () { 100 | // 定位完成 101 | } 102 | }) 103 | }, 104 | 105 | // 加载收藏标记 106 | showCollection: function () { 107 | var that = this; 108 | var query = new AV.Query('Collection'); 109 | // 添加条件后,开始查询 110 | query.equalTo('privacy', PRIVACY_PUBLIC); // 只显示公开的收藏 111 | query.find() 112 | .then(function (data) { 113 | // 查询成功 114 | that.addCollectionMarker(data); 115 | }, function (error) { 116 | // 查询失败 117 | console.error('Failed to save in LeanCloud:' + error.message); 118 | that.showPrompt('加载收藏失败'); 119 | }); 120 | }, 121 | // 搜索框输入事件 122 | onSearchInput: function (e) { 123 | search = e.detail.value; 124 | }, 125 | // 搜索按钮点击事件 126 | onSearchTap: function (e) { 127 | if (!search || search.length == 0) { 128 | this.showPrompt('搜索值不能为空'); 129 | return; 130 | } 131 | var that = this; 132 | // 新建查询 133 | // 标题中包含搜索值 134 | var titleLike = new AV.Query('Collection'); 135 | titleLike.contains('title', search); 136 | // 类型中包含搜索值 137 | var typeLike = new AV.Query('Collection'); 138 | typeLike.contains('type', search); 139 | // 公开类型 140 | var publicType = new AV.Query('Collection'); 141 | publicType.equalTo('privacy', PRIVACY_PUBLIC); 142 | // 公开条件 143 | var publicCondition = AV.Query.or(titleLike, typeLike); 144 | // 公开搜索 145 | var publicQuery = AV.Query.and(publicType, publicCondition); 146 | 147 | // 标题等于搜索值 148 | var titleEqual= new AV.Query('Collection'); 149 | titleEqual.equalTo('title', search); 150 | // 类型等于搜索值 151 | var typeEqual = new AV.Query('Collection'); 152 | typeEqual.equalTo('type', search); 153 | // 私密类型 154 | var privateType = new AV.Query('Collection'); 155 | privateType.equalTo('privacy', PRIVACY_PRIVATE); 156 | // 私密条件:标题完全匹配或类型完全匹配 157 | var privateCondition = AV.Query.or(titleEqual, typeEqual); 158 | // 私密搜索 159 | var privateQuery = AV.Query.and(privateType, privateCondition); 160 | 161 | // 公开搜索和私密搜索都显示 162 | var query = AV.Query.or(publicQuery, privateQuery); 163 | query.find() 164 | .then(function (data) { 165 | // 查询成功 166 | // 清空原收藏标记 167 | that.clearCollectionMarker(); 168 | // 添加收藏标记 169 | that.addCollectionMarker(data); 170 | }, function (error) { 171 | // 查询失败 172 | console.error('Failed to save in LeanCloud:' + error.message); 173 | that.showPrompt('加载收藏失败'); 174 | }); 175 | }, 176 | // 取消搜索按钮点击事件 177 | onCancelSearchTap: function (e) { 178 | var that = this; 179 | // 清空原收藏标记 180 | this.clearCollectionMarker(); 181 | // 清空搜索框 182 | this.setData({ 183 | searchValue: '', 184 | markers: markers, 185 | }); 186 | search = ''; 187 | var query = new AV.Query('Collection'); 188 | // 添加条件后,开始查询 189 | query.equalTo('privacy', PRIVACY_PUBLIC); // 只显示公开的收藏 190 | query.find() 191 | .then(function (data) { 192 | // 添加收藏标记 193 | that.addCollectionMarker(data); 194 | }, function (error) { 195 | // 查询失败 196 | console.error('Failed to save in LeanCloud:' + error.message); 197 | that.showPrompt('加载收藏失败'); 198 | }); 199 | }, 200 | 201 | // 地图非标记点点击事件 202 | onMapTap: function (e) { 203 | var that = this; 204 | // 显示加载中 205 | wx.showToast({ 206 | title: '加载选取工具', 207 | icon: 'loading', 208 | duration: 2000 209 | }); 210 | // 跳转选取位置 211 | wx.chooseLocation({ 212 | success: function (res) { 213 | // 选取成功 214 | // 更新选取点 215 | selected = { 216 | latitude: res.latitude, 217 | longitude: res.longitude, 218 | }; 219 | // 更新选取点标记 220 | that.moveSelectedMarker(selected); 221 | }, 222 | cancel: function () { 223 | // 选取取消 224 | }, 225 | fail: function () { 226 | // 选取失败 227 | that.showPrompt('选取失败'); 228 | }, 229 | complete: function () { 230 | // 选取完成 231 | } 232 | }) 233 | }, 234 | 235 | // 标记点点击事件 236 | onMarkerTap: function (e) { 237 | // 定位标记 238 | if (e.markerId == LOCATION_MARKER_ID) { 239 | wx.showToast({ 240 | title: '当前定位', 241 | icon: 'success', 242 | }); 243 | } else if (e.markerId == SELECTED_MARKER_ID) { 244 | // 选取标记 245 | wx.showToast({ 246 | title: '选取位置', 247 | icon: 'success', 248 | }); 249 | } else { 250 | // 收藏标记 251 | var marker = markers[e.markerId]; 252 | var collection = { 253 | title: marker.title, 254 | type: marker.type, 255 | content: marker.content, 256 | }; 257 | // 弹出添加收藏对话框 258 | this.setData({ 259 | collectionModalHidden: false, 260 | collection: collection 261 | }); 262 | } 263 | }, 264 | // 点击收藏信息对话框确认按钮 265 | onCollectionTap: function () { 266 | this.setData({ 267 | collectionModalHidden: true, 268 | }); 269 | }, 270 | 271 | // 点击添加收藏按钮事件 272 | onCollectTap: function () { 273 | if (!selected) { 274 | this.showPrompt('还未选取点') 275 | return; 276 | } 277 | // 弹出添加收藏对话框 278 | this.setData({ 279 | collectModalHidden: false 280 | }); 281 | }, 282 | // 点击确认添加收藏事件 283 | onConfirmCollectTap: function () { 284 | var that = this; 285 | if (!selected) { 286 | that.showPrompt('还未选取点'); 287 | return; 288 | } 289 | // 输入校验 290 | if (!collectTitle || collectTitle.length == 0) { 291 | that.showPrompt('标题不能为空'); 292 | return; 293 | } 294 | if (!collectType || collectType.length == 0) { 295 | that.showPrompt('类型不能为空'); 296 | return; 297 | } 298 | if (!collectContent) { 299 | collectContent = ''; 300 | } 301 | 302 | var collection = AV.Object.extend('Collection'); 303 | var col = new collection(); 304 | col.set('title', collectTitle); 305 | col.set('type', collectType); 306 | col.set('content', collectContent); 307 | col.set('latitude', selected.latitude); 308 | col.set('longitude', selected.longitude); 309 | col.set('privacy', privacy); 310 | col.save().then(function (success) { 311 | // 添加成功 312 | that.showPrompt('添加成功'); 313 | markers.push({ 314 | id: markers.length, 315 | title: collectTitle, 316 | iconPath: COLLECTION_MARKER_RES, 317 | latitude: selected.latitude, 318 | longitude: selected.longitude, 319 | width: 40, 320 | height: 40 321 | }); 322 | that.setData({ 323 | markers: markers, 324 | }); 325 | // 隐藏添加收藏对话框 326 | that.setData({ 327 | collectModalHidden: true, 328 | value: '', // 清空输入框内容 329 | }); 330 | }, function (error) { 331 | // 添加失败 332 | console.error('Failed to save in LeanCloud:' + error.message); 333 | that.showPrompt('添加失败'); 334 | }); 335 | }, 336 | // 点击取消添加收藏事件 337 | onCancelCollectTap: function () { 338 | //隐藏添加收藏对话框 339 | this.setData({ 340 | collectModalHidden: true, 341 | value: '', // 清空输入框内容 342 | }); 343 | }, 344 | // 标题输入事件 345 | onCollectTitleInput: function (e) { 346 | collectTitle = e.detail.value; 347 | }, 348 | // 类型输入事件 349 | onCollectTypeInput: function (e) { 350 | collectType = e.detail.value; 351 | }, 352 | // 内容输入事件 353 | onCollectContentInput: function (e) { 354 | collectContent = e.detail.value; 355 | }, 356 | // 私密性单选框更改事件 357 | onPrivacyChange: function (e) { 358 | privacy = parseInt(e.detail.value); 359 | }, 360 | 361 | // 将选取点标记移至指定点 362 | moveSelectedMarker: function (point) { 363 | // 更新选取点标记 364 | selectedMarker = { 365 | id: SELECTED_MARKER_ID, 366 | title: 'selected', 367 | iconPath: SELECTED_MARKER_RES, 368 | latitude: point.latitude, 369 | longitude: point.longitude, 370 | width: 40, 371 | height: 40 372 | }; 373 | markers[SELECTED_MARKER_ID] = selectedMarker; 374 | this.setData({ 375 | markers: markers 376 | }); 377 | }, 378 | 379 | // 将收藏点添加到标记中 380 | addCollectionMarker: function (colFromCloud) { 381 | for (var i = 0; i < colFromCloud.length; ++i) { 382 | // 添加标记 383 | markers.push({ 384 | id: markers.length, 385 | title: colFromCloud[i].get('title'), 386 | iconPath: COLLECTION_MARKER_RES, 387 | latitude: colFromCloud[i].get('latitude'), 388 | longitude: colFromCloud[i].get('longitude'), 389 | width: 40, 390 | height: 40, 391 | type: colFromCloud[i].get('type'), 392 | content: colFromCloud[i].get('content'), 393 | }); 394 | } 395 | this.setData({ 396 | markers: markers, 397 | }); 398 | }, 399 | 400 | // 清空收藏标记 401 | clearCollectionMarker: function () { 402 | markers = [ 403 | locationMarker, 404 | selectedMarker, 405 | ]; 406 | this.setData({ 407 | markers: markers, 408 | }); 409 | }, 410 | 411 | onLoad: function (options) { 412 | // 页面初始化 options为页面跳转所带来的参数 413 | }, 414 | onReady: function () { 415 | // 页面渲染完成 416 | this.getLocation(); // 定位 417 | this.showCollection(); // 显示收藏点 418 | }, 419 | onShow: function () { 420 | // 页面显示 421 | }, 422 | onHide: function () { 423 | // 页面隐藏 424 | }, 425 | onUnload: function () { 426 | // 页面关闭 427 | } 428 | }) -------------------------------------------------------------------------------- /pages/map/map.js: -------------------------------------------------------------------------------- 1 | // pages/map/map.js 2 | // 获取应用实例 3 | var app = getApp(); 4 | 5 | // 获取LeanCloud对象 6 | const AV = require('../../libs/av-weapp.js'); 7 | 8 | var height; // 屏幕高度,在onLoad中获取 9 | var width; // 屏幕宽度,在onLoad中获取 10 | 11 | var mapCtx; // 地图上下文,用于获取或设置中心坐标,在定位成功后初始化 12 | 13 | var mapHeight; // 地图控件高度,在onLoad获取页面高度后计算 14 | var mapWidth; // 地图控件宽度,在onLoad获取页面宽度后计算 15 | var MAP_HEIGHT_SCALA = 0.87; // 高度占总高度比例 16 | var MAP_WIDTH_SCALA = 1; // 宽度占总宽度比例 17 | 18 | var CENTER_CONTROL_ID = 0; // 中心控件ID 19 | var centerControl = { id: CENTER_CONTROL_ID, }; // 中心控件 20 | var CENTER_CONTROL_RES = '/res/selected.png'; // 中心控件图标 21 | 22 | var LOCATION_TYPE = 'gcj02'; // 定位类型,gcj02 返回可用于地图的坐标,wgs84 返回 gps 坐标 23 | var DEFAULT_SCALA = 16; // 默认缩放,范围5-18 24 | 25 | var location = {}; // 定位坐标 26 | var LOCATION_MARKER_ID = 0; // 定位点ID 27 | var locationMarker = { id: LOCATION_MARKER_ID }; // 定位标记 28 | var LOCATION_MARKER_RES = '/res/location.png'; // 定位标记图标 29 | 30 | var SELECTED_MARKER_ID = 1; // 选取点ID 31 | var selectedMarker = { id: SELECTED_MARKER_ID, }; // 选取标记 32 | 33 | // 添加收藏对话框 34 | var collectTitle; // 标题 35 | var collectType; // 类型 36 | var collectContent; // 内容 37 | var PRIVACY_PRIVATE = 1; // 私密 38 | var PRIVACY_PUBLIC = 0; // 公开 39 | var privacy = PRIVACY_PRIVATE; // 私密性 40 | 41 | var COLLECTION_MARKER_RES = '/res/collection.png'; // 收藏标记图标 42 | 43 | var search; // 搜索框文本 44 | 45 | var markers = [ 46 | // 定位标记 47 | locationMarker, 48 | // 选取点ID 49 | selectedMarker, 50 | ]; // 地图标记 51 | 52 | var controls = [ 53 | // 中心控件 54 | centerControl, 55 | ]; // 地图控件 56 | 57 | Page({ 58 | data: { 59 | collectModalHidden: true, // 添加收藏对话框隐藏 60 | collectionModalHidden: true, // 收藏信息对话框隐藏 61 | value: '', // 输入框清空 62 | privacy: [ 63 | { name: '私密', value: PRIVACY_PRIVATE, checked: 'true' }, 64 | { name: '公开', value: PRIVACY_PUBLIC }, 65 | ] // 私密性单选框选项 66 | }, 67 | 68 | // 显示对话框 69 | showPrompt: function (content) { 70 | wx.showModal({ 71 | title: '提示', 72 | content: content, 73 | showCancel: false, 74 | }); 75 | }, 76 | 77 | // 定位 78 | getLocation: function () { 79 | var that = this; 80 | // 开始定位 81 | wx.getLocation({ 82 | type: LOCATION_TYPE, // 默认为 wgs84 返回 gps 坐标,gcj02 返回可用于 wx.openLocation 的坐标 83 | success: function (res) { 84 | // 定位成功 85 | // 定位坐标 86 | location = { 87 | latitude: res.latitude, 88 | longitude: res.longitude, 89 | } 90 | // // 更新定位标记 91 | // locationMarker = { 92 | // id: LOCATION_MARKER_ID, 93 | // title: 'location', 94 | // iconPath: LOCATION_MARKER_RES, 95 | // latitude: res.latitude, 96 | // longitude: res.longitude, 97 | // width: 100, 98 | // height: 100, 99 | // }; 100 | // markers[LOCATION_MARKER_ID] = locationMarker; 101 | that.addCenterControl(); // 添加中心控件 102 | // 更新数据 103 | that.setData({ 104 | position: location, // 定位坐标 105 | scala: DEFAULT_SCALA, // 缩放比例[5-18] 106 | markers: markers, // 标记点 107 | }); 108 | mapCtx = wx.createMapContext('map'); 109 | }, 110 | fail: function () { 111 | // 定位失败 112 | that.showPrompt('定位失败'); 113 | }, 114 | complete: function () { 115 | // 定位完成 116 | } 117 | }) 118 | }, 119 | 120 | // 添加地图中心控件 121 | addCenterControl: function () { 122 | centerControl = { 123 | id: CENTER_CONTROL_ID, 124 | iconPath: CENTER_CONTROL_RES, 125 | position: { 126 | left: mapWidth / 2 - 40 / 2, 127 | top: mapHeight / 2 - 40, 128 | width: mapWidth * 0.1, 129 | height: mapWidth * 0.1 130 | }, // 根据地图宽高和图片尺寸计算位置 131 | clickable: true 132 | } 133 | controls[CENTER_CONTROL_ID] = centerControl; 134 | this.setData({ 135 | controls: controls, 136 | }) 137 | }, 138 | 139 | // 加载收藏标记 140 | showCollection: function () { 141 | var that = this; 142 | var query = new AV.Query('Collection'); 143 | // 添加条件后,开始查询 144 | query.equalTo('privacy', PRIVACY_PUBLIC); // 只显示公开的收藏 145 | query.find() 146 | .then(function (data) { 147 | // 查询成功 148 | that.addCollectionMarker(data); 149 | }, function (error) { 150 | // 查询失败 151 | console.error('Failed to save in LeanCloud:' + error.message); 152 | that.showPrompt('加载收藏失败'); 153 | }); 154 | }, 155 | // 搜索框输入事件 156 | onSearchInput: function (e) { 157 | search = e.detail.value; 158 | }, 159 | // 搜索按钮点击事件 160 | onSearchTap: function (e) { 161 | if (!search || search.length == 0) { 162 | this.showPrompt('搜索值不能为空'); 163 | return; 164 | } 165 | var that = this; 166 | // 新建查询 167 | // 标题中包含搜索值 168 | var titleLike = new AV.Query('Collection'); 169 | titleLike.contains('title', search); 170 | // 类型中包含搜索值 171 | var typeLike = new AV.Query('Collection'); 172 | typeLike.contains('type', search); 173 | // 公开类型 174 | var publicType = new AV.Query('Collection'); 175 | publicType.equalTo('privacy', PRIVACY_PUBLIC); 176 | // 公开条件 177 | var publicCondition = AV.Query.or(titleLike, typeLike); 178 | // 公开搜索 179 | var publicQuery = AV.Query.and(publicType, publicCondition); 180 | 181 | // 标题等于搜索值 182 | var titleEqual= new AV.Query('Collection'); 183 | titleEqual.equalTo('title', search); 184 | // 类型等于搜索值 185 | var typeEqual = new AV.Query('Collection'); 186 | typeEqual.equalTo('type', search); 187 | // 私密类型 188 | var privateType = new AV.Query('Collection'); 189 | privateType.equalTo('privacy', PRIVACY_PRIVATE); 190 | // 私密条件:标题完全匹配或类型完全匹配 191 | var privateCondition = AV.Query.or(titleEqual, typeEqual); 192 | // 私密搜索 193 | var privateQuery = AV.Query.and(privateType, privateCondition); 194 | 195 | // 公开搜索和私密搜索都显示 196 | var query = AV.Query.or(publicQuery, privateQuery); 197 | query.find() 198 | .then(function (data) { 199 | // 查询成功 200 | // 清空原收藏标记 201 | that.clearCollectionMarker(); 202 | // 添加收藏标记 203 | that.addCollectionMarker(data); 204 | }, function (error) { 205 | // 查询失败 206 | console.error('Failed to save in LeanCloud:' + error.message); 207 | that.showPrompt('加载收藏失败'); 208 | }); 209 | }, 210 | // 取消搜索按钮点击事件 211 | onCancelSearchTap: function (e) { 212 | var that = this; 213 | // 清空原收藏标记 214 | this.clearCollectionMarker(); 215 | // 清空搜索框 216 | this.setData({ 217 | searchValue: '', 218 | markers: markers, 219 | }); 220 | search = ''; 221 | var query = new AV.Query('Collection'); 222 | // 添加条件后,开始查询 223 | query.equalTo('privacy', PRIVACY_PUBLIC); // 只显示公开的收藏 224 | query.find() 225 | .then(function (data) { 226 | // 添加收藏标记 227 | that.addCollectionMarker(data); 228 | }, function (error) { 229 | // 查询失败 230 | console.error('Failed to save in LeanCloud:' + error.message); 231 | that.showPrompt('加载收藏失败'); 232 | }); 233 | }, 234 | 235 | // 地图非标记点点击事件 236 | onMapTap: function (e) { 237 | var that = this; 238 | // 显示加载中 239 | wx.showToast({ 240 | title: '加载选取工具', 241 | icon: 'loading', 242 | duration: 2000 243 | }); 244 | // 跳转选取位置 245 | wx.chooseLocation({ 246 | success: function (res) { 247 | // 选取成功 248 | var point = { 249 | latitude: res.latitude, 250 | longitude: res.longitude, 251 | }; 252 | that.setData({ 253 | position: point // 设置中心位置为选定点 254 | }); 255 | }, 256 | cancel: function () { 257 | // 选取取消 258 | }, 259 | fail: function () { 260 | // 选取失败 261 | // that.showPrompt('选取失败'); 262 | }, 263 | complete: function () { 264 | // 选取完成 265 | } 266 | }) 267 | }, 268 | 269 | // 标记点点击事件 270 | onMarkerTap: function (e) { 271 | // 定位标记 272 | if (e.markerId == LOCATION_MARKER_ID) { 273 | wx.showToast({ 274 | title: '当前定位', 275 | icon: 'success', 276 | }); 277 | } else if (e.markerId == SELECTED_MARKER_ID) { 278 | // 选取标记 279 | wx.showToast({ 280 | title: '选取位置', 281 | icon: 'success', 282 | }); 283 | } else { 284 | // 收藏标记 285 | var marker = markers[e.markerId]; 286 | var collection = { 287 | title: marker.title, 288 | type: marker.type, 289 | content: marker.content, 290 | }; 291 | // 弹出添加收藏对话框 292 | this.setData({ 293 | collectionModalHidden: false, 294 | collection: collection 295 | }); 296 | } 297 | }, 298 | // 点击收藏信息对话框确认按钮 299 | onCollectionTap: function () { 300 | this.setData({ 301 | collectionModalHidden: true, 302 | }); 303 | }, 304 | 305 | // 点击添加收藏按钮事件 306 | onCollectTap: function () { 307 | if (!mapCtx) { 308 | this.showPrompt('还未定位成功'); 309 | return; 310 | } 311 | // 弹出添加收藏对话框 312 | this.setData({ 313 | collectModalHidden: false 314 | }); 315 | }, 316 | // 点击确认添加收藏事件 317 | onConfirmCollectTap: function () { 318 | var that = this; 319 | if (!mapCtx) { 320 | that.showPrompt('还未定位成功'); 321 | return; 322 | } 323 | // 输入校验 324 | if (!collectTitle || collectTitle.length == 0) { 325 | that.showPrompt('标题不能为空'); 326 | return; 327 | } 328 | if (!collectType || collectType.length == 0) { 329 | that.showPrompt('类型不能为空'); 330 | return; 331 | } 332 | if (!collectContent) { 333 | collectContent = ''; 334 | } 335 | 336 | mapCtx.getCenterLocation({ 337 | success: function (center) { 338 | var collection = AV.Object.extend('Collection'); 339 | var col = new collection(); 340 | col.set('title', collectTitle); 341 | col.set('type', collectType); 342 | col.set('content', collectContent); 343 | col.set('latitude', center.latitude); 344 | col.set('longitude', center.longitude); 345 | col.set('privacy', privacy); 346 | col.save().then(function (success) { 347 | // 添加成功 348 | that.showPrompt('添加成功'); 349 | markers.push({ 350 | id: markers.length, 351 | title: collectTitle, 352 | iconPath: COLLECTION_MARKER_RES, 353 | latitude: center.latitude, 354 | longitude: center.longitude, 355 | width: mapWidth * 0.1, 356 | height: mapWidth * 0.1 357 | }); 358 | that.setData({ 359 | markers: markers, 360 | }); 361 | // 隐藏添加收藏对话框 362 | that.setData({ 363 | collectModalHidden: true, 364 | value: '', // 清空输入框内容 365 | }); 366 | }, function (error) { 367 | // 添加失败 368 | console.error('Failed to save in LeanCloud:' + error.message); 369 | that.showPrompt('添加失败'); 370 | }); 371 | } 372 | }) 373 | }, 374 | // 点击取消添加收藏事件 375 | onCancelCollectTap: function () { 376 | //隐藏添加收藏对话框 377 | this.setData({ 378 | collectModalHidden: true, 379 | value: '', // 清空输入框内容 380 | }); 381 | }, 382 | // 标题输入事件 383 | onCollectTitleInput: function (e) { 384 | collectTitle = e.detail.value; 385 | }, 386 | // 类型输入事件 387 | onCollectTypeInput: function (e) { 388 | collectType = e.detail.value; 389 | }, 390 | // 内容输入事件 391 | onCollectContentInput: function (e) { 392 | collectContent = e.detail.value; 393 | }, 394 | // 私密性单选框更改事件 395 | onPrivacyChange: function (e) { 396 | privacy = parseInt(e.detail.value); 397 | }, 398 | 399 | // 将收藏点添加到标记中 400 | addCollectionMarker: function (colFromCloud) { 401 | for (var i = 0; i < colFromCloud.length; ++i) { 402 | // 添加标记 403 | markers.push({ 404 | id: markers.length, 405 | title: colFromCloud[i].get('title'), 406 | iconPath: COLLECTION_MARKER_RES, 407 | latitude: colFromCloud[i].get('latitude'), 408 | longitude: colFromCloud[i].get('longitude'), 409 | width: mapWidth * 0.1, 410 | height: mapWidth * 0.1, 411 | type: colFromCloud[i].get('type'), 412 | content: colFromCloud[i].get('content'), 413 | }); 414 | } 415 | this.setData({ 416 | markers: markers, 417 | }); 418 | }, 419 | 420 | // 清空收藏标记 421 | clearCollectionMarker: function () { 422 | markers = [ 423 | locationMarker, 424 | selectedMarker, 425 | ]; 426 | this.setData({ 427 | markers: markers, 428 | }); 429 | }, 430 | 431 | onLoad: function (options) { 432 | // 页面初始化 options为页面跳转所带来的参数 433 | var that = this; 434 | // 获取系统信息 435 | wx.getSystemInfo({ 436 | success: function (res) { 437 | // 获取页面大小 438 | height = res.windowHeight; 439 | width = res.windowWidth; 440 | 441 | // 设置地图大小 442 | mapHeight = height * MAP_HEIGHT_SCALA; 443 | mapWidth = width * MAP_WIDTH_SCALA; 444 | that.setData({ 445 | mapHeight: mapHeight + 'px', 446 | mapWidth: mapWidth + 'px' 447 | }) 448 | } 449 | }); 450 | }, 451 | onReady: function () { 452 | // 页面渲染完成 453 | this.getLocation(); // 定位 454 | this.showCollection(); // 显示收藏点 455 | }, 456 | onShow: function () { 457 | // 页面显示 458 | }, 459 | onHide: function () { 460 | // 页面隐藏 461 | }, 462 | onUnload: function () { 463 | // 页面关闭 464 | } 465 | }) --------------------------------------------------------------------------------