I'm working with mapbox gl directions, I can start the map, and create the directions from point A to B, but I got a issue when I add more waypoints, if I try to move the traced route in the waypoint A.a and A.b, the result doesn't respect the array order
If I move from index 1 to 2, the result must add the new coordinates between the index 1 and 2, but it add the result between the 0 and 1.
My code is simple, I don't know if I'm missing something
let firstElement = route[0].location;
let lasIndex = (route.length - 1)
let lastElement = route[lasIndex].location;
let waypoints = route.slice(1, -1)
this.directions.setOrigin(firstElement);
waypoints.forEach((element, index) => {
this.directions.addWaypoint(index, element.location);
});
this.directions.setDestination(lastElement);
hope someone can helpe me to solve this problem
Related
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
I'm looking for a smart way to insert a point into a LineString with Openlayers-3. Today, I saved the closest point along the full LineString, made a loop with forEachSegment to find the segment of the closest point and insert the point between start and end of this segment. Finally, I give the new section back into the geometry of the full LineString.
It's working. But any smarter, short solution?
Thanks & Cheers!
Andreas.
pp=modifyfeatures.item(g).getGeometry().forEachSegment(function (start, end){
waylinexy=new Array();
waylinexy.push(start);
waylinexy.push(end);
var segment = new ol.Feature({geometry:new ol.geom.LineString(waylinexy, 'XY')});
pp.push(start);
if (segment.getGeometry().getClosestPoint(cmpos).toString()==cmpos.toString()){pp.push(cmpos); }
pp.push(end);
return pp;
});
var ps = new ol.Feature({geometry:new ol.geom.LineString(pp, 'XY')});
modifyfeatures.item(g).getGeometry().setCoordinates(pp);
Looks like foreachsegment is not working with lines with more than one segment. For insering more than one point into a linestring I use this solution now:
p=new Array();
cmpos=modifyfeatures.item(g).getGeometry().getClosestPoint(eventcoord);
linegeo=modifyfeatures.item(g).getGeometry().getCoordinates();
for (a=0;a<linegeo.length-1;a++)
{
start=linegeo[a];
end=linegeo[a+1];
var segment = new ol.Feature({geometry:new ol.geom.LineString([start, end], 'XY')});
p.push(start);
if (segment.getGeometry().getClosestPoint(cmpos).toString()==cmpos.toString()){p.push(cmpos); }
p.push(end);
}
modifyfeatures.item(g).getGeometry().setCoordinates(p);
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 am trying to add some functionality that will zoom the map in/out depending on the points that are returned from a query. So for example, say we're zoomed in on the state of Texas. If I execute a query and the service returns back points that are in Texas AND some located in California, I would like the map to then zoom out and then display both California and Texas. I have been looking through the ArcGIS JS API to see how I could implement it but I'm having trouble figuring out what properties and/or methods to use to accomplish this.
The FeatureSet provided to the QueryTask's onComplete callback has the property features that is an array of Graphics.
The javascript api provides the esri.graphicsExtent(graphics) function that can accept that array of Graphics and calculate their extent. Once the extent has been calculated, map.setExtent(extent) can be used to zoom the map to that extent.
It should be noted that the documentation for esri.graphicsExtent(...) specifies that 'If the extent height and width are 0, null is returned.' This case will occur if the returned Graphics array only has a single point in it, so you'll want to check for it.
Here's an example QueryTask onComplete callback that could be used to zoom the map to the extents of points returned by the query:
function onQueryComplete(returnedPointFeatureSet){
var featureSet = returnedPointFeatureSet || {};
var features = featureSet.features || [];
var extent = esri.graphicsExtent(features);
if(!extent && features.length == 1) {
// esri.getExtent returns null for a single point, so we'll build the extent by hand by subtracting/adding 1 to create x and y min/max values
var point = features[0];
extent = new esri.geometry.Extent(point.x - 1, point.y - 1, point.x + 1, point.y + 1, point.spatialReference);
}
if(extent) {
// assumes the esri map object is stored in the globally-scoped variable 'map'
map.setExtent(extent)
}
}
I agree, map.setExtent(extent, true) is the way to go here. Another observation: In case we have only a single point it's worth considering simply using map.centerAndZoom(point, ZOOM_LEVEL) instead of creating an extent. Then, we could just have this:
function onQueryComplete(returnedPointFeatureSet){
var featureSet = returnedPointFeatureSet || {};
var features = featureSet.features || [];
var extent = esri.graphicsExtent(features);
if(!extent && features.length == 1) {
var point = features[0];
map.centerAndZoom(point, 12);
}
else {
map.setExtent(extent, true);
}
}
Not a good idea to create an extent from a point that way. If the units are in degrees you could get a huge extent. Instead, you could do a buffer around the point using the geometryEngine
function onQueryComplete(featureSet){
if (featureSet.features.length) {
var extent = esri.graphicsUtils.graphicsExtent(featureSet.features);
if(!extent && featureSet.features.length == 1 && featureSet.features[0].geometry.type == "point") {
var point = featureSet.features[0];
var extent = esri.geometry.geometryEngine.buffer(point.geometry, 1, "meters").getExtent();
}
// assumes the esri map object is stored in the globally-scoped variable 'map'
map.setExtent(extent)
}
}
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