创建随机位置时距离错误

Posted

技术标签:

【中文标题】创建随机位置时距离错误【英文标题】:Wrong distances when creating random locations 【发布时间】:2012-05-21 09:33:55 【问题描述】:

我正在尝试在我的位置附近创建随机位置。我想要的是在我所在位置周围 200 米的圆圈内创建随机纬度/经度对。问完这个问题后:generate random locations nearby my location这就是我想出的。

在 onLocationChanged 中,这就是我所做的:

private void updateWithNewLocation(Location location) 
    if (location != null) 
        this.myItemizedOverlay.clear();
        this.nonPlayerItemizedOverlay.clear();
        this.mapOverlays.clear();
        // Update my map location.
        Double latitude = location.getLatitude() * 1E6;
        Double longitude = location.getLongitude() * 1E6;
        GeoPoint geoPoint = new GeoPoint(latitude.intValue(),
                longitude.intValue());

        CustomOverlayItem pcOverlayItem = new CustomOverlayItem(geoPoint,
                "", "", "");

        this.mapController.animateTo(geoPoint);

        this.myItemizedOverlay.setLocation(location);
        this.myItemizedOverlay.addOverlay(pcOverlayItem);
        this.mapOverlays.add(this.myItemizedOverlay);

        // Everytime i get a new location i generate random non player
        // characters near my location
        int numberOfNonPlayers = new Random().nextInt(5);

        for (int i = 0; i < numberOfNonPlayers; i++) 
            int radius = (int) this.myMapView.getProjection()
                    .metersToEquatorPixels(200);
            double lowerLimit = -1;
            double upperLimit = 1;

            Double newLatitude = location.getLatitude()
                    * 1E6
                    + (radius * (lowerLimit + (Math.random() * ((upperLimit - lowerLimit) + 1))));
            Double newLongitude = location.getLongitude()
                    * 1E6
                    + (radius * (lowerLimit + (Math.random() * ((upperLimit - lowerLimit) + 1))));

            GeoPoint geoPoint2 = new GeoPoint(newLatitude.intValue(),
                    newLongitude.intValue());

            CustomOverlayItem npcOverlayItem = new CustomOverlayItem(
                    geoPoint2, "", "", "");

            Location newLocation = new Location("npc " + i);
            newLocation.setLatitude(newLatitude);
            newLocation.setLongitude(newLongitude);

            this.nonPlayerItemizedOverlay = new NonPlayerItemizedOverlay(
                    this.nonPlayerDrawable, this.myMapView);
            this.nonPlayerItemizedOverlay.setLocation(newLocation);
            this.nonPlayerItemizedOverlay.addOverlay(npcOverlayItem);
            this.mapOverlays.add(this.nonPlayerItemizedOverlay);
        
    

这是我的 NonPlayerItemizedOverlay 类:

public class NonPlayerItemizedOverlay extends BaseItemizedOverlay 

public NonPlayerItemizedOverlay(Drawable defaultMarker, MapView mapView) 
    super(defaultMarker, mapView);
    // TODO Auto-generated constructor stub


private Location location;

public static int metersToRadius(float meters, MapView map, double latitude) 
    return (int) (map.getProjection().metersToEquatorPixels(meters) * (1 / Math
            .cos(Math.toRadians(latitude))));


@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) 
    super.draw(canvas, mapView, shadow);

    if (shadow == false) 
        Projection projection = mapView.getProjection();

        // Get the current location
        Double latitude = location.getLatitude();
        Double longitude = location.getLongitude();
        GeoPoint geoPoint = new GeoPoint(latitude.intValue(),
                longitude.intValue());

        // Convert the location to screen pixels
        Point point = new Point();
        projection.toPixels(geoPoint, point);

        // int radius = metersToRadius(30, mapView, latitude);
        int radius = (int) mapView.getProjection()
                .metersToEquatorPixels(50);

        RectF oval = new RectF(point.x - radius, point.y - radius, point.x
                + radius, point.y + radius);

        // Setup the paint
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(2.0f);

        paint.setColor(0xffE62020);
        paint.setStyle(Style.STROKE);
        canvas.drawOval(oval, paint);

        paint.setColor(0x18E62020);
        paint.setStyle(Style.FILL);
        canvas.drawOval(oval, paint);
    


public Location getLocation() 
    return location;


public void setLocation(Location location) 
    this.location = location;

还有我的 MyItemizedOverlay 类:

public class MyItemizedOverlay extends BaseItemizedOverlay 

public MyItemizedOverlay(Drawable defaultMarker, MapView mapView) 
    super(defaultMarker, mapView);
    // TODO Auto-generated constructor stub


private Location location;

public static int metersToRadius(float meters, MapView map, double latitude) 
    return (int) (map.getProjection().metersToEquatorPixels(meters) * (1 / Math
            .cos(Math.toRadians(latitude))));


@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) 
    super.draw(canvas, mapView, shadow);

    if (shadow == false) 
        Projection projection = mapView.getProjection();

        // Get the current location
        Double latitude = location.getLatitude() * 1E6;
        Double longitude = location.getLongitude() * 1E6;
        GeoPoint geoPoint = new GeoPoint(latitude.intValue(),
                longitude.intValue());

        // Convert the location to screen pixels
        Point point = new Point();
        projection.toPixels(geoPoint, point);

        // int radius = metersToRadius(100, mapView, latitude);
        int radius = (int) mapView.getProjection().metersToEquatorPixels(
                200);

        RectF oval = new RectF(point.x - radius, point.y - radius, point.x
                + radius, point.y + radius);

        // Setup the paint
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(2.0f);

        paint.setColor(0xff6666ff);
        paint.setStyle(Style.STROKE);
        canvas.drawOval(oval, paint);

        paint.setColor(0x186666ff);
        paint.setStyle(Style.FILL);
        canvas.drawOval(oval, paint);
    


public Location getLocation() 
    return location;


public void setLocation(Location location) 
    this.location = location;

事情是发生了一些奇怪的事情,因为所有随机位置都离我的位置中心太近了,似乎该公式没有涵盖整个半径,我认为距离不是真正的米。

知道我的公式可能有什么问题吗?

提前致谢

【问题讨论】:

我不是地图投影方面的专家,但这些人可能是:gis.stackexchange.com 谢谢托尼,这个链接真的帮助了我。如果您用它写回复,我会将其标记为已接受 【参考方案1】:

有关地图投影坐标计算的问题,此 SE 网站可能会有所帮助:http://gis.stackexchange.com(地理信息系统)。

【讨论】:

【参考方案2】:

请务必使用位置类的 distanceTo() 公式。您可以这样做:

double distance  = a.distanceTo(b);

其中 a 和 b 是 Location 对象。

【讨论】:

谢谢。检查后,距离以实际米为单位。现在看来我没有使用整个半径创建位置,就像它的一半

以上是关于创建随机位置时距离错误的主要内容,如果未能解决你的问题,请参考以下文章

线程在随机位置随机时间后停止运行,没有任何错误

全随机发生器手机怎么用

Plot.ly API 在创建图形时随机抛出 JSON 解码错误

像轮子动画一样旋转图像,并在随机位置停止

将距离添加到 GPS 坐标

为啥随机梯度下降方法能够收敛