route google example customize color android google-maps overlay draw polygon

example - Cómo dibujar un polígono de mano libre en el mapa de Google V2 en Android?



polyline color google maps android (4)

Así que tenemos alguna solución para dibujar a mano alzada en el mapa v2. Implementa GoogleMap.OnMarkerDragListener en tu actividad de mapa. Anulará la función MarkerDrag.

@Override public void onMarkerDrag(Marker marker) { //add the marker''s latlng in a arraylist of LatLng and pass it to the loop for (int i = 0; i < arraylistoflatlng.size(); i++) { myMap.addPolyline(new PolylineOptions() .addAll(arraylistoflatlng) .width(5) .color(Color.RED)); } }

puede pasar algún tipo de truco de mano libre, ya que tan pronto como el usuario toque el mapa, deberá detectar esas coordenadas y pasarlo al onMarkerDrag. Como deberá usar la información del área para un proceso posterior. Para el evento táctil, puede implementar GoogleMap.OnMapClickListener y obtener las coordenadas de su parámetro. Espero que esto ayude :)

Quiero dibujar un Free Hand Polygon on the Map in Google Map V2 .

Esta tarea fue posible con Overlay Map V1, pero Google Map eliminó esa clase de V2. (Según este Google Map V2 tiene Eliminar clase de superposición ).

Buen ejemplo para que Google Map V1 dibuje un polígono de estilo libre.

En Map V2, podemos dibujar un polígono programáticamente con la ayuda de Google Official Doc, pero ¿qué debe hacer un usuario? He encontrado una respuesta poco clara para Map V2

Comencé con un simple mapa de Google y dibuje un polígono para hacer esto programáticamente y funciona correctamente, pero ahora estoy buscando cómo dibujar un usuario. No quiero dibujar según el marcador en el polígono.

// Instantiates a new Polygon object and adds points to define a rectangle PolygonOptions rectOptions = new PolygonOptions() .add(new LatLng(37.35, -122.0), new LatLng(37.45, -122.0), new LatLng(37.45, -122.2), new LatLng(37.35, -122.2), new LatLng(37.35, -122.0)); // Get back the mutable Polygon Polygon polygon = myMap.addPolygon(rectOptions);

He hecho muchas investigaciones y desarrollos sobre este tema, pero no encontré una manera perfecta de implementar tal cosa en Map V2.

Algunas preguntas

  • ¿Cómo dibujar un polígono de estilo libre en Map V2 (como podemos hacer con Map V1)?
  • ¿Hay algún truco o alternativa para lograr esto? Si es así, ¿cómo?
  • ¿Podemos obtener un evento táctil en el mapa y dibujar un polígono?
  • ¿Es factible en Map V2?
  • ¿Es posible con un evento táctil que devuelve una matriz de latitud-longitud?
  • ¿Cómo puedo obtener Lat-long basado en coordenadas de pantalla en setOnDragListener ?

Cada nueva versión tiene algo extra en comparación con la anterior, por lo que espero que pueda lograr lo mismo en Map v2 también.

No estoy pidiendo que me proporcione un código de muestra o publique su código, solo una dirección y documentación adecuadas.

He proporcionado todos los documentos y pruebas que encontré durante la Investigación y Desarrollo.


Después de pasar todo un día en Rnd y probar algunas alternativas, he encontrado una solución. De hecho, he encontrado dos alternativas para el mismo problema, pero me gustaría sugerir el uso de la Alternativa 2 porque es realmente muy fácil en comparación con la Alternativa 1 .

De hecho, he encontrado la Alternativa 1 con la ayuda de TheLittleNaruto , AndroidHacker y algunos otros desarrolladores y la Alternativa 2 con la ayuda de Khan así que gracias a todos.

Alternativa 1

Cómo dibujar un polígono de estilo libre en Map V2 (como podemos hacer con Map V1)? ¿Es factible en Map V2?

Sí, eso es factible pero no puede obtener OnTouch() y OnDraw() directamente en el mapa. Entonces debemos tener que pensar de otra manera para lograr esto.

¿Hay algún truco o forma alternativa de lograr esto? Si es así, ¿cómo?

Sí, Google Map V2 no admite OnTouch() u OnDraw() en un mapa utilizando class="com.google.android.gms.maps.SupportMapFragment" por lo que debemos planificar un Fragmento personalizado.

¿Es posible devolver una matriz de lat-long con evento táctil?

Sí, si creamos cualquier fragmento de mapa personalizado y lo usamos, podemos obtener ese evento Touch o Drag sobre el mapa.

¿Cómo puedo obtener una base de Lat-long en coordenadas de pantalla en setOnDragListener?

setOnDragListener devolverá coordenadas de pantalla (x, y) . Ahora para eso, hay algunas técnicas para convertir (x, y) a LatLng e incluyen Projection junto con Point & LatLng .

customMapFragment.setOnDragListener(new MapWrapperLayout.OnDragListener() {@Override public void onDrag(MotionEvent motionEvent) { Log.i("ON_DRAG", "X:" + String.valueOf(motionEvent.getX())); Log.i("ON_DRAG", "Y:" + String.valueOf(motionEvent.getY())); float x = motionEvent.getX(); // get screen x position or coordinate float y = motionEvent.getY(); // get screen y position or coordinate int x_co = Integer.parseInt(String.valueOf(Math.round(x))); // casting float to int int y_co = Integer.parseInt(String.valueOf(Math.round(y))); // casting float to int projection = mMap.getProjection(); // Will convert your x,y to LatLng Point x_y_points = new Point(x_co, y_co);// accept int x,y value LatLng latLng = mMap.getProjection().fromScreenLocation(x_y_points); // convert x,y to LatLng latitude = latLng.latitude; // your latitude longitude = latLng.longitude; // your longitude Log.i("ON_DRAG", "lat:" + latitude); Log.i("ON_DRAG", "long:" + longitude); // Handle motion event: } });

Como funciona ?

Como ya mencioné antes, tenemos que crear una vista raíz personalizada y, usando eso, podemos obtener Touch or Drag Events sobre el mapa.

Paso 1: MySupportMapFragment extends SupportMapFragment y lo usaremos como nuestro archivo .xml

<fragment android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" class="pkg_name.MySupportMapFragment" />

Paso 2: Crear un MapWrapperLayout extends FrameLayout para que podamos establecer un oyente Touch o Drag dentro e incrustar su vista con vista de mapa. Entonces, necesitamos una interfaz que usaremos en Root_Map.java

MySupportMapFragment.Java

public class MySupportMapFragment extends SupportMapFragment { public View mOriginalContentView; public MapWrapperLayout mMapWrapperLayout; @Override public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState); mMapWrapperLayout = new MapWrapperLayout(getActivity()); mMapWrapperLayout.addView(mOriginalContentView); return mMapWrapperLayout; } @Override public View getView() { return mOriginalContentView; } public void setOnDragListener(MapWrapperLayout.OnDragListener onDragListener) { mMapWrapperLayout.setOnDragListener(onDragListener); } }

MapWrapperLayout.java

public class MapWrapperLayout extends FrameLayout { private OnDragListener mOnDragListener; public MapWrapperLayout(Context context) { super(context); } public interface OnDragListener { public void onDrag(MotionEvent motionEvent); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (mOnDragListener != null) { mOnDragListener.onDrag(ev); } return super.dispatchTouchEvent(ev); } public void setOnDragListener(OnDragListener mOnDragListener) { this.mOnDragListener = mOnDragListener; } }

Root_Map.Java

public class Root_Map extends FragmentActivity { private GoogleMap mMap; public static boolean mMapIsTouched = false; MySupportMapFragment customMapFragment; Projection projection; public double latitude; public double longitude; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.root_map); MySupportMapFragment customMapFragment = ((MySupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)); mMap = customMapFragment.getMap(); customMapFragment.setOnDragListener(new MapWrapperLayout.OnDragListener() { @Override public void onDrag(MotionEvent motionEvent) { Log.i("ON_DRAG", "X:" + String.valueOf(motionEvent.getX())); Log.i("ON_DRAG", "Y:" + String.valueOf(motionEvent.getY())); float x = motionEvent.getX(); float y = motionEvent.getY(); int x_co = Integer.parseInt(String.valueOf(Math.round(x))); int y_co = Integer.parseInt(String.valueOf(Math.round(y))); projection = mMap.getProjection(); Point x_y_points = new Point(x_co, y_co); LatLng latLng = mMap.getProjection().fromScreenLocation(x_y_points); latitude = latLng.latitude; longitude = latLng.longitude; Log.i("ON_DRAG", "lat:" + latitude); Log.i("ON_DRAG", "long:" + longitude); // Handle motion event: } }); }}

Referencia Link1 , Link2

Hasta aquí, puedo obtener LatLong basado en coordenadas de pantalla X, Y. Ahora solo tengo que almacenarlo en Array . Esa matriz se usará para dibujar en el mapa y finalmente se verá como un polígono de forma libre.

Espero que esto definitivamente te ayude.

Actualizar:

Alternativa 2

Como sabemos, el diseño de cuadros es un diseño transparente, así que lo he logrado utilizando el Diseño de cuadros. En este caso, no hay necesidad de crear un fragmento personalizado. Acabo de utilizar Frame Layout como diseño de raíz. Así que, básicamente, obtendré Touch Events en el diseño de la raíz y devolverá las coordenadas de la pantalla, tal como obtuvimos previamente en el fragmento personalizado.

Ahora, he creado un botón dentro del "sorteo gratuito". Entonces, cuando haces clic en eso, puedes mover los dedos en el mapa y dibujar un polígono de mano libre que deshabilitará que tu mapa se mueva en la pantalla. Cuando vuelve a hacer clic en el mismo botón, la pantalla pasa al modo ideal.

root_map.xml

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <fragment android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" class="com.google.android.gms.maps.SupportMapFragment" /> <FrameLayout android:id="@+id/fram_map" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/btn_draw_State" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Free Draw" /> </FrameLayout> </FrameLayout>

Root_Map.java

FrameLayout fram_map = (FrameLayout) findViewById(R.id.fram_map); Button btn_draw_State = (Button) findViewById(R.id.btn_draw_State); Boolean Is_MAP_Moveable = false; // to detect map is movable

// El botón cambiará el estado de desplazamiento del mapa

btn_draw_State.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Is_MAP_Moveable = !Is_MAP_Moveable; } });

Toque clic en el diseño del cuadro y con la ayuda del hacer alguna tarea

fram_map.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { float x = event.getX(); float y = event.getY(); int x_co = Math.round(x); int y_co = Math.round(y); projection = mMap.getProjection(); Point x_y_points = new Point(x_co, y_co); LatLng latLng = mMap.getProjection().fromScreenLocation(x_y_points); latitude = latLng.latitude; longitude = latLng.longitude; int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN: // finger touches the screen val.add(new LatLng(latitude, longitude)); case MotionEvent.ACTION_MOVE: // finger moves on the screen val.add(new LatLng(latitude, longitude)); case MotionEvent.ACTION_UP: // finger leaves the screen Draw_Map(); break; } return Is_MAP_Moveable; } });

// Dibuja tu mapa

public void Draw_Map() { rectOptions = new PolygonOptions(); rectOptions.addAll(val); rectOptions.strokeColor(Color.BLUE); rectOptions.strokeWidth(7); rectOptions.fillColor(Color.CYAN); polygon = mMap.addPolygon(rectOptions); }

Sin embargo, ahora debe mantener su lista mientras dibuja, por lo que debe borrar los datos de su lista anterior.


Mira esto ... Creo que U son capaces de mostrar Google Map v2

Echa un vistazo al método "decodePoly" y "drawPath" en AsyncTask

Imposición principal en "drawPath" ...

PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true); for (int z = 0; z < list.size(); z++) { LatLng point = list.get(z); options.add(point); } line = myMap.addPolyline(options);

Clase completa para su referencia ..

package com.example.androidhackergooglemap; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONObject; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.location.Location; import android.location.LocationManager; import android.os.AsyncTask; import android.os.Bundle; import android.provider.Settings; import android.support.v4.app.FragmentActivity; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Toast; public class MainActivity extends FragmentActivity implements OnClickListener { private GoogleMap myMap; Polyline line; Context context; Location location; boolean check_provider_enabled = false; // Static LatLng LatLng startLatLng = new LatLng(30.707104, 76.690749); LatLng endLatLng = new LatLng(30.721419, 76.730017); public void onCreate(Bundle bd) { super.onCreate(bd); setContentView(R.layout.activity_main); context = MainActivity.this; // GoogleMap myMap myMap = ((SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map)).getMap(); myMap.setMyLocationEnabled(true); myMap.moveCamera(CameraUpdateFactory.newLatLng(startLatLng)); myMap.animateCamera(CameraUpdateFactory.zoomTo(12)); LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); boolean enabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER); location = service.getLastKnownLocation(LocationManager.GPS_PROVIDER); // check if enabled and if not send user to the GSP settings // Better solution would be to display a dialog and suggesting to // go to the settings if (!enabled) { /*Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(intent);*/ Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(intent); Toast.makeText(getApplicationContext(), "Enable GPS servcies to use this app.", Toast.LENGTH_LONG).show(); } else{ try{ String urlTopass = makeURL(startLatLng.latitude, startLatLng.longitude, endLatLng.latitude, endLatLng.longitude); new connectAsyncTask(urlTopass).execute(); }catch(Exception e){ e.printStackTrace(); } } // Now auto clicking the button // btntemp.performClick(); } private class connectAsyncTask extends AsyncTask<Void, Void, String> { private ProgressDialog progressDialog; String url; connectAsyncTask(String urlPass) { url = urlPass; } @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); progressDialog = new ProgressDialog(context); progressDialog.setMessage("Fetching route, Please wait..."); progressDialog.setIndeterminate(true); progressDialog.show(); } @Override protected String doInBackground(Void... params) { JSONParser jParser = new JSONParser(); String json = jParser.getJSONFromUrl(url); return json; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); progressDialog.hide(); if (result != null) { drawPath(result); } } } public String makeURL(double sourcelat, double sourcelog, double destlat, double destlog) { StringBuilder urlString = new StringBuilder(); urlString.append("http://maps.googleapis.com/maps/api/directions/json"); urlString.append("?origin=");// from urlString.append(Double.toString(sourcelat)); urlString.append(","); urlString.append(Double.toString(sourcelog)); urlString.append("&destination=");// to urlString.append(Double.toString(destlat)); urlString.append(","); urlString.append(Double.toString(destlog)); urlString.append("&sensor=false&mode=driving&alternatives=true"); return urlString.toString(); } public class JSONParser { InputStream is = null; JSONObject jObj = null; String json = ""; // constructor public JSONParser() { } public String getJSONFromUrl(String url) { // Making HTTP request try { // defaultHttpClient DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { BufferedReader reader = new BufferedReader( new InputStreamReader(is, "iso-8859-1"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "/n"); } json = sb.toString(); is.close(); } catch (Exception e) { Log.e("Buffer Error", "Error converting result " + e.toString()); } return json; } } public void drawPath(String result) { if (line != null) { myMap.clear(); } myMap.addMarker(new MarkerOptions().position(endLatLng).icon( BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))); myMap.addMarker(new MarkerOptions().position(startLatLng).icon( BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))); try { // Tranform the string into a json object final JSONObject json = new JSONObject(result); JSONArray routeArray = json.getJSONArray("routes"); JSONObject routes = routeArray.getJSONObject(0); JSONObject overviewPolylines = routes .getJSONObject("overview_polyline"); String encodedString = overviewPolylines.getString("points"); List<LatLng> list = decodePoly(encodedString); PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true); for (int z = 0; z < list.size(); z++) { LatLng point = list.get(z); options.add(point); } line = myMap.addPolyline(options); /*for (int z = 0; z < list.size() - 1; z++) { LatLng src = list.get(z); LatLng dest = list.get(z + 1); line = myMap.addPolyline(new PolylineOptions() .add(new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude, dest.longitude)) .width(5).color(Color.BLUE).geodesic(true)); }*/ } catch (Exception e) { e.printStackTrace(); } } private List<LatLng> decodePoly(String encoded) { List<LatLng> poly = new ArrayList<LatLng>(); 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; } @Override public void onClick(View arg0) { // TODO Auto-generated method stub } }

Espero eso ayude. ¡Aclamaciones!

ACTUALIZAR

Link1 esto ... Link1

También verifique este ... Cómo dibujar una forma en el fragmento del mapa al tocarlo usando google map V2

Algunos más referencia ... Link2


este es el tutorial API V2 de google maps:

public class MapPane extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map_activity); GoogleMap map = ((MapFragment) getFragmentManager() .findFragmentById(R.id.map)).getMap(); map.moveCamera(CameraUpdateFactory.newLatLngZoom( new LatLng(-18.142, 178.431), 2)); // Polylines are useful for marking paths and routes on the map. map.addPolyline(new PolylineOptions().geodesic(true) .add(new LatLng(-33.866, 151.195)) // Sydney .add(new LatLng(-18.142, 178.431)) // Fiji .add(new LatLng(21.291, -157.821)) // Hawaii .add(new LatLng(37.423, -122.091)) // Mountain View ); } }

enlace: https://developers.google.com/maps/documentation/android/