【问题标题】:Adding Randomized markers in a radius around you [Google Maps]在您周围的半径范围内添加随机标记 [Google 地图]
【发布时间】:2017-05-11 06:48:47
【问题描述】:

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

我有地图,我在学校的位置上放了一些标记,所以当你在它们上行走时,你会“捡起它们”并获得一分。现在我想制作随机标记,这样你就可以在任何地方玩游戏。有什么想法吗?

这是我的代码:

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) {}

}

【问题讨论】:

标签: android google-maps


【解决方案1】:

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

通过以下链接:

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

【讨论】:

    【解决方案2】:

    使用集群管理器的最简单方法:

      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));
    }
    

    它:

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

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

    更多关于集群的信息你可以find here

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

    【讨论】:

    • 我对编程真的很陌生,当我复制它时,我的代码看起来像这样:prntscr.com/f6ixyk 我导入了我必须导入的内容,如果我猜想我认为我需要在我的代码的顶部?
    • 您可以使用普通的MarkerOptions,而不是使用ClusterMarker,并像在原始代码中一样使用GoogleMap.addMarker(MarkerOptions options) 添加它们。 SphericalUtil 类是 Google Maps Android API 实用程序库的一部分(正如我之前提到的)。请参考我在帖子中添加的链接,并查看文档如何将此依赖项添加到您的项目中。然后导入类,你应该没问题。
    • 克隆项目出现问题:prntscr.com/f8dwuv
    • 同步你的 Gradle 构建有问题。请阅读Constants file 中的评论。您需要准备 gradle.properties 文件并在其中添加 FirebaseUrl、HomeLongitude 和 HomeLatitude 常量。这允许 Gradle 在 BuildConfig 类中生成常量。
    【解决方案3】:

    简单的解决方案

    调用此方法“generateRandomMarkers”生成随机标记

    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
        }
    

    随机坐标生成方法

    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);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-29
      • 1970-01-01
      • 1970-01-01
      • 2019-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多