public static FeatureCollection ToFeatureCollection(this FAnnotation annotation)
        {
            var list = new List <Feature>();

            if (annotation is PointAnnotation)
            {
                var pa = (PointAnnotation)annotation;
                list.Add(pa.ToFeature());
            }
            else if (annotation is PolylineAnnotation)
            {
                var pa = (PolylineAnnotation)annotation;
                list.Add(pa.ToFeature());
            }
            else if (annotation is MultiPolylineAnnotation)
            {
                var pa = (MultiPolylineAnnotation)annotation;
                list.Add(pa.ToFeature());
            }

            return(FeatureCollection.FromFeatures(list.ToArray()));
        }
Ejemplo n.º 2
0
        /// <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
        }
Ejemplo n.º 3
0
 public static FeatureCollection toFeatureCollection(this IEnumerable <Feature> features)
 {
     return(FeatureCollection.FromFeatures(features.ToArray()));
 }