I know i have asked a similar question like this before about saving the custom added markers to the map so when exiting the app and returning to the map the markers should still be there, but am training myself and find it hard to understand a few things
Here is my code for SavePreferences()
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("listSize", markerList.size());
for(int i = 0; i <markerList.size(); i++){
editor.putFloat("lat"+i, (float) markerList.get(i).getPosition().latitude);
editor.putFloat("long"+i, (float) markerList.get(i).getPosition().longitude);
editor.putString("title"+i, markerList.get(i).getTitle());
}
editor.commit();
}
And here is the LoadPreferences()
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
int size = sharedPreferences.getInt("listSize", 0);
for(int i = 0; i < size; i++){
double lat = (double) sharedPreferences.getFloat("lat"+i,0);
double longit = (double) sharedPreferences.getFloat("long"+i,0);
String title = sharedPreferences.getString("title"+i,"NULL");
markerList.add(googleMap.addMarker(new MarkerOptions().position(new LatLng(lat, longit)).title(title)));
}
}
}
and then i have this:
private List<Marker> markerList;
public MapActivity(){
if(markerList == null){
markerList = new ArrayList<Marker>();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_googlemaps);
So all of the above i understand, but what i don't understand is how do i tell the app to save the onMapLongClick marker to the above code, This is my onMapLongClick code:
#Override
public void onMapLongClick(LatLng point) {
thePoint=point;
Marker marker = googleMap.addMarker(new MarkerOptions()
.position(thePoint).icon(BitmapDescriptorFactory
.fromResource(R.drawable.ic_marker)));
markerId = marker.getId(); //this is for the image taken by the camera intent to display full size image for marker.
So basically, how do I save onMapLongClick to shared preferences?
EDIT
This code I have here goes by the onCreate method?
LoadPreferences();
Intent intent = getIntent();
Bundle data = intent.getExtras();
String label = data.getString("title");
int newLatitude = data.getInt("firstPoint");
int newLongitude = data.getInt("secondPoint");
Could some one please help me?
Related
I built an android app with a map and I added some custom markers, let me show you.
I want to rotate that picture to points to an another point. I saved the coordinations for the other point too.
This is what is saved by now in the database about this marker.
Latitude and Longitude are the actual marker's position, and del_lat, del_lng is the delivery address which I want to point to. How can I rotate the image in that position?
Here's my ClusterManagerRenderer
public class ClusterManagerRenderer extends DefaultClusterRenderer<FinalMarkerCluster> {
private final IconGenerator iconGenerator;
private ImageView imageView;
private final int markerWidth;
private final int markerHeight;
public ClusterManagerRenderer(Context context, GoogleMap map, ClusterManager<FinalMarkerCluster> clusterManager) {
super(context, map, clusterManager);
iconGenerator = new IconGenerator(context.getApplicationContext());
imageView = new ImageView(context.getApplicationContext());
markerWidth = (int) context.getResources().getDimension(R.dimen.custom_marker_image);
markerHeight = (int) context.getResources().getDimension(R.dimen.custom_marker_image);
imageView.setLayoutParams(new ViewGroup.LayoutParams(markerWidth,markerHeight));
int padding = (int) context.getResources().getDimension(R.dimen.custom_marker_padding);
imageView.setPadding(padding, padding,padding,padding);
iconGenerator.setContentView(imageView);
}
#Override
protected void onBeforeClusterItemRendered(FinalMarkerCluster item, MarkerOptions markerOptions) {
imageView.setImageResource(item.getIconPicture());
Bitmap icon = iconGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)).title(item.getTitle());
}
#Override
protected boolean shouldRenderAsCluster(Cluster<FinalMarkerCluster> cluster) {
return false;
}
}
And here I'm creating the Marker
private void setRendering(List<MarkerCluster> markerClusters) {
for(int i = 0 ;i < markerClusters.size() ;i++) {
LatLng latLng = new LatLng(markerClusters.get(i).getLatitude(), markerClusters.get(i).getLongitude());
String title = markerClusters.get(i).getTitle();
String snippet = markerClusters.get(i).getSnippet();
LatLng delLatLng = new LatLng(markerClusters.get(i).getDel_lat(), markerClusters.get(i).getDel_lng());
int pic = markerClusters.get(i).getIconPicture();
String offerid = markerClusters.get(i).getOfferid();
FinalMarkerCluster finalMarkerCluster = new FinalMarkerCluster(
latLng,
title,
snippet,
pic,
offerid,
delLatLng
);
finalMarkerClusters.add(finalMarkerCluster);
}
if(mGoogleMap != null) {
if(mClusterManager == null) {
mClusterManager = new ClusterManager<FinalMarkerCluster>(getApplicationContext(),mGoogleMap);
}
if(mClusterManagerRender == null) {
mClusterManagerRender = new ClusterManagerRenderer(getApplicationContext(),mGoogleMap,mClusterManager);
mClusterManager.setRenderer(mClusterManagerRender);
}
for(int j = 0; j< finalMarkerClusters.size();j++) {
mClusterManager.addItem(finalMarkerClusters.get(j));
}
mClusterManager.cluster();
}
}
And here's the MarkerCluster object
public class FinalMarkerCluster implements ClusterItem {
private LatLng position;
private String title;
private String snippet;
private int iconPicture;
private String offerId;
private LatLng deliveryPosition;
public FinalMarkerCluster(LatLng position, String title, String snippet, int iconPicture, String offerId, LatLng deliveryPosition) {
this.position = position;
this.title = title;
this.snippet = snippet;
this.iconPicture = iconPicture;
this.offerId = offerId;
this.deliveryPosition = deliveryPosition;
}
WITH GETTERS AND SETTERS
I just want to rotate the image in that point, Thank you in advance!
This doesn't address clustering but for simple marker rotation two things come in handy:
To determine bearing from point A (the lower-right marker on sample screen) to point B use SphericalUtil.computeHeading:
// add two markers
LatLng m1 = new LatLng(40.763807, -80.362280);
LatLng m2 = new LatLng(40.821666, -80.636242);
MarkerOptions m1o = new MarkerOptions().position(m1).title("m1").flat(true);
MarkerOptions m2o = new MarkerOptions().position(m2).title("m2").flat(true);
double hdg = SphericalUtil.computeHeading(m1,m2);
And to rotate the first marker (A, lower-right) in the direction of the second marker apply the bearing to marker to rotate:
m1o.rotation((float)hdg);
And add markers
mMap.addMarker(m1o);
mMap.addMarker(m2o);
Note the use of flat which maintains north-alignment on screen rotation. If that is not desired then remove the flat for the non-rotated- markers.
Note also the rotation is about the anchor point which may need further consideration.
In this image the screen has been rotated so "screen-up" is ~NNW for demo purposes.
i use google maps with get (user) device location (GPS Location) in my android app, and insert into database (SQLite) latitude and longitude and adress !
now i want displayed multiple location with LatLng read from database ... no problem in create marker, but in marker info (country, city ...) only show last inserted location for all markers !
this my code :
private void displayMultiplePoint() {
if (LOCATION_TABLE.size() > 0) {
for (int i = 0; LOCATION_TABLE.size() > i; i++) {
int id = LOCATION_TABLE.get(i).getId();
lat = LOCATION_TABLE.get(i).getLatitude();
lng = LOCATION_TABLE.get(i).getLongitude();
place = LOCATION_TABLE.get(i).getPlace();
rate = LOCATION_TABLE.get(i).getRate();
drawMarker(new LatLng(lat, lng), "city", place, rate);
displayToast(id + "" + place);
}
}
}
private void drawMarker(final LatLng point, final String city, final String place, final float rate) {
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker arg0) {
return null;
}
#Override
public View getInfoContents(Marker arg0) {
View v = null;
try {
v = getLayoutInflater().inflate(R.layout.custom_info_contents, null);
ImageView map_image = (ImageView) v.findViewById(R.id.maps_image);
map_image.setImageResource(R.drawable.runhd);
TextView city_txt = (TextView) v.findViewById(R.id.maps_city);
city_txt.setText(city);
TextView place_txt = (TextView) v.findViewById(R.id.maps_place);
place_txt.setText(place);
RatingBar rate_bar = (RatingBar) v.findViewById(R.id.exercise_display_rate);
rate_bar.setRating(rate);
} catch (Exception ev) {
System.out.print(ev.getMessage());
}
return v;
}
});
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(point);
mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(point, 6));
}
i show toast form rowId from lcation table in databse, and displaled 3 row id : 1, 2, 3 but in marker info show last id (id no : 3)
this my fragment :
thank's
I have many solution for your case But at first :
Your fall with setInfoWindowAdapter method it's just invoked one time, So after you iterated your database items and passing info through drawMarker it's just shown the last modified (saved) data from the variables, So i suggest to move it in your for loop (I know it's not a perfect solution) :
for (int i = 0; LOCATION_TABLE.size() > i; i++) {
int id = LOCATION_TABLE.get(i).getId();
lat = LOCATION_TABLE.get(i).getLatitude();
lng = LOCATION_TABLE.get(i).getLongitude();
place = LOCATION_TABLE.get(i).getPlace();
rate = LOCATION_TABLE.get(i).getRate();
drawMarker(new LatLng(lat, lng), "city", place, rate);
displayToast(id + "" + place);
..........
#Override
public View getInfoContents(Marker arg0) {
View v = null;
try {
v = getLayoutInflater().inflate(R.layout.custom_info_contents, null);
ImageView map_image = (ImageView) v.findViewById(R.id.maps_image);
map_image.setImageResource(R.drawable.runhd);
TextView city_txt = (TextView) v.findViewById(R.id.maps_city);
city_txt.setText("city");
TextView place_txt = (TextView) v.findViewById(R.id.maps_place);
place_txt.setText(place);
RatingBar rate_bar = (RatingBar) v.findViewById(R.id.exercise_display_rate);
rate_bar.setRating(rate);
} catch (Exception ev) {
System.out.print(ev.getMessage());
}
return v;
......
}
2nd Solution Using Cursor through your database and use it anywhere (This is will be awesome).
3rd Using Clustering Algorithm in google_maps-utils-example.
The info window is being shown for only last marker because setInfoWindowAdapter() sets info window for the entire map. Inside setInfoWindowAdapter() you need to associate marker argument with corresponding data.
You need to maintain a marker to data map.
Map<Marker, Place> markerToPlaceMap = new HashMap<>();
where, Place is a class to hold city, place, and rating.
class Place {
public String city, place;
public float rating;
}
Note: Please change members to private and implement getters and setters as per your suitability.
Next, Your drawMarker() will change as follows. It needs to add the marker and it's related place to markerToPlace map.
private void drawMarker(final LatLng point, final String city, final String place, final float rate) {
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(point);
Marker marker = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(point, 6));
markerToPlaceMap.put(marker, new Place(city, place, rating));
}
Finally, you will override GoogleMap.setInfoWindowAdapter() and access Place related to a marker for setting corresponding info contents.
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
View v = null;
try {
v = getLayoutInflater().inflate(R.layout.custom_info_contents, null);
ImageView map_image = (ImageView) v.findViewById(R.id.maps_image);
map_image.setImageResource(R.drawable.runhd);
TextView city_txt = (TextView) v.findViewById(R.id.maps_city);
city_txt.setText(markerToPlace.get(marker).city); // <- Check how corresponding place for a marker is fetched and used
TextView place_txt = (TextView) v.findViewById(R.id.maps_place);
place_txt.setText(markerToPlace.get(marker).place);
RatingBar rate_bar = (RatingBar) v.findViewById(R.id.exercise_display_rate);
rate_bar.setRating(markerToPlace.get(marker).rate);
} catch (Exception ev) {
System.out.print(ev.getMessage());
}
return v;
}
});
i Use Cursor through your database and get data rows (and show in Toast)
but
my code change to this :
private void displayMultiplePoint() {
Cursor cursor = DB_HELPER.LOCATION_MARKERS();
if (cursor.moveToFirst()) {
for (int i = 0; cursor.getCount() > i; i++) {
int id = cursor.getInt(cursor.getColumnIndex("id"));
double lat = cursor.getDouble(cursor.getColumnIndex("latitude"));
double lng = cursor.getDouble(cursor.getColumnIndex("longitude"));
String place = cursor.getString(cursor.getColumnIndex("place"));
float rate = cursor.getFloat(cursor.getColumnIndex("rate"));
displayToast(id + ", " + place + rate);
cursor.moveToNext();
drawMarker(new LatLng(lat, lng));
}
cursor.close();
}
}
i get arg0.getId form : (m0, m1, m2 ...)
public View getInfoContents(Marker arg0)
(is unique for each marker) then select data by id where id = arg0
My full code
https://gist.github.com/anonymous/6dd0f33270cc4f46149e
In line 110~131 I want to change the location, it does work, the mapview will change
private class MapClickedListener implements OnClickListener {
#Override
public void onClick (View v) {
String lng = "121.558561";
lng = edt_lng.getText().toString().trim();
String lat = "25.031005";
lat = edt_lat.getText().toString().trim();
if(lng.equals("")||lat.equals("")){
Toast.makeText(getApplicationContext(), "input again!", Toast.LENGTH_LONG).show();
location = locManager.getLastKnownLocation(bestProvider);
updateToNewLocation(location);
}else{
Location location = new Location(LocationManager.NETWORK_PROVIDER);
location.setLongitude(Double.parseDouble(lng));
location.setLatitude(Double.parseDouble(lat));
updateToNewLocation(location);
}
}
}
On line 133~148, I want to know distance between location and a point I set
private Button.OnClickListener EQ = new Button.OnClickListener(){
#Override
public void onClick (View v) {
eqlocation.setLongitude(120.82);
eqlocation.setLatitude(23.85);
location = locManager.getLastKnownLocation(bestProvider);
float[] result = new float[5];
Location.distanceBetween(location.getLatitude(), location.getLongitude(), eqlocation.getLatitude(), eqlocation.getLongitude(), result);
BigDecimal bd = new BigDecimal(result[0]);
BigDecimal rounded = bd.setScale(2, RoundingMode.HALF_UP);
double dis = rounded.doubleValue();
String dist = String.valueOf(dis/1000);
Toast.makeText(getApplicationContext(), "distance: " + dist + "km", Toast.LENGTH_LONG).show();
}
};
But the result is wrong when I change the location by line 110~131's code.
What should I do to get the right result?
have you tried distanceTo() and checked if you get any better results?, I ususally use distanceTo() with good results.
I am making android application to get nearby locations, I display the locations on the map, and if any marker is pressed, another activity will be opened, the second activity shows the info about the place, I want to display the distance between my current location and the marker. I passed the longitude and latitude from the first activity to the details activity; like this :
public void onInfoWindowClick(Marker arg0) {
Intent intent = new Intent(getBaseContext(), PlaceDetailsActivity.class);
String reference = mMarkerPlaceLink.get(arg0.getId());
intent.putExtra("reference", reference);
intent.putExtra("mLatitude", mLatitude);
intent.putExtra("mLongitude", mLongitude);
startActivity(intent);
}
in the placeDetailsActivity :
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_place_details);
Intent i=getIntent();
c_lat=i.getStringExtra("mLatitude");
c_lng=i.getStringExtra("mLongitude");
double d_lat=Double.parseDouble(lat);
double d_lng=Double.parseDouble(lng);
double c_lat1 =Double.parseDouble(c_lat);
double c_lng1=Double.parseDouble(c_lng);
float[] results = new float[1];
Location.distanceBetween(c_lat1, c_lng1, d_lat, d_lng, results);
d=results[0];
I get d_lat and d_lng from :
protected void onPostExecute(HashMap<String,String> hPlaceDetails){
String name = hPlaceDetails.get("name");
String icon = hPlaceDetails.get("icon");
String vicinity = hPlaceDetails.get("vicinity");
lat = hPlaceDetails.get("lat");
lng = hPlaceDetails.get("lng");
String formatted_address = hPlaceDetails.get("formatted_address");
String formatted_phone = hPlaceDetails.get("formatted_phone");
String website = hPlaceDetails.get("website");
String rating = hPlaceDetails.get("rating");
String international_phone_number = hPlaceDetails.get("international_phone_number");
String url = hPlaceDetails.get("url");
when I test my application, it crashes!!
I have a listview with choice mode, and it working. I want to save that checked item to shared preference, then use it in another activity. But, my SharedPreferences doesn'nt save my string correct, and save another file call DATA_Preferences that i never call in my code.
The result is my Next activity get wrong value..
Here is my code that i use to save my string and call it use by another activity:
public void onClick(View v) {
SparseBooleanArray checked = listView.getCheckedItemPositions();
ArrayList<DBLokasi> selectedItems = new ArrayList<DBLokasi>();
// Item position in adapter
SharedPreferences prefs = getSharedPreferences("DATA_COOR", Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = prefs.edit();
for (int i = 0; i < checked.size(); i++) {
int position = checked.keyAt(i);
// Add slected if truee
if (checked.valueAt(i))
selectedItems.add(adapter.getItem(position));
prefsEditor.putFloat(POINT_LATITUDE_KEY + i, Float.parseFloat(values.get(position).getLat()));
prefsEditor.putFloat(POINT_LONGITUDE_KEY + i, Float.parseFloat(values.get(position).getLng()));
}
prefsEditor.commit();
String[] outputStrArr = new String[selectedItems.size()];
for (int i = 0; i < selectedItems.size(); i++) {
outputStrArr[i] = String.valueOf(selectedItems.get(i));
}
Bundle b = new Bundle();
Location location = new Location("POINT_LOCATION");
for (int i = 0; i < checked.size(); i++) {
location.setLatitude(prefs.getFloat(POINT_LATITUDE_KEY + i, 0));
location.setLongitude(prefs.getFloat(POINT_LONGITUDE_KEY + i, 0));
double latitude = prefs.getFloat(POINT_LATITUDE_KEY + i, 0);
double longitude = prefs.getFloat(POINT_LONGITUDE_KEY + i, 0);
prefsEditor.commit();
b.putDouble("Latitude" + i, latitude );
b.putDouble("Longitude" + i, longitude);
}
int banyakPilih = checked.size();
b.putInt("banyakPilih", banyakPilih);
Intent intent = new Intent(getApplicationContext(),
HasilPilihanActivity.class);
// Create a bundle object
b.putStringArray("selectedItems", outputStrArr);
// Add the bundle to the intent.
intent.putExtras(b);
// start the ResultActivity
startActivity(intent);
}
I save my Prefernces in DATA_COOR.xml file name, it save my string, but i got another file that save my preference with file name DATA_Preferences in my Explorer. Some body can give me solution? Thanks before..
Define private SharedPreferences mediaPrefs = null;
put this on your constructor mediaPrefs = this.getSharedPreferences("Testing", 1);
put below method to the source:
public void storeStateString(String prefsKeys, Float prefsValue) {
SharedPreferences.Editor prefEditor = mediaPrefs.edit();
prefEditor.putFloat(prefsKeys, prefsValue);
prefEditor.commit();
}
Use this method to store the state like:
storeStateString("POINT_LATITUDE_KEY"+i,Float.parseFloat(values.get(position).getLat()));
and now you can get this preference through:
Float finalValue = mediaPrefs.getFloat("POINT_LATITUDE_KEY1","2.0l");
where 2.0l is defalut value if mediaPrefs is null;
Let me know if any issues regarding that.