Neshoz

Untitled

Feb 18th, 2017
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 23.68 KB | None | 0 0
  1. package se.malmo.lighthouse.siberianhusky;
  2.  
  3. import android.Manifest;
  4. import android.app.FragmentManager;
  5. import android.content.DialogInterface;
  6. import android.content.pm.PackageManager;
  7. import android.graphics.Color;
  8. import android.location.Location;
  9. import android.location.LocationManager;
  10. import android.os.Build;
  11. import android.os.Bundle;
  12. import android.support.v4.app.ActivityCompat;
  13. import android.support.v4.content.ContextCompat;
  14. import android.support.v7.app.AlertDialog;
  15. import android.support.v7.widget.CardView;
  16. import android.view.View;
  17. import android.view.ViewGroup;
  18. import android.widget.AdapterView;
  19. import android.widget.ArrayAdapter;
  20. import android.widget.Spinner;
  21. import android.widget.TextView;
  22. import android.widget.Toast;
  23.  
  24. import com.directions.route.AbstractRouting;
  25. import com.directions.route.Route;
  26. import com.directions.route.RouteException;
  27. import com.directions.route.Routing;
  28. import com.directions.route.RoutingListener;
  29. import com.google.android.gms.common.ConnectionResult;
  30. import com.google.android.gms.common.api.GoogleApiClient;
  31. import com.google.android.gms.common.api.Status;
  32. import com.google.android.gms.location.LocationListener;
  33. import com.google.android.gms.location.LocationServices;
  34. import com.google.android.gms.location.places.Place;
  35. import com.google.android.gms.location.places.ui.PlaceAutocompleteFragment;
  36. import com.google.android.gms.location.places.ui.PlaceSelectionListener;
  37. import com.google.android.gms.maps.GoogleMap;
  38. import com.google.android.gms.maps.OnMapReadyCallback;
  39. import com.google.android.gms.maps.SupportMapFragment;
  40. import com.google.android.gms.maps.model.BitmapDescriptorFactory;
  41. import com.google.android.gms.maps.model.LatLng;
  42. import com.google.android.gms.maps.model.Marker;
  43. import com.google.android.gms.maps.model.MarkerOptions;
  44. import com.google.android.gms.maps.model.Polyline;
  45. import com.google.android.gms.maps.model.PolylineOptions;
  46. import com.google.maps.android.SphericalUtil;
  47.  
  48. import java.util.ArrayList;
  49. import java.util.List;
  50.  
  51. import se.malmo.lighthouse.siberianhusky.models.CustomDialogInterface;
  52. import se.malmo.lighthouse.siberianhusky.models.MapLocationDrawer;
  53. import se.malmo.lighthouse.siberianhusky.models.RouteCoordinate;
  54. import se.malmo.lighthouse.siberianhusky.models.RouteNameFragment;
  55. import se.malmo.lighthouse.siberianhusky.models.TravelMethodsFragment;
  56. import se.malmo.lighthouse.siberianhusky.repositories.DataBaseFetcher;
  57.  
  58. public class CreateNewRouteActivity extends ToolbarMenu implements OnMapReadyCallback,
  59.         GoogleApiClient.ConnectionCallbacks,
  60.         GoogleApiClient.OnConnectionFailedListener,
  61.         LocationListener,
  62.         RoutingListener,
  63.         GoogleMap.OnInfoWindowClickListener,
  64.         CustomDialogInterface{
  65.  
  66.     private GoogleMap mMap;
  67.     private GoogleApiClient googleApiClient;
  68.     private DataBaseFetcher dataFetcher;
  69.     private Object selectedSpinnerItem;
  70.  
  71.     private Location currentLocation;
  72.     private MapLocationDrawer mapLocationDrawer;
  73.     private Marker myLocationMarker;
  74.     private Marker originMarker;
  75.     private Marker destinationMarker;
  76.     private final int REQUEST_LOCATION_PERMISSION = 1;
  77.     private LatLng origin;
  78.     private LatLng destination;
  79.  
  80.     private CardView travelLocationsCard;
  81.     private Spinner selectionSpinner;
  82.  
  83.     private List<LatLng> coordinates;
  84.     private List<Polyline> polylines;
  85.     private List<LatLng> markerPositions;
  86.     private String travelMethod;
  87.     private List<LatLng> routeCoordinates;
  88.  
  89.     private String from = "";
  90.     private String to = "";
  91.  
  92.     private TravelMethodsFragment travelMethodsFragment;
  93.     private RouteNameFragment routeNameFragment;
  94.     private AlertDialog.Builder builder;
  95.  
  96.     private se.malmo.lighthouse.siberianhusky.models.Route route;
  97.  
  98.     private PlaceAutocompleteFragment autoCompleteStartFragment;
  99.  
  100.     @Override
  101.     protected void onCreate(Bundle savedInstanceState) {
  102.         super.onCreate(savedInstanceState);
  103.         setContentView(R.layout.create_new_route_activity);
  104.  
  105.         /**
  106.          * Realm
  107.          */
  108.         dataFetcher = new DataBaseFetcher(this);
  109.  
  110.         /**
  111.          * Create a route object which we manipulate and later save when user is done
  112.          */
  113.         route = new se.malmo.lighthouse.siberianhusky.models.Route();
  114.         int checkNrOfRoutes = dataFetcher.getAllSavedRoutes().size();
  115.  
  116.         route.setRouteID(checkNrOfRoutes + 1);
  117.  
  118.         /**
  119.          * Origin search location
  120.          */
  121.         autoCompleteStartFragment = (PlaceAutocompleteFragment)
  122.                 getFragmentManager().findFragmentById(R.id.create_new_route_startDestination_autoComplete);
  123.         autoCompleteStartFragment.setHint("Origin");
  124.  
  125.         /**
  126.          * Destination search location
  127.          */
  128.         final PlaceAutocompleteFragment autocompleteEndFragment = (PlaceAutocompleteFragment)
  129.                 getFragmentManager().findFragmentById(R.id.create_new_route_endDestination_autoComplete);
  130.         autocompleteEndFragment.setHint("Destination");
  131.  
  132.         /**
  133.          * Map
  134.          */
  135.         final SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
  136.                 .findFragmentById(R.id.create_new_route_map);
  137.         mapFragment.getMapAsync(this);
  138.  
  139.         /**
  140.          * CardViews
  141.          */
  142.         travelLocationsCard = (CardView) findViewById(R.id.select_travel_locations_card);
  143.         travelLocationsCard.setVisibility(View.GONE);
  144.  
  145.         /**
  146.          * Spinner and Adapter
  147.          */
  148.         final List<String> selections = new ArrayList<>();
  149.         selections.add("No selection");
  150.         selections.add("Change Travel Method");
  151.         selections.add("Change Locations");
  152.         selectionSpinner = (Spinner) findViewById(R.id.create_new_route_switch_selections);
  153.         /**
  154.          * Since spinners are not designed to perform a bunch of logic when you actually use them, I had to override the view of my adapter, hiding the first value since it's empty because of the spinners initial
  155.          * load selection function.
  156.          */
  157.         ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, selections) {
  158.             @Override
  159.             public View getDropDownView(int position, View convertView, ViewGroup parent) {
  160.                 View view;
  161.                 if (position == 0) {
  162.                     TextView textView = new TextView(getContext());
  163.                     textView.setHeight(0);
  164.                     textView.setVisibility(View.GONE);
  165.                     view = textView;
  166.                 } else {
  167.                     view = super.getDropDownView(position, null, parent);
  168.                 }
  169.                 return view;
  170.             }
  171.         };
  172.  
  173.         spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
  174.         selectionSpinner.setAdapter(spinnerAdapter);
  175.  
  176.         /**
  177.          * DialogFragment in which we select travel methods
  178.          */
  179.         travelMethodsFragment = new TravelMethodsFragment(this);
  180.  
  181.         /**
  182.          * Route name fragment
  183.          */
  184.         routeNameFragment = new RouteNameFragment();
  185.  
  186.         /**
  187.          * Lists for travelmethods and coordinates
  188.          */
  189.         coordinates = new ArrayList<>();
  190.         routeCoordinates = new ArrayList<>();
  191.         markerPositions = new ArrayList<>();
  192.  
  193.         /**
  194.          * Our very loved MapLocationDrawer
  195.          */
  196.         mapLocationDrawer = new MapLocationDrawer(this);
  197.  
  198.         /**
  199.          * Get current location
  200.          */
  201.         LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
  202.         if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
  203.             locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, new android.location.LocationListener() {
  204.                 @Override
  205.                 public void onLocationChanged(Location location) {
  206.                     currentLocation = location;
  207.                     if (myLocationMarker != null) {
  208.                         myLocationMarker.remove();
  209.                     }
  210.                     myLocationMarker = mMap.addMarker(new MarkerOptions()
  211.                             .icon(BitmapDescriptorFactory.fromResource(R.drawable.my_location_icon))
  212.                             .position(new LatLng(location.getLatitude(), location.getLongitude()))
  213.                             .title("My Position"));
  214.                     myLocationMarker.showInfoWindow();
  215.                 }
  216.  
  217.                 @Override
  218.                 public void onStatusChanged(String provider, int status, Bundle extras) {
  219.  
  220.                 }
  221.  
  222.                 @Override
  223.                 public void onProviderEnabled(String provider) {
  224.  
  225.                 }
  226.  
  227.                 @Override
  228.                 public void onProviderDisabled(String provider) {
  229.  
  230.                 }
  231.             });
  232.         }
  233.  
  234.         FragmentManager manager = getFragmentManager();
  235.         travelMethodsFragment.show(manager, "Dialog");
  236.  
  237.         /**
  238.          * Get origin coordinates from place object when user finishes search
  239.          */
  240.         autoCompleteStartFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
  241.             @Override
  242.             public void onPlaceSelected(Place place) {
  243.                 origin = place.getLatLng();
  244.                 coordinates.add(origin);
  245.                 from = place.getAddress().toString();
  246.                 if (originMarker != null) {
  247.                     originMarker.remove();
  248.                 }
  249.                 originMarker = mMap.addMarker(new MarkerOptions()
  250.                         .position(origin)
  251.                         .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
  252.                 markerPositions.add(originMarker.getPosition());
  253.             }
  254.  
  255.             /**
  256.              * Something must've gotten terribly wrong
  257.              */
  258.             @Override
  259.             public void onError(Status status) {
  260.                 Toast.makeText(getBaseContext(),
  261.                         "Error fetching location: " + status.getStatusMessage(),
  262.                         Toast.LENGTH_SHORT)
  263.                         .show();
  264.             }
  265.         });
  266.  
  267.         /**
  268.          * Get destination coordinates when user finishes search
  269.          */
  270.         autocompleteEndFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
  271.             @Override
  272.             public void onPlaceSelected(Place place) {
  273.                 destination = place.getLatLng();
  274.                 coordinates.add(destination);
  275.                 to = place.getAddress().toString();
  276.                 if (destinationMarker != null) {
  277.                     destinationMarker.remove();
  278.                 }
  279.                 destinationMarker = mMap.addMarker(new MarkerOptions()
  280.                         .position(destination)
  281.                         .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
  282.                 markerPositions.add(destinationMarker.getPosition());
  283.  
  284.                 selectedSpinnerItem = null;
  285.  
  286.                 if (!routeCoordinates.isEmpty()) {
  287.                     routeCoordinates.clear();
  288.                 }
  289.                 else {
  290.                     mapLocationDrawer.zoomWithinCurrentMarkers(mMap, markerPositions);
  291.                     requestRoute();
  292.                 }
  293.             }
  294.  
  295.             /**
  296.              * Something must've gotten terribly wrong
  297.              */
  298.             @Override
  299.             public void onError(Status status) {
  300.                 Toast.makeText(getBaseContext(),
  301.                         "Error fetching location: " + status.getStatusMessage(),
  302.                         Toast.LENGTH_SHORT)
  303.                         .show();
  304.             }
  305.         });
  306.  
  307.         /**
  308.          * Checks what card that is visible and perform logic based on it, code is pretty self explanatory.
  309.          */
  310.         selectionSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
  311.             @Override
  312.             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
  313.                 selectedSpinnerItem = parent.getItemAtPosition(position);
  314.                 if (selectedSpinnerItem.equals("Change Travel Method")) {
  315.                     selectionSpinner.setSelection(selections.indexOf(String.valueOf(selections.get(0))));
  316.                     travelMethod = "";
  317.                     if (travelLocationsCard.getVisibility() == View.VISIBLE) {
  318.                         travelLocationsCard.setVisibility(View.GONE);
  319.                     }
  320.                 } else if (selectedSpinnerItem.equals("Change Locations")) {
  321.                     if (travelLocationsCard.getVisibility() == View.GONE) {
  322.                         selectionSpinner.setSelection(selections.indexOf(String.valueOf(selections.get(0))));
  323.                         origin = null;
  324.                         destination = null;
  325.                         autoCompleteStartFragment.setText("");
  326.                         autocompleteEndFragment.setText("");
  327.                         if (polylines != null) {
  328.                             for (Polyline polyline : polylines) {
  329.                                 polyline.remove();
  330.                             }
  331.                         }
  332.                         if (originMarker != null || destinationMarker != null) {
  333.                             if (originMarker != null) {
  334.                                 originMarker.remove();
  335.                             }
  336.                             if (destinationMarker != null) {
  337.                                 destinationMarker.remove();
  338.                             }
  339.                         }
  340.                         travelLocationsCard.setVisibility(View.VISIBLE);
  341.                     }
  342.                 }
  343.             }
  344.  
  345.             @Override
  346.             public void onNothingSelected(AdapterView<?> parent) {
  347.  
  348.             }
  349.         });
  350.     }
  351.  
  352.     public void requestRoute() {
  353.         /**
  354.          * Check if either one of the search fields are empty
  355.          */
  356.         if (origin == null || destination == null) {
  357.             if (origin == null) {
  358.                 builder = new AlertDialog.Builder(getBaseContext());
  359.                 builder.setMessage("You must enter a start location");
  360.                 builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
  361.                     public void onClick(DialogInterface dialog, int id) {
  362.                         dialog.dismiss();
  363.                     }
  364.                 });
  365.             }
  366.             if (destination == null) {
  367.                 builder = new AlertDialog.Builder(getBaseContext());
  368.                 builder.setMessage("You must enter an end destination");
  369.                 builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
  370.                     public void onClick(DialogInterface dialog, int id) {
  371.                         dialog.dismiss();
  372.                     }
  373.                 });
  374.             }
  375.         } else {
  376.             /**
  377.              * We only have to check the first index in the list since the user only has 2 choices.
  378.              */
  379.             if (travelMethod != null && travelMethod.equals("Walking")) {
  380.                 Routing routing = new Routing.Builder()
  381.                         .travelMode(AbstractRouting.TravelMode.WALKING)
  382.                         .withListener(this)
  383.                         .alternativeRoutes(false)
  384.                         .waypoints(origin, destination)
  385.                         .build();
  386.                 routing.execute();
  387.             }
  388.             /**
  389.              * Same as above, checking the first index and set the travel method accordingly.
  390.              */
  391.             else if (travelMethod != null && travelMethod.equals("Biking")) {
  392.                 Routing routing = new Routing.Builder()
  393.                         .travelMode(AbstractRouting.TravelMode.BIKING)
  394.                         .withListener(this)
  395.                         .alternativeRoutes(false)
  396.                         .waypoints(origin, destination)
  397.                         .build();
  398.                 routing.execute();
  399.             }
  400.         }
  401.     }
  402.  
  403.     @Override
  404.     public void onRoutingFailure(RouteException e) {
  405.         if (e != null) {
  406.             Toast.makeText(getBaseContext(),
  407.                     "You are not able to travel, by this method, to this destination.",
  408.                     Toast.LENGTH_SHORT)
  409.                     .show();
  410.         } else {
  411.             Toast.makeText(getBaseContext(),
  412.                     "Could not find location, please try again",
  413.                     Toast.LENGTH_SHORT)
  414.                     .show();
  415.         }
  416.     }
  417.  
  418.     @Override
  419.     public void onRoutingStart() {
  420.  
  421.     }
  422.  
  423.     /**
  424.      * Override callback from request route
  425.      *
  426.      * @param arrayList
  427.      * @param i
  428.      */
  429.     @Override
  430.     public void onRoutingSuccess(ArrayList<Route> arrayList, int i) {
  431.         polylines = new ArrayList<>();
  432.  
  433.         /**
  434.          * Check if there already are Routes displayed on the map, remove if so.
  435.          */
  436.         if (polylines.size() > 0) {
  437.             for (Polyline existingLine : polylines) {
  438.                 existingLine.remove();
  439.             }
  440.         }
  441.  
  442.         for (int n = 0; n < arrayList.size(); n++) {
  443.             PolylineOptions polyOptions = new PolylineOptions();
  444.             polyOptions.color(Color.rgb(26, 136, 153));
  445.             polyOptions.width(15);
  446.  
  447.             /**
  448.              * Fetch and add all the points contained in the polyline for route on pos n
  449.              */
  450.             polyOptions.addAll(arrayList.get(n).getPoints());
  451.             Polyline line = mMap.addPolyline(polyOptions);
  452.             polylines.add(line);
  453.         }
  454.  
  455.         routeCoordinates = polylines.get(0).getPoints();
  456.         if(!routeCoordinates.isEmpty()){
  457.             double distance = calculateRouteDistance(routeCoordinates);
  458.             route.setRouteDistance(distance);
  459.         }
  460.  
  461.         for (int j = 0; j < routeCoordinates.size(); j++) {
  462.             RouteCoordinate coord = new RouteCoordinate(routeCoordinates.get(j).latitude, routeCoordinates.get(j).longitude);
  463.             coord.setParentID(route.getRouteID());
  464.             route.getRouteCoordinates().add(coord);
  465.         }
  466.  
  467.         /**
  468.          * Get the fragmentManager, send the route to realm, pass the route id to the fragment.
  469.          */
  470.         FragmentManager manager = getFragmentManager();
  471.         Bundle bundle = new Bundle();
  472.         bundle.putInt("routeId", route.getRouteID());
  473.         travelLocationsCard.setVisibility(View.GONE);
  474.         dataFetcher.createNewRoute(route, route.getRouteName(), route.getRouteCoordinates(), route.getRouteDistance());
  475.         routeNameFragment.setArguments(bundle);
  476.         routeNameFragment.show(manager, "RouteNameDialog");
  477.     }
  478.  
  479.     @Override
  480.     public void onRoutingCancelled() {
  481.  
  482.     }
  483.  
  484.  
  485.     private double calculateRouteDistance(List<LatLng> list){
  486.         return SphericalUtil.computeLength(list);
  487.     }
  488.  
  489.     /**
  490.      * Build google api client to work with
  491.      */
  492.     protected synchronized void buildGoogleApiClient() {
  493.         if (googleApiClient == null) {
  494.             googleApiClient = new GoogleApiClient.Builder(this)
  495.                     .addApi(LocationServices.API)
  496.                     .build();
  497.             googleApiClient.connect();
  498.         }
  499.     }
  500.  
  501.     /**
  502.      * Override method and give us our current location.
  503.      */
  504.     @Override
  505.     public void onConnected(Bundle bundle) {
  506.  
  507.     }
  508.  
  509.     @Override
  510.     public void onMapReady(GoogleMap googleMap) {
  511.         mMap = googleMap;
  512.         googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
  513.         mMap.setOnInfoWindowClickListener(this);
  514.  
  515.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  516.             if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
  517.                 buildGoogleApiClient();
  518.                 mMap.setMyLocationEnabled(true);
  519.             }
  520.         } else {
  521.             buildGoogleApiClient();
  522.             mMap.setMyLocationEnabled(true);
  523.         }
  524.     }
  525.  
  526.     @Override
  527.     public void onInfoWindowClick(Marker marker){
  528.         if(travelLocationsCard.getVisibility() == View.VISIBLE) {
  529.             myLocationMarker = marker;
  530.             origin = myLocationMarker.getPosition();
  531.             markerPositions.add(origin);
  532.             autoCompleteStartFragment.setText("My Position");
  533.             if(originMarker != null){
  534.                 originMarker.remove();
  535.             }
  536.             originMarker = mMap.addMarker(new MarkerOptions()
  537.                     .position(origin)
  538.                     .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
  539.             from = "My Position";
  540.         }
  541.  
  542.     }
  543.  
  544.     @Override
  545.     public void onConnectionFailed(ConnectionResult result) {
  546.  
  547.     }
  548.  
  549.     @Override
  550.     public void onConnectionSuspended(int cause) {
  551.  
  552.     }
  553.  
  554.     @Override
  555.     public void onLocationChanged(Location location) {
  556.  
  557.     }
  558.     // TODO: Is never called. Should it be called in onCreate?
  559.     public boolean checkLocationPermission() {
  560.         if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  561.             ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION);
  562.             return true;
  563.         }
  564.  
  565.         return false;
  566.     }
  567.  
  568.     @Override
  569.     public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
  570.         switch (requestCode) {
  571.             case REQUEST_LOCATION_PERMISSION: {
  572.                 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  573.                     if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
  574.                         if (googleApiClient == null) {
  575.                             buildGoogleApiClient();
  576.                         }
  577.                         mMap.setMyLocationEnabled(true);
  578.                     }
  579.                 } else {
  580.                     Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
  581.                 }
  582.             }
  583.         }
  584.     }
  585.  
  586.     @Override
  587.     public void onStop() {
  588.         super.onStop();
  589.         dataFetcher.closeDb();
  590.     }
  591.  
  592.     @Override
  593.     public void onPause() {
  594.         super.onPause();
  595.         dataFetcher.closeDb();
  596.     }
  597.  
  598.     @Override
  599.     public void onDestroy() {
  600.         super.onDestroy();
  601.         dataFetcher.closeDb();
  602.  
  603.         // check if routeNamefragent is not null close it.
  604.          if (routeNameFragment.getDialog() != null) {
  605.              routeNameFragment.getDialog().dismiss();
  606.          }
  607.     }
  608.  
  609.     @Override
  610.     public void okButtonClicked(String value) {
  611.         travelMethod = travelMethodsFragment.getSelectedMethod();
  612.         travelLocationsCard.setVisibility(View.VISIBLE);
  613.     }
  614. }
  615.  
  616. // TODO
  617. /**
  618.  * Task: Does the user want to see distance on the route?
  619.  * Task: Coordinate travel method with existing lib to display correct routes
  620.  * Task: Fix camera zoom and animation when requesting route result
  621.  * Task: Display information about where you currently are such as street name?
  622.  * Task: Implement visibility method - Check which card that is visible and make it invisible (is user wants to change travel method and locations)
  623.  * Task: Origin can be current location
  624.  * Task: User is able to select, by clicking on it, a polyline(Route) when creating a new route.
  625.  * Task: When user clicks on a polyline, save the other polylines in a list which we can later draw again.
  626.  */
Add Comment
Please, Sign In to add comment