Ejemplo n.º 1
0
        /// <summary>
        /// Post the user's location.
        /// 
        /// When a new location is uploaded, we need to
        /// 1) Determine if that location is within the radius of a place in the places collection
        /// 2) If it is inside a place, add it to the place.usersInPlace array if it is not already there
        /// 3) If there is an entry trigger, and the user's previous location does not exist or was outside the place, run the entry trigger
        /// 4) If it was inside a place, and it is now outside of the place, remove it from the place.usersInPlace array if it is there
        /// 5) If there is an exit trigger, and the user's previous location exists and was inside the place, run the exit trigger
        /// </summary>
        /// <param name="request">LocationRequest</param>
        public LocationResponse Post(LocationRequest request)
        {
            Location location = new Location ();
            location.user_id = request.user_id;
            if (request.create_date == DateTime.MinValue) {
                location.create_date = DateTime.Now;
            } else {
                location.create_date = request.create_date;
            }

            location.loc = new GeoJson2DGeographicCoordinates (request.longitude, request.latitude);

            //Insert the location into the locations collection
            locationscollection.Insert (location);

            //if we have a locationLimit from the appSettings, then each time we insert for a user, remove all but the limit from the collection;
            if (locationLimit > 0) {
                var query = Query<LocationRequest>.EQ (l => l.user_id, request.user_id);
                var entities = locationscollection.Find (query).OrderByDescending (l => l.Id).Skip (locationLimit);
                foreach (var entity in entities) {
                    locationscollection.Remove (Query.EQ ("_id", entity.Id));
                }

            }

            //Store found placeIDs and trigger types in a dictionary
            Dictionary<ObjectId, string> dictPlaces = GetPlacesByLocation (request);

            //For each entry in the dictionary,
            //if ENTER, then run enter trigger where placeID = placeID and type = ENTER
            //if EXIT, then run exit trigger where placeID = placeID and type = EXIT

            foreach (KeyValuePair<ObjectId, string> de in dictPlaces) {
                //Update the place by placeID with the userID based on the type
                //if ENTER, add the user to the place.usersInPlace dictionary
                //if EXIT, remove the user from the place.usersInPlace dictionary
                //RunTrigger (de.Key, de.Value);
            }

            LocationResponse response = new LocationResponse ();
            response.responseStatus = new ResponseStatus ();
            response.responseStatus.ErrorCode = "200";
            response.responseStatus.Message = "SUCCESS";
            return response;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets the places by location.
        /// </summary>
        /// <returns>The places by location.</returns>
        /// <param name="request">Request.</param>
        Dictionary<ObjectId, string> GetPlacesByLocation(LocationRequest request)
        {
            var earthRadius = 6378.0; // km

            Dictionary<ObjectId, string> dictPlaces = new Dictionary<ObjectId, string> ();

            //Get places
            MongoCollection<PlaceResponse> placescollection = db.GetCollection<PlaceResponse> ("place");
            MongoCollection<Location> locationscollection = db.GetCollection<Location> ("location");

            if (!BsonClassMap.IsClassMapRegistered (typeof(PlaceResponse))) {
                BsonClassMap.RegisterClassMap<PlaceResponse> ();
            }
            if (!BsonClassMap.IsClassMapRegistered (typeof(Location))) {
                BsonClassMap.RegisterClassMap<Location> ();
            }

            placescollection.EnsureIndex (IndexKeys.GeoSpatialSpherical ("loc"));

            foreach (var place in placescollection.FindAll ()) {

                //Set the query to determine if the new location is in each place
                var icquery = Query.WithinCircle ("loc", place.loc.Longitude, place.loc.Latitude, place.radius / earthRadius, false);

                //Debug
                Console.WriteLine (icquery);

                //Get all locations for user by createdate desc
                var locs = locationscollection.FindAll ().Where (u => u.user_id == request.user_id).OrderByDescending (l => l.create_date);
                //Get all locations inside place for user by createdate desc
                var locsinsideplace = locationscollection.Find (icquery).Where (l => l.user_id == request.user_id).OrderByDescending (l => l.create_date);

                List<Location> listlocs = new List<Location> ();
                List<Location> listlocsinsideplace = new List<Location> ();

                //get the total list of locations for the given user into a list
                listlocs = locs.ToList ();

                //get the list of locations that are in this place
                listlocsinsideplace = locsinsideplace.ToList ();

                int idxCurrentLocation = -1;
                int idxPriorLocation = -1;

                idxCurrentLocation = listlocsinsideplace.FindIndex (l => l.Id == listlocs [0].Id);
                Console.WriteLine ("idxCurrentLocation: " + idxCurrentLocation);

                if (listlocs.Count > 1) {
                    idxPriorLocation = listlocsinsideplace.FindIndex (l => l.Id == listlocs [1].Id);
                    Console.WriteLine ("idxPriorLocation: " + idxPriorLocation);
                }
                //if idxCurrentLocation = -1 and idxPriorLocation = -1 location not in place
                if (idxCurrentLocation == -1 && idxPriorLocation == -1) {
                    Console.WriteLine ("Not in place");
                }
                //if idxCurrentLocation = 0 and idxPriorLocation = -1 ENTER
                else if (idxCurrentLocation == 0 && idxPriorLocation == -1) {
                    dictPlaces.Add (place.Id, "ENTER");
                    //If an enter trigger exists on the place, fire the trigger and add the user to the place
                    place.usersInPlace.AddIfNotExists (request.user_id);
                    placescollection.Save (place);
                    Console.WriteLine ("Execute ENTER trigger");
                }
                //if idxCurrentLocation = -1 and idxPriorLocation = 0 EXIT
                else if (idxCurrentLocation == -1 && idxPriorLocation == 0) {
                    dictPlaces.Add (place.Id, "EXIT");
                    //If an exit trigger exists on the place, fire the trigger and remove the user to the place
                    place.usersInPlace.Remove (request.user_id);
                    placescollection.Save (place);
                    Console.WriteLine ("Execute EXIT trigger");
                }
                //if idxCurrentLocation = 0 and idxPriorLocation >= 0 STILL IN PLACE
                else if (idxCurrentLocation == 0 && idxPriorLocation >= 0) {
                    Console.WriteLine ("Still in place");
                }

                /*
                //If the list of locations inside the place has a count > 1, and the id of the location inside the place is the most current, and the second location is not inside the place, then the user has entered the place
                if (listlocsinsideplace.Count >= 1 && listlocs.Count > 1 && listlocs [0].Id == listlocsinsideplace [0].Id && listlocs [1].Id == listlocsinsideplace [0].Id) {
                    dictPlaces.Add (place.Id, "ENTER");
                    //If an enter trigger exists on the place, fire the trigger and add the user to the place
                    place.usersInPlace.AddIfNotExists (request.user_id);
                    placescollection.Save (place);
                    Console.WriteLine ("Execute ENTER trigger");
                }
                //If the list of locations inside the place has a count > 1, and the id of the location inside the place is the second location, and the first location is not inside the place, then the user has left the place
                else if (listlocsinsideplace.Count >= 1 && listlocs.Count > 1 && listlocs [1].Id == listlocsinsideplace [0].Id && listlocs [0].Id != listlocsinsideplace [0].Id) {
                    dictPlaces.Add (place.Id, "EXIT");
                    //If an exit trigger exists on the place, fire the trigger and remove the user to the place
                    place.usersInPlace.Remove (request.user_id);
                    placescollection.Save (place);
                    Console.WriteLine ("Execute EXIT trigger");
                }
                //If the list of locations inside the place has a count of 1, then the user is new to the place
                else if (listlocsinsideplace.Count == 1) {
                    dictPlaces.Add (place.Id, "ENTER");
                    //If an enter trigger exists on the place, fire the trigger and add the user to the place
                    place.usersInPlace.AddIfNotExists (request.user_id);
                    placescollection.Save (place);
                    Console.WriteLine ("Execute ENTER trigger");
                } else {
                    Console.WriteLine ("Still in place");
                }
                */

            }

            return dictPlaces;
        }