package net.mvla.mvhs.map;
import android.Manifest;
import android.animation.ObjectAnimator;
import android.app.Dialog;
import android.app.FragmentManager;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Point;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.GroundOverlayOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import net.mvla.mvhs.BuildConfig;
import net.mvla.mvhs.R;
import net.mvla.mvhs.Utils;
import net.mvla.mvhs.ui.DrawerActivity;
import net.mvla.mvhs.widget.SearchView;
import org.json.JSONException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import rx.Single;
import rx.SingleSubscriber;
public class MapActivity extends DrawerActivity {
public static final String STATE_MAP_MODE = "mapMode";
public static final String FRAGMENT_LIST = "List";
private static final int REQUEST_LOCATION = 42;
private boolean mDebugMode;
private boolean mListShowing;
private boolean mChoosingStart;
private boolean mChoosingDestination;
private LatLng mStartingLocation;
private boolean mNavigating;
private Marker mDestinationMarker;
private List<Polyline> mNavPathPolylines;
private int mNavPathStep;
private List<String> mNavTexts;
private Map<LocationNode, Marker> mMarkers;
private SearchView mSearchView;
private DownloadInfoTask mTask;
private FloatingActionButton mNavSelectionFab;
private View mNavigationSelectionAppBar;
private Button mStartingLocationButton;
private Toolbar mNavToolbar;
private FloatingActionButton mMyLocFab;
private boolean mNeedEnableLocation;
private LatLngBounds mapBounds;
@Override
protected int getSelfNavDrawerItem() {
return R.id.nav_map;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_MAP_MODE, !mListShowing);
}
private void showNav() {
final View listFrame = findViewById(R.id.navigation_appbar);
ObjectAnimator animator = new ObjectAnimator();
animator.setProperty(View.TRANSLATION_Y);
animator.setFloatValues(0f);
animator.setTarget(listFrame);
animator.setDuration(250);
animator.setInterpolator(new LinearOutSlowInInterpolator());
animator.start();
}
private void hideNav() {
final View listFrame = findViewById(R.id.navigation_appbar);
ObjectAnimator animator = new ObjectAnimator();
animator.setProperty(View.TRANSLATION_Y);
animator.setFloatValues(-listFrame.getMeasuredHeight());
animator.setTarget(listFrame);
animator.setDuration(250);
animator.setInterpolator(new FastOutLinearInInterpolator());
animator.start();
}
private void showSelection() {
final View listFrame = findViewById(R.id.navigation_selection_appbar);
ObjectAnimator animator = new ObjectAnimator();
animator.setProperty(View.TRANSLATION_Y);
animator.setFloatValues(0f);
animator.setTarget(listFrame);
animator.setDuration(250);
animator.setInterpolator(new LinearOutSlowInInterpolator());
animator.start();
}
private void hideSelection() {
final View listFrame = findViewById(R.id.navigation_selection_appbar);
ObjectAnimator animator = new ObjectAnimator();
animator.setProperty(View.TRANSLATION_Y);
animator.setFloatValues(-listFrame.getMeasuredHeight());
animator.setTarget(listFrame);
animator.setDuration(250);
animator.setInterpolator(new FastOutLinearInInterpolator());
animator.start();
}
private void showList(int listMarginTop) {
final FrameLayout listFrame = (FrameLayout) findViewById(R.id.activity_map_list_fragment_container);
ObjectAnimator animator = new ObjectAnimator();
animator.setProperty(View.Y);
animator.setFloatValues(Utils.convertDpToPx(this, listMarginTop));
animator.setTarget(listFrame);
animator.setDuration(250);
animator.setInterpolator(new LinearOutSlowInInterpolator());
animator.start();
ObjectAnimator animator2 = new ObjectAnimator();
animator2.setProperty(View.ALPHA);
animator2.setFloatValues(1f);
animator2.setTarget(findViewById(R.id.activity_map_searchbox_background));
animator2.setDuration(250);
animator2.setInterpolator(new LinearOutSlowInInterpolator());
animator2.start();
listFrame.setPadding(0, 0, 0, Utils.convertDpToPx(this, listMarginTop));
mListShowing = true;
mSearchView.setDrawerIconState(false, true);
}
private void hideList() {
final FrameLayout layout = (FrameLayout) findViewById(R.id.activity_map_list_fragment_container);
ObjectAnimator animator = new ObjectAnimator();
animator.setProperty(View.Y);
animator.setTarget(layout);
animator.setFloatValues(layout.getMeasuredHeight());
animator.setDuration(250);
animator.setInterpolator(new FastOutLinearInInterpolator());
animator.start();
ObjectAnimator animator2 = new ObjectAnimator();
animator2.setProperty(View.ALPHA);
animator2.setFloatValues(0f);
animator2.setTarget(findViewById(R.id.activity_map_searchbox_background));
animator2.setDuration(250);
animator2.setInterpolator(new LinearOutSlowInInterpolator());
animator2.start();
mListShowing = false;
mSearchView.setDrawerIconState(true, true);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode != REQUEST_LOCATION ||
(permissions.length == 1 &&
permissions[0].equals(Manifest.permission.ACCESS_FINE_LOCATION) &&
grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
getMap().subscribe(this::onLocationPermissionGranted);
} else {
// Permission was denied. Display an error message.
new MaterialDialog.Builder(this)
.title(R.string.permission_needed)
.content(R.string.permission_denied_desc)
.cancelable(false)
.positiveText(android.R.string.ok)
.dismissListener(materialDialog -> onLocationPermissionDenied())
.show();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
mapBounds = new LatLngBounds(new LatLng(37.358832, -122.068615),
new LatLng(37.361553, -122.065151));
if (savedInstanceState == null) {
mListShowing = false;
downloadMapData();
} else {
mListShowing = !savedInstanceState.getBoolean(STATE_MAP_MODE);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an expanation to the user
new MaterialDialog.Builder(this)
.title(R.string.permission_needed)
.content(R.string.permission_needed_desc)
.cancelable(false)
.positiveText(android.R.string.ok)
.onPositive((materialDialog, dialogAction) -> requestLocationPermission())
.show();
} else {
// No explanation needed, we can request the permission.
requestLocationPermission();
}
} else {
mNeedEnableLocation = true;
}
//ADD MAP AND LIST FRAGMENTS
FragmentManager manager = getFragmentManager();
MapFragment mapFragment = (MapFragment) manager.findFragmentById(R.id.activity_map_fragment_container);
boolean initCamera = false;
if (mapFragment == null) {
mapFragment = MapFragment.newInstance();
manager.beginTransaction().add(R.id.activity_map_fragment_container, mapFragment).commit();
initCamera = true;
}
initMap(mapFragment, initCamera);
MapListFragment listFragment = (MapListFragment) manager.findFragmentByTag(FRAGMENT_LIST);
if (listFragment == null) {
listFragment = new MapListFragment();
manager.beginTransaction()
.add(R.id.activity_map_list_fragment_container, listFragment, FRAGMENT_LIST)
.commit();
}
CheckBox debug = (CheckBox) findViewById(R.id.activity_map_checkbox_debug);
debug.setOnCheckedChangeListener((buttonView, isChecked) -> {
mDebugMode = isChecked;
MapFragment mapFragmentInstance = (MapFragment) getFragmentManager().findFragmentById(R.id.activity_map_fragment_container);
mapFragmentInstance.getMapAsync(this::updateMapOverlays);
});
debug.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE);
LinearLayout openListBar = (LinearLayout) findViewById(R.id.activity_map_showlist_linearlayout);
openListBar.setOnClickListener(v -> {
showList(80);
((MapListFragment) getFragmentManager().findFragmentByTag(FRAGMENT_LIST)).updateDataAndSearch("");
});
mSearchView = (SearchView) findViewById(R.id.activity_map_searchbox);
mSearchView.setCallback(new SearchView.SearchViewCallback() {
@Override
public void onQueryTextChange(String newText) {
((MapListFragment) getFragmentManager().findFragmentByTag(FRAGMENT_LIST))
.updateDataAndSearch(newText);
}
@Override
public void onFocusChange(boolean focused) {
if (focused) {
showList(80);
}
}
@Override
public void onDrawerIconClicked() {
if (mChoosingDestination || mChoosingStart || mListShowing) {
onBackPressed();
mSearchView.clearFocus();
mSearchView.clearText();
} else {
openDrawer();
}
}
});
mSearchView.setDrawerIconState(true, false);
mNavigationSelectionAppBar = findViewById(R.id.navigation_selection_appbar);
mStartingLocationButton = (Button) findViewById(R.id.navigation_appbar_startingloc_button);
mStartingLocationButton.setOnClickListener(v -> enterChoosingStart());
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mNavigationSelectionAppBar.getLayoutParams();
params.height += getStatusBarHeight();
mNavigationSelectionAppBar.setLayoutParams(params);
Toolbar navSelection = (Toolbar) findViewById(R.id.navigation_selection_toolbar);
navSelection.setNavigationIcon(R.drawable.ic_arrow_back_black_24dp);
navSelection.setNavigationOnClickListener(v -> exitChoosingDestination());
mNavSelectionFab = (FloatingActionButton) findViewById(R.id.activity_map_nav_fab);
mNavSelectionFab.setOnClickListener(v -> {
if (!mNavigating) {
enterChoosingDestination();
} else {
//nav step = how many lines travelled
if (mNavPathStep < mNavPathPolylines.size()) {
//nav step = how many lines travelled-1
mNavPathPolylines.get(mNavPathStep).setColor(Color.argb(255, 255, 255, 0));
mNavToolbar.setTitle(mNavTexts.get(mNavPathStep));
mNavPathStep++;
} else {
mNavPathStep = 0;
mNavToolbar.setTitle(mNavTexts.get(0));
for (Polyline p : mNavPathPolylines) {
if (p != null) {
p.setColor(Color.argb(127, 255, 255, 0));
}
}
mNavPathStep++;
}
}
});
mNavSelectionFab.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.primary)));
mMyLocFab = (FloatingActionButton) findViewById(R.id.activity_map_my_loc_fab);
mMyLocFab.setBackgroundTintList(ColorStateList.valueOf(Color.WHITE));
mMyLocFab.setOnClickListener(v -> {
getMap().subscribe(map -> {
Location myLocation = map.getMyLocation();
if (myLocation != null) {
LatLng latLng = new LatLng(myLocation.getLatitude(), myLocation.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLng(latLng);
map.animateCamera(cameraUpdate);
}
});
});
mNavToolbar = (Toolbar) findViewById(R.id.navigation_toolbar);
mNavToolbar.setNavigationIcon(R.drawable.ic_close_black_24dp);
mNavToolbar.setNavigationOnClickListener(v -> onBackPressed());
ViewGroup.MarginLayoutParams params2 = (ViewGroup.MarginLayoutParams) mNavToolbar.getLayoutParams();
params2.topMargin = getStatusBarHeight();
mNavToolbar.setLayoutParams(params2);
//RESTORE MAP MODE AND STUFF
if (mListShowing) {
showList(80);
((MapListFragment) getFragmentManager().findFragmentByTag(FRAGMENT_LIST)).updateDataAndSearch("");
} else {
Utils.addOnGlobalLayoutListener(findViewById(R.id.activity_map_list_fragment_container), () -> {
final FrameLayout listFragmentFrame = (FrameLayout) findViewById(R.id.activity_map_list_fragment_container);
listFragmentFrame.setTranslationY(listFragmentFrame.getMeasuredHeight());
});
mSearchView.setDrawerIconState(true, true);
}
Utils.addOnGlobalLayoutListener(mNavigationSelectionAppBar, () -> {
mNavigationSelectionAppBar.setTranslationY(-mNavigationSelectionAppBar.getMeasuredHeight());
final View listFragment1 = findViewById(R.id.navigation_appbar);
listFragment1.setTranslationY(-listFragment1.getMeasuredHeight());
});
mMarkers = new HashMap<>();
}
private void onLocationPermissionGranted(GoogleMap map) {
//Permission granted
map.setMyLocationEnabled(true);
mMyLocFab.setVisibility(View.VISIBLE);
}
private void onLocationPermissionDenied() {
mMyLocFab.setVisibility(View.GONE);
}
private void requestLocationPermission() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
}
private void enterChoosingStart() {
mStartingLocation = null;
mSearchView.clearText();
hideSelection();
mChoosingDestination = false;
mChoosingStart = true;
showList(80);
}
private void exitChoosingDestination() {
hideSelection();
hideList();
mChoosingDestination = false;
}
private void enterChoosingDestination() {
mChoosingStart = false;
mSearchView.clearFocus();
mSearchView.clearText();
showSelection();
mChoosingDestination = true;
showList(176);
}
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
private void initMap(MapFragment map, final boolean initCamera) {
final MapFragment finalMap = map;
Utils.addOnGlobalLayoutListener(findViewById(R.id.activity_map_fragment_container), () ->
finalMap.getMapAsync(googleMap -> MapActivity.this.onMapReady(googleMap, initCamera)));
}
private void onMapReady(final GoogleMap googleMap, boolean initCamera) {
if (mNeedEnableLocation) {
onLocationPermissionGranted(googleMap);
mNeedEnableLocation = false;
}
googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
googleMap.getUiSettings().setMapToolbarEnabled(false);
googleMap.getUiSettings().setMyLocationButtonEnabled(false);
googleMap.getUiSettings().setRotateGesturesEnabled(false);
googleMap.getUiSettings().setCompassEnabled(false);
googleMap.getUiSettings().setTiltGesturesEnabled(false);
googleMap.setPadding(0, getResources().getDimensionPixelSize(R.dimen.map_padding_top), 0, 0);
if (initCamera) {
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(
mapBounds, Utils.convertDpToPx(MapActivity.this, 8)));
}
LatLngBounds cameraBounds = new LatLngBounds(
new LatLng(37.359568, -122.068124), new LatLng(37.361009, -122.065455));
googleMap.setLatLngBoundsForCameraTarget(cameraBounds);
googleMap.setMinZoomPreference(17);
googleMap.setOnMarkerClickListener(marker -> {
MapActivity.this.onMarkerClick(marker);
return false;
});
googleMap.setOnMapClickListener(latLng -> {
Point clickedPoint = googleMap.getProjection().toScreenLocation(latLng);
if (!mDebugMode && !mMarkers.isEmpty()) {
for (Marker marker : mMarkers.values()) {
marker.hideInfoWindow();
marker.remove();
}
mMarkers.clear();
} else {
for (LocationNode node : MapData.locationNodeMap.values()) {
Point nodePoint = googleMap.getProjection().toScreenLocation(node.latLng);
int dx = clickedPoint.x - nodePoint.x;
int dy = clickedPoint.y - nodePoint.y;
if (Utils.convertDpToPx(MapActivity.this, 24) >= Math.sqrt(dx * dx + dy * dy)) {
Marker marker = createMarker(googleMap, node);
marker.showInfoWindow();
break;
}
}
}
});
googleMap.setOnInfoWindowClickListener(marker ->
MapActivity.this.startNavigation(marker, googleMap));
googleMap.setOnCameraMoveListener(() -> {
if (mNavigating) {
for (Polyline line : mNavPathPolylines) {
if (line != null) {
line.setWidth((googleMap.getCameraPosition().zoom - 14.7f) * 6f);
}
}
}
});
}
private Marker createMarker(GoogleMap googleMap, LocationNode node) {
MarkerOptions options = new MarkerOptions().position(new LatLng(node.latLng.latitude, node.latLng.longitude))
.title(node.getName())
.snippet(getString(R.string.press_for_navigation));
Marker marker = googleMap.addMarker(options);
mMarkers.put(node, marker);
return marker;
}
public void onMapListItemClicked(LocationNode node) {
if (mChoosingStart) {
onBackPressed();
mStartingLocationButton.setText(node.getName());
mStartingLocation = node.latLng;
return;
}
getMap().subscribe(map -> {
Marker marker = mMarkers.get(node);
if (marker == null) {
marker = createMarker(map, node);
}
if (mChoosingDestination) {
onBackPressed();
startNavigation(marker, map);
} else {
if (mListShowing) {
hideList();
}
mSearchView.clearFocus();
marker.showInfoWindow();
map.animateCamera(CameraUpdateFactory.newLatLng(marker.getPosition()));
}
});
}
private void startNavigation(Marker marker, GoogleMap googleMap) {
Node startPlace;
if (mStartingLocation == null) {
Location myLocation = googleMap.getMyLocation();
if (myLocation == null) {
Toast.makeText(MapActivity.this,
"Your location cannot be obtained",
Toast.LENGTH_LONG).show();
enterChoosingDestination();
return;
}
double myLat = myLocation.getLatitude();
double myLong = myLocation.getLongitude();
startPlace = new Node(myLat, myLong);
} else {
startPlace = MapData.locationNodeMap.get(mStartingLocation);
}
clearNav();
if (!MapData.onCampus(startPlace)) {
Toast.makeText(MapActivity.this,
R.string.not_on_campus,
Toast.LENGTH_LONG).show();
enterChoosingDestination();
return;
}
Node closestPathNode = null;
double closestDistance = -1;
List<Node> nodes = new ArrayList<>(MapData.pathNodeMap.values());
nodes.addAll(MapData.locationNodeMap.values());
for (Node node : nodes) {
double distance = Node.distance(node, startPlace);
if (closestDistance == -1 || distance < closestDistance) {
closestDistance = distance;
closestPathNode = node;
}
}
if (closestPathNode == null) {
Toast.makeText(MapActivity.this, "Error: closest path node null", Toast.LENGTH_SHORT);
return;
}
List<Node> navPath = MapData.findPath(closestPathNode.latLng, marker.getPosition());
if (navPath == null) {
Toast.makeText(MapActivity.this, "Error: path not found", Toast.LENGTH_SHORT).show();
return;
}
navPath.add(0, startPlace);
if (mDebugMode) {
updateMapOverlays(googleMap);
}
int totalDistance = 0;
mNavPathPolylines = new ArrayList<>();
for (int i = 1; i < navPath.size(); ) {
Node n = navPath.get(i - 1);
int index = i;
while (index < navPath.size() - 1) {
int test = index + 1;
if (!MapData.nodesLiesOnOnePath(navPath.subList(i - 1, test + 1))) {
break;
}
Log.e("Nav Succeeded", navPath.subList(i - 1, test + 1).toString());
index = test;
}
Polyline polyline = googleMap.addPolyline(
new PolylineOptions()
.add(n.latLng, navPath.get(index).latLng)
.color(Color.argb(255, 255, 255, 0))
.width((googleMap.getCameraPosition().zoom - 14.7f) * 6f)
.zIndex(1000)
);
float[] results = new float[3];
Location.distanceBetween(n.latLng.latitude, n.latLng.longitude,
navPath.get(index).latLng.latitude, navPath.get(index).latLng.longitude, results);
totalDistance += results[0];
mNavPathPolylines.add(polyline);
i += index - i + 1;
}
mNavPathPolylines.add(0, null);
mNavPathStep = mNavPathPolylines.size();
mNavTexts = new ArrayList<>();
double bearingPrevious = 0;
for (int i = 1; i < mNavPathPolylines.size(); i++) {
List<LatLng> latLngs = mNavPathPolylines.get(i).getPoints();
LatLng n = latLngs.get(0);
LatLng n2 = latLngs.get(1);
double bearing = Utils.bearing(n.latitude, n.longitude, n2.latitude, n2.longitude);
Log.e("NavCalc", "Bearing " + bearing + " for points " + n + ", " + n2);
String nav = null;
if (i == 1) {
if (bearing < 45 || bearing >= 315) {
nav = getString(R.string.north);
} else if (bearing < 135) {
nav = getString(R.string.east);
} else if (bearing < 225) {
nav = getString(R.string.south);
} else if (bearing < 315) {
nav = getString(R.string.west);
}
} else {
double difference = bearing - bearingPrevious;
difference = (difference + 360) % 360;
if (difference < 45 || difference >= 315) {
nav = getString(R.string.forward);
} else if (difference < 135) {
nav = getString(R.string.right);
} else if (difference < 225) {
nav = getString(R.string.around);
} else if (difference < 315) {
nav = getString(R.string.left);
}
}
bearingPrevious = bearing;
mNavTexts.add(nav);
}
LocationNode endLocationNode = (LocationNode) navPath.get(navPath.size() - 1);
mNavTexts.add(getString(R.string.arrived_at) + endLocationNode.getName());
LatLngBounds bounds = new LatLngBounds.Builder().include(startPlace.latLng).include(marker.getPosition()).build();
getMap().subscribe(map -> {
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, Utils.convertDpToPx(this, 128)));
});
mNavigating = true;
marker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW));
mDestinationMarker = marker;
showNav();
mNavSelectionFab.setImageResource(R.drawable.ic_chevron_right_black_24dp);
if (startPlace instanceof LocationNode) {
mNavToolbar.setTitle(String.format(getString(R.string.path_to), ((LocationNode) startPlace).getName(), endLocationNode.getName()));
} else {
mNavToolbar.setTitle(String.format(getString(R.string.path_to), "your location", endLocationNode.getName()));
}
mNavToolbar.setSubtitle(String.format(getString(R.string.total), totalDistance * 3.28084, totalDistance * 0.001 / 5 * 60));
Toast.makeText(this, getString(R.string.proceed), Toast.LENGTH_SHORT).show();
}
private boolean onMarkerClick(Marker marker) {
Node node = MapData.pathNodeMap.get(marker.getPosition());
if (node == null) {
return true;
}
String snippet = node.toString() + "\nConnected:";
for (Node n2 : node.getConnected()) {
snippet += "\n" + n2;
}
snippet += "\n" + node.getG();
Toast.makeText(MapActivity.this,
snippet,
Toast.LENGTH_SHORT).show();
return false;
}
@Override
public void onBackPressed() {
if (mNavigating) {
clearNav();
} else if (mChoosingDestination) {
exitChoosingDestination();
} else if (mChoosingStart) {
enterChoosingDestination();
} else if (!mListShowing) {
super.onBackPressed();
} else {
hideList();
}
}
private void clearNav() {
mNavigating = false;
mStartingLocation = null;
mStartingLocationButton.setText(R.string.your_location);
hideNav();
mNavSelectionFab.setImageResource(R.drawable.ic_directions_black_24dp);
if (mDestinationMarker != null) {
mDestinationMarker.remove();
mDestinationMarker = null;
}
MapData.cleanTempNodes();
if (mNavPathPolylines != null) {
for (Polyline line : mNavPathPolylines) {
if (line != null) {
line.remove();
}
}
mNavPathPolylines = null;
}
if (mDebugMode) {
getMap().subscribe(this::updateMapOverlays);
}
}
private Single<GoogleMap> getMap() {
return Single.create(new Single.OnSubscribe<GoogleMap>() {
@Override
public void call(SingleSubscriber<? super GoogleMap> singleSubscriber) {
((MapFragment) getFragmentManager().findFragmentById(R.id.activity_map_fragment_container))
.getMapAsync(singleSubscriber::onSuccess);
}
});
}
private void updateMapOverlays(GoogleMap googleMap) {
if (googleMap == null) {
return;
}
googleMap.clear();
GroundOverlayOptions schoolMap = new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.map))
.transparency(0.1f)
.positionFromBounds(mapBounds);
googleMap.addGroundOverlay(schoolMap);
if (mNavPathPolylines != null) {
List<Polyline> newPolylines = new ArrayList<>();
for (Polyline p : mNavPathPolylines) {
if (p != null) {
Polyline polyline = googleMap.addPolyline(new PolylineOptions()
.addAll(p.getPoints())
.color(Color.argb(255, 255, 255, 0))
.zIndex(1000)
.width((googleMap.getCameraPosition().zoom - 14.7f) * 6f));
newPolylines.add(polyline);
}
}
mNavPathPolylines = newPolylines;
mNavPathStep = mNavPathPolylines.size();
}
if (mDebugMode) {
for (LocationNode node : MapData.locationNodeMap.values()) {
MarkerOptions options = new MarkerOptions().position(new LatLng(node.latLng.latitude, node.latLng.longitude))
.title(node.getName())
.snippet("Press for navigation");
mMarkers.put(node, googleMap.addMarker(options));
}
Set<TwoNodes> addedNodeMap = new HashSet<>();
for (Node n : MapData.pathNodeMap.values()) {
for (Node connected : n.getConnected()) {
TwoNodes path = new TwoNodes(n, connected);
if (!addedNodeMap.contains(path)) {
addedNodeMap.add(path);
googleMap.addPolyline(new PolylineOptions()
.add(new LatLng(n.latLng.latitude, n.latLng.longitude),
new LatLng(connected.latLng.latitude, connected.latLng.longitude))
.color(Color.WHITE)
.width(20));
}
}
MarkerOptions options = new MarkerOptions();
options.position(new LatLng(n.latLng.latitude, n.latLng.longitude));
googleMap.addMarker(options);
}
}
}
private void downloadMapData() {
if (mTask == null || mTask.getStatus() != AsyncTask.Status.RUNNING) {
/*ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {*/
mTask = new DownloadInfoTask();
mTask.execute("http://pluscubed.github.io/mvhs-map-data/production-mapdata.json");
/*} else {
new MaterialDialog.Builder(this)
.content("Not connected to the Internet.")
.positiveText("Dismiss")
.negativeText("Retry")
.callback(new MaterialDialog.ButtonCallback() {
@Override
public void onNegative(MaterialDialog dialog) {
super.onNegative(dialog);
downloadMapData();
}
})
.showSelection();
}*/
}
}
private class DownloadInfoTask extends AsyncTask<String, Void, Void> {
private Dialog mLoadingDialog;
@Override
protected void onPreExecute() {
mLoadingDialog = new MaterialDialog.Builder(MapActivity.this)
.title(R.string.loading)
.cancelable(false)
.progress(true, 0)
.show();
}
@Override
protected Void doInBackground(String... urls) {
String thing = null;
InputStream stream = null;
try {
// Instantiate the parser
/*URL url = new URL(urls[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
// Starts the query
conn.connect();
Log.e("", "Connection opened");
stream = conn.getInputStream();*/
stream = getAssets().open("production-mapdata.json");
// Makes sure that the InputStream is closed after the app is
// finished using it.
BufferedReader streamReader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
StringBuilder responseStrBuilder = new StringBuilder();
String inputStr;
while ((inputStr = streamReader.readLine()) != null)
responseStrBuilder.append(inputStr);
thing = responseStrBuilder.toString();
} catch (IOException e) {
e.printStackTrace();
//return getResources().getString(R.string.connection_error);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (thing != null) {
try {
MapData.init(thing);
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(Void voids) {
mLoadingDialog.dismiss();
getMap().subscribe(MapActivity.this::updateMapOverlays);
}
}
}