我正试图让Google Maps Geofencing出现在我的地图中。
除“地理栅栏”部分(该部分未在地图上显示)之外,其余所有代码均可正常工作。
这是我在手机中使用的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Blank App</title>
<script src="http://maps.google.com/maps/api/js" type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 100%; height: 100vh;"></div>
<div id="geolocation"></div>
<script type="text/javascript" src="cordova.js"></script>
<script>
class CircularGeofenceRegion {
constructor(opts) {
Object.assign(this, opts)
}
inside(lat2, lon2) {
const lat1 = this.latitude
const lon1 = this.longitude
const R = 63710; // Earth's radius in m
return Math.acos(Math.sin(lat1)*Math.sin(lat2) +
Math.cos(lat1)*Math.cos(lat2) *
Math.cos(lon2-lon1)) * R < this.radius;
}
}
</script>
<script type="text/javascript">
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log("navigator.geolocation works well");
getMapLocation();
watchMapPosition();
}
var Latitude = undefined;
var Longitude = undefined;
// Get geo coordinates
function getMapLocation() {
navigator.geolocation.getCurrentPosition
(onMapSuccess, onMapError, { enableHighAccuracy: true });
}
// Success callback for get geo coordinates
var onMapSuccess = function (position) {
Latitude = position.coords.latitude;
Longitude = position.coords.longitude;
getMap(Latitude, Longitude);
}
// Get map by using coordinates
function getMap(latitude, longitude) {
var mapOptions = {
center: new google.maps.LatLng(0, 0),
zoom: 1,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map
(document.getElementById("map"), mapOptions);
var latLong = new google.maps.LatLng(latitude, longitude);
var marker = new google.maps.Marker({
position: latLong
});
marker.setMap(map);
map.setZoom(15);
map.setCenter(marker.getPosition());
//////////////////////////////////////////////////////////////////////////////////////
var locations = [
['Location1', -25.363, 131.044, 1]
];
var infowindow = new google.maps.InfoWindow({});
var marker, count;
for (count = 0; count < locations.length; count++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[count][1], locations[count][2]),
map: map,
title: locations[count][0]
});
google.maps.event.addListener(marker, 'click', (function (marker, count) {
return function () {
infowindow.setContent(locations[count][0]);
infowindow.open(map, marker);
}
})(marker, count));
}
//////////////////////////////////////////////////////////////////////////////////////
// FENCING SECTION:
const fenceA = new CircularGeofenceRegion({
name: 'myfence',
latitude: 85.363,
longitude: 31.044,
radius: 100 // meters
});
const fences = [fenceA]
const fenceOptions = {}
navigator.geolocation.watchPosition(({coords}) => {
for (const fence of fences) {
const lat = coords.latitude
const lon = coords.longitude
if (fence.inside(lat, lon)) {
// do some logic
}
}
}, console.error, fenceOptions);
// END OF FENCING SECTION
///////////////////////////////////////////////////////////////////////////////////////
}
// Success callback for watching your changing position
var onMapWatchSuccess = function (position) {
var updatedLatitude = position.coords.latitude;
var updatedLongitude = position.coords.longitude;
if (updatedLatitude != Latitude && updatedLongitude != Longitude) {
Latitude = updatedLatitude;
Longitude = updatedLongitude;
getMap(updatedLatitude, updatedLongitude);
}
}
// Error callback
function onMapError(error) {
console.log('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
// Watch your changing position
function watchMapPosition() {
return navigator.geolocation.watchPosition
(onMapWatchSuccess, onMapError, { enableHighAccuracy: true, maximumAge: 3600000 });
}
</script>
</body>
</html>
我已在代码中标记了Fencing部分的开头和结尾。
还有一个称为CircularGeofenceRegion的类,它是代码的开头。
任何人都可以帮助使栅栏正常工作/出现吗?
答案 0 :(得分:0)
不直接回答您的问题,但是仅供参考,您可以在地图上放置一个圆圈并自己获取周长/周长。过滤时,我使用Web Worker释放UI线程。
importScripts("Tier3Toolbox.js");
var currVintage = 0;
var inBounds = false;
var facFilter = [];
var imageProlog = "<div style='height:5em; width:5em; display:inline-block;vertical-align:middle;'>" +
"<img style='height:100%; width: 100%; max-height:100%; max-width:100%' src='";
var imageEpilog = "' ></div>";
var facilityTable, lineBreak;
self.addEventListener('message', function(e)
{
var data = e.data;
switch (data.cmd) {
case 'init':
initThread(data.load);
break;
case 'initFilter':
for (var i=0; i<data.filterTable.length; i++) {
facFilter[data.filterTable[i].locTypeId] = {'icon':data.filterTable[i].icon};
}
break;
case 'filter':
facFilter = [];
for (var i=0; i<data.filterTable.length; i++) {
if (data.filterTable[i].facSelected)
facFilter[data.filterTable[i].locTypeId] = {'icon':data.filterTable[i].icon};
}
break;
case 'search':
var searchVintage = ++currVintage;
var tableSearch = new searcher(searchVintage, data);
break;
case 'reset':
reset();
self.postMessage({'reset': true});
break;
case 'stop':
self.postMessage({'success' : true});
self.close();
break;
default:
self.postMessage({'success' : false, 'msg' : data.msg});
};
}, false);
function initThread(msg)
{
facilityTable = JSON.parse(msg);
reset();
self.postMessage({'success' : true,
'cnt' : facilityTable.length
});
}
function reset()
{
for (var i=0; i<facilityTable.length; i++) {
facilityTable[i].visible=false
}
currVintage = 0;
}
function searcher(searchVintage, msg)
{
var myVintage = searchVintage;
var facIndex = -1;
var msg = msg;
var checkLoop = function()
{
if (myVintage != currVintage)
return;
if (++facIndex == facilityTable.length)
return;
inBounds = geoFencer.call(this, msg);
if (inBounds) {
var facMatch = 0;
var bubbleHTML = "";
for (var i=0; i<facilityTable[facIndex].facilities.length; i++){
var currFac = facilityTable[facIndex].facilities[i];
if (facFilter[currFac.locTypeId] != undefined) {
if (facMatch != 0) {
lineBreak = (facMatch / 3);
if (lineBreak == lineBreak.toFixed(0)) {
bubbleHTML += "<br />";
}
}
facMatch++;
bubbleHTML += imageProlog + facFilter[currFac.locTypeId].icon + imageEpilog;
}
}
if (facMatch == 0) {
inBounds = false;
}
}
if (inBounds != facilityTable[facIndex].visible) {
self.postMessage({'match' : inBounds,
'facIndex' : facIndex,
'scopeVintage': msg.scopeVintage,
'bubbleHTML' : bubbleHTML,
'success' : true
});
facilityTable[facIndex].visible = inBounds;
}
setTimeout(checkLoop,0);
}
var circleCheck = function(msg)
{
var diff = Tier3Toolbox.calculateDistance(
msg.centerLat,
msg.centerLng,
facilityTable[facIndex].searchLat,
facilityTable[facIndex].searchLng);
if (msg.radius > diff)
return true;
return false;
}
var rectangleCheck = function(msg)
{
if (facilityTable[facIndex].searchLat > msg.SWLat &&
facilityTable[facIndex].searchLat < msg.NELat &&
facilityTable[facIndex].searchLng > msg.SWLng &&
facilityTable[facIndex].searchLng < msg.NELng)
return true;
return false;
}
var GEOFENCER = [circleCheck,rectangleCheck];
var geoFencer = GEOFENCER[msg.checker];
setTimeout(checkLoop,0);
return this;
}
从主线调用它,例如:-
function createFacilityMarkers(xmlhttp){
facFinder = new Worker("facfinder.js");
facFinder.addEventListener('message', workerInit, false);
facFinder.postMessage({'cmd' : 'init', 'load' : xmlhttp.responseText});
计算距离函数为:-
Tier3Toolbox.calculateDistance =
function(lat1, lon1, lat2, lon2){
var dLat = this.toRad(lat2 - lat1);
var dLon = this.toRad(lon2 - lon1);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.toRad(lat1)) *
Math.cos(this.toRad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
var distance = this.EARTH_RADIUS * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return distance;
}
如果用户用手指/鼠标在地图上移动圆,则此设置非常有用。 (好消息是Google Maps最终修复了将圆拖动到边框时停止滚动地图的错误!)
PS。如果您不知道如何做Circle位:-
var circleOptions = {
clickable: true,
draggable: true,
editable: true,
visible: false,
strokeColor: 'gray',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: 'gray',
fillOpacity: 0.35,
center: marker.getPosition()
};
radarCircle = new radarView(new google.maps.Circle(circleOptions));
google.maps.event.addDomListener(radarCircle, 'center_changed', reScope);
google.maps.event.addDomListener(radarCircle, 'radius_changed', reScope);
function radarView(superBase)
{
this.__proto__ = superBase;
if (this instanceof google.maps.Circle) {
augmentCircle.apply(this);
} else if (this instanceof google.maps.Rectangle) {
augmentRectangle.apply(this);
} else {
Tier3Toolbox.reportError({header:"Internal error",
message:"Inheriting from unknown object"});
}
this.doX = function(x){return "x is>" + x;};
return this;
}
function augmentCircle()
{
this.moveBorder = function()
{
google.maps.event.trigger(radarCircle,"center_changed");
}
}
function augmentRectangle()
{
this.moveBorder = function()
{
google.maps.event.trigger(radarRectangle,"bounds_changed");
}
}
function reScope() {
var searchReq = {'cmd':'search', 'scopeVintage':scopeVintage};
if (radarShape.getCenter) {
searchReq.checker = 0;
var currCenter = radarCircle.getCenter();
searchReq.centerLat = currCenter.lat();
searchReq.centerLng = currCenter.lng();
searchReq.radius = radarCircle.getRadius();
} else {
searchReq.checker = 1;
searchReq.SWLat = radarShape.getBounds().getSouthWest().lat();
searchReq.SWLng = radarShape.getBounds().getSouthWest().lng();
searchReq.NELat = radarShape.getBounds().getNorthEast().lat();
searchReq.NELng = radarShape.getBounds().getNorthEast().lng();
}
facFinder.postMessage(searchReq);
}