When I click somewhere on map, app draw polyline between current location and destination (click). I want that destination marker is clicking by himself all the time (every few seconds), so on user movement new polylines are drawing (updating the last one).
I tried with handler and bunch of the things and didn't find solution.
Any answer would be highly appreciated.
private ArrayList<LatLng> mClickedPoints;
/** Setting onclick listener for the map */
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
/**
* Clearing map if user clicks on map more then one time.
* Reseting View widgets and arrays, adding points of interests
*/
if (mClickedPoints.size() > 1) {
mMap.clear();
mClickedPoints.clear();
mClickedPoints = new ArrayList<>();
}
/** Adding current location to the ArrayList */
mClickedPoints.add(start);
Log.i("current location", start.toString());
MarkerOptions options = new MarkerOptions();
options.position(start);
/** Destination click */
mClickedPoints.add(point);
/** Setting the position of the marker */
options.position(point);
/** Checks if start and end locations are captured */
if (mClickedPoints.size() >= 2) {
orig = mClickedPoints.get(0);
dest = mClickedPoints.get(1);
}
mMap.addMarker(options);
request_directions_and_get_response();
}
});
onLocationChanged() override:
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
/** Setting current location marker */
start = new LatLng(location.getLatitude(),location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(start);
markerOptions.title("Current Location");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
mCurrLocationMarker = mMap.addMarker(markerOptions);
}
In order to use the clicked points ArrayList as you have it now, you'll need to remove the previous origin, then add the current origin to the start of the ArrayList, and then get re-calculated directions based on the new current location.
Something like this:
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
/** Setting current location marker */
start = new LatLng(location.getLatitude(),location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(start);
markerOptions.title("Current Location");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//If there is a previous route drawn:
if (mClickedPoints.size() >= 2) {
//remove the old origin:
mClickedPoints.remove(0);
//add the new one at the 0th position:
mClickedPoints.add(0, start);
//set orig and dest for directions:
orig = mClickedPoints.get(0);
dest = mClickedPoints.get(1);
//get updated directions:
request_directions_and_get_response();
}
}
Related
I know there are similar questions around, but I was not able to find a solid answer, here is my question: Is there any way I can make Markers without a Google Map reference to be stored in an ArrayList (or any other storage), and then just simply add them to my map?
Background:
I have an app, that at the moment has around 3,500 markers. Each marker also has a data associated with it (boolean array storing data for each marker which is used to make them visible/invisible based on users interactions). At the moment, I get these marker's location and data using a class that extends AsyncTask. After the loading is finished, then I create my markers using this data on the main Thread. However, this takes some time, and it freezes the UI while the markers are being created and added to the map. I want to do this somehow in the background.
What I have tried so far:
I created another class that extends AsyncTask passing in my LocationData and my Google Map object. But I get an error when I try to make the markers in my Async class. I get a Runtime error saying I need to do this on the UI thread.
java.lang.RuntimeException: An error occurred while executing
doInBackground()
Caused by: com.google.maps.api.android.lib6.common.apiexception.c: Not
on the main thread
I have also thought about just making MarkerOptions object in the background and then use that to create markers in the main thread; however, I cannot add a tag to the MarkerOption, it needs to be added to the marker. In that case, I need to go through all of them again in the main thread just to add the tag, which I feel like is not saving me too much time/resources.
Any suggestion/help would be appreciated on how to create these markers and attach their tags without blocking the UI?
Thanks in advance.
Here are some of my code:
LocationLoader class
(BinLocation is my Location class, each object has boolean variables (marker tags) and LatLng)
public class LocationLoader extends AsyncTaskLoader> {
private String TAG = LocationLoader.class.getName();
String[] fileNameArray;
//ArrayLists
private ArrayList<BinLocation> mBinLocationArrayList = new ArrayList<>();
public LocationLoader(Context context, String... fileNames){
super(context);
//get the file names that was passed in
fileNameArray = fileNames;
}//LocationLoader
#Override
protected void onStartLoading() {
Log.v(TAG, "onStartLoading called");
forceLoad();
}//onStartLoading
#Override
public ArrayList<BinLocation> loadInBackground() {
Log.v(TAG, "loadInBackground called");
String path = "/storage/emulated/0/";
File file;
String output = "";
//Read data from file
for (int i = 0; i < fileNameArray.length; i++) {
file = new File(path + fileNameArray[i]);
try (Scanner scanner = new Scanner(file)) {
//first line of the text, containing the location and version
output = scanner.nextLine();
String prefix = (output.split(":"))[0];
String line;
while (scanner.hasNextLine()) {
line = scanner.nextLine();
String inputArray[] = line.split(",");
BinLocation binLocation = new BinLocation(
prefix + "-" + inputArray[0],
Double.parseDouble(inputArray[1]),
Double.parseDouble(inputArray[2]),
Integer.parseInt(inputArray[3].trim()),
Integer.parseInt(inputArray[4].trim()),
Integer.parseInt(inputArray[5].trim()),
Integer.parseInt(inputArray[6].trim()));
mBinLocationArrayList.add(binLocation);
}//while
} catch (Exception e) {
Log.e(TAG, "File read error: ", e);
}
}//for
Log.v(TAG, "readLocation finished");
Log.v(TAG, "ArrayList size: " + mBinLocationArrayList.size());
return mBinLocationArrayList;
}//loadInBackground
}//LocationLoader class
Here is my MarkerLoader class (I have tried this and got the doInBackground() error). Also there is no code right now here for adding the data to the marker but it foes in the loop right after it has been added to the map.
public class MarkerLoader extends AsyncTaskLoader<ArrayList<Marker>> {
private GoogleMap map;
private ArrayList<Marker> mMarkerArrayList = new ArrayList<>();
private ArrayList<MyLocation> mBinLocationArrayList = new ArrayList<>();
public MarkerLoader (Context context, GoogleMap map, ArrayList<BinLocation> binLocationArrayList) {
super(context);
this.map = map;
this.mBinLocationArrayList = binLocationArrayList;
}//MarkerLoader
#Override
protected void onStartLoading() {
Log.v(TAG, "onStartLoading called");
forceLoad();
}//onStartLoading
#Override
public ArrayList<Marker> loadInBackground() {
Log.v(TAG, "loadInBackground called");
Marker marker;
for (BinLocation binLocation : mMyLocationArrayList) {
marker = map.addMarker(new MarkerOptions()
.position(binLocation.getPosition()));
mMarkerArrayList.add(marker);
}
Log.v(TAG, "loadInBackground finished, with: " + mMarkerArrayList.size());
return mMarkerArrayList;
}
}
This is the helper function(populateMap()) in the main Activity that makes the markers and save them in an ArrayList
private void populateMap() {
if (!checkMapReady() || !mMapIsEmpty) {
return;
}//if Map Not ready
//Initialize ArrayList
mMarkerArrayList = new ArrayList<>();
/**
* This part uses the loop to go through each MyLocation object in the ArrayList, extract
* all the data, and set the markers
*/
//Check to make sure the BinLocation ArrayList is not empty otherwise we will crash
if (mBinLocationArrayList.isEmpty()) {
Log.w(TAG, "populateMap() terminated, mBinLocationArrayList empty");
return;
}//if BinLocation empty
//Safety check to clear the map before populating it
mMap.clear();
//create a markerMyLocation object
Marker mMaker;
//This goes through the ArrayList for every MyLocation object and sets up the markerMyLocation
for (BinLocation binLocation : mBinLocationArrayList) {
//get boolean values
boolean[] booleanValues = {binLocation.getGarbage(), binLocation.getContainer(),
binLocation.getPaper(), binLocation.getCompost()};
//Set different icon
switch (markerIconPreference) {
case "customIcon":
//custom icon
//Decide what icon to use
if (booleanValues[0] && !booleanValues[1] && !booleanValues[2] && !booleanValues[3]) {
//Make a new MarkerOptions object to add the data
//garbage markers
mMaker = mMap.addMarker(new MarkerOptions()
.title(binLocation.getId())
.position(binLocation.getPosition())
.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_garbage))
.visible(garbageVisible));
} else {
//Make a new MarkerOptions object to add the data
//recycling markers
mMaker = mMap.addMarker(new MarkerOptions()
.title(binLocation.getId())
.position(binLocation.getPosition())
.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_recycling))
.visible(recyclingVisible));
}
//Add our boolean array as an object to our markerMyLocation
mMaker.setTag(booleanValues);
//Add the markerMyLocation to the ArrayList
mMarkerArrayList.add(mMaker);
break;
case "coloredTeardrop":
//teardrop icon
//Decide what icon to use
if (booleanValues[0] && !booleanValues[1] && !booleanValues[2] && !booleanValues[3]) {
//Make a new MarkerOptions object to add the data
//garbage markers
mMaker = mMap.addMarker(new MarkerOptions()
.title(binLocation.getId())
.position(binLocation.getPosition())
.visible(garbageVisible));
} else {
//Make a new MarkerOptions object to add the data
//recycling markers
mMaker = mMap.addMarker(new MarkerOptions()
.title(binLocation.getId())
.position(binLocation.getPosition())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))
.visible(recyclingVisible));
}
//Add our boolean array as an object to our markerMyLocation
mMaker.setTag(booleanValues);
//Add the markerMyLocation to the ArrayList
mMarkerArrayList.add(mMaker);
break;
}//switch
}//for
//disable the progress bar
mProgressBar.setVisibility(View.GONE);
//De-activate the CountDown timer since the map is ready
mCountDownTimer.cancel();
//set the boolean to false
mMapIsEmpty = false;
Log.v(TAG, "populateMap finished. Markers: " + mMarkerArrayList.size());
}//populateMap
Here is the onMapReady function
public void onMapReady(GoogleMap map) {
Log.v(TAG, "onMapReady called");
mMap = map;
//Setup on map loaded
mMap.setOnMapLoadedCallback(this);
//Check to see if the map is empty and the location array list is not empty and then call populateMap
if (mMapIsEmpty && !mBinLocationArrayList.isEmpty()) {
populateMap();
}//if map empty
//set bounds
mMap.setLatLngBoundsForCameraTarget(GREATER_VANCOUVER_BOUND);
//Set min zoom level to match the bound
mMap.setMinZoomPreference(10.0f);
//disable map toolbar
UiSettings mUiSettings = mMap.getUiSettings();
mUiSettings.setMapToolbarEnabled(false);
//Set listeners
mMap.setOnMarkerClickListener(this);
mMap.setOnInfoWindowCloseListener(this);
mMap.setOnInfoWindowClickListener(this);
// Setting our custom info window, passing out helper method
mMap.setInfoWindowAdapter(new CustomInfoWindowAdapter());
//Here we check for permission and setup the map accordingly
if (!checkLocationPermission()) {
//Permission is not granted, log, and use the default location
Log.v(TAG, "No location permission");
//setup default map
defaultMapSetup();
} else {
Log.v(TAG, "Location permission granted");
//Enable my location and initialize the map there
mMap.setMyLocationEnabled(true);
//Setup the map
locationMapSetup();
}//if -permission
}//onMapReady
try to Create your markers in another thread like this
YourActivity.this.runOnUiThread(new Runnable(){
public void run(){
//paste your code here.
});
I am creating an app and i am drawing a route from current marker to nearby markers. when i tap on nearby marker it created a route, and when i again tap on another marker previous route still show. so i want to remove the previous route and draw a new route from current marker to nearby marker. Please help me using my source code....
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker arg0) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
//for direction Route
if(CurrentMarker != null) {
LatLng origin = CurrentMarker.getPosition();
LatLng dest = marker.getPosition();
String url = getDirectionsUrl(origin, dest);
DownloadPar downloadPar = new DownloadPar();
// Start downloading json data from Google Directions API
downloadPar.execute(url);
}
View myContentsView = getLayoutInflater().inflate(R.layout.details, null);
TextView tvTitle = ((TextView)myContentsView.findViewById(R.id.title));
tvTitle.setText(marker.getTitle());
TextView tvSnippet = ((TextView)myContentsView.findViewById(R.id.snippet));
tvSnippet.setText(marker.getSnippet());
return myContentsView;
}
});
Please help me...
Thanks
Declare a variable:
private Polyline polyline;
Then in your method when you initially add the Polyline to the Map:
polyline = mMap.addPolyline(lineOptions);
Then when you want to update the Polyline I believe you can use:
polyline.setPoints(newPoints);
Otherwise, remove the polyline by calling polyline.setMap(null) and create a new one like you have done above.
For more information regarding Polyline, see the documentation
protected void onPostExecute(List>> result) {
ArrayList points = null;
PolylineOptions lineOptions = null;
// MarkerOptions markerOptions = new MarkerOptions();
//markerOptions.position(latLng);
// markerOptions.title("Find Location");
// markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
// FindMarker = mMap.addMarker(markerOptions);
// Traversing through all the routes
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(8);
lineOptions.color(Color.GRAY);
}
// Drawing polyline in the Google Map for the i-th route
mMap.addPolyline(lineOptions);
}
}
This application purposed to get the distance from 2 points of coordinate. The ways is just to click in the map of the position place that you want to count the distance. But there's problem in the point's start, where the application cannot changes the position place.
this is my code:
public class MapsActivity extends FragmentActivity {
// the Google Map object
private GoogleMap mMap;
//ArrayList markerPoints;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// we set the layout for the Activity
setContentView(R.layout.activity_maps);
// the geocoder is instantiated for the first time
geocoder=new Geocoder(this);
// if there isn't a map, it will be created
setUpMapIfNeeded();
}
// LatLng objects store a pair of terrestrial coordinates (latitude and longitude)
private static LatLng STARTING_MARKER_POSITION =new LatLng(3.099465, 101.717111);
/* distanceFrom indicates the starting point to calculate the distance from.
It's initialized with STARTING_MARKER_POSITION
*/
private LatLng distanceFrom= STARTING_MARKER_POSITION;
// line will be drawn at the click event
private Polyline line=null;
// A Geocoder can transform a pair of latitude/longitude into a street address and viceversa.
// We'll use it in the listener
private static Geocoder geocoder=null;
private GoogleMap.OnMapClickListener clickListener=new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(final LatLng pos) {
// this method is called when the user taps the map
// if a line already appears, it's removed
if (line!=null)
line.remove();
// a new line is created
line = mMap.addPolyline(new PolylineOptions()
.add(distanceFrom, pos)
.width(9) // width of the line
.color(Color.BLUE)); // line color
// call the converter object for geocoding invocation and distance calculation
new AddressConverter().execute(distanceFrom, pos);
}
};
#Override
protected void onResume() {
super.onResume();
// the availability of the GoogleMap will be checked before the Activity starts interacting with the user
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// the map is created only it has not been initialized
if (mMap == null) {
// the map is located in the layout
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
// if a map exists, we proceed with initialization
if (mMap != null) {
setUpMap();
}
}
}
// Now it's time to configure the map. We can add markers, shapes, event handlers and so on
private void setUpMap() {
// the camera will be positioned according to the new coordinates
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(STARTING_MARKER_POSITION, 14));
// we choose the type of the map: Satellite in this case
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// markerOptions describes the marker we want to place
MarkerOptions markerOptions=new MarkerOptions()
.position(STARTING_MARKER_POSITION)
.draggable(true);
// the marker has to be draggable as we'll move it
// the marker is rendered on the map
mMap.addMarker(markerOptions);
// we define the object to invoke when the marker is dragged
mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener()
{
#Override
public void onMarkerDragStart(Marker arg0)
{
// this method is called when the drag starts
// the operation we need is the cancellation of a preexisting line
if (line!=null)
line.remove();
}
#Override
public void onMarkerDragEnd(final Marker pos)
{
// we get the final position of the marker
distanceFrom=pos.getPosition();
}
#Override
public void onMarkerDrag(Marker arg0)
{
// operations performed during the movement. Nothing to do
}
});
// the callback to invoke is set
mMap.setOnMapClickListener(clickListener);
}
// we want to know which address corresponds to this location
// we use AsyncTask to perform slower operations on a separate thread
private class AddressConverter extends AsyncTask<LatLng,Void,String>
{
// The ProgressDialog window we'll show during the calculation
private ProgressDialog progress=null;
// this method is called before the background job starts. It works on the main thread
#Override
protected void onPreExecute() {
// ProgressDialog is shown
progress= ProgressDialog.show(MapsActivity.this,"Distance calculator","We are calcultating the distance...", true,false);
}
// this method works on a separate thread
// it performs geocoding operations to retrieve the address of the points and calculates the distance in meters between them
#Override
protected String doInBackground(LatLng... params) {
float[] distance=new float[1];
try {
// the Location class contains what we need to calculate distances
Location.distanceBetween(params[0].latitude,params[0].longitude,params[1].latitude,params[1].longitude,distance);
// geocoding operations
List<Address> fromResult=geocoder.getFromLocation(params[0].latitude,params[0].longitude,1);
List<Address> toResult=geocoder.getFromLocation(params[1].latitude,params[1].longitude,1);
// the message informs the user about the distance from the marker to the point selected with the click
// if we have got both the addresses, we use them to compose the message, otherwise we show only the distance
if (fromResult.size()>0 && toResult.size()>0)
{
// ((TextView) findViewById(R.id.tvDuration)).setText(route.duration.text);
return "The distance between " + getAddressDescription(fromResult.get(0)) + " and " + getAddressDescription(toResult.get(0)) + " is " + Math.round(distance[0]) + " meters";
}
else
return "The distance is " + Math.round(distance[0]) + " meters";
}
catch (IOException e) {
return "The distance is " + Math.round(distance[0]) + " meters";
}
}
#Override
protected void onPostExecute(String message)
{
if (progress!=null)
progress.dismiss();
// The builder of the window is instantiated
AlertDialog.Builder builder=new AlertDialog.Builder(MapsActivity.this);
builder.setTitle("Distance");
builder.setMessage(message);
// the Alert dialog appears
builder.show();
}
}
// this method only formats the message with addresses
private String getAddressDescription(Address a)
{
String city=a.getLocality();
String address=a.getAddressLine(0);
return "'"+address+"' ("+city+")";
}}
Use distanceBetween() method, It will give you exact distance in meters.
Location.distanceBetween(double startLatitude, double startLongitude,
double endLatitude, double endLongitude, float[] results);
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;
}
}
}
}
});
i am really stuck on this:
I have longitude / latitude points to draw on a google map within an android app.
Therefor I created a class extending Overlay...
I get the current longitude/latitude portion of view via:
GeoPoint topLeft = proj.fromPixels(0, 0);
GeoPoint bottomRight = proj.fromPixels(width-1, height-1);
int topLat = topLeft.getLatitudeE6();
int topLon = topLeft.getLongitudeE6();
int bottomLat = bottomRight.getLatitudeE6();
int bottomLon = bottomRight.getLongitudeE6();
The following works (only latitudes):
if(latLon[0] >= bottomLat && latLon[0] <= topLat){ // do something; }
but this does not work (longitudes):
if(latLon[1] >= topLon && latLon[1] <= bottomLon) { // do something; }
latLon[0] is the latitude I want to check
latLon[1] is the longitude I want to check
Anybody an idea?
Greetz!
Longitude numbers are negative from the 0 meridian in England, westward. They're negative in North America and South America.
Use a google map and insert your marker on it.
See below :
public class MapActivity extends GeolocationActivity implements GoogleMap.OnInfoWindowClickListener{
private final String TAG = "MapFragment";
private MapView _mapView;
private GoogleMap _gmap;
/**
* the logo of the marker on the map
*/
private Bitmap _littlePin;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map);
_mapView = (MapView) findViewById(R.id.location_map);
_mapView.onCreate(savedInstanceState);
_gmap = _mapView.getMap(); // initalise the map
if (_gmap != null)
{
setUpMap();
}
}
/**
* set up the map; Add the market on it with a blue dot for the location of the user in real time
* #return false if something goes wrong, true otherwise
* _latitude = latitude of the user, get from the GeolocationActivity
* _longitude = longitude of the user, get from the GeolocationActivity
*/
private boolean setUpMap()
{
// Gets to GoogleMap from the MapView and does initialization stuff
_gmap.getUiSettings().setMyLocationButtonEnabled(false);
_gmap.setMyLocationEnabled(true);
if (_gmap == null) {
Toast.makeText(this, "Google Maps not available", Toast.LENGTH_LONG).show();
return false;
}
// Needs to call MapsInitializer before doing any CameraUpdateFactory calls
MapsInitializer.initialize(this);
BitmapDrawable bitmapDrawable = (BitmapDrawable) getResources().getDrawable(R.drawable.pin); // file stored in /res/drawable/
Bitmap bitmap = bitmapDrawable.getBitmap();
_littlePin = Bitmap.createScaledBitmap(bitmap, 96, 96, false); // 96/96px
_gmap.setOnInfoWindowClickListener(this);// add listener on this class
// here the _lat and _long should be the user of this cafe, at the moment I am using the one of the user
this.addMarker("Cafe", "Best cafe in London", new LatLng(_latitude, _longitude));
// camera, 13 if the zoon, you can change it manually, or dynamically in order to see all your markers
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(_latitude, _longitude), 13);
_gmap.animateCamera(cameraUpdate); // zoom effect
return true;
}
/**
* Add markers on the map view
* #param title title of place / marker
* #param description short description
* #param position geposition, LatLng object, filled with latitude and longitude.
*/
private void addMarker(String title, String description, LatLng position)
{
_gmap.addMarker(new MarkerOptions()
.position(position)
.title(title)
.snippet(description)
.icon(BitmapDescriptorFactory.fromBitmap(_littlePin)));
}
/**
* The user click on the marker on the map, this callback is called
* #param marker clicked marker
*/
#Override
public void onInfoWindowClick(Marker marker) {
Log.d(TAG, "onMarkerClick " + marker.getTitle());
}
#Override
public void onResume() {
_mapView.onResume();
super.onResume();
}
#Override
public void onDestroy() {
super.onDestroy();
_mapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
_mapView.onLowMemory();
}
}
Here is a good example which gonna help you.
and the github with the code sample is here.
Hope this help.