I have a collection of objects in a set which have Longitude and lattitude as properties. Now I want to get all those objects which are in a certain distance say 50 mile radius of an input longitude and lattitude. What data structure I should use and algorithm for searching all those points.
Took the help of below code to solve my problem.
package com.csc.banking.celeriti.cache.srv.utils;
public class GeoDistanceCalculator {
private static double distance(double lat1, double lon1, double lat2, double lon2, char unit) {
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;
if (unit == 'K') {
dist = dist * 1.609344;
} else if (unit == 'N') {
dist = dist * 0.8684;
}
return (dist);
}
public static double distanceKms(double lat1, double lon1, double lat2, double lon2){
return distance(lat1, lon1, lat2, lon2, 'K');
}
public static double distanceNauticalMiles(double lat1, double lon1, double lat2, double lon2){
return distance(lat1, lon1, lat2, lon2, 'N');
}
public static double distanceMiles(double lat1, double lon1, double lat2, double lon2){
return distance(lat1, lon1, lat2, lon2, 'M');
}
private static double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
private static double rad2deg(double rad) {
return (rad * 180 / Math.PI);
}
public static void main(String[] args) {
System.out.println(distance(32.9697, -96.80322, 29.46786, -98.53506, 'M') + " Miles\n");
System.out.println(distance(32.9697, -96.80322, 29.46786, -98.53506, 'K') + " Kilometers\n");
System.out.println(distance(32.9697, -96.80322, 29.46786, -98.53506, 'N') + " Nautical Miles\n");
System.out.println(distance(28.6207641, 77.36392920000003, 28.6314512, 77.21666720000007, 'K') + " Connaught Place Delhi to Noida 62\n");
}
}
Related
I have a spline interpolation formula.
UE4 -> UnrealMathUtility.h
template< class T, class U >
static FORCEINLINE_DEBUGGABLE T CubicInterp( const T& P0, const T& T0, const T& P1, const T& T1, const U& A )
{
const float A2 = A * A;
const float A3 = A2 * A;
return (T)(((2*A3)-(3*A2)+1) * P0) + ((A3-(2*A2)+A) * T0) + ((A3-A2) * T1) + (((-2*A3)+(3*A2)) * P1);
}
P0\P1 - start/end point
T0\T1 - start/end tangent
How can I calculate normals at each point?
I recently discovered spatial columns in Microsoft SQL.
I have now successfully stored LINESTRING sqlgeometry with correct EPSG (STRID). Checked by using AutoCAD Map.
The data is now sqlgeometry LINESTRINGs containing groups of X Y coordinates.
Using C# (or an sql statement), how do I get latitude and longitude values of the coordinate points?
What you need is reprojection onto spherical coordinates.
SQL Server does not provides such functionality. You need some plumbing in C# to get your geometries and project coordinates.
If you have your conversion function, using a GeometrySink is fast and would help.
internal class SqlGeometryProjectionSink : IGeometrySink110
{
IGeometrySink110 _sink;
int _outSrid;
Func<double, double, double[]> _coordTransform;
public SqlGeometryProjectionSink(IGeometrySink110 p_Sink, int outSrid, Func<double, double, double[]> coordTransform)
{
_sink = p_Sink;
_outSrid = outSrid;
_coordTransform = coordTransform;
if (_coordTransform == null)
{
_coordTransform = new Func<double, double, double[]>((x, y) => new double[] { x, y });
}
}
void IGeometrySink.AddLine(double x, double y, double? z, double? m)
{
double[] proj = _coordTransform(x, y);
_sink.AddLine(proj[0], proj[1], z, m);
}
void IGeometrySink.BeginFigure(double x, double y, double? z, double? m)
{
double[] proj = _coordTransform(x, y);
_sink.BeginFigure(proj[0], proj[1], z, m);
}
void IGeometrySink.BeginGeometry(OpenGisGeometryType type)
{
_sink.BeginGeometry(type);
}
void IGeometrySink.EndFigure()
{
_sink.EndFigure();
}
void IGeometrySink.EndGeometry()
{
_sink.EndGeometry();
}
void IGeometrySink.SetSrid(int srid)
{
_sink.SetSrid(_outSrid);
}
public static SqlGeometry ReprojectGeometry(SqlGeometry geom, int srid, Func<double, double, double[]> coordTransform)
{
if (geom != null)
{
SqlGeometryBuilder builder = new SqlGeometryBuilder();
SqlGeometryProjectionSink sink = new SqlGeometryProjectionSink(builder, srid, coordTransform);
geom.Populate(sink);
return builder.ConstructedGeometry;
}
return null;
}
void IGeometrySink110.AddCircularArc(double x1, double y1, double? z1, double? m1, double x2, double y2, double? z2, double? m2)
{
throw new NotImplementedException();
}
}
If you don't know the formula you can use for example DotSpatial which provides transformations functions. (see here for an implementation example : https://github.com/xfischer/SqlServerSpatial.Toolkit/blob/4a60154f206af430b27de730afd0340db19f9191/SqlServerSpatial.Toolkit/Viewers/GDI/SqlGeometryReprojection.cs)
When I try to caculate sinh−1(x) using functions:
double asinh_recursion(double buf, double increment, double input_var, unsigned long item_count) {
if (fabs(increment) < 1E-5) {
return buf;
}
return asinh_recursion(buf + increment, increment * (-1) * (2 * item_count - 1) * (2 * item_count -1) / (2 * item_count + 1) / 2 / item_count * input_var, input_var, item_count + 1);
}
double asinh(double x) {
if (!(fabs(x) < 1.0)) {
printf("error asinh():wrong param x(fabs(x) > 1.0)");
return -1.0;
}
return asinh_recursion(0.0, x, x * x, 1);
}
it seem works.
but when I try to use block and Y-Combinator to do it:
typedef void * (^YCBlock)(void *);
YCBlock Y;
double asinh_with_block(double x) {
if (!(fabs(x) < 1.0)) {
printf("error asinh():wrong param x(fabs(x) > 1.0)");
return -1.0;
}
Y= (YCBlock) ^ (YCBlock f) {
return (YCBlock) ^ (YCBlock g) {
return g(g);
}(
(YCBlock) ^ (YCBlock h) {
return f(^ (void * x) { return ((YCBlock)h(h))(x); });
}
);
};
typedef double (^ RECUR_BLK_TYPE)(double, double, unsigned long);
RECUR_BLK_TYPE recur_block = Y(^(RECUR_BLK_TYPE recur_block){
return Block_copy(^ double (double buf, double increment, unsigned long item_count){
if (item_count < 4) {
printf("param:%lf,%lf,%lu\n", buf, increment, item_count);
}
if (fabs(increment) < 1E-5) {
return buf;
}
buf = buf + increment;
increment = increment * (-1) * (2 * item_count - 1) * (2 * item_count -1) / (2 * item_count + 1) / 2 / item_count * (x * x);
++item_count;
if (item_count < 4) {
printf("\tbuf:%lf\n", buf);
}
return recur_block(buf, increment, item_count);
});
});
double ret = recur_block(0, x, 1);
Block_release(recur_block);
Block_release(Y);
return ret;
}
but it works strangely in the output(x=0.5):
param:0.000000,0.500000,1
buf:0.500000
param:0.500000,-0.020833,2
buf:0.479167
param:0.500000,0.002344,3
...
asinh_with_block(0.500000):0.500000
it seem like that in the block, at some time,when I pass buf=0.479167, next time when I print it, it is still 0.500000.
I wanna to find why it works like this, maybe I wrote some wrong code at somewhere...
The problem is that your Y combinator is only made to work with an underlying function that takes one void * parameter and returns a void *. You can see that in the line:
return f(^ (void * x) { return ((YCBlock)h(h))(x); });
The block in there that takes x (one argument) and passed the x to another thing as one argument. For it to work with a recursive function of multiple arguments, this function must take those multiple arguments and pass them all on (of course, the types all need to be right too, because different types have different sizes, and the ABI for passing and returning things of different types is different). So you will need a different Y combinator for each function signature.
You have a recursive function that takes three parameters (two doubles and an unsigned long) and returns a double. You can (minimally) make it work by changing the relevant block in the Y combinator and coercing it from the wrong type to the right type:
return f(^ (double buf, double increment, unsigned long item_count) {
return ((RECUR_BLK_TYPE)((YCBlock)h(h)))(buf, increment, item_count);
});
But to really make it clean with correct type safety without this unsafe casting would require you to carefully set up the types. Something like this:
typedef double (^Func)(double, double, unsigned long);
typedef Func (^FuncFunc)(Func);
typedef Func (^RecursiveFunc)(void *);
typedef Func (^YCBlock)(FuncFunc);
Y = ^(FuncFunc f) {
return ^(RecursiveFunc g) {
return g(g);
}(
^(void *temp) {
RecursiveFunc h = temp; // trick to hide the recursive typing
return f(^(double buf, double increment, unsigned long item_count) {
return h(h)(buf, increment, item_count);
});
}
);
};
I've been looking at the Vala programming language over the past few days, and it looks promising. However, I can't figure out how to properly assign a constant (currently the Vala equivalent to final) in object construction. For example, in Java:
import java.lang.Math;
public class Rectangle {
public final double sideA;
public final double sideB;
public final double area;
public final double diagonal;
public Rectangle (double SideA, double SideB) {
sideA = SideA;
sideB = SideB;
area = SideA * SideB;
diagonal = Math.sqrt(Math.pow(SideA, 2) + Math.pow(SideB, 2));
}
}
How would this be written in Vala?
Vala doesn't have a direct equivalent of Java's final keyword. I think the closest you are going to be able to come is something like this:
public class Rectangle : GLib.Object {
public double sideA { get; construct; }
public double sideB { get; construct; }
public double area { get; construct; }
public double diagonal { get; construct; }
public Rectangle (double SideA, double SideB) {
GLib.Object (
sideA: SideA,
sideB: SideB,
area: SideA * SideB,
diagonal: Math.sqrt(Math.pow(SideA, 2) + Math.pow(SideB, 2)));
}
}
construct properties are a bit different from final, largely because of how GObject construction works. They can only be set at construct time, but unlike final in Java (IIRC... most of my Java knowledge has been repressed) they can also be set during construct by a subclass. For example, this is perfectly acceptable:
public class Square : Rectangle {
public Square (double Side) {
GLib.Object (
sideA: Side,
sideB: Side,
area: Side * Side,
diagonal: Math.sqrt(Math.pow(Side, 2) + Math.pow(Side, 2)));
}
}
So, if you want to allow GObject-style construction (which I would suggest you do if you are making a library other people will call... if the code is just for you there is no need), you might want to do something more like this:
public class Rectangle : GLib.Object {
public double sideA { get; construct; }
public double sideB { get; construct; }
private double? _area = null;
public double area {
get {
if ( _area == null )
_area = sideA * sideB;
return _area;
}
}
private double? _diagonal = null;
public double diagonal {
get {
if ( _diagonal == null )
_diagonal = Math.sqrt(Math.pow(sideA, 2) + Math.pow(sideB, 2));
return _diagonal;
}
}
public Rectangle (double SideA, double SideB) {
GLib.Object (
sideA: SideA,
sideB: SideB,
area: SideA * SideB,
diagonal: Math.sqrt(Math.pow(SideA, 2) + Math.pow(SideB, 2)));
}
}
I have been trying to create a list of general global C functions for various classes to use, and although i've done this in the past, this one is having problems. Here are the .h and .c parts of the list.
CGGeometry.h
//CDPoint
//////////////////////////////////////////////////////////////////////
typedef struct CDPoint {
CGFloat x, y, z;
} CDPoint;
// Creates a CDPoint from 3 float numbers
CDPoint CDPointMake(float x, float y, float z);
//CDLine
//////////////////////////////////////////////////////////////////////
typedef struct CDLine {
CDPoint a, b;
} CDLine;
// Creates a CDPoint from 2 CDPoints
CDLine CDLineMake(CDPoint a, CDPoint b);
//CDVector
//////////////////////////////////////////////////////////////////////
typedef struct CDVector {
CDPoint start, finish;
CDPoint gradient;
} CDVector;
// Creates a CDVector from 2 CDPoints
CDVector CDVectorMake(CDPoint startPoint, CDPoint endPoint);
// Returns a point travelled to on a given vector, using a start point and a distance scalar.
CDPoint CDVectorTrace(CDVector vecToTrace, CDPoint startPoint, float distance);
//CDExtra
//////////////////////////////////////////////////////////////////////
// This is stuff that shoudn't really be in this section, but are for convenience purposes until it has enough functions to be standalone.
GLfloat* CDMeshColorsCreateGrey(CGFloat bValue, CGFloat vertCount);
CGFloat* CDMeshVertexesCreateRectangle(CGFloat height, CGFloat width);
CDGeometry.c
#include "CDGeometry.h"
//CDGeometry.c
/* A collection of functions and typedefs that aid 2D and 3D environment positioning and provides methods for objects and processes. Also includes elements relevant to collision detection. */
//CDPoint
//////////////////////////////////////////////////////////////////////
CDPoint CDPointMake(float x, float y, float z)
{
return (CDPoint) {x, y, z};
}
//CDLine
//////////////////////////////////////////////////////////////////////
CDLine CDLineMake(CDPoint a, CDPoint b)
{
return (CDLine) {a, b};
}
//CDVector
//////////////////////////////////////////////////////////////////////
CDVector CDVectorMake(CDPoint startPoint, CDPoint endPoint)
{
CDPoint grad = CDPointMake(startPoint.x / endPoint.x,
startPoint.y / endPoint.y,
startPoint.z / endPoint.z);
return (CDVector) {startPoint, endPoint, grad};
}
//CDExtra
/////////////////////////////////////////////////////////////////////
GLfloat* CDMeshColorsCreateGrey(CGFloat bValue, CGFloat vertCount)
{
GLfloat *greyColor = (GLfloat *) malloc(vertCount * 4 * sizeof(GLfloat));
int index = 0;
for (index = 0; index < (vertCount); index++)
{
int position = index * 4;
greyColor[position] = bValue;
greyColor[position + 1] = bValue;
greyColor[position + 2] = bValue;
greyColor[position + 3] = 1.0;
}
return greyColor;
}
CGFloat* CDMeshVertexesCreateRectangle(CGFloat height, CGFloat width) {
CGFloat *squareVertexes = (CGFloat *) malloc(8 * sizeof(CGFloat));
squareVertexes[0] = -(width / 2);
squareVertexes[1] = -(height / 2);
squareVertexes[2] = (width / 2);
squareVertexes[3] = -(height / 2);
squareVertexes[4] = (width / 2);
squareVertexes[5] = (height / 2);
squareVertexes[6] = -(width / 2);
squareVertexes[7] = (height / 2);
return squareVertexes;
}
When I don't import or any other framework, I receive 'Parse Error: unknown type name' for CGFloat and GLfloat. When I do inside the .h file, I get Parse and Semantic errors, where NSString is an unknown type name inside the framework, as well as other, 'Expected Identifier or (" errors.
I've never had to include this header for my original C function lists, i've gone through other example code from Apple and i've checked headers on other classes that use these functions and typedefs, and I cant find the problem.
CGFloat is part of the CoreGraphics Framework. If you want to use pure C you will not have access to the CGFloat and need to define it as just a float. If your class is only going to be used with Objective-C you can make it a .m file and you should not have any trouble.