What this parameter is responsible for? markerSpec in InteractiveInfoWindowAndroid by Appolica - google-maps-markers

in https://github.com/Appolica/InteractiveInfoWindowAndroid i read that
markerSpec - Provides the marker's offsetX and offsetY
but I can't understand what it is responsible for, I changed the values in every possible way, but the result was always the same. R.dimen.marker_offset_x =5dp R.dimen.marker_offset_y=39dp
public void onMapReady(GoogleMap googleMap) {
final Marker marker2 = googleMap.addMarker(new MarkerOptions().position(new LatLng(1, 1)).snippet(FORM_VIEW));
final int offsetX = (int) getResources().getDimension(R.dimen.marker_offset_x);
final int offsetY = (int) getResources().getDimension(R.dimen.marker_offset_y);
final InfoWindow.MarkerSpecification markerSpec =
new InfoWindow.MarkerSpecification(offsetX, offsetY);
formWindow = new InfoWindow(marker2, markerSpec, new FormFragment());
googleMap.setOnMarkerClickListener(MainActivity.this);
}
Maybe someone has worked with this and can explain it to me

Okay I was entering too large values

Related

How do I change the speed of an AnimationTimer in JavaFX?

I'm trying to change the speed of an AnimationTimer so the code runs slower, here is the code I have so far:
AnimationTimer timer = new AnimationTimer() {
#Override
public void handle(long now) {
if (upOrDown != 1) {
for (int i = 0; i < 4; i++) {
snakePositionDown[i] = snake[i].getX();
snakePositionDownY[i] = snake[i].getY();
}
snake[0].setY(snake[0].getY() + 25);
for (int i = 1; i < 4; i++) {
snake[i].setX(snakePositionDown[i - 1]);
snake[i].setY(snakePositionDownY[i - 1]);
}
leftOrRight = 2;
upOrDown = 0;
}
}
};
timer.start();
How would I make the AnimationTimer run slower?
Thanks in advance!
You could use a Timeline for this purpose. Adjusting the Timeline.rate property also allows you to update the "speed":
// update once every second (as long as rate remains 1)
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), event -> {
if (upOrDown != 1) {
for (int i = 0; i < 4; i++) {
snakePositionDown[i] = snake[i].getX();
snakePositionDownY[i] = snake[i].getY();
}
snake[0].setY(snake[0].getY() + 25);
for (int i = 1; i < 4; i++) {
snake[i].setX(snakePositionDown[i - 1]);
snake[i].setY(snakePositionDownY[i - 1]);
}
leftOrRight = 2;
upOrDown = 0;
}
}));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
...
// double speed
timeline.setRate(2);
An AnimationTimer's handle() method is invoked on every "pulse" - i.e., every time a frame is rendered. By default, the JavaFX toolkit will attempt to do this 60 times per second, but that is not in any way guaranteed. It can be changed by setting a system property, and it is possible that future versions of JavaFX will attempt to execute pulses more frequently. If the FX Application Thread has a large amount of work to do, then pulses may occur less frequently than the target rate. Consequently, the code in your handle() method needs to account for the amount of time since the last update.
The parameter passed to the handle(...) method represents the current system time in nanoseconds. So a typical way to approach this is:
AnimationTimer h = new AnimationTimer() {
private long lastUpdate; // Last time in which `handle()` was called
private double speed = 50 ; // The snake moves 50 pixels per second
#Override
public void start() {
lastUpdate = System.nanoTime();
super.start();
}
#Override
public void handle(long now) {
long elapsedNanoSeconds = now - lastUpdate;
// 1 second = 1,000,000,000 (1 billion) nanoseconds
double elapsedSeconds = elapsedNanoSeconds / 1_000_000_000.0;
// ...
snake[0].setY(snake[0].getY() + elapsedSeconds * speed);
// ...
lastUpdate = now;
}
}

Processing: Confusion with UnHex, is there an easier way?

Doing a uni assignment that requires the importing of table data and conversion of numbers into hexadecimal number.
I tried using unHex() but it got quite confusing converting the strings.
Is there an easier way to convert them?
This is a screenshot of the table data:
Table table;
void setup() {
size(200, 200);
background(255);
table = loadTable("msfw15.csv", "header");
}
void draw() {
//Getting tags, probably an easier way.
String work = table.getString(0, 1);
String fashion = table.getString(1, 1);
String blogger = table.getString(2, 1);
String girlsnight = table.getString(3, 1);
String backstage = table.getString(4, 1);
String ootd = table.getString(5, 1);
String melbourne = table.getString(6, 1);
String sydney = table.getString(7, 1);
String emergingdesigner = table.getString(8, 1);
String fashiongram = table.getString(9, 1);
String foodblogger = table.getString(10, 1);
String hiphop = table.getString(11, 1);
String muji = table.getString(12, 1);
String monochrome = table.getString(13, 1);
String swag = table.getString(14, 1);
String alannahhill = table.getString(15, 1);
String popsofcolour = table.getString(16, 1);
String stylesketch = table.getString(17, 1);
String artist = table.getString(18, 1);
String designer = table.getString(19, 1);
String model = table.getString(20, 1);
String vogue = table.getString(21, 1);
String knitwear = table.getString(22, 1);
String knitting = table.getString(23, 1);
color workd = unhex("FF" + work);
fill(workd);
noStroke();
rect(50, 50, 100, 100);
}
First, I think you really need to learn about for loops. Going through that table should only take a couple lines of code. Here is a link to the for loop reference.
Next, I'd recommend checking out the unhex() reference:
String hs = "FF006699";
int hi = unhex(hs);
fill(hi);
rect(30, 20, 55, 55);
Other than that, you need to be much more specific about exactly what you're confused about. What about the unhex() function isn't working how you expect?

Feature Detection Opencv/Javacv not working

I am trying to run the feature detection program of javacv to compare the similar features in 2 images however I am getting a runtimeexception. Since I am completely new to javacv I don't know how to resolve this.
The exception trace is
OpenCV Error: Assertion failed (queryDescriptors.type() == trainDescCollection[0].type()) in unknown function, file ..\..\..\src\opencv\modules\features2d\src\matchers.cpp, line 351
Exception in thread "main" java.lang.RuntimeException: ..\..\..\src\opencv\modules\features2d\src\matchers.cpp:351: error: (-215) queryDescriptors.type() == trainDescCollection[0].type()
at com.googlecode.javacv.cpp.opencv_features2d$DescriptorMatcher.match(Native Method)
at Ex7DescribingSURF.main(Ex7DescribingSURF.java:63)
Here is the source code
import static com.googlecode.javacv.cpp.opencv_core.NORM_L2;
import static com.googlecode.javacv.cpp.opencv_core.cvCreateImage;
import static com.googlecode.javacv.cpp.opencv_features2d.drawMatches;
import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImage;
import java.util.Arrays;
import java.util.Comparator;
import javax.swing.JFrame;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.cpp.opencv_core.CvMat;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.CvSize;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_features2d.BFMatcher;
import com.googlecode.javacv.cpp.opencv_features2d.DMatch;
import com.googlecode.javacv.cpp.opencv_features2d.DescriptorExtractor;
import com.googlecode.javacv.cpp.opencv_features2d.DrawMatchesFlags;
import com.googlecode.javacv.cpp.opencv_features2d.KeyPoint;
import com.googlecode.javacv.cpp.opencv_nonfree.SURF;
public class Ex7DescribingSURF {
/**
* Example for section "Describing SURF features" in chapter 8, page 212.
*
* Computes SURF features, extracts their descriptors, and finds best
* matching descriptors between two images of the same object. There are a
* couple of tricky steps, in particular sorting the descriptors.
*/
public static void main(String[] args) {
IplImage img = cvLoadImage("A.jpg");
IplImage template = cvLoadImage("B.jpg");
IplImage images[] = { img, template };
// Setup SURF feature detector and descriptor.
double hessianThreshold = 2500d;
int nOctaves = 4;
int nOctaveLayers = 2;
boolean extended = true;
boolean upright = false;
SURF surf = new SURF(hessianThreshold, nOctaves, nOctaveLayers,
extended, upright);
DescriptorExtractor surfDesc = DescriptorExtractor.create("SURF");
KeyPoint keyPoints[] = { new KeyPoint(), new KeyPoint() };
CvMat descriptors[] = new CvMat[2];
// Detect SURF features and compute descriptors for both images
for (int i = 0; i < 1; i++) {
surf.detect(images[i], null, keyPoints[i]);
// Create CvMat initialized with empty pointer, using simply `new
// CvMat()` leads to an exception.
descriptors[i] = new CvMat(null);
surfDesc.compute(images[i], keyPoints[i], descriptors[i]);
}
// Create feature matcher
BFMatcher matcher = new BFMatcher(NORM_L2, true);
DMatch matches = new DMatch();
// "match" is a keyword in Scala, to avoid conflict between a keyword
// and a method match of the BFMatcher,
// we need to enclose method name in ticks: `match`.
matcher.match(descriptors[0], descriptors[1], matches, null);
System.out.println("Matched: " + matches.capacity());
// Select only 25 best matches
DMatch bestMatches = selectBest(matches, 25);
// Draw best matches
IplImage imageMatches = cvCreateImage(new CvSize(images[0].width()
+ images[1].width(), images[0].height()), images[0].depth(), 3);
drawMatches(images[0], keyPoints[0], images[1], keyPoints[1],
bestMatches, imageMatches, CvScalar.BLUE, CvScalar.RED, null,
DrawMatchesFlags.DEFAULT);
CanvasFrame canvas = new CanvasFrame("");
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvas.showImage(imageMatches);
}
// ----------------------------------------------------------------------------------------------------------------
/** Select only the best matches from the list. Return new list. */
private static DMatch selectBest(DMatch matches, int numberToSelect) {
// Convert to Scala collection for the sake of sorting
int oldPosition = matches.position();
DMatch a[] = new DMatch[matches.capacity()];
for (int i = 0; i < a.length; i++) {
DMatch src = matches.position(i);
DMatch dest = new DMatch();
copy(src, dest);
a[i] = dest;
}
// Reset position explicitly to avoid issues from other uses of this
// position-based container.
matches.position(oldPosition);
// Sort
DMatch aSorted[] = a;
Arrays.sort(aSorted, new DistanceComparator());
// DMatch aSorted[]=sort(a);
// Create new JavaCV list
DMatch best = new DMatch(numberToSelect);
for (int i = 0; i < numberToSelect; i++) {
// Since there is no may to `put` objects into a list DMatch,
// We have to reassign all values individually, and hope that API
// will not any new ones.
copy(aSorted[i], best.position(i));
}
// Set position to 0 explicitly to avoid issues from other uses of this
// position-based container.
best.position(0);
return best;
}
private static void copy(DMatch src, DMatch dest) {
// TODO: use Pointer.copy() after JavaCV/JavaCPP 0.3 is released
// (http://code.google.com/p/javacpp/source/detail?r=51f4daa13d618c6bd6a5556ff2096d0e834638cc)
// dest.put(src)
dest.distance(src.distance());
dest.imgIdx(src.imgIdx());
dest.queryIdx(src.queryIdx());
dest.trainIdx(src.trainIdx());
}
static class DistanceComparator implements Comparator<DMatch> {
public int compare(DMatch o1, DMatch o2) {
if (o1.compare(o2))
return -1;
else
return 1;
}
};
}
Does anybody know what I might need more to make this work.. Any help appreciated
As the error clearly says that descriptor types does not match. You have to check for the condition if the descriptor types match.
A simple if statement before matcher.match would solve your problem
if (descriptors[0].type() == descriptors[1].type())
{
matcher.match(descriptors[0], descriptors[1], matches, null);
System.out.println("Matched: " + matches.capacity());
}
The CvMat was not initialized properly which was giving the error.
descriptors[i] = new CvMat(null);
Instead I put it like this which solved the problem.
descriptors[i] = CvMat.create(1, 1);
Don't know if still needed, but I found answer. In code there's problem with this loop:
for (int i = 0; i < 1; i++) {
surf.detect(images[i], null, keyPoints[i]);
// Create CvMat initialized with empty pointer, using simply `new
// CvMat()` leads to an exception.
descriptors[i] = new CvMat(null);
surfDesc.compute(images[i], keyPoints[i], descriptors[i]);
}
i is just 0, than the loop exits and you try to use object descriptors[1] which is absent.
Change it to for( int i = 0, i < 2, i++) {

Windows phone 8 gps / altitude problems

UPDATE: using the sample from here - http://code.msdn.microsoft.com/wpapps/Location-sample-f11aa4e7 and adding an altitude readout I get the same thing as my code. Poor accuracy is being off by 50ft. Going back and forth between 720 (correct) and 300 ft means something is wrong. I just can't see where...
I'm starting to make a GPS tracking app for windows phone 8 but something is going haywire. In my app, (and in the sample location app) i get some readings that are correct and others that are not. In general, the altitude jumps back and forth between ~95 and ~215 (with 215 being correct). The distance I'm getting is hugely inaccurate as well, quickly jumping to several miles while sitting at my desk or walking around outside.
I'm not sure what code to post, as it is identical to the sample code. If you think there is another relevant section i should post let me know and I'll add it.
double maxSpeed = 0.0;
double maxAlt = -9999999.0;
double minAlt = 9999999.0;
double curDistance = 0.0;
GeoCoordinate lastCoord = null;
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if ((bool)IsolatedStorageSettings.ApplicationSettings["LocationConsent"] != true)
{
// The user has opted out of Location.
return;
}
if (App.Geolocator == null)
{
// Use the app's global Geolocator variable
App.Geolocator = new Geolocator();
}
App.Geolocator.DesiredAccuracy = PositionAccuracy.High;
//App.Geolocator.MovementThreshold = 1; // The units are meters.
App.Geolocator.ReportInterval = 1000;
//App.Geolocator.DesiredAccuracyInMeters = 50;
App.Geolocator.StatusChanged += geolocator_StatusChanged;
App.Geolocator.PositionChanged += geolocator_PositionChanged;
/*
geolocator = new Geolocator();
geolocator.DesiredAccuracy = PositionAccuracy.High;
//geolocator.MovementThreshold = 1; // The units are meters.
geolocator.ReportInterval = 1000;
geolocator.StatusChanged += geolocator_StatusChanged;
geolocator.PositionChanged += geolocator_PositionChanged;
*
* */
logging = true;
startTime = DateTime.Now;
}
public static GeoCoordinate ConvertGeocoordinate(Geocoordinate geocoordinate)
{
return new GeoCoordinate
(
geocoordinate.Latitude,
geocoordinate.Longitude,
geocoordinate.Altitude ?? Double.NaN,
geocoordinate.Accuracy,
geocoordinate.AltitudeAccuracy ?? Double.NaN,
geocoordinate.Speed ?? Double.NaN,
geocoordinate.Heading ?? Double.NaN
);
}
void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
Dispatcher.BeginInvoke(() =>
{
if (lastCoord == null)
{
lastCoord = ConvertGeocoordinate(args.Position.Coordinate);
}
DateTime currentTime = DateTime.Now;
TimeSpan totalTime = currentTime - startTime;
timeValue.Text = totalTime.ToString(#"hh\:mm\:ss");
System.Diagnostics.Debug.WriteLine(args.Position.Coordinate.Altitude.ToString());
GeoCoordinate thisLocation = ConvertGeocoordinate(args.Position.Coordinate);
if (true) //units check true = standard
{
double speed = (double)thisLocation.Speed;
speed *= 2.23694; //m/s -> mph
speedValue.Text = speed.ToString("0");
double alt = (double)thisLocation.Altitude;
if (alt > maxAlt)
{
maxAlt = alt;
}
if (alt < minAlt)
{
minAlt = alt;
}
/*
double currentAlt = (maxAlt - minAlt);
currentAlt *= 3.28084; //m -> ft
* */
alt *= 3.28084;
altValue.Text = alt.ToString("0");
double distance = thisLocation.GetDistanceTo(lastCoord);
curDistance += distance;
distance = curDistance * 0.000621371; // m -> miles
distanceValue.Text = distance.ToString("0.00");
distanceUnits.Text = "(mi)";
speedUnits.Text = "(mph)";
altUnits.Text = "(ft)";
}
});
}
EDIT: I didn't mention, but the speed is perfectly fine as an fyi. the lat / long is pretty close in general to where i am as well, so I don't think it's a hardware issue.
UPDATE: When stopping in the debugger to check the value instead of just printing it, it gives this:
Altitude = An internal error has occurred while evaluating method Windows.Devices.Geolocation.Geocoordinate.get_Altitude()
I tried to search for this, but the error is nowhere to be found on the internet...
The documentation states that altitude and a few others aren't guaranteed, but it also says that the value will be null if it isn't there. I check, and it's never null. It always prints a value, either correct or ~400 ft off.
UPDATE: Sample code:
void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
System.Diagnostics.Debug.WriteLine(args.Position.Coordinate.Altitude.ToString());
if (!App.RunningInBackground)
{
Dispatcher.BeginInvoke(() =>
{
LatitudeTextBlock.Text = args.Position.Coordinate.Latitude.ToString("0.00");
LongitudeTextBlock.Text = args.Position.Coordinate.Longitude.ToString("0.00");
});
}
else
{
Microsoft.Phone.Shell.ShellToast toast = new Microsoft.Phone.Shell.ShellToast();
toast.Content = args.Position.Coordinate.Latitude.ToString("0.00");
toast.Title = "Location: ";
toast.NavigationUri = new Uri("/MainPage.xaml", UriKind.Relative);
toast.Show();
}
}
You might be seeing a different issues (too) but GPS altitudes are not very reliable. I have a few Garmin devices and they all jump about all over the place. You really need a barometer for decent altitude accuracy.
Here is a link on GPS attitude inaccuracy GPS Elevation

Clustering Algorithm for Mapping Application

I'm looking into clustering points on a map (latitude/longitude). Are there any recommendations as to a suitable algorithm that is fast and scalable?
More specifically, I have a series of latitude/longitude coordinates and a map viewport. I'm trying to cluster the points that are close together in order to remove clutter.
I already have a solution to the problem (see here), only I am wondering if there is any formal algorithm that solves the problem efficiently.
For a virtual earth application I've used the clustering described
here. It's lightning fast and easily extensible.
Google Maps Hacks has a hack, "Hack 69. Cluster Markers at High Zoom Levels", on that.
Also, see Wikipedia on clustering algorithms.
You could look at indexing all your points using a QuadTile scheme, and then based upon the scale the further down the quad-splits you go. All similarly located points will then be near each other in your index, allowing the clustering to happen efficiently.
QuadTiles are an example of Morton Codes, and there is a python example linked from that wikipedia article that may help.
I looked at various libraries and found them so complex couldn't understand a word so I decided to make my own clustering algorithm
Here goes my code in Java
static int OFFSET = 268435456;
static double RADIUS = 85445659.4471;
static double pi = 3.1444;
public static double lonToX(double lon) {
return Math.round(OFFSET + RADIUS * lon * pi / 180);
}
public static double latToY(double lat) {
return Math.round(OFFSET
- RADIUS
* Math.log((1 + Math.sin(lat * pi / 180))
/ (1 - Math.sin(lat * pi / 180))) / 2);
}
// This calculates the pixel distance between tow lat long points at a particular zoom level
public static int pixelDistance(double lat1, double lon1, double lat2,
double lon2, int zoom) {
double x1 = lonToX(lon1);
double y1 = latToY(lat1);
double x2 = lonToX(lon2);
double y2 = latToY(lat2);
return (int) (Math
.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2))) >> (21 - zoom);
}
// The main function which actually calculates the clusters
1. ArrayList of lat long points is iterated to length .
2. inner loop a copy of the same arraylist is iterated from i+1 position ie leaving the top loop's index
3. 0th element is taken as the centre of centroid and all other points are compared if their pixel distance is very less add it into cluster
4. remove all elements from top arraylist and copy arraylist which have formed cluster
5 restart the process by reinitializing the index from 0;
6 if the centroid selected has no clusters then that element is not deleted
static ArrayList<Cluster> cluster(ArrayList<Marker> markers, int zoom) {
ArrayList<Cluster> clusterList = new ArrayList<Cluster>();
ArrayList<Marker> originalListCopy = new ArrayList<Marker>();
for (Marker marker : markers) {
originalListCopy.add(marker);
}
/* Loop until all markers have been compared. */
for (int i = 0; i < originalListCopy.size();) {
/* Compare against all markers which are left. */
ArrayList<Marker> markerList = new ArrayList<Marker>();
for (int j = i + 1; j < markers.size();) {
int pixelDistance = pixelDistance(markers.get(i).getLatitude(),
markers.get(i).getLongitude(), markers.get(j)
.getLatitude(), markers.get(j).getLongitude(),
zoom);
if (pixelDistance < 40) {
markerList.add(markers.get(i));
markerList.add(markers.get(j));
markers.remove(j);
originalListCopy.remove(j);
j = i + 1;
} else {
j++;
}
}
if (markerList.size() > 0) {
Cluster cluster = new Cluster(clusterList.size(), markerList,
markerList.size() + 1, originalListCopy.get(i)
.getLatitude(), originalListCopy.get(i)
.getLongitude());
clusterList.add(cluster);
originalListCopy.remove(i);
markers.remove(i);
i = 0;
} else {
i++;
}
/* If a marker has been added to cluster, add also the one */
/* we were comparing to and remove the original from array. */
}
return clusterList;
}
Just pass in your array list here containing latitude and longitude
then to display clusters
here goes the function
#Override
public void onTaskCompleted(ArrayList<FlatDetails> flatDetailsList) {
LatLngBounds.Builder builder = new LatLngBounds.Builder();
originalListCopy = new ArrayList<FlatDetails>();
ArrayList<Marker> markersList = new ArrayList<Marker>();
for (FlatDetails detailList : flatDetailsList) {
markersList.add(new Marker(detailList.getLatitude(), detailList
.getLongitude(), detailList.getApartmentTypeString()));
originalListCopy.add(detailList);
builder.include(new LatLng(detailList.getLatitude(), detailList
.getLongitude()));
}
LatLngBounds bounds = builder.build();
int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
googleMap.moveCamera(cu);
ArrayList<Cluster> clusterList = Utils.cluster(markersList,
(int) googleMap.getCameraPosition().zoom);
// Removes all markers, overlays, and polylines from the map.
googleMap.clear();
// Zoom in, animating the camera.
googleMap.animateCamera(CameraUpdateFactory.zoomTo(previousZoomLevel),
2000, null);
CircleOptions circleOptions = new CircleOptions().center(point) //
// setcenter
.radius(3000) // set radius in meters
.fillColor(Color.TRANSPARENT) // default
.strokeColor(Color.BLUE).strokeWidth(5);
googleMap.addCircle(circleOptions);
for (Marker detail : markersList) {
if (detail.getBhkTypeString().equalsIgnoreCase("1 BHK")) {
googleMap.addMarker(new MarkerOptions()
.position(
new LatLng(detail.getLatitude(), detail
.getLongitude()))
.snippet(String.valueOf(""))
.title("Flat" + flatDetailsList.indexOf(detail))
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.bhk1)));
} else if (detail.getBhkTypeString().equalsIgnoreCase("2 BHK")) {
googleMap.addMarker(new MarkerOptions()
.position(
new LatLng(detail.getLatitude(), detail
.getLongitude()))
.snippet(String.valueOf(""))
.title("Flat" + flatDetailsList.indexOf(detail))
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.bhk_2)));
}
else if (detail.getBhkTypeString().equalsIgnoreCase("3 BHK")) {
googleMap.addMarker(new MarkerOptions()
.position(
new LatLng(detail.getLatitude(), detail
.getLongitude()))
.snippet(String.valueOf(""))
.title("Flat" + flatDetailsList.indexOf(detail))
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.bhk_3)));
} else if (detail.getBhkTypeString().equalsIgnoreCase("2.5 BHK")) {
googleMap.addMarker(new MarkerOptions()
.position(
new LatLng(detail.getLatitude(), detail
.getLongitude()))
.snippet(String.valueOf(""))
.title("Flat" + flatDetailsList.indexOf(detail))
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.bhk2)));
} else if (detail.getBhkTypeString().equalsIgnoreCase("4 BHK")) {
googleMap.addMarker(new MarkerOptions()
.position(
new LatLng(detail.getLatitude(), detail
.getLongitude()))
.snippet(String.valueOf(""))
.title("Flat" + flatDetailsList.indexOf(detail))
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.bhk_4)));
} else if (detail.getBhkTypeString().equalsIgnoreCase("5 BHK")) {
googleMap.addMarker(new MarkerOptions()
.position(
new LatLng(detail.getLatitude(), detail
.getLongitude()))
.snippet(String.valueOf(""))
.title("Flat" + flatDetailsList.indexOf(detail))
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.bhk5)));
} else if (detail.getBhkTypeString().equalsIgnoreCase("5+ BHK")) {
googleMap.addMarker(new MarkerOptions()
.position(
new LatLng(detail.getLatitude(), detail
.getLongitude()))
.snippet(String.valueOf(""))
.title("Flat" + flatDetailsList.indexOf(detail))
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.bhk_5)));
}
else if (detail.getBhkTypeString().equalsIgnoreCase("2 BHK")) {
googleMap.addMarker(new MarkerOptions()
.position(
new LatLng(detail.getLatitude(), detail
.getLongitude()))
.snippet(String.valueOf(""))
.title("Flat" + flatDetailsList.indexOf(detail))
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.bhk_2)));
}
}
for (Cluster cluster : clusterList) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
options.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.cluster_marker, options);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(getResources().getColor(R.color.white));
paint.setTextSize(30);
canvas.drawText(String.valueOf(cluster.getMarkerList().size()), 10,
40, paint);
googleMap.addMarker(new MarkerOptions()
.position(
new LatLng(cluster.getClusterLatitude(), cluster
.getClusterLongitude()))
.snippet(String.valueOf(cluster.getMarkerList().size()))
.title("Cluster")
.icon(BitmapDescriptorFactory.fromBitmap(bitmap)));
}
}
ANY QUESTIONS OR DOUBTS PLEASE ASK WILL CLEAR THEM ALL ...........THANKS

Resources