I create a new map with zoom equals 4:
map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: new google.maps.LatLng(39.9526, -98.5795),
mapType: 'terrain'
});
I listen for the zoom_changed event so that I can redraw my markers with a new scale:
google.maps.event.addListener(map, 'zoom_changed', function () {
var zoom = map.getZoom();
$log.debug("zoom: " + zoom);
and I create my new icon here:
var greenMarkerIcon = {
path: google.maps.SymbolPath.CIRCLE,
fillOpacity: 1,
fillColor: "green",
strokeWeight: 1,
scale: map.getZoom()
}
When I zoom in, everything looks lovely. The icon grows bigger in scale as I drill down. Zooming out is where the problem is:
Click here for image of icon after reducing scale
The border of the circle becomes bigger and bigger. I've added a debug statement for the icon.strokeWeight property and it remains 1 the entire time. I'm blowing away all of my old markers and redrawing them again, so I don't know why the single marker strokeWeight is appearing bigger.
Any ideas?
I am assuming that you want to change marker icon scale on map zoom and the marker should be smaller/bigger without changing the stroke. Then you need to change only icon scale and set it to the marker:
google.maps.event.addListener(map, 'zoom_changed', function () {
var zoom = map.getZoom();
console.log("zoom: " + zoom);
greenMarkerIcon.scale = (zoom + 1) * scale; // +1 is for avoiding zoom=0, scale is initial scale of icon
marker.setIcon(greenMarkerIcon);
});
check this example: http://jsfiddle.net/dUMFW/108/
The answer provided is correct.
I found out what I was doing wrong. I was creating a new marker each time the user clicked a zoom button. Markers should be created only once and the associated icon should be changed on zoom.
Thanks.
Related
I'm trying to draw a circle on my Leaflet Map that should be always visible and centered even when user move or zoom in the map.
The following code works well when user move the map, but when the user zoom in or zoom out, the size of the circle is not updated. I would like to keep always the same dimension for the circle.
HTML
<div id="map" class="map" style="height:75vh;"></div>
JS
// Init Leaflet Map basically
this.map = L.map("map").setView([38.63, -90.23], 12);
window.map = this.map;
this.tileLayer = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 20,
maxNativeZoom: 18,
attribution: '© OpenStreetMap, © CARTO'
});
this.tileLayer.addTo(this.map);
// Create circle that will be always visible and will have alwaus the same width.
this.circle = L.circle([38.63, -90.23], 3000, {
color: '#5d78ff',
fillOpacity: 0
}).addTo(this.map);
// Set circle always centered when map is moved.
this.map.on("moveend", (s) => {
this.circle.setLatLng(this.map.getCenter());
});
// todo: Set circle always centered when map is zoom in/out
this.map.on("zoomend", (s) => {
this.circle.setLatLng(this.map.getCenter());
console.log('test');
});
JSFIDDLE
https://jsfiddle.net/4uorasdn/
You can use CircleMarker instead of using Circle.
The relevant part of your code that needs to be changed should look something like this.
this.circle = L.circleMarker([38.63, -90.23], {
radius: 200,
color: '#5d78ff',
fillColor: '#f03',
fillOpacity: 0.2,
opacity: 1,
title: "test"
}).addTo(this.map);
And you can find a working jsfiddle here.
I am using marker cluster group.
using that I am able to show two markers.
when you click number two which is in red color you will see two markers.
after that when I click one marker I need to zoom in two levels to see the location
I wrote a marker click for that and in that i added zoom and tried to use fitbounds too, but its not zooming in.
we used mapcenter then also it did not work `
can you tell me how to fix it.
providing my code snippet and sandbox below.
https://codesandbox.io/s/20756jrz8p
MarkerClick = e => {
console.log("e----->", e);
this.setState({
viewport: { center: [20, 6], zoom: 7 }
});
//this.refs.mymap.leafletElement.setZoom(8);
//let bounds = this.refs.mymap.leafletElement.fitBounds();
//console.log("bounds----->", bounds);
console.log(
"after setting state zoomlevel bounds showCard--->",
this.state.zoom
);
// this.setState({ zoom: 18 });
//this.setState({ zoomLevel: 7 });
};
The Zoom value you have used in MarkerClick() is lower than the current zoom value (zoom = 8). Hence you are not getting proper zoom. Use Zoom = 14 or 16 and a different set of co-ordinates instead of [20,6].
For Example:
MarkerClick = e => {
...
this.setState({
viewport: { center: [43.39528702235596, 6.294845731267186], zoom: 16 }
});
...
}
This is related to a previous question: Leafletjs dynamically bound map to visible overlays.
I am now using the Leaflet.FeatureGroup.SubGroup plugin with the Leaflet.markercluster plugin. Trying to set map bound to all visible markers and marker clusters. I am using 3 co-ordinates to test:
[43.6425657, -79.38705569999999]
[43.7164673, -79.3395846]
[-41.3142772, 174.8135975]
This is the code so far:
var map = L.map("mapid");
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png").addTo(map);
map.setView([43.6532, -79.3832], 2);
var parentGroup = L.markerClusterGroup().addTo(map),
consultingMarkers = L.featureGroup.subGroup(parentGroup).addTo(map),
otherMarkers = L.featureGroup.subGroup(parentGroup).addTo(map);
// subGroup1
L.marker([43.6425657, -79.38705569999999]).addTo(consultingMarkers);
L.marker([43.7164673, -79.3395846]).addTo(consultingMarkers);
// subGroup2
L.marker([-41.3142772, 174.8135975], {icon: otherIcon}).addTo(otherMarkers);
var overlays = {
'consulting': consultingMarkers,
'other': otherMarkers
};
L.control.layers(null, overlays, {
collapsed: false
}).addTo(map);
map.on('overlayadd overlayremove', function () {
var bounds = parentGroup.getBounds(),
southWest = bounds.getSouthWest();
// Fit bounds only if the Parent Group actually has some markers,
// i.e. it returns valid bounds.
if (southWest && !southWest.equals(bounds.getNorthEast())) {
map.fitBounds(parentGroup.getBounds());
}
});
So far, I am running into these problems:
Map does not bound to the [-41.3142772, 174.8135975] co-ordinate
Un-checking the "consulting" layer does not bound the map to the markers from the "other" layer which has the co-ordinate [-41.3142772, 174.8135975].
Update: it seems to have this bounding problem for single markers. I tried adding another marker co-ordinate [43.76089289999999, -79.4103427] which would be in the cluster. But if I remove "consulting" cluster and remove "other" layer. The map still does not bound to the last marker left on the map.
If I understand correctly, you are puzzled because when one of your SubGroups has only 1 marker, the map.fitBounds does not look to be executed?
In that case, that is simply the expected behaviour of the !southWest.equals(bounds.getNorthEast()) check: it avoids executing the next block when bounds represents a null area, i.e. there is 0 or 1 marker into it.
By replacing the check by bounds.isValid(), you avoid only the case when there is 0 marker, but in the case there is exactly 1 marker, it will allow executing the next block, therefore trying to fit bounds on a null area. In such case, Leaflet pans to that single marker and zooms to maxZoom.
map.on('overlayadd overlayremove', function () {
var bounds = parentGroup.getBounds();
if (bounds.isValid()) {
map.fitBounds(bounds);
}
});
Demo: https://jsfiddle.net/3v7hd2vx/355/
I am having an issue with layered markers in the Google Maps API when trying to open an InfoWindow on mouseover. I have created a sample fiddle using Google's Complex Items documentation example.
The beachflag marker is a complex shape and uses a 'poly' element to define the area for the mouseover. This allows the mouseover to only appear when the cursor is on the upper half of the img where the flag part actually is.
var map_marker = new google.maps.Marker({
position: new google.maps.LatLng(-33.890542, 151.274856),
map: map,
shape: {
coords: [1, 1, 1, 20, 18, 20, 18, 1],
type: 'poly'
},
zIndex: 101,
optimized: false,
icon: "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png"
});
The circle marker is situated behind the flag and is intended to be overlapped by the flag.
var map_marker = new google.maps.Marker({
position: new google.maps.LatLng(-33.890542, 151.274856),
map: map,
zIndex: 100,
optimized: false,
icon: {
path: google.maps.SymbolPath.CIRCLE,
fillColor: "#0FF",
fillOpacity: 1,
strokeWeight: 1.5,
scale: 40
}
});
I have a mouseover event displaying an InfoWindow for both markers but the problem lies in the small area underneath the flag marker polygon, there is a void where the circle InfoWindow is expected to be show, but doesn't.
One possible resolution to this is to turn the circle marker into a straight Circle, however I need my circle to be a fixed size and not scale with my zoom level.
How can I see the lower-level marker through the upper-level marker's "empty space" outside of its defined poly shape, and correctly display the mouseover InfoWindow?
I have used google maps for displaying some locations using markers, based on the user's current location. User's current location is the center point of the map. The default zoom level is 12. In default, I displayed markers within 300 miles(approximately in my case) distance only.
In that how can I do the following,
1) If decrease the zoom level, I need to increase the distance that should display markers within the increased distance also. how much distance should I increase in miles (i.e. Zoom level is 11) ?
2) If increase the zoom level, I need to decrease the distance that should display markers without the increased distance. how much distance should I decrease in miles (i.e. Zoom level is 13) ?
Please suggest me there is any built-in option to do that ...
I'm not sure if I understand your question correctly, but when you increase the zoom by 1 you must divide the distance by 2. When you decrease the zoom by 1 you must multiply the distance by 2.
The formula would be:
newDistance=(Math.pow(2,initialZoom-currentZoom)*initialDistanceAtInitialZoom)
Demo: (drawing a circle where the formula above will be used to calculate the radius)
function initialize() {
var map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 4,
minZoom:2,
center: new google.maps.LatLng(52.52, 13.4),
noClear:true,
zoomControl:true,
draggable:false,
scrollwheel:false,
disableDefaultUI:true
}),
circle = new google.maps.Circle({
map:map,
center:map.getCenter(),
radius:300000*1.609344
}),
ctrl = document.getElementById('radius');
map.controls[google.maps.ControlPosition.TOP_CENTER].push(ctrl);
google.maps.event.addListener(map,'zoom_changed',
(function(z,r){
return function(){
var radius=(Math.pow(2,z-map.getZoom())*r);
circle.setRadius(radius);
ctrl.innerHTML=(radius/1609.344).toFixed(3)+' miles(zoom:'+map.getZoom()+')';
}
}(map.getZoom(),circle.getRadius())
));
google.maps.event.trigger(map,'zoom_changed');
}
google.maps.event.addDomListener(window, 'load', initialize);
html,body,#map_canvas{
height:100%;
margin:0;
padding:0;
}
#radius{
background:#fff;
padding:4px;
font-size:14px;
font-family:Monospace;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<div id="map_canvas"><div id="radius"></div></div>
I found the zoom_changed event after a quick google
ex:
map.addListener('zoom_changed', function() {
infowindow.setContent('Zoom: ' + map.getZoom());
});
more info Google Api Docs here