| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548 |
- <template>
- <view class="box-picker_position">
- <view class="map_wp">
- <map id="map_20221212" class="picker-map" scale="12" min-scale="12" @regionchange="handleRegionchange" :latitude="position.latitude" :longitude="position.longitude" show-location='true' :polygons="polygons"></map>
- <view :class="['picker_map_location', animateLocation?'animated':'']"></view>
- </view>
- <view class="list-picker_position">
- <view class="hd">
- <input type="text" v-model="searchKey" class="input_text" placeholder="请输入搜索地点">
- <button class="btn-search" type="default" @click="searchPosition"><view class="picker-search"></view>搜索</button>
- </view>
- <view class="bd">
- <view v-for="(item,index) in searchlist" @click="changeSelectItem(index)" :class="['item',item.useable?'':'disabled']" :key="index">
- <view class="item-l">
- <view class="picker-address"></view>
- </view>
- <view class="item-c">
- <view class="title">{{item.title}}</view>
- <view class="address">{{item.address}}</view>
- </view>
- <view class="item-r">
- <view v-if="item.select" class="picker-checked"></view>
- </view>
- </view>
- </view>
- <view class="ft">
- <button @click="confirmSelect" :class="['btn-selected', canConfirm?'':'disabled']">确定选点</button>
- </view>
- </view>
- </view>
- </template>
- <script>
- var QQMapWX = require('./qqmap-wx-jssdk.js');
- var qqmapsdk,handleRegionchangeTimmer;
- export default {
- props:{
- polygons:{
- type:Array,
- default:[
- {
- points:[
- {
- latitude:'36.829066',
- longitude:'118.025761',
- },
- {
- latitude:'36.825012',
- longitude:'118.066702',
- },
- {
- latitude:'36.81161',
- longitude:'118.042681'
- },
- {
- latitude:'36.801964',
- longitude:'118.034875',
- },
- ],
- strokeWidth:1,
- strokeColor:'#ff000066',
- fillColor:'#ff000016'
- },
- {
- points:[
- {
- latitude:'36.817369',
- longitude:'118.001311',
- },
- {
- latitude:'36.808682',
- longitude:'118.010281',
- },{
- latitude:'36.805555',
- longitude:'117.996537',
- },
- ],
- strokeWidth:1,
- strokeColor:'#ff000066',
- fillColor:'#ff000016'
- },
- ]
- },
- qqmapsdkKey:{
- type:String,
- default:''
- },
- base_url:{
- type:String,
- default:''
- },
- sig:{
- type:String,
- default:''
- }
- },
- data() {
- return {
- canConfirm: false,
- animateLocation:false,
- isChangeSelectItem:false,
- searchKey:'',
- position:{
- latitude:'36.811995',
- longitude:'118.05539'
- },
- searchlist:[]
- };
- },
- mounted(){
- if(this.qqmapsdkKey==''){
- console.error('需要腾讯地图开发Key,申请地址:https://lbs.qq.com/miniProgram/jsSdk/jsSdkGuide/jsSdkOverview')
- return;
- }
- qqmapsdk = new QQMapWX({
- key:this.qqmapsdkKey,
- BASE_URL:this.base_url
- });
- let that = this;
- let needRegetLocation = true;
-
- if(uni.getStorageSync('mapPickerPosition')){
- let data = JSON.parse(uni.getStorageSync('mapPickerPosition'));
- if(new Date().getTime() < data.expireTime){
- needRegetLocation = false;
- that.position.latitude = data.position.latitude;
- that.position.longitude = data.position.longitude;
- that.init();
- }
- }
- if(needRegetLocation){
- uni.getLocation({
- cacheTimeout:1,
- accuracy:'best',
- type:'gcj02',
- isHighAccuracy:true,
- success:function(e){
- console.log(e);
- that.position.latitude = e.latitude;
- that.position.longitude = e.longitude;
- uni.setStorageSync('mapPickerPosition',JSON.stringify({
- expireTime: new Date().getTime() - 0 + 60*1000,
- position:{
- latitude: e.latitude,
- longitude: e.longitude
- }
- }))
- that.init();
- },
- fail:function(e){
- console.log(e);
- }
- })
- }
- // uni.onLocationChange(function(e){
- // console.log(11111,e);
- // that.position.latitude = e.latitude;
- // that.position.longitude = e.longitude;
- // })
- },
- methods:{
- init(){
- this.animateLocation = true;
- handleRegionchangeTimmer = setTimeout(()=>{
- this.renderList();
- },400)
- },
- renderList(){
- let that = this;
- let mapContext = uni.createMapContext("map_20221212", that);
- mapContext.getCenterLocation({
- success:function(rst){
- let options = {
- location:rst.latitude+','+rst.longitude,
- get_poi:1,
- poi_options: 'radius=1000',
- sig:that.sig,
- success:function(res){
- //console.log('xxxxx',res.result.pois)
- let isSelect = false;
- if(res.message == "query ok"){
- //that.$data.searchlist = [];
- that.$data.searchlist = [...res.result.pois];
- for(let i = 0;i<that.$data.searchlist.length;i++){
- that.$data.searchlist.useable = false;
- that.$data.searchlist.select = false;
- for(let j = 0;j < that.polygons.length;j++){
- if(that.isPointInPolygon(that.$data.searchlist[i].location.lat,that.$data.searchlist[i].location.lng,that.polygons[j].points)){
- that.$data.searchlist[i].useable = true;
- if(!isSelect){
- that.$data.searchlist[i].select = true;
- isSelect = true;
- }
- }
- }
-
- }
- setTimeout(()=>{
- that.animateLocation = false;
- },200)
- }
- if(isSelect){
- that.canConfirm = true;
- }else{
- that.canConfirm = false;
- }
- },
- fail:function(error){
- console.log(error);
- }
- };
- if(typeof(window)==='undefined'){
- delete options.sig;
- }
- if(options.sig===''){
- delete options.sig;
- }
- qqmapsdk.reverseGeocoder(options);
-
- }
- });
- },
- searchPosition(){
- if(this.searchKey.replace(/\s+/,'')==''){
- return;
- }
- let that = this;
- let searchOptions = {
- keyword:this.searchKey,
- location:{
- latitude:this.position.latitude,
- longitude:this.position.longitude
- },
- sig:that.sig,
- success:function(rst){
- let isSelect = false;
- if(rst.message == "query ok"){
- //that.$data.searchlist = [];
- that.$data.searchlist = [...rst.data];
- for(let i = 0;i<that.$data.searchlist.length;i++){
- that.$data.searchlist.useable = false;
- that.$data.searchlist.select = false;
- for(let j = 0;j < that.polygons.length;j++){
- if(that.isPointInPolygon(that.$data.searchlist[i].location.lat,that.$data.searchlist[i].location.lng,that.polygons[j].points)){
- that.$data.searchlist[i].useable = true;
- if(!isSelect){
- that.$data.searchlist[i].select = true;
- that.position.latitude = that.$data.searchlist[i].location.lat;
- that.position.longitude = that.$data.searchlist[i].location.lng;
- isSelect = true;
- }
- }
- }
-
- }
- }
- if(isSelect){
- that.canConfirm = true;
- }else{
- that.canConfirm = false;
- }
- }
- };
- if(typeof(window)==='undefined'){
- delete searchOptions.sig;
- }
- if(searchOptions.sig===''){
- delete searchOptions.sig;
- }
-
- qqmapsdk.search(searchOptions);
- },
- changeSelectItem(index){
- if(this.$data.searchlist[index].useable){
- for(let i = 0;i<this.$data.searchlist.length;i++){
- let temp = {};
- for(var key in this.$data.searchlist[i]){
- temp[key] = this.$data.searchlist[i][key];
- }
- if(i===index){
- temp.select = true;
- this.isChangeSelectItem = true;
- this.position.latitude = temp.location.lat;
- this.position.longitude = temp.location.lng;
- }else{
- temp.select = false;
- }
- this.$set(this.$data.searchlist,i,temp);
- }
- }
- },
- handleRegionchange(e){
- console.log(e);
- this.animateLocation = false;
- if(e.type=='end'){
- if(this.isChangeSelectItem){
- setTimeout(()=>{
- this.isChangeSelectItem = false;
- },100)
- return;
- }else{
- this.animateLocation = true;
- if(handleRegionchangeTimmer){
- clearTimeout(handleRegionchangeTimmer);
- }
- handleRegionchangeTimmer = setTimeout(()=>{
- this.renderList();
- },400)
-
- }
- }
- },
- isPointInPolygon(aLat, aLon, pointList){
- /*
- :param aLon: double 经度
- :param aLat: double 纬度
- :param pointList: list [{latitude: 22.22, longitude: 113.113}...] 多边形点的顺序需根据顺时针或逆时针,不能乱
- */
- var iSum = 0
- var iCount = pointList.length
-
- if(iCount < 3) {
- return false
- }
- // 待判断的点(x, y) 为已知值
- var y = aLat
- var x = aLon
- for(var i = 0; i < iCount; i++) {
- var y1 = pointList[i].latitude
- var x1 = pointList[i].longitude
- if(i == iCount - 1) {
- var y2 = pointList[0].latitude
- var x2 = pointList[0].longitude
- } else {
- var y2 = pointList[i + 1].latitude
- var x2 = pointList[i + 1].longitude
- }
- // 当前边的 2 个端点分别为 已知值(x1, y1), (x2, y2)
- if (((y >= y1) && (y < y2)) || ((y >= y2) && (y < y1))) {
- // y 界于 y1 和 y2 之间
- // 假设过待判断点(x, y)的水平直线和当前边的交点为(x_intersect, y_intersect),有y_intersect = y
- // 则有(2个相似三角形,公用顶角,宽/宽 = 高/高):|x1 - x2| / |x1 - x_intersect| = |y1 - y2| / |y1 - y|
- if (Math.abs(y1 - y2) > 0) {
- var x_intersect = x1 - ((x1 - x2) * (y1 - y)) / (y1 - y2);
- if(x_intersect < x) {
- iSum += 1
- }
- }
- }
- }
- if(iSum % 2 != 0) { //true就是在
- return true
- }else { //false就是不在
- return false
- }
- },
- confirmSelect(){
- if(this.canConfirm){
- this.searchlist.forEach(val=>{
- if(val.select){
- val.polygonIndex = [];
- this.polygons.forEach((polygon,index)=>{
- if(this.isPointInPolygon(val.location.lat,val.location.lng,polygon.points)){
- val.polygonIndex.push(index);
- }
- })
- uni.setStorageSync('polygonLocationPicker',JSON.stringify(val));
- this.$emit('selected',JSON.stringify(val));
- }
- })
- }
- }
- }
- }
- </script>
- <style scoped lang="scss">
- @keyframes bounceInDown {
- from,
- 20%,
- 53%,
- to {
- animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
- transform: translate3d(0, 0, 0);
- }
-
- 40%,
- 43% {
- animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
- transform: translate3d(0, -30rpx, 0) scaleY(1.1);
- }
-
- 70% {
- animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
- transform: translate3d(0, -15rpx, 0) scaleY(1.05);
- }
-
- 80% {
- transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
- transform: translate3d(0, 0, 0) scaleY(0.95);
- }
-
- 90% {
- transform: translate3d(0, -4rpx, 0) scaleY(1.02);
- }
- }
-
- .box-picker_position{
- height: 100%;
- width: 100%;
- background: #fff;
- display: flex;
- flex-flow: column;
- position: relative;
- overflow: hidden;
- box-sizing: border-box;
- }
- .map_wp{
- position: relative;
- width: 750rpx;
- height: 400rpx;
- }
- .picker_map_location{
- width: 60rpx;
- height: 60rpx;
- background-image: url("data:image/svg+xml,%3Csvg t='1670988557938' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='3498' width='200' height='200'%3E%3Cpath d='M511.968 0c-207.84 0-376.96 169.12-376.96 376.992 0 54.208 11.104 105.984 32.96 153.888 94.24 206.24 274.976 424 328.128 485.824 3.968 4.608 9.792 7.296 15.904 7.296s11.904-2.656 15.904-7.296c53.12-61.824 233.856-279.552 328.128-485.824 21.888-47.904 32.96-99.648 32.96-153.888-0.032-207.872-169.152-376.992-376.992-376.992zM511.968 572.8c-107.968 0-195.808-87.84-195.808-195.808s87.84-195.84 195.808-195.84 195.808 87.84 195.808 195.84c0 107.968-87.84 195.808-195.808 195.808z' fill='%23fa3c23' p-id='3499'%3E%3C/path%3E%3C/svg%3E");
- background-size: cover;
- background-position: center bottom;
- position: absolute;
- left: 50%;
- top: 50%;
- margin-left: -30rpx;
- margin-top: -60rpx;
- z-index: 999;
- transform-origin: center bottom;
- }
- .picker_map_location.animated{
- animation: bounceInDown .6s linear infinite;
- }
- .picker-map{
- width: 750rpx;
- height: 400rpx;
- }
- .list-picker_position{
- position: relative;
- flex: 1;
- display: flex;
- flex-flow: column;
- overflow: hidden;
- .hd{
- padding: 20rpx 20rpx 10rpx;
- display: flex;
- .input_text{
- flex: 1;
- box-sizing: border-box;
- background: #f2f2f2;
- border-radius: 6rpx;
- height: 60rpx;
- font-size: 28rpx;
- padding-left: 1em;
- }
- }
- .bd{
- padding: 20rpx;
- box-sizing: border-box;
- flex: 1;
- overflow-y: scroll;
- .item{
- display: flex;
- padding: 15rpx 10rpx;
- border-bottom: 1px solid #ccc;
- line-height: 1.92;
- align-items: stretch;
- .title{
- font-size: 32rpx;
- }
- .address{
- font-size: 24rpx;
- color: #999;
- line-height: 1.5;
- }
- }
- .item-l{
- padding: 10rpx 6rpx 0 0;
- }
- .item-c{
- flex: 1;
- }
- .item-r{
- width: 60rpx;
- display: flex;
- align-items: center;
- align-content: center;
- }
- .item.disabled{
- opacity: .5;
- }
- }
- }
- .btn-search{
- background: #007AFF;
- font-size: 24rpx;
- color: #fff;
- display: flex;
- padding: 0;
- align-items: center;
- justify-content: center;
- width: 120rpx;
- }
- .picker-search{
- background-image: url("data:image/svg+xml,%3Csvg t='1670900132396' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='2679' width='200' height='200'%3E%3Cpath d='M685.6 660.336l155.152 155.168a16 16 0 0 1 0 22.624l-11.312 11.328a16 16 0 0 1-22.624 0l-158.528-158.544a289.792 289.792 0 0 1-165.152 51.36C322.336 742.256 192 611.904 192 451.12 192 290.336 322.336 160 483.136 160c160.784 0 291.12 130.336 291.12 291.136 0 82.112-33.984 156.272-88.672 209.2z m-202.464 33.92c134.272 0 243.12-108.848 243.12-243.12C726.256 316.848 617.408 208 483.136 208 348.848 208 240 316.848 240 451.136c0 134.272 108.848 243.12 243.136 243.12z' p-id='2680' fill='%23dbdbdb'%3E%3C/path%3E%3C/svg%3E"); background-size: cover;
- background-size: cover;
- width:36rpx;
- height: 36rpx;
- width: 36rpx;
- display: block;
- margin-right: 5rpx;
- }
- .picker-checked{
- background-image: url("data:image/svg+xml,%3Csvg t='1670909673260' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='3763' width='200' height='200'%3E%3Cpath d='M417.185185 768c-9.481481 0-18.962963-3.792593-26.548148-11.377778l-246.518518-246.518518c-15.17037-15.17037-15.17037-37.925926 0-53.096297 15.17037-15.17037 37.925926-15.17037 53.096296 0L417.185185 676.977778l409.6-409.6c15.17037-15.17037 37.925926-15.17037 53.096296 0 15.17037 15.17037 15.17037 37.925926 0 53.096296l-436.148148 436.148148c-7.585185 7.585185-17.066667 11.377778-26.548148 11.377778z' p-id='3764' fill='%231e63ed'%3E%3C/path%3E%3C/svg%3E");
- background-size: cover;
- width: 46rpx;
- height: 46rpx;
- display: block;
- }
- .picker-address{
- background-image: url("data:image/svg+xml,%3Csvg t='1670910118471' class='icon' viewBox='0 0 1024 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='4833' width='200' height='200'%3E%3Cpath d='M508.313 1018.666c0 0-379.51-422.921-379.51-632.516 0-209.606 169.914-379.51 379.51-379.51s379.511 169.903 379.51 379.51c0 209.596-379.51 632.516-379.51 632.516zM508.313 55.295c-182.719 0-330.854 150.305-330.854 335.72s330.854 559.534 330.854 559.534 330.854-374.117 330.854-559.534c0-185.415-148.135-335.72-330.854-335.72zM508.312 512.654c-87.336 0-158.129-70.793-158.129-158.129s70.793-158.129 158.129-158.129 158.129 70.793 158.129 158.129c0 87.328-70.793 158.129-158.129 158.129zM508.313 240.185c-64.488 0-116.772 52.285-116.772 116.772s52.285 116.772 116.772 116.772c64.498 0 116.772-52.285 116.772-116.772 0-64.488-52.275-116.772-116.772-116.772z' fill='%23666666' p-id='4834'%3E%3C/path%3E%3C/svg%3E");
- background-size: cover;
- width: 36rpx;
- height: 36rpx;
- display: block;
- }
- .btn-selected{
- background: #007AFF;
- height: 80rpx;
- line-height: 80rpx;
- font-size: 32rpx;
- color: #fff;
- border: none;
- border-radius: 0;
- }
- .btn-selected.disabled{
- background: #f2f2f2;
- color: #ccc;
- }
- </style>
|