无法让Geofence出现在谷歌地图中

问题描述 投票:0回答:1

我想让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的类,它是代码的开头。

任何人都可以帮助让击剑工作/出现吗?

javascript google-maps cordova phonegap geofencing
1个回答
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;
}

如果用户将用手指/鼠标在地图上移动圆圈,则此设置非常有用。 (好消息是谷歌地图最终修复了当圆圈被拖到边界时阻止地图滚动的错误!)

PS。如果您不知道如何做圆位: -

    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);
}
© www.soinside.com 2019 - 2024. All rights reserved.