Now I have geo coordinates of Lambert 2, like this
X:595833.007,
Y:2418927.985
In order to show this place in the google map, I need the related geo coordinates of WSG84, like this
X:48.7687954,
Y:2.27984782
Is there angularjs library which includes the this function ? Thanks in advance.
To realize the convertion of coordinates among different geodetic systems, I create this repo, angular-geo-converter. it is quite easy to use.
Add the script dependence of angular-geo-convert.js:
<script src="angular-geo-converter.js"></script>
Add the module dependence in your root module of your angular application:
angular.module('app',['geoConverter'])
Call the service in your controller
angular.module('app').controller('geoCtrl',['geoConverter',function(geoConverter){
var coordinates = geoConverter.lambert2wgs(595833,2418928);
var coordinateX = coordinates.latitude; // result:48.7687954
var coordinateY = coordinates.longitude; // result:2.27984782
}])
PS: The convertion in the answer of manzapanza is not correct.
Here I found the algorithm to convert Lambert 2 to WSG84 coords.
You should create a service:
(function(){
'user strict';
function Lambert2ToWSG84() {
var self = {};
self.convert = function(x, y) {
var newLongitude, newLatitude;
var n = 0.77164219;
var F = 1.81329763;
var thetaFudge = 0.00014204;
var e = 0.08199189;
var a = 6378388;
var xDiff = 149910;
var yDiff = 5400150;
var theta0 = 0.07604294;
var xReal = xDiff - x;
var yReal = yDiff - y;
var rho = Math.sqrt(xReal * xReal + yReal * yReal);
var theta = Math.atan(xReal / -yReal);
newLongitude = (theta0 + (theta + thetaFudge) / n) * 180 / Math.PI;
newLatitude = 0;
for (var i = 0; i < 5 ; ++i) {
newLatitude = (2 * Math.atan(Math.pow(F * a / rho, 1 / n) * Math.pow((1 + e * Math.sin(newLatitude)) / (1 - e * Math.sin(newLatitude)), e / 2))) - Math.PI / 2;
}
newLatitude *= 180 / Math.PI;
return {
lat: newLatitude,
lng: newLongitude
};
};
return self;
}
angular
.module('myModuleName')
.factory('Lambert2ToWSG84', Lambert2ToWSG84);
})();
And use it, for example, in a controller:
function MyCtrl(Lambert2ToWSG84) {
var vm = this;
vm.convert = function(x, y){
return Lambert2ToWSG84.convert(x, y);
};
}
MyCtrl.$inject = ['Lambert2ToWSG84'];
angular
.module('myModuleName')
.controller('MyCtrl', MyCtrl);
CHECK THE DEMO FIDDLE
Related
I have been trying to convert the 360 degree camera, single fish eye image, to equirectangular viewer in node js for the past two days. In stackoverflow, the same question is asked and answered in pseudo code. I have been trying to convert pseudo code to node js and cleared some errors. Now the project runs without error but the output image is blank.
From that pseudo, I dont know the polar_w, polar_h and geo_w, geo_h, geo and polar value, so, it gave static value to show the output. Here is a link which i followed to convert pseudo code to node js.
How to convert spherical coordinates to equirectangular projection coordinates?.
Here is the code I tried for converting spherical image to equirectangular viewer:
exports.sphereImage=(request, response)=>{
var Jimp = require('jimp');
// Photo resolution
var img_w_px = 1280;
var img_h_px = 720;
var polar_w = 1280;
var polar_h = 720;
var geo_w = 1280;
var geo_h = 720;
var img_h_deg = 70;
var img_w_deg = 30;
// Camera field-of-view angles
var img_ha_deg = 70;
var img_va_deg = 40;
// Camera rotation angles
var hcam_deg = 230;
var vcam_deg = 60;
// Camera rotation angles in radians
var hcam_rad = hcam_deg/180.0*Math.PI;
var vcam_rad = vcam_rad/180.0*Math.PI;
// Rotation around y-axis for vertical rotation of camera
var rot_y = [
[Math.cos(vcam_rad), 0, Math.sin(vcam_rad)],
[0, 1, 0],
[-Math.sin(vcam_rad), 0, Math.cos(vcam_rad)]
];
// Rotation around z-axis for horizontal rotation of camera
var rot_z = [
[Math.cos(hcam_rad), -Math.sin(hcam_rad), 0],
[Math.sin(hcam_rad), Math.cos(hcam_rad), 0],
[0, 0, 1]
];
Jimp.read('./public/images/4-18-2-42.jpg', (err, lenna) => {
polar = new Jimp(img_w_px, img_h_px);
geo = new Jimp(img_w_px, img_h_px);
for(var i=0; i<img_h_px; ++i)
{
for(var j=0; j<img_w_px; ++j)
{
// var p = img.getPixelAt(i, j);
var p = lenna.getPixelColor(i, j)
// var p = getPixels(img, { x: i, y: j })
// Calculate relative position to center in degrees
var p_theta = (j - img_w_px / 2.0) / img_w_px * img_w_deg / 180.0 * Math.PI;
var p_phi = -(i - img_h_px / 2.0) / img_h_px * img_h_deg / 180.0 *Math. PI;
// Transform into cartesian coordinates
var p_x = Math.cos(p_phi) * Math.cos(p_theta);
var p_y = Math.cos(p_phi) * Math.sin(p_theta);
var p_z = Math.sin(p_phi);
var p0 = {p_x, p_y, p_z};
// Apply rotation matrices (note, z-axis is the vertical one)
// First vertically
var p1 = rot_y[1][2][3] * p0;
var p2 = rot_z[1][2][3] * p1;
// Transform back into spherical coordinates
var theta = Math.atan2(p2[1], p2[0]);
var phi = Math.asin(p2[2]);
// Retrieve longitude,latitude
var longitude = theta / Math.PI * 180.0;
var latitude = phi / Math.PI * 180.0;
// Now we can use longitude,latitude coordinates in many different
projections, such as:
// Polar projection
{
var polar_x_px = (0.5*Math.PI + phi)*0.5 * Math.cos(theta)
/Math.PI*180.0 * polar_w;
var polar_y_px = (0.5*Math.PI + phi)*0.5 * Math.sin(theta)
/Math.PI*180.0 * polar_h;
polar.setPixelColor(p, polar_x_px, polar_y_px);
}
// Geographical (=equirectangular) projection
{
var geo_x_px = (longitude + 180) * geo_w;
var geo_y_px = (latitude + 90) * geo_h;
// geo.setPixel(geo_x_px, geo_y_px, p.getRGB());
geo.setPixelColor(p, geo_x_px, geo_y_px);
}
// ...
}
}
geo.write('./public/images/4-18-2-42-00001.jpg');
polar.write('./public/images/4-18-2-42-00002.jpg');
});
}
And tried another method by slicing image into four parts to detect car. Sliced image into four parts using image-slice module and to read and write jimp module is used. But unfortunately cars not detected properly.
Here is the code i used for slicing image:
exports.sliceImage=(request, response)=>{
var imageToSlices = require('image-to-slices');
var lineXArray = [540, 540];
var lineYArray = [960, 960];
var source = './public/images/4-18-2-42.jpg'; // width: 300, height: 300
imageToSlices(source, lineXArray, lineYArray, {
saveToDir: './public/images/',
clipperOptions: {
canvas: require('canvas')
}
}, function() {
console.log('the source image has been sliced into 9 sections!');
});
}//sliceImage
And for detect car from image i used opencv4nodejs. Cars are not detected properly. here is the code i used for detect car:
function runDetectCarExample(img=null){
if(img==null){
img = cv.imread('./public/images/section-1.jpg');
}else
{
img=cv.imread(img);
}
const minConfidence = 0.06;
const predictions = classifyImg(img).filter(res => res.confidence > minConfidence && res.className=='car');
const drawClassDetections = makeDrawClassDetections(predictions);
const getRandomColor = () => new cv.Vec(Math.random() * 255, Math.random() * 255, 255);
drawClassDetections(img, 'car', getRandomColor);
cv.imwrite('./public/images/section-'+Math.random()+'.jpg', img);
var name="distanceFromCamera";
var focalLen= 1.6 ;//Focal length in mm
var realObjHeight=254 ;//Real Height of Object in mm
var cameraFrameHeight=960;//Height of Image in pxl
var imgHeight=960;//Image Height in pxl
var sensorHeight=10;//Sensor height in mm
var R = 6378.1 //#Radius of the Earth
var brng = 1.57 //#Bearing is 90 degrees converted to radians.
var hc=(200/100);//Camera height in m
predictions
.forEach((data)=> {
// imgHeight=img.rows;//Image Height in pxl
// realObjHeight=data.rect.height;
// data.rect[name]=((focalLen)*(realObjHeight)*
(cameraFrameHeight))/((imgHeight)*(sensorHeight));
var dc=(((data.rect.width * focalLen) / img.cols)*2.54)*100; // meters
console.log(Math.floor(parseInt(data.rect.width)));
// var dc=((Math.floor(parseInt(data.rect.width)* 0.264583) * focalLen) / img.cols); // mm
var lat1=13.0002855;//13.000356;
var lon1=80.2046441;//80.204632;
// Gate 13.0002855,80.2046441
// Brazil Polsec : -19.860566, -43.969436
// var d=Math.sqrt((dc*dc)+(hc*hc));
// d=(data.rect[name])/1000;
data.rect[name]=d=dc/1000;
lat1 =toRadians(lat1);
lon1 = toRadians(lon1);
brng =toRadians(90);
// lat2 = Math.asin( Math.sin(lat1)*Math.cos(d/R) +
// Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng));
// lon2 = lon1 +
Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1),
// Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));
var lat2 = Math.asin(Math.sin(lat1) * Math.cos(d/6371) +
Math.cos(lat1) * Math.sin(d/6371) * Math.cos(brng));
var lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(d/6371) * Math.cos(lat1),
Math.cos(d/6371) - Math.sin(lat1) * Math.sin(lat2));
lat2 = toDegrees(lat2);
lon2 = toDegrees(lon2);
data.rect['latLong']=lat2+','+lon2;
// console.log(brng);
});
response.send(predictions);
cv.imshowWait('img', img);
};
here is the fish eye image which need to be converted to equirectangular.
Any help much appreciated pls....
You are asking how to convert a 360deg fish-eye projection to an equirectangular projection.
In order to do this, for every pixel on the fish-eye image you need to know where to place in onto the output image.
Your input image is 1920x1080, let us assume you want to output it to an equirectangular projection of the same size.
The input circle mapping is defined as:
cx = 960; // center of circle on X-axis
cy = 540; // center of circle on Y-axis
radius = 540; // radius of circle
If you have a pixel at (x,y) in the input image, then we can calculate the spherical coordinates using:
dx = (x - cx) * 1.0 / radius;
dy = (y - cy) * 1.0 / radius;
theta_deg = atan2(dy, dx) / MATH_PI * 180;
phi_deg = acos(sqrt(dx*dx + dy*dy)) / MATH_PI * 180;
outputx = (theta_deg + 180) / 360.0 * outputwidth_px;
outputy = (phi_deg + 90) / 180.0 * outputheight_px;
So there we translated (x,y) from the fish-eye image to the (outputx,outputy) in the equirectangular image. In order to not leave the implementation as the dreaded "exercise to the reader", here is some sample Javascript-code using the Jimp-library as used by the OP:
var jimp = require('jimp');
var inputfile = 'input.png';
jimp.read(inputfile, function(err, inputimage)
{
var cx = 960;
var cy = 540;
var radius = 540;
var inputwidth = 1920;
var inputheight = 1080;
var outputwidth = 1920;
var outputheight = 1080;
new jimp(outputwidth, outputheight, 0x000000ff, function(err, outputimage)
{
for(var y=0;y<inputheight;++y)
{
for(var x=0;x<inputwidth;++x)
{
var color = inputimage.getPixelColor(x, y);
var dx = (x - cx) * 1.0 / radius;
var dy = (y - cy) * 1.0 / radius;
var theta_deg = Math.atan2(dy, dx) / Math.PI * 180;
var phi_deg = Math.acos(Math.sqrt(dx*dx + dy*dy)) / Math.PI * 180;
var outputx = Math.round((theta_deg + 180) / 360.0 * outputwidth);
var outputy = Math.round((phi_deg + 90) / 180.0 * outputheight);
outputimage.setPixelColor(color, outputx, outputy);
}
}
outputimage.write('output.png');
});
});
Note that you will still need to do blending of the pixel with neighbouring pixels (for the same reason as when you're resizing the image).
Additionally, in your case, you only have half of the sphere (you can't see the sun in the sky). So you would need to use var outputy = Math.round(phi_deg / 90.0 * outputheight). In order to keep the right aspect ratio, you might want to change the height to 540.
Also note that the given implementation may not be efficient at all, it's better to use the buffer directly.
Anyway, without blending I came up with the result as demonstrated here:
So in order to do blending, you could use the simplest method which is the nearest neighbour approach. In that case, you should invert the formulas in the above example. Instead of moving the pixels from the input image to the right place in the output image, you can go through every pixel in the output image and ask which input pixel we can use for that. This will avoid the black pixels, but may still show artifacts:
var jimp = require('jimp');
var inputfile = 'input.png';
jimp.read(inputfile, function(err, inputimage)
{
var cx = 960;
var cy = 540;
var radius = 540;
var inputwidth = 1920;
var inputheight = 1080;
var outputwidth = 1920;
var outputheight = 1080/2;
var blendmap = {};
new jimp(outputwidth, outputheight, 0x000000ff, function(err, outputimage)
{
for(var y=0;y<outputheight;++y)
{
for(var x=0;x<outputwidth;++x)
{
var theta_deg = 360 - x * 360.0 / outputwidth - 180;
var phi_deg = 90 - y * 90.0 / outputheight;
var r = Math.sin(phi_deg * Math.PI / 180)
var dx = Math.cos(theta_deg * Math.PI / 180) * r;
var dy = Math.sin(theta_deg * Math.PI / 180) * r;
var inputx = Math.round(dx * radius + cx);
var inputy = Math.round(dy * radius + cy);
outputimage.setPixelColor(inputimage.getPixelColor(inputx, inputy), x, y);
}
}
outputimage.write('output.png');
});
});
For reference, in order to convert between Cartesian and Spherical coordinate systems. These are the formulas (taken from here). Note that the z is in your case just 1, a so-called "unit" sphere, so you can just leave it out of the equations. You should also understand that since the camera is actually taking a picture in three dimensions, you also need formulas to work in three dimensions.
Here is the generated output image:
Since I don't see your original input image in your question anymore, in order for anyone to test the code from this answer, you can use the following image:
Run the code with:
mkdir /tmp/test
cd /tmp/test
npm install --permanent jimp
cat <<EOF >/tmp/test/main.js
... paste the javascript code from above ...
EOF
curl https://i.stack.imgur.com/0zWt6.png > input.png
node main.js
Note: In order to further improve the blending, you should remove the Math.round. So for instance, if you need to grab a pixel at x is 0.75, and the pixel on the left at x = 0 is white, and the pixel on the right at x = 1 is black. Then you want to mix both colors into a dark grey color (using ratio 0.75). You would have to do this for both dimensions simultaneously, if you want a nice result. But this should really be in a new question imho.
I'm trying to create a Javascript function that can find the closest coordinate match in an array of coordinates.
My coordinates: 33.9321, 18.8602
These coordinates will vary, but the 4 locations listed below will stay the same.
Location1: 33.9143, 18.5701
Location2: 26.2041, 28.0473
Location3: 25.7479, 28.2293
Location4: 29.8587, 31.0218
try to run my code to see if it helps you.
I have used var home as your stargint point if browser didn't work for you.
Also I have saved all locations in var points so you can change that if you need.
Then I just look over each point and it will output in the console what is the distance to ref point. In your case it's the first point
var home = [ '33.9321', '18.8602' ];
var points = [
[ '33.9143', '18.5701' ],
[ '26.2041', '28.0473' ],
[ '25.7479', '28.2293' ],
[ '29.8587', '31.0218' ]
];
// loop over each point and output distance!
for( var i = 0; i < points.length; i++){
var diff = twoPointsDiff(home[0],home[1],points[i][0],points[i][1]);
console.log( 'distance from point' + (i+1) + ': ' + diff );
}
// helper fn to calc distance
function twoPointsDiff(lat1,lon1,lat2,lon2) {
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; // Distance in km
return d;
}
// helper fn to convert deg to radians
function deg2rad(deg) {
return deg * (Math.PI/180)
}
I'm facing issues getting value of a variable from another function. I'm trying to get the distance of the place from current position in google maps, but using Haversine Formula of calculating distance.
My HTML:
<p>
<script>
lat = "<?php echo $atm_row_data->latitude;?>";
lng = "<?php echo $atm_row_data->longitude;?>";
dist = getDistance(lat, lng);
document.write(dist);
</script>
</p>
My JavaScript:
var curPosition;
var lat, lng;
/**** get current position ****/
function getPosition() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showCurrentPosition);
} else {
alert('Geolocation is not supported by this browser.');
}
}
function showCurrentPosition(position) {
lat = position.coords.latitude;
lng = position.coords.longitude;
curPosition = new google.maps.LatLng(lat, lng);
console.log('curPosition: '+curPosition); <--- this works
}
/******** Haversine Formula of Getting Distance ********/
var rad = function(x) {
return x * Math.PI / 180;
};
function getDistance(lt, lg) {
console.log(curPosition); <--- this shows undefined
var p1 = curPosition;
var R = 6378137; // Earth’s mean radius in meter
var dLat = rad(lt - p1.lat());
var dLong = rad(lg - p1.lng());
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(rad(p1.lat())) * Math.cos(rad(lt)) *
Math.sin(dLong / 2) * Math.sin(dLong / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
if (d >= 1000)
return Math.round( (d / 1000) * 100) / 100 + "Km";
else
return Math.round( (d * 100) / 100) + "m";
};
/******** END Haversine Formula of Getting Distance ********/
Where am I going wrong?
Any help is appreciated...
Knowing the google api, , navigator.geolocation has a callback, so showcurrentPostion is the callback function, but the thing is u never call
getPosition() <--
function getDistance(lt, lg) {
console.log(curPosition); <--- this shows undefined <---- so this will always be undefined
var p1 = curPosition;
var R = 6378137; // Earth’s mean radius in meter
var dLat = rad(lt - p1.lat());
var dLong = rad(lg - p1.lng());
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(rad(p1.lat())) * Math.cos(rad(lt)) * <--- see comment
Math.sin(dLong / 2) * Math.sin(dLong / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
if (d >= 1000)
return Math.round( (d / 1000) * 100) / 100 + "Km";
else
return Math.round( (d * 100) / 100) + "m";
};
comment: <------ p1 curposition gets an google maps object with lat and long where i know that lat() is not a function so this will fail
so even when u get the current position the function above (getDistance()) will fail
Call getPosition first() <--- u need to get the position
edit: i see that u can call console.log and you say it works, so i think its a scoping issue,
I made an example for you -> http://codepen.io/anon/pen/qOBMPj
i'm not able to render the googlemap within the pen, but u can look at the source, on how its done. hope this helps you.
so in order to do this calculation u dont really need google maps u just need the first/ and second coords, but its fun to do something with on on the google map:)
In your script tags, your only call getDistance(lat,lng), but showCurrentPosition(position) is never called! So the variable curPosition is undefined, because it is not defined yet!
You need to call showCurrentPosition(position) for the variable curPosition to hold a value.
Perhaps calling getPosition() at the beginning of your getDistance() function could solve the problem, as it seems to call showCurrentPosition.
Alternative to show the position in HTML (this is just a quick snippet, you can adapt it to whatever you like):
function getPositionHTML() {
navigator.geolocation.getCurrentPosition(function(pos) {
curPosition = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
});
return curPosition;
}
It basically does the same thing as your other function, but it relies on the Single Reponsibility Principle, so once you called this function you can manipulate curPosition however you want.
I am working on a transition between Orthogonal and Mercator projections on an interactive map (zoom + drag) of the world. I based my attempt off of this answer by #mbostock. My transition works well but the console returns this:
Error: Invalid value for attribute d= "M399.97994119370463,631.2543931983346L401.90905516286807,634.6157013775801L402.49382423943246,639.8924592362391L397.1999166487309,.......,InfinityL492,InfinityL298.23496934976544,InfinityZ"
also
Error: Invalid value for attribute d="M407.5277462873383,448.4656515493841L407.3237573717514,448.5198670656254L408.0599991645186,448.54332648718287L408.0215749188842,448.4385574971469ZM410.40575858016456,448.5990104765492L410.8017911794915,448.571665201377L411.4470970198755...,NaNL415,NaNL415,NaNZM415,NaNL415,NaNL415,NaNZM415,NaNL415,449.0295187376797L415,449.0295187376797L414.9999381778805,449.02952802059315L415,449.02952802059315L414.41200773961845,.."
I am using topoJson from a Natural Earth shapefile and I only receive one of these path errors for each time the tween function is returned. I believe this means that only one path element that is having this problem.
Here are my transition methods that I have within a projection class:
animation(timeout, newProjection) {
let self = this;
let projection = this.interpolatedProjection(this.prjFnc, newProjection);
let path = d3.geo.path().projection(projection);
this.svg.transition()
.duration(timeout / 2)
.tween('projection', function() {
return function(_) {
self.alpha(_);
self.svg.selectAll('path').attr('d', path);
};
});
}
interpolatedProjection(a, b) {
let self = this;
this.a = a;
this.b = b;
this.α = null;
function raw(λ, φ) {
let pa = self.a([λ *= 180 / Math.PI, φ *= 180 / Math.PI]), pb = self.b([λ, φ]);
return [(1 - self.α) * pa[0] + self.α * pb[0], (self.α - 1) * pa[1] - self.α * pb[1]];
}
this.intProjection = d3.geo.projection(raw).scale(1);
this.center = this.intProjection.center;
this.translate = this.intProjection.translate;
delete this.intProjection.scale;
delete this.intProjection.translate;
delete this.intProjection.center;
return this.alpha(0.1);
}
alpha(_) {
if(!arguments.length) {
return this.α;
}
this.α = +_;
let ca = this.a.center(),
cb = this.b.center(),
ta = this.a.translate(),
tb = this.b.translate();
this.center(
[(1 - this.α) * ca[0] + this.α * cb[0],
(1 - this.α) * ca[1] + this.α * cb[1]]
);
this.translate(
[Math.round((1 - this.α) * ta[0] + this.α * tb[0]),
Math.round((1 - this.α) * ta[1] + this.α * tb[1])]
);
return this.intProjection;
}
Any thoughts?
The infinity errors were caused by paths attempting be drawn outside of the svg. I was able to remove these errors by adding a Clip Extent to the interpolated projection.
interpolatedProjection(a, b) {
let self = this;
this.a = a;
this.b = b;
this.α = null;
function raw(λ, φ) {
let pa = self.a([λ *= 180 / Math.PI, φ *= 180 / Math.PI]), pb = self.b([λ, φ]);
return [(1 - self.α) * pa[0] + self.α * pb[0], (self.α - 1) * pa[1] - self.α * pb[1]];
}
this.intProjection = d3.geo.projection(raw).scale(1)
.clipExtent(this.extent); // this addition
this.center = this.intProjection.center;
this.translate = this.intProjection.translate;
delete this.intProjection.scale;
delete this.intProjection.translate;
delete this.intProjection.center;
return this.alpha(0.1);
}
I was also was receiving a NaN error in the d attribute in which I was able to remove by not letting the tween index reach a value of 1.
animation(timeout, newProjection) {
let self = this;
let projection = this.interpolatedProjection(this.prjFnc, newProjection);
let path = d3.geo.path().projection(projection);
this.svg.transition()
.duration(timeout)
.tween('projection', function() {
return function(_) {
if (_ === 1) { return; } // This addition
self.alpha(_);
self.paths.attr('d', path);
};
});
}
I have an array of users and their gps coordinates.
what formula can I use to get all the users that are within X KM range
from a user?
I need to avoid heavy calculations.
I was thinking about sorting the array, but I realized that it isn't a good idea, because I would have to set a sorted array for each user.
Use the Haversine formula to find the users that are within a specified distance from a specified point:
function getNearbyUsers(lat, lng, distanceInKm, users) {
var R = 6373;
var latRad = lat * Math.PI/180;
var lngRad = lng * Math.PI/180;
var returnUsers = [];
for (var i = 0; i < users.length; i++) {
var lat2Rad = users[i].lat * Math.PI/180;
var lng2Rad = users[i].lng * Math.PI/180;
var dlat = lat2Rad - latRad;
var dlng = lng2Rad - lngRad;
var a = Math.pow(Math.sin(dlat/2),2) + Math.cos(latRad) * Math.cos(lat2Rad) * Math.pow(Math.sin(dlng/2),2);
var c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a)); // great circle distance in radians
var d = c * R; // Distance from user in km
if (d < distanceInKm) returnUsers.push(users[i]);
}
return returnUsers;
}