Come disegnare il poligono a mano libera in Google Maps V2 in Android?

Voglio disegnare un Free Hand Polygon on the Map in Google Map V2 .

Questo task è stato ansible con Overlay Map V1, ma Google Map ha rimosso quella class da V2. (Per questo Google Map V2 ha la class di rimozione della sovrapposizione ).

  • SDL init failure, la ragione è: Nessun dispositivo video disponibile
  • Cattura della qualità dell'image dopo la ridimensionamento / ridimensionamento della bitmap
  • Binding dei dati di Android utilizzando il tag include
  • Android "ciao mondo" esempio di pushnotification
  • Aprire una tastiera numbersca senza forzare il text EditText per essere solo numbersco
  • lancio app facebook da altre app
  • Buon esempio per Google Map V1 per disegnare il poligono di stile libero.

    Nella Mappa V2, possiamo disegnare un poligono in modo programmato con l'aiuto di Google Doc ufficiale, ma che cosa dovrebbe fare un utente? Ho trovato una risposta non chiara per la mappa V2

    Ho iniziato con semplice mappa Google e disegnare il poligono per farlo in modo programmato e funziona correttamente, ma ora sto cercando come un utente può disegnare? Non voglio disegnare sulla base del marker sul poligono.

     // 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); 

    Ho fatto un sacco di ricerca e sviluppo su questo argomento, ma non ho trovato un modo perfetto per implementare una cosa del genere in Map V2.

    Alcune domande

    • Come disegnare il poligono freestyle in Map V2 (come possiamo fare con Map V1)?
    • C'è qualche trucco o alternativa per raggiungere questo objective? Se sì come?
    • Possiamo get un evento di touch sulla mappa e disegnare il poligono?
    • È ansible in Map V2?
    • È ansible con un evento a contatto che restituisce un arrays di lat-long?
    • Come posso get Lat-long basato sulle coordinate dello schermo su setOnDragListener ?

    Ogni nuova versione ha qualcosa di più rispetto a quello più vecchio, quindi mi aspetto che posso raggiungere la stessa cosa anche in Map v2.

    Non sto chiedendo di dare un codice di esempio o submit il tuo codice, solo una direzione e una documentazione adeguata.

    Ho fornito tutti i documenti e le prove che ho trovato durante la Ricerca e lo Sviluppo.

  • Invia Firebase Token da Android a Google Cloud Endpoints
  • Android: Come posso forzare un'authentication di facebook per il web mobile
  • Android-Studio: Errore: Imansible creare la macchina virtuale Java
  • Come get l'ID di elemento in un gestore onItemClick
  • ListView setOnItemClickListner non funziona
  • L'applicazione si blocca quando scatto un'image dalla galleria e l'integro in Gmail
  • 4 Solutions collect form web for “Come disegnare il poligono a mano libera in Google Maps V2 in Android?”

    Dopo aver trascorso un'intera giornata in Rnd e sperimentando alcune alternative ho trovato una soluzione. In realtà ho trovato due alternative per la stessa questione, ma vorrei suggerire l'utilizzo di Alternative 2 perché è veramente molto facile rispetto all'Appendice 1 .

    In realtà ho trovato Alternative 1 con l'aiuto di TheLittleNaruto , AndroidHacker e di altri sviluppatori e Alternative 2 con l'aiuto di Khan così grazie a tutti.

    Alternativa 1

    Come disegnare il poligono di stile libero in Map V2 (come possiamo fare con Map V1)? È ansible in Map V2?

    Sì, è ansible, ma non è ansible get direttamente OnTouch() e OnDraw() sulla mappa. Quindi dobbiamo wherer pensare ad un altro modo per raggiungere questo objective.

    C'è qualche trucco o modo alternativo per raggiungere questa cosa, se sì come?

    Sì, Google Map V2 non support OnTouch() o OnDraw() in una mappa utilizzando class="com.google.android.gms.maps.SupportMapFragment" quindi dobbiamo pianificare un frammento personalizzato.

    È ansible restituire arrays di lat-long con evento touch?

    Sì, se creiamo un frammento di mappe personalizzato e lo utilizziamo possiamo get l'evento Touch o Drag su mappa.

    Come posso get la base di Lat-lungo sulle coordinate dello schermo su setOnDragListener?

    setOnDragListener restituirà le coordinate dello schermo (x, y) . Ora per questo, ci sono alcune tecniche per convertire (x, y) in LatLng e includono Projection insieme a 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: } }); 

    Come funziona ?

    Come ho già detto prima, dobbiamo creare una vista di root personalizzata e usando che possiamo get Touch o trascinare gli events sulla mappa.

    Passaggio 1: creiamo MySupportMapFragment extends SupportMapFragment e lo useremo come nostro file .xml

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

    Passo 2: Creare un MapWrapperLayout extends FrameLayout modo che possiamo impostare un MapWrapperLayout extends FrameLayout Touch o Drag nell'interno e incorporare la sua vista con la visualizzazione mappa. Quindi, abbiamo bisogno di un'interface che useremo in 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: } }); }} 

    Riferimento Link1 , Link2

    Fino ad ora sono in grado di get LatLong basandosi sulle coordinate dello schermo X, Y. Ora devo solo memorizzarlo in Array . Quella matrix verrà utilizzata per disegnare sulla mappa e infine apparirà come un poligono a forma libera.

    immettere qui la descrizione dell'immagine

    Spero che questo ti aiuterà sicuramente.

    Aggiornare:

    Alternativa 2

    Come sappiamo, il layout Frame è un layout trasparente in modo da averlo raggiunto utilizzando il Layout Frame. In questo caso, non è necessario creare un frammento personalizzato. Ho appena utilizzato Layout Frame come layout di root. Così fondamentalmente otterrò Touch Events nel layout root e che restituirà le coordinate dello schermo, come abbiamo ottenuto nel frammento personalizzato in precedenza.

    Ora, ho creato un button all'interno del "Draw gratuito". Quindi, quando si fa clic su che è ansible spostare le dita sulla mappa e disegnare un poligono a mano libera e che disattiverà la tua mappa essere mobile sullo schermo. Quando si fa nuovamente clic sullo stesso button, lo schermo entra in modalità ideale.

    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 

    // Button modifica lo stato mobile della mappa

     btn_draw_State.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (Is_MAP_Moveable != true) { Is_MAP_Moveable = true; } else { Is_MAP_Moveable = false; } } }); 

    Tocca il button del layout della cornice e con l'aiuto di fare un certo task

     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; } if (Is_MAP_Moveable == true) { return true; } else { return false; } } }); 

    // Disegna la tua mappa

     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); } 

    Tuttavia, ora è necessario mantenere la tua list mentre si disegna, quindi è necessario cancellare i dati precedenti della list.

    Check this out .. Credo che U siano in grado di mostrare Google Map v2

    Controllare il metodo "decodePoly" e "drawPath" in AsyncTask

    Principale impatto in "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); 

    Completa la class per il tuo riferimento ..

     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 } } 

    Spero che sia d'aiuto. Saluti!

    AGGIORNARE

    controllare questo .. Creare OnDragListener per il frammento di Google Map v2

    Controlla anche questo .. Come disegnare una forma sul frammento della mappa toccandolo usando la mappa di Google V2

    Alcuni ulteriori riferimenti .. Come get le coordinate dello schermo dal marcatore in google maps v2 android

    Quindi abbiamo qualche soluzione per disegnare a mano la mano sulla mappa v2. Implementa GoogleMap.OnMarkerDragListener nell'attività della tua mappa. Supererà la function di MarkerDrag.

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

    è ansible passare una sorta di hack per la mano libera, come non appena l'utente toccherà la mappa, dovrai individuare le coordinate e passarla all'indirizzo onMarkerDrag. Dovnetworking utilizzare le informazioni della zona per ulteriori processi. Per l'evento di contatto è ansible implementare GoogleMap.OnMapClickListener e get le coordinate dal suo parametro. Spero che questo aiuterà 🙂

    questo è Google Maps API V2 tutorial:

     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 ); } } 

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

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.