【问题标题】:Drawing route on Google Maps using Google Maps Android API v2使用 Google Maps Android API v2 在 Google Maps 上绘制路线
【发布时间】:2013-12-04 09:54:29
【问题描述】:

我有一个应用程序,我在其中使用 Google Plays 新服务 API for Maps 持续跟踪用户的位置。我每秒钟都在更新位置,并且我还在检查用户活动,如静止、倾斜、车内等,以获得更好的位置跟踪。我可以使用我的代码绘制路径,但它不准确,并且与用户实际驾驶/行走的道路有很大不同。它总是在远离实际用户路径的地方画线。

我的服务:-

public class MyService extends Service implements LocationListener {

    private final Context mContext;
    private static MyService mInstance = null;
    private final static String TAG = "RidingTimerService";

    boolean isGPSEnabled = false;

    private long mStartTime = 0L;
    private long timeInMilliseconds = 0L;
    private long timeSwapBuff = 0L;
    private long updatedTime = 0L;
    private Handler mHandler = null;
    private int mHours = 0;

    // Declaring a Location Manager
    private LocationManager mLocationManager = null;
    private Location mCurrentLocation = null; // location
    private double[][] positions;
    private long[] times;
    private final Integer data_points = 2; // how many data points to calculate
    private double mTravelledDistance = 0.0f;

    private SharedPreferences mPreferences = null;
    private ArrayList<LatLng> mDirectionsPoints = new ArrayList<LatLng>();

    public boolean mIsPhoneMoving = false;
    public int mActivityType = -1;
    int counter = 0;

    private IntentFilter mBroadcastFilter;
    private DetectionRequester mDetectionRequester;
    private DetectionRemover mDetectionRemover;

    public MyService() {
        mContext = this;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
        // two arrays for position and time.
        positions = new double[data_points][2];
        times = new long[data_points];

        mStartTime = SystemClock.uptimeMillis();
        mHandler = new Handler();
        mHandler.postDelayed(countDownTimerThread, 0);
        mPreferences = getSharedPreferences(MyPreferences.PREFERENCES,
                Context.MODE_PRIVATE);
        // Create a new Intent filter for the broadcast receiver
        mBroadcastFilter = new IntentFilter(
                MyConstants.ACTION_REFRESH_STATUS_LIST);
        mBroadcastFilter.addCategory(MyConstants.CATEGORY_LOCATION_SERVICES);

        // Get detection requester and remover objects
        mDetectionRequester = new DetectionRequester(this);
        mDetectionRemover = new DetectionRemover(this);
        mDirectionsPoints.clear();
    }

    /**
     * Pause the timer
     */
    public void pauseRide() {
        timeSwapBuff += timeInMilliseconds;
        mHandler.removeCallbacks(countDownTimerThread);
        mLocationManager.removeUpdates(this);
    }

    /**
     * Restart the timer
     */
    public void reStartRide() {
        mStartTime = SystemClock.uptimeMillis();
        mHandler.postDelayed(countDownTimerThread, 0);
        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                0, 0, this);
    }

    @Override
    public void onDestroy() {
        mHandler.removeCallbacks(countDownTimerThread);
        mLocationManager.removeUpdates(this);
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        getLocation();
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * Timer thread
     */
    private final Runnable countDownTimerThread = new Runnable() {

        public void run() {
            mHours = 0;
            timeInMilliseconds = SystemClock.uptimeMillis() - mStartTime;
            updatedTime = timeSwapBuff + timeInMilliseconds;
            int secs = (int) (updatedTime / 1000);
            final int mins = secs / 60;
            mHours = mins / 60;
            secs = secs % 60;

            final Message msg = new Message();
            final Bundle bundle = new Bundle();
            bundle.putInt(MyPreferences.BROADCAST_CODES, 300);
            bundle.putString(
                    "time",
                    String.format("%02d", mHours) + ":"
                            + String.format("%02d", mins) + ":"
                            + String.format("%02d", secs));
            msg.setData(bundle);
            final Intent intent = new Intent(MyConstants.BROADCAST_INTENT);
            intent.putExtras(bundle);
            sendBroadcast(intent);
            mHandler.postDelayed(this, 1000);
        }
    };

    @Override
    public IBinder onBind(final Intent intent) {
        return null;
    }

    @Override
    public void onLocationChanged(final Location location) {
        if (location != null) {
            LocationUtils.sLatitude = location.getLatitude();
            LocationUtils.sLongitude = location.getLongitude();

            mDirectionsPoints.add(new LatLng(LocationUtils.sLatitude,
                    LocationUtils.sLongitude));
            riderLocation(location);
        } else {
            Log.i(TAG, "Location is not available.");
        }
    }

    /**
     * Calculate speed, distance and average speed. Send Broadcast which
     * received by activities
     * 
     * @param location
     */
    private void riderLocation(final Location location) {
        DecimalFormat formatter = new DecimalFormat("#0.00");
        double distance = 0.0;
        Double speed = 0.0;
        long t1 = 0l;
        final float[] results = new float[3];

        positions[counter][0] = location.getLatitude();
        positions[counter][1] = location.getLongitude();
        times[counter] = location.getTime();

        final Bundle bundle = new Bundle();
        bundle.putInt(MyPreferences.BROADCAST_CODES, 200);

        distance = calculateDistance(positions[counter][0],
                positions[counter][1], positions[(counter + (data_points - 1))
                        % data_points][0],
                positions[(counter + (data_points - 1)) % data_points][1]);

        Location.distanceBetween(positions[counter][0], positions[counter][1],
                positions[(counter + (data_points - 1)) % data_points][0],
                positions[(counter + (data_points - 1)) % data_points][1],
                results);

        mTravelledDistance += results[0] / 1000;
        LocationUtils.sDistance = formatter
                .format((mTravelledDistance * 100.0) / 100.0);

        final double averageSpeed = mTravelledDistance / mHours;
        LocationUtils.sAverageSpeed = formatter
                .format((averageSpeed * 100.0) / 100.0);

        if (location.hasSpeed()) {
            speed = location.getSpeed() * 3.6;
            LocationUtils.sSpeed = speed.intValue();
        } else {
            try {
                t1 = times[counter]
                        - times[(counter + (data_points - 1)) % data_points];
            } catch (final NullPointerException e) {
                // all good, just not enough data yet.
            }

            speed = (distance / t1) * 3.6;
            LocationUtils.sSpeed = speed.intValue();
            counter = (counter + 1) % data_points;
        }

        LocationUtils.sLatitude = location.getLatitude();
        LocationUtils.sLongitude = location.getLongitude();

        final Intent intent = new Intent(MyConstants.BROADCAST_INTENT);
        intent.putExtras(bundle);
        sendBroadcast(intent);
    }

    public void onProviderDisabled(final String arg0) {
        Toast.makeText(getApplicationContext(), "Gps Disabled",
                Toast.LENGTH_LONG).show();
    }

    public void onProviderEnabled(final String arg0) {
        Toast.makeText(getApplicationContext(), "Gps Enabled",
                Toast.LENGTH_SHORT).show();
    }

    /**
     * @return location
     */
    public Location getLocation() {
        try {
            mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

            // getting GPS status
            isGPSEnabled = mLocationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);

            if (!isGPSEnabled) {
                // no network provider is enabled
                showSettingsAlert();
            } else {
                // if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled) {
                    mLocationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER, 0, 0, this);
                    Log.d(TAG, "GPS Enabled");
                    if (mCurrentLocation == null) {
                        if (mLocationManager != null) {
                            mCurrentLocation = mLocationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);

                            if (mCurrentLocation != null) {
                                LocationUtils.sLatitude = mCurrentLocation
                                        .getLatitude();
                                LocationUtils.sLongitude = mCurrentLocation
                                        .getLongitude();
                            }
                        }
                    } else {
                        LocationUtils.sLatitude = mCurrentLocation
                                .getLatitude();
                        LocationUtils.sLongitude = mCurrentLocation
                                .getLongitude();
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return mCurrentLocation;
    }

    /**
     * @fn public static RidingTimerService getInstance()
     * @brief returns instance of the service.
     * @return RidingTimerService instance
     */
    public static MyService getInstance() {
        return mInstance;
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }

    /**
     * Reset all the values stored in Preferences
     */
    public void resetAllText() {
        mPreferences.edit().putString(MyPreferences.LATITUDE, "0.0").commit();
        mPreferences.edit().putString(MyPreferences.LONGITUDE, "0.0")
                .commit();
        mPreferences.edit().putString(MyPreferences.SPEED, "0.0").commit();
        mPreferences.edit().putString(MyPreferences.AVERAGE_SPEED, "0.0")
                .commit();
        mPreferences.edit().putString(MyPreferences.DISTANCE, "0.0").commit();
    }

    /**
     * Respond to "Start" button by requesting activity recognition updates.
     * 
     * @param view
     *            The view that triggered this method.
     */
    public void onStartUpdates() {
        // Pass the update request to the requester object
        mDetectionRequester.requestUpdates();
    }

    /**
     * Respond to "Stop" button by canceling updates.
     * 
     * @param view
     *            The view that triggered this method.
     */
    public void onStopUpdates() {
        // Pass the remove request to the remover object
        mDetectionRemover.removeUpdates(mDetectionRequester
                .getRequestPendingIntent());

        /*
         * Cancel the PendingIntent. Even if the removal request fails,
         * canceling the PendingIntent will stop the updates.
         */
        mDetectionRequester.getRequestPendingIntent().cancel();
    }

    /**
     * Function to show settings alert dialog On pressing Settings button will
     * lauch Settings Options
     * */
    public void showSettingsAlert() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
        alertDialog.setTitle("GPS");
        alertDialog.setMessage("GPS is not enabled. Do you want to enable it?");

        // On pressing Settings button
        alertDialog.setPositiveButton("Settings",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(
                                Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        mContext.startActivity(intent);
                    }
                });

        // on pressing cancel button
        alertDialog.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });

        // Showing Alert Message
        alertDialog.show();
    }

    /**
     * @return List of Direction points
     */
    public ArrayList<LatLng> getDirectionsPoints() {
        if (mDirectionsPoints != null) {
            return mDirectionsPoints;
        } else {
            mDirectionsPoints = new ArrayList<LatLng>();
            return mDirectionsPoints;
        }
    }

    /**
     * Calculate distance
     * 
     * @param lat1
     * @param lon1
     * @param lat2
     * @param lon2
     * @return
     */
    private double calculateDistance(final double lat1, final double lon1,
            final double lat2, final double lon2) {
        // haversine great circle distance approximation, returns meters
        final double theta = lon1 - lon2;
        double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
                + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
                * Math.cos(deg2rad(theta));
        dist = Math.acos(dist);
        dist = rad2deg(dist);
        dist = dist * 60; // 60 nautical miles per degree of seperation
        dist = dist * 1852; // 1852 meters per nautical mile
        return dist;
    }

    private double deg2rad(final double deg) {
        return (deg * Math.PI / 180.0);
    }

    private double rad2deg(final double rad) {
        return (rad * 180.0 / Math.PI);
    }
}

我每 1 秒更新一次位置,每 3 秒更新一次活动识别。我能够获取位置,但在 Google 地图中未正确绘制路径。

绘制路径的代码:-

public class MapsActivity extends FragmentActivity {

    private static GoogleMap mGoogleMap = null;
    private static final String TAG = "MapsActivity";
    private Button mBtnStartRide, mBtnPauseRide, mBtnStopRide = null;
    private static TextView mTxtLatLong, mTxtTimer, mTxtTotalSize,
            mTxtSpeed = null;
    private static PolylineOptions mPolyLineOptions = null;
    // Storing the directions returned by the direcction api
    private SharedPreferences mPreferences = null;
    private MapsBroadcastReceiver receiver = null;

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

        receiver = new MapsBroadcastReceiver();
        mPreferences = getSharedPreferences(TestPreferences.PREFERENCES,
                Context.MODE_PRIVATE);

        mTxtLatLong = (TextView) findViewById(R.id.txtLatLong);
        mTxtTimer = (TextView) findViewById(R.id.txtTimer);
        mTxtTotalSize = (TextView) findViewById(R.id.txtDirectionsSize);
        mTxtSpeed = (TextView) findViewById(R.id.txtSpeed);

        mBtnStartRide = (Button) findViewById(R.id.btn_start_ride);
        mBtnPauseRide = (Button) findViewById(R.id.btn_pause_ride);
        mBtnStopRide = (Button) findViewById(R.id.btn_stop_ride);

        final Button mBtnCenter = (Button) findViewById(R.id.btn_center);
        mBtnCenter.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                animateCameraTo();
            }
        });

        mBtnStartRide.setOnClickListener(btnStartRideClickListener);
        mBtnPauseRide.setOnClickListener(btnPauseRideClickListener);
        mBtnStopRide.setOnClickListener(btnStopRideClickListener);

        initilizeMap();
    }

    /**
     * Start Ride Button Click Listener
     */
    private OnClickListener btnStartRideClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (mPreferences.getBoolean(TestPreferences.IS_RIDE_PAUSE, false)) {
                if (MyService.getInstance() != null) {
                    MyService.getInstance().reStartRide();
                }
            } else {
                startService(new Intent(MapsActivity.this,
                        MyService.class));
            }

            mPreferences.edit().putBoolean(TestPreferences.IS_RIDE_START, true)
                    .commit();
            mPreferences.edit().remove(TestPreferences.IS_RIDE_PAUSE).commit();
            mPreferences.edit().remove(TestPreferences.IS_RIDE_STOPPED)
                    .commit();

            mBtnStartRide.setVisibility(View.GONE);
            mBtnPauseRide.setVisibility(View.VISIBLE);
            mBtnStopRide.setVisibility(View.VISIBLE);
        }
    };

    /**
     * Start Ride Button Click Listener
     */
    private OnClickListener btnPauseRideClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            MyService.getInstance().pauseRide();

            mPreferences.edit().putBoolean(TestPreferences.IS_RIDE_PAUSE, true)
                    .commit();
            mPreferences.edit()
                    .putBoolean(TestPreferences.IS_RIDE_START, false).commit();
            mBtnStartRide.setVisibility(View.VISIBLE);
            mBtnPauseRide.setVisibility(View.GONE);
            mBtnStopRide.setVisibility(View.VISIBLE);
        }
    };

    /**
     * Stop Ride Button Click Listener
     */
    private OnClickListener btnStopRideClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            stopService(new Intent(MapsActivity.this, MyService.class));
            mPreferences.edit().remove(TestPreferences.IS_RIDE_PAUSE).commit();
            mPreferences.edit()
                    .putBoolean(TestPreferences.IS_RIDE_START, false).commit();
            mPreferences.edit()
                    .putBoolean(TestPreferences.IS_RIDE_STOPPED, true).commit();
            mBtnStartRide.setVisibility(View.VISIBLE);
            mBtnPauseRide.setVisibility(View.GONE);
            mBtnStopRide.setVisibility(View.GONE);
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(receiver, new IntentFilter(
                MyConstants.BROADCAST_INTENT));
        initilizeMap();

        if (mPreferences.getBoolean(TestPreferences.IS_RIDE_START, false)) {
            mBtnStartRide.setVisibility(View.GONE);
            mBtnPauseRide.setVisibility(View.VISIBLE);
            mBtnStopRide.setVisibility(View.VISIBLE);
        } else if (mPreferences
                .getBoolean(TestPreferences.IS_RIDE_PAUSE, false)) {
            mBtnStartRide.setVisibility(View.VISIBLE);
            mBtnPauseRide.setVisibility(View.GONE);
            mBtnStopRide.setVisibility(View.VISIBLE);
        } else if (mPreferences.getBoolean(TestPreferences.IS_RIDE_STOPPED,
                false)) {
            // Show start button and gone Pause & Stop both
            mBtnStartRide.setVisibility(View.VISIBLE);
            mBtnPauseRide.setVisibility(View.GONE);
            mBtnStopRide.setVisibility(View.GONE);
        } else {
            // Show start button and gone Pause & Stop both
            mBtnStartRide.setVisibility(View.VISIBLE);
            mBtnPauseRide.setVisibility(View.GONE);
            mBtnStopRide.setVisibility(View.GONE);
        }

        setAllText();
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(receiver);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mGoogleMap = null;
    }

    /**
     * Function to load map. If map is not created it will create it for you
     * */
    private void initilizeMap() {
        if (mGoogleMap == null) {
            mGoogleMap = ((MapFragment) getFragmentManager().findFragmentById(
                    R.id.map)).getMap();
            // check if map is created successfully or not
            if (mGoogleMap == null) {
                Toast.makeText(getApplicationContext(),
                        "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                        .show();
            } else {
                mPolyLineOptions = new PolylineOptions().width(6).color(
                        Color.BLUE);
                mGoogleMap.setTrafficEnabled(true);
                mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
                mGoogleMap.getUiSettings().setRotateGesturesEnabled(true);
                mGoogleMap.getUiSettings().setCompassEnabled(true);
                mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
                mGoogleMap.getUiSettings().setZoomControlsEnabled(true);

                if (MyService.getInstance() != null
                        && MyService.getInstance().getDirectionsPoints() != null
                        && !MyService.getInstance().getDirectionsPoints()
                                .isEmpty()
                        && MyService.getInstance().getDirectionsPoints()
                                .size() >= 1) {
                    mGoogleMap.addMarker(new MarkerOptions()
                            .position(
                                    MyService.getInstance()
                                            .getDirectionsPoints().get(0))
                            .anchor(0.8f, 1.0f).title("Your Location"));

                    animateCameraTo(MyService.getInstance()
                            .getDirectionsPoints().get(0).latitude,
                            MyService.getInstance().getDirectionsPoints()
                                    .get(0).longitude);
                }
            }
        } else {
            mPolyLineOptions = new PolylineOptions().width(6).color(Color.BLUE);
            mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
            mGoogleMap.getUiSettings().setRotateGesturesEnabled(true);
            mGoogleMap.getUiSettings().setCompassEnabled(true);
            mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
            mGoogleMap.getUiSettings().setZoomControlsEnabled(true);

            if (MyService.getInstance() != null
                    && MyService.getInstance().getDirectionsPoints() != null
                    && !MyService.getInstance().getDirectionsPoints()
                            .isEmpty()
                    && MyService.getInstance().getDirectionsPoints().size() >= 1) {

                Log.i(TAG, "Lat long in resume2222222222 = "
                        + MyService.getInstance().getDirectionsPoints()
                                .get(0).latitude
                        + ", "
                        + MyService.getInstance().getDirectionsPoints()
                                .get(0).longitude);

                mGoogleMap.addMarker(new MarkerOptions()
                        .position(
                                MyService.getInstance().getDirectionsPoints()
                                        .get(0)).anchor(0.8f, 1.0f)
                        .title("Your Location"));

                animateCameraTo(MyService.getInstance().getDirectionsPoints()
                        .get(0).latitude, MyService.getInstance()
                        .getDirectionsPoints().get(0).longitude);
            }
        }
    }

    /**
     * @author Scorpion
     * 
     */
    private class MapsBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {

            switch (intent.getExtras().getInt(TestPreferences.BROADCAST_CODES)) {
            case 100:
                showErrorDialog(intent.getExtras().getInt(
                        TestPreferences.BROADCAST_CODES));
                break;

            case 200:
                setAllText();
                break;

            case 300:
                if (intent.getExtras().getString("time") != null) {
                    mTxtTimer.setText("Timer - "
                            + intent.getExtras().getString("time"));
                } else {
                    mTxtTimer.setText("Timer - 00:00:00");
                }
                break;

            default:
                break;
            }

            if (MyService.getInstance() != null
                    && !MyService.getInstance().getDirectionsPoints()
                            .isEmpty()
                    && MyService.getInstance().getDirectionsPoints().size() == 1) {
                mGoogleMap.addMarker(new MarkerOptions()
                        .position(
                                MyService.getInstance().getDirectionsPoints()
                                        .get(0)).anchor(0.8f, 1.0f)
                        .title("Your Location"));
            }

        }
    }

    /**
     * 
     */
    public void setAllText() {
        mTxtLatLong.setText("Lat - " + LocationUtils.sLatitude + ", Lng - "
                + LocationUtils.sLongitude);

        mTxtSpeed.setText("Speed - " + LocationUtils.sSpeed);
        mTxtTotalSize.setText("Distance - " + LocationUtils.sDistance);
    }

    /**
     * Animate to position on Google Maps
     * 
     * @param lat
     * @param lng
     */
    private void animateCameraTo() {
        // Saving the points in a polyline

        if (MyService.getInstance() != null
                && MyService.getInstance().getDirectionsPoints() != null
                && !MyService.getInstance().getDirectionsPoints().isEmpty()) {
            mPolyLineOptions.geodesic(true);
            mPolyLineOptions.addAll(MyService.getInstance()
                    .getDirectionsPoints());

            // Drawing the path on the map Polyline route =
            mGoogleMap.addPolyline(mPolyLineOptions);

            int index = MyService.getInstance().getDirectionsPoints().size() - 1;
            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(MyService.getInstance().getDirectionsPoints()
                            .get(index)).zoom(20).build();

            mGoogleMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(cameraPosition));
        }

    }

    /**
     * Animate to position on Google Maps
     * 
     * @param lat
     * @param lng
     */
    private void animateCameraTo(final double lat, final double lng) {
        // Saving the points in a polyline
        if (MyService.getInstance() != null
                && MyService.getInstance().getDirectionsPoints() != null
                && !MyService.getInstance().getDirectionsPoints().isEmpty()) {
            mPolyLineOptions.geodesic(true);
            mPolyLineOptions.addAll(MyService.getInstance()
                    .getDirectionsPoints());

            // Drawing the path on the map
            mGoogleMap.addPolyline(mPolyLineOptions);
            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(new LatLng(lat, lng)).zoom(20).build();

            mGoogleMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(cameraPosition));
        }

    }

    /**
     * Show a dialog returned by Google Play services for the connection error
     * code
     * 
     * @param errorCode
     *            An error code returned from onConnectionFailed
     */
    private void showErrorDialog(int errorCode) {

        // Get the error dialog from Google Play services
        Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(errorCode,
                MapsActivity.this,
                LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);

        // If Google Play services can provide an error dialog
        if (errorDialog != null) {

            // Create a new DialogFragment in which to show the error dialog
            ErrorDialogFragment errorFragment = new ErrorDialogFragment();

            // Set the dialog in the DialogFragment
            errorFragment.setDialog(errorDialog);

            // Show the error dialog in the DialogFragment
            errorFragment.show(getSupportFragmentManager(),
                    LocationUtils.APPTAG);
        }
    }
}

从位置提供者获得的坐标结果:- 23.030392522689674,72.5570888165469,23.030408166940184,72.55708600340783,23.030451207802273,72.55708215400317,23.030448342522195,72.5570607428365,23.03045605637773,72.55702903413072,23.03046687434995,72.55702007867455,23.030481227996425,72.55702017125606,23.03049188235562,72.55701618151457,23.030501580461667,72.55701051075931,23.030506644074638,72.55700568837983,23.030510243171772,72.55699463185964,23.03051656621021,72.55698811382064,23.030523584332027, 72.55698589863236,23.030527893257556,72.5569835596,23.03052731568596,72.55698681171178,23.030533706759005,72.55699683791043,23.03053795413862,72.5570022232021,23.03054422659466,72.55700788646914,23.030550353227323,72.5570133047868,23.03056167617575,72.5570171806126,23.030572274532982,72.55702744953462,23.03057623596164,72.55703687229187,23.03058756510295,72.55703589208271,23.030591797598742,72.5570396833694,23.030597556470788,72.55703954449652, 23.030602030769657, 72.55704359454182, 23.030 606735158617,72.55704993131606,23.030611670633565,72.55705060538087,23.030618875802222,72.55705181604097,23.030629137631596,72.55705043471286,23.030651405170016,72.55705440295588,23.03066642161307,72.55705285209174,23.030690454277963,72.55703884780276,23.030708214416187,72.55703489882957,23.03072341369183,72.5570340196122,23.030737371000015,72.55703289416898,23.03075088423441,72.55703750535102,23.030767572625837,72.55704489874579,23.030794398930176, 72.55703870239826,23.03081655932613,72.55702474270966,23.030827505666753,72.5570121351611,23.03083720431765,72.55700390084714,23.03084624667527,72.55700122660554,23.030859495795887,72.55699948514881,23.030870357210333,72.55699625144317,23.030881843633054

【问题讨论】:

  • 这有点困难,很多编码很可能与问题无关。但是 LocationUtils 的静态字段的使用是非常可疑的。如果这个类同时被不同的线程使用,那么结果坐标是不可预测的。
  • 我使用 LocationUtils 类来存储速度、距离、位置(纬度/经度),这些值被其他活动使用。所以我同意同时使用这些值,但只有我的服务在其中写入值,其他活动和类只读取这些值来显示它。没有别的...
  • 您是否检查过一次 GPS 更新调用 onLocationChanged 的​​频率?我不确定如果多次注册同一个 LocationListener 会发生什么(就像您的服务中的情况一样)。我记得我以某种方式设法被多次调用。但我不记得是相同的情况还是我偶然创建了多个 LocationListeners 实例。
  • 我每秒获取位置更新,我只注册了 1 个位置侦听器而不是多个。而且我也在检查速度,所以如果速度为 0,我不会在我的列表中添加点并避免这些点。主要问题是绘制的路线实际上并不是它必须绘制的地方。由于某种原因,它总是被拉出道路;不知道为什么。
  • 现在,我看到 requestLocationUpdates 两次。其中一个是在 reStart 方法中,它似乎被多次调用。结合静态 LocationUtils 这看起来仍然很可疑。

标签: android google-maps-android-api-2 google-polyline


【解决方案1】:

此代码将起作用

GoogleMap map;
   // ... get a map.
   // Add a thin red line from London to New York.
   Polyline line = map.addPolyline(new PolylineOptions()
       .add(new LatLng(51.5, -0.1), new LatLng(40.7, -74.0))
       .width(5)
       .color(Color.RED));

【讨论】:

  • 我使用的是相同的代码,但它没有按要求工作。它从骑行中绘制路线,而不是用户驾驶/步行的确切位置。
  • @Scorpion 为了使其按要求工作更好,您可以做的是将位置更新请求中的准确度设置为优先准确度并缩短更新间隔位。
【解决方案2】:

您应该将您的问题分解为数据收集和数据显示方面。

因此,取两个您确切知道的坐标并在谷歌地图上绘制一条直线折线。 如果它真的显示在错误的位置,GoogleMap 确实有一个错误,顺便说一句我不相信。

然后打印出您的坐标,例如在绘制它们之前到 LogCat 并检查坐标。如果他们错了,这不是 GoogleMaps 的问题,而是 LocationProvider 或您如何使用它的问题。

如果坐标收集正确,您可以通过某种方式从 LogCat 中提取它们并直接在代码中使用它们来绘制折线。如果然后折线被移位,您可能又在 GoogleMap 中发现了一个错误。然后你应该在这里粘贴坐标,以便有人可以复制它。它可能取决于设备。我从来没有与地图不匹配的折线。

【讨论】:

  • 我已经添加了从位置提供者那里获得的位置。你知道我怎样才能从谷歌地图上的这个位置获取路线,我不是在问 android 从位置绘制路线。我想在网上交叉检查这个位置。有什么办法可以交叉检查吗?
  • 或者从定位结果可以判断它们是否正确?
  • 得到了这个网站..darrinward.com/lat-long 我在其中添加了我的所有位置,它显示的结果与我的设备上的结果相同。所以我们可以说问题出在我从位置提供者那里得到的位置(纬度/经度)。但我不认为这是一个问题,我还缺少其他东西。
  • 也许您的 GPS 有点不准确。我认为有很多应用程序可以在地图上跟踪和显示路线。只需在同一设备上尝试它们,它们是否会显示更好的结果。
【解决方案3】:

您绘制路径的代码看起来很奇怪。 在for-loop 内,您应该只将点添加到PolylineOptions 的实例(您在进入for 循环之前创建)。

然后,在for-loop 之后,您可以将widthcolor 等添加到polylineOptions object,最后在mGoogleMap.addPolyline() 中使用。

在您的编码中,您以某种方式为每个点添加了一个新的polyline(我想知道这是否会画线,因为每条“线”仅包含一个点。)。

【讨论】:

  • 感谢您的评论。最初,我在代码中更新的循环内使用了 PolyLineOptions。但在这方面,路径也在远离道路,我在路上驾驶车辆,但我的路径总是显示在远离道路的地方......这是代码的主要问题......
  • 我很确定,这个问题与绘制折线无关,而是来自 RidingTimerService 的 LatLng 点。 (这是您自己的类还是某个库?找不到它。)我有一个类似的应用程序,其中折线与我的真实方式完美匹配。
  • 它是我自己的类,不使用任何库。如果你没有任何问题,你能分享一些你的代码的sn-p吗?我使用了来自 android 开发者网站的代码,并使用了 Google Maps Android API v2 最新代码示例,并为此使用了 Google Play services sdk...
  • 为了获得准确的位置,我将位置更新间隔设置为 1 秒。在 onLocationChanged 方法中,我将 lat、long 存储在一个列表中,并从该列表中我在谷歌地图上绘制路径
  • 我已经添加了我的服务类的完整源代码以供参考。如果你能在这方面帮助我,那对我来说将是很大的帮助..
猜你喜欢
  • 2012-12-05
  • 1970-01-01
  • 2013-02-12
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
  • 2013-01-20
  • 1970-01-01
相关资源
最近更新 更多