首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在你周围的半径内添加随机标记[Google Maps]

在你周围的半径内添加随机标记[Google Maps]
EN

Stack Overflow用户
提问于 2017-05-11 14:48:48
回答 3查看 907关注 0票数 1

所以我是一名学生,我对编程真的很陌生。我们正在为我们的android手机做一个游戏,我需要一些帮助,我想要一个菜单(我可以自己做),在那里你作为用户可以选择你周围的特定半径,比如说你周围1公里半径,然后我想在你周围的半径内放置随机标记。

我有地图,我在学校的位置上放了一些标记,所以当你走在他们上面的时候,你就会“拿起他们”并得到一分。现在我想做一个随机标记,这样你就可以随时随地玩这个游戏了。有什么想法吗?

下面是我的代码:

代码语言:javascript
运行
复制
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener {

GoogleMap mGoogleMap;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
public static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private static final int DEFAULT_ZOOM = 18;
private List<MarkerOptions> targets;
private MarkerOptions myMarker;
private static final String TAG = MapsActivity.class.getSimpleName();

private int score = 0;

private TextView scoreTV;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);

    scoreTV = (TextView) findViewById(R.id.scoreTV);
    scoreTV.setText("Score: 0");

    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

@Override
public void onMapReady(GoogleMap googleMap)
{
    mGoogleMap = googleMap;

    UiSettings settings = mGoogleMap.getUiSettings();
    settings.setZoomControlsEnabled(true);
    settings.setCompassEnabled(true);

    setupTargets();

    addTargetsToMap();

    try {
        // Customise the styling of the base map using a JSON object defined
        // in a raw resource file.
        boolean success = googleMap.setMapStyle(
                MapStyleOptions.loadRawResourceStyle(
                        this, R.raw.style_json));

        if (!success) {
            Log.e(TAG, "Style parsing failed.");
        }
    } catch (Resources.NotFoundException e) {
        Log.e(TAG, "Can't find style. Error: ", e);
    }

    //Initialize Google Play Services
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            //Location Permission already granted
            buildGoogleApiClient();
            //mGoogleMap.setMyLocationEnabled(true);
        } else {
            //Request Location Permission
            checkLocationPermission();
        }
    }
    else {
        buildGoogleApiClient();
        //mGoogleMap.setMyLocationEnabled(true);
    }
}

protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();
}

@Override
public void onConnected(Bundle bundle) {
    startLocationUpdates();
}

private void startLocationUpdates() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(5000);
    mLocationRequest.setFastestInterval(3000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }
}




@Override
public void onLocationChanged(Location location)
{
    Log.e("Location: ", location.toString());

    mLastLocation = location;

    Iterator<MarkerOptions> iter = targets.iterator();
    while (iter.hasNext()) {
        MarkerOptions target = iter.next();
        Location targetLocation = new Location(LocationManager.GPS_PROVIDER);
        targetLocation.setLatitude(target.getPosition().latitude);
        targetLocation.setLongitude(target.getPosition().longitude);
        float distance = location.distanceTo(targetLocation);
        if (distance < 10.0f) {
            Toast.makeText(this, "Target aquired, plus one point!", Toast.LENGTH_SHORT).show();
            score++;
            scoreTV.setText("Score: " + score);
            iter.remove();
        }
    }
    mGoogleMap.clear();

    addTargetsToMap();

    //Place current location marker
    LatLng position = new LatLng(location.getLatitude(), location.getLongitude());
    myMarker = new MarkerOptions();
    myMarker.position(position);
    myMarker.title("Me");
    myMarker.icon(BitmapDescriptorFactory.fromResource(R.drawable.dansa));
    mGoogleMap.addMarker(myMarker);

    //move map camera
    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(position, DEFAULT_ZOOM));

}

private void checkLocationPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
            new AlertDialog.Builder(this)
                    .setTitle("Location Permission Needed")
                    .setMessage("This app needs the Location permission, please accept to use location functionality")
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            //Prompt the user once explanation has been shown
                            ActivityCompat.requestPermissions(MapsActivity.this,
                                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                    PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
                        }
                    })
                    .create()
                    .show();


        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String permissions[], @NonNull int[] grantResults) {
    switch (requestCode) {
        case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // location-related task you need to do.
                if (ContextCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED) {

                    if (mGoogleApiClient == null) {
                        buildGoogleApiClient();
                    }
                    mGoogleMap.setMyLocationEnabled(true);
                }

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
            }
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

//=============== START TARGETS ====================
private void setupTargets() {

    targets = new ArrayList<MarkerOptions>();

    MarkerOptions target = new MarkerOptions();

    target.position(new LatLng(58.393813, 15.564835)).title("Target 1");
    targets.add(target);

    target = new MarkerOptions();
    target.position(new LatLng(58.394039, 15.564811)).title("Target 2");
    targets.add(target);

    target = new MarkerOptions();
    target.position(new LatLng(58.394244, 15.565093)).title("Target 3");
    targets.add(target);

}

private void addTargetsToMap() {
    for(MarkerOptions target : targets){
        mGoogleMap.addMarker(target);
    }
}
//=============== END TARGETS ====================


//=============== START LIFECYCLE ====================
@Override
public void onPause() {
    super.onPause();

    //stop location updates when Activity is no longer active
    if (mGoogleApiClient != null) {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    }
}

@Override
protected void onResume() {
    super.onResume();
    if(mGoogleApiClient!=null) {
        if(mGoogleApiClient.isConnected())
            startLocationUpdates();
    }

}


//=============== END LIFECYCLE ====================


//====================== NOT USED =======================

@Override
public void onConnectionSuspended(int i) {}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {}

}
EN

回答 3

Stack Overflow用户

发布于 2017-05-11 15:06:47

您可以使用VisibleRegion获取特定半径的LatLongBound,并可以在该区域中添加标记。

通过以下链接:

https://developers.google.com/android/reference/com/google/android/gms/maps/model/VisibleRegion

票数 0
EN

Stack Overflow用户

发布于 2017-05-11 15:29:04

使用Cluster Manager的最简单方法:

代码语言:javascript
运行
复制
  private void loadMarkers(ClusterManager<ClusterMarker> manager, GoogleMap map, LatLng center, int count,
    double minDistance, double maxDistance) {
  double minLat = Double.MAX_VALUE;
  double maxLat = Double.MIN_VALUE;
  double minLon = Double.MAX_VALUE;
  double maxLon = Double.MIN_VALUE;

  for (int i = 0; i < count; ++i) {
    double distance = minDistance + Math.random() * maxDistance;
    double heading = Math.random() * 360 - 180;

    LatLng position = SphericalUtil.computeOffset(center, distance, heading);

    ClusterMarker marker = new ClusterMarker(new MarkerOptions().position(position).title("Item No. " + i));
    manager.addItem(marker);

    minLat = Math.min(minLat, position.latitude);
    minLon = Math.min(minLon, position.longitude);
    maxLat = Math.max(maxLat, position.latitude);
    maxLon = Math.max(maxLon, position.longitude);
  }

  LatLng min = new LatLng(minLat, minLon);
  LatLng max = new LatLng(maxLat, maxLon);
  LatLngBounds bounds = new LatLngBounds(min, max);

  map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100));
}

It:

  • 生成距定义中心位置的最小和最大距离内的标记数量,
  • 计算最小和最大经度和纬度,以便地图相机可以正确放大或缩小,并允许所有生成的位置在屏幕上可见,
  • 对所有标记进行聚类以改善显示效果。

SphericalUtil类是Google Maps Android API utility library的一部分。

有关集群的更多信息,您可以find here

你可以从我的GitHub repository中克隆完整的工作示例。

票数 0
EN

Stack Overflow用户

发布于 2021-05-28 02:37:37

Easy solution

调用此方法"generateRandomMarkers"以生成随机标记

代码语言:javascript
运行
复制
void generateRandomMarkers() {
        //set your own minimum distance here
        int minimumDistanceFromMe = 10;
        //set your own maximum distance here
        int maximumDistanceFromMe = 500;
        //set number of markers you want to generate in Map/
        int markersToGenerate = 3;
        for (int position = 1; position <=markersToGenerate ; position++) {
              LatLng coordinates = generateRandomCoordinates(minimumDistanceFromMe, maximumDistanceFromMe);
                Log.i("random_coordinates",""+coordinates);
                mapView.addMarker(new MarkerOptions().position(new LatLng(coordinates.latitude,coordinates.longitude)).title("mid point").snippet("Snippet"));
        }// end FOR loop
    }

方法来生成随机坐标。

代码语言:javascript
运行
复制
public LatLng generateRandomCoordinates(int min, int max) {
        // Get the Current Location's longitude and latitude
        double currentLong = currentLocation.getLongitude();
        double currentLat = currentLocation.getLatitude();

        // 1 KiloMeter = 0.00900900900901° So, 1 Meter = 0.00900900900901 / 1000
        double meterCord = 0.00900900900901 / 1000;

        //Generate random Meters between the maximum and minimum Meters
        Random r = new Random();
        int randomMeters = r.nextInt(max + min);

        //then Generating Random numbers for different Methods
        int randomPM = r.nextInt(6);

        //Then we convert the distance in meters to coordinates by Multiplying number of meters with 1 Meter Coordinate
        double metersCordN = meterCord * (double) randomMeters;

        //here we generate the last Coordinates
        if (randomPM == 0) {
            return new LatLng(currentLat + metersCordN, currentLong + metersCordN);
        } else if (randomPM == 1) {
            return new LatLng(currentLat - metersCordN, currentLong - metersCordN);
        } else if (randomPM == 2) {
            return new LatLng(currentLat + metersCordN, currentLong - metersCordN);
        } else if (randomPM == 3) {
            return new LatLng(currentLat - metersCordN, currentLong + metersCordN);
        } else if (randomPM == 4) {
            return new LatLng(currentLat, currentLong - metersCordN);
        } else {
            return new LatLng(currentLat - metersCordN, currentLong);
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43908376

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档