drawing a line in google maps perpendicular to two points - javascript

I have two coordinates for which I would like to draw a perpendicular line of equal length. Is there either a simple google maps offset for this or a clean javascript approach by which I might accomplish this? What would that be?
Here is what I have thus far. As you can see, I plot the two points as markers and then attempt to draw a line between them, except I need to get that line perpendicular to the line between the two coordinates.
var locations = [
['', position.coords.latitude, position.coords.longitude, 1],
['', llat, llng, 2]
];
var marker, i;
for ( var i = 0; i < locations.length; i++ )
{
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
}
var borderPlanCoordinates = [
new google.maps.LatLng(llat, position.coords.longitude),
new google.maps.LatLng(position.coords.latitude,llng)
];
var borderPath = new google.maps.Polyline({
path: borderPlanCoordinates,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 10,
map: map
});
borderPath.setMap(map);

So you have two points with coordinates (x1,y1) and (x2, y2) and you want to draw a line segment whose length is the distance between them, which is the perpendicular bisector of the segment connecting them, and which is bisected by said segment?
Probably the simplest way is to set cx = (x1 + x2)/2, cy = (y1+y2)/2), dx = (x2-x1)/2, dy = (y2-y1)/2 and then draw a line from (cx-dy, cy+dx) to (cx+dy, cy-dx).
This works because (cx, cy) is the midpoint of the segment you want, and then you're just taking the vector from that midpoint to (x2,y2) and rotating it by plus and minus 90 degrees to find the endpoints of the segment you want to draw.

I tried this solution, the middle of the segment is ok BUT it doesn't look perpendicular on google maps, I suspect because of spherical projection (not orthonormal).
Here is a solution that works :
spherical = google.maps.geometry.spherical;
var F = new google.maps.LatLng(latF, longF);
var T = new google.maps.LatLng(latT, longT);
// M is the middle of [FT]
var latM = (latF + latT)/2;
var longM = (longF + longT)/2;
var M = new google.maps.LatLng(latM, longM);
// Get direction of the segment
var heading = spherical.computeHeading(F, T);
var dist = 200; // distance in meters
// Place point A that is oriented at 90° in a distance of dist from M
var A = spherical.computeOffset(M, dist, heading+90);
var perpendicularCoordinates = [M, A ];
var perpendicular = new google.maps.Polyline({
path: perpendicularCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
Here is the related fiddle : http://jsfiddle.net/8m7vm650/15/
Please note that you need to use an optional google maps library called geometry which is done by adding libraries=geometry to query string when loading maps : http://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=false

Related

how to get an image to point in a certain direction in a visualisation map

So I am using JavaScript to plot a position of a flight and its flight path on a visualisation map. I am getting the data from a node server that I have created. I have looked at similar question on stack over flow but I haven't been able to get them working.
I am currently struggling with the positioning of the flight icon, as I want it to point in the same direction as the flight path or even put a marker at the top of the image so it can point to a certain latitude and longitude. At the minute the flight icon only faces north.
Here is a screenshot of my code. I tried using the anchor in the Google maps API but I couldn't get it working so I commented it out.
var flightCord = [];
for (var i = 0; i < data.flight.length; i++) {
var lat = data.flight[0].lat1;
var lng = data.flight[0].lng1;
// Co-ordinates for Dublin Airport 53.421379, -6.27
var image = new google.maps.MarkerImage("plane3.png"
//new google.maps.Size(25,25),
//null, null,
//new google.maps.Point(53.4213879,-6.27)
//new google.maps.Point(0, 50)
);
var latLng = new google.maps.LatLng(lat,lng);
var marker = new google.maps.Marker({
position: latLng,
map: map,
icon: image
});
var flightCord = [
{lat:data.flight[0].lat1, lng: data.flight[0].lng1},
{lat:data.flight[i].lat1, lng:data.flight[i].lng1}];
}
var flightPath = new google.maps.Polyline({
path: flightCord,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 1
});

How To Get Coordinates of the google maps Corners?

I need to draw polygon with just four coordinates that is for the four corners of the loaded map in zoom 13 on other hand get coordinates of the whole map to show to user. ( user search the specific area with draw a polygon on the map but if he/she don't draw a polygon i want to draw a polygon in size of the projected map for him/her and show the result. )
Create the map at zoom: 13
var map = new google.maps.Map(document.getElementById("map"), {
center: {lat: 51.561162, lng: -0.163331},
zoom: 13
});
Then use map.getBounds() to get the LatLngBounds of the visible map.
var bounds = map.getBounds();
You can then use this to get the LatLng coordinates of the South West and North East corners:
var NECorner = bounds.getNorthEast();
var SWCorner = bounds.getSouthWest();
Then you can use those to work out the coordinates for the other two corners:
var NWCorner = new google.maps.LatLng(NECorner.lat(), SWCorner.lng());
var SECorner = new google.maps.LatLng(SWCorner.lat(), NECorner.lng());
And finally draw the polygon, using those corners for the paths array:
var polygon = new google.maps.Polygon({
map: map,
paths: [NWCorner, NECorner, SECorner, SWCorner],
fillColor: 'red',
fillOpacity: 0.7
});
Thanks duncan
Lemme write it in short form for Kotlin developers
var bounds = googleMap!!.projection.visibleRegion.latLngBounds
var neCorner = bounds.northeast
var swCorner = bounds.southwest
var nwCorner = LatLng(neCorner.latitude, swCorner.longitude)
var seCorner = LatLng(swCorner.latitude, neCorner.longitude)

Rotating polygon coordinates on a map (Google Map API)

I have a set of latitude and longitude coordinates in an array. When plotted as points on a Polygon in Google Maps, they form roughly an irregular oval pointing from west to east.
I would like to rotate the polygon to arbitrary degrees with a point near the far left (western) axis as the origin point.
What's important to me is that the overall distances are preserved — the total length and width of the polygon in miles should be preserved even though size of the polygon in pixels will obviously vary because of the map projection.
I've spent many hours Googling and searching on this site for an answer to this question but haven't been able to find one. Strictly speaking this is not a Google Maps issue — it's just a geometry issue related to rotating polygons on a map projection.
Here is more or less (some things dropped/renamed for simplicity) what I've been playing with so far:
function transpose_poly() {
//the polygon I'm transposing; these are actually in lng,lat not lat,lng
var poly = [
[165.2467094000077,11.90511591102683],[165.1960646350092,11.8776472999036],[165.163749733589,11.84385698549516],[165.1260503052001,11.79105209544025],[165.1174590975139,11.73721064669002],[165.1239723221977,11.68443896599666],[165.1455712453083,11.62322111902237],[165.1628352566873,11.60212814234246],[165.2801792409835,11.57112282455308],[165.3469838984795,11.55321856612457],[165.4267372080734,11.49929306693537],[165.565122175408,11.43334434041074],[165.7036021721537,11.37198352732909],[165.7982543390455,11.32757670668951],[165.942446703552,11.2660302522167],[166.0435044916007,11.23207374453692],[166.1628753311194,11.19161490039798],[166.3468035041342,11.13537294275959],[166.432786256031,11.11077339082378],[166.6460225244011,11.09603091173615],[166.9054486129032,11.10353634871533],[167.0953310801652,11.11920326808891],[167.2738338244123,11.14546202299651],[167.5299835821322,11.20017441185735],[167.7587090824888,11.25007287877568],[168.0532186132958,11.32987818697488],[168.3030699093596,11.40339603540862],[168.592055474493,11.49329084618948],[168.8894586866613,11.59767488596071],[169.1097084341002,11.70426500697907],[169.3388671138959,11.8464629880637],[169.47335151263,11.96284699062962],[169.4987805640997,12.00051052731504],[169.5113979458664,12.04997756596092],[169.496674063518,12.07975001861134],[169.4439862794831,12.10473302818016],[169.3792705121883,12.11718325976015],[169.2053586392944,12.12366910168141],[169.0210976722354,12.12171866909852],[168.7390558752391,12.08703266811138],[168.4733370821476,12.04764814638675],[168.1055698159765,12.00021651042535],[167.8745488025422,11.97152786285725],[167.5955303201492,11.94724207538445],[167.1571321566584,11.94152529858467],[166.8673995936747,11.95771709621411],[166.6698153277294,11.98911065050636],[166.4432968316392,12.03361885637251],[166.2604579582592,12.0693923391982],[166.0834945953367,12.09610600014998],[165.9206278637858,12.10688793842689],[165.7421018997999,12.1070118835482],[165.6244752224984,12.09489163127243],[165.4939687494391,12.0642833194958],[165.4055155587918,12.02521842289156],[165.3386147079753,11.97769336095395],[165.278157772496,11.92168821285675],[165.2467094000077,11.90511591102683],
];
var pos = marker.getPosition(); //where it transposes it to
var marker_lat = pos.lat();
var marker_lng = pos.lng();
var angle = document.getElementById("poly_angle").value; //rotational angle
var original_lat = 11.697222; //the original lat/lng of the polygon coordinates above
var original_lng = 165.27194399999996; //used to move the general polygon to a new set of coords as an offset
var new_poly = []; //the transformed polygon
//iterate over polygon array, create new array of Google Maps LatLng objects that are transposed and rotated
for(var i=0; i<poly.length; i++) {
new_poly.push( rotateLatLng( (poly[i][1]-original_lat)+marker_lat,(poly[i][0].lng()-original_lng)+marker_lng,angle));
}
// plot the polygon on the map
poly_obj = new google.maps.Polygon({
paths: poly_new,
strokeColor: "#ff763b",
strokeOpacity: 1,
strokeWeight: 1,
fillColor: "#ff763b",
fillOpacity: 0.25,
map: map,
visible: true
});
}
//this rotating function is cobbled together from code I found... it doesn't really work. It somewhat rotates it but distorts it terribly and gives really bizarre results
function rotateLatLng (pointLat,pointLng,angle) {
var pos = marker.getPosition();
var theX = pointLat;
var theY = pointLng;
var rotationTheta = angle;
var rotationThetaRad = rotationTheta*(Math.PI/180);
var rotationOriginX = pos.lat();
var rotationOriginY = pos.lng();
var newX;
var newY;
if (rotationOriginX == 0 && rotationOriginY == 0) {
newX = theX * Math.cos(rotationThetaRad) - Math.sin(rotationThetaRad) * theY;
newY = theX * Math.sin(rotationThetaRad) + Math.cos(rotationThetaRad) * theY;
} else {
newX = (theX - rotationOriginX) * Math.cos(rotationThetaRad) - (theY - rotationOriginY) * Math.sin(rotationTheta) + rotationOriginX;
newY = (theX - rotationOriginX) * Math.sin(rotationThetaRad) + (theY - rotationOriginY) * Math.cos(rotationTheta) + rotationOriginY;
}
return new google.maps.LatLng(newX,newY);
}
I don't think the above is necessarily the right way to do it at all. Any pointers would be helpful.
A much more simplified version of this problem would be to say that if I had an origin point of lat1,lng1, and another target point of lat2,lng2, how do I calculate lat3,lng3 which is defined as being the same distance between lat1,lng1 and lat2,lng2 but at an arbitrary angle? Because if I knew how to do that, applying that to the entire polygon should be a snap.

Work out LatLng distance from LatLng (or point in circle) - Google Maps v3

I need to find out if certain LatLngs are inside a Google Maps Circle (one of these: http://code.google.com/apis/maps/documentation/javascript/overlays.html#Circles). How would I get around doing this? My markup for making the circle is:
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
circlemarker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
THEradius = parseFloat(THEradius);
var populationOptions = {
strokeColor: "#BDAEBB",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#BDAEBB",
fillOpacity: 0.5,
map: map,
center: results[0].geometry.location,
radius: THEradius
};
cityCircle = new google.maps.Circle(populationOptions);
map.fitBounds(cityCircle.getBounds());
}
});
Could I just use the radius?
var distance = google.maps.geometry.spherical.computeDistanceBetween(
results[0].geometry.location, otherLatLng);
if (distance <= THEradius) {...} else {...}
I hope that works for you. See http://code.google.com/apis/maps/documentation/javascript/reference.html#spherical
What you need to do is to convert either your lat-lon list into google coordinate space, or the circle into lat-lon coordinate space.
How you do the conversion depends on the language you are using, but there are websites that will do the conversion for you if it is a one off.
Once you've got the lat-lon locations in the same co-ordinate space as your circle, you can use simple pythagoras math to work out if the location is less than the radius of the circle (as you suggest).
HYP = (OPP^2 * ADJ^2)^0.5
Where:
OPP is the difference in x direction from the centre of the circle
ADJ is the difference in y direction from the centre of the circle.
HYP is the distance in a straight line from the centre of the circle
In terms of mathematics, to find the distance from one point to another in 2D, use Pythagoras:
X = X1 - X2
Y = Y1 - Y2
(The above effectively calculates a vector from one point to another)
Distance from 1 to 2 = sqrt(X^2 + Y^2)
Then you can compare that to your radius. If the distance is less than your radius, the point is within the circle.
You need to first acquire the point corresponding to the centre of the circle and the point you are trying to compare. These must be in the same co-ordinate space.

Drawing anonymous circles in Google Maps

I'm trying to draw a google maps that has multiple Circle overlays, however I do not want to reveal the correct center of the radius.
So for example, myLatlng is my lat/lon center of the radius, I want to draw a circle not around it, but a circle that will include that point.
This is how I currently draw my circle:
var myLatlng = new google.maps.LatLng(33.33333,22.22222);
var circle = new google.maps.Circle({
map: map,
radius: 3218,
strokeColor: "#FFAA00",
fillColor: "#00AAFF",
fillOpacity: 0.3,
center: myLatlng,
zIndex: 99999,
});
33.33333,22.22222 is a 'secret' location that I do not want to reveal, however I would like to have that point within the circle.
Is that possible?
Thanks!
In your example code. The circle could move anywhere such that 33.3 and 22.2 could still be included.
One way to do this would be to simply add a random offset.
// Generate random between -5 and 5 (just an example)
var latOffset = Math.floor(Math.random()*11) - 5;
var longOffset = Math.floor(Math.random()*11) - 5;
var myLatlng = new google.maps.LatLng(33.33333 + latOffset,22.22222 + longOffset);
The tricky bit you've got is to ensure that the random offset doesn't move the circle out of bounds. The section Expressing latitude and longitude as linear units on Wikipedia should help.

Categories

Resources