Open the popups of all markers that are visible on the map with a zoom > 10 - popup

I need to open all the markers that are visible on the map at Zoom,
10. I also use leaflet.markercluster.
Init map:
initMap() {
this.map = L.map('map', {
center: [55.55, 37.61],
zoom: 9,
layers: this.layer
})
this.tileLayer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution:
'© OpenStreetMap, ©'
})
this.tileLayer.addTo(this.map)
this.map.on('zoom', function(ev) {
???
})
Add marker layer:
this.markerLayer = new L.LayerGroup() // layer contain searched elements
// this.map.addLayer(this.markerLayer)
for (const i in data) {
...
const marker = new L.Marker(new L.latLng(loc), { title: title, icon: icon })// se property searched
marker.bindPopup(title)
this.markerLayer.addLayer(marker)
}
Use leaflet marker cluster:
this.markersLayer = L.markerClusterGroup({
iconCreateFunction: function(cluster) { ... },
singleMarkerMode: false
})
this.markersLayer.addLayer(this.markerLayer)
this.map.addLayer(this.markersLayer)

You should add your markers to an array before / after adding them to the map to access them easily.
var markers = [];
for (const i in data) {
const marker = new L.Marker(new L.latLng(loc), { title: title, icon: icon })
marker.bindPopup(title)
this.markerLayer.addLayer(marker)
markers.push(marker);
}
after that you can just loop through your markers array and use openPopUp function of marker to open popups of your markers programmatically.
for(i = 0; i< markers.length;i++){
markers[i].openPopup();
}

Related

How to automatically add roofs as polygons in Mapbox

Currently I am getting streets from the geocoding api then displying houses in that street in satelite view. Is there a way to automatically detect house roofs and automatically draw polygons over them?
mapboxgl.accessToken = accessToken;
const map = new mapboxgl.Map({
container: 'map', // container ID
style: 'mapbox://styles/mapbox/satellite-v9', // style URL
center: [lng, lat], // starting position [lng, lat]
zoom: 17, // starting zoom
});
const draw = new MapboxDraw({
displayControlsDefault: false,
controls: {
polygon: true,
trash: true
},
// Set mapbox-gl-draw to draw by default.
// The user does not have to click the polygon control button first.
defaultMode: 'draw_polygon'
});
map.addControl(draw)
map.addControl(new mapboxgl.NavigationControl())
map.on('draw.create', updateArea)
map.on('draw.delete', updateArea)
map.on('draw.update', updateArea)
function updateArea(e) {
const data = draw.getAll()
const answer = document.getElementById('calculated-area')
if (data.features.length > 0) {
const area = turf.area(data)
// Restrict the area to 2 decimal points.
const rounded_area = Math.round(area * 100) / 100
const areaInCM = rounded_area * 10000
answer.innerHTML =
`<p><strong>${areaInCM.toLocaleString('en-US')}</strong> square centimeters</p>`;
} else {
answer.innerHTML = ''
if (e.type !== 'draw.delete')
alert('Click the map to draw a polygon.')
}
}

How to stop cursor flickering over mapbox marker icons?

How do I stop cursor flickering over my Mapbox icons? Here is the live site where you can see the problem when hovering over the marker icons: https://rustic-waters-group.thesparksite.com/lakes/
Here is my code:
mapboxgl.accessToken = 'pk.eyJ1IjoiZG1pdHJpbWFydGluIiwiYSI6ImNreHRobHRmcjVqM3cydmt5NWkxdWNibTcifQ.CuN5Dwc963TW-BKRcowxBA';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/dmitrimartin/ckxtj5aur4fvv15mrhmihala8',
center: [-89.2, 44.33],
zoom: 9.2
});
map.on('load', () => {
const popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
map.on('mouseenter', 'lakes', (event) => {
map.getCanvas().style.cursor = 'pointer';
const features = map.queryRenderedFeatures(event.point, {
layers: ['lakes']
});
if (event.features.length === 0) return;
popup.setLngLat(features[0].geometry.coordinates);
popup.setHTML('<h3 class="lake-popup">' + features[0].properties.title + '</h3>');
popup.setMaxWidth("calc(100vw - 40px);");
popup.addTo(map);
});
map.on('mouseleave', 'lakes', () => {
map.getCanvas().style.cursor = '';
popup.remove();
});
map.on('click', 'lakes', (event) => {
const features = map.queryRenderedFeatures(event.point, {
layers: ['lakes']
});
if (event.features.length === 0) return;
window.location.href = ('/lakes/' + features[0].properties.url + '/');
});
document.getElementById("lakes-header").onmouseover = function() {
MyMouseOver();
};
function MyMouseOver() {
document.getElementById("wrapper").style.display = "none";
document.getElementById("lakes-header").style.display = "none";
}
});
The issue stems from the popup box on top of the layer and can be fixed by adding the CSS property 'cursor-events: none' to the popup. That should stop the flickering and shouldn't interfere with the layers.

I can make clickable country labels but get error when I click anywhere else

I am trying to create a pop when the user clicks the country label. My code accomplishes this but if the user accidentally clicks anywhere else I get the error "TypeError: Cannot read property 'properties' of undefined". Any help would be appreciated. Thanks.
export default class App extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
lng: -32.87393,
lat: 43.6439,
zoom: 3,
mxZoom: 7,
};
this.mapContainer = React.createRef();
}
componentDidMount() {
const { lng, lat, zoom , mxZoom} = this.state;
const map = new mapboxgl.Map({
container: this.mapContainer.current,
style: 'mapbox://styles/chriswade112358/ckpipp5el0jky18qwzep8ppyl',
center: [lng, lat],
zoom: zoom,
minZoom: zoom,
maxZoom: mxZoom,
});
map.on('style.load', function() {
map.on('click', function(e) {
const features = map.queryRenderedFeatures(e.point, { layers: ['country-label'] });
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML('you clicked here: <br/>' + features[0].properties.name)
.addTo(map);
});
});
}

update properties of geojson to use it with leaflet

I have a requirement of using leaflet.js to add a map to my site. The site has an administration view where an admin can add markers and add description and image to each marker.
I used the leaflet.draw plugin, and on the create event I try to update the GeoJSON object I got using event.layer.toGeoJSON() to add some properties like image and text but with no luck.
Can any one help me on this?
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osmAttrib = '© OpenStreetMap contributors',
osm = L.tileLayer(osmUrl, {
maxZoom: 18,
attribution: osmAttrib
});
map = new L.Map('map', {
layers: [osm],
center: new L.LatLng(31.9500, 35.9333),
zoom: 15
}),
drawnItems = L.geoJson().addTo(map);
map.addControl(new L.Control.Draw({
edit: {
featureGroup: drawnItems
}
}));
map.on('draw:created', function(event) {
var layer = event.layer;
var json = event.layer.toGeoJSON();
json.properties.desc = null;
json.properties.image = null;
drawnItems.addLayer(L.GeoJSON.geometryToLayer(json));
addPopup(layer);
});
function addPopup(layer) {
var content = '<input id="markerDesc" type="text"/ onblur="saveData(layer);">';
layer.bindPopup(content).openPopup();
alert('out');
}
function saveData(layer) {
var markerDesc = $('#markerDesc').val();
var json = layer.toGeoJSON();
json.feature.properties.desc = markerDesc;
}
There is no need in your "draw:created" listener to convert into GeoJSON and then back to a layer.
By the way, you then add a popup to layer whereas you do not do anything with it, since you transformed it into GeoJSON data and created a new layer out of that data.
Simply create the following structure, so that the stored data can be converted into GeoJSON later on (if you ever need that functionality): layer.feature.type = "Feature" and layer.feature.properties.
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osmAttrib = '© OpenStreetMap contributors',
osm = L.tileLayer(osmUrl, {
maxZoom: 18,
attribution: osmAttrib
});
map = L.map('map', {
layers: [osm],
center: [31.9500, 35.9333],
zoom: 15
});
var drawnItems = L.geoJson().addTo(map);
map.addControl(new L.Control.Draw({
edit: {
featureGroup: drawnItems
}
}));
map.on('draw:created', function (event) {
var layer = event.layer,
feature = layer.feature = layer.feature || {};
feature.type = feature.type || "Feature";
var props = feature.properties = feature.properties || {};
props.desc = null;
props.image = null;
drawnItems.addLayer(layer);
addPopup(layer);
});
function addPopup(layer) {
var content = document.createElement("textarea");
content.addEventListener("keyup", function () {
layer.feature.properties.desc = content.value;
});
layer.on("popupopen", function () {
content.value = layer.feature.properties.desc;
content.focus();
});
layer.bindPopup(content).openPopup();
}
Demo: https://jsfiddle.net/ve2huzxw/314/
Edited: previous code did not actually implemented well the GeoJSON properties functionality (was saved on geometry instead of feature, due to missing layer.feature.type = "Feature", see also Leaflet Draw not taking properties when converting FeatureGroup to GeoJson)

google map info window data display

I have error about for info window data. I can't get the Please help me to check my code.
function initialize() {
map = new google.maps.Map(document.getElementById(map), {
center: new google.maps.LatLng(1.352083, 103.819836),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
//var infowindow;
if (markers) {
for (var level in markers) {
for (var i = 0; i < markers[level].length; i++) {
var details = markers[level][i];
//var infowindow;
markers[level][i] = new google.maps.Marker({
title: details.name,
position: new google.maps.LatLng(
details.location[0], details.location[1]),
clickable: true,
draggable: false,
icon: details.icon
});
var infowindow = new google.maps.InfoWindow({
content: details.description,
//content : markers[level][i].description,
position: new google.maps.LatLng(details.location[0], details.location[1])
//position: markers[level][i].position
});
google.maps.event.addListener(markers[level][i], 'click', function() {
infowindow.setPosition(this.position);
alert(this.position);
//infowindow.setContent(markers[level][i].description);
infowindow.open(map,markers[level][i]);
});
}
}
}
I can't get the description data. Please help me to check my code.