如何使用GoogleMaps绘制Snake路径?

时间:2019-05-28 04:27:25

标签: android google-maps

这就是代码的工作方式:

enter image description here

这就是我想要的

enter image description here

(1,2)“这是我的意思,另一个是蛇的轨迹”

这是正确的

enter image description here

我想在这里成为3

enter image description here

(3,4)“我要使其绘制标记正确的方法 示例:

7 8 9
6 5 4
1 2 3

我尝试更改变量I和J并对其进行编辑以找到我的需要,但我无法让所有人都告诉我这很简单,但无法弄清楚

for (double J = Lat1; J < Lat2; J += oneMeter) {

    for (double I = Lng1; I < Lng2-oneMeter; I += oneMeter) {
        if(I+oneMeter<=Lng2){
        mMap.addMarker(new MarkerOptions().title(markerNumber++ + "").position(new LatLng(J, I)).icon(BitmapDescriptorFactory.fromResource(R.drawable.pvpanels)));
        //Test
        Polyline line = mMap.addPolyline(new PolylineOptions().add(
                new LatLng(J, I),
                new LatLng(J, I+ oneMeter ))
                .width(10).color(Color.RED));}
        else if(I+oneMeter>Lng2){
            Polyline line = mMap.addPolyline(new PolylineOptions().add(
                    new LatLng(J, I- oneMeter),
                    new LatLng(J+oneMeter , I))
                    .width(10).color(Color.RED));
        }

    }
}

我希望它可以做蛇形并且正确的点格式可以将图像1转换为2,将3转换为4

1 个答案:

答案 0 :(得分:1)

您的问题不清楚, 我假设您已完成所有设置,并尝试通过路径连接到Google Map中的点。

第1步。添加以下依赖项     实施'com.google.code.gson:gson:2.6.1'     实施'com.mcxiaoke.volley:library:1.0.19'

第2步。在map_activity.xml中

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
MapsActivity.class中的

第3步

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleMap.OnMapClickListener, GoogleApiClient.ConnectionCallbacks {
private static final String TAG = MapsActivity.class.getSimpleName();
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private LocationRequest mLocationRequest;
private double latitudeValue = 0.0;
private double longitudeValue = 0.0;
private GoogleMap mMap;
private static final int PERMISSION_LOCATION_REQUEST_CODE = 100;
private List<LatLng> latLngList;
private MarkerOptions yourLocationMarker;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    latLngList = new ArrayList<LatLng>();
    if (mGoogleApiClient == null) {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addApi(LocationServices.API)
                .build();
    }
    mLocationRequest = createLocationRequest();
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    mMap.setOnMapClickListener(this);
}
@Override
public void onMapClick(LatLng latLng) {
    if(latLngList.size() > 0){
        refreshMap(mMap);
        latLngList.clear();
    }
    latLngList.add(latLng);
    Log.d(TAG, "Marker number " + latLngList.size());
    mMap.addMarker(yourLocationMarker);
    mMap.addMarker(new MarkerOptions().position(latLng));
    LatLng defaultLocation = yourLocationMarker.getPosition();
    LatLng destinationLocation = latLng;
    //use Google Direction API to get the route between these Locations
    String directionApiPath = Helper.getUrl(String.valueOf(defaultLocation.latitude), String.valueOf(defaultLocation.longitude),
            String.valueOf(destinationLocation.latitude), String.valueOf(destinationLocation.longitude));
    Log.d(TAG, "Path " + directionApiPath);
    getDirectionFromDirectionApiServer(directionApiPath);
}
@Override
public void onConnected(@Nullable Bundle bundle) {
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest);
    PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(@NonNull LocationSettingsResult result) {
            final Status status = result.getStatus();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    Log.d(TAG, "Connection method has been called");
                    if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                            && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                        assignLocationValues(mLastLocation);
                        setDefaultMarkerOption(new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()));
                    }else{
                        ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_LOCATION_REQUEST_CODE);
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    break;
            }
        }
    });
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_LOCATION_REQUEST_CODE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                // permission was denied, show alert to explain permission
                showPermissionAlert();
            }else{
                //permission is granted now start a background service
                if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                        && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                    assignLocationValues(mLastLocation);
                    setDefaultMarkerOption(new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude()));
                }
            }
        }
    }
}
private void assignLocationValues(Location currentLocation){
    if (currentLocation != null) {
        latitudeValue = currentLocation.getLatitude();
        longitudeValue = currentLocation.getLongitude();
        Log.d(TAG, "Latitude: " + latitudeValue + " Longitude: " + longitudeValue);
        markStartingLocationOnMap(mMap, new LatLng(latitudeValue, longitudeValue));
        addCameraToMap(new LatLng(latitudeValue, longitudeValue));
    }
}
private void addCameraToMap(LatLng latLng){
    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(latLng)
            .zoom(16)
            .build();
    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
private void showPermissionAlert(){
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(R.string.permission_request_title);
    builder.setMessage(R.string.app_permission_notice);
    builder.create();
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            if (ActivityCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_LOCATION_REQUEST_CODE);
            }
        }
    });
    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Toast.makeText(MapsActivity.this, R.string.permission_refused, Toast.LENGTH_LONG).show();
        }
    });
    builder.show();
}
private void markStartingLocationOnMap(GoogleMap mapObject, LatLng location){
    mapObject.addMarker(new MarkerOptions().position(location).title("Current location"));
    mapObject.moveCamera(CameraUpdateFactory.newLatLng(location));
}
private void refreshMap(GoogleMap mapInstance){
    mapInstance.clear();
}
protected LocationRequest createLocationRequest() {
    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(5000);
    mLocationRequest.setFastestInterval(3000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    return mLocationRequest;
}
private void setDefaultMarkerOption(LatLng location){
    if(yourLocationMarker == null){
        yourLocationMarker = new MarkerOptions();
    }
    yourLocationMarker.position(location);
}
@Override
protected void onStart() {
    mGoogleApiClient.connect();
    super.onStart();
}
@Override
protected void onStop() {
    mGoogleApiClient.disconnect();
    super.onStop();
}
private void getDirectionFromDirectionApiServer(String url){
    GsonRequest<DirectionObject> serverRequest = new GsonRequest<DirectionObject>(
            Request.Method.GET,
            url,
            DirectionObject.class,
            createRequestSuccessListener(),
            createRequestErrorListener());
    serverRequest.setRetryPolicy(new DefaultRetryPolicy(
            Helper.MY_SOCKET_TIMEOUT_MS,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    VolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(serverRequest);
}
private Response.Listener<DirectionObject> createRequestSuccessListener() {
    return new Response.Listener<DirectionObject>() {
        @Override
        public void onResponse(DirectionObject response) {
            try {
                Log.d("JSON Response", response.toString());
                if(response.getStatus().equals("OK")){
                    List<LatLng> mDirections = getDirectionPolylines(response.getRoutes());
                    drawRouteOnMap(mMap, mDirections);
                }else{
                    Toast.makeText(MapsActivity.this, R.string.server_error, Toast.LENGTH_SHORT).show();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
    };
}
private List<LatLng> getDirectionPolylines(List<RouteObject> routes){
    List<LatLng> directionList = new ArrayList<LatLng>();
    for(RouteObject route : routes){
        List<LegsObject> legs = route.getLegs();
        for(LegsObject leg : legs){
            List<StepsObject> steps = leg.getSteps();
            for(StepsObject step : steps){
                PolylineObject polyline = step.getPolyline();
                String points = polyline.getPoints();
                List<LatLng> singlePolyline = decodePoly(points);
                for (LatLng direction : singlePolyline){
                    directionList.add(direction);
                }
            }
        }
    }
    return directionList;
}
private Response.ErrorListener createRequestErrorListener() {
    return new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    };
}
private void drawRouteOnMap(GoogleMap map, List<LatLng> positions){
    PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
    options.addAll(positions);
    Polyline polyline = map.addPolyline(options);
    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(positions.get(1).latitude, positions.get(1).longitude))
            .zoom(17)
            .build();
    map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
/**
 * Method to decode polyline points
 * Courtesy : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
 * */
private List<LatLng> decodePoly(String encoded) {
    List<LatLng> poly = new ArrayList<>();
    int index = 0, len = encoded.length();
    int lat = 0, lng = 0;
    while (index < len) {
        int b, shift = 0, result = 0;
        do {
            b = encoded.charAt(index++) - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
        lat += dlat;
        shift = 0;
        result = 0;
        do {
            b = encoded.charAt(index++) - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
        lng += dlng;
        LatLng p = new LatLng((((double) lat / 1E5)),
                (((double) lng / 1E5)));
        poly.add(p);
    }
    return poly;
}
}

从GOOGLE DIRECTION API返回的JSON响应对象

返回的响应对象是Json对象,并且方向路径存储在Polyline类中。这是Json响应对象的类结构。我们将使用Gson库将其转换为纯Java对象类。

应该看起来像这样:

{
   "geocoded_waypoints" : [
      {
         "geocoder_status" : "OK",
         "place_id" : "ChIJZymwbofzU0YRvgugqrVwH8Q",
         "types" : [ "street_address" ]
      },
      {
         "geocoder_status" : "OK",
         "place_id" : "EiJOeWdhdGFuIDMyLCAyNDIgMzEgSMO2cmJ5LCBTdmVyaWdl",
         "types" : [ "street_address" ]
      }
   ],
   "routes" : [
      {
         "bounds" : {
            "northeast" : {
               "lat" : 55.8541564,
               "lng" : 13.661235
            },
            "southwest" : {
               "lat" : 55.85187149999999,
               "lng" : 13.660381
            }
         },
         "copyrights" : "Map data ©2016 Google",
         "legs" : [
            {
               "distance" : {
                  "text" : "0.3 km",
                  "value" : 260
               },
               "duration" : {
                  "text" : "1 min",
                  "value" : 84
               },
               "end_address" : "Nygatan 32, 242 31 Hörby, Sweden",
               "end_location" : {
                  "lat" : 55.85187149999999,
                  "lng" : 13.660381
               },
               "start_address" : "Nygatan 12B, 242 31 Hörby, Sweden",
               "start_location" : {
                  "lat" : 55.8541564,
                  "lng" : 13.661235
               },
               "steps" : [
                  {
                     "distance" : {
                        "text" : "0.3 km",
                        "value" : 260
                     },
                     "duration" : {
                        "text" : "1 min",
                        "value" : 84
                     },
                     "end_location" : {
                        "lat" : 55.85187149999999,
                        "lng" : 13.660381
                     },
                     "html_instructions" : "Head \u003cb\u003esouth\u003c/b\u003e on \u003cb\u003eNygatan\u003c/b\u003e toward \u003cb\u003eKvarngatan\u003c/b\u003e\u003cdiv style=\"font-size:0.9em\"\u003eDestination will be on the left\u003c/div\u003e",
                     "polyline" : {
                        "points" : "o_|sIwekrAVHxBj@|Bh@nBr@d@Hb@L"
                     },
                     "start_location" : {
                        "lat" : 55.8541564,
                        "lng" : 13.661235
                     },
                     "travel_mode" : "DRIVING"
                  }
               ],
               "traffic_speed_entry" : [],
               "via_waypoint" : []
            }
         ],
         "overview_polyline" : {
            "points" : "o_|sIwekrApCt@|Bh@nBr@hAV"
         },
         "summary" : "Nygatan",
         "warnings" : [],
         "waypoint_order" : []
      }
   ],
   "status" : "OK"
}

实体对象类

我们将创建以下类来模仿Json响应对象的结构。这些课程是

DIRECTIONOBJECT.JAVA

开始
public class DirectionObject {
    private List<RouteObject> routes;
    private String status;
    public DirectionObject(List<RouteObject> routes, String status) {
        this.routes = routes;
        this.status = status;
    }
    public List<RouteObject> getRoutes() {
        return routes;
    }
    public String getStatus() {
        return status;
    }
}

接下来是 LEGSOBJECT.JAVA

public class LegsObject {
    private List<StepsObject> steps;
    public LegsObject(List<StepsObject> steps) {
        this.steps = steps;
    }
    public List<StepsObject> getSteps() {
        return steps;
    }
}

现在 POLYLINEOBJECT.JAVA

public class PolylineObject {
    private String points;
    public PolylineObject(String points) {
        this.points = points;
    }
    public String getPoints() {
        return points;
    }
}

然后我们创建 ROUTEOBJECT.JAVA

public class RouteObject {
    private List<LegsObject> legs;
    public RouteObject(List<LegsObject> legs) {
        this.legs = legs;
    }
    public List<LegsObject> getLegs() {
        return legs;
    }
}

我们快到了!现在创建下一个类,即 STEPSOBJECTS.JAVA

public class StepsObject {
    private PolylineObject polyline;
    public StepsObject(PolylineObject polyline) {
        this.polyline = polyline;
    }
    public PolylineObject getPolyline() {
        return polyline;
    }
}

完成上述所有类的设置后,现在我们开始设置网络调用和API消耗!

我们将使用Volley进行网络通话

创建此类:

public class CustomApplication extends Application{
    private RequestQueue requestQueue;
    @Override
    public void onCreate() {
        super.onCreate();
        requestQueue = 
VolleySingleton.getInstance(getApplicationContext()).getRequestQueue();
    }
    public RequestQueue getVolleyRequestQueue(){
        return requestQueue;
    }
}

现在其余的类用于API使用逻辑:

现在创建一个类并将其命名为 GsonRequest.java

public class GsonRequest<T> extends Request<T> {
// create variables
private Gson mGson = new Gson();
private Class<T> tClass;
private Map<String, String> headers;
private Map<String, String> params;
private Response.Listener<T> listener;
public GsonRequest(int method, String url, Class<T> tClass, Response.Listener<T> listener, Response.ErrorListener errorListener) {
    super(method, url, errorListener);
    this.tClass = tClass;
    this.listener = listener;
    mGson = new Gson();
}
public GsonRequest(int method, String url, Class<T> tClass, Map<String, String> params, Response.Listener<T> listener, Response.ErrorListener errorListener) {
    super(method, url, errorListener);
    this.tClass = tClass;
    this.params = params;
    this.listener = listener;
    this.headers = null;
    mGson = new Gson();
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    return headers != null ? headers : super.getHeaders();
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
    return params;
}
protected void deliverResponse(T response) {
    listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
    try {
        String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        return Response.success(mGson.fromJson(json, tClass), HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    } catch (JsonSyntaxException e) {
        return Response.error(new ParseError(e));
    }
}
}

VOLLEYSINGLETON.JAVA

创建一个新的Java类并将其命名为 VolleySingleton.java

public class VolleySingleton {
private static VolleySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;
private VolleySingleton(Context context) {
    mCtx = context;
    mRequestQueue = getRequestQueue();
    mImageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() {
        private final LruCache<String, Bitmap> cache = new LruCache<String, Bitmap>(20);
        @Override
        public Bitmap getBitmap(String url) {
            return cache.get(url);
        }
        @Override
        public void putBitmap(String url, Bitmap bitmap) {
            cache.put(url, bitmap);
        }
    });
}
public static synchronized VolleySingleton getInstance(Context context) {
    if (mInstance == null) {
        mInstance = new VolleySingleton(context);
    }
    return mInstance;
}
public RequestQueue getRequestQueue() {
    if (mRequestQueue == null) {
        mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
    }
    return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
    getRequestQueue().add(req);
}
public ImageLoader getImageLoader() {
    return mImageLoader;
}
}

并且最终

HELPER.JAVA

创建另一个Java类名称为 Helper.java

public class Helper {
    private static final String DIRECTION_API = "https://maps.googleapis.com/maps/api/directions/json?origin=";
    public static final String API_KEY = "AIzaSyCuZCfoPPUV1upJT10kJbCbV71LUqwhFCM";
    public static final int MY_SOCKET_TIMEOUT_MS = 5000;
    public static String getUrl(String originLat, String originLon, String destinationLat, String destinationLon){
        return Helper.DIRECTION_API + originLat+","+originLon+"&destination="+destinationLat+","+destinationLon+"&key="+API_KEY;
    }
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }
}