I am drawing transport lines that are overlapping: two lines are going through the same road.
var routePath = new google.maps.Polyline({
path: polylinePoints,
As one line hides the other, I would like to shift one of these lines to make the two lines visible on the network.
I was wondering if it was possible to move a polyline as "one whole shape"?
because when I use the options: draggable:true, editable:true I get the opportunity to redraw the polyline "point by point", and as you have understood, it is not what I would like to do.
Thanks.
You can try this way (it is only a suggestion not tested ):
manage the polyline by click event
google.maps.event.addListener(drawingManager, 'click', function(line) {
var coord = line.getPath();
var newCoords
var numCoord = coord.length;
for (i = 0; i < numCoord; i++) {
newCoord[i] = new google.maps.LatLng(coord[i].lat + yourShiftY, coord[i].lng + yourShiftX);
}
line.setPath(newCoord);
});
Related
I am new to Leaflet and I am trying to show a map with markers.
The problem I have is that the markers disappear when I zoom out, and are replaced with a number:
I used CircleMarkers to be able to set the color of each marker, and so that the markers keep their size no matter the zoom level. I add the markers using markercluster because I want to be able to delete them all easily.
<script src="https://unpkg.com/leaflet.markercluster#1.3.0/dist/leaflet.markercluster.js"></script>
function addMarkers(data){
// setup a marker group
markerList = L.markerClusterGroup();
for (var i = 0; i < data.length; i++){
var circleColor = getcolor(data[i].roundScore);
var circle = L.circleMarker([data[i].solutionLat, data[i].solutionLng], {
color: circleColor,
fillColor: circleColor,
fillOpacity: 0.5,
radius: 5
});
circle.bindPopup("Score : " + data[i].roundScore + "\n Address :" + data[i].address);
markerList.addLayer(circle);
}
window.mapMark.addLayer(markerList);
}
function deleteMarkers(){
if(markerList) {
markerList.clearLayers();
}
}
I have no idea how to change this behavior, and whether it is linked to the markers themselves or to the tile I use, which is openstreetmap:
const attribution =
'© OpenStreetMap contributors';
const tileUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
const tiles = L.tileLayer(tileUrl, { attribution });
tiles.addTo(mapMark);
}
Any help or hint would be greatly appreciated.
Thank you very much :)
The disappearance of your Circle Markers and replacement by numbers is the expected effect of Leaflet.markercluster. should you have included the plugin CSS files as well, these numbers would appear in green/yellow/orange bubbles.
To avoid this clustering, but still be able to remove all your Markers at once, simply use a basic Layer Group instead of a MarkerClusterGroup:
https://leafletjs.com/reference-1.7.1.html#layergroup
Used to group several layers and handle them as one.
markerList = L.layerGroup();
// you can also clear layers of a basic Layer Group
markerList.clearLayers();
I have a leaflet.js map with a collection of markers, which can be shown/hidden in a legend div done with plugin Leaflet.StyledLayerControl (I think this is not too relevant but just in case).
I can capture the event when layers are shown or hidden and in that event I would like to zoom to fit all visible markers.
There are a few questions in SO with a very similar title but most of them pretend to fit zoom to a known collection of markers, which is not my case (some other questions with very similar subject refer to Google maps, not leaflet).
So, the question would be:
A) Can I set zoom to fit all visible markers?
B) or, how can I get an array of all visible markers to apply the other solutions seen?
This is how I create markers on map:
const icon_general = L.divIcon({html: '<i class="fas fa-map-marker fa-2x"></i>', iconSize: [20, 20], className: 'node_icon'});
var node_10031 = L.marker([40.7174605,-3.9199218],{ icon: icon_general}).addTo(layer1);
node_10031.bindPopup('<h2>Title</h2>');
var node_10032 = L.marker([40.7184576,-3.9202692],{ icon: icon_general}).addTo(layer1);
node_10032.bindPopup('<h2>Title</h2>');
var node_10032 = L.marker([40.7361371,-3.9453966],{ icon: icon_general}).addTo(layer2);
node_10032.bindPopup('<h2>Title</h2>');
Layers are then hidden or shown and I can capture that event, that is where I want to modifiy zoom or loop through visible markers.
EDIT (final solution based on Seth Lutske response):
This is my final solution, maybe it's less eficient as on each click it loops through all visible markers in map, but after some attempts this was the succesful one (I wasn't able to manage properly the individual events for add/remove layer):
function setZoom2Visible()
{
var visibleLayerGroup = new L.FeatureGroup();
mymap.eachLayer(function(layer){
if (layer instanceof L.Marker)
visibleLayerGroup.addLayer(layer);
});
const bounds = visibleLayerGroup.getBounds();
mymap.fitBounds(bounds);
}
$('.menu-item-checkbox input[type=checkbox]').click(function(){
setZoom2Visible();
});
Create a featureGroup and add the markers to it:
const myGroup = L.featureGroup([node_10031, node_10032, node_10033]);
On whatever event you're using to capture the markers being added to the map, you can get the bounds of the featureGroup and set the map's bounds to that:
function onMarkersAddedEventHandler(){
const bounds = myGroup.getBounds();
map.fitBounds(bounds);
}
Now if you're saying that each marker has its own toggle in the UI, it's a bit more complicated. You'll have to attach an event to each marker's UI checkbox, and on change of that checkbox, add or remove the marker from the group, then reset the bounds:
const node_10031_checkbox = document.querySelector('input[type="checkbox"]#10031');
function onMarkersAddedEventHandler(e){
if (e.target.checked){
myGroup.addLayer(node_10031)
} else {
myGroup.removeLayer(node_10031)
}
const bounds = myGroup.getBounds();
map.fitBounds(bounds);
}
My App show couriers on Google Maps and as soon as the application receive a GPS update for one of the courier I keep the Map updated with the new courier position. It happen every second for each of my couriers.
The issue is that every time a courier is updated it is moved on top of all others causing a "disco" effect on the map (because couriers may have differe marker color).
I wish to keep the Marker at the same position (in terms of zIndex or whatever) when its position is updated.
How can I do that?
I don't think any code is required here... I do nothing special than create markers and update markers, but I'm pretty sure a comment will arrive with: "show code", so here we are:
funciton createCourierMarkers() {
var couriersStorage = [];
for (var i = 0; i < couriers.length; i++) {
var courier = couriers[i];
var status = courier.status || 'free';
var courierPosition = _getCourierPosition(courier);
var icon = MarkersService.getCourierIcon(status);
var courierMarker = new google.maps.Marker({
map: map,
position: courierPosition,
icon: icon,
zIndex: 200,
type: 'courier',
id: courier.id,
status: status
});
couriersStorage.push(courierMarker);
}
}
function updateCourierMarkerPosition(courier, marker) {
var courierPosition = _getCourierPosition(courier);
marker.setPosition(courierPosition);
}
I have a polygon which is editable so when i start to edit it it shows small icon on it.
Below in picture an arrow icon (for undo changes).
so i want to add another icon by my own so user can delete that polygon by clicking on it. So ho to add icon there?
Update
Here is what i do so far
Link
Now i just want to add icon when polygon complete event fired.
So you've already got the event listener for when the polygon is complete.
What you could do is add a marker in the middle of your polygon, with a custom icon that looks similar or identical to the 'undo' icon Google are using.
google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
drawingManager.setDrawingMode(google.maps.drawing.OverlayType.FALSE);
// find out the paths of this polygon
var path = polygon.getPath();
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < path.length; i++) {
bounds.extend(path.getAt(i));
}
var centre = bounds.getCenter();
// add a marker here:
var marker = new google.maps.Marker({
position: centre,
map: map,
icon: 'https://google-developers.appspot.com/maps/documentation/javascript/examples/full/images/beachflag.png'
});
});
I try to use custom icons for the markers on my map.
It works great on FF and IE8, but IE7 only shows the default google markers.
For creation of the Markers I use the Class LabeledMarker,
the Image is file type image/PNG.
This code is used to create the marker:
var icon = new GIcon();
icon.image = this.options.icon;
icon.iconSize = new GSize(24, 24);
icon.iconAnchor = new GPoint(12, 12);
icon.infoWindowAnchor = new GPoint(12, 0);
point = new GLatLng(this.data['geo_n'], this.data['geo_o']);
var opts = {
icon: icon,
clickable: false,
labelText: 'test'
};
marker = new LabeledMarker(point, opts);
map.addOverlay(marker)
OK, the problem was something else.
I know that I hate for-loops in IE.
There is a for-loop that iterates over a config-array to find the right icon to display.
for(i in cfg.icons[key]){
Like this in the first iteration i had the value 'rgbToHex' and caused my script to abort
Replaced with this all my scripts work great now:
for(var i = 0; i < cfg.icons[key].length; i++){