功能描述:
最近在做有关谷歌地图相关的东西:涉及两个功能: 1:自动定位功能,点击自动定位,然后可以拿到位置行政区信息,进行表单的一个填充(地理反编码) 2、地点搜索功能
具体实现所需的谷歌开放
仅业务逻辑来看,难度是并不大的,涉及到谷歌地图的三个相关接口: 1、地理反编码(经纬度转换为行政区)
https://maps.googleapis.com/maps/api/geocode/json?language=cn&latlng=39.9,116.4&key=谷歌key值
2、地点搜索
https://maps.googleapis.com/maps/api/place/queryautocomplete/json?key=谷歌key值&input=输入内容
3、根绝上述2接口,拿到的place_id去获取该地点的具体信息,然后进行表单的一个填充
https://maps.googleapis.com/maps/api/geocode/json?place_id=ChIJeRpOeF67j4AR9ydy_PIzPuM&key=谷歌key
遇到的难点
1、当前地理位置的获取,在这里就是单纯的用 navigator.geolocation来做的
这种做法是有瑕疵的,例如用的浏览器不支持navigator.geolocation就无法来进行定位了,
有时候利用一些地图的开放api来实现定位功能,例如百度地图的: new window.BMap.LocalCity()
async getCurrentLocation() {
if (navigator.geolocation) {
await navigator.geolocation.getCurrentPosition(position => {
let {longitude, latitude } = position.coords;
this.lng = longitude;
this.lat = latitude;
this.switchLnglatRegion();
}, err => {
console.log('定位发生错误', err);
});
} else {
this.toast = this.$createToast({
txt: '当前浏览器不支持自动定位功能',
type: 'warn',
time: 2000
});
this.toast.show();
}
},
2、可以看到谷歌api有些接口是需要获取浏览器语言的: 各国多语言参考
const getLanguage = function() {
let lan = window.navigator.browserLanguage || window.navigator.language;
lan = lan.toLowerCase().replace('-', '_');
let rootLang = lan.substring(0, 2);
if ('zh' === rootLang && lan.split('_')[1]) {
lan = rootLang + '_' + lan.split('_')[1].toUpperCase();
}
return lan;
};
export {getLanguage};
let language = getLanguage().slice(3).toLowerCase()
3、地图的引入方式:
为什么会单独说这个,因为上方的三个接口,第一个可以正常调用,但是第二个,(第三个没尝试),会直接导致跨域。 用了jsonp方式解决这个跨域,还是搞不定,最终就只好采用,导入谷歌地图,然后使用实例的方法。
传统地图的引入方式:可是这些服务其实都是付费服务,系统中是需要用户自己配置好key,然后去获取用户的地图配置信息,拿到key,不能写死。
<script
src="https://maps.googleapis.com/maps/api/js?key=‘你申请的key值&callback=initMap&libraries=&v=weekly’"
defer>
</script>
最终的引入方式:
import $ from 'jquery';
import { toLonLat } from 'ol/proj';
import dealWorkApi from '@/api/dealWork';
export default {
data() {
return {
googlePromise: null,
validationPromise: null,
google: null,
geocoder: null,
autocompleteService: null,
googleUrl: ''
};
},
computed: {
},
async created() {
await this.initGis();
this.googlePromise = this.initGoogleService(this.googleUrl);
this.validationPromise = this.googlePromise.then(() =>
this.checkValidation()
);
},
methods: {
async initGis() {
await dealWorkApi.getGis({
success: (resp) => {
const { URL } = resp.GISAPI;
this.googleUrl = URL;
},
errorResponse: (res) => {
console.log(res);
}
});
},
initGoogleService(googleUrl) {
return new Promise((resolve, reject) => {
$.ajax({
type: 'get',
url: `https://${googleUrl}&libraries=places`,
dataType: 'script',
timeout: 5 * 1000,
success: () => this.getResponse(resolve, reject),
error: () => this.getResponse(resolve, reject)
});
});
},
getResponse(resolve, reject) {
setTimeout(() => {
const google = window.google;
if (!google) {
return reject();
}
this.google = google;
this.geocoder = new google.maps.Geocoder();
this.placesService = new google.maps.places.PlacesService(
document.createElement('div')
);
this.autocompleteService = new google.maps.places.AutocompleteService();
resolve(google);
}, 300);
},
getAddress(coordinates) {
const [lng, lat] = toLonLat(coordinates);
return new Promise((resolve, reject) => {
const res = this.googlePromise.then(
() => {
let geocodeRes = this.geocoder.geocode(
{ location: { lng, lat } },
(response, status) => {
resolve({ response, status });
}
);
if (geocodeRes === undefined) {
reject({ response: [], status: 'fail' });
}
},
() => {
resolve();
}
);
if (!res) {
reject({ response: [], status: 'fail' });
}
});
},
searchAddress(address) {
return new Promise((resolve, reject) => {
const res = this.autocompleteService.getPlacePredictions(
{ input: address },
(response, status) => {
resolve({ response, status });
}
);
if (!res) {
reject({ response: [], status: 'fail' });
}
});
},
getPlaceDetail(placeId) {
return new Promise((resolve) => {
this.placesService.getDetails(
{
placeId
},
(response, status) => {
resolve({ response, status });
}
);
});
}
}
};
这段引入script的方法堪称经典,其余jquery永远滴神,详情其他用法参考
$.ajax({
type: 'get',
url: `https://${googleUrl}&libraries=places`,
dataType: 'script',
timeout: 5 * 1000,
success: () => this.getResponse(resolve, reject),
error: () => this.getResponse(resolve, reject)
});
|