Could you suggest any idea how to do the following task?
I have the route from point A to point B. The route passes through several countries. How Can I calculate using Google Maps or alternative the distance of route part for each country?
Will be very appreciated for any ideas?
This should get you going, check fiddle here https://jsfiddle.net/yeoman/nm50vypx/1/
Basically do following:
1. Get latitude and longitude of FIRST point
2. Get latitude and longitude of SECOND point
3. User built-in API function google.maps.geometry.spherical.computeDistanceBetween()
var p1 = new google.maps.LatLng(45.463688, 9.18814);
var p2 = new google.maps.LatLng(46.0438317, 9.75936230000002);
alert(calcDistance(p1, p2));
//calculates distance between two points in km's
function calcDistance(p1, p2) {
return (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) / 1000).toFixed(2);
}
IMPORTANT: your script tag must have &libraries=geometry included in it.
For example <script type="text/javascript" src="http://maps.google.com/maps/api/js?key=YOURKEYHERE&libraries=geometry"></script>
Another One line example
var latitude1 = 39.46;
var longitude1 = -0.36;
var latitude2 = 40.40;
var longitude2 = -3.68;
var distance = google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(latitude1,longitude1), new google.maps.LatLng(latitude2,longitude2));
EDIT: Distance results are expressed in meters
Related
There are plenty of examples on how to draw lines on canvas, in js.
But for only educational purposes i want to draw line using algorithm. basically method gets two Vector2 points, from them it finds middle point, then it continues like that recursively until minimum distance of 2 pixels is reached.
I have DrawPoint method to basically draw 1 point on canvas, and DrawLine method that does all the job.
For now I have 2 problems:
1: points are not colored red, as they should be.
2:
It doesnt look like a line.
For Vector2 i used "Victor.js" plugin, and it seems to be working well.
this is code i have:
JS:
var point2 = new Victor(100, 100);
var point3 = new Victor(150, 150);
DrawLine(point2, point3);
function DrawLine(vec0, vec1)
{
var point0 = new Victor(vec0.x, vec0.y);
var point1 = new Victor(vec1.x, vec1.y);
var dist = point1.distance(point0);
if (dist < 2)
return;
//this is how it should look like in c# var middlePoint = point0 + (point1 - point0)/2; But looks like i cant just divide by 2 using victor js because i can only divide vector by vector.
var middlePoint = point0.add(point1.subtract(point0).divide(new Victor(2,2)));
DrawPoint(middlePoint);
DrawLine(point0, middlePoint);
DrawLine(middlePoint, point1);
}
function DrawPoint(point){
var c = document.getElementById("screen");
var ctx = c.getContext("2d");
ctx.fillStyle = "FF0000";
ctx.fillRect(point.x, point.y, 3,1);
}
I really appreciate any help you can provide.
The victor.js documentation shows that most functions of Victors do not return new Victors, but operate on the current instance. In a way, v1.add(v2) is semantically more like v1 += v2 and not v1 + v2.
The problem is with calculating the midpoint. You could use the mix() method, which blends two vectors with a weight. You must clone() the Victor first, otherwise point0will be midofied:
var middlePoint = point0.clone().mix(point1, 0.5);
If you don't change the original Vectors, you don't need to create new instances of Victors from the arguments, you can use the arguments directly:
function DrawLine(point0, point1)
{
var dist = point1.distance(point0);
if (dist < 2) return;
var middlePoint = point0.clone().mix(point1, 0.5);
DrawPoint(middlePoint);
DrawLine(point0, middlePoint);
DrawLine(middlePoint, point1);
}
Finally, as Sven the Surfer has already said in a comment, "FF0000" isn't a valid colour. Use "#FF0000", note the hash mark, or one of the named web colours such as "crimson".
I have attached the library
<script type="text/javascript" src="http://maps.googleapis.com`/maps/api/js?libraries=geometry&sensor=false"></script>
I have place A, with Latitude 30.694491 and longitude 76.665095
and place B with Latitude 30.7141289 and longitude 76.709398
<script>
computeDistanceBetween(from:LatLng, to:LatLng, radius?:number);
</script>
i dont know how to add lat and long to above function???
i want the distance between 2 places!!!!
and also is it possible to find displacement between them????
Use google.maps.geometry.spherical.computeDistanceBetween(a,b) to find distance between two points... read about computeDistanceBetween
It's in meters
var a = new google.maps.LatLng(30.694491, 76.665095);
var b = new google.maps.LatLng(30.7141289, 76.709398);
console.log(google.maps.geometry.spherical.computeDistanceBetween(a,b));
alert(google.maps.geometry.spherical.computeDistanceBetween(a,b));
<script type="text/javascript" src="http://maps.google.com/maps/api/js?libraries=geometry&sensor=false&language=en"></script>
You need to create LatLng Objects.
var _aCord = new google.maps.LatLng(30.694491, 30.694491);
var _bCord = new google.maps.LatLng(30.7141289, 76.709398);
computeDistanceBetween(_aCord, _bCord);
I have a kml file exported from Google Earth which is essentially a path of part of the River Thames in London. I have put this into Google Maps with Javascript as a KmlLayer.
I need to find a way to calculate the distance between one point on the route and the end of the route. Obviously it can't just be linear distance as the route goes up, down, back, forth etc.
I can't think of a way to do this using a kml file and Google Maps so any other suggestions or methods would be fine. I could perhaps gather the coordinates from the kml file and using them another way on the map? But I'm not sure where to start.
Apologies as always if this question has been answered elsewhere, but I have looked and had no luck.
Thanks in advance,
Adam
I found a solution, and that was to extract the kml coordinates into a javascript array of objects.
I then iterated through the array and got the distance between each point on the route using the Haversine Formula, and assigned each object a distance value (from the start of the route).
From there I could work out at each point on the route, how far it was from the start and finish just by using the distance value.
views.string = '-1.692525715111287,51.692324976351,0 -1.691353785046965,51.69214295521361,0 -1.690097310611129,51.69205100316109,0...//etc etc';
var array = views.string.split(',0 ');
map.route = [];
$.each(array, function (i, e) {
if ((i + 1) == array.length) {
e = e.replace(',0', '');
}
var coords = e.split(',');
map.route.push({ lat: parseFloat(coords[1]), lng: parseFloat(coords[0]) });
});
var distance = 0;
$.each(map.route, function (i, e) {
if (map.route[i - 1] != undefined) {
var d = map.getDistance(map.route[i - 1], e);
distance += d;
e.distance = distance;
}
else {
e.distance = distance;
}
});
I have a list of polylines, just like google maps does when I click on the polyline I want an infowindow to show up just where I clicked, and it works just fine with this function
function mapsInfoWindow(polyline, content) {
google.maps.event.addListener(polyline, 'click', function(event) {
infowindow.content = content;
infowindow.position = event.latLng;
infowindow.open(map);
});
}
the problem comes when I click on the list(using the same function for that), event obviously doesn't have the latLng, but I'd like infowindow to show up in the middle of the polyline anyway, just like it does when you click on the list in the google maps link I mentioned before.
Tried LatLngBounds(); but that gives the actuall center of the area the polylines create, not the middle I need.
Any idea how to do it?
So this is the(bit hacky) solution.
Use http://www.geocodezip.com/scripts/v3_epoly.js library, then count the total length of you polyline(various ways), divide it in half and call epoly's .GetPointsAtDistance() function upon it.
This should return LatLng point, but it acts a bit weird sometimes, returning two points or even turning that point somehow "broken". So the most secure thing you can do is probably this:
var pointInHalf = polyline.GetPointsAtDistance(polylineLength);
var pointCoordinate = new google.maps.LatLng(pointInHalf[0].lat(), pointInHalf[0].lng());
Well, better than nothing.
From http://www.geocodezip.com/v3_polyline_example_geodesic_proj.html
Without extensions and assuming the polyline is a straight line.
It is possible to convert the lat/lng coordinates to point plane (x,y) postions and calculate the average between the two. This will give you a central pixel position. You can then convert this position back to a latlng for map plotting.
var startLatLng = startMarker.getPosition();
var endLatLng = endMarker.getPosition();
var startPoint = projection.fromLatLngToPoint(startLatLng);
var endPoint = projection.fromLatLngToPoint(endLatLng);
// Average
var midPoint = new google.maps.Point(
(startPoint.x + endPoint.x) / 2,
(startPoint.y + endPoint.y) / 2);
// Unproject
var midLatLng = projection.fromPointToLatLng(midPoint);
var midMarker = createMarker(midLatLng, "text");
More information on changing the projection http://code.google.com/apis/maps/documentation/javascript/reference.html#Projection
So firstly you need to use the geometry library which calculates distances. Add libraries=geometry to your JS call, e.g.
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
Assuming you know the start point and end point for your polyline, you should be able to do this:
var inBetween = google.maps.geometry.spherical.interpolate(startLatlng, endLatlng, 0.5);
infowindow.position = inBetween;
I guess if you don't already know the start and end points, you could work it out from polyline.getPath().
to get the coordinates of your polyline you should do:
var widePath = new google.maps.Polyline({
path: waypointsCoordinates,
strokeColor: '#3366FF',
strokeOpacity: 0.0,
editable: true,
draggable: true,
strokeWeight: 3
});
and do:
var latLng [];
latLng = widePath.getPath().getArray();
Might be a bit old as well, but why not add the infobox on the click?
infowindow.setPosition(event.latLng);
infowindow.open(this.getMap());
If it's a click that is.
I have 2 OpenLayers.LonLat objects, and I want to determine the distance in pixels for the current zoom between the 2. I'm using OpenLayers.Layer.getViewPortPxFromLonLat() to determine the x and y of the points and then subtract to see the difference between the 2, but the values that I get are very small for points that are 2000km apart.
Here is my code:
var center_lonlat = new OpenLayers.LonLat(geometry.lon, geometry.lat);
var center_px = layer.getViewPortPxFromLonLat(center_lonlat);
var radius_m = parseFloat(feature.attributes["radius"]);
var radius_lonlat = OpenLayers.Util.destinationVincenty(center_lonlat, 0, radius_m);
var radius_px = layer.getViewPortPxFromLonLat(radius_lonlat);
var radius = radius_px.y - center_px.y;
I'm trying here to draw a circle, giving that I receive a center point and a radius in meters. The LonLat object seems to be ok.
Am I doing something wrong ?
I found the issue: destinationVincenty() need and returns coordinates in wgs84 where my map was using spherical mercator projection.
I hope I got correctly the answer, because projections make me dizzy and never really understood them :(. I was looking in the console to the numbers for my coordinates and the coordinates from the map.getExtent() that is used to calculate the getViewPortPxFromLonLat() and I realised they are not in the right order of magnitude, and then it hit me.
So, the code is now:
var spherical_mercator = new OpenLayers.Projection("EPSG:900913");
var wgs84 = new OpenLayers.Projection("EPSG:4326");
var map = feature.layer.map;
var geometry = feature.geometry;
var center_lonlat = new OpenLayers.LonLat(geometry.y, geometry.x);
var center_px = map.getViewPortPxFromLonLat(center_lonlat);
var radius_m = parseFloat(feature.attributes["radius"]);
var radius_lonlat = OpenLayers.Util.destinationVincenty(center_lonlat.clone().transform(spherical_mercator, wgs84), 0, radius_m).transform(wgs84, spherical_mercator);
var radius_px = map.getViewPortPxFromLonLat(radius_lonlat);
var radius = Math.abs(radius_px.y - center_px.y);
Measured the circles with the OpenLayers.Control.ScaleLine, and the size is dead on :D
You seem to be doing right. If the distance you get is too small, maybe there is a problem with OpenLayers.Util.destinationVincenty function? Have you tried to replace the bearing (0) with anything else - its value seem to be not important in your case. But frankly speaking, I wasn't able to understand how it works while browsing the source