ユーザーのgps位置を使用して、ユーザーがマーカーの半径内にいるかどうかを検出しようとしています。マーカーの座標がありますが、ユーザーがエリア内にいるかどうかを計算する方法がわかりません。以下を使用しようとしましたが、現在の場所がサークルの内側にある場合でも、「外側」のメッセージが表示され続けます。
public class MapaEscola extends FragmentActivity {
private GoogleMap googleMap;
private Serializable escolas;
private ProgressDialog dialog;
private Circle mCircle;
private Marker mMarker;
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
setContentView(R.layout.maps);
// Loading map
initilizeMap();
// Changing map type
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// Showing / hiding your current location
googleMap.setMyLocationEnabled(true);
// Enable / Disable zooming controls
googleMap.getUiSettings().setZoomControlsEnabled(true);
// Enable / Disable my location button
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
// Enable / Disable Compass icon
googleMap.getUiSettings().setCompassEnabled(true);
// Enable / Disable Rotate gesture
googleMap.getUiSettings().setRotateGesturesEnabled(true);
// Enable / Disable zooming functionality
googleMap.getUiSettings().setZoomGesturesEnabled(true);
Bundle extra = getIntent().getBundleExtra("extra");
ArrayList<Escolas> objects = (ArrayList<Escolas>) extra.getSerializable("array");
try {
for(int i = 0; i < objects.size(); i ++) {
System.out.println(" escolas " + objects.get(i).getLatitude() + " " + objects.get(i).getLongitude());
float latitude = objects.get(i).getLatitude();
float longitude = objects.get(i).getLongitude();
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-23.316281, -51.155528), 15));
MarkerOptions options = new MarkerOptions();
// Setting the position of the marker
options.position(new LatLng(latitude, longitude));
googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
LatLng latLng = new LatLng(latitude, longitude);
drawMarkerWithCircle(latLng);
googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
float[] distance = new float[2];
Location.distanceBetween( mMarker.getPosition().latitude, mMarker.getPosition().longitude,
mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
if( distance[0] > (mCircle.getRadius() / 2) ){
Toast.makeText(getBaseContext(), "Outside", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getBaseContext(), "Inside", Toast.LENGTH_LONG).show();
}
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void drawMarkerWithCircle(LatLng position){
double radiusInMeters = 500.0;
int strokeColor = 0xffff0000; //red outline
int shadeColor = 0x44ff0000; //opaque red fill
CircleOptions circleOptions = new CircleOptions().center(position).radius(radiusInMeters).fillColor(shadeColor).strokeColor(strokeColor).strokeWidth(8);
mCircle = googleMap.addCircle(circleOptions);
MarkerOptions markerOptions = new MarkerOptions().position(position);
mMarker = googleMap.addMarker(markerOptions);
}
private void initilizeMap() {
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Não foi possível carregar o mapa", Toast.LENGTH_SHORT)
.show();
}
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Android.R.id.home:
super.onBackPressed();
finish();
return true;
}
return true;
}
@Override
protected void onResume() {
super.onResume();
initilizeMap();
}
}
私は更新されたコードを実行して、主な問題が何であるかを理解しました。
onMyLocationChange()
コールバックに渡されたLocation
を使用する必要があります。これにより、現在の場所を使用して、デバイスがサークル内にあるかどうかがわかります。
googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
float[] distance = new float[2];
/*
Location.distanceBetween( mMarker.getPosition().latitude, mMarker.getPosition().longitude,
mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
*/
Location.distanceBetween( location.getLatitude(), location.getLongitude(),
mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
if( distance[0] > mCircle.getRadius() ){
Toast.makeText(getBaseContext(), "Outside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getBaseContext(), "Inside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius() , Toast.LENGTH_LONG).show();
}
}
});
これが私が実行した完全に機能する例です。これは元のコードの縮小バージョンです。
public class MainActivity extends ActionBarActivity {
private GoogleMap googleMap;
private Serializable escolas;
private ProgressDialog dialog;
private Circle mCircle;
private Marker mMarker;
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
setContentView(R.layout.activity_main);
// Loading map
initilizeMap();
// Changing map type
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// Showing / hiding your current location
googleMap.setMyLocationEnabled(true);
// Enable / Disable zooming controls
googleMap.getUiSettings().setZoomControlsEnabled(true);
// Enable / Disable my location button
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
// Enable / Disable Compass icon
googleMap.getUiSettings().setCompassEnabled(true);
// Enable / Disable Rotate gesture
googleMap.getUiSettings().setRotateGesturesEnabled(true);
// Enable / Disable zooming functionality
googleMap.getUiSettings().setZoomGesturesEnabled(true);
// Bundle extra = getIntent().getBundleExtra("extra");
//ArrayList<Escolas> objects = (ArrayList<Escolas>) extra.getSerializable("array");
try {
//test outside
double mLatitude = 37.77657;
double mLongitude = -122.417506;
//test inside
//double mLatitude = 37.7795516;
//double mLongitude = -122.39292;
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLatitude, mLongitude), 15));
MarkerOptions options = new MarkerOptions();
// Setting the position of the marker
options.position(new LatLng(mLatitude, mLongitude));
//googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
LatLng latLng = new LatLng(mLatitude, mLongitude);
drawMarkerWithCircle(latLng);
googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
float[] distance = new float[2];
/*
Location.distanceBetween( mMarker.getPosition().latitude, mMarker.getPosition().longitude,
mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
*/
Location.distanceBetween( location.getLatitude(), location.getLongitude(),
mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
if( distance[0] > mCircle.getRadius() ){
Toast.makeText(getBaseContext(), "Outside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getBaseContext(), "Inside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius() , Toast.LENGTH_LONG).show();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private void drawMarkerWithCircle(LatLng position){
double radiusInMeters = 500.0;
int strokeColor = 0xffff0000; //red outline
int shadeColor = 0x44ff0000; //opaque red fill
CircleOptions circleOptions = new CircleOptions().center(position).radius(radiusInMeters).fillColor(shadeColor).strokeColor(strokeColor).strokeWidth(8);
mCircle = googleMap.addCircle(circleOptions);
MarkerOptions markerOptions = new MarkerOptions().position(position);
mMarker = googleMap.addMarker(markerOptions);
}
private void initilizeMap() {
if (googleMap == null) {
googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(
R.id.map)).getMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Não foi possível carregar o mapa", Toast.LENGTH_SHORT)
.show();
}
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Android.R.id.home:
super.onBackPressed();
finish();
return true;
}
return true;
}
@Override
protected void onResume() {
super.onResume();
initilizeMap();
}
}
サークル内の結果:
サークル外の結果:
こんにちは私はこのコードで正しく動作しています
//Getting current location
private void getCurrentLocation() {
mMap.clear();
//Creating a location object
Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
//Getting longitude and latitude
longitude = location.getLongitude();
latitude = location.getLatitude();
//moving the map to location
moveMap();
}
Circle circle = mMap.addCircle(new CircleOptions()
.center(new LatLng(54.773097, -6.557841))
.radius(55)
.strokeColor(Color.RED)
);
pLong = location.getLongitude();
pLat = location.getLatitude();
float[] distance = new float[2];
Location.distanceBetween(pLat, pLong,
circle.getCenter().latitude, circle.getCenter().longitude, distance);
if( distance[0] > circle.getRadius() ){
Toast.makeText(getBaseContext(), "You are not in a bunker", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getBaseContext(), "You are inside a bunker", Toast.LENGTH_LONG).show();
}
}
@Daniel Nugent:imho getRadius()
は直径ではなく半径を返すため、「_/2
_」は間違っています
@WARpoluido:場所が変わるとmMarker
変数が更新されることがわかりません。 onMyLocationChange()
に指定された値を使用しないのはなぜですか?
_Location.distanceBetween( mCircle.getCenter().latitude, mCircle.getCenter().longitude, location.getLatitude(), location.getLongitude(), distance);
if( distance[0] > mCircle.getRadius() ){
...
_
受け入れられたDaniel Nugentの解は、setOnMyLocationChangeListener
がdeprecatedになっているため、もうあまり良くありません。
これがフラグメントでそれを行う現在の方法です-アクティビティのthis
でgetActivity()
を変更します:
private boolean mLocationPermissionGranted;
// The geographical location where the device is currently located. That is, the last-known
// location retrieved by the Fused Location Provider.
private Location mLastKnownLocation;
private long UPDATE_INTERVAL = 10 * 1000; /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */
private FusedLocationProviderClient mFusedLocationProviderClient;
private void addLocationChangeListener(){
// Construct a FusedLocationProviderClient.
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity());
// Create the location request to start receiving updates
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
//mLocationRequest.setMaxWaitTime(0);
//mLocationRequest.setSmallestDisplacement(0);
// Create LocationSettingsRequest object using location request
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
LocationSettingsRequest locationSettingsRequest = builder.build();
// Check whether location settings are satisfied
// https://developers.google.com/Android/reference/com/google/Android/gms/location/SettingsClient
SettingsClient settingsClient = LocationServices.getSettingsClient(getActivity());
settingsClient.checkLocationSettings(locationSettingsRequest);
// new Google API SDK v11 uses getFusedLocationProviderClient(this)
if (mLocationPermissionGranted) {
mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,
new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
// do work here
Location location = locationResult.getLastLocation();
}
},
Looper.myLooper());
} else {
getLocationPermission();
}
}