2015-07-12 75 views
0

我的應用程序應該讓用戶輸入緯度和經度值,並且MapActivity打開以這些座標爲圓心並在該區域繪製一個圓。出於某種原因,無論將哪個座標對發送到MapActivity,他的地圖總是以非洲附近海洋中間的一個點爲中心。谷歌地圖顯示不正確的座標(Android)

這個應用程序的功能直到最近才用得很好,但應用程序的其他功能工作得很好。用戶也可以選擇一個位置來圍繞地圖的中心,代碼基本上是相同的,除了放入MapActivity軟件包的緯度和經度值被硬編碼,而不是由用戶輸入。

更令人困惑的是,MapActivity接收用戶輸入的值很好,但它不會移動到該位置。我使用logcat來確保MapActivity獲得正確的值。我目前使用Android Studio version 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; 
} 

}

請讓我知道是否有再我應該提供的信息。

+0

聽起來好像你的值是(0,0),那時你將地圖居中並添加圓圈。在執行此操作時爲這些值添加日誌記錄。另外,將該代碼部分添加到您的問題中。 –

+0

我使用日誌記錄來查看地圖活動打開後日期和緯度值是多少,日誌顯示它正確接收值。我不認爲將地圖居中是問題,因爲列表中的活動使用與自定義活動相同的方式打包lat和lon值,並且該活動完美無缺。我想編輯我的帖子以添加更多我的代碼來準確顯示我在做什麼,但是我無法找到如何編輯帖子的生活。 – Ben

+0

小編輯鏈接,您問題的左下角。 –

回答

0

到目前爲止,你的代碼看起來很好。我猜你忘了將地圖攝像機移動到指定的座標中。試試這個,

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

這會將地圖攝像頭視圖移動到特定的LatLng。