Has anyone managed to use ItemizedOverlays in Android Beta 0.9? I can't get it to work, but I'm not sure if I've done something wrong or if this functionality isn't yet available.
I've been trying to use the ItemizedOverlay and OverlayItem classes. Their intended purpose is to simulate map markers (as seen in Google Maps Mashups) but I've had problems getting them to appear on the map.
I can add my own custom overlays using a similar technique, it's just the ItemizedOverlays that don't work.
Once I've implemented my own ItemizedOverlay (and overridden createItem), creating a new instance of my class seems to work (I can extract OverlayItems from it) but adding it to a map's Overlay list doesn't make it appear as it should.
This is the code I use to add the ItemizedOverlay class as an Overlay on to my MapView.
// Add the ItemizedOverlay to the Map
private void addItemizedOverlay() {
Resources r = getResources();
MapView mapView = (MapView)findViewById(R.id.mymapview);
List<Overlay> overlays = mapView.getOverlays();
MyItemizedOverlay markers = new MyItemizedOverlay(r.getDrawable(R.drawable.icon));
overlays.add(markers);
OverlayItem oi = markers.getItem(0);
markers.setFocus(oi);
mapView.postInvalidate();
}
Where MyItemizedOverlay is defined as:
public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> {
public MyItemizedOverlay(Drawable defaultMarker) {
super(defaultMarker);
populate();
}
#Override
protected OverlayItem createItem(int index) {
Double lat = (index+37.422006)*1E6;
Double lng = -122.084095*1E6;
GeoPoint point = new GeoPoint(lat.intValue(), lng.intValue());
OverlayItem oi = new OverlayItem(point, "Marker", "Marker Text");
return oi;
}
#Override
public int size() {
return 5;
}
}
For the sake of completeness I'll repeat the discussion on Reto's post over at the Android Groups here.
It seems that if you set the bounds on your drawable it does the trick:
Drawable defaultMarker = r.getDrawable(R.drawable.icon);
// You HAVE to specify the bounds! It seems like the markers are drawn
// through Drawable.draw(Canvas) and therefore must have its bounds set
// before drawing.
defaultMarker.setBounds(0, 0, defaultMarker.getIntrinsicWidth(),
defaultMarker.getIntrinsicHeight());
MyItemizedOverlay markers = new MyItemizedOverlay(defaultMarker);
overlays.add(markers);
By the way, the above is shamelessly ripped from the demo at MarcelP.info. Also, here is a good howto.
try :
Drawable defaultMarker = r.getDrawable(R.drawable.icon);
defaultMarker.setBounds(0, 0, defaultMarker.getIntrinsicWidth(),
defaultMarker.getIntrinsicHeight());
MyItemizedOverlay markers = new MyItemizedOverlay(defaultMarker);
overlays.add(markers);
Related
Assumption and what I want to achieve
I'm working on an application that receives current location information from an external RTK-GPS via serial communication, and draws dots or lines on an osmdroid map.
I have already realized receiving the location information and converting the received data to a type that can be displayed on TextView.
For serial communication, I am using FTDI's "usb-serial-for-android" library, and for map functions, I am using "osmdroid".
Currently
Receive location data from RTK-GPS via serial communication.
Get the latitude and longitude in double type from the received data (String type).
Create a GeoPoint from the acquired latitude and longitude, set it to a marker, and draw it on the map. At this time, the GeoPoint is also stored in the GeoPoint list.
The following procedure is used to display the marker of the current location on the map. Currently, the received latitude and longitude are set to the marker and all the markers are drawn.
Eventually, I'd like to draw the trajectory of movement as a line while updating the current location marker.
Problems and error messages
The problem we are experiencing is that when we start drawing, the application immediately becomes sluggish and freezes.
Since 10 data are sent from GPS per second, if we try to draw all the received data on the map, the number of markers will be huge and the app will freeze.
Therefore, we tried to draw markers in 10 marker skips, but even so, the application became sluggish and froze as soon as it started drawing.
Next, when the number of data exceeded 100, I deleted the oldest data first, and the application did not freeze after starting drawing. However, I don't think it is possible to draw all the loci with this method. If possible, I would like to draw all the loci that have been moved.
My questions are as follows.
Is it possible to draw the movement locus using the above method and policy?
Is it impossible to draw such a moving locus in Android?
Does OSMDROID have a function to draw the movement locus?
Are there any similar questions?
Please let me know.
Here is my code.
public class MapGeneratorMainActivity extends Activity {
private static final double MAP_ZOOM = 15.0;
private static final double MAP_ZOOM2 = 17.0;
static MapView mapGeneratorMainMap = null;
public static List<Marker> currentMarkers = new ArrayList<>();
ArrayList<GeoPoint> currentPoints = new ArrayList<>();
ArrayList<GeoPoint> currentPoints2hz = new ArrayList<>();
ArrayList<Polyline> currentTrajectory = new ArrayList<>();
public static int receiveCount = 0;
public static GeoPoint currentP2hz;
public MapGeneratorMainActivity() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
org.osmdroid.config.Configuration.getInstance().load(getApplicationContext(),
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()));
setContentView(R.layout.map_generator_main_activity);
MapView mapGeneratorMainMap = findViewById(R.id.MapGaneratorMainMap);
mapGeneratorMainMap.setMultiTouchControls(true);
IMapController mapController = mapGeneratorMainMap.getController();
mapController.setZoom(MAP_ZOOM);
GeoPoint centerPoint = new GeoPoint(aveLat, aveLon);
mapController.setCenter(centerPoint);
mapGeneratorMainMap.setTilesScaledToDpi(true);
final MapTileProviderBasic tileProvider = new MapTileProviderBasic(getApplicationContext());
ITileSource tileSource = new XYTileSource("GSI", 14, 24, 256, ".jpg", new String[]{TILE_SEVER});
tileProvider.setTileSource(tileSource);
final TilesOverlay tilesOverlay = new TilesOverlay(tileProvider, this.getApplicationContext());
tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT);
mapGeneratorMainMap.getOverlays().add(tilesOverlay);
mapGeneratorMainMap.invalidate();
FloatingActionButton myLocationButton = findViewById(R.id.myLocationButton);
myLocationButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intentService = new Intent(getApplication(), gpsService.class); //位置情報受信サービス
intentService.putExtra("REQUEST_CODE", 1);
startForegroundService(intentService);
}
});
//Receiver
UpdateReceiver receiver = new UpdateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("DO_ACTION");
registerReceiver(receiver, filter);
}
protected class UpdateReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
String currentLat = null;
String currentLon = null;
MapView mapGeneratorMainMap = findViewById(R.id.MapGaneratorMainMap);
mapGeneratorMainMap.setMultiTouchControls(true);
IMapController mapController = mapGeneratorMainMap.getController();
mapController.setZoom(MAP_ZOOM2);
Bundle extras = intent.getExtras();
String msg = extras.getString("message"); //String型の位置情報
TextView currentLocatonTextView = findViewById(R.id.CurrentLocation);
currentLocatonTextView.setText(msg);
String[] currentLocaton = msg.split(",", -1);
currentLat = currentLocaton[0];
currentLon = currentLocaton[1];
double Lat = Double.parseDouble(currentLat);
double Lon = Double.parseDouble(currentLon);
GeoPoint currentP = new GeoPoint(Lat, Lon);
if(receiveCount == 0){
currentP2hz = new GeoPoint(Lat, Lon);
currentPoints.add(currentP);
currentPoints2hz.add(currentP2hz);
currentPtMarker = new Marker(mapGeneratorMainMap);
Drawable currentMarkerIcon = ResourcesCompat.getDrawable(getResources(), R.drawable.current_point_marker, null);
currentPtMarker.setIcon(currentMarkerIcon);
currentPtMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER);
currentPtMarker.setPosition(currentP);
currentMarkers.add(currentPtMarker);
mapGeneratorMainMap.getOverlayManager().add(currentPtMarker);
mapGeneratorMainMap.invalidate();
}
else if(receiveCount == 100) {
currentPoints.add(currentP);
currentP2hz = new GeoPoint(Lat, Lon);
currentPoints2hz.add(currentP2hz);
receiveCount = 0;
currentPtMarker = new Marker(mapGeneratorMainMap);
Drawable currentMarkerIcon = ResourcesCompat.getDrawable(getResources(), R.drawable.current_point_marker, null);
currentPtMarker.setIcon(currentMarkerIcon);
currentPtMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER);
currentPtMarker.setPosition(currentP);
currentMarkers.add(currentPtMarker);
mapGeneratorMainMap.getOverlayManager().add(currentPtMarker);
mapGeneratorMainMap.invalidate();
}
if(currentMarkers.size() >= 100){
currentMarkers.get(0).remove(mapGeneratorMainMap);
currentMarkers.remove(0);
}
receiveCount += 1;
}
}
Good morning everyone.
I was able to solve this problem.
The reason why it didn't work was that some of the data received by serial communication was not good.
After eliminating this bad data and receiving only the good data, I was able to do what I wanted.
thanks so much.
Part of my application uses RecyclerView with CardView elements, and every CardView element contains Google Map which draws specific route. On every map I am zooming and positioning route inside of map so it can fill whole view but problems arrive when I begin to scroll and every next CardView doesn't position my route inside a map but leaves it unzoomed and unpositioned. Picture is below:
Im using onBindViewHolder to setup map and route drawing and then I'm using zoomToLatLng to zoom the map
#Override
public void onBindViewHolder(RouteViewHolder holder, int position) {
holder.destination.setText(routesCV.get(position).getDestination());
holder.startingPoint.setText(routesCV.get(position).getStartingPoint());
GoogleMap gMap = holder.map.getMap();
if (gMap != null) {
ArrayList<PointModel> mapPosition = routesCV.get(position).getPoints();
ArrayList<LatLng> points = new ArrayList<LatLng>();
for (PointModel item : mapPosition) {
points.add(new LatLng(item.getLatitude(),item.getLongitude()));
}
for (LatLng item : points) {
gMap.addMarker(new MarkerOptions().position(item));
}
zoomMapToLatLngBounds(holder.linearlayout, gMap, points);
}
}
Zoom method:
private void zoomMapToLatLngBounds(final LinearLayout layout,final GoogleMap mMap, final ArrayList<LatLng> bounds){
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
for (int i=0; i<bounds.size(); i++) {
boundsBuilder.include(bounds.get(i));
}
final LatLngBounds boundsfinal = boundsBuilder.build();
final ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout() {
layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsfinal, 25));
}
});
From logs public void onGlobalLayout() doesnt even execute. Do u know what might be the problem ? Tnx!
I made a OnMapLoadedCallback() function to position the map. It works now!
I want to draw polygon on google maps which may be resized. Any marker removed successfully by onMarkerClick but I can't change marker position by drag it to another place.
Here is my code:
PolygonOptions polygon = new PolygonOptions();
Polygon my_polygon ;
polygon.fillColor(Color.RED);
....
#Override
public boolean onMarkerClick(Marker arg0) {
my_polygon.remove();
arg0.remove();
polygon.getPoints().remove(arg0.getPosition()); //it's ok, marker deleted
return true;
}
#Override
public void onMarkerDrag(Marker marker)
{
polygon.getPoints().remove(marker.getPosition()); //marker still in polygon list
}
#Override
public void onMarkerDragStart(Marker marker)
{
polygon.getPoints().remove(marker.getPosition()); //marker still in polygon list
}
#Override
public void onMarkerDragEnd(Marker marker)
{
my_polygon.remove();
polygon.getPoints().remove(marker.getPosition()); //marker still in polygon list
polygon.add(marker.getPosition());
my_polygon=map.addPolygon(polygon); //created new polygon which contains previous marker position
}
So, how can I remove previus marker points correctly?
First keep all the LatLng points in a arraylist of LatLng.
Dont remove marker in
onMarkerDragStart(Marker marker) even save it to a new LatLng variable. Now at onMarkerDragEnd(Marker marker) , first get the new point and then remove the old one that u were save in the new LatLng variable . At the same time you need to remove the same marker from the arraylist that u have saved and add this new value and then draw a polygon again.
for example if suppose u have declare an arraylist of latlng like this
ArrayList points = new ArrayList();
then draw a ploygon in onMarkerDragEnd(Marker marker) like the following
Polygon polygon = map.addPolygon(new PolygonOptions()
.addAll(points)
.strokeColor(Color.BLACK)
.strokeWidth(5)
.fillColor(0x884d4d4d));
try this. hope it will help. :)
I have a map that I want to put a marker on, but the marker isn't showing up. Here is my code:
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;
public class MapDetailActivity extends MapActivity
{
private final static String TAG = MapDetailActivity.class.getSimpleName();
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.map_view);
// get longitude and latitude values from detail activity/object
Bundle bundle = this.getIntent().getExtras();
float latitude = bundle.getFloat("uie.top25.seattle.latitude");
float longitude = bundle.getFloat("uie.top25.seattle.longitude");
Log.i(TAG, "Latitude that is set : " + latitude);
Log.i(TAG, "Longitude that is set : " + longitude);
// create longitude and latitude map points
Double lat = latitude * 1E6;
Double lon = longitude * 1E6;
// create point on map
GeoPoint point = new GeoPoint(lat.intValue(), lon.intValue());
OverlayItem oi = new OverlayItem(point, null, null);
MapView mapView = (MapView) this.findViewById(R.id.myMapView);
MapController mapController = mapView.getController();
// set point on map
mapController.animateTo(point);
oi.setMarker(oi.getMarker(R.drawable.mm_20_red));
// set zoom level
mapController.setZoom(19);
}
#Override
protected boolean isRouteDisplayed()
{
// No driving directions, so this method returns false
return false;
}
}
Can someone tell me what I am doing wrong?
You must add your item to map using https://developers.google.com/maps/documentation/android/hello-mapview this documentation Part-2
You need to create an Overlay to display a marker, read this:
https://developers.google.com/maps/documentation/android/reference/com/google/android/maps/Overlay
If you couldn't be bothered reading all of that here's a ready to use tutorial:
http://android-er.blogspot.com/2009/11/display-marker-on-mapview-using.html
You will need to go through the documentation and examples, but the basic steps are:
1-Create your itemizedOverlay by extending the itemizedOverlay from google maps.
2-Add an overlay Item to your Itemized overlay, and set the marker or use the default one defined in the previous step.
3-Add the itemized overlay to the mapview overlays with:
mapview.getoverlays().add(myItemizedOverlay);
Just after you have add the overlay to the mapview overlays list, the overlay will be considered by mapview to be called for drawing on screen (calling the onDraw method)
good luck.
I just started Android development and working on a little app related to google maps api. Am using the Google Map View for this and following this tutorial..
I've created a custom itemizedOverlay, which has a constructor like this(as told in the tutorial) -
public pujaItemizedOverlay(Drawable defaultMarker, Context context) {
super(defaultMarker);
mContext = context;
}
I have a image file named sprite.png in the res/drawable/ forder. And here is my onCreate() function -
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapView mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.sprite);
pujaItemizedOverlay itemizedoverlay = new pujaItemizedOverlay(drawable, this);
GeoPoint point = new GeoPoint(19240000,-99120000);
OverlayItem overlayitem = new OverlayItem(point, "Hola, Mundo!", "I'm in Mexico City!");
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
}
The problem is, The image named sprite doesn't show up on the map.
One this I'd like to mention is that, according to the tutorial, they added a second paramete to the constructor of the custom itemizedOverlay of the class Context. But in their example, when they called that overlay, they provided only one parameter(check the tutorial page), like -
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable);
Eclipse showed an obvious error in this line, so I added the second parameter as this to provide the current context. Am I doing it right here?
Update:
The image in question is here.
Found the solution here. It seems that if the mapview doesn't know how to align the image it won't show it at all.