I'm moving my SQLite database over to Core Data. My database table looks like this:
CREATE TABLE IF NOT EXISTS stops (id integer primary key autoincrement, type text, lat real, lon real, stop_id integer unique, stop_code integer, title text, subtitle text, url text, lastupdate text
My Entity looks like this:
I'm not worries about moving the data over, it's really just a local cache that gets updated from time to time. If its empty, it will just repopulate.
My issue is I have a SQLite custom function:
static void distanceFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
{
// check that we have four arguments (lat1, lon1, lat2, lon2)
assert(argc == 4);
// check that all four arguments are non-null
if (sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL || sqlite3_value_type(argv[2]) == SQLITE_NULL || sqlite3_value_type(argv[3]) == SQLITE_NULL) {
sqlite3_result_null(context);
return;
}
// get the four argument values
double lat1 = sqlite3_value_double(argv[0]);
double lon1 = sqlite3_value_double(argv[1]);
double lat2 = sqlite3_value_double(argv[2]);
double lon2 = sqlite3_value_double(argv[3]);
// convert lat1 and lat2 into radians now, to avoid doing it twice below
double lat1rad = DEG2RAD(lat1);
double lat2rad = DEG2RAD(lat2);
// apply the spherical law of cosines to our latitudes and longitudes, and set the result appropriately
// 6378.1 is the approximate radius of the earth in kilometres
sqlite3_result_double(context, acos(sin(lat1rad) * sin(lat2rad) + cos(lat1rad) * cos(lat2rad) * cos(DEG2RAD(lon2) - DEG2RAD(lon1))) * 6378.1);
}
The function given a 2 latitudes and 2 longitudes would return the distance. This would let me do something like:
SELECT *, distance(lat, lon, %f, %f) as dist FROM stops WHERE dist < 1 ORDER BY dist
Now, I've got all my data in Core Data, but no idea how to do something like the SQL above with a NSFetchRequest. So how would I go about fetching entities in this manner?
Related
We will get streaming data of many cars on a particular Stream Analytics. Each row will have vehicleId, latitude and longitude of vehicle. I need to raise an alarm whenever distance between ANY two cars is less than suppose x meters.
Right now we can consider radial distance to keep it simple. Hence, we need to calculate distance of cars NOT from a fix point but from other cars ( near by cars can keep changing with time ). Hence, we cannot hard-code vehicle id in the query for sure.
We do have Geo-spatial functions support https://learn.microsoft.com/en-us/stream-analytics-query/geospatial-functions ..
I am not sure if this can even be done by Stream Analytics query directly.
I created a small example of the potential solution, not perfect one perhaps, but it resolves the problem in the ASA job.
Essentially I have re-used javascript function that expects simple latitude and longitude and gives the distance in meters. You can use potentially the geospatial embedded function - I haven't tried to play with that.
So, idea is to cross join input, for all input messages(unfortunately yes, you get duplicated result but it works), and then you apply distance function and filter to the output only those that have a distance less than a threshold value. The following example propagates to the output only if the distance is not zero(it means it compared with itself) and if it is less than 5 meters:
with inputData as (select * from input i1 inner join input i2 ON DATEDIFF(second,i1,i2) BETWEEN 0 AND 5),
distances as (select *, udf.getGeoDistance(i1.lat,i1.long,i2.lat,i2.long) as distance from inputData)
select *
into output
from distances
where distance <> 0 and distance < 5
UDF function:
// Sample UDF which returns sum of two values.
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
'use strict';
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c * 1000; // Distance in m
return d;
}
function deg2rad(deg) {
return deg * (Math.PI / 180);
}
Input:
[
{
"name" : "car1",
"lat" : 59.3293371,
"long" : 13.4877472
},
{
"name" : "car2",
"lat" : 59.293371,
"long" : 13.2619422
},
{
"name" : "car3",
"lat" : 59.3293371,
"long" : 13.4877040
}
]
And result(car1 and car3 are close to each other):
Follow your latest comment,you use tumbling-window and set 5 seconds timeunit to get slice of data.Per my knowledge, you still could not calculate distance of cars each other by sql and Geo-spatial functions directly.Not to mention a warning.
I came up with an idea that you may could use Azure Function as the output of ASA job.Collect the slice of data and send them into Azure Function as json parameter.Inside function,you could write code to calculate the distances between cars each other,even alert warnings to other destinations.
answer_array = np.zeros_like(self.redarray)
answer_array_gpu = cuda.mem_alloc(answer_array.nbytes)
redarray_gpu = cuda.mem_alloc(self.redcont.nbytes)
greenarray_gpu = cuda.mem_alloc(self.greencont.nbytes)
bluearray_gpu = cuda.mem_alloc(self.bluecont.nbytes)
cuda.memcpy_htod(redarray_gpu, self.redcont)
cuda.memcpy_htod(greenarray_gpu, self.greencont)
cuda.memcpy_htod(bluearray_gpu, self.bluecont)
cuda.memcpy_htod(answer_array_gpu, answer_array)
desaturate_mod = SourceModule("""
__global__ void array_desaturation(float *a, float *b, float *c, float *d){
int index = blockIdx.x * blockDim.x + threadIdx.x;
d[index] = ((a[index] + b[index] + c[index])/3);
}
""")
func = desaturate_mod.get_function("array_desaturation")
func(redarray_gpu, greenarray_gpu, bluearray_gpu, answer_array_gpu,
block=(self.gpu_threads, self.gpu_threads, self.blocks_to_use))
desaturated = np.empty_like(self.redarray)
cuda.memcpy_dtoh(desaturated, answer_array_gpu)
print(desaturated)
print("Up to here")
I wrote this piece of code for finding the average of values on three arrays and save it in to a fourth array. The code is neither printing the result, nor the line saying "Up to here". What could be the error?
Additional info: Redarray, greenarray and bluearray are float32 numpy arrays
I know getting started with arrays in C, and especially in PyCUDA can be pretty tricky, it took me months to get a 2D sliding max algorithm working.
In this example, you can't access array elements like you can in Python where you can just provide an index since you are passing a pointer to the memory address to the first element in each array. A useful example for how this works in C can be found here. You will also have to pass in the length for the arrays (assuming they are all equal so that we do not go out of bounds) and if they are of different lengths, all of them respectively.
Hopefully, you can understand how to access your array elements via pointers in C from that link. Then #talonmies provides an nice example here for how to pass in a 2D array (this is the same as a 1D array since the 2D array gets flattened to a 1D one in memory on the GPU). However, when I was working with this, I never passed in the strides which #talonmies does, working like the TutorialsPoint tutorial says *(pointer_to_array + index) is correct. Providing a memory stride here will cause you to go out of bounds.
Therefore my code for this would look more like:
C_Code = """
__global__ void array_desaturation(float *array_A, float *array_B, float *array_C, float *outputArray, int arrayLengths){
int index = blockIdx.x * blockDim.x + threadIdx.x;
if(index >= arrayLengths){ // In case our threads created would be outwise out of the bounds for our memory, if we did we would have some serious unpredictable problems
return;
}
// These variables will get the correct values from the arrays at the appropriate index relative to their unique memory addresses (You could leave this part out but I like the legibility)
float aValue = *(array_A + index);
float bValue = *(array_B + index);
float cValue = *(array_C + index);
*(outputArray + index) = ((aValue + bValue + cValue)/3); //Set the (output arrays's pointer + offset)'s value to our average value
}"""
desaturate_mod = SourceModule(C_Code)
desaturate_kernel = desaturate_mod.get_function("array_desaturation")
desaturate_kernel(cuda.In(array_A), # Input
cuda.In(array_B), # Input
cuda.In(array_C), # Input
cuda.Out(outputArray), # Output
numpy.int32(len(array_A)), # Array Size if they are all the same length
block=(blockSize[0],blockSize[1],1), # However you want for the next to parameters but change your index accordingly
grid=(gridSize[0],gridSize[1],1)
)
print(outputArray) # Done! Make sure you have defined all these arrays before ofc
In my game,if I touch a particular object,coin objects will come out of them at random speeds and occupy random positions.
public void update(delta){
if(isTouched()&& getY()<Constants.WORLD_HEIGHT/2){
setY(getY()+(randomSpeed * delta));
setX(getX()-(randomSpeed/4 * delta));
}
}
Now I want to make this coins occupy positions in some patterns.Like if 3 coins come out,a triangle pattern or if 4 coins, rectangular pattern like that.
I tried to make it work,but coins are coming out and moved,but overlapping each other.Not able to create any patterns.
patterns like:
This is what I tried
int a = Math.abs(rndNo.nextInt() % 3)+1;//no of coins
int no =0;
float coinxPos = player.getX()-coins[0].getWidth()/2;
float coinyPos = player.getY();
int minCoinGap=20;
switch (a) {
case 1:
for (int i = 0; i < coins.length; i++) {
if (!coins[i].isCoinVisible() && no < a) {
coins[i].setCoinVisible(true);
coinxPos = coinxPos+rndNo.nextInt()%70;
coinyPos = coinyPos+rndNo.nextInt()%70;
coins[i].setPosition(coinxPos, coinyPos);
no++;
}
}
break;
case 2:
for (int i = 0; i < coins.length; i++) {
if (!coins[i].isCoinVisible() && no < a) {
coins[i].setCoinVisible(true);
coinxPos = coinxPos+minCoinGap+rndNo.nextInt()%70;
coinyPos = coinyPos+rndNo.nextInt()%150;
coins[i].setPosition(coinxPos, coinyPos);
no++;
}
}
break:
......
......
default:
break;
may be this is a simple logic to implement,but I wasted a lot of time on it and got confused of how to make it work.
Any help would be appreciated.
In my game, when I want some object at X,Y to reach some specific coordinates Xe,Ye at every frame I'm adding to it's coordinates difference between current and wanted position, divided by constant and multiplied by time passed from last frame. That way it starts moving quickly and goes slowly and slowly as it's closer, looks kinda cool.
X += ((Xe - X)* dt)/ CONST;
Y += ((Ye - Y)* dt)/ CONST;
You'll experimentally get that CONST value, bigger value means slower movement. If you want it to look even cooler you can add velocity variable and instead of changing directly coordinates depending on distance from end position you can adjust that velocity. That way even if object at some point reaches the end position it will still have some velocity and it will keep moving - it will have inertia. A bit more complex to achieve, but movement would be even wilder.
And if you want that Xe,Ye be some specific position (not random), then just set those constant values. No need to make it more complicated then that. Set like another constat OFFSET:
static final int OFFSET = 100;
Xe1 = X - OFFSET; // for first coin
Ye1 = Y - OFFSET;
Xe2 = X + OFFSET; // for second coin
Ye2 = Y - OFFSET;
...
I am using the following code to get the locations for the nearest clinics in kms the code works sweet. But what I cant understand is how to get around the parse object only returning 100 objects so I guess my question should be how do i return just a subset that match the current long and lat of the clinics.
I call the below functions in my viewdIdLoadMethod
List<Clinics> _clicics;
_clicics =GetAllNearestFamousPlaces (54.269412, -0.93399086);
public List<Clinics> GetAllNearestFamousPlaces(double currentLatitude,double currentLongitude)
{
List<Clinics> Caldistance = new List<Clinics>();
var query = ParseObject.GetQuery("clinics");
query.FindAsync().ContinueWith(t =>
{
IEnumerable<ParseObject> results = t.Result;
foreach (var obj in results)
{
double distance = Distance(currentLatitude, currentLongitude, obj.Get<double>("lat"), obj.Get<double>("long"));
if (distance < 25) //nearbyplaces which are within 25 kms
{
Clinics dist = new Clinics();
dist.Name = obj.Get<string>("Name");
dist.Latitute = obj.Get<double>("lat");
dist.Longitude =obj.Get<double>("long");
Caldistance.Add(dist);
}
}
});
return Caldistance;
}
private double Distance(double lat1, double lon1, double lat2, double lon2)
{
double theta = lon1 - lon2;
double dist = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * Math.Cos(deg2rad(theta));
dist = Math.Acos(dist);
dist = rad2deg(dist);
dist = (dist * 60 * 1.1515) / 0.6213711922; //miles to kms
return (dist);
}
private double deg2rad(double deg)
{
return (deg * Math.PI / 180.0);
}
private double rad2deg(double rad)
{
return (rad * 180.0 / Math.PI);
}
This may not be syntactically correct - I don't actually use Parse so I'm guessing based on their docs
// assume your point of origin is 54.269412, -0.93399086
// each degree of lat/long is **roughly** 100 km so we'll fudge and +- .5 to narrow down the
// list of clinics
double lat = 54.269412;
double lng = -0.93399086;
double minLong = lng - 0.5;
double maxLong = lng + 0.5;
double minLat = lat - 0.5;
double maxLat = lat + 0.5;
var query = from clinic in ParseObject.GetQuery("clinics")
where clinic.Get<double>("lat") >= minLat
and clinic.Get<double>("lat") <= maxLat
and clinic.Get<double>("long") >= minLat
and clinic.Get<double>("long") <= maxLat
select clinic;
// 1000 is the max we can request at a time
query = query.Limit(1000);
// now execute your query to get the results, and then use your Distance() function to calculate
// the precise distance and remove results that are to far away, etc
I have a cassandra table with user name, latitude and longitude. I would like to get a list of users who are inside the circle with a given latitude, longitude and distance.
For example: my input Lat= 78.3232 and Long = 65.3234 and distance = 30 miles.
I would like to get a list of users who are within 30 miles distance from the point 78.3232 and 65.3234. Is it possible to solve this with single CQL3 query? Or can anyone give me a hint start solving this query?
There was no geospatial support for cassandra so I found a way to Implement it mathematically to generate box coordinates around the point (That was good enough for my work) and use query to get coordinates within boundary.
I'll post the code for others reference.
public class GeoOperations {
public static final int UPPER_LATITUDE = 0;
public static final int LOWER_LATITUDE = 1;
public static final int UPPER_LONGITUDE = 2;
public static final int LOWER_LONGITUDE = 3;
private static final double KM_TO_MILES = 0.621371;
private final double Latitude;
private final double Longitude;
double Boundary[];
public GeoOperations(double init_latitude, double init_longitude) {
Latitude = init_latitude;
Longitude = init_longitude;
Boundary = new double[4];
}
public void GenerateBoxCoordinates(double Distance) {
Distance = Distance * KM_TO_MILES;
double Lat_Factor = (Distance) / 69;
Boundary[UPPER_LATITUDE] = Latitude + Lat_Factor;
Boundary[LOWER_LATITUDE] = Latitude - Lat_Factor;
double Long_Factor = (Distance) / (3960 * 2 * Math.PI / 360 * Math.cos(Latitude));
Boundary[UPPER_LONGITUDE] = Longitude + Long_Factor;
Boundary[LOWER_LONGITUDE] = Longitude - Long_Factor;
for (double x : Boundary) {
System.out.println(x);
}
}
}
And then Used Simple CQL to find coordinates within ranges
if values are like this
UPPER_LATITUDE = 60
LOWER_LATITUDE = 40
UPPER_LONGITUDE = 10
LOWER_LONGITUDE = 5
Query will be something like this (actually I used kundera with Hibernate and used a JPA query. So I havent tested it but it should work)
SELECT * FROM Points_Tablle
WHERE LATITUDE > 40
AND LATITUDE < 60
AND LONGITUDE > 5
AND LONGITUDE < 10;
If you're using DataStax enterprise, you get Geospatial out of the box. Check out Patrick's Demo:
https://github.com/PatrickCallaghan/datastax-geospatial-demo