I am working on an app where I have a set of pre-defined co-ordinates stored in an array like the one below:
var SpeedcameraLocationDictionary: [[String : AnyObject]] = [
["camindex": "1a", "Latitude":xxxx, "Longitude":xxxx,"Distance":34, "legalspeed":110],
["camindex": "1b", "Latitude":xxxx, "Longitude":xxxx,"Distance":34, "legalspeed":110],
["camindex": "2a", "Latitude":xxxx, "Longitude":xxxx,"Distance":26, "legalspeed":110],
["camindex": "2b", "Latitude":xxxx, "Longitude":xxxx,"Distance":26, "legalspeed":110]]
What I want to do is, when the users location matches any lat & long in the array (+ or - 5 meters) , start doing some calculations. I have variables set up to hold the lat & long of the user, and the relevant CLLocation manager. Implanting on checking the users location every 30 secs, so i have a timer set up to trigger at 30sec intervals.
I believe I need to set up a geofence around the relevant point, but I'm not really sure how to do the check & set up.
I imagine it would be along the lines of the following:
if Timer = 30secs
let region = CLCircularRegion(center: Latitudefromarray,longitudefromarray, radius: 5,)
if (Latitude +/- 5m == region AND longitude +/- 5m == region)
do calculations....
could somebody either point me in the direction of a tutorial that could help me achieve this goal, or provide some sample code to achieve the goal I'm after? i have been following this tutorial but am struggling to adapt it to my needs.
Thanks
Related
I am making a practice simple app as I am learning swiftUI. My current problem seems to lie in this function:
variables
#State var cameras: [Camera] = []
#State var angle: Double = 0.0
func fetchAngle(){
COLLECTION_CAMERAS.whereField("active", isEqualTo: true).addSnapshotListener { snapshot, _ in
self.cameras = snapshot!.documents.compactMap({ try? $0.data(as: Camera.self)})
self.angle = cameras[0].angle
}
There can only be one active camera out of the three.
I know its bad practice but all the program is in the MainView() for simplicity, after I finish debugging I will use MVVM.
The angle variable is #Published, because I want to redraw the user interface when its updated.
The there is a set of 3 buttons and each time I press one of them, successfully update in firebase the active field to true or false.
As there are three cameras I fetch the collection and wish to only get the camera where the active field is true. So far so good, my problem starts (I think) with this code self.angle = cameras[0].angle. What I wish to achieve is to be able to set self.angle with the angle of the only camera that has active == true.
I have an NSManagedObject class that's persisted in a SQLite database in Core Data. This object has persistent Latitude and Longitude properties. I'm trying to create an NSFetchedRequestController that fetches all of the instances of that class that are within a certain distance from the user. Having done some research, it seems impossible to do this with Core Data, because Core Data only supports bounding-box style queries, not predicates with blocks.
For example, I have a class of Groups with latitude and longitude properties. Given the latitude and longitude (of, say, a user), fetch all groups that are within a 6 mile radius of the given latitude and longitude.
class Group{
var latitude: Float
var longitude: Float
}
I'd like to take advantage of Core Data's R-Tree Indexing to do a fast bounding-box query on the latitudes and longitudes of instances of my class near my user. Then I'd like to filter the results with a more precise predicate, using my own block of code to see which of the instances are within my users current location. Here's the "Bounding box" query.
let request: NSFetchRequest<Group> = Group.fetchRequest()
let (topLeft,bottomRight) = boundingBox(center: center, radius: searchRadius)
let maxLat = topLeft.latitude
let minLon = topLeft.longitude
let minLat = bottomRight.latitude
let maxLon = bottomRight.longitude
let predicate = NSPredicate(format: "(%f < longitude AND longitude < %f) AND (%f < latitude AND latitude < %f)", minLon, maxLon, minLat, maxLat)
request.predicate = predicate
The problem is that I'd like a fetch that looked like this:
let location: CLLocation = /* Initialize a CLLocation */
let predicate = NSPredicate { (obj, _) -> Bool in
let object = obj as! Group
let objLocation = CLLocation(latitude: Double(object.latitude), longitude: Double(object.longitude))
return location.distance(from: objLocation) < 9656 //6 miles in meters
}
NSFetched results controller doesn't allow predicate with block. There's a significant difference between these two fetches. The first gets all groups in a Bounding Box, (the minLat, minLon, maxLat, and maxLat), the latter gets all groups in a Circle of a given radius.
I want to then use an NSFetchedRequestController to display the results in a table, and take advantage of the nice auto-update features. But of course, Core Data only supports bounding-box style queries, not the two-step filter method I need. Is there a proper solution?
I'm open to using other databases, if Core Data simply won't work with this type of use. I took a look at YapDatabase, and it seems more flexible, and includes R-Tree indexing, but I'm concerned that it's not well supported. Realm doesn't support R-Tree Indexing.
I am new to AzureMap with limited knowledge of JavaScript and looking help in getting the real time alert based on some random flag during the fleet movement based on the co ordinates .
I tried multiple sources to design it like followed Sample code enter link description here
My requirement is :
Pip should pop up or appear only on arrival of the fleet (truck) .
Thanks
To verify, when the truck gets to the end of the line you want to open a popup. I'm assuming you have a constant flow of data updating the truck position and that you can easily grab the trucks coordinate. As such you would only need a function to determine if the truck coordinate is at the end of the route line. You will likely need to account for a margin of error (i.e. within 15 meters of the end of the line) as a single coordinate can represent a single molecule with enough decimal places and GPS devices typically have an accuracy of +/- 15 meters. With this in mind all you would need to do is calculate the distance from the truck coordinate to the last coordinate of the route line. For example:
var lastRouteCoord = [-110, 45];
var truckCoord = [-110.0001, 45.0001];
var minDistance = 15;
//Get the distance between the coordinates (by default this function returns a distance in meters).
var distance = atlas.math.getDistanceTo(lastRouteCoord, truckCoord);
if(distance <= minDistance){
//Open popup.
//Examples: https://azuremapscodesamples.azurewebsites.net/index.html#Popups
}
I've created a game which loops through a table of properties to create enemies to place on screen. The created enemies are stored in a variable called "baddie", and things like their x and y value are determined by the properties I gave them in the table. Currently, "baddie" creates 3 enemies at varying spots on screen. It looks something like this.
for i=1, #level[section]["enemies"] do
local object = level[section]["enemies"][i]
baddie = display.newSprite(baddieSheet, baddieData)
baddie.anchorX = 0.5
baddie.anchorY = 1
baddie.x = object["position"][1]; baddie.y = object["position"][2];
baddie.xScale = -1
baddie.myName = "Baddie"
baddie.health = 15
baddie:setSequence("standrt"); baddie:play()
physics.addBody(baddie, "dynamic", {radius=22, density=0.1, friction=10.0, bounce=0.0})
baddie.isFixedRotation = true
enemyGroup:insert(baddie)
end
I then inserted all of the created instances stored in the baddie variable, into a display group called "enemyGroup."
Now here's my question. I'm working on my game's AI and storing it all in an enterFrame listener. I want to make a "True/False" flag called "inRange." When the enemy's x position is within 20 pixels of the player's x, inRange = true. When it's true, the enemy will attack him. But I haven't figured out a way to make the inRange flag check for each individual enemy, instead of all of them.
I was thinking of something like,
for i = 1, enemyGroup.numChildren do
enemyGroup[i].widthBetween = enemyGroup[i].x - sprite.x
if enemyGroup[i].widthBetween <= 20 and enemyGroup[i].widthBetween >= -20 then
enemyGroup[i].inRange = true
else
enemyGroup[i].inRange = false
end
end
But the issue is, enemyGroup[i].inRange is a local value and I can't call for it in outside of the loop or in other functions. This is obviously problematic, because in another function I want to have each individual enemy punch, roll, jump, etc when their individual inRange property is true. Is there a way I can store enemyGroup[i].inRange so that I can call for it whenever?
Sorry if this question is confusing. It's been a struggle to word it.
I'm not sure why this isn't working for you. enemyGroup[i].inRange is not local, its an attribute of the object at enemyGroup[i]. It should be avalble anywhere you can access enemyGroup[i].
Personally I would have not used a display.newGroup() for this, instead I would have just created an array/table that's scoped for the whole scene.
local baddies = {}
then in your loop:
--enemyGroup:insert(baddie) instead of this, do this:
baddies[#baddies + 1] = baddie
Then you have a table that you can loop over, but it's really more code style than functionality. As long as your enemyGroup is scoped at a high enough level that any function that the scene can see.
you should create a file in the structure below:
module(..., package.seeall)
enemyGroup = {}
and in all your files where you want to use this table, first of all require this file( assume you named this file enemies.lua):
local enemiesArray = require "enemies"
-- somewhere in your code:
enemiesArray.enemyGroup[i].isRange = true -- or whatever you like to do
there is one better option for you to use _G variable. when you store an object to _G you can access that wherever you want( like the famous design pattern Singleton ). just set the variable one time and use it anywhere and as much as you want. for example:
-- in one file you set enemy table:
_G.enemies = enemyGroup
-- somewhere else in nowhere :)
print(_G.enemies.isRange)
I have a model in angularJS which is bound to firebase $scope.items=$firebase(blah) and I use ng-repeat to iterate through the items.
Every item in firebase has a corresponding geofire location by the key of the item.
How can I update my controller to only include items by a custom radius around the user? I don't want to filter by distance in angular, just ask firebase to only retrieve closer items (say 0.3km around a location). I looked around geoqueries but they have a different purpose and I don't know how to bind them to the model anyway. The user may change the radius and the items list should be updated accordingly, so they need to be bound somehow.
Any suggestion is welcome, but an example would be greatly appreciated as I don't have fluency in this trio of angular/firebase/geofire yet :P
It's difficult to figure out what you need to do without seeing your code. But in general you'll need to query a Firebase ref that contains the Geohash as either the name of the child or the priority.
A good example of such a data structure can be found here: https://publicdata-transit.firebaseio.com/_geofire/i
i
9mgzcy8ewt:lametro:8637: true
9mgzgvu3hf:lametro:11027: true
9mgzuq55cc:lametro:11003: true
9mue7smpb9:nctd:51117: true
...
l
...
lametro:11027
0: 33.737797
1: -118.294708
actransit:1006
actransit:1011
actransit:1012
...
The actual transit verhicles are under the l node. Each of them has an array contains the location of that vehicle as a longitutude and latitude pair.
The i node is an index that maps each vehicle to a Geohash. You can see that the name of each node is built up as <geohash>:<metroarea>:<vehicleid>.
Since the Geohash is at the start of the name, we can filter on Geohash with a Query:
var ref = new Firebase("https://publicdata-transit.firebaseio.com/_geofire");
var query = ref.child('i').startAt(null, '9mgzgvu3ha').endAt(null, '9mgzgvu3hz');
query.once('child_added', function(snapshot) { console.log(snapshot.name()); });
With this query Firebase will give us all nodes whose name falls within the range. If all is well, this will output the name of one node:
9mgzgvu3hf:lametro:11027
Once you have that node, you can parse the name to extract the vehicleid and then lookup the actual location of the vehicle under l.
Calculating Geohashes based on a location and a range
In the snippet above, I hardcoded the geohash values to use. Normally you'll want to to get all nodes in a certain range around a center. Instead of calculating these yourself, I recommend using the geohashQueries function from GeoFire for that:
var whitehouse = [38.8977, -77.0366];
var rangeInKm = 0.3;
var hashes = geohashQueries(center, radiusInKm*1000);
console.log(JSON.stringify(hashes));
This outputs a number of Geohash ranges:
[["dqcjqch","dqcjqc~"],["dqcjr10","dqcjr1h"],["dqcjqbh","dqcjqb~"],["dqcjr00","dqcjr0h"]]
You can pass each of these Geohash ranges into a Firebase query:
hashes.forEach(function(hash) {
var query = geoFireRef.child('i').startAt(null, hash[0]).endAt(null, hash[1]);
query.once('child_added', function(snapshot) { log(snapshot.name()); });
});
I hope this helps you settings things up.
Here is a Fiddle that I created a while ago to experiment with this stuff: http://jsfiddle.net/aF9mN/.