PhoneGap 中的 Google Maps API v3:移动后复制圆并绘制切线

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

(这是我发表的另一篇文章的一部分,PhoneGap 中的 Google Maps API v3:移动后标记无法正确绘制)。我一直在使用 PhoneGap 在 Android 上开发 Google Maps API 3 应用程序。它应该跟踪用户位置并用标记和周围的圆圈标记该位置。我一直在 Android 2.3 上开发这个,并且运行良好。然后我升级到了 Android 4.x 的手机,我想它仍然运行良好。

上周,当我移动标记和圆圈时,我开始注意到谷歌地图做了一些奇怪的事情。它似乎创建了一个重复的标记和圆圈,而不是仅仅移动它们。在另一篇文章中,我得到了标记问题的答案,但没有得到圆的答案。有时,如果我更改缩放比例,重复的圆圈似乎就会消失。而且,它偶尔会从顶部画出一些奇怪的切线。请参阅下面的图片。

在我的手机上收到 Android 更新至版本 4.1.1 后不久,我就开始注意到这一点。不确定这是否相关,我找不到有关问题的任何信息。

我将地图和音位间隙代码减少到一个相当小的样本,并且它仍在这样做。我很确定这与phonegap无关。无论如何,我将 PhoneGap 升级到 2.2,但正如预期的那样,它没有帮助。谁能告诉我移动圆圈时是否做错了什么?

我尝试的一个解决方案是在移动它之前隐藏圆圈,然后在移动它之后再次显示它。这似乎解决了重复和切线问题,但它使地图闪烁,当你每 3 秒左右移动它时,这真的很烦人。所以这似乎不是一个可以接受的解决方案。测试代码如下。请注意,我在测试代码中删除了我的 Google 地图 API 密钥。

我还了解到,使其正确重绘的一种方法是拖动地图,使任何圆圈的任何部分都不可见。然后,当我将其拖回以使圆圈可见时,它会被重新绘制为一个正确的圆圈。

谢谢,埃里克

<!DOCTYPE HTML>
<html>
<head>
<title>Marker Test</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
    html {height: 100%}
    body {height: 100%; margin:0; padding:0}
    #map_canvas {height: 100%}
</style>
<script type="text/javascript" charset="utf-8" src="js/phonegap.js"></script>
<script type="text/javascript" charset="utf-8" src="http://maps.googleapis.com/maps/api/js?key=YOUR_KEY_HERE&sensor=true"></script>
<script type="text/javascript" charset="utf-8">
    // Wait for PhoneGap to load
    //
    document.addEventListener("deviceready", onDeviceReady, false);

    // globals
    var watchID = null;
    var map = null;
    var myLocationMarker = null;
    var searchCircle = null;

    // PhoneGap is ready
    //
    function onDeviceReady() {
        startGPS();
    }

    function onUnLoad() {
        console.log("clearing watch " + watchID);
        navigator.geolocation.clearWatch(watchID);
    }

function startGPS() {
    console.log("In startGPS");

    var refreshMilliseconds = 5000;
    var options = { frequency: refreshMilliseconds, enableHighAccuracy: true};

    watchID = navigator.geolocation.watchPosition(onGPSSuccess, onGPSError, options);

    // create Google map
    var mapOptions = {
        zoom: 14,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

    myLocationMarker = new google.maps.Marker({
        title: 'This is me!',
        zIndex: 90,
        optimized: false,
        map:map
    });     

    searchCircle = new google.maps.Circle({
        fillColor: '#c0e4dd',
        strokeColor: '#f15f22',
        fillOpacity: 0.5,
        radius: 1500,
        map:map
    });     
}

var onGPSSuccess = function(p) {
    // get the new coordinates
    var lat = p.coords.latitude;
    var lng = p.coords.longitude;

    console.log("watch ID " + watchID);

    // now that we have the coordinates, we can move the marker and circle on the Google Map
    MoveMarkerAndCircle(lat, lng);
};

var MoveMarkerAndCircle = function(lat, lng) {
    var myLocation = new google.maps.LatLng(lat, lng);
    myLocationMarker.setPosition(myLocation);

//  searchCircle.setVisible(false);
    searchCircle.setCenter(myLocation);
//  searchCircle.setVisible(true);

    map.setCenter(myLocation);  
}

var onGPSError = function() {
    console.log("GPS Error");
};

var GenerateFakeMovement = function() {
    var currentPosition = myLocationMarker.getPosition();
    var newLat = currentPosition.lat() + 0.01;
    var newLng = currentPosition.lng() + 0.01;
    MoveMarkerAndCircle(newLat, newLng);
}
</script>
</head>
<body  style="height:100%;text-align:center" onunload="onUnLoad()">
    <div id="map_canvas" style="width: 100%;height:80%"></div>
    <a href='#' onclick="GenerateFakeMovement();" style="padding-top:5px">MAKE FAKE MOVEMENT</a>
</body>
</html>

2 Circles tangent line broken circles

android cordova google-maps-api-3
3个回答
1
投票
<!DOCTYPE HTML>
<html>
<head>
<title>Marker Test</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
    html {height: 100%}
    body {height: 100%; margin:0; padding:0}
    #map_canvas {height: 100%}
</style>
<script type="text/javascript" charset="utf-8" src="http://maps.googleapis.com/maps/api/js?v=3&sensor=true"></script>
<script type="text/javascript" charset="utf-8">
    var watchID = null;
    var map = null;
    var myLocationMarker = null;
    var searchCircle = null;
    function onDeviceReady() {
        startGPS();
    }

    function onUnLoad() {
        console.log("clearing watch " + watchID);
        navigator.geolocation.clearWatch(watchID);
    }

function startGPS() {
    console.log("In startGPS");

    var refreshMilliseconds = 5000;
    var options = { frequency: refreshMilliseconds, enableHighAccuracy: true};

    if(watchID ==null)
    watchID = navigator.geolocation.watchPosition(onGPSSuccess, onGPSError, options);

    // create Google map
    var mapOptions = {
        zoom: 14,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

    myLocationMarker = new google.maps.Marker({
        title: 'This is me!',
        zIndex: 90,
        optimized: false,
        map:map
    });     

    searchCircle = new google.maps.Circle({
        fillColor: '#c0e4dd',
        strokeColor: '#f15f22',
        fillOpacity: 0.5,
        radius: 1500,
        map:map
    });     
}

var onGPSSuccess = function(p) {
    // get the new coordinates
    var lat = p.coords.latitude;
    var lng = p.coords.longitude;

    console.log("watch ID " + watchID);

    // now that we have the coordinates, we can move the marker and circle on the Google Map
    MoveMarkerAndCircle(lat, lng);
};

var MoveMarkerAndCircle = function(lat, lng) {
 var myLocation = new google.maps.LatLng(lat, lng);
    myLocationMarker.setPosition(myLocation);

//  searchCircle.setVisible(false);
    searchCircle.setCenter(myLocation);
//  searchCircle.setVisible(true);

    map.setCenter(myLocation);  
}

var onGPSError = function() {
    console.log("GPS Error");
};

function GenerateFakeMovement() {
 var currentPosition = myLocationMarker.getPosition();
    var newLat = currentPosition.lat() + 0.01;
    var newLng = currentPosition.lng() + 0.01;
    MoveMarkerAndCircle(newLat, newLng);
}
</script>
</head>
<body  style="height:100%;text-align:center" onload="onDeviceReady()" onunload="onUnLoad()">
    <div id="map_canvas" style="width: 100%;height:80%"></div>
    <a href='#' onclick="GenerateFakeMovement();" style="padding-top:5px">MAKE FAKE MOVEMENT</a>
</body>
</html>​

0
投票

可能与您的问题不完全相关,但如果您将圆圈绑定到标记,则无需手动设置圆圈位置。

 if (myMarker == undefined) {
      myMarker = new google.maps.Marker({
          position: mouseEvent.latLng,
          title: 'My Position',
          map: map,
          draggable: true
      });

      var circle = new google.maps.Circle({
          map: map,
          radius: 100000, // 100 km
          fillOpacity: 0.1,
          strokeOpacity: 0.5,
          strokeWeight: 1
      });

      circle.bindTo('center', myMarker, 'position'); //This will set the circle bound to the marker at center
}

所以你只需要更新标记的位置即可。 希望这有帮助。


0
投票

我希望我将其作为“答案”发布是正确的。我仍然遇到这个问题,但我已经将自己的示例缩小到了这一点,似乎很明显,这只是 Android 4.1.1 上的 Google Maps API v3 的问题。缩小测试用例的代码如下,不再涉及 PhoneGap。

我已将测试页面发布到网上: http://kcwebprogrammers.com/MarkerTest-NoGps.html

如果您在 Windows(Chrome 或 IE)中或使用 Android 2.3 上的互联网浏览器浏览,则移动圆圈就可以了。如果您在Android 4.1.1上使用互联网浏览器浏览到同一页面,那么您会看到移动圆圈后原始圆圈仍然可见,从而导致两个圆圈。所以我已将问题发布到 Google 地图问题列表中。

感谢以上的建议。如果有人认为我应该对这篇文章做任何不同的事情,请告诉我。

<!DOCTYPE HTML>
<html>
<head>
<title>Marker Test</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
    html {height: 100%}
    body {height: 100%; margin:0; padding:0}
    #map_canvas {height: 100%}
</style>
<script type="text/javascript" charset="utf-8" src="http://maps.googleapis.com/maps/api/js?key=YOUR_KEY_HERE&sensor=true"></script>
<script type="text/javascript" charset="utf-8">

// globals
var watchID = null;
var map = null;
var myLocationMarker = null;
var searchCircle = null;
var myLocation = null;
    
function onLoad() {
    startGPS();
}

function onUnLoad() {
    console.log("clearing watch " + watchID);
}
    
function startGPS() {
    // simulate getting position from GPS
    myLocation = new google.maps.LatLng(39, -90);
    
    // create Google map
    var mapOptions = {
        zoom: 14,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        center:myLocation
    };
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
    google.maps.event.trigger(map, 'resize');
    
    myLocationMarker = new google.maps.Marker({
        title: 'This is me!',
        zIndex: 90,
        optimized: false,
        map:map,
        position: myLocation
    });     

    searchCircle = new google.maps.Circle({
        fillColor: '#c0e4dd',
        strokeColor: '#f15f22',
        fillOpacity: 0.5,
        radius: 1500,
        map:map,
        center:myLocation
    });
    // using bindTo instead does not fix the problem
//  searchCircle.bindTo('center', myLocationMarker, 'position'); //This will set the circle bound to the marker at center
}

var MoveMarkerAndCircle = function(lat, lng) {
    myLocation = new google.maps.LatLng(lat, lng);
    myLocationMarker.setPosition(myLocation);
    
    // set circle invisible before moving and visible after does fix redraw for 4.1.1
    // but causes some annoying flashing of the circle for 4.1.1 and everything else
//  searchCircle.setVisible(false);
    searchCircle.setCenter(myLocation);
//  searchCircle.setVisible(true);
}

var GenerateFakeMovement = function() {
    var currentPosition = myLocationMarker.getPosition();
    var newLat = currentPosition.lat() + 0.001;
    var newLng = currentPosition.lng() + 0.001;
    MoveMarkerAndCircle(newLat, newLng);
}
</script>
</head>
<body  style="height:100%;text-align:center" onunload="onUnLoad()" onload="startGPS()">
    <div id="map_canvas" style="width: 100%;height:90%"></div>
    <a href='#' onclick="GenerateFakeMovement();" style="padding-top:5px">MOVE MARKER AND CIRCLE</a>
</body>
</html>
© www.soinside.com 2019 - 2024. All rights reserved.