I have a text file speedVan.txt in my assets folder in android studio which stores coordinates, However when I run it the markers do not appear on the map. My code is below, thank you.
This is the content of the text file, there are no spaces between the text lines:
52.2651 -9.7112 52.2791 -9.7024
52.2800 -9.7675 52.2746 -9.8096
52.1407 -10.1748 52.1296 -10.2493
52.0724 -9.5753 52.1005 -9.6231
52.1021 -9.6276 52.1065 -9.6425
52.0812 -9.2470 52.0542 -9.3850
52.1134 -9.5169 52.1437 -9.5543
52.4096 -9.5167 52.4208 -9.5078
52.4428 -9.4105 52.4491 -9.4474
This is my activity:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("speedVan.txt")));
String line;
//Log.e("Reader Stuff",reader.readLine());
while ((line = reader.readLine()) != null) {
Log.e("code",line);
String[] ar1 = line.split(" ");
double startLat = Double.parseDouble(ar1[0]);
double startLong = Double.parseDouble(ar1[1]);
double endLat = Double.parseDouble(ar1[2]);
double endLong = Double.parseDouble(ar1[3]);
LatLng start = new LatLng(startLat, startLong);
LatLng end = new LatLng(endLat, endLong);
mMap.addMarker(new MarkerOptions().position(start).title(""));
mMap.addMarker(new MarkerOptions().position(end).title(""));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(start,14));
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Change SupportMapFragment to MapFragment. Something like this
MapFragment mapFragment = (MapFragment) getFragmentManager() .findFragmentById(R.id.map);
Please remove the ;; that you have used and put a single ;
And instead of:
int startLat = Integer.parseInt(ar1[0]);
int startLong = Integer.parseInt(ar1[1]);;
int endLat = Integer.parseInt(ar1[2]);;
int endLong = Integer.parseInt(ar1[3]);;
Please put:
double startLat = Double.parseDouble(ar1[0]);
double startLong = Double.parseDouble(ar1[1]);
double endLat = Double.parseDouble(ar1[2]);
double endLong = Double.parseDouble(ar1[3]);
We are using double because the constructor of LatLng takes two double arguements.
And please note that because of your first statement Log.e("Reader Stuff",reader.readLine()); the first line of the text file will not be parsed because a line is being read and logged and the next time you call reader.readLine(), you will get the second line.
Edit:
Maybe you are not able to see the markers because you haven't moved the map camera. To move the camera to any marker:
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(start,14));
start is the LatLng and 14 is the Zoom level.
Related
Can you guys help me out.
My code shows same document when I click a marker.
I think there problem in my for loop.
I am creating a list of parking spots and when clicked i would show the details of Parking spots in modal bottom sheet
here is my code.
public class ParkingSpace extends AppCompatActivity implements OnMapReadyCallback{
private GoogleMap mMap;
Parking parking;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference parkingRef = db.collection("Parking Lots");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parking_space);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.mapView);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(#NonNull GoogleMap googleMap) {
mMap = googleMap;
LatLng sydney = new LatLng(16.4023,120.5960);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney,14));
parkingRef.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (QueryDocumentSnapshot documentSnapshot: queryDocumentSnapshots){
parking = documentSnapshot.toObject(Parking.class);
parking.setDocumentId(documentSnapshot.getId());
String lat = parking.getLatitude();
String lon = parking.getLongitude();
String title = parking.getparkingName();
String owner = parking.getName();
String documentId= parking.getDocumentId();
double latd = Double.parseDouble(lat);
double lond = Double.parseDouble(lon);
LatLng location = new LatLng(latd,lond);
mMap.addMarker(new MarkerOptions().snippet("Owner: " +owner).position(location).title(title));
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(#NonNull Marker marker) {
parking = documentSnapshot.toObject(Parking.class);
String path = documentSnapshot.getReference().getPath();
Toast.makeText(ParkingSpace.this, "Document ID:" +documentId, Toast.LENGTH_SHORT).show();
BottomSheet bottomSheet = new BottomSheet();
Bundle bundle = new Bundle();
bundle.putString("lat",lat);
bottomSheet.setArguments(bundle);
bottomSheet.show(getSupportFragmentManager(),"bottomsheet");
return false;
}
});
}
}
});
}
}
You are effectively using the same Parking instance ( parking ) for all markers because each iteration of the loop sets it to the value of the next query result. So by the time the marker click event occurs the parking instance is the last one processed (for all markers).
An alternate approach is to associate a parking instance with the newly added marker and get that instance in the onMarkerClick.
Something like this:
// ... all your code up to this line remains same ....
// Here the `addMarker` method returns the newly added Marker to which we can associate
// any object needed - so associate the "parking" instance...
Marker m = mMap.addMarker(new MarkerOptions().snippet("Owner: " +owner).position(location).title(title));
m.setTag(parking);
Then in your onMarkerClick replace:
parking = documentSnapshot.toObject(Parking.class);
with
// Use the associated Parking object (saved as a tag) to get needed info
Parking p = (Parking) marker.getTag();
if (p == null) {
// some other marker on map
return;
}
String documentId = p.getDocumentId();
String lat = p.getLatitude();
// and any other data I may have missed should come from "p".
Getting trouble of plotting my markers on maps , im able to fetch my Latitude and Longitude of my users from firebase and store it to my arraylist , my problem is how im i able to set my arraylist globally? here is my code .
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private GoogleMap googleMap;
private MarkerOptions options = new MarkerOptions();
private ArrayList<LatLng> latlngs = new ArrayList<>();
private ArrayList<String> Names = new ArrayList<>();
String Lat ,Lon,Names1;
double latitude , longitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Positions");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot chidSnap : dataSnapshot.getChildren()) {
Lat = String.valueOf(chidSnap.child("Latitude").getValue());
Lon = String.valueOf(chidSnap.child("Longitude").getValue());
Names1 = String.valueOf(chidSnap.getKey());
latitude= Double.parseDouble(Lat);
longitude= Double.parseDouble(Lon);
latlngs.add(new LatLng(latitude, longitude));
Names.add(Names1);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// System.out.println(Names);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
for (LatLng point : latlngs) {
options.position(point);
options.title("Users");
options.snippet("someDesc");
googleMap.addMarker(options);
}
}
}
I have no idea what is wrong with this thing , somehow my map is showing no marker and my list "latlngs" is showing "0.0,0.0"
I have no idea how to set my latlngs globally since it is inside the code of fetching the datas from firebase.
Query to Firebase is an asynchronous process. So, probably your onDataChange is executed after onMapReady. Try below:
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot chidSnap : dataSnapshot.getChildren()) {
....
}
if(mMap != null) {
for (LatLng point : latlngs) {
options.position(point);
options.title("Users");
options.snippet("someDesc");
mMap.addMarker(options);
}
}
}
Or call mapFragment.getMapAsync(MapsActivity.this); from inside onDataChange
Im working with google maps project now and im fetching my data from firebase ,im able to plot multiple markers with the help of all the kind developers in this site, one thing is when plotting those markers my markers title are the same , the "same" means that all my markers have the same Title please see my image
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private GoogleMap googleMap;
private MarkerOptions options = new MarkerOptions();
private ArrayList<LatLng> latlngs = new ArrayList<>();
private ArrayList<String> Names = new ArrayList<>();
String Lat ,Lon,Names1;
double latitude , longitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Positions");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot chidSnap : dataSnapshot.getChildren()) {
// System.out.println(chidSnap.getKey()); //displays the key for the node
// System.out.println(chidSnap.child("Latitude").getValue());
// System.out.println( chidSnap.child("Longitude").getValue()); //gives the value for given keyname
//some latitude and logitude value
// System.out.println(latlngs); //gives the value for given keyname
Lat = String.valueOf(chidSnap.child("Latitude").getValue());
Lon = String.valueOf(chidSnap.child("Longitude").getValue());
Names1 = String.valueOf(chidSnap.getKey());
latitude= Double.parseDouble(Lat);
longitude= Double.parseDouble(Lon);
latlngs.add(new LatLng(latitude, longitude));
Names.add(Names1);
}
if(mMap != null) {
for (LatLng point : latlngs) {
options.position(point);
options.title(String.valueOf(Names));
options.snippet("someDesc");
mMap.addMarker(options);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// System.out.println(Names);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
for (LatLng point : latlngs) {
options.position(point);
options.title(String.valueOf(Names));
options.snippet("someDesc");
googleMap.addMarker(options);
}
}
}
My MapsActivity above. What im expecting is one marker should be named to Lex B05 , and the other user should be amanda thank in advance for your help!..
That because you are passing same arrayList Names to all marker, Try below code while adding marker
for (int i=0;i< latlngs.size();i++) {
LatLng point=latlngs.get(i);
options.position(point);
options.title(Names.get(i));
options.snippet("someDesc");
mMap.addMarker(options);
}
Hope this will help!!
I'm creating a map of some cities in Sweden and would like some functionality added to it. I would like to display the city name and the distance in kilometers of the city closest to the center of the map, where I have placed a crosshairs through an ImageView in my layout XML file. Is there a proper way of accomplishing this?
This is the code I'm currently using to create my map and place my city markers:
public class MyMap extends Activity implements OnMapReadyCallback
{
public final Context context = this;
private String fileString = "";
private String coordsFileName = "coords";
private GoogleMap myMap = null;
private LatLngBounds bounds = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_map);
// Gets the map fragment from the xml file
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
// Load strings from file
fileString = ReadFromFile(coordsFileName);
}
#Override
public void onMapReady(GoogleMap map)
{
myMap = map;
List<Marker> markers = new ArrayList<Marker>();
String[] locations = fileString.split(";");
for (String location : locations)
{
try
{
String[] cityLatLng = location.split(":|,");
String cityName = cityLatLng[0];
Double lat = Double.parseDouble(cityLatLng[1]);
Double lng = Double.parseDouble(cityLatLng[2]);
LatLng cityPos = new LatLng(lat, lng);
// Create marker
Marker marker = myMap.addMarker(new MarkerOptions()
.position(cityPos)
.title(cityName));
// Add new marker to array of markers
markers.add(marker);
}
catch(Exception e)
{
System.out.println("Error 3: " + e.getMessage());
}
}
// Move the camera to show all markers
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : markers)
{
builder.include(marker.getPosition());
}
bounds = builder.build();
myMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback()
{
#Override
public void onMapLoaded()
{
// Pixel offset from edge of map
int padding = 30;
// Move the camera
myMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, padding));
}
});
}
}
And this is my layout xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.MapFragment"/>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_locate"
android:layout_gravity="center_vertical"
android:layout_centerInParent="true"
android:contentDescription="#string/crosshairs"/>
</RelativeLayout>
One of the probable solution is to first find the center coordinates of the map by using
map.getCenter();
This will return the latlang object. Then you can compare the distance of the center with each of the position markers (that represents cities) using the Google Distance Matrix API, find out the min by using a minDist() method and return the coordinates of marker at minimum distance (which is the name of the city)
Hope that would help!!!
I actually managed to solve it using Location objects and GoogleMap.setOnCameraChangeListener() to recalculate each time the user navigates the map. Below is the code I managed to put together to achieve this.
myMap.setOnCameraChangeListener(new OnCameraChangeListener()
{
#SuppressLint("DefaultLocale") #Override
public void onCameraChange(CameraPosition position)
{
// Get the latlng of the map center
LatLng mapCenter = myMap.getCameraPosition().target;
// Create a centerlocation based on the map's latlng
Location centerLocation = new Location("CenterLocation");
centerLocation.setLatitude(mapCenter.latitude);
centerLocation.setLongitude(mapCenter.longitude);
// Location for storage of the city closest to the map
Location closestCity = new Location("ClosestCity");
float distance = 0;
for (City city : cities)
{
Location cityLocation = new Location(city.getCityName());
cityLocation.setLatitude(city.getLatitude());
cityLocation.setLongitude(city.getLongitude());
float currentCityDistance = cityLocation.distanceTo(centerLocation);
if(distance == 0)
{
distance = currentCityDistance;
closestCity = cityLocation;
}
if(currentCityDistance < distance)
{
distance = currentCityDistance;
closestCity = cityLocation;
}
}
// Convert from meters to kilometers
float distanceKm = distance / 1000;
String kilometersString = String.format("%.2f", distanceKm);
// Present a toast with information
Toast.makeText(getBaseContext(), "Distance to " + closestCity.getProvider() + ": " + kilometersString + " km", Toast.LENGTH_SHORT).show();
}
});
I'm having some issues using FragmentActivity and SupportMapFragment. The map's zoom is all wonky.
Here's the code:
public class GoogleMapActivity extends FragmentActivity{
Double longitude, latitude;
static LatLng koordinate;
GoogleMap supportMap;
String title, address;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_googlemaps);
SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
supportMap = fm.getMap();
longitude = 13.597651720046997;
latitude = 45.22456639103469;
title = "Turistička zajednica Općine Vrsar";
address = "ul. Rade Končara 46";
koordinate = new LatLng(longitude, latitude);
Marker marker = supportMap.addMarker(new MarkerOptions().position(koordinate).title(title).snippet(address)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_star)));
//supportMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
supportMap.moveCamera(CameraUpdateFactory.newLatLngZoom(koordinate, 15));
supportMap.animateCamera(CameraUpdateFactory.zoomTo(12), 2000, null);
}}
For some reason, I get following thing in google maps, which is not zoomed enough:
http://imageshack.us/f/812/3yl.png/
When I click on the zoom, the map goes into this state:
http://imageshack.us/f/825/k8np.png/
I need the maps to zoom enough so that the street names are shown.This works just fine in my previous application, but I used regular MapFragment there. For this app, I need SupportMapFragment. Maybe that's causing this issue?
Zoom in the Google Map
googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
OR
LatLng latLng = new LatLng(latitude, longitude);
// Showing the current location in Google Map
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
the maximum zoom allowed is 17 i guess.
i hope this must work...