Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 谷歌地图显示不正确的坐标(Android)_Java_Android_Google Maps Android Api 2 - Fatal编程技术网

Java 谷歌地图显示不正确的坐标(Android)

Java 谷歌地图显示不正确的坐标(Android),java,android,google-maps-android-api-2,Java,Android,Google Maps Android Api 2,我的应用程序应该让用户输入纬度和经度值,然后围绕这些坐标打开一个MapActivity,并在该区域上画一个圆圈。由于某种原因,无论什么样的坐标对被发送到MaPcActuple,He图总是围绕在非洲附近的海洋中的一个点。 直到最近,应用程序的这个功能还可以正常工作,但应用程序的另一个功能也可以正常工作。用户还可以选择一个位置以使地图居中,代码基本相同,只是为MapActivity放入捆绑包的纬度和经度值是硬编码的,而不是用户输入的 更令人困惑的是,MapActivity接收到用户输入的值,但它没有

我的应用程序应该让用户输入纬度和经度值,然后围绕这些坐标打开一个MapActivity,并在该区域上画一个圆圈。由于某种原因,无论什么样的坐标对被发送到MaPcActuple,He图总是围绕在非洲附近的海洋中的一个点。 直到最近,应用程序的这个功能还可以正常工作,但应用程序的另一个功能也可以正常工作。用户还可以选择一个位置以使地图居中,代码基本相同,只是为MapActivity放入捆绑包的纬度和经度值是硬编码的,而不是用户输入的

更令人困惑的是,MapActivity接收到用户输入的值,但它没有移动到该位置。我使用logcat来确保MapActivity得到了正确的值

我目前正在使用Android Studio 1.2.1.1版

以下是经过编辑以包含所有代码的地图活动代码

private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private Location mCurrentLocation;
private double targetLat;
private double targetLon;
private double latRandom;
private double lonRandom;
private int radius;
private int circleState;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map);
    Bundle b = getIntent().getExtras();
    targetLat = b.getDouble("lat");
    targetLon = b.getDouble("lon");
    Log.i("MapActivity","targetLat = "+targetLat);
    Log.i("MapActivity","targetLon = "+targetLon);
    radius = getIntent().getExtras().getInt("rad");
    setUpMapIfNeeded();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();


}

@Override
protected void onResume() {
    super.onResume();
    setUpMapIfNeeded();
}

/**
 * Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
 * installed) and the map has not already been instantiated.. This will ensure that we only ever
 * call {@link #setUpMap()} once when {@link #mMap} is not null.
 * <p/>
 * If it isn't installed {@link SupportMapFragment} (and
 * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
 * install/update the Google Play services APK on their device.
 * <p/>
 * A user can return to this FragmentActivity after following the prompt and correctly
 * installing/updating/enabling the Google Play services. Since the FragmentActivity may not
 * have been completely destroyed during this process (it is likely that it would only be
 * stopped or paused), {@link #onCreate(Bundle)} may not be called again so we should call this
 * method in {@link #onResume()} to guarantee that it will be called.
 */
private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the map.
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
}

/**
 * This is where we can add markers or lines, add listeners or move the camera. In this case, we
 * just add a marker near Africa.
 * <p/>
 * This should only be called once and when we are sure that {@link #mMap} is not null.
 */
private void setUpMap() {
    mMap.setMapType(MAP_TYPE_HYBRID); //set map type

    double shiftFactor = .0001;
    int color = getIntent().getExtras().getInt("color");

    while(findDistance(targetLat,targetLon,targetLat+shiftFactor,targetLon+shiftFactor)<radius){
        shiftFactor+=.0001;
    }


    latRandom = (Math.random()*shiftFactor);
    lonRandom = (Math.random()*shiftFactor);
    int rand2 = (int)(Math.random()*2)+1;
    if(rand2==1){
        latRandom = 0 - latRandom;
    }
    rand2 = (int)(Math.random()*2)+1;
    if(rand2==1){
        lonRandom = 0 - lonRandom;
    }


    LatLng loc = new LatLng(targetLat+latRandom,targetLon + lonRandom); //lat and long values for target(shift)
    CircleOptions circOpt = new CircleOptions(); //circle appearance
    circOpt.center(loc).radius(radius);
    circOpt.strokeWidth(0);
    circOpt.fillColor(color);
    mMap.addCircle(circOpt);
    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 19)); //move screen to target(shift)
    mMap.setMyLocationEnabled(true);
    circleState=3;

}
@Override
protected void onStart(){
    super.onStart();
    mGoogleApiClient.connect();
}
@Override
protected void onStop(){
    super.onStart();
    mGoogleApiClient.disconnect();
}

@Override
public void onConnected(Bundle bundle) {
    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(1000);
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}

@Override
public void onConnectionSuspended(int i) {
    Toast.makeText(this,"Connection Suspended", Toast.LENGTH_SHORT).show();
}

@Override
public void onLocationChanged(Location location) {
    double lat = location.getLatitude();
    double lon = location.getLongitude();
    double difference = findDistance(lat,lon,targetLat,targetLon);
    if(difference<radius && difference > 4&& circleState==3){
        mMap.clear();
        LatLng loc = new LatLng(targetLat+latRandom,targetLon + lonRandom); //lat and long values for target(shift)
        CircleOptions circOpt = new CircleOptions(); //circle appearance
        circOpt.center(loc).radius(radius);
        circOpt.strokeWidth(0);
        circOpt.fillColor(Color.argb(120, 0, 0, 255));
        mMap.addCircle(circOpt);
        circleState = 2;
    }
    else if(difference<4&&difference > 2 && circleState==2){
        mMap.clear();
        LatLng loc = new LatLng(targetLat,targetLon); //lat and long values for target(not shifted)
        CircleOptions circOpt = new CircleOptions(); //circle appearance
        circOpt.center(loc).radius(4); //Make smaller search circle
        circOpt.strokeWidth(0);
        circOpt.fillColor(Color.argb(120, 0, 255, 0));
        mMap.addCircle(circOpt);
        circleState = 1;
    }
    else if(difference<3&&circleState==1){
        mMap.addCircle(new CircleOptions().center(new LatLng(targetLat,targetLon)).radius(1).strokeWidth(0).fillColor(Color.RED));
        circleState=0;
    }

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Toast.makeText(this,"Connection Failed",Toast.LENGTH_SHORT).show();
}

//Precondition: two pairs of real coordinates
public double findDistance(double lat1,double lon1, double lat2, double lon2){
    final int EARTH_RADIUS = 6371000;
    double a = Math.sin(Math.toRadians(lat2 - lat1)/2)*Math.sin(Math.toRadians(lat2 - lat1)/2)+
            Math.cos(Math.toRadians(lat1))*Math.cos(Math.toRadians(lat2))*
                    Math.sin(Math.toRadians(lon2 - lon1)/2)*Math.sin(Math.toRadians(lon2 - lon1)/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    return EARTH_RADIUS * c ; //Return the distance
}
}

以下是“活动”的代码,其中包含可从中选择的位置列表以及硬编码值。目前只有一个地点

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quest_select);
    listView = (ListView)findViewById(R.id.list);
    String [] places = new String[] {"Light"}; //add more presets here, add coordinates to switch statement
    ArrayAdapter<String>adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,android.R.id.text1,places);
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            switch(position){
                case 0:
                    startMap(view,43.005993,-75.984314);
                    break;

                default:
                    Toast.makeText(getApplicationContext(), "Not a valid selection",Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    });
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_quest_select, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
public void startMap(View view,double latVal,double lonVal){
    Intent intent = new Intent(this, MapActivity.class);
    Bundle b = new Bundle();
    b.putDouble("lat",latVal);
    b.putDouble("lon", lonVal);
    b.putInt("rad", 50);
    b.putInt("color", Color.argb(120,0,255,0));
    intent.putExtras(b);
    startActivity(intent);
}
最后是活动中的代码,用户在其中输入纬度和经度值。编辑以包含整个代码

public class CustomOptions extends ActionBarActivity {
private Spinner colorSelect;
private EditText latSet;
private EditText lonSet;
private double lat, lon;
private SeekBar radSet;
private TextView currentRadius;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_custom_options);
    colorSelect = (Spinner) findViewById(R.id.spinner1);
    String [] colors = new String[]{"Red","Blue","Green","Orange"};
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,colors);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    colorSelect.setAdapter(adapter);
    latSet = (EditText)findViewById(R.id.editText);
    lonSet = (EditText)findViewById(R.id.editText2);
    radSet = (SeekBar)findViewById(R.id.seekBar);
    radSet.setProgress(50);
    radSet.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            currentRadius.setText(String.valueOf(radSet.getProgress())+"m");
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });
    currentRadius = (TextView)findViewById(R.id.currentRadius);
    currentRadius.setText(radSet.getProgress() + "m");

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_custom_options, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
public void startMap(View view){

    if(checkValidity()&&Math.abs(lat)<=90&&Math.abs(lon)<=180) {
        Intent intent = new Intent(this, MapActivity.class);
        Bundle b = new Bundle();
        b.putDouble("lat",lat);
        b.putDouble("lon", lon);
        b.putInt("rad", radSet.getProgress());
        switch(colorSelect.getSelectedItemPosition()){
            case 0:
                b.putInt("color", Color.argb(120, 255, 0, 0));
                break;
            case 1:
                b.putInt("color", Color.argb(120, 0, 255, 0));
                break;
            case 2:
                b.putInt("color", Color.argb(120, 0, 0, 255));
                break;
            case 3:
                b.putInt("color",Color.argb(120,255,140,0));
                break;
            default:
                Toast.makeText(this,"Abort Captain!",Toast.LENGTH_SHORT).show();
                break;
        }
        intent.putExtras(b);
        Toast.makeText(this,"starting activity",Toast.LENGTH_SHORT).show();
        startActivity(intent);
    }
    else{

        if(Math.abs(lat)>90) Toast.makeText(this, "Invalid Latitude Value",Toast.LENGTH_SHORT).show();
        if(Math.abs(lat)>90) Toast.makeText(this, "Invalid Longitude Value",Toast.LENGTH_SHORT).show();

    }
}
public boolean checkValidity() {
    if(TextUtils.isEmpty(latSet.getText().toString())){
        Toast.makeText(this, "Set a latitude value",Toast.LENGTH_SHORT).show();
        return false;
    }
    if(TextUtils.isEmpty(lonSet.getText().toString())){
        Toast.makeText(this, "Set a longitude value",Toast.LENGTH_SHORT).show();
        return false;
    }
    return true;
}
}


如果我还需要提供更多信息,请告诉我。

到目前为止,您的代码看起来还不错。我猜你忘了把地图相机移到指定的坐标。试试这个

LatLng my_latlng= new LatLng(-33.867, 151.206);
map.setMyLocationEnabled(true);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(my_latlng, 13));

这会将地图摄影机视图移动到特定的板条。

听起来,在地图居中并添加圆时,您的值是0,0。为执行此操作时的值添加日志记录。另外,将代码部分添加到您的问题中。我使用日志记录来查看在打开Map活动后te lat和lon值的情况,日志显示它正确接收了值。我不认为将地图居中是个问题,因为具有列表的活动以与自定义活动相同的方式绑定lat和lon值,并且该活动工作得非常好。我想编辑我的帖子,添加更多代码,以准确显示我在做什么,但我找不到如何为我的一生编辑帖子。小编辑链接,您问题的左下方。谢谢,我编辑了我的问题,以包含地图活动和自定义位置活动的所有代码。我运行了您的代码,对我来说效果很好。我通过Intent Extras将数据发送到MapActivity,它在地图上的确切位置放置了一个绿色圆圈,并直接位于圆圈的中心。