Using the Golden Map MapView

Keywords: Android Amap SDK PHP

Skip importing the Golden Map, import the package, and go directly to use

1. Use in Activity

1. Use mapview in layout

<com.amap.api.maps.MapView
        android:id="@+id/amapView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="#fff"
        android:clickable="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/estimate_payment" />

2. Initialize the map in Actvity
Problems encountered:
(1) MapView.onCreate was not called in onCreate, resulting in a blank map
(2) MapView.OnPause is used in onPause, and MapView.OnResume is not used in onResume, causing the mapview to become stuck (neither moving the map nor zooming gestures work)
(3) Hide precision circles, zoom buttons, custom positioning bluespots ( https://lbs.amap.com/api/android-sdk/guide/interaction-with-map/control-interaction)
(4) Custom positioning button: Because Golden Map does not provide a way to replace the positioning button, you need to hide the positioning button of the original map, add a custom button, and perform the positioning after clicking.( http://lbsbbs.amap.com/forum.php?mod=viewthread&tid=14167)
Effect:

    @InjectView(R.id.amapView)
    MapView mBmapView;
    //Declare AMapLocationClient class object
    private AMapLocationClient mLocationClient = null;
    //Declare AMapLocationClientOption object
    private AMapLocationClientOption mLocationOption = null;
    private AMap mAmap;
    private static final int MAP_ZOOM_SIZE = 18;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Execute mMapView.onCreate(savedInstanceState) when activity executes onCreate to create a map
        mBmapView.onCreate(savedInstanceState);
    }
    
    @Override
    protected void onPause() {
        if (mBmapView != null) {
        //Execute mMapView.onPause () when activity executes onPause, suspending map drawing
            mBmapView.onPause();
        }
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
        }
        super.onPause();
    }
    
    @Override
    protected void onResume() {
    //Execute mMapView.onResume() when activity executes onResume, redraw the loaded map
        mBmapView.onResume();
        if (mLocationClient != null) {
            mLocationClient.startLocation();
        }
        super.onResume();
    }
    
    @Override
    protected void onDestroy() {
        LogUtils.i("onDestroy");
        clearRouteLines();
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
        }
        if (mBmapView != null) {
        //Execute mMapView.onDestroy() when activity executes onDestroy, destroying the map
            mBmapView.onDestroy();
        }
        super.onDestroy();
    }
    
    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        //Execute mMapView.onSaveInstanceState (outState) when activity executes onSaveInstanceState to save the current state of the map
        mBmapView.onSaveInstanceState(outState);
    }

     private void initMap() {
        if (mAmap == null) {
            mAmap = mBmapView.getMap();
        }
        //Set the zoom level of the map you want to show
        CameraUpdate mCameraUpdate = CameraUpdateFactory.zoomTo(MAP_ZOOM_SIZE);
        mAmap.moveCamera(mCameraUpdate);

        //Custom positioning of bluespots:
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.location_indicator));
        //Continuously locate and move your view to the center of the map, locating the bluespot and following the device.(position once a second)
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
        //Set Precision Circle (Hide Precision Circle)
        myLocationStyle.strokeColor(Color.argb(0, 0, 0, 0));
        myLocationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));
        //Hide Golden logo
        mAmap.getUiSettings().setLogoBottomMargin(-60);
        //Set Style to locate bluespots
        mAmap.setMyLocationStyle(myLocationStyle);
        
        //Initialize Location
        mLocationClient = new AMapLocationClient(getApplicationContext());
        //Set Location Callback Listening
        mLocationClient.setLocationListener(this);
        //Initialize AMapLocationClientOption object
        mLocationOption = new AMapLocationClientOption();
        //Set the positioning mode to AMapLocationMode.Hight_Accuracy, High Precision mode.
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //Get the highest accuracy results in the last 3 seconds:
        //Set the setOnceLocationLatest(boolean b) interface to true, and the SDK will return the highest accuracy results in the last 3 seconds when you start positioning.
        //If set to true, the setOnceLocation(boolean b) interface will also be set to true, otherwise it will not default to false.
        mLocationOption.setOnceLocationLatest(true);
        //Set whether to return address information (default return address information)
        mLocationOption.setNeedAddress(true);
        //Sets whether simulation locations are allowed, defaults to true, and allows simulation locations
        mLocationOption.setMockEnable(false);
        //Turn off caching
        mLocationOption.setLocationCacheEnable(false);
        mLocationClient.setLocationOption(mLocationOption);

        // Set to true to start showing positioning bluespots, false to hide positioning bluespots and not locate them, default is false
        mAmap.setMyLocationEnabled(true);
        //Hide the zoom button in the lower right corner
        mAmap.getUiSettings().setZoomControlsEnabled(false);
        //Set the default location button to not display, display the custom location button, and set the click event.
        mAmap.getUiSettings().setMyLocationButtonEnabled(false);
        
        //Start Location
        mLocationClient.startLocation();
    }

Hide the positioning icon for the Gourde map:

//Set the default location button to not display, display the custom location button, and set the click event.
mAmap.getUiSettings().setMyLocationButtonEnabled(false);

Set the icon's shaded attribute elevation (background s will take effect)

    <ImageView
        android:id="@+id/im_location"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_gravity="right"
        android:layout_margin="10dp"
        android:background="@drawable/roadrescue_location_btn_selector"
        android:clickable="true"
        android:elevation="2dp"
        android:scaleType="center"
        android:src="@drawable/location_btn"
        app:layout_constraintRight_toRightOf="parent" />

Set click events for custom positioning icons

    @OnClick({R.id.im_location })
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.im_location:
                //Custom positioning control that moves to the positioning point, animateCamera animation effect, set the level of map zoom you want to show
                CameraUpdate mCameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, MAP_ZOOM_SIZE);
                mAmap.moveCamera(mCameraUpdate);
                break;
        }
    }

2. Use in Fragment s

Create maps in onCreateView, like any other Activity

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        mBmapView.onCreate(savedInstanceState);
        return mRootView;
    }

3. Route Planning

Given the starting point (available through onLocationChanged) and the ending point (such as the starting position of the drip driver), the route is drawn first, showing the user and driver markers.Then the longitude and latitude of the driver's position are obtained from the server by handler every minute, and the driver's marker position is redrawn, so it moves.
1. Draw path, start and end marker s

    //Route Planning
    private RouteSearch mRouteSearch;
    //The purpose of this array is to put in all the coordinate points of the planned route for easy drawing.
    private ArrayList<LatLng> latLonArray = new ArrayList<>();
        //Car smooth route, store two points
    private ArrayList<LatLng> runArray = new ArrayList<>();
    //A marker that moves smoothly, that is, a cart
    private SmoothMoveMarker smoothMarker;
    
/**
     * Given the driver's address, get the latitude and longitude of the driver's starting position (for not knowing the driver's latitude and longitude, knowing the driver's starting address) and the driving time, and draw a picture first
     * Road Map, Start and End
     * @param cityName
     */
    private void getStoreLatlon(String cityName) {
        LogUtils.i("StoreyName;" + cityName);
        GeocodeSearch geocodeSearch = new GeocodeSearch(this);
        geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
                
            }
            
            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
                
                if (i == 1000) {
                    if (geocodeResult != null && geocodeResult.getGeocodeAddressList() != null
                            && geocodeResult.getGeocodeAddressList().size() > 0) {
                        
                        GeocodeAddress geocodeAddress = geocodeResult.getGeocodeAddressList().get(0);
                        double latitude = geocodeAddress.getLatLonPoint().getLatitude();//latitude
                        double longititude = geocodeAddress.getLatLonPoint().getLongitude();//longitude
                        mStoreLatlng = new LatLng(latitude, longititude);
                        getStoreDriveTime();
                        LogUtils.i("lgq Geocoding:" + geocodeAddress.getAdcode() + "");
                        LogUtils.i("lgq latitude latitude:" + latitude + "");
                        LogUtils.i("lgq longitude longititude:" + longititude + "");
                    }
                    else {
                        ToastUtil.showMessage(RoadRescueApplyAct.this, "Place name error");
                    }
                }
            }
        });
        
        GeocodeQuery geocodeQuery = new GeocodeQuery(cityName.trim(), "29");
        geocodeSearch.getFromLocationNameAsyn(geocodeQuery);
    }
    
    /**
     *Query driver-to-user path
     */
    private void getStoreDriveTime() {
        mRouteSearch = new RouteSearch(this);
        mRouteSearch.setRouteSearchListener(this);
        LatLng rescueLatlng = new LatLng(mCurrentRescueOrder.getLat(), mCurrentRescueOrder.getLng());
        RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(convertToLatLonPoint(rescueLatlng),
                convertToLatLonPoint(mStoreLatlng));
        RouteSearch.DriveRouteQuery routeQuery = new RouteSearch.DriveRouteQuery(fromAndTo,
                RouteSearch.DRIVING_SINGLE_AVOID_CONGESTION, null, null, "");
        mRouteSearch.calculateDriveRouteAsyn(routeQuery);
    }

//It goes to the callback method, chooses onDriveRouteSearched for processing, and stores all the latitude and longitude points of the path in the driverRouteResult
@Override
    public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {
        LogUtils.i("i:" + i);
        if (i == 1000) {
            if (driveRouteResult == null) {
                LogUtils.e("driveResult is null");
            }
            if (!latLonArray.isEmpty()) {
                latLonArray.clear();
            }
            //Set estimated wait time
            LogUtils.i("time:" + driveRouteResult.getPaths().get(0).getDuration());
            mDriveDuration = driveRouteResult.getPaths().get(0).getDuration();
            mDistance = driveRouteResult.getPaths().get(0).getDistance();
            Spanned durationText = Html
                    .fromHtml(getString(R.string.roadrescue_duration, secondsToMinute(mDriveDuration)));
            mTvWaitTime.setText(durationText);
            //Set Distance
            Spanned distanceText = Html.fromHtml(getString(R.string.roadrescue_distance, meterToKilometer(mDistance)));
            mTvRescueDistance.setText(distanceText);
            //Do not draw a path map for work
            if (mCurrentRescueOrder.getStatus() == 1 || mCurrentRescueOrder.getStatus() == 2) {
                return;
            }
            for (DrivePath path : driveRouteResult.getPaths()) {
                for (DriveStep step : path.getSteps()) {
                    for (LatLonPoint point : step.getPolyline()) {
                        latLonArray.add(convertToLatLng(point));
                    }
                }
            }
            //Plan your route, draw your starting point, car, road map
            drawingRouteOverlay(latLonArray);
            //Use the change point as the starting point for smooth car in the future
            if (runArray.size() == 0) {
                runArray.add(mStoreLatlng);
            }
            showCarMarker(mStoreLatlng);
        }
        else {
            LogUtils.e("no route to find");
        }
    }
    
    /**
     * Draw a route
     * @param drivePath
     */
    private void drawingRouteOverlay(List<LatLng> drivePath) {
        this.startLatLng = drivePath.get(0);
        this.endLatLng = drivePath.get(drivePath.size() - 1);
        polyLineOptions = new PolylineOptions();
        polyLineOptions.width(width);
        polyLineOptions.setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.custtexture));
        endBitmap = BitmapDescriptorFactory.fromResource(R.drawable.location_savecar);
        //Mark customer location on map as starting point
        addMarkerToMap(drivePath);
        //Draw a route
        drawLine(drivePath);
    }
    
    /**
     * Add marker s for start and end points to the map
     */
    public void addMarkerToMap(List<LatLng> drivePath) {
        try {
            //Clear the original marker
            mAmap.clear();
            //Add the user's location marker to the map
            LatLng rescueLatLng = new LatLng(mCurrentRescueOrder.getLat(), mCurrentRescueOrder.getLng());
            endMarker = mAmap.addMarker(new MarkerOptions().position(rescueLatLng).icon(endBitmap));
        }
        catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
    
    /**
     * Draw lines
     */
    private void drawLine(List<LatLng> drivePath) {
        try {
            polyLineOptions.addAll(drivePath);
            allPolyLines.add(mAmap.addPolyline(polyLineOptions));
        }
        catch (Throwable e) {
            e.printStackTrace();
        }
    }

    //Show the driver's location
    private void showCarMarker(LatLng location) {
        zoomToSpan();
        if (rescueCarMarker == null) {
            //If it's empty, the way to add a new icon is to set the positioning icon, which you can customize
            rescueCarMarker = mAmap.addMarker(new MarkerOptions().position(location)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.savecar)));
        }
        else {
            rescueCarMarker.setPosition(location);
        }
    }
    
    /**
     * Always keep points where they can be seen
     */
    private void zoomToSpan() {
        try {
            LatLngBounds.Builder b = LatLngBounds.builder();
            b.include(new LatLng(startLatLng.latitude, startLatLng.longitude));
            b.include(new LatLng(endLatLng.latitude, endLatLng.longitude));
            LatLngBounds bounds = b.build();
            //This is the way to keep the vision in the middle, and see the Golden Map API in detail
            mAmap.animateCamera(CameraUpdateFactory.newLatLngBoundsRect(bounds, 100, 100, 100, 450));
        }
        catch (Throwable e) {
            e.printStackTrace();
        }
    }

2. Update driver marker location

//Get driver latitude and longitude from server every minute
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_RESCUE_CAR_LOCATION,
                                        UPDATE_RESCUE_CAR_LOCATION_INTERNAL);
 private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (runArray == null) {
                return;
            }if (msg.what == MSG_UPDATE_RESCUE_CAR_LOCATION) {
                //Get Driver Location
                getRescueCarDistance(mCurrentRescueOrder.getOrderId());
                sendEmptyMessageDelayed(MSG_UPDATE_RESCUE_CAR_LOCATION, UPDATE_RESCUE_CAR_LOCATION_INTERNAL);
            }
        }
    };
    
    /**
     * Get driver position and calculate distance (out)
     * @param orderId
     */
    private void getRescueCarDistance(long orderId) {
        RequestManager2.getServiceInstance()
                .getRescuevehicleLocation(orderId)
                .compose(RequestManager2.<LatLng> setSchedulers())
                .subscribe(new BackgroundSubscriber<LatLng>(RoadRescueApplyAct.this) {
                    @Override
                    public void onSuccess(LatLng latLng) {
                        super.onSuccess(latLng);
                        LogUtils.e("rescuecar,latLng:" + latLng);
                        //Get the distance between the store and the user, time calculated by map map
                        LatLng rescueLatlng = new LatLng(mCurrentRescueOrder.getLat(), mCurrentRescueOrder.getLng());
                        mDistance = AMapUtils.calculateLineDistance(rescueLatlng, latLng);
                        Spanned distanceText = Html
                                .fromHtml(getString(R.string.roadrescue_distance, meterToKilometer(mDistance)));
                        mTvRescueDistance.setText(distanceText);
                        //Add Marker to show car location
                        if (latLng.longitude == 0 || latLng.latitude == 0) {
                            return;
                        }
                        //Update Car Location
                       if (runArray.size() == 1) {
                            //If there is only one point in runArray, get the latest car location and add another point
                            runArray.add(latLng);
                        }
                        else if (runArray.size() == 2) {
                        	//If there are already two points in runArray, remove the first one and add the latest one
                            runArray.remove(0);
                            runArray.add(latLng);
                        }
                        if (smoothMarker != null) {
                            smoothMarker.destroy();
                        }
                        //Slide the car from runArray 0 to 1
                        showCarMarkerSmooth();
                    }
                });
    }

	//Slide Cart
    private void showCarMarkerSmooth() {
        
        // Getting track coordinate points
        zoomToSpan();
        if(rescueCarMarker!=null){
            //Remove the car marker set at the beginning
            rescueCarMarker.remove();
        }
        smoothMarker = new SmoothMoveMarker(mAmap);
        // Set Sliding Icon
        smoothMarker.setDescriptor(BitmapDescriptorFactory.fromResource(R.drawable.savecar));
        
        LatLng drivePoint = runArray.get(0);
        Pair<Integer, LatLng> pair = SpatialRelationUtil.calShortestDistancePoint(runArray, drivePoint);
        runArray.set(pair.first, drivePoint);
        List<LatLng> subList = runArray.subList(pair.first, runArray.size());
        
        // Setting Sliding Track Coordinate Points
        smoothMarker.setPoints(subList);
        // Set total sliding time 60s
        smoothMarker.setTotalDuration(60);
        // Start Sliding
        smoothMarker.startSmoothMove();
    }

But the actual driver's location data may not be available, so we can simulate the driver's movement by choosing from all latitude and longitude points of the obtained route to simulate the driver continuing along the planned route.Define two ArrayList s, one for latLonArray to store all the points of the planned route, and one for runArray to store two points, constantly pulling points from latLonArray to simulate updating the driver's progress.(For example, the points in latLongArray are 0, 1, 2, 3, 4..., runArray updates data (0,1) (1,2) (2,3)...Then the car marker slides forward based on the two points inside runArray)

    /**
     * Query routes based on latitude and longitude of start and end points
     */
    private void startRouteSearch() {
        LogUtils.e("startRouteSearch");
        mRouteSearch = new RouteSearch(this);
        mRouteSearch.setRouteSearchListener(this);
        RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(mStarPoint, mEndPoint);
        RouteSearch.DriveRouteQuery routeQuery = new RouteSearch.DriveRouteQuery(fromAndTo,
                RouteSearch.DRIVING_SINGLE_AVOID_CONGESTION, null, null, "");
        mRouteSearch.calculateDriveRouteAsyn(routeQuery);
    }
    
    @Override
    public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {
        LogUtils.i("i:" + i);
        if (i == 1000) {
            if (driveRouteResult == null) {
                LogUtils.e("driveResult is null");
            }
            if (!latLonArray.isEmpty()) {
                latLonArray.clear();
            }
            for (DrivePath path : driveRouteResult.getPaths()) {
                for (DriveStep step : path.getSteps()) {
                    for (LatLonPoint point : step.getPolyline()) {
                        latLonArray.add(convertToLatLng(point));
                    }
                }
            }
            //Plan your route, draw your starting point, car, road map
            drawingRouteOverlay(latLonArray);
            runArray.add(latLonArray.get(0));
            runArray.add(latLonArray.get(1));
            showCarMarkerSmooth();
            mHandler.sendEmptyMessage(MSG_UPDATE_CAR);
        }
        else {
            LogUtils.e("no route to find");
        }
    }
    
    private void showCarMarkerSmooth() {
        zoomToSpan();
        smoothMarker = new SmoothMoveMarker(mAmap);
        // Set Sliding Icon
        smoothMarker.setDescriptor(BitmapDescriptorFactory.fromResource(R.drawable.car));
        
        LatLng drivePoint = runArray.get(0);
        Pair<Integer, LatLng> pair = SpatialRelationUtil.calShortestDistancePoint(runArray, drivePoint);
        runArray.set(pair.first, drivePoint);
        List<LatLng> subList = runArray.subList(pair.first, runArray.size());
        
        // Setting Sliding Track Coordinate Points
        smoothMarker.setPoints(subList);
        // Set total sliding time
        smoothMarker.setTotalDuration(1);
        // Start Sliding
        smoothMarker.startSmoothMove();
    }
        private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (runArray == null) {
                return;
            }
            if (msg.what == MSG_UPDATE_CAR) {
                if (latLonArray.size() > 2) {
                    if (runArray.size() > 0) {
                        runArray.remove(0);
                        runArray.add(latLonArray.remove(0));
                    }
                    else {
                        runArray.add(latLonArray.remove(0));
                        runArray.add(latLonArray.remove(0));
                    }
                    if (smoothMarker != null) {
                        smoothMarker.destroy();
                    }
                    showCarMarkerSmooth();
                    sendEmptyMessageDelayed(MSG_UPDATE_CAR, UPDATE_CAR_INTERNAL);
                }
                else {
                    LogUtils.e("stop");
                    smoothMarker.stopMove();
                    clearRouteLines();
                    smoothMarker.destroy();
                    removeMessages(MSG_UPDATE_CAR);
                }
        }
    };

Posted by troublemaker on Fri, 17 May 2019 05:46:58 -0700