How to set a background image to google maps - android - android

How to Set background image of a custom google map marker?
this question is not about the marker mentioned in the above question link
its about the background of a land
As we set background image to google map makers
is there anyway to set a background image to highlight a special Continent using android?
any help or a reference

Instantiate a new GroundOverlayOptions object.
Specify the image as a BitmapDescriptor.
Set the position of the image using one of the available methods:
position(LatLng location, float width, float height)
position(LatLng location, float width)
positionFromBounds(LatLngBounds bounds)
Set any optional properties, such as transparency, as desired.
Call GoogleMap.addGroundOverlay() to add the image to the map.
Refer this and this

You need to draw a polygon by selecting some points on map.
Example code :
public class MainActivity extends FragmentActivity implements
OnMapClickListener,
OnMapLongClickListener,
OnMarkerClickListener {
private GoogleMap myMap;
Location myLocation;
boolean markerClicked;
PolygonOptions polygonOptions;
Polygon polygon;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager manager = getSupportFragmentManager();
SupportMapFragment mapFragment = (SupportMapFragment) manager
.findFragmentById(R.id.map);
myMap = mapFragment.getMap();
myMap.setMyLocationEnabled(true);
myMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
myMap.setOnMapClickListener(this);
myMap.setOnMapLongClickListener(this);
myMap.setOnMarkerClickListener(this);
markerClicked = false;
}
#Override
public void onMapLongClick(LatLng point)
{
myMap.addMarker(new MarkerOptions()
.position(point).title(point.toString()));
markerClicked = false;
}
#Override
public boolean onMarkerClick(Marker marker)
{
if(markerClicked)
{
if(polygon != null)
{
polygon.remove();
polygon = null;
}
polygonOptions.add(marker.getPosition());
polygonOptions.strokeColor(Color.BLACK);
polygonOptions.strokeWidth(5);
polygonOptions.fillColor(0x884d4d4d);
polygon = myMap.addPolygon(polygonOptions);
marker.remove();
}
else
{
if(polygon != null)
{
polygon.remove();
polygon = null;
}
polygonOptions = new PolygonOptions().add(marker.getPosition());
markerClicked = true;
marker.remove();
}
return true;
}
#Override
public void onMapClick(LatLng point)
{
Toast.makeText(getApplicationContext(),
"Long Press to select locations", Toast.LENGTH_LONG).show();
}
}
using this fragment
fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
Also read the official Documentation here.

Replace codes in getInfoContents with getInfoWindow. The difference between them is getInfoContents wraps your View in ViewGroup with default background.
try this one

Related

Reduce the marker clickable radius

I am working on the google map project for navigation. and creating and displaying many polygons.
But when I try to click near the marker it always detects the marker point. So I would like to know that is there any property there where I can set the marker clickable radius?
I show that is available in the JavaScript but I could not find any lead regarding Android.
Any help or reference much appreciated.
Anyway you can use a workaround:
disable marker clicks response;
detect touch on map determine nearest marker by yourself.
Of course, you need to store all of the markers in that case.
While the first point is simple:
mGoogleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
return true;
}
});
the second is not: even if "empty" onMarkerClick() return true markers will always intercept this event.
To get rid of that you can use approach with "touchable wrapper" like in this answer within custom MapFragment that can intercept touch events before they goes to MapFragment. When you get touch event you can get screen coordinates of touch. Then you need to find marker with minimal distance from touch location (you also need to convert marke's 'LatLng' position into screen flat coordinates via Projection.toScreenLocation() method). If founded marker within clickable radius you can process custom onMarkerClick event, if not - process polygon click.
Something like that:
Class TouchableWrapper - the core of approach:
public class TouchableWrapper extends FrameLayout {
private static final int CLICK_RADIUS_IN_PIXELS = 25;
private GoogleMap mGoogleMap;
private List<Marker> mMarkers;
public TouchableWrapper(Context context) {
super(context);
}
public void setGoogleMapAndMarkers(GoogleMap googleMap, List<Marker> markers) {
mGoogleMap = googleMap;
mMarkers = markers;
}
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (mGoogleMap == null) return super.dispatchTouchEvent(event);
int screenX = (int) event.getX();
int screenY = (int) event.getY();
if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
// find marker nearest to touch position
Projection projection = mGoogleMap.getProjection();
Marker nearestMarker = null;
int minDistanceInPixels = Integer.MAX_VALUE;
for (Marker marker : mMarkers) {
Point markerScreen = projection.toScreenLocation(marker.getPosition());
int distanceToMarker = (int) Math.sqrt((screenX - markerScreen.x) * (screenX - markerScreen.x)
+ (screenY - markerScreen.y) * (screenY - markerScreen.y));
if (distanceToMarker < minDistanceInPixels) {
minDistanceInPixels = distanceToMarker;
nearestMarker = marker;
}
}
// "drop" nearest marker if it is not within radius
if (minDistanceInPixels > CLICK_RADIUS_IN_PIXELS) {
nearestMarker = null;
}
if (nearestMarker != null) {
// decide what to process (marker click or polygon click) here
Toast.makeText(getContext(),
"Clicked on marker " + nearestMarker.getTitle(), Toast.LENGTH_LONG).show();
}
}
return super.dispatchTouchEvent(event);
}
}
You can adjust clickable radius via CLICK_RADIUS_IN_PIXELS constant value.
Customized MapFragmet that uses TouchableWrapper class:
public class TouchableMapFragment extends MapFragment {
public View originalContentView;
public TouchableWrapper touchView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
originalContentView = super.onCreateView(inflater, parent, savedInstanceState);
touchView = new TouchableWrapper(getActivity());
touchView.addView(originalContentView);
return touchView;
}
#Override
public View getView() {
return originalContentView;
}
}
'MainActivity' that uses TouchableMapFragment:
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
private static final String TAG = MainActivity.class.getSimpleName();
static final LatLng MARKER_1 = new LatLng(50.450311, 30.523730);
static final LatLng MARKER_2 = new LatLng(50.4502, 30.52365);
private GoogleMap mGoogleMap;
private TouchableMapFragment mMapFragment;
private List<Marker> mMarkers = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMapFragment = (TouchableMapFragment) getFragmentManager()
.findFragmentById(R.id.map_fragment);
mMapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
// store markers
Marker marker = mGoogleMap.addMarker(new MarkerOptions()
.position(MARKER_1)
.title("Marker 1"));
mMarkers.add(marker);
marker = mGoogleMap.addMarker(new MarkerOptions()
.position(MARKER_2)
.title("Marker 2"));
mMarkers.add(marker);
// pass stored markers to "touchable wrapper"
mMapFragment.touchView.setGoogleMapAndMarkers(mGoogleMap, mMarkers);
// disable marker click processing
mGoogleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
return true;
}
});
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(MARKER_1, 14));
}
}
and 'MainActivity' layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.MainActivity">
<fragment
android:id="#+id/map_fragment"
android:name="<your.package.name>.TouchableMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Also, in your case you need to pass List<Polygon> to TouchableWrapper like List<Marker> in example above and process polygon click in its dispatchTouchEvent(MotionEvent event) too.

Editable multiple polygon using dragListener in Google Maps

I would like to implement multiple polygons with an editable using a drag listener. I am able to draw the multiple polygons but I don't know how to make editable.
I am able to move marker for current polygon but when I try to move previous polygon’s marker app is crash. I tried with saving polygon list but I can not able to drag the marker.
please see my code HERE.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (readyToGo()) {
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);
if (savedInstanceState == null) {
mapFragment.getMapAsync(this);
}
mapFragment.getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
CameraUpdate center =
CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044,
-73.98180484771729));
CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
mMap.moveCamera(center);
mMap.animateCamera(zoom);
mMap.setIndoorEnabled(false);
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
Marker marker = mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
marker.setTag(latLng);
markerList.add(marker);
points.add(latLng);
drawPolygon(points);
}
});
mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
#Override
public void onMarkerDragStart(Marker marker) {
}
#Override
public void onMarkerDrag(Marker marker) {
updateMarkerLocation(marker, false);
}
#Override
public void onMarkerDragEnd(Marker marker) {
updateMarkerLocation(marker, true);
}
});
}
public void closePolygon(View view) {
}
public void newPolygon(View view) {
//
points.clear();
markerList.clear();
polygon = null;
// mMap.clear();
}
private void updateMarkerLocation(Marker marker, boolean calculate) {
LatLng latLng = (LatLng) marker.getTag();
int position = points.indexOf(latLng);
points.set(position, marker.getPosition());
marker.setTag(marker.getPosition());
drawPolygon(points);
}
private void drawPolygon(List<LatLng> latLngList) {
if (polygon != null) {
polygon.remove();
}
polygonOptions = new PolygonOptions();
polygonOptions.addAll(latLngList);
polygon = mMap.addPolygon(polygonOptions);
}
}
Basically this approach keeps the markers and points as collections associated with each polygon. It simplifies things by assuming after 5 markers a new polygon is created (equivalent to an add polygon).
UPDATED: To use the "new polygon" button as defined in the layout in github. Button listener just sets a flag and instead of using a size=5 check replace the check with the flag.
A map from any marker to its corresponding list is maintained for use in the updateMarkerLocation method.
All of this is predicated on the fact that any marker has a unique id provided by the map API getId() which in practice is a string like "m7".
I've listed the parts updated:
// Map a marker id to its corresponding list (represented by the root marker id)
HashMap<String,String> markerToList = new HashMap<>();
// A list of markers for each polygon (designated by the marker root).
HashMap<String,List<Marker>> polygonMarkers = new HashMap<>();
// A list of polygon points for each polygon (designed by the marker root).
HashMap<String,List<LatLng>> polygonPoints = new HashMap<>();
// List of polygons (designated by marker root).
HashMap<String,Polygon> polygons = new HashMap<>();
// The active polygon (designated by marker root) - polygon added to.
String markerListKey;
// Flag used to record when the 'New Polygon' button is pressed. Next map
// click starts a new polygon.
boolean newPolygon = false;
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
CameraUpdate center =
CameraUpdateFactory.newLatLng(new LatLng(40.76793169992044,
-73.98180484771729));
CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
mMap.moveCamera(center);
mMap.animateCamera(zoom);
mMap.setIndoorEnabled(false);
Button b = findViewById(R.id.bt_new_polygon);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
newPolygon = true;
}
});
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
Marker marker = mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
marker.setTag(latLng);
// Special case for very first marker.
if (polygonMarkers.size() == 0) {
polygonMarkers.put(marker.getId(),new ArrayList<Marker>());
// only 0 or 1 polygons so just add it to new one or existing one.
markerList = new ArrayList<>();
points = new ArrayList<>();
polygonMarkers.put(marker.getId(),markerList);
polygonPoints.put(marker.getId(),points);
markerListKey = marker.getId();
}
if (newPolygon) {
newPolygon = false;
markerList = new ArrayList<>();
points = new ArrayList<>();
polygonMarkers.put(marker.getId(),markerList);
polygonPoints.put(marker.getId(),points);
markerListKey = marker.getId();
}
markerList.add(marker);
points.add(latLng);
markerToList.put(marker.getId(),markerListKey);
drawPolygon(markerListKey, points);
}
});
private void updateMarkerLocation(Marker marker, boolean calculate) {
// Use the marker to figure out which polygon list to use...
List<LatLng> pts = polygonPoints.get(markerToList.get(marker.getId()));
// This is much the same except use the retrieved point list.
LatLng latLng = (LatLng) marker.getTag();
int position = pts.indexOf(latLng);
pts.set(position, marker.getPosition());
marker.setTag(marker.getPosition());
drawPolygon(markerToList.get(marker.getId()),pts);
}
private void drawPolygon(String mKey, List<LatLng> latLngList) {
// Use the existing polygon (if any) for the root marker.
Polygon polygon = polygons.get(mKey);
if (polygon != null) {
polygon.remove();
}
polygonOptions = new PolygonOptions();
polygonOptions.addAll(latLngList);
polygon = mMap.addPolygon(polygonOptions);
// And update the list for the root marker.
polygons.put(mKey,polygon);
}
Initial
Initial collection of 3 polygons added by clicking on map...
Modified
Then an image showing a point in each polygon stretched...

Sygic not showing current position nor displaying markers

i want to show the location indicator when the map is loaded and add a marker whenever the map is clicked but none of these seem to work !
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MapFragment mapFragment = (MapFragment) getSupportFragmentManager().findFragmentById(R.id.mapFragment);
assert mapFragment != null;
mapFragment.getMapAsync(new OnMapInitListener() {
#Override
public void onMapReady(MapView mapView) {
OnlineManager.getInstance().enableOnlineMapStreaming(true);
PositionManager.getInstance().startPositionUpdating();
PositionManager.getInstance().enableRemotePositioningService();
mpView=mapView;
mpView.addMapGestureListener(new MapGestureAdapter() {
#Override
public boolean onMapClicked(final MotionEvent e, final boolean isTwoFingers) {
MapMarker marker = new MapMarker(new GeoCoordinates(PositionManager.getInstance().getLastKnownPosition().getLongitudeAccuracy(),PositionManager.getInstance().getLastKnownPosition().getLatitudeAccuracy()));
mpView.addMapObject(marker);
return true;
}
});
}
#Override
public void onMapError(int error, String info) {}
});
}
You’re trying to create new Marker with getLongitudeAccuracy() and getLatitudeAccuracy(). You need to use geo coordinates!
If you want to add the marker to the position of last known gps signal you can use this code:
MapMarker marker = new MapMarker(PositionManager.getInstance().getLastKnownPosition().getCoordinates())
But as there can be no known position at that time it can result in no marker added. So be sure you have location turned on and strong signal. Based on your example it would make more sense to add marker to the position you clicked on. For that purpose use this code:
mpView.addMapGestureListener(new MapGestureAdapter() {
#Override
public boolean onMapClicked(final MotionEvent e, final boolean isTwoFingers) {
MapMarker marker = new MapMarker(mpView.geoCoordinatesFromPoint(e.getX(), e.getY()));
mpView.addMapObject(marker);
return true;
}
});

How to set info window details in Google Maps Clustering Utility Android?

I am trying to display a list of venues on Google Maps in Android, which can be clustered on zoom out and on zoom in unclustered.
WHEN UNCLUSTERED, an individual item info window can be opened to look at that venue details, and clicked to open a separate activity.
I am using this https://developers.google.com/maps/documentation/android-api/utility/marker-clustering?hl=en
I am doing this :
Getting Map Fragment in onResume()
#Override
public void onResume() {
super.onResume();
// Getting map for the map fragment
mapFragment = new SupportMapFragment();
mapFragment.getMapAsync(new VenuesInLocationOnMapReadyCallback(getContext()));
// Adding map fragment to the view using fragment transaction
FragmentManager fragmentManager = getChildFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.venues_in_location_support_map_fragment_container, mapFragment);
fragmentTransaction.commit();
}
MapReadyCallback :
private class VenuesInLocationOnMapReadyCallback implements OnMapReadyCallback {
private static final float ZOOM_LEVEL = 10;
private final Context context;
public VenuesInLocationOnMapReadyCallback(Context context) {
this.context = context;
}
#Override
public void onMapReady(final GoogleMap map) {
// Setting up marker clusters
setUpClusterManager(getContext(), map);
// Allowing user to select My Location
map.setMyLocationEnabled(true);
// My location button handler to check the location setting enable
map.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
#Override
public boolean onMyLocationButtonClick() {
promptForLocationSetting(getContext(), map);
// Returning false ensures camera try to move to user location
return false;
}
});
map.getUiSettings().setMyLocationButtonEnabled(true);
// Disabling map toolbar
map.getUiSettings().setMapToolbarEnabled(false);
}
}
Setting up Cluster Manager
private void setUpClusterManager(final Context context, GoogleMap map) {
// Declare a variable for the cluster manager.
ClusterManager<LocationMarker> mClusterManager;
// Position the map.
LatLng wocLatLng = new LatLng(28.467948, 77.080685);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(wocLatLng, VenuesInLocationOnMapReadyCallback.ZOOM_LEVEL));
// Initialize the manager with the context and the map.
mClusterManager = new ClusterManager<LocationMarker>(context, map);
// Point the map's listeners at the listeners implemented by the cluster
// manager.
map.setOnCameraChangeListener(mClusterManager);
map.setOnMarkerClickListener(mClusterManager);
// Add cluster items (markers) to the cluster manager.
addLocations(mClusterManager);
// Setting custom cluster marker manager for info window adapter
map.setInfoWindowAdapter(mClusterManager.getMarkerManager());
mClusterManager.getMarkerCollection().setOnInfoWindowAdapter(new MyLocationInfoWindowAdapter());
map.setOnInfoWindowClickListener(new MyMarkerInfoWindowClickListener());
}
Adding Cluster items (markers)
private void addLocations(ClusterManager<LocationMarker> mClusterManager) {
for (int i = 0; i < venuesDetailsJsonArray.length(); i++) {
try {
JSONObject thisVenueJson = (JSONObject) venuesDetailsJsonArray.get(i);
JSONObject thisVenueLocationJson = thisVenueJson.getJSONObject("location");
LocationMarker thisVenueMarker = new LocationMarker(thisVenueLocationJson.getDouble("latitude"),
thisVenueLocationJson.getDouble("longitude"), thisVenueJson.getInt("id"));
mClusterManager.addItem(thisVenueMarker);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
MyLocationInfoWIndowAdapter
private class MyLocationInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
Log.e("getInfoContent", marker.toString());
View venueInfoWindow = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.venues_map_item, null);
return venueInfoWindow;
}
}
MarkerInfoWindowClickListener
private class MyMarkerInfoWindowClickListener implements GoogleMap.OnInfoWindowClickListener {
#Override
public void onInfoWindowClick(Marker marker) {
// TODO: This is the click listener, that means all the info must be added as Tag to Marker
Intent venueDetailsDisplayIntent = new Intent(getActivity(), VenueDetailsDisplayActivity.class);
startActivity(venueDetailsDisplayIntent);
}
}
Location Marker class
public class LocationMarker implements ClusterItem{
private final LatLng mPosition;
private final int id;
public LocationMarker(double lat, double lng, int id) {
mPosition = new LatLng(lat, lng);
this.id = id;
}
#Override
public LatLng getPosition() {
return mPosition;
}
public int getId() {
return this.id;
}
}
The way that I am understanding the flow is this :
onResume --> fragmentTransaction --> VenuesInLocationOnMapReadyCallback --> setUpClusterManager --> addLocations (This adds Custom markers)
Marker Click --> MyLocationInfoWindowAdapter --> getInfoContents(Marker marker)
Marker Info Window click --> MyMarkerInfoWindowClickListener
According to my Understanding of process (I could be wrong):
I am adding an id to my custom LocationMarker when Adding markers in addLocations function.
I need to display different info in infoWindow for different markers.
InfoWindow is displayed using MyLocationInfoWindowAdapter-->getInfoContents(Marker marker)
But here is the rub, I can't find a way to figure out which marker has been clicked upon so that I can set appropriate info in InfoWindow.
On Click on opened InfoWindow I need to open a separate Activity. A/C to me InfoWindow click is handled using MyMarkerInfoWindowClickListener-->onInfoWindowClick(Marker marker) Here too I am having the same problem (I can't figure out which marker's info window has been clicked).

Open alert on click on marker [maps v2]

I've a problem with Google Maps v2. I've to show a custom dialog when the user clicks on the only marker on the map. But the only things that happens is, it centers the map on the marker.
Here's the code:
public class where extends FragmentActivity implements OnMarkerClickListener{
private final LatLng STARTING_POINT=new LatLng(37.5****, 14.2****);
Marker marker;
TextView testo;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mappa);
GoogleMap map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(STARTING_POINT, 5));
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//zoom che dura 2 secondi
map.animateCamera(CameraUpdateFactory.zoomTo(19), 3000, null);
map.setOnMarkerClickListener(this);
marker = map.addMarker(new MarkerOptions().position(STARTING_POINT).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
}
#Override
public boolean onMarkerClick(Marker marker) {
if(this.marker == marker){
AlertDialog.Builder alertadd = new AlertDialog.Builder(dovesiamo.this);
LayoutInflater factory = LayoutInflater.from(dovesiamo.this);
final View view = factory.inflate(R.layout.alert, null);
alertadd.setView(view);
alertadd.show();
}
return false;
}
Change
if(this.marker == marker)
to
if(this.marker.equals(marker))

Categories

Resources