Exemplo n.º 1
0
        /// <summary>
        /// Precalculates speed factors for all the given profiles.
        /// </summary>
        public void CalculateFor(params Profile[] profiles)
        {
            lock (this)
            { // don't allow multiple threads to fill this cache at the same time.
                var newEdgeProfileFactors = new Dictionary <string, FactorAndSpeed[]>(_edgeProfileFactors);

                var edgeProfileFactors = new FactorAndSpeed[profiles.Length][];
                for (var p = 0; p < profiles.Length; p++)
                {
                    edgeProfileFactors[p] = new FactorAndSpeed[(int)_db.EdgeProfiles.Count];
                }

                for (uint edgeProfile = 0; edgeProfile < _db.EdgeProfiles.Count; edgeProfile++)
                {
                    var edgeProfileTags = _db.EdgeProfiles.Get(edgeProfile);
                    for (var p = 0; p < profiles.Length; p++)
                    {
                        edgeProfileFactors[p][edgeProfile]
                            = profiles[p].FactorAndSpeed(edgeProfileTags);
                    }
                }

                for (var p = 0; p < profiles.Length; p++)
                {
                    newEdgeProfileFactors[profiles[p].FullName] = edgeProfileFactors[p];
                }

                _edgeProfileFactors = newEdgeProfileFactors;
            }
        }
        /// <summary>
        /// Returns an isacceptable function using the cached data.
        /// </summary>
        public Func <GeometricEdge, bool> GetIsAcceptable(bool verifyCanStopOn, List <uint> closures, params IProfileInstance[] profileInstances)
        {
            if (!this.ContainsAll(profileInstances))
            {
                throw new ArgumentException("Not all given profiles are supported.");
            }

            var cachedFactors = new FactorAndSpeed[profileInstances.Length][];

            for (var p = 0; p < profileInstances.Length; p++)
            {
                cachedFactors[p] = _edgeProfileFactors[profileInstances[p].Profile.FullName];
            }

            return((edge) =>
            {
                // first check for closure
                if (closures.Contains(edge.Id))
                {
                    return false;
                }

                float distance;
                ushort edgeProfileId;
                Data.Edges.EdgeDataSerializer.Deserialize(edge.Data[0],
                                                          out distance, out edgeProfileId);
                for (var i = 0; i < profileInstances.Length; i++)
                {
                    var cachedFactor = cachedFactors[i][edgeProfileId];
                    if (cachedFactor.Value <= 0)
                    { // edge is not accessible to this profile.
                        return false;
                    }

                    if (verifyCanStopOn)
                    {     // check for a stopping point.
                        if (!cachedFactor.CanStopOn())
                        { // can't use this edge as stopping point.
                            return false;
                        }
                    }

                    if (profileInstances[i].IsConstrained(cachedFactor.Constraints))
                    { // edge is constrained, vehicle too heavy or too big for example.
                        return false;
                    }
                }
                return true;
            });
        }
Exemplo n.º 3
0
 /// <summary>
 /// Converts a factor definition for the given factor and speed.
 /// </summary>
 public static Factor ToFactor(this FactorAndSpeed factorAndSpeed)
 {
     if (factorAndSpeed.Direction >= 3)
     {
         return(new Profiles.Factor()
         {
             Direction = (short)(factorAndSpeed.Direction - 3),
             Value = factorAndSpeed.Value
         });
     }
     return(new Profiles.Factor()
     {
         Direction = factorAndSpeed.Direction,
         Value = factorAndSpeed.Value
     });
 }
Exemplo n.º 4
0
 /// <summary>
 /// Converts a speed definition for the given factor and speed.
 /// </summary>
 public static Speed ToSpeed(this FactorAndSpeed factorAndSpeed)
 {
     if (factorAndSpeed.Direction >= 3)
     {
         return(new Profiles.Speed()
         {
             Direction = (short)(factorAndSpeed.Direction - 3),
             Value = 1.0f / factorAndSpeed.SpeedFactor
         });
     }
     return(new Profiles.Speed()
     {
         Direction = factorAndSpeed.Direction,
         Value = 1.0f / factorAndSpeed.SpeedFactor
     });
 }
        /// <summary>
        /// Precalculates speed factors for all the given profiles.
        /// </summary>
        public void CalculateFor(params Profile[] profiles)
        {
            var edgeProfileFactors = new FactorAndSpeed[profiles.Length][];

            for (var p = 0; p < profiles.Length; p++)
            {
                edgeProfileFactors[p] = new FactorAndSpeed[(int)_db.EdgeProfiles.Count];
            }
            for (uint edgeProfile = 0; edgeProfile < _db.EdgeProfiles.Count; edgeProfile++)
            {
                var edgeProfileTags = _db.EdgeProfiles.Get(edgeProfile);
                for (var p = 0; p < profiles.Length; p++)
                {
                    edgeProfileFactors[p][edgeProfile]
                        = profiles[p].FactorAndSpeed(edgeProfileTags);
                }
            }

            for (var p = 0; p < profiles.Length; p++)
            {
                _edgeProfileFactors[profiles[p].FullName] = edgeProfileFactors[p];
            }
        }
Exemplo n.º 6
0
 /// <summary>
 /// Converts a factor definition for the given factor and speed.
 /// </summary>
 public static bool CanStopOn(this FactorAndSpeed factorAndSpeed)
 {
     return(factorAndSpeed.Direction < 3);
 }
Exemplo n.º 7
0
        /// <summary>
        /// Get a function to calculate properties for a set given edge attributes.
        /// </summary>
        /// <returns></returns>
        public sealed override FactorAndSpeed FactorAndSpeed(IAttributeCollection attributes)
        {
            lock (_script)
            {
                // build lua table.
                _attributesTable.Clear();
                if (attributes == null || attributes.Count == 0)
                {
                    return(Profiles.FactorAndSpeed.NoFactor);
                }
                foreach (var attribute in attributes)
                {
                    _attributesTable.Set(attribute.Key, DynValue.NewString(attribute.Value));
                }

                // call factor_and_speed function.
                _resultsTable.Clear();
                _script.Call(_function, _attributesTable, _resultsTable);

                // get the results.
                var   result = new FactorAndSpeed();
                float val;
                if (!_resultsTable.TryGetFloat("speed", out val))
                {
                    val = 0;
                }
                if (val == 0)
                {
                    return(Profiles.FactorAndSpeed.NoFactor);
                }
                result.SpeedFactor = 1.0f / (val / 3.6f); // 1/m/s
                if (_metric == ProfileMetric.TimeInSeconds)
                {                                         // use 1/speed as factor.
                    result.Value = result.SpeedFactor;
                }
                else if (_metric == ProfileMetric.DistanceInMeters)
                { // use 1 as factor.
                    result.Value = 1;
                }
                else
                { // use a custom factor.
                    if (!_resultsTable.TryGetFloat("factor", out val))
                    {
                        val = 0;
                    }
                    result.Value = val;
                }
                if (!_resultsTable.TryGetFloat("direction", out val))
                {
                    val = 0;
                }
                result.Direction = (short)val;
                bool boolVal;
                if (!_resultsTable.TryGetBool("canstop", out boolVal))
                { // default stopping everywhere.
                    boolVal = true;
                }
                if (!boolVal)
                {
                    result.Direction += 3;
                }

                return(result);
            }
        }