예제 #1
0
        private void RefreshView(AddRemoveCollection addRemoveCollection, CancellationToken token)
        {
            if (token.IsCancellationRequested)
            {
                return;
            }

            // remove out of view items
            foreach (var station in Items.Where(t => addRemoveCollection.ToRemove.Contains(t)).ToList())
            {
                var item = StationControls.First(c => c.Station.Latitude == station.Latitude && c.Station.Longitude == station.Longitude);
                _clusterManager.RemoveItem(item);
                StationControls.Remove(item);
                Items.Remove(station);
                station.Control = null;
                if (station.IsInRefreshPool)
                {
                    _contractService.RemoveStationFromRefreshingPool(station);
                }
                if (token.IsCancellationRequested)
                {
                    return;
                }
            }


            foreach (var station in addRemoveCollection.ToAdd.Where(t => !Items.Contains(t)).ToList())
            {
                var item = new ClusterItem(station.Latitude, station.Longitude)
                {
                    Station = station
                };
                StationControls.Add(item);
                _clusterManager.AddItem(item);
                Items.Add(station);
                if (token.IsCancellationRequested)
                {
                    return;
                }
            }
            _clusterManager.Cluster();
        }
예제 #2
0
        public async void OnMapReady(GoogleMap googleMap)
        {
            _gettingMap = false;
            // TODO TO HELP DEBUG auto download paris to help dev on performances 
            //var contractToTest = "Paris";
            //var contractService = SimpleIoc.Default.GetInstance<IContractService>();
            //var contract = contractService.GetCountries().First(country => country.Contracts.Any(c => c.Name == contractToTest)).Contracts.First(c => c.Name == contractToTest);
            //await SimpleIoc.Default.GetInstance<ContractsViewModel>().AddOrRemoveContract(contract);
            _contractService = SimpleIoc.Default.GetInstance<IContractService>();
            _contractService.ContractRefreshed += OnContractRefreshed;
            _contractService.StationRefreshed += OnStationRefreshed;

            // set the initial visual state of the bike/parking buttons
            SwitchModeStationParkingVisualState();

            _map = googleMap;
            _maxZoom = _map.MaxZoomLevel;

            LoadPreviousTile();

            //Setup and customize your Google Map
            _map.UiSettings.CompassEnabled = true;
            _map.UiSettings.MyLocationButtonEnabled = false;
            _map.UiSettings.MapToolbarEnabled = false;
            _map.MyLocationEnabled = true;

            // add padding to prevent action bar to hide the position button
            //var dp = (int)(48 * Resources.DisplayMetrics.Xdpi / Resources.DisplayMetrics.Density);
            //_map.SetPadding(0, dp, 0, 0);
            //_map.vie
            //View locationButton = suppormanagerObj.getView().findViewById(2);
            //var rlp = (RelativeLayout.LayoutParams)locationButton.getLayoutParams(); 
            //// position on right bottom 
            //rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0); rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE); 

            // Initialize the camera position
            SetViewPoint(await GetStartingCameraPosition(), false);

            // Initialize the marker with the stations
            _clusterManager = new ClusterManager(this, _map);
            _clusterRender = new StationRenderer(this, _map, _clusterManager);
            _clusterManager.SetRenderer(_clusterRender);

            _map.SetOnCameraChangeListener(_clusterManager);
            // this disable the rest of the event handlers
            // so there is no way to distinct a click on a cluster and a marker 
            _map.MarkerClick += _map_MarkerClick;
            //_map.SetOnMarkerClickListener(new OnMarkerClickListener());
            //_clusterManager.SetOnClusterClickListener(this);
            //_clusterManager.SetOnClusterItemClickListener(this);

            // check if the app contains a least one city, otherwise, tells the user to download one
            MainViewModel.MainPageLoadedCommand.Execute(null);

            // On long click, display the address on a info window
            Observable.FromEventPattern<GoogleMap.MapLongClickEventArgs>(_map, "MapLongClick")
                .Subscribe(e =>
                {
                    AddPlaceMarker(e.EventArgs.Point, null, null);
                    SelectItem(e.EventArgs.Point);
                    //IList<Address> addresses = new List<Address>();
                    //try
                    //{
                    //    // Convert latitude and longitude to an address (GeoCoder)
                    //    addresses = await (new Geocoder(this).GetFromLocationAsync(currentMarkerPosition.Latitude, currentMarkerPosition.Longitude, 1));
                    //}
                    //catch (Exception ex)
                    //{
                    //    Log.Debug("MyActivity", "Geocoder crashed: " + ex.Message);
                    //}
                    //return new AddressesFromLocationDTO { Addresses = addresses, Location = FormatLatLng(e.EventArgs.Point) };

                });
            _map.MapClick += _map_MapClick;


            if (_parameterLat != 0 && _parameterLon != 0)
            {
                ShowIntentLocation();
            }
            else
            {
                // center the map on last user location
                GetPreviousLastUserLocation();
            }





            // Initialize the behavior when long clicking somewhere on the map
            //_map.MapLongClick += async (sender, e) =>
            //{
            //    // On long click, display the address on a info window
            //    if (longClickMarker != null)
            //    {
            //        // Remove a previously created marker
            //        longClickMarker.Remove();
            //    }

            //    IList<Address> addresses = new List<Address>();
            //    currentMarkerPosition = e.Point;
            //    var latLongString = $"(latitude: { Math.Round(currentMarkerPosition.Latitude)}, longitude: { Math.Round(currentMarkerPosition.Longitude, 4)})";
            //    try
            //    {

            //        // Resolve the addresses (can throw an exception)
            //        var task = new Geocoder(this).GetFromLocationAsync(currentMarkerPosition.Latitude, currentMarkerPosition.Longitude, 1);
            //        AddressesFromLocationStream.OnNext(new AddressesFromLocationDTO { AddressesTask = task, Location = currentMarkerPosition });
            //    }
            //    catch (Exception)
            //    {
            //        // Ignore
            //    }
            //    finally
            //    {
            //        AddressesFromLocationStream.OnNext(new AddressesFromLocationDTO { Addresses = addresses, Location = currentMarkerPosition });
            //    }
            //};


            _contractService = SimpleIoc.Default.GetInstance<IContractService>();
            var mapObserver = Observable.FromEventPattern(_map, "CameraChange");
            TaskCompletionSource<bool> tcs;
            mapObserver
                .Do((e) =>
                {
                    if (_map.CameraPosition.Zoom > _maxZoom)
                    {
                        _map.MoveCamera(CameraUpdateFactory.ZoomTo(_maxZoom));
                    }
                    cts.Cancel();
                    cts = new CancellationTokenSource();
                }).Throttle(throttleTime)
                .Select(async x =>
                {
                    var stations = _contractService.GetStations();
                    // some services can provide wrong values in lat or lon... just take care of it
                    foreach (var station in stations.Where(s => s.Location == null))
                    {
                        station.Location = new LatLng(station.Latitude, station.Longitude);
                    }
                    LatLngBounds bounds = null;
                    tcs = new TaskCompletionSource<bool>();
                    RunOnUiThread(() =>
                    {
                        try
                        {
                            // can return null
                            bounds = _map.Projection.VisibleRegion.LatLngBounds;
                        }
                        catch
                        {
                        }
                        tcs.SetResult(true);
                    });

                    await tcs.Task;


                    var collection = new AddRemoveCollection();
                    if (bounds != null)
                    {
                        // extends slightly the bound view
                        // to provide a better experience
                        //bounds = MapHelper.extendLimits(bounds, 1);
                        collection.ToRemove = Items.Where(t => !bounds.Contains((LatLng)t.Location)).ToList();
                        collection.ToAdd = stations.Where(t => !Items.Contains(t)
                        && bounds.Contains((LatLng)t.Location)).Take(MAX_CONTROLS).ToList();
                        if (Items.Count > MAX_CONTROLS + collection.ToRemove.Count)
                            collection.ToAdd.Clear();

                    }
                    // precalculate the items offset (that deffer well calculation)
                    //foreach (var velib in collection.ToAdd)
                    //{
                    //    velib.GetOffsetLocation2(leftCornerLocation, zoomLevel);
                    //}
                    return collection;
                })
                .Switch()
                .Subscribe(x =>
                {
                    if (x == null)
                        return;


                    RunOnUiThread(() =>
                    {
                        RefreshView(x, cts.Token);
                    });

                });
        }