Leaflet JS - center and zoom on feature group - javascript

Code:
var map = L.map('map');
L.tileLayer('//{s}.tile.cloudmade.com/41339be4c5064686b781a5a00678de62/998/256/{z}/{x}/{y}.png',{minZoom:8, maxZoom:15}).addTo(map);
marker1 = L.marker([37.4185539, -122.0829068]).addTo(map);
marker1.bindPopup("Google Campus");
marker2 = L.marker([37.792359, -122.404686]).addTo(map);
marker2.bindPopup("Financial District");
var group = new L.featureGroup([marker1, marker2]);
map.fitBounds(group.getBounds());
The above code will center the map on the center of the markers, but does not set a zoom level so that the markers and only the markers are visible.
If I leave out the 'minZoom' attribute of the map object when adding the initial layer, the entire globe is visible. My desire is to have the map set a zoom and boundaries so that the markers are visible, and zoomed in. Any clues on how to accomplish this?
I thought that the fitBounds method would set a Zoom level, but for some reason in my situation it does not do so.

Your code is setting the map to a zoom level where both of the markers are visible at the highest possible zoom level. Because of the distance between the two markers and the way web mapping works, this is best fit using raster map tiles. Higher zoom levels will be zoomed in so much that you won't be able to see both markers.

Related

In google maps javascript api - how to move map not marker

currently i have a little project that needs to make marker static and move map to the marker display on the map - i hope it makes any sense -
how to move map not marker - like i said the marker cannot move but the map needs to move to the marker when location changed - also marker is displayed at the bottom the map to make room for other events above the marker such as a path display and etc -
whats done already is when car moves it watches gps - then tells marker to move to that gps as a current location and then panby to the bottom of the map - this makes marker jerk at the bottom of the map when its location changed - so i figured if i keep marker static by placing it into a div above map and fixate it via css style - so it stays in the same place all the time - but this is wrong as it cannot be moved with map then when someone drags map with a finger - so this cannot be right solution - what is your solution to this dilema unless i am missing something -
To achieve what you want, you need to rotate the map on the correct axis, find the position of the center of the map, and finally center the map at the right place.
1 - Rotate the map
In your case (I presume you want the car always face of the road in front of the user position) you need to rotate the map before centering, otherwise the map is always oriented to the north and it can be anoying when the car move in other orientation (south for exemple). In this case the point of view is oriented in the wrong direction and the user don't see the upcoming road.
You can find an exemple here in the documentation. Basicaly you need to use setHeading() method. The rotation on gmap is not easy than it can be (see this post).
2 - Find the center of the map
To find the updated position of the center of your map, you need to retrieve the latLng location of a point always at the same distance (in pixel of the map container) above your marker fixed location. Use the methods fromLatLngToPoint() and fromPointToLatLng() to retrieve the position from the map to the real world or vice versa (see getProjection() for more details).
Exemple :
Your map is displayed in 1000*1000 px and the bottom position of the marker you choose is at 500px of the left side and 950px of the top side. If you want to move the center of the map without changing the position of the marker, you need to find the latLng position of the point at 450px above your marker.
function findMapCenter(map, markerLatLng) {
// need this to adjust from the actual zoom on the map
let scale = Math.pow(2, map.getZoom());
// position in pixel x.y from the container
let markerWorldCoordinate = map.getProjection().fromLatLngToPoint(markerLatLng);
// calcul of the position of the center
let centerWorldCoordinate = new google.maps.Point(
markerWorldCoordinate.x,
markerWorldCoordinate.y + (450/scale) // 450 because in my exemple is from 450px at the top of the marker
);
// return latLng of the center point of the map
return map.getProjection().fromPointToLatLng(centerWorldCoordinate);
}
3 - Set the map at the right place
Use setCenter() method to center the map on a choosen latLng location.
let marker; // = config of your marker
let gMap = new google.maps.Map(document.getElementById('map'));
update({lat:MARKER_LATITUDE, lng:MARKER_LONGITUDE});
// call this every time you want to update
function update(markerNewLatLng){
// ... first step : rotate the map if you need to
// then update marker position
marker.setPosition(markerNewLatLng);
// center the map
gMap.setCenter(findMapCenter(gmap, markerNewLatLng));
}

Leaflet: draw polyline across dateline without using worldCopyJump

I need to show marker across map, drag sideway will have the marker show without hiding the previous one
worldCopyJump will replicate but previous map marker will be gone
I need to limit maxbound only to top and bottom, not sideway.
I couldnt use code below:
var maxSouthWest = L.latLng(-85, -360);
var maxNorthEast = L.latLng(85, 360);
var maxBounds = L.latLngBounds(maxSouthWest, maxNorthEast);
Can the latitude and longitude to be correct even crossing map dateline?
I need to draw shortest polyline route which similar to google map, example Japan to USA
in my leaflet will have the longitude more than 180 (240 example), which i want it to be in correct lat lng
worldCopyJump doesnt suit what I need
cannot cut polyline as user are allow to draw the best route line (even wrapping the whole world)
Refer to https://github.com/Leaflet/Leaflet/issues/5340 for image.

How to obtain marker position relative to HTML page

I am using Google Maps API V3 for JavaScript, I do like to get a Marker's position relatively to my page in pixels (left, top), so I can add a custom label when hoving the mouse over my marker. How do I get that position?
If your referring to getting the position of your mouse while you hover, use overlay in the listener to get the projection and the pixel coordinates. Overlays are objects on the map that are tied to latitude/longitude coordinates, so they move when you drag or zoom the map. If you want to place an image on a map, you can use a GroundOverlay object or you can create your own Custom Overlays with the use of OverlayView class.
Sample code using OverlayView:
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map); // 'map' is new google.maps.Map(...)

Google Maps API - Create Offset for Overlays dynamical for every zoom level

I have a balloon which pops up when clicking on a Marker. Sometimes the balloon exeeds the bounds of the map and is not fully shown.
I can't center the map to the coordinates of the marker, because the ballon is sometimes too high and would still be outside the bounds. So I need an offset which moves the center of the map slightly down so the balloon is always nicly in the middle of my map.
The problem is that Google maps doesn't work with pixels but with LatLng. Therefore I need a dynamically scalable function to keep the offset in every zoomlevel the same!
Alright, I found an algorithmic solution!
map.setCenter(
new google.maps.LatLng(
marker.getPosition().lat()+(X/Math.pow(2,map.getZoom())),
marker.getPosition().lng()
)
);
Each zoom level nearly doubles the LatLng which is shown on the map. So just find an X which is the perfect offset for you (in my case it was 128) and everything works great!
PS: The position of the marker is the same as the balloon.

Google Maps API V3 fromDivPixelToLatLng not consistent

I need to place a marker at a fixed pixel location within the map's div. To instantiate a marker, you need a LatLng. I understand that fromDivPixelToLatLng() is the way to convert from pixel co-ordinates to a LatLng, but I can't get it to behave consistently.
I have posted a simple example of my problem at http://www.pinksy.co.uk/newsquare/overlaytest.html. Click on the map to place a marker at 200px/200px. Drag the map around and click again. I was expecting a marker to be placed at 200px/200px every time, but this is not the case.
First I set up the map as usual, in a 600px by 300px div:
var london = new google.maps.LatLng(51.501904,-0.130463);
var mapOptions = {
zoom: 15,
center: london,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
Then I create an overlay:
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
To test fromDivPixelToLatLng(), I create a click event on the map, which attempts to place a marker at pixel location 200px/200px. Regardless of where you drag the map, I was expecting the marker to always be placed at 200px/200px:
google.maps.event.addListener(map, 'click', function(event) {
var pixelLatLng = overlay.getProjection().fromDivPixelToLatLng(new google.maps.Point(200,200));
var marker = new google.maps.Marker({
position: pixelLatLng,
map: map
});
});
However, drag the map around, and you will see that the marker is not always placed at 200px/200px. Any ideas?
Thanks!
After experimentation, I have found that fromContainerPixelToLatLng() is what I'm looking for. For the benefit of others, I have posted an example at http://www.pinksy.co.uk/newsquare/overlaytest2.html.
(For the record, I'm still unsure why fromDivPixelToLatLng behaves the way it does, but never mind!)
Check the demo under:
http://jsbin.com/otidih/51 for some more experiments on this.
To get the logging start the console - most things are logged there.
Detailed explanation from this groups post.
A shorter version below:
The ContainerPixel is calculated relative to your map container. If you pan the map, then the ContainerPixel of LatLngs changes.
The ContainerPixel of things that don't move with the map (float) doesn't change.
For example, the ContainerPixel of the mapCenter stays the same if you don't resize the map:
overlay.getProjection().fromLatLngToContainerPixel(map.getCenter())
The DivPixel is calculated relative to a huge Div that holds the entire tilespace for the world at the current zoom level.
overlay.getProjection().fromLatLngToDivPixel(point)
If you do not change the zoom level and move (pan) the map, then the DivPixel of anything that moves with the map will stay the same. For example the DivPixel of a given city on a map will stay the same, even if you move the map. It will only change when you change the zoom level or cross the international dateline.
Please note that the actual reference point used for calculating the DivPixel gets reset
whenever the map zooms, so the same LatLng can have different DivPixel values even when you come back to the same zoom level.
Also to be considered is the Point value returned from
map.getProjection().fromLatLngToPoint()
which is well explained in the API Reference
It translates from the LatLng cylinder to the big point plane which always stays the same (no matter which zoom level). Given LatLngs will always map to the same Point.
The (0,0) point is the (85.0511287798066,-180) LatLng - where to Google Map cuts of (if you want to know why , read about the Mercator projection)

Categories