How to check if 2 routes share a path - javascript

I have 2 routes, routes A to B and C to D on google maps. Now route C to D share the same street/path with route A to B. How do I check if one is on the polyline of the other?
For example: C to D is on A to B

You can use Geometry Library's poly namespace which contains utility functions that determine whether a given point is inside or near a polygon or polyline.
Use isLocationOnEdge(point:LatLng, poly:Polygon|Polyline, tolerance?:number) method to determine whether a point falls on or near a polyline, or on or near the edge of a polygon. You need to pass the point, the polyline/polygon, and optionally a tolerance value in degrees to google.maps.geometry.poly.isLocationOnEdge() then the function returns true if the distance between the point and the closest point on the line or edge falls within the specified tolerance.
Example:
function initialize() {
var myPosition = new google.maps.LatLng(46.0, -125.9);
var mapOptions = {
zoom: 5,
center: myPosition,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map'),
mapOptions);
var cascadiaFault = new google.maps.Polyline({
path: [
new google.maps.LatLng(49.95, -128.1),
new google.maps.LatLng(46.26, -126.3),
new google.maps.LatLng(40.3, -125.4)
]
});
cascadiaFault.setMap(map);
if (google.maps.geometry.poly.isLocationOnEdge(myPosition, cascadiaFault, 10e-1)) {
alert("Relocate!");
}
}
google.maps.event.addDomListener(window, 'load', initialize);
You can also check these examples on GitHub.

Related

How can I convert lat long coordinates to point coordinates on the map layer in Mapbox?

For a project I need to convert latitude and longitude coordinates to the map layer (map html canvas) point coordinates (in x and y). I have gone through almost the whole of Mapbox's documentation, but I can't seem to find it. Does anybody know how to do it?
(Javascript)
This:
let point;
coordinates = [20,50]
point = convert(coordinates); // => point = (x, y);
You can use mapboxgl.Map method called "project". It returns mapboxgl.Point by LngLatLike coordinates.
TypeScript:
const coordinates: LngLatLike = [37, 55];
const point = map.project(coordinates); // return Point object
// output: {
// x: 713.802690844605
// y: 390.2335262644118
// }
Here is an example code from the official website.
You have to register from the official website. And then you should get an access token for using Mapbox in your project. So it is quite simple.
You can watch this video to understand visually how to do it.
<script>
mapboxgl.accessToken = '<your access token here>';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [12.550343, 55.665957],
zoom: 8
});
var marker = new mapboxgl.Marker()
.setLngLat([12.550343, 55.665957])
.addTo(map);
</script>
Here you see above, in the "center" attribute you can define your own lat(firstly) and lng(secondly)

how to obtain marker's pixel coordinates

My code puts a marker on the map each time I click on it.
The objective is to get each time marker's lat/lon coordinates together with pixel coordinates. So far I've been successful only in getting lat/lon coord. The next step now would be taking these as input and compute the pixel coordinates.
<script>
function initMap() {41.85, -87.65
var myLatlng = {lat: 41.85, lng: -87.65};
var map = new google.maps.Map(
document.getElementById('map'), {zoom: 18,
center: myLatlng,
disableDefaultUI: false,
mapTypeId: 'satellite',
zoomControl: true,
mapTypeControl: true,
scaleControl: true,
streetViewControl: false,
rotateControl: false,
fullscreenControl: true});
map.setOptions({draggableCursor:'default'});
map.addListener('click', function(marker){
marker = new google.maps.Marker({map: map,
clickable: false,
position: marker.latLng,
})
var markerposLat = marker.getPosition().lat();
var markerposLon = marker.getPosition().lng();
function pixl(markerposLat,markerposLon){
var projection = map.getProjection();
var bounds = map.getBounds();
var topRight = projection.fromLatLngToPoint(bounds.getNorthEast());
var bottomLeft = projection.fromLatLngToPoint(bounds.getSouthWest());
var scale = Math.pow(2, map.getZoom());
var worldPoint = projection.fromLatLngToPoint(markerposLat,markerposLon);
return [Math.floor((worldPoint.x - bottomLeft.x) * scale), Math.floor((worldPoint.y - topRight.y) * scale)]
};
localStorage["pixl"] = JSON.stringify(pixl);
localStorage["markerLat"] = JSON.stringify(markerposLat);
localStorage["markerLon"] = JSON.stringify(markerposLon);
console.log(localStorage["pixl"],localStorage["markerLat"], localStorage["markerLon"]);
});
}
</script>
Function pixl is always undefined. I realize it's a question that have been asked many times. In fact I've tried to adapt many methods. My starting points are this: convert-lat-lon-to-pixels-and-back and of course this: showing pixel and tile coordinates. I can't spot the problem.
Please note that the fromLatLngToPoint method requires a google.maps.LatLng class as its parameter. From the documentation:
fromLatLngToPoint(latLng[, point])
Parameters:
latLng: LatLng
point: Point optional
Return Value: Point optional
Translates from the LatLng cylinder to the Point plane. This interface specifies a function which implements translation from given LatLng values to world coordinates on the map projection. The Maps API calls this method when it needs to plot locations on screen. Projection objects must implement this method, but may return null if the projection cannot calculate the Point.
So in your code, I would do it this way instead:
var worldPoint = projection.fromLatLngToPoint(marker.getPosition());
Another thing I (and #geocodezip) noticed is that you are not passing a parameter to your pixl function. This is why it is intended for you to get an undefined response. You should include a parameter like below instead in order to get the correct value:
localStorage["pixl"] = JSON.stringify(pixl((markerposLat,markerposLon)));
Here is the working fiddle for this.

Google Maps API Polyline creation failing with "Uncaught TypeError: number is not a function"

I'm working a django project using the google maps JS api.
Basically what's going on here is that I'm creating a map centered at a point (works perfectly), drawing a bunch of points specified by the journey variable (value is substituted in by django template),
and then trying to draw a polyine between these points. (Fails to produce a polyline with a "Uncaught TypeError: number is not a function" at the JS console.)
The traceback at the JS console is pretty indecipherable to me, particularly due to all the .js files being minned.
When I log the path attribute of the polyline, and the coordinate I'm adding (as seen below), everything seems to work. I know the coord is formatted correctly, because I think Marker and Polyline should take the same datatype (LatLng) for their locations, and the Markers work fine. Anyone have any idea what's happening?
var mapOptions = {
center: { lat: 37.23112,
lng: -122.29398
},
zoom: 15
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
// Make the line that will trace the guys route:
var polyOptions = {
strokeColor: '#000000',
srokeOpacity: 1.0,
strokeWeight: 3
};
var poly = new google.maps.Polyline(polyOptions);
poly.setMap(map);
// Make an array of everywhere the lilguys has been. Passed into this django template as {"lat": 12, "lng": 8} objects.
var journey = [{"lat": 33.2389, "lng":-123.9349}, {"lat":32.928392, "lng":-122.29289}, {"lat":33.928982, "lng":-120.298392}];
var journey_markers = [];
// Draw all the placemarks
for (var i = 0; i < journey.length; i++) {
var coord = journey[i];
journey_markers.push(new google.maps.Marker({position: coord, map:map}));
var path = poly.getPath();
console.log(coord);
console.log(path);
path.push(coord);
}
Thank you!
EDIT:
I substituted the template variables in for what they evaluate to. This was checked by looking at the HTML source code in the browser, and confirmed to not be the source of the bug.
Figured out the answer. It seems to be that unlike Markers, the Polyine path requires google.maps.LatLng() objects rather than latlng literals.
The following fixes the issue:
...
// Draw all the placemarks
for (var i = 0; i < journey.length; i++) {
var coord = new google.maps.LatLng(journey[i].lat, journey[i].lng);
...

What do I need to do to pass value as attribute from angular template to directive?

I have a directive that looks like this:
<g-map-locations center={{myLocation}} zoom="4" id="map" class="map"></g-map-locations>
The zoom-value is used in angular to set the zoom for a google map:
attrs.zoom = zoom
setMapOptions: function(center, zoom){
var mapOptions = {
zoom: zoom,
center: center
}
return mapOptions;
},
google maps complain that setZoom: is not a number, though it works i do
zoom = 4
Can I tell angular to pass the value as a number or convert it in the directive somehow?
HTML attributes are passed in as strings, save for when they are passed in as scoped objects and parsed. The easiest solution, in my view, would be to parse the the number as integer:
setMapOptions: function(center, zoom){
var mapOptions = {
zoom: parseInt(zoom, 10),
center: center
}
return mapOptions;
}

Google Maps v3 Marker Always Appears at Top Left

I'm writing some Google Maps API v3 code, which seems to work just fine with multiple markers, but when there's only 1, it always plots the marker in the top left of the map, just beyond the visible area:
Here's my coffeescript code:
class SimpleMap
constructor: (div_id, lat = 40.783627, lng = -73.942583) ->
# L.Icon.Default.imagePath = "/assets"
#div_id = div_id
#map_options = {center: new google.maps.LatLng(lat, lng), zoom: 10, mapTypeId: google.maps.MapTypeId.ROADMAP}
#markers = []
#map = new google.maps.Map document.getElementById(div_id), #map_options
#loadMarkers() # gets them and plots on the map
#autoFit()
loadMarkers: ->
items = $(".grid-item[data-lat], .apartment[data-lat]")
for item in items
console.log "Adding #{item}"
#addMarker(item)
#autoFit()
addMarker: (item) ->
console.log "Adding marker"
lat = $(item).attr("data-lat")
lng = $(item).attr("data-lng")
console.log "#{lat}, #{lng}"
marker = new google.maps.Marker(
position: new google.maps.LatLng lat, lng
map: #map
title: "This is my marker"
)
#markers.push marker
autoFit: ->
bounds = new google.maps.LatLngBounds()
for marker in #markers
bounds.extend marker.getPosition()
#map.fitBounds bounds
# if you leave out the below, the marker appears int he same position as in the screenshot (slightly off screen) but at the max zoom level.
listener = google.maps.event.addListener(#map, "idle", =>
#map.setZoom 9 if #map.getZoom() > 8
#map.setCenter #markers[0].getPosition()
google.maps.event.removeListener listener
)
The map seems to ignore my attempts to set setCenter(#markers[0].getPosition()). Any ideas?
I believe the issue is in:
bounds = new google.maps.LatLngBounds()
for marker in #markers
bounds.extend marker.getPosition()
#map.fitBounds bounds
where you are extending the current map bounds to include all markers, but you have only one marker, the bounds will extend in a way that the marker will be in the map limit border.
Regards
Following the comments this issue occurs only when there is 1 marker.
Based on this fact I would neardown the problem to this line:
#map.fitBounds bounds
When there is only 1 marker, the NE-corner of bounds is equal to the SW-corner.
I noticed unexpected interactions when you use bounds as fitBounds()-argument in this case.
Suggestion:
only use fitBounds() when there are at least 2 markers.

Categories

Resources