I would like to implement multiple polygons with an editable using a drag listener. I am able to draw the multiple polygons but I don't know how to make editable.
I am able to move marker for current polygon but when I try to move previous polygon’s marker app is crash. I tried with saving polygon list but I can not able to drag the marker.
please see my code HERE.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (readyToGo()) {
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
if (savedInstanceState == null) {
mapFragment.getMapAsync(this);
}
mapFragment.getMapAsync(this);
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
CameraUpdate center =
CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044,
-73.98180484771729));
CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
mMap.moveCamera(center);
mMap.animateCamera(zoom);
mMap.setIndoorEnabled(false);
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
Marker marker = mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
marker.setTag(latLng);
markerList.add(marker);
points.add(latLng);
drawPolygon(points);
}
});
mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
@Override
public void onMarkerDragStart(Marker marker) {
}
@Override
public void onMarkerDrag(Marker marker) {
updateMarkerLocation(marker, false);
}
@Override
public void onMarkerDragEnd(Marker marker) {
updateMarkerLocation(marker, true);
}
});
}
public void closePolygon(View view) {
}
public void newPolygon(View view) {
//
points.clear();
markerList.clear();
polygon = null;
// mMap.clear();
}
private void updateMarkerLocation(Marker marker, boolean calculate) {
LatLng latLng = (LatLng) marker.getTag();
int position = points.indexOf(latLng);
points.set(position, marker.getPosition());
marker.setTag(marker.getPosition());
drawPolygon(points);
}
private void drawPolygon(List<LatLng> latLngList) {
if (polygon != null) {
polygon.remove();
}
polygonOptions = new PolygonOptions();
polygonOptions.addAll(latLngList);
polygon = mMap.addPolygon(polygonOptions);
}
}
Basically this approach keeps the markers and points as collections associated with each polygon. It simplifies things by assuming after 5 markers a new polygon is created (equivalent to an add polygon).
UPDATED: To use the "new polygon" button as defined in the layout in github. Button listener just sets a flag and instead of using a size=5 check replace the check with the flag.
A map from any marker to its corresponding list is maintained for use in the updateMarkerLocation
method.
All of this is predicated on the fact that any marker has a unique id provided by the map API getId()
which in practice is a string like "m7".
I've listed the parts updated:
// Map a marker id to its corresponding list (represented by the root marker id)
HashMap<String,String> markerToList = new HashMap<>();
// A list of markers for each polygon (designated by the marker root).
HashMap<String,List<Marker>> polygonMarkers = new HashMap<>();
// A list of polygon points for each polygon (designed by the marker root).
HashMap<String,List<LatLng>> polygonPoints = new HashMap<>();
// List of polygons (designated by marker root).
HashMap<String,Polygon> polygons = new HashMap<>();
// The active polygon (designated by marker root) - polygon added to.
String markerListKey;
// Flag used to record when the 'New Polygon' button is pressed. Next map
// click starts a new polygon.
boolean newPolygon = false;
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
CameraUpdate center =
CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044,
-73.98180484771729));
CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
mMap.moveCamera(center);
mMap.animateCamera(zoom);
mMap.setIndoorEnabled(false);
Button b = findViewById(R.id.bt_new_polygon);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
newPolygon = true;
}
});
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
Marker marker = mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
marker.setTag(latLng);
// Special case for very first marker.
if (polygonMarkers.size() == 0) {
polygonMarkers.put(marker.getId(),new ArrayList<Marker>());
// only 0 or 1 polygons so just add it to new one or existing one.
markerList = new ArrayList<>();
points = new ArrayList<>();
polygonMarkers.put(marker.getId(),markerList);
polygonPoints.put(marker.getId(),points);
markerListKey = marker.getId();
}
if (newPolygon) {
newPolygon = false;
markerList = new ArrayList<>();
points = new ArrayList<>();
polygonMarkers.put(marker.getId(),markerList);
polygonPoints.put(marker.getId(),points);
markerListKey = marker.getId();
}
markerList.add(marker);
points.add(latLng);
markerToList.put(marker.getId(),markerListKey);
drawPolygon(markerListKey, points);
}
});
private void updateMarkerLocation(Marker marker, boolean calculate) {
// Use the marker to figure out which polygon list to use...
List<LatLng> pts = polygonPoints.get(markerToList.get(marker.getId()));
// This is much the same except use the retrieved point list.
LatLng latLng = (LatLng) marker.getTag();
int position = pts.indexOf(latLng);
pts.set(position, marker.getPosition());
marker.setTag(marker.getPosition());
drawPolygon(markerToList.get(marker.getId()),pts);
}
private void drawPolygon(String mKey, List<LatLng> latLngList) {
// Use the existing polygon (if any) for the root marker.
Polygon polygon = polygons.get(mKey);
if (polygon != null) {
polygon.remove();
}
polygonOptions = new PolygonOptions();
polygonOptions.addAll(latLngList);
polygon = mMap.addPolygon(polygonOptions);
// And update the list for the root marker.
polygons.put(mKey,polygon);
}
Initial collection of 3 polygons added by clicking on map...
Then an image showing a point in each polygon stretched...