in my application i get 25 markers from the webservice, and i add them to the map, then when user move the map i detect the center position and i get new 25 markers to add them in the map. the process must be:
1-get 25 markers from webservice
2-add the 25 markers to the map
3-when map move, detect the center position
4-get new 25 markers
5-add the new 25 markers to the map
6-delete the old 25 markers from the map
my problem is in number 6, how can i delete the 25 old markers after adding the 25 new markers.
i hope that i can find any helpful ideas, and thank you
#Barns thank you for your help, that loop doesn't work and i get this error java.util.HashMap$HashIterator.nextEntry, so i change it with this loop and finnaly it works
for (Iterator<Map.Entry<String, Marker>> iterator = markerList.entrySet().iterator(); iterator.hasNext();){
Map.Entry<String, Marker> entry = iterator.next();
//Log.e("key", entry.getKey()+"");
String bikeId = entry.getKey();
int i = SearchBike(bikeId);
//Log.e("i",i+"");
if (i == 0) {
Marker marker = entry.getValue();
marker.remove();
iterator.remove();
markerList.remove(bikeId);
}
}
for SearchBike(bikeId) i create it because i can't use arrayList.contain() because the result is an object not a string
private int SearchBike(String id){
int i = 0;
for (Bikes bike : arrayList){
if (bike.getId().equals(id)) {
i++;
}
}
return i;
}
so if i==0 that's mean the marker doesn't exist in the new list and should be deleted from the map
Create a HashMap class variable to hold information about the markers:
HashMap<Long, Marker> markerList = new HashMap<>();
(I assume bike.getId() returns a long type, but if you have used a different type you must change the definition of the HashMap and the following code to reflect that type.)
After the for (Bikes bike : arrayList) loop is run go through all the values in the markerList and remove the Markers that aren't in the arrayList.
private void addMarkers(){
//set Markers of bikes list
//First loop!!
for (Bikes bike : arrayList){
BitmapDescriptor pinMarker = null;
LatLng latLng = new LatLng(Double.parseDouble(bike.getLatitude()),Double.parseDouble(bike.getLongitude()));
switch (bike.getBreakdown()){
case "false":
pinMarker = pinWork;
break;
case "true":
pinMarker = pinMaintenance;
break;
}
Marker marker = VelosMap.addMarker(new MarkerOptions()
.position(latLng)
.icon(pinMarker)
.zIndex(1));
if(!markerList.containsKey(bike.getId())){
Marker marker = map.addMarker(marker);
//Add the marker to the marker list
markerList.put(bike.getId(), marker);
HashMap<String,String>data=new HashMap<String,String>();
data.put("id",bike.getId());
data.put("imei",bike.getImei());
data.put("inUse",bike.getInUse());
data.put("breakdown",bike.getBreakdown());
marker.setTag(data);
}
}
// This will iterate through all the items in the new list ...
//...and remove the markers that are not found in the new list
// Second Loop!!
Iterator<Long> it = markerList.keySet().iterator();
while(it.hasNext();){
Long key = it.next();
if(!bikeContains(key)){
Marker marker = markerList.remove(key);
marker.remove();
}
}
}
private boolean bikeContains(Long id){
for (Bikes bike : arrayList){
Long bikeId = bike.getId();
if(bikeId == id){
return true;
}
}
return false;
}
EXPLANATION:
The first time through addMarkers():
The markerList is empty so in line if(!markerList.containsKey(bike.getId())){ a new entry will be added every pass through the first loop for (Bikes bike : arrayList){. And the Marker will be added to the map. In the second loop for (Long key : markerList.keySet()){ we iterate through the HashMap and if the arrayList does not contain the "key" then it is removed from the markerList and from the map. But, because this is the first time through, nothing will be removed.
The second time through the addMarkers() method different bike locations are present in the arrayList containing the Bike data which should have bikes with different "id" values than the first time around--at least for some bikes.
This time when if(!markerList.containsKey(bike.getId())){ is called some of the values for bike.getId() will still be in the markerList --> nothing is done! But, some bike.getId() values will not be in the list--> these will be add to the list and markers added to the map. This means you will have more than 25 markers and more than 25 elements in markerList.
In the second loop for (Long key : markerList.keySet()){ a check is performed to see if the arrayList contains the keys from the markerList. If not in arrayList then that marker is removed from the markerList and the from the map.
What you must do is, before adding the new markers, you must clear the map by calling mGoogleMap.clear() . And you have to do this every time before adding the new markers.
Related
I would like to know how can I add for example the same marker into different array lists. I have let's say 5 array lists and 7 markers. I am adding the markers to the map, adding each marker to it's corresponding list and filter to display or hide the markers according to the list selected by the user. Everything works fine when the lists contain different markers, but when I have common markers in two lists the common marker will be kept only in the last list added.
List<Marker> firstList = new ArrayList<>();
List<Marker> secondList= new ArrayList<>();
List<Marker> thirdList= new ArrayList<>();
List<Marker> fourthList= new ArrayList<>();
List<Marker> fifthList= new ArrayList<>();
Marker marker1 = mMap.addMarker(new MarkerOptions().position(latLong1).title("MARKER1").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker1"));
Marker marker2 = mMap.addMarker(new MarkerOptions().position(latLong2).title("MARKER2").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker2"));
Marker marker3 = mMap.addMarker(new MarkerOptions().position(latLong3).title("MARKER3").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker3"));
Marker marker4 = mMap.addMarker(new MarkerOptions().position(latLong4).title("MARKER4").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker4"));
Marker marker5 = mMap.addMarker(new MarkerOptions().position(latLong5).title("MARKER5").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker5"));
Marker marker6 = mMap.addMarker(new MarkerOptions().position(latLong6).title("MARKER6").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker6"));
Marker marker7 = mMap.addMarker(new MarkerOptions().position(latLong7).title("MARKER7").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker7"));
firstList.add(marker1);
secondList.add(marker2);
secondList.add(marker3);
thirdList.add(marker1);
thirdList.add(marker4);
fourthList.add(marker5);
fifthList.add(marker6);
fifthList.add(marker7);
fifthList.add(marker1);
fifthList.add(marker2);
So when I filter the markers by lists for example if I filter for firstList no marker will be displayed, if I filter for thirdList only marker4 will be displayed and if I filter for fifthList than al the markers will be displayed including marker1. So the list keeps only the last added common items. So how can I make it so that the lists will keep all their objects even though they are common to other lists?
Thanks in advance!
UPDATE:
I don't know if this is exactly what you suggested, but I did this and now the filter is working properly. By doing this I have another problem.
List<Marker> firstList = new ArrayList<>();
List<Marker> secondList= new ArrayList<>();
List<Marker> thirdList= new ArrayList<>();
List<Marker> fourthList= new ArrayList<>();
List<Marker> fifthList= new ArrayList<>();
firstList.add(mMap.addMarker(new MarkerOptions().position(latLong1).title("MARKER1").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker1")));
secondList.add(mMap.addMarker(new MarkerOptions().position(latLong2).title("MARKER2").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker2")));
secondList.add(mMap.addMarker(new MarkerOptions().position(latLong3).title("MARKER3").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker3")));
thirdList.add(mMap.addMarker(new MarkerOptions().position(latLong1).title("MARKER1").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker1")));
thirdList.add(mMap.addMarker(new MarkerOptions().position(latLong4).title("MARKER4").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker4")));
fourthList.add(mMap.addMarker(new MarkerOptions().position(latLong5).title("MARKER5").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker5")));
fifthList.add(mMap.addMarker(new MarkerOptions().position(latLong6).title("MARKER6").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker6")));
fifthList.add(mMap.addMarker(new MarkerOptions().position(latLong7).title("MARKER7").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker7")));
fifthList.add(mMap.addMarker(new MarkerOptions().position(latLong1).title("MARKER1").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker1")));
fifthList.add(mMap.addMarker(new MarkerOptions().position(latLong2).title("MARKER2").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)).snippet("Snippet marker2")));
Now I want to add OnInfoWindowClickListener to my markers info window. Each marker must open a new activity. Before doing this modification I was adding all the markers to the a private Map allMarkersMap = new HashMap(); and I was adding every marker to the HashMap with allMarkersMap.put(marker1, Marker1.class);
GoogleMap.OnInfoWindowClickListener MyOnInfoWindowClickListener = new GoogleMap.OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker marker) {
Class cls = allMarkersMap.get(marker);
Intent intent = new Intent(MainActivity.this, cls );
startActivity(intent);
}
};
How can I do this now?
Your markers have the same references, that's what leads you to this behaviour.
Instead of creating and passing markers, you should create MarkerOptions and when you add a marker to your array list then create a new Marker. MarkerOptions is the object which keep the informations you want for your markers, that's the only object which should be instantiated once.
I am displaying the location of buses in google map where I am getting the location from the bus database table on the server. I am facing problem to delete or to update their locations on google map since a new marker is always being created when the longitude and latitude change in the bus table. How can I delete and update specific Marker in Google Map?
I appreciate any help.
Code:
private void gotoLocation(double lat, double lng, String route_direct) {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
final float zoom = 11;
LatLng ll = new LatLng(lat, lng);
if (lat != 0 && lng != 0 && !route_direct.isEmpty()) {
MarkerOptions markerOpt = new MarkerOptions().title(route_direct)
.position(ll).visible(true);
Marker marker = map.addMarker(markerOpt);
marker.showInfoWindow();
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, zoom);
map.moveCamera(update);
}
}
I solved in this way. I created HashMap for markers.
Sample,
HashMap<String, Marker> markerlist = new HashMap<>();
markerlist.put(route_direct, yourmarker);//add marker to list
markerlist.get(route_direct);//get marker from list
Then in your update process, try this code
if(markerlist.containsKey(route_direct)){
Marker marker = markerlist.get(route_direct);
//update marker
}else{
//add marker or do anything
}
but to use this flow, you need to have unique data for marker such as marker id.
Hope this will help you. Good luck.
Here we have used on our project in didTap marker delegates, We have created two functions one is Create marker and second one is delete marker code is given below in IOS swift
1.CreateMarker function call when you get Response from APIs
2.DeleteMarker call when you want to delete marker from map
//MARK: CreateMarker
func CreateMarker(TripLocation:[RECDATA])
{
//let path = GMSMutablePath()
for i in 0..<TripLocation.count
{
// Marker icon
var image = UIImage(named: "ic_greenMark")
// Get location coordinate
let locationTujuan = CLLocation(latitude: Double(TripLocation[i].facilityLatitude ?? 0.0) , longitude: Double(TripLocation[i].facilityLongitude ?? 0.0) )
image = UIImage(named: "ic_greenMark")
// create marker
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(locationTujuan.coordinate.latitude, locationTujuan.coordinate.longitude)
// marker.title = titleMarker
marker.icon = image
marker.map = MapView
let camera = GMSCameraPosition.camera(withLatitude:CLLocationDegrees(TripLocation[i].facilityLatitude!), longitude: CLLocationDegrees(TripLocation[i].facilityLongitude ?? 0.0), zoom: 8)
MapView.camera = camera
// append marker into markers array to show all marker in map
markers.append(marker)
}
}
//MARK: DeleteMarker
func DeleteMarker(marker:GMSMarker)
{
// Create Temp Object array
var Tempmarkers = [RECDATA]()
//check marker is exist or not
for obj in arrayRECDATA
{
let lat = Double(obj.facilityLatitude!)
let log = Double(obj.facilityLongitude!)
// remove marker from object array
if marker.position.latitude != lat && marker.position.longitude != log
{
Tempmarkers.append(obj)
}
}
// store temp array into original array
arrayRECDATA = Tempmarkers
// clean all marker and reload
MapView.clear()
CreateMarker(TripLocation: arrayRECDATA)
}
Thank you :)
Define variable for each marker like
Marker m1;
Marker m2;
etc.
And do whatever operation on specific marker using that variable. To delete the specific marker
m1.delete ();
m2.delete ();
Something like this, you can try and let me know if you face any issue.
I want to refresh the position of about 50-100 markers on a map every 5 seconds. It gets the position data from a web service, which all works fine. The problem is, I am getting huge lag on a Galaxy S5 when deleting all the markers and creating new ones.
Is there any other way to move markers? I don't think deleting them and recreating them is a good idea.
I saw other apps using the maps api and refreshing marker positions, but without any lag at all (for example FlightRadar24). How to solve that problem?
Update:
I am using the code from the answer below but it still recreates the marker every time. Does someone know why?
My ServiceData class:
public static class ServiceData {
String ID;
String title;
String snippet;
float hue;
LatLng latlon;
ServiceData(String id, String title, String snippet, float hue, LatLng latlon) {
this.ID = id;
this.title = title;
this.snippet = snippet;
this.hue = hue;
this.latlon = latlon;
}
}
Every time I update the markers I call itemList.clear(); (Containing the ServiceData class) to clear it.
then I'm using
itemList.add(new ServiceData(id, line, snippet, hue, new LatLng(lat, lon)); to add the items to it.
When you first add markers on the map, also add them to some List or Map (that will depend on data you are retrieving, and how you can identify markers), and then when you have to refresh marker location don't recreate markers, but set their positions to new values with marker.setPosition(latlng);
Code example for updating marker positions on the map:
public class ServiceData
{
String id;
LatLng latlng;
}
GoogleMap gmap;
public Map<String, Marker> markers = new HashMap<String, Marker>();
public List<ServiceData> list = new ArrayList<ServiceData>();
public void refreshMarkers()
{
Map<String, Marker> updatedMarkers = new HashMap<String, Marker>();
for (ServiceData data: list)
{
// if marker exists move its location, if not add new marker
Marker marker = markers.get(data.id);
if (marker == null)
{
marker = gmap.addMarker(new MarkerOptions().position(data.latlng));
}
else
{
marker.setPosition(data.latlng);
markers.remove(data.id);
}
updatedMarkers.put(data.id, marker);
}
// all markers that are left in markers list need to be deleted from the map
for (Marker marker : markers.values())
{
marker.remove();
}
markers = updatedMarkers;
}
How can I hide multiple markers on Android Maps V2?
I have 10 markers. 5 a certain type of cinema and 5 another type.
If I use the below code only the last marker disappears.
Marker cinema1,cinema2;
cinema1 = gMap.addMarker......
cinema1 = gMap.addMarker......
cinema2 = gMap.addMarker......
cinema2 = gMap.addMarker......
and so on
On Click Event
cinema1.setVisible(false);
This only sets the last marker = to cinema1 to invisible (obviously) so the questions is how can I set all 5 markers invisible without declaring a Marker for each?
Thanks
You should create list with markers and manipulate with its help.
Marker dilers1,dilers2;
List<Marker> markers = new ArrayList<>();
dilers1 = mMap.addMarker(new MarkerOptions().position(new LatLng(55.755823,37.622315)).title("Melbourne"));
dilers2 = mMap.addMarker(new MarkerOptions().position(new LatLng(55.765823,37.612315)).title("Melbourne2"));
markers.add(dilers1);
markers.add(dilers2);
public void changer(){
for (Marker mkr: markers) {
mkr.setVisible(false);
}
}
You could just use an Hashmap if your types have an ID
Hashmap<Integer, Marker> markers = new Hashmap<Integer, Marker>()
markers.Add(cinema1.getID(), gMap.addMarker(...));
markers.Add(cinema2.getID(), gMap.addMarker(...));
markers.Add(cinema3.getID(), gMap.addMarker(...));
i am currently trying to implement an ActionBar-Button that on usage sets all my markers on my GoogleMap-object visible or invisible. My problem is that i don't know how i can get a reference to all my markers once they have been created and are shown on my map. Im looking for a solution where i stash all my marker-objects into an array, that i can access in other parts of my code aswell. is this approach reasonable?
here is what i am thinking of:
private Marker[] mMarkerArray = null;
for (int i = 0; i < MainActivity.customers.size(); i++) {
LatLng location = new LatLng(mData.lat, mData.lng);
Marker marker = mMap.addMarker(new MarkerOptions().position(location)
.title(mData.title)
.snippet(mData.snippet));
mMarkerArray.add(marker);
}
and set all my markers invisible on within another method:
for (int i = 0; i < mMarkerArray.length;; i++) {
mMarkerArray[i].setVisible(false);
}
it refuses to add the markers to a Marker[]-array. how can i achieve it?
mMarkerArray.add(marker) doesnt work
i figured out an answer that also regards my customerList having customers without coordinates --> (0,0;0,0). inspired by this blog.
initialize ArrayList:
private ArrayList<Marker> mMarkerArray = new ArrayList<Marker>();
add marker to my map and to the mMarkerArray:
for (int i = 0; i < MainActivity.customers.size(); i++) {
Customer customer = MainActivity.customers.get(i);
if (customer.getLon() != 0.0) {
if (!customer.isProspect()) {
Data mData= new Data(customer.getLat(),customer.getLon(),customer.getName(),
customer.getOrt());
LatLng location = new LatLng(mData.lat, mData.lng);
Marker marker = mMap.addMarker(new MarkerOptions().position(location)
.title(mData.title)
.snippet(mData.snippet));
mMarkerArray.add(marker);
}}}
set all markers not-visible
for (Marker marker : mMarkerArray) {
marker.setVisible(false);
//marker.remove(); <-- works too!
}
Replace
private Marker[] mMarkerArray = null;
with
private List<Marker> mMarkerArray = new ArrayList<Marker>();
and you should be fine.
If you use Android Maps Extensions, you can simply iterate over all markers using
for (Marker marker : googleMap.getMarkers()) {
marker.setVisible(false);
}
without having your own List of all Markers.
You can keep a Collection of OverlayItem within your Activity or Fragment and then call MapView.getOverlays().clear() to make them "invisible" and then add them back to make them visible again. Call MapView.invalidate() after each action to cause the map to be repainted.