Changeset View
Changeset View
Standalone View
Standalone View
src/it/reyboz/bustorino/ActivityMap.java
/* | |||||
BusTO Activities | |||||
Copyright (C) 2020 Andrea Ugo e Fabio Mazza | |||||
This program is free software: you can redistribute it and/or modify | |||||
it under the terms of the GNU General Public License as published by | |||||
the Free Software Foundation, either version 3 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU General Public License for more details. | |||||
You should have received a copy of the GNU General Public License | |||||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
package it.reyboz.bustorino; | package it.reyboz.bustorino; | ||||
import android.content.Context; | import android.content.Context; | ||||
import android.content.Intent; | import android.content.Intent; | ||||
import android.location.Location; | |||||
import android.location.LocationManager; | |||||
import android.os.Build; | import android.os.Build; | ||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import android.util.Log; | |||||
import android.view.View; | |||||
import android.widget.ImageButton; | |||||
import android.support.annotation.RequiresApi; | import android.support.annotation.RequiresApi; | ||||
import android.support.v7.app.AppCompatActivity; | import android.support.v7.app.AppCompatActivity; | ||||
import android.support.v7.preference.PreferenceManager; | import android.support.v7.preference.PreferenceManager; | ||||
import android.widget.Toast; | |||||
import org.osmdroid.api.IMapController; | import org.osmdroid.api.IMapController; | ||||
import org.osmdroid.config.Configuration; | import org.osmdroid.config.Configuration; | ||||
import org.osmdroid.events.DelayedMapListener; | import org.osmdroid.events.DelayedMapListener; | ||||
import org.osmdroid.events.MapListener; | import org.osmdroid.events.MapListener; | ||||
import org.osmdroid.events.ScrollEvent; | import org.osmdroid.events.ScrollEvent; | ||||
import org.osmdroid.events.ZoomEvent; | import org.osmdroid.events.ZoomEvent; | ||||
import org.osmdroid.tileprovider.tilesource.TileSourceFactory; | import org.osmdroid.tileprovider.tilesource.TileSourceFactory; | ||||
import org.osmdroid.util.BoundingBox; | import org.osmdroid.util.BoundingBox; | ||||
Show All 14 Lines | |||||
public class ActivityMap extends AppCompatActivity { | public class ActivityMap extends AppCompatActivity { | ||||
private static final String TAG = "Busto-MapActivity"; | private static final String TAG = "Busto-MapActivity"; | ||||
private static final String MAP_CURRENT_ZOOM_KEY = "map-current-zoom"; | private static final String MAP_CURRENT_ZOOM_KEY = "map-current-zoom"; | ||||
private static final String MAP_CENTER_LAT_KEY = "map-center-lat"; | private static final String MAP_CENTER_LAT_KEY = "map-center-lat"; | ||||
private static final String MAP_CENTER_LON_KEY = "map-center-lon"; | private static final String MAP_CENTER_LON_KEY = "map-center-lon"; | ||||
private static MapView map = null; | public static final String BUNDLE_LATIT = "lat"; | ||||
public static final String BUNDLE_LONGIT = "lon"; | |||||
public static final String BUNDLE_NAME = "name"; | |||||
public static final String BUNDLE_ID = "ID"; | |||||
private static final double DEFAULT_CENTER_LAT = 45.0708; | |||||
private static final double DEFAULT_CENTER_LON = 7.6858; | |||||
private static final double POSITION_FOUND_ZOOM = 18.6; | |||||
private MapView map = null; | |||||
public Context ctx; | public Context ctx; | ||||
private MyLocationNewOverlay mLocationOverlay = null; | private MyLocationNewOverlay mLocationOverlay = null; | ||||
private FolderOverlay stopsFolderOverlay = null; | private FolderOverlay stopsFolderOverlay = null; | ||||
protected ImageButton btCenterMap; | |||||
protected ImageButton btFollowMe; | |||||
@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB) | @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB) | ||||
@Override public void onCreate(Bundle savedInstanceState) { | @Override public void onCreate(Bundle savedInstanceState) { | ||||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||||
//handle permissions first, before map is created. not depicted here | //handle permissions first, before map is created. not depicted here | ||||
//load/initialize the osmdroid configuration, this can be done | //load/initialize the osmdroid configuration, this can be done | ||||
ctx = getApplicationContext(); | ctx = getApplicationContext(); | ||||
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx)); | Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx)); | ||||
//setting this before the layout is inflated is a good idea | //setting this before the layout is inflated is a good idea | ||||
//it 'should' ensure that the map has a writable location for the map cache, even without permissions | //it 'should' ensure that the map has a writable location for the map cache, even without permissions | ||||
//if no tiles are displayed, you can try overriding the cache path using Configuration.getInstance().setCachePath | //if no tiles are displayed, you can try overriding the cache path using Configuration.getInstance().setCachePath | ||||
//see also StorageUtils | //see also StorageUtils | ||||
//note, the load method also sets the HTTP User Agent to your application's package name, abusing osm's tile servers will get you banned based on this string | //note, the load method also sets the HTTP User Agent to your application's package name, abusing osm's tile servers will get you banned based on this string | ||||
//inflate and create the map | //inflate and create the map | ||||
setContentView(R.layout.activity_map); | setContentView(R.layout.activity_map); | ||||
map = (MapView) findViewById(R.id.map); | map = (MapView) findViewById(R.id.map); | ||||
map.setTileSource(TileSourceFactory.MAPNIK); | map.setTileSource(TileSourceFactory.MAPNIK); | ||||
//map.setTilesScaledToDpi(true); | |||||
map.setFlingEnabled(true); | |||||
// add ability to zoom with 2 fingers | // add ability to zoom with 2 fingers | ||||
map.setMultiTouchControls(true); | map.setMultiTouchControls(true); | ||||
btCenterMap = (ImageButton) findViewById(R.id.ic_center_map); | |||||
btFollowMe = (ImageButton) findViewById(R.id.ic_follow_me); | |||||
//setup FolderOverlay | //setup FolderOverlay | ||||
stopsFolderOverlay = new FolderOverlay(); | stopsFolderOverlay = new FolderOverlay(); | ||||
// take the parameters if it's called from other Activities | // take the parameters if it's called from other Activities | ||||
Bundle b = getIntent().getExtras(); | Bundle b = getIntent().getExtras(); | ||||
GeoPoint marker = null; | |||||
String name = null; | startMap(b, savedInstanceState); | ||||
String ID = null; | |||||
if(b != null) { | |||||
double lat = b.getDouble("lat"); | |||||
double lon = b.getDouble("lon"); | |||||
marker = new GeoPoint(lat, lon); | |||||
name = b.getString("name"); | |||||
ID = b.getString("ID"); | |||||
} | |||||
startMap(marker, name, ID); | |||||
// on drag and zoom reload the markers | // on drag and zoom reload the markers | ||||
map.addMapListener(new DelayedMapListener(new MapListener() { | map.addMapListener(new DelayedMapListener(new MapListener() { | ||||
@Override | @Override | ||||
public boolean onScroll(ScrollEvent paramScrollEvent) { | public boolean onScroll(ScrollEvent paramScrollEvent) { | ||||
loadMarkers(); | loadMarkers(); | ||||
return true; | return true; | ||||
} | } | ||||
@Override | @Override | ||||
public boolean onZoom(ZoomEvent event) { | public boolean onZoom(ZoomEvent event) { | ||||
loadMarkers(); | loadMarkers(); | ||||
return true; | return true; | ||||
} | } | ||||
})); | })); | ||||
btCenterMap.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) { | |||||
Log.i(TAG, "centerMap clicked "); | |||||
final GeoPoint myPosition = mLocationOverlay.getMyLocation(); | |||||
map.getController().animateTo(myPosition); | |||||
} | |||||
}); | |||||
btFollowMe.setOnClickListener(new View.OnClickListener() { | |||||
@Override | |||||
public void onClick(View v) { | |||||
Log.i(TAG, "btFollowMe clicked "); | |||||
if (!mLocationOverlay.isFollowLocationEnabled()) { | |||||
mLocationOverlay.enableFollowLocation(); | |||||
btFollowMe.setImageResource(R.drawable.ic_follow_me_on); | |||||
} else { | |||||
mLocationOverlay.disableFollowLocation(); | |||||
btFollowMe.setImageResource(R.drawable.ic_follow_me); | |||||
} | |||||
} | |||||
}); | |||||
} | } | ||||
public void startMap(GeoPoint marker, String name, String ID) { | public void startMap(Bundle incoming, Bundle savedInstanceState) { | ||||
//parse incoming bundle | |||||
GeoPoint marker = null; | |||||
String name = null; | |||||
String ID = null; | |||||
if(incoming != null) { | |||||
double lat = incoming.getDouble(BUNDLE_LATIT); | |||||
double lon = incoming.getDouble(BUNDLE_LONGIT); | |||||
marker = new GeoPoint(lat, lon); | |||||
name = incoming.getString(BUNDLE_NAME); | |||||
ID = incoming.getString(BUNDLE_ID); | |||||
} | |||||
// move the map on the marker position or on a default view point: Turin, Piazza Castello | // move the map on the marker position or on a default view point: Turin, Piazza Castello | ||||
// and set the start zoom | // and set the start zoom | ||||
IMapController mapController = map.getController(); | IMapController mapController = map.getController(); | ||||
GeoPoint startPoint; | GeoPoint startPoint = null; | ||||
if (marker != null) { | if (marker != null) { | ||||
startPoint = marker; | startPoint = marker; | ||||
mapController.setZoom(20.0); | mapController.setZoom(POSITION_FOUND_ZOOM); | ||||
} | |||||
else if (savedInstanceState != null) { | |||||
mapController.setZoom(savedInstanceState.getDouble(MAP_CURRENT_ZOOM_KEY)); | |||||
mapController.setCenter(new GeoPoint(savedInstanceState.getDouble(MAP_CENTER_LAT_KEY), | |||||
savedInstanceState.getDouble(MAP_CENTER_LON_KEY))); | |||||
} else { | } else { | ||||
startPoint = new GeoPoint(45.0708, 7.6858); | boolean found = false; | ||||
mapController.setZoom(18.0); | LocationManager locationManager = | ||||
(LocationManager) this.getSystemService(Context.LOCATION_SERVICE); | |||||
if(locationManager!=null) { | |||||
Location userLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); | |||||
if (userLocation != null) { | |||||
mapController.setZoom(POSITION_FOUND_ZOOM); | |||||
startPoint = new GeoPoint(userLocation); | |||||
found = true; | |||||
} | |||||
} | |||||
if(!found){ | |||||
startPoint = new GeoPoint(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LON); | |||||
mapController.setZoom(16.0); | |||||
} | } | ||||
} | |||||
// set the minimum zoom level | // set the minimum zoom level | ||||
map.setMinZoomLevel(15.5); | map.setMinZoomLevel(15.0); | ||||
//add contingency check (shouldn't happen..., but) | |||||
if (startPoint != null) { | |||||
mapController.setCenter(startPoint); | mapController.setCenter(startPoint); | ||||
} | |||||
// Location Overlay | // Location Overlay | ||||
// from OpenBikeSharing (THANK GOD) | // from OpenBikeSharing (THANK GOD) | ||||
GpsMyLocationProvider imlp = new GpsMyLocationProvider(this.getBaseContext()); | GpsMyLocationProvider imlp = new GpsMyLocationProvider(this.getBaseContext()); | ||||
imlp.setLocationUpdateMinDistance(200); | imlp.setLocationUpdateMinDistance(10); | ||||
imlp.setLocationUpdateMinTime(30000); | imlp.setLocationUpdateMinTime(2000); | ||||
this.mLocationOverlay = new MyLocationNewOverlay(imlp,map); | this.mLocationOverlay = new MyLocationNewOverlay(imlp,map); | ||||
this.mLocationOverlay.enableMyLocation(); | mLocationOverlay.enableMyLocation(); | ||||
mLocationOverlay.enableFollowLocation(); | |||||
mLocationOverlay.setOptionsMenuEnabled(true); | |||||
/* | |||||
mLocationOverlay.runOnFirstFix(() -> { | |||||
mapController.setCenter(mLocationOverlay.getMyLocation()); | |||||
mapController.animateTo(mLocationOverlay.getMyLocation()); | |||||
}); | |||||
*/ | |||||
map.getOverlays().add(this.mLocationOverlay); | map.getOverlays().add(this.mLocationOverlay); | ||||
//add stops overlay | //add stops overlay | ||||
map.getOverlays().add(this.stopsFolderOverlay); | map.getOverlays().add(this.stopsFolderOverlay); | ||||
loadMarkers(); | loadMarkers(); | ||||
if (marker != null) { | if (marker != null) { | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | public void loadMarkers() { | ||||
for (Stop stop : stops) { | for (Stop stop : stops) { | ||||
GeoPoint marker = new GeoPoint(stop.getLatitude(), stop.getLongitude()); | GeoPoint marker = new GeoPoint(stop.getLatitude(), stop.getLongitude()); | ||||
Marker stopMarker = makeMarker(marker, stop.getStopDefaultName(), stop.ID, false); | Marker stopMarker = makeMarker(marker, stop.getStopDefaultName(), stop.ID, false); | ||||
stopsFolderOverlay.add(stopMarker); | stopsFolderOverlay.add(stopMarker); | ||||
} | } | ||||
} | } | ||||
protected boolean detachMapFromPosition(){ | |||||
if (mLocationOverlay.isFollowLocationEnabled()) { | |||||
mLocationOverlay.disableFollowLocation(); | |||||
btFollowMe.setImageResource(R.drawable.ic_follow_me); | |||||
return true; | |||||
} return false; | |||||
} | |||||
public void onResume(){ | public void onResume(){ | ||||
super.onResume(); | super.onResume(); | ||||
//this will refresh the osmdroid configuration on resuming. | //this will refresh the osmdroid configuration on resuming. | ||||
//if you make changes to the configuration, use | //if you make changes to the configuration, use | ||||
//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); | //SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); | ||||
//Configuration.getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this)); | //Configuration.getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this)); | ||||
map.onResume(); //needed for compass, my location overlays, v6.0.0 and up | map.onResume(); //needed for compass, my location overlays, v6.0.0 and up | ||||
mLocationOverlay.enableMyLocation(); | mLocationOverlay.enableMyLocation(); | ||||
} | } | ||||
public void onPause(){ | public void onPause(){ | ||||
super.onPause(); | super.onPause(); | ||||
//this will refresh the osmdroid configuration on resuming. | //this will refresh the osmdroid configuration on resuming. | ||||
//if you make changes to the configuration, use | //if you make changes to the configuration, use | ||||
//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); | //SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); | ||||
//Configuration.getInstance().save(this, prefs); | //Configuration.getInstance().save(this, prefs); | ||||
map.onPause(); //needed for compass, my location overlays, v6.0.0 and up | map.onPause(); //needed for compass, my location overlays, v6.0.0 and up | ||||
mLocationOverlay.disableMyLocation(); | mLocationOverlay.disableMyLocation(); | ||||
} | } | ||||
@Override | |||||
protected void onSaveInstanceState(Bundle outState) { | |||||
super.onSaveInstanceState(outState); | |||||
outState.putDouble(MAP_CURRENT_ZOOM_KEY, map.getZoomLevelDouble()); | |||||
outState.putDouble(MAP_CENTER_LAT_KEY, map.getMapCenter().getLatitude()); | |||||
outState.putDouble(MAP_CENTER_LON_KEY, map.getMapCenter().getLongitude()); | |||||
} | |||||
} | } | ||||
No newline at end of file | No newline at end of file |
Public contents are in Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA) or GNU Free Documentation License (at your option) unless otherwise noted. · Contact / Register