Draw Route X Kilometers from Origin - google-maps-api-3

Running/walking distance display.
User enters a location and a distance.
I can overlay a circle with a radius of the distance the user entered, with the user's location as the center point.
I can set four cardinal points (N, S, E, W) around the point of origin at the distance the user set and draw the routes to those points, such that point B is 100KM from point A, but the mapped route is, say, 145km along the road.
Is it possible to display a route along the road exactly 100km?
Edited to update progress.

Finally solved this and thought I'd share.
so, the user supplies a location and a distance; we'll say 100Km.
The code finds cardinal points 100Km N, S, E, W of the point of origin, then solves routes to each point. If solving for the route is successful, the result contains an array of points from the point of origin to the destination.
directionsService.route({
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function(result) {
renderDirections(result);
});
//don't use the google api DirectionsRender() to draw the route.
//instead - result holds an array of lat/long points that make up the entire route. Lets say it's latlong[123]
//iterate through that array, getting a distance from point A to latlong[0], A to latlong[1], etc...
//when that distance is >= user supplied distance, STOP, and draw a polyline from point A through the latlong points in the array latlong[78]
function computeTotalDistance(result) {
var total = 0;
var myroute = result.routes[0];
if(myroute)
{
//create a LatLon from the Starting point
var objGeo = new LatLon(Geo.parseDMS(myroute.overview_path[0].Qa), Geo.parseDMS(myroute.overview_path[0].Ra));
//call get distance from the starting point to each other point in the array
//each subsequent point should be a longer distance
var arrPointsToDraw =[];
for(var i = 1; i<=myroute.overview_path.length-1;i++)
{
try
{
var objGeo2 = new LatLon(Geo.parseDMS(myroute.overview_path[i].Qa), Geo.parseDMS(myroute.overview_path[i].Ra));
}
catch(err)
{
alert(err.description);
}
//here, total = kilometers
total = objGeo.distanceTo(objGeo2,3);
//add coordinates to our array of points that we are going to draw
arrPointsToDraw.push(new google.maps.LatLng(objGeo2._lat, objGeo2._lon));
if(parseInt(total) > parseInt(distance.value))
{
arrPointsToDraw.pop();//remove the last element of the array
break;
}
}
//at this point, arrPointsToDraw[] contains the lat/long points that are closest to our distance
//without going over
lines[lines.length] = new google.maps.Polyline({
path: arrPointsToDraw,
strokeColor: '#1589FF',
strokeOpacity: 1.0,
strokeWeight: 3
});
lines[lines.length-1].setMap(map);
}//end if(myRoute)
}
This code makes use of two fantastic collections of functions found here

Related

How do you remove a vertex from a polygon with multiple paths?

In googlemaps api, when editing a polygon with multiple paths, removeAT eliminates the wrong vertex
For simple polygons, the removeAT will remove the correct vertex, but for multiple path polygons, it seems to remove only the vertex number from the first path.
Given this definition of a polygon for multiple paths:
var blockpolygon = newgoogle.maps.Polygon({
paths: [blockcoords0,blockcoords1,blockcoords2,blockcoords3,blockcoords4,blockcoords5]
});
where the paths are previously defined, for example:
var blockcoords4 = [{lat:51.799693211411,lng:-114.12380330669},{lat:51.799109509173,lng:-114.12273800578},{lat:51.799558197929,lng:-114.1223323167},{lat:51.799684004911,lng:-114.12232429316},{lat:51.799876802912,lng:-114.12248608283},{lat:51.800102904916,lng:-114.12290678386},{lat:51.800133809341,lng:-114.12306439938},{lat:51.800077007986,lng:-114.12331471639},{lat: 51.799693211411, lng: -114.12380330669}];
and the polygon is set as editable
When this event fires:
blockpolygon.addListener("rightclick", function(event)
{
this.getPath().removeAt(event.vertex);
}
The vertex from the first path on the list is removed, which is not the vertex that was "clicked"
Is there any way to remove the vertex from the correct path?
If I could identify which path and have the removeAT pointed to the correct path, that would make my day.
the hint from geocodezip was enough. Here's the solution:
blockpolygon.addListener("rightclick", function(event)
{
for (i=0; i<this.getPaths().getLength(); i++)
{
for (j=0; j< this.getPaths().getAt(i).getLength(); j++)
{
var distance = google.maps.geometry.spherical.computeDistanceBetween(event.latLng, this.getPaths().getAt(i).getAt(j));
if (distance==0) this.getPaths().getAt(i).removeAt(j);
}
}
}

google.maps.geometry.spherical.computeOffset error (a.lat is not a function)

I wanted a latlng value near a particular distance. I went throught the documentation of google maps api v3.
Have a look at my code :
generateCirclepolygon(){
for (let location of this.pointsLocation) {
let LatLng:any = {
lat: parseFloat(location.lat),
lng: parseFloat(location.lng)
};
let newpoints = [];
var polypoint = google.maps.geometry.spherical.computeOffset(LatLng , 3000 , 0)
console.log(polypoint , 'point');
}
}
After runing this code im getting ERROR TypeError: a.lat is not a function.
I'm sending a LatLng object to that which has lat and lng values and they are numbers. 3000 is the distance in meters and 0 is heading (i.e 0 degrees in clock wise from north).
I want the latlng value from my point to 3000 meters towards north. My main aim is to draw a circular polygon around a point by repeating this to get an array of points.
Related questions:
Google maps a.lat is not a function
Google Maps API a.lat is not a function error
Per the documentation, the computeOffset method takes a google.maps.LatLng as an argument:
computeOffset(from, distance, heading[, radius])
Parameters:
from: LatLng
distance: number
heading: number
radius (optional): number
Return Value: LatLng
Returns the LatLng resulting from moving a distance from an origin in the specified heading (expressed in degrees clockwise from north).
You are providing a LatLngLiteral (which doesn't have a .lat method, it has a .lat property.
let LatLng:any = {
lat: parseFloat(location.lat),
lng: parseFloat(location.lng)
};
should be:
let LatLng:any = new google.maps.LatLng(
parseFloat(location.lat),
parseFloat(location.lng)
);

GeoFire - Save item to specific location with radius

I don't have any code to share at this point, but I'm trying to figure out how to solve my issue.. I was hoping some of you might have some advice.
I'm building an app where I get the user's lat/long from geolocation and if they are in an predetermined area with a radius they can post data to the server, but not if they aren't in an area that I specified is allowed.. Here is an image for example:
So in this example, the user could post if they are in the radius of one of the circles but not if they aren't.
I would also have to fetch the data based off of which circle they are in..
What I'm wondering is, how would I specify where these radius' exist and does this scale easily? If I needed to add 10-30 new locations would that be easy to do?
You have the user location from the device and as you have the circles; you have the circle centre with their radius. At time of posting, you check the distance from the user location to the circle centre and enumerate thought the circle locations. if the distance is within the radius, they can post if not, not.
var radius = 100 //example
let canPostLocations = [
CLLocation1,
CLLocation2
]
func isInRange() -> Bool {
for canPost in canPostLocations {
let locationDistance = location.distance(from: canPost)
if (locationDistance < radius) {
return true
}
}
return false
}
use as:
var mayPost = false
var userLocation: CLLocation! = nil
if userLocation != nil {
mayPost = InRange(location: userLocation).isInRange()
}

Calculating a nearby street to use on streetview

I am facing an unusual problem where I need to calculate the latlong of a position on a map that has streetview imagery, without knowing the actual position.
I know the end destination of my user, but I need to calculate the latlong of a nearby position (approximately 1km away or less, this should be variable) that has streetview imagery and use that as the start destination.
An example would be that I know I need to go to Times Square, but I want to have a start destination that is about 1km away by road. I then need to verify that there is street view imagery for this co-ordinate before I decide that it's the starting point.
The function below recursively doubles the search distance, (up to a maximum of 10000 meters), until a panorama is found.
Sample code:
// Global vars
var G = google.maps;
var streetViewService = new G.StreetViewService();
function getNearSVP(latlon,maxDist) {
streetViewService.getPanoramaByLocation(latlon, maxDist, function(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
return data.location.latLng;
}
else{
if (maxDist < 10000){
maxDist = maxDist * 2;
return getNearSVP(latlon, maxDist);
}
else {
alert('StreetView is not available within '+maxDist+' meters of this location');
}
}
});
}
Live demo here

google maps api v3 - nearest streetview

When streetview is not available for a certain location, I would like to find the nearest possible location with streetview?
The only way I could think of is.
radius = 0;
noOfPoints = 3;
while(radius < 10 miles){
radius = radius + 0.2 miles
points = calculate 4 * noOfPoints at this radius
loop(points)
{
if(streetview visibile for point)
bingo, break;
}
break if bingo;
noOfPOints = noOfPoints+1;
}
But this is ridiculously expensive even if I want to find streetview within a 10-mile radius and I am counting on luck to find streetview at one of these points, i.e, I could just miss an actual point with streetview.
can somebody please direct me towards a better approach??
You can try to use the StreetViewService to help you find a nearest existing street view:
var astorPlace = new google.maps.LatLng(40.729884, -73.990988);
var webService = new google.maps.StreetViewService();
/**Check in a perimeter of 50 meters**/
var checkaround = 50;
/** checkNearestStreetView is a valid callback function **/
webService.getPanoramaByLocation(astorPlace,checkaround ,checkNearestStreetView);
function checkNearestStreetView(panoData){
if(panoData){
if(panoData.location){
if(panoData.location.latLng){
/**Well done you can use a nearest existing street view coordinates**/
}
}
}
/** Else do something... **/
}

Resources