private List <LatLng> GetPoints(String keyword) { Dictionary <string, LatLng> results = new Dictionary <string, LatLng>(); // Calculate four equidistant points around Sydney to use as search centers // so that four searches can be done. List <LatLng> searchCenters = new List <LatLng>(4); for (int heading = 45; heading < 360; heading += 90) { searchCenters.Add(SphericalUtil.ComputeOffset(SYDNEY, SEARCH_RADIUS / 2, heading)); } for (int j = 0; j < 4; j++) { var result = GetJsonPlaces(keyword, searchCenters[j]).Result; try { for (int i = 0; i < result.Place.Count; i++) { if (!results.ContainsKey(result.Place[i].Id)) { results.Add(result.Place[i].Id, new LatLng(result.Place[i].Geometry.Location.Latitude, result.Place[i].Geometry.Location.Longitude)); } } } catch (Exception) { Toast.MakeText(this, "Cannot process JSON results", ToastLength.Short).Show(); } } return(results.Values.ToList()); }
public void setRouteIncreaseForward(LatLng endLatLng) { if (endLatLng == null) { return; } if (_marker != null) { if (NeedUpdateRotation()) { var heading = SphericalUtil.computeHeading(_marker.Position, endLatLng); heading = heading + 180; //if (Options.HeadingConverter != null) // heading = Options.HeadingConverter(heading); double mapHeading = 0; if (_googleMap?.CameraPosition != null) { mapHeading = -_googleMap.CameraPosition.Bearing; } _marker.Rotation = (float)heading + (float)mapHeading; _lastUpdatedLocation = endLatLng; } _marker.Position = endLatLng; } }
public void Run() { long elapsed = SystemClock.UptimeMillis() - _start; float t = _interpolator.GetInterpolation((float)elapsed / (float)_duration); double lng = t * _toPosition.Longitude + (1 - t) * _startPosition.Longitude; double lat = t * _toPosition.Latitude + (1 - t) * _startPosition.Latitude; var endLatLng = new LatLng(lat, lng); if (NeedUpdateRotation()) { var heading = SphericalUtil.computeHeading(_marker.Position, endLatLng); heading = heading + 180; //if (Options.HeadingConverter != null) // heading = Options.HeadingConverter(heading); double mapHeading = 0; if (_gMap?.CameraPosition != null) { mapHeading = -_gMap.CameraPosition.Bearing; } _marker.Rotation = (float)heading + (float)mapHeading; _lastUpdatedLocation = endLatLng; } _marker.Position = endLatLng; if (t < 1.0) { // Post again 16ms later. _handler.PostDelayed(this, 16); } else { _endAction?.Invoke(); } //else //{ // if (hideMarker) // { // marker.Visible = false; // } // else // { // marker.Visible = true; // } //} }
public void OnDataChange(DataSnapshot snapshot) { if (snapshot.Value != null) { var child = snapshot.Children.ToEnumerable <DataSnapshot>(); availableDrivers.Clear(); foreach (DataSnapshot data in child) { if (data.Child("ride_id").Value != null) { if (data.Child("ride_id").Value.ToString() == "waiting") { //Get Driver Location double latitude = double.Parse(data.Child("location").Child("latitude").Value.ToString()); double longitude = double.Parse(data.Child("location").Child("longitude").Value.ToString()); LatLng driverLocation = new LatLng(latitude, longitude); AvailableDriver driver = new AvailableDriver(); //compute Distance between Pickup Location and Driver Location driver.DistanceFromPickup = SphericalUtil.ComputeDistanceBetween(mPickupLoction, driverLocation); driver.ID = data.Key; availableDrivers.Add(driver); } } } if (availableDrivers.Count > 0) { availableDrivers = availableDrivers.OrderBy(o => o.DistanceFromPickup).ToList(); DriversFound?.Invoke(this, new DriverFoundEventArgs { Drivers = availableDrivers }); } else { DriverNotFound.Invoke(this, new EventArgs()); } } else { DriverNotFound.Invoke(this, new EventArgs()); } }
/** * Makes four radar search requests for the given keyword, then parses the * json output and returns the search results as a collection of LatLng objects. * * @param keyword A string to use as a search term for the radar search * @return Returns the search results from radar search as a collection * of LatLng objects. */ private List <LatLng> getPoints(string keyword) { Dictionary <string, LatLng> results = new Dictionary <string, LatLng>(); // Calculate four equidistant points around Sydney to use as search centers // so that four searches can be done. List <LatLng> searchCenters = new List <LatLng>(4); for (int heading = 45; heading < 360; heading += 90) { searchCenters.Add(SphericalUtil.ComputeOffset(SYDNEY, SEARCH_RADIUS / 2, heading)); } for (int j = 0; j < 4; j++) { string jsonResults = getJsonPlaces(keyword, searchCenters[j]); try { // Create a JSON object hierarchy from the results JSONObject jsonObj = new JSONObject(jsonResults); JSONArray pointsJsonArray = jsonObj.GetJSONArray("results"); // Extract the Place descriptions from the results for (int i = 0; i < pointsJsonArray.Length(); i++) { if (!results.ContainsKey(pointsJsonArray.GetJSONObject(i).GetString("id"))) { JSONObject location = pointsJsonArray.GetJSONObject(i) .GetJSONObject("geometry").GetJSONObject("location"); results.Add(pointsJsonArray.GetJSONObject(i).GetString("id"), new LatLng(location.GetDouble("lat"), location.GetDouble("lng"))); } } } catch (JSONException) { Toast.MakeText(this, "Cannot process JSON results", ToastLength.Short).Show(); } } return(results.Values.ToList()); }
public void Create(List <ActiveDrivers> activeDrivers) { availableDrivers = activeDrivers; if (availableDrivers.Count > 0) { availableDrivers.ForEach(x => { LatLng driverLocation = new LatLng(Convert.ToDouble(x.Latitude), Convert.ToDouble(x.Longitude)); LatLng pickUpLocation = new LatLng(Convert.ToDouble(rides.RidesInfo.LocationInfo.PickupLatitude), Convert.ToDouble(rides.RidesInfo.LocationInfo.PickupLongitude)); x.DistanceFromPickup = SphericalUtil.ComputeDistanceBetween(pickUpLocation, driverLocation); }); availableDrivers = availableDrivers.OrderBy(o => o.DistanceFromPickup).ToList(); DriversFound?.Invoke(this, new DriverFoundEventArgs { Drivers = availableDrivers, Ride = rides }); } else { DriverNotFound.Invoke(this, new EventArgs()); } }
/// <summary> /// This has a problem, if the same pin updates a couple of times a second pin might jump suddenly to the /// 2nd to latest position then smooth animate to the latest position, but I think this is ok logically since /// By the time it's animating its final animation position is not really up to date. /// </summary> /// <param name="pin">Pin.</param> private void animateLocationChange(Pin pin) { #region Simultaneous pin update System.Threading.Tasks.Task.Run(async () => { // If there exist a pin that caused this update if (isPinAnimating) return; //// Wait for pin position assignment in the same call isPinAnimating = true; // Get all pins with the same key and same flat value (animatable pins) var pinsWithSimilarKey = xMap.pins.Where( (Pin arg) => arg.IsCenterAndFlat == pin.IsCenterAndFlat).ToArray(); Device.BeginInvokeOnMainThread(() => { var geoJsonSource = (MGLShapeSource)nStyle.SourceWithIdentifier(mapLockedPinsSourceKey); var visibleMovablePinCount = pinsWithSimilarKey.Count(p => p.isVisible); var currentHeadingCollection = new double[visibleMovablePinCount]; var features = new NSObject[visibleMovablePinCount]; // Update the entire frame MapBox.Extensions.MapExtensions.animatePin( (double d) => { System.Threading.Tasks.Task.Run(() => { for (int i = 0; i < visibleMovablePinCount; i++) { var p = pinsWithSimilarKey[i]; Position theCurrentAnimationJump = p.position; double theCurrentHeading = p.heading; // Only update the pin if it is the pin that cause this animation call // OR the if it actually requested for a position update before this current animation has not been finished if (pin == p || p.requestForUpdate) { theCurrentAnimationJump = SphericalUtil.interpolate(p.previousPinPosition, p.position, d); theCurrentHeading = SphericalUtil.computeHeading(p.previousPinPosition, p.position); } currentHeadingCollection[i] = theCurrentHeading; var feature = new MGLPointFeature { Coordinate = new CLLocationCoordinate2D(theCurrentAnimationJump.latitude, theCurrentAnimationJump.longitude) }; feature.Attributes = NSDictionary<NSString, NSObject>.FromObjectsAndKeys( new object[] { p.image, theCurrentHeading, p.imageScaleFactor, p.id }, new object[] { MapboxRenderer.pin_image_key, MapboxRenderer.pin_rotation_key, MapboxRenderer.pin_size_key, MapboxRenderer.pin_id_key }); // Add to the new animation frame features[i] = feature; } // Update the entire layer Device.BeginInvokeOnMainThread(() => geoJsonSource.Shape = MGLShapeCollectionFeature.ShapeCollectionWithShapes(features)); }); }, async (d, b) => { // DO NOT REMOVE, this is essential for the simultaneous pin location update to work await System.Threading.Tasks.Task.Delay(500); isPinAnimating = false; // Stabilize the pins, at this moment all the pins are updated for (int i = 0; i < visibleMovablePinCount; i++) { var p = pinsWithSimilarKey[i]; // To avoid triggering heading property change event p.PropertyChanged -= Pin_PropertyChanged; p.requestForUpdate = false; p.heading = currentHeadingCollection[i]; p.PropertyChanged += Pin_PropertyChanged; } }, 500); }); }); #endregion }
private void showDistance() { double distance = SphericalUtil.ComputeDistanceBetween(mMarkerA.Position, mMarkerB.Position); mTextView.Text = "The markers are " + formatNumber(distance) + " apart."; }
/// <summary> /// This has a problem, if the same pin updates a couple of times a second pin might jump suddenly to the /// 2nd to latest position then smooth animate to the latest position, but I think this is ok logically since /// By the time it's animating its final animation position is not really up to date. /// </summary> /// <param name="pin">Pin.</param> private void animateLocationChange(Pin pin) { #region Simultaneous pin update System.Threading.Tasks.Task.Run(async() => { // If there exist a pin that caused this update if (isPinAnimating) { return; } // Wait for pin position assignment in the same call isPinAnimating = true; // Get all pins with the same key and same flat value (animatable pins) var pinsWithSimilarKey = xMap.pins.Where( (Pin arg) => arg.IsCenterAndFlat == pin.IsCenterAndFlat).ToArray(); Device.BeginInvokeOnMainThread(() => { var geoJsonSource = (GeoJsonSource)nMap.GetSource(mapLockedPinsSourceKey); var visibleMovablePinCount = pinsWithSimilarKey.Count(p => p.isVisible); var currentHeadingCollection = new double[visibleMovablePinCount]; var features = new Feature[visibleMovablePinCount]; // Update the entire frame MapBox.Extensions.MapExtensions.animatePin( (double d) => { System.Threading.Tasks.Task.Run(() => { for (int i = 0; i < visibleMovablePinCount; i++) { var p = pinsWithSimilarKey[i]; Position theCurrentAnimationJump = p.position; double theCurrentHeading = p.heading; // Only update the pin if it is the pin that cause this animation call // OR the if it actually requested for a position update before this current animation has not been finished if (pin == p || p.requestForUpdate) { theCurrentAnimationJump = SphericalUtil.interpolate(p.previousPinPosition, p.position, d); theCurrentHeading = SphericalUtil.computeHeading(p.previousPinPosition, p.position); } currentHeadingCollection[i] = theCurrentHeading; var feature = Feature.FromGeometry( Com.Mapbox.Geojson.Point.FromLngLat(theCurrentAnimationJump.longitude, theCurrentAnimationJump.latitude)); feature.AddStringProperty(MapboxRenderer.pin_image_key, p.image); feature.AddNumberProperty(MapboxRenderer.pin_rotation_key, (Java.Lang.Number)theCurrentHeading); feature.AddNumberProperty(MapboxRenderer.pin_size_key, (Java.Lang.Number)p.imageScaleFactor); feature.AddStringProperty(MapboxRenderer.pin_id_key, p.id); // Add to the new animation frame features[i] = feature; } // Extension method bypass, fromFeatures accepts IList as parameter var featureCollection = FeatureCollection.FromFeatures(features); // Update the entire layer Device.BeginInvokeOnMainThread(() => geoJsonSource.SetGeoJson(featureCollection)); }); }, async(d, b) => { // DO NOT REMOVE, this is essential for the simultaneous pin location update to work await System.Threading.Tasks.Task.Delay(500); isPinAnimating = false; // Stabilize the pins, at this moment all the pins are updated for (int i = 0; i < visibleMovablePinCount; i++) { var p = pinsWithSimilarKey[i]; // To avoid triggering heading property change event p.PropertyChanged -= Pin_PropertyChanged; p.requestForUpdate = false; p.heading = currentHeadingCollection[i]; p.PropertyChanged += Pin_PropertyChanged; } }, 500); }); }); #endregion }