Can't set text on pushpins in Bing Maps - bing-maps

I'm following the example here but I don't get to see the text, only the pushpins themselves. What can I be missing?
for (index in centers)
map.entities.push(new Microsoft.Maps.Pushpin(centers[index]),
{ text: "A", visible: true, textOffset: new Microsoft.Maps.Point(0, 5) });
The array centers is just a set of points and, since I get the pushpins to appear at the right locations, I believe that the error is in the options.
Note that I'm trying to reuse the default pushpins as far as I can and intentionally omit the custom icon. In case I have to use a custom icon (which would be a shame), where can I find a set of pushpins looking like the default one (possibly in various colors)?

From bing interactive sdk.
Just delete the line with the custom pin from you pushpinOptions and you will get the default push pin with text.
The error in you code that you pass the pushpinOptions as parameter to map.entities.push method, but the options is a parameter of new Microsoft.Maps.Pushpin method.
var offset = new Microsoft.Maps.Point(0, 5);
var pushpinOptions = { text : '1', visible: true, textOffset: offset};
var pushpin= new Microsoft.Maps.Pushpin(
new Microsoft.Maps.Location(47.6, -122.33),
pushpinOptions);
map.entities.push(pushpin);

Related

Add Maki Icon instead of Mapbox Geocoder Marker

Just a quick question, if anyone has ever replaced the Mapbox default marker with a Maki icon. I've only seen examples of using Maki icons for point tilesets/layers, but I'm wanting to use it for non-tileset features, specifically replacing the marker that adds after geocoding, at the location of the address just geocoded.
Or, trying to find something that is similar to Google Maps symbols below. Any suggestions appreciated.
var pinImage = {
path: google.maps.SymbolPath.CIRCLE,
fillColor: '#ff4b00',
fillOpacity: .9,
scale: 5,
strokeColor: '#CDDC39',
strokeWeight: 0,
strokeOpacity: .5
}
The MapboxGeocoder control has a marker option https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md#parameters which controls the marker placed on the map when you select a result.
There is an example at https://docs.mapbox.com/mapbox-gl-js/example/custom-marker-icons/ to create a Marker with a custom icon.
So you could create an HTML Element which contains either an SVG or PNG icon from Maki and use that as your element in your custom Marker passed to the MapboxGeocoder control.
I think this sample is what you are looking for Use a custom render function with a geocoder
It allows you to add a custom render function including the icon...
var geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
types: 'poi',
// see https://docs.mapbox.com/api/search/#geocoding-response-object for information about the schema of each response feature
render: function(item) {
// extract the item's maki icon or use a default
var maki = item.properties.maki || 'marker';
return (
"<div class='geocoder-dropdown-item'><img class='geocoder-dropdown-icon' src='https://unpkg.com/#mapbox/maki#6.1.0/icons/" +
maki +
"-15.svg'><span class='geocoder-dropdown-text'>" +
item.text +
'</span></div>'
);
},
mapboxgl: mapboxgl
});
map.addControl(geocoder);

Leaflet map completely grey programmatically opening a popup tofa marker

I declare a leaflet map with
<div id="map" class="map-div"></div>
end initialize it with
var map = L.map('map').setView([51.178882, -1.826215],16);
$scope.map = map;
// OSM Mapnik
var osmUrl = "<a href='http://www.openstreetmap.org'>Open StreetMap</a>";
L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© ' + osmUrl,
maxZoom: 18,
}).addTo(map);
I grab some data from my server, and and markers to the map, in a loop, by calling this function (it's AngularJS, but I doubt that that plays a role):
$scope.AddMarkerToMap = function(companyData, index, array)
{
var companyName = companyData.company_name;
var latitude = companyData.latitude;
var longitude = companyData.longitude;
var cssClassname = 'comapny_has_no_present_workers';
if (companyData['currentWorkers'] > 0)
cssClassname = 'comapny_has_present_workers';
var pubLatLng = L.latLng(latitude,longitude);
// see https://leafletjs.com/reference-1.4.0.html#marker
var marker = L.marker(pubLatLng,
{
// this is the tooltip hover stuff
title: companyData['currentWorkers'] + ' current matches ' + companyData['previousWorkers'] + ' previous matches',
// see https://leafletjs.com/reference-1.4.0.html#icon
// this is a permanent label.
icon: new L.DivIcon({
className: cssClassname,
////html: '<img class="my-div-image" src="http://png-3.vector.me/files/images/4/0/402272/aiga_air_transportation_bg_thumb"/>'+
//// '<span class="my-div-span">RAF Banff Airfield</span>'
html: '<span>' + companyName + '</span>'
})
}).addTo($scope.map);
// see https://leafletjs.com/reference-1.4.0.html#popup
marker.bindPopup("<b>Hello world!</b><br>I am a popup.").openPopup();
}; // AddMarkerToMap()
And the entire map is suddenly grey - with no problems reported in the developer console.
If I comment out the line
marker.bindPopup("<b>Hello world!</b><br>I am a popup.").openPopup();
then everything displays as expected.
The code seems correct, as per the Leaflet documentation.
[Updtae] I just checked and if I only marker.bindPopup("<b>Hello world!</b><br>I am a popup."), the the map displays and I can click on the marker to display the popup. But when I try to programmatically open it with .openPopup(); the map is all grey.
[Update++] the map and its markers display just fine, with any one of
marker.bindPopup("<b>Hello world!</b><br>I am a popup.");
$scope.map.fitBounds(bounds, {padding: [50, 50]});
but with both, the map is grey :-(
What am I doing wrongly?
I think the issue comes from trying to change the map view (possibly through openPopup with autoPan, which is on by default) too often, typically in a loop without giving any delay for the map to actually set the view between each call.
IIRC, this is already identified as a limitation in Leaflet, but I could not find the exact thread in the issue tracker unfortunately.
Normally, a very simple fix is simply to remove the map view changes within your loop, and keep only the very last one.
In your case, if you have the default behaviour of only 1 Popup being opened at a time, then that would definitely be a valid solution: just open the popup of your last Marker.
If you did configure your map to keep several Popups open simultaneously, and you do want to open all of them through your loop, then make sure to disable autoPan (at least during your loop).

Leaflet js dealing with a lot of markers in a single co-ordinate

I am using leafletjs and leafletjs marker clustering to display where my friends live. The problem is that some of them life in a same house, so the coordinates for multiple markers are the same. Issue occurs when there is more than 50 friends living in the same place.
Is there any way, that the markers could be hidden and when a cluster is clicked it would display a table containing all of the names?
My code for adding markers:
export function markersFromData(map, markers) {
return (data) => {
const markerList = [];
data.map((v) => {
const title = v.name;
const marker = L.marker(new L.LatLng(v.latitude, v.longitude), {
opacity: 0,
});
marker.bindPopup(title);
markerList.push(marker);
return markers.addLayer(marker);
});
map.addLayer(markers);
// eslint-disable-next-line
const group = new L.featureGroup(markerList);
map.fitBounds(group.getBounds());
};
}
Map example
Thank you for your time.
A clean solution would be instead of building one marker per data item (i.e. friend), to first group them by matching position.
Then build 1 marker per position, with metadata reflecting the number of items in that position and list of associated names.
Then in the Leaflet Marker cluster group, use the iconCreateFunction to customize the displayed number to sum these number of friends instead of number of child markers.

Mapbox: Filtering out markers in a Leaflet Omnivore KML layer

I am exporting Google Directions routes as KML and displaying them on a Mapbox map by reading them with Omnivore and adding them to the map,
The Google KML stores each route as two Places (the start and end points) and one LineString (the route). In Mapbox I would like to show only the routes, that is to filter out the markers somehow. I'm displaying markers out of my own database and the Google markers clutter it up.
Here is my code. I change the styling of the LineStrings just to show that I can, but do not know what magic call(s) to make to not display the Points.
Thanks.
runLayer = omnivore.kml('data/xxxx.kml')
.on('ready', function() {
var llBnds = runLayer.getBounds();
map.fitBounds(llBnds);
this.eachLayer(function (layer) {
if (layer.feature.geometry.type == 'LineString') {
layer.setStyle({
color: '#4E3508',
weight: 4
});
}
if (layer.feature.geometry.type == 'Point') {
//
// Do something useful here to not display these items!!
//
}
});
})
.addTo(map);
Welcome to SO!
Many possible solutions:
Most straight forward from the code you provided, just use the removeLayer method on your runLayer Layer Group when you get a 'Point' feature.
Cleaner solution would be to filter out those features before they are even converted into Leaflet layers, through a custom GeoJSON Layer Group passed as 3rd argument of omnivore.kml, with a specified filter option:
var customLayer = L.geoJSON(null, {
filter: function(geoJsonFeature) {
// my custom filter function: do not display Point type features.
return geoJsonFeature.geometry.type !== 'Point';
}
}).addTo(map);
var runLayer = omnivore.kml('data/xxxx.kml', null, customLayer);
You can also use the style and/or onEachFeature options on customLayer to directly apply your desired style on your LineString.

Refreshing PopUp content in GeoJSON layer in leaflet

I am loading a geojson file using leaflet's L.geoJSON() to display a map.
Initially i have attahced a popup with each feature.The popup shows a certain property "Count". The code is:
var geoJSON = new L.geoJson(var_name,{
onEachFeature: function(feature,layer){layer.bindPopup('Count :'+feature.properties.Count);},
style: applyStyle
}).addTo(map);
This code works fine.
After this, the user initiates an event and i make an ajax call and assign new values to the property "Count" of each feature. I also use the setStyle function so that the style is reassigned based on new values of "Count". Here is the code:
$.ajax({
type: 'GET',
url: 'new_data.json',
dataType: 'json',
success: function(data){
var i;
for(i=0;i<48;i++){
var_name.features[i].properties.Count = data[i];
}
geoJSON.setStyle(applyStyle);
}
});
The style changes work well but the popup still contains the old value for the property "Count".
There is so setPopUp function like setStyle. So how do i make the popUp change its value?
In other words, can we call the onEachFeature method again after the geoJSON layer has been loaded?
P.S.: I am not using same popup content for each feature. After i make the ajax call, i update the "Count" property of each feature. I want the pop-up for each feature to show the value of its new value of "Count" property.
What you're doing now is using the setStyle method of your L.GeoJSON layer, which when called, iterates all the features contained in the layer and calls the setStyle method of each feature. (If the feature has a setStyle method). Since there is no setPopup method in L.GeoJSON. (it's a very rare use case if you would want the same popup content on each feature) you'll have to iterate the features in your GeoJSON layer yourself and set the new content on the popup itself:
var geojsonLayer = new L.GeoJSON(geojsonCollection, {
'onEachFeature': function (feature, layer) {
layer.bindPopup('Initial content');
}
}).addTo(map);
geojsonLayer.eachLayer(function (layer) {
layer._popup.setContent('Updated content')
});
Here's an example on Plunker: http://embed.plnkr.co/uYHC8jZtgls351YhsmPS/preview
Using the each layer function as suggested by #iH8 , i was able to do this in the following way:
var j = 0; geoJSON.eachLayer(function (layer){
layer._popup.setContent("new count = " + var_name.features[j++].properties.Count);