I was having some troubles when trying to customize the clsutered markers on Google Map. I am using Google Map Android API Library and reference from GoogleMap Documentation. Here are my codes:
private void setUpClusterer() {
googleBasemap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(
1.379348, 103.849876), 11.0f));
mClusterManager = new ClusterManager<EventClusterItem>(this,
googleBasemap);
googleBasemap.setOnCameraChangeListener(mClusterManager);
googleBasemap.setOnMarkerClickListener(mClusterManager);
addItems();
}
private void addItems() {
for (int i = 0; i < convertedGeomList.size(); i++) {
EventClusterItem offsetItem = new EventClusterItem(convertedGeomList.get(i)
.getY(), convertedGeomList.get(i).getX());
mClusterManager.addItem(offsetItem);
}
}
And my EventClusterItem class:
public class EventClusterItem implements ClusterItem {
private final LatLng mPosition;
public EventClusterItem(double lat, double lng) {
mPosition = new LatLng(lat, lng);
}
public LatLng getPosition() {
return mPosition;
}
}
So basically with these codes, it only shows up a red color marker onto the map. I wonder how can I customize the marker with my own image. I know you can do this to customize the marker on the map:
Marker melbourne = mMap.addMarker(new MarkerOptions()
.position(MELBOURNE)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
But I not sure how to implement it in this case. Any guides?
Thanks in advance.
Use answers from these posts:
How to set my own icon for markers in clusterer in Google Maps
How to add title, snippet and icon to ClusterItem?
There is no any guide about this API. You should find the code for this library and try to understand it - it is easy, the code is perfect (but a little bit slow in fact).
Related
I'm trying to make an app that will use an Place autocomplete fragment in one activity and when I select a place in it, on a click of a button, I'm supposed to open another activity (Google Maps activity) and it's supposed to get the location that I chose in the first one. I've tried passing Longitude and Latitude from Main class to Maps class, but it just crashes my app. Anyone have any idea how to fix?
Thank you in advance!
EDIT: Sample of what I've tried so far:
/*This is the main class where my autocomplete fragment is*/
Double Lat;
Double lang;
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
// Lat = place.getLatLng().latitude;
// lang = place.getLatLng().longitude;
setLang(place.getLatLng().longitude);
setLat(place.getLatLng().latitude);
Log.i(TAG, "Place: " + place.getName());
}
public void setLang(Double langg){
this.lang = langg;
}
public void setLat(Double Latt){
this.Lat = Latt;
}
public Double getLang(){
return lang;
}
public Double getLat(){
return Lat;
}
/* This is the maps class */
MainActivity maAct;
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng place = new LatLng(maAct.getLat(), maAct.getLang());
// LatLng paris = new LatLng(48.8566, 2.3522);
mMap.addMarker(new MarkerOptions().position(place).title("Marker inPlace"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(place));
}
Ok, you may consider to pass the latitude and longitude by Intent.
// MainActivity
Intent intent = new Intent(MainActivity.this, MapActivity.class);
intent.putExtra("lat", Lat);
intent.putExtra("lng", lang);
startActivity(intent);
And..
// Map Activity onMapReady
double lat = getIntent().getDoubleExtra("lat", DEFAULT_LAT);
double lng = getIntent().getDoubleExtra("lng", DEFAULT_LNG);
LatLng place = new LatLng(lat, lng);
mMap.addMarker(new MarkerOptions().position(place).title("Marker inPlace"));
You cannot getValue by maAct, your concept is incorrect.
First if you just
MainActivity maAct;
maAct is not assigned any 'value', so that if you call any methods of maAct, you will get NullPointerException.
Besides, if you really give it a 'value',
// it is totally wrong, just an example only
MainActivity maAct = new MainActivity();
But it is not the same reference so that you cannot get the values you stored before.
What i understand is you want to navigate to the passed latitude and longitude.Here is a sample
String uri = String.format(Locale.ENGLISH, "google.navigation:q=%f,%f", Double.parseDouble(latitude), Double.parseDouble(longitude));
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
if(intent.resolveActivity(context.getPackageManager())!=null)
context.startActivity(intent);
You can find more info like creating markers and all here
Edit:
As per your code you want to set the marker.Here is the steps and sample for a working marker example.
Hello everyone I am new dealing with google map API , and I have a list of LatLng object that added marker on map .
for (LatLng location : camerasLocations) {
googleMap.addMarker(new MarkerOptions()
.position(location).icon(icon)
.title(cameraList.get(j).getName()));
}
I want to know the position of the marker on that array when I click on the marker with :
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
showDialog(getActivity(), "");
return false;
}
});
any help please ...
First you need to set position as tag on marker while adding marker in google map
for(int i = 0, i < camerasLocations.size(), i++){
Marker marker = googleMap.addMarker(new MarkerOptions()
.position(location).icon(icon)
.title(cameraList.get(j).getName()))
.setTag(i);
}
And then you can obtain this marker position in the onclick method using getTag() method :
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
Toast.makeText(this, "Marker position >> " + marker.getTag(), Toast.LENGTH_SHORT).show();
return false;
}
});
As far as I know, they are not positioned in that way. You would have to handle it yourself. If you are sure you just want to get the index based on the order of creation, you can do sth like that:
Create private field with Map, for storing that information
//class field
private Map<Marker, Integer> markersOrderNumbers = new HashMap<>();
Afterward, populate it
//Your method
int markerIndex = 0;
for (LatLng location : camerasLocations) {
Marker marker = googleMap.addMarker(new MarkerOptions()
.position(location).icon(icon)
.title(cameraList.get(j).getName()));
markersOrderNumbers.put(marker,markerIndex);
markerIndex++;
}
And then you can obtain this index number in the onclick method
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
Integer index = markersOrderNumbers.get(marker);
//Do whatever you want to
showDialog(getActivity(), "");
return false;
}
});
I might add that if you are not certainly focused on the index itself but rather on some information that you get using that Id, you can use provided method to map marker with needed information at the first place like:
Map<Marker, Whatever> ...
So I've been able to get periodic updates of my current location through the developer android page, making your app location aware. Now, whenever my location changes, I am able to get the latitude and longitude of that location. However, who do i implement this with Google Maps?
This line below implements a button on my map that finds my current location and places a blue dot/marker on it (does not receive periodic updates)
mMap.setMyLocationEnabled(true);
What should I put in my onLocationChanged() event in order for the blue dot to be updated with the new lat and long?
The blue dot and the precision circle are automatically managed by the map and you can't update it or change it's symbology. In fact, it's managed automatically using it's own LocationProvider so it gets the best location resolution available (you don't need to write code to update it, just enable it using mMap.setMyLocationEnabled(true);).
If you want to mock it's behaviour you can write something like this (you should disable the my location layer doing mMap.setMyLocationEnabled(false);):
private BitmapDescriptor markerDescriptor;
private int accuracyStrokeColor = Color.argb(255, 130, 182, 228);
private int accuracyFillColor = Color.argb(100, 130, 182, 228);
private Marker positionMarker;
private Circle accuracyCircle;
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
markerDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.yourmarkericon);
}
#Override
public void onLocationChanged(Location location) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
float accuracy = location.getAccuracy();
if (positionMarker != null) {
positionMarker.remove();
}
final MarkerOptions positionMarkerOptions = new MarkerOptions()
.position(new LatLng(latitude, longitude))
.icon(markerDescriptor)
.anchor(0.5f, 0.5f);
positionMarker = mMap.addMarker(positionMarkerOptions);
if (accuracyCircle != null) {
accuracyCircle.remove();
}
final CircleOptions accuracyCircleOptions = new CircleOptions()
.center(new LatLng(latitude, longitude))
.radius(accuracy)
.fillColor(accuracyFillColor)
.strokeColor(accuracyStrokeColor)
.strokeWidth(2.0f);
accuracyCircle = mMap.addCircle(accuracyCircleOptions);
}
mMap.setMyLocationEnabled(true);
this is simple trick for blue marker of current location and did the trick for me.
Firstly sorry for asking so many questions here the past couple of weeks, I'm new to android studio and finding it tough to figure out a lot of the core concepts by myself.
In regards to the question, I have a project set up so whatever you type into the "1.2, -1.2" ect parameters you will find you the distance between two places and your answer will be displayed as a toast. However, I want the latitudes and longitueds to be variables.
Button button1=(Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Double distance = 1.0;
int val = 1;
Toast.makeText(getApplicationContext(), "You are " + String.valueOf(distance
(1.2, -1.2, 1.3, -2.4, "K")) + "kilometers away from the flag", Toast.LENGTH_LONG).show(); }
});
I have the following two methods and I want the values LatLng and currentLatitude and currentLongitude doubles for the parameters above.
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(53.3835,6.5996)).title("Marker"));
}
and
private void handleNewLocation(Location location) {
Log.d(TAG, location.toString());
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
//mMap.addMarker(new MarkerOptions().position(new LatLng(currentLatitude, currentLongitude)).title("Current Location"));
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title("I am here!");
mMap.addMarker(options);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
Any insight on how to do it would be much appreciated. From what I've read I know I'll need to split the LatLng variable into strings but thats all I can think of so far
If those 2 methods are in the same class then just make those 2 variables attributes of that class, else you will need to pass them to the corresponding classes. I will demonstrate in a simpler example than your code :
public class MyClass(){
private int lat;
private int longt;
//constructors ,setters and getters
public void method1(){
//affecting those attributes with values
lat = 1;
longt = 2;
}
public void method2(){
//simply access the attributes
System.out.println("lat "+lat+" longt "+longt);
}
}
Reading the comments , I think I need to further explain to you that when a variable is declared inside a method, it is local to that method, and therefor it will be "destroyed" (garbage collected or w.e) when that method is done doing it's job. But when a variable is declared outside a method, like the class's attributes, you can still refer to it whenever you need to, until the instance of that class is "destroyed".
I've got a Google Map with Polygons, I've got everything to work except this last part which is detect if a Marker is already inside a Polygon.The current situation is when I touch a Polygon it will add the Marker"which is correct" but if I touch the Polygon in a different spot it will remove the Marker and add a new one. What I want to happen is if a Marker is already within those points don't add a new one. My code is below any help would be appreciate.
public void onMapClick(LatLng point) {
for (int j = 0; j < arrPolygons.size(); j++) {
if (isPointInPolygon(point, arrPolygons.get(j).getPoints())) {
if (marker != null) {
marker.remove();
marker = null;
Log.v("Marker", "Removing Marker");
}else{
marker = googleMap.addMarker(new MarkerOptions()
.position(point)
.title("test")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
Log.v("Marker", "ADDing Marker");
}
}
}
Any help would be appreciated.
The easiest way to do this would be using the Google Maps Android API Utility Library, which contains the PolyUtil class.
First import the library by adding the current version to your build.gradle, currently 0.3.4
for example:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.google.android.gms:play-services-maps:7.3.0'
compile 'com.google.maps.android:android-maps-utils:0.3.4'
}
For this simple example we'll assume the Map Activity class definition and member variables look like this, and only one Polygon defined in polygonList:
import com.google.maps.android.PolyUtil;
//other imports.....
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private Marker marker;
List<LatLng> polygonList = new ArrayList<LatLng>();
//.............
You would then set up your GoogleMap.OnMapClickListener like this in order to only add one Marker inside the Polygon.:
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
if (PolyUtil.containsLocation(point, polygonList, false)) {
if (marker == null) {
//only add Marker if there is not one already inside the Polygon
marker = mMap.addMarker(new MarkerOptions()
.position(point)
.title("test")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
Log.v("Marker", "ADDing Marker");
}
}
}
});
Multiple Polygons, Multiple Markers Solution:
In order to make it work with multiple Ploygons, you could use a POJO to store Polygon/Marker pairs:
public class PolyMarkerObject{
Polygon polygon;
Marker marker;
}
Then define a new member variable polyMarkerList:
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
List<PolyMarkerObject> polyMarkerList = new ArrayList<>();
//.............
Add each Polygon to the list when drawing it:
List<LatLng> newPolygon = new ArrayList<>();
//set up the points in the Polygon.......
Polygon p = mMap.addPolygon(new PolygonOptions()
.addAll(newPolygon)
.strokeColor(Color.RED)
.fillColor(Color.BLUE));
PolyMarkerObject newPolyMarkerObj = new PolyMarkerObject();
newPolyMarkerObj.polygon = p;
polyMarkerList.add(newPolyMarkerObj);
Then cycle through the list on each Map click to see whether the current Ploygon already has a Marker. If it does not have a Marker already, then remove any Marker already placed in a different Polygon, and create one in the current Polygon:
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
for (PolyMarkerObject pmObj : polyMarkerList) {
//only add Marker if there is not one already inside the Polygon
if (PolyUtil.containsLocation(point, pmObj.polygon.getPoints(), false)) {
if (pmObj.marker == null) {
//Add Marker to current Polygon
Marker newMarker = mMap.addMarker(new MarkerOptions()
.position(point)
.title("test")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
pmObj.marker = newMarker;
Log.v("Marker", "ADDing Marker");
break;
}
}
}
}
});
Multiple Polygons, One Marker Solution:
In this case, you just need one Marker reference, and a list of Polygons:
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
Marker marker;
List<Polygon> polyList = new ArrayList<>();
//................
Add the Polygon to the list when it's added to the Map:
List<LatLng> newPolygon = new ArrayList<>();
//set up the points in the Polygon.......
Polygon p = mMap.addPolygon(new PolygonOptions()
.addAll(newPolygon)
.strokeColor(Color.RED)
.fillColor(Color.BLUE));
polyList.add(p);
Then, in the Map click listener, you have two cases, one for if the Marker reference is null (no Marker added yet), and one for if the Marker is in a different Polygon. If the Marker is in the current Polygon already, it will not be moved.
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
for (Polygon pObj : polyList) {
//find Polygon user tapped inside of
if (PolyUtil.containsLocation(point, pObj.getPoints(), false)) {
//first case, no Marker
if (marker == null) {
//Add Marker to current Polygon
marker = mMap.addMarker(new MarkerOptions()
.position(point)
.title("test")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
Log.v("Marker", "ADDing first Marker");
break;
}
else if (!PolyUtil.containsLocation(marker.getPosition(), pObj.getPoints(), false)) {
//Marker exists already in a different Polygon
//remove Marker from previous Polygon
marker.remove();
//Add Marker to current Polygon
marker = mMap.addMarker(new MarkerOptions()
.position(point)
.title("test")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
Log.v("Marker", "Moving Marker to new Polygon");
break;
}
}
}
}
});