custom markers not displaying on mapbox map - mapbox

I am working with a mapbox map on a web page, and have everything working fine with the map and dropping pins, but cant get custom markers working.
My code that is working for dropping a pin is:
L.mapbox.featureLayer({
type: 'Feature',
geometry: { type:'Point', coordinates:[$longitude, $latitude] },
properties: { title:'My Location', description:'My Description', 'marker-size':'large', 'marker-color':'#cc0000', 'marker-symbol':'building' }
}).addTo(map);
This works and populates the map with my locations.
I have used this code to try and add a custom marker, but this doesnt work:
L.mapbox.featureLayer({
type: 'Feature',
geometry: { type:'Point', coordinates:[$longitude, $latitude] },
properties: { title:'My Location', description:'My Description', icon: { iconUrl: 'https://www.mapbox.com/mapbox.js/assets/images/astronaut1.png', iconSize: [50, 50], iconAnchor: [25, 25], popupAnchor: [0, -25], className: 'dot' } }
}).addTo(map);
I also have multiple pins and other layers on the map that can be turned on or off, and everything is working well, I just cant get this custom marker to work at all!
Does anyone have custom markers working with code like this on mapbox?

I don't think you can specify custom marker options like icon like that in the main GeoJSON properties hash.
I believe you would need to do something like the below instead.
var customIcon = new L.Icon({iconUrl: 'https://www.mapbox.com/mapbox.js/assets/images/astronaut1.png', iconSize: [50, 50], iconAnchor: [25, 25], popupAnchor: [0, -25], className: 'dot' })
L.mapbox.featureLayer(
{
type: 'Feature',
geometry: { type:'Point', coordinates:[$longitude, $latitude] },
properties: { title:'My Location', description:'My Description'}
},
{
pointToLayer: function(feature,latLng) { return L.marker(latLng, {icon: customIcon}}
}).addTo(map);
See https://www.mapbox.com/mapbox.js/api/v2.2.2/l-mapbox-featurelayer/

Related

How is this NYT Mapbox map rendered?

The map below is a high resolution county Mapbox map, with dynamically changing data. When trying to render the same high resolution county map with other tools, a lot of processing power is required. Why is this different?
Additionally, I believe they are using a custom tileset to render the county shapes, but then how is the data passed into the visualization? Any insight here would be appreciated. NYT Map Link
Whatever you want to know is in their main.js script
They do not use leaflet but mapbox-gl-js sdkVersion:"2.0.1"
They create a map with their own style
map$1 = new mapboxGl.Map({
container: $wrap,
style: 'mapbox://styles/nytgraphics/cjnxfd2cy57nq2rqj8o3d7sl2',
scrollZoom: false,
boxZoom: false,
maxZoom: 10
});
Then they create their fill layers based on the sources they load
function addSources() {
Object.keys(tilesets).forEach((name) => {
map$1.addSource(name, {
type: 'vector',
url: `mapbox://${tilesets[name]}`,
promoteId: 'geoid'
});
});
map$1.on('sourcedata', () => {
addLayers();
});
}
...
...
map$1.addLayer({
id: 'counties',
type: 'fill',
source: 'counties',
'source-layer': 'USA_Counties_With_RI',
paint: {
'fill-color': [
'case',
['has', ['get', 'geoid'], ['literal', colorLookup]],
['get', ['get', 'geoid'], ['literal', colorLookup]],
'#cccccc'
],
}
});

Tooltip doesn't work in Google Scatter Chart

I'm trying to create a scatter plot using Google charts and I don't seem to be able to add a column to be a tooltip. I read various sources that state that the data definition should be as:
var data = new google.visualization.DataTable();
data.addColumn('string', 'Year');
data.addColumn('number', 'Sales');
// A column for custom tooltip content
data.addColumn({type: 'string',role: 'tooltip',});
data.addRows([
['Name1', 1000, 'Tooltip string'],
['Name2', 1170, 'Tooltip string'],
['Name3', 660, 'Tooltip string'],
]);
However, it doesn't work.
JSFiddle to demonstrate the issue: https://jsfiddle.net/shakedk/c37L0d1n/
column roles are not supported by material charts,
along with several other options.
see --> Tracking Issue for Material Chart Feature Parity
for custom tooltips, you will need to use a classic chart.
material = google.charts.Scatter -- package: 'scatter'
classic = google.visualization.ScatterChart -- package: 'corechart'
see following working snippet...
google.charts.load('current', {
'packages': ['corechart']
});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Year');
data.addColumn('number', 'Sales');
// A column for custom tooltip content
data.addColumn({
type: 'string',
role: 'tooltip',
});
data.addRows([
['Name1', 1000, 'Tooltip string'],
['Name2', 1170, 'Tooltip string'],
['Name3', 660, 'Tooltip string'],
]);
var options = {
width: 800,
height: 500,
chart: {
title: 'Example',
},
};
var chart = new google.visualization.ScatterChart(document.getElementById('scatterchart_material'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="scatterchart_material"></div>
To add to the answer of WhiteHat:
ScatterChart + Tooltip + Dashboard filter column:
I experienced with the ScatterChart that tooltips also do not work with the "arrayToDataTable method" IF there is also a string column that is used as the filter column of the google.visualization.ControlWrapper.
The "arrayToDataTable method" works well with just 2 columns with data and a 3rd column with the tooltip.
It also works well if the 3rd column contains the input for the dashboard filter.
But there is a 3rd and a 4th column then the "arrayToDataTable method" cannot be used (for ScatterCharts).
It works well if I use the DataTable.addRows method:
google.charts.setOnLoadCallback(chart_ecdf);
function chart_ecdf() {
var data = new google.visualization.DataTable();
data.addColumn('number','Population');
data.addColumn('number','Area');
data.addColumn({
type: 'string',
role: 'tooltip',
})
data.addColumn('string','Filter');
data.addRows([
[1324, 9640821, 'Annotated 1', 'A'],
[1133, 3287263, 'Annotated 2', 'A'],
[304, 9629091, 'Annotated 3', 'A'],
[232, 1904569, 'Annotated 4', 'B'],
[187, 8514877, 'Annotated 5', 'B']
]);
var filter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'filter_ecdf',
options: {
filterColumnIndex: 3,
ui: { caption: 'Kies een type', label: false, allowTyping: false, allowMultiple: false, allowNone: false, sortValues: false } },
state: {'selectedValues': ['{{ .Params.ecdf_filter_state | safeJS }}']}
});
var chart = new google.visualization.ChartWrapper({
chartType: 'ScatterChart',
containerId: 'grafiek_ecdf',
view: {columns: [0,1,2]},
options: {
chartArea: {top:10, left:35, width:'82%', height:'90%'},
vAxis: {minValue: 0, maxValue: 1, format: 'percent'},
hAxis: {format: '#.##%' },
legend: 'none',
colors: ['#ffa852'] },
});
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_ecdf'));
dashboard.bind(filter, chart);
dashboard.draw(data);
}

MapBox GL custom markers with symbol layer

I am trying to cluster custom markers in MapBox GL JS but I cannot figure out how to get a custom marker image from a url into the symbol layer? It either does not work or no markers show up at all. How is it done? I need to know how to use a custom image from a url with the symbol layer. Thank you very much.
map.addSource('parcelpoints', {
type: 'geojson',
data: geojson,
cluster: true,
clusterMaxZoom: 14, // Max zoom to cluster points on
clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
});
map.addLayer({
id: 'clusters',
type: 'circle',
source: 'parcelpoints',
filter: ['has', 'point_count'],
paint: {
// Use step expressions (https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-step)
// with three steps to implement three types of circles:
// * Blue, 20px circles when point count is less than 100
// * Yellow, 30px circles when point count is between 100 and 750
// * Pink, 40px circles when point count is greater than or equal to 750
'circle-color': [
'step',
['get', 'point_count'],
'#51bbd6',
100,
'#f1f075',
750,
'#f28cb1'
],
'circle-radius': [
'step',
['get', 'point_count'],
20,
100,
30,
750,
40
]
}
});
map.addLayer({
id: 'cluster-count',
type: 'symbol',
source: 'parcelpoints',
filter: ['has', 'point_count'],
layout: {
'text-field': '{point_count_abbreviated}',
'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],
'text-size': 12
}
});
map.addLayer({
id: 'unclustered-point',
type: 'symbol',
source: 'parcelpoints',
filter: ['!has', 'point_count'],
'layout': {
'visibility': 'visible',
'icon-image': { url: "marker.svg" }
}
});
First you need to:
load the external image with a specific ID, via map.loadImage().
add the image with a specific ID, via map.addImage(https://docs.mapbox.com/mapbox-gl-js/api/map/#map#loadimage).
There is a worked example here: https://www.mapbox.com/mapbox-gl-js/example/add-image/
// If the style's sprite does not already contain an image with ID 'kitty',
// add the image 'cat-icon.png' to the style's sprite with the ID 'kitty'.
map.loadImage('https://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Cat_silhouette.svg/400px-Cat_silhouette.svg.png', (error, image) => {
if (error) throw error;
if (!map.hasImage('kitty')) map.addImage('kitty', image);
});
To include your loaded image in a symbol layer will look something like:
map.addLayer({
'id': 'clusters',
'type': 'circle',
'source': 'parcelpoints',
'filter': ['has', 'point_count'],
'icon-image': 'kitty',
...
There is no support for directly loading symbol images from URLs.

Google Charts area chart custom tooltip not working as expected

I'm trying to add tooltips to a Google Area Chart, but I'm getting unexpected behavior. I took the Area Chart JSFiddle example and modified it to add a custom tooltip as described here. My content looks like this:
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', { type: 'string', role: 'tooltip'}],
['2013', 1000, 400, 'wtf'],
['2014', 1170, 460, 'hithere'],
['2015', 660, 1120, 'doh'],
['2016', 1030, 540, 'moohaha']
]);
var options = {
title: 'Company Performance',
hAxis: {title: 'Year', titleTextStyle: {color: '#333'}},
vAxis: {minValue: 0},
focusTarget: 'category'
};
var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
JSFiddle here: https://jsfiddle.net/accelerate/y18tb8eq/
Rather than replacing the entire tooltip content, like I expected, the 'expenses' line in the tooltip gets replaced with my tooltip data. For example, the tooltip for the first set of data looks like:
2013
Sales: 1,000
Expenses: wtf
Can someone explain to me what I'm doing wrong?
I figured it out. Which column the tooltip is in matters. I needed to put the tooltip column immediately after the first column. So my header column has to look like this:
['Year', { type: 'string', role: 'tooltip'}, 'Sales', 'Expenses']

Fit Mapbox map to boundaries of dynamic markers

I try to create a map with mapbox, that features dynamic markers. I want the map to automatically fit to the markers, as described here: https://www.mapbox.com/mapbox.js/example/v1.0.0/fit-map-to-markers/. Unfortunately I can't get it working.
The code also contains the feature markers as links (https://www.mapbox.com/mapbox.js/example/v1.0.0/markers-as-links/), which works great – but as JS- and Mapbox-Noob, I can't figure out how to combine both.
The code right now is this:
<div class='start-map'>
<div id='map'></div>
<script>
var map = L.mapbox.map('map', 'XXX', {zoomControl: false})
.setView([-20.1908, -67.5893], 3);
var geoJson = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-67.5893, -20.1908]
},
properties: {
title: 'Salar de Uyuni',
'marker-size': 'small',
'marker-color': '#fff',
url: 'http://localhost'
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [170.2, -43.4764]
},
properties: {
title: 'Franz Josef Glacier',
'marker-size': 'small',
'marker-color': '#fff',
url: 'http://localhost'
}
}
]
};
map.featureLayer.setGeoJSON(geoJson);
map.featureLayer.on('click', function(e) {
e.layer.unbindPopup();
window.open(e.layer.feature.properties.url);
});
geoJson.on('ready', function() {
// featureLayer.getBounds() returns the corners of the furthest-out markers,
// and map.fitBounds() makes sure that the map contains these.
map.fitBounds(geoJson.getBounds());
});
</script>
</div>
Here's corrected code: https://gist.github.com/tmcw/10203442
Issues in this example:
geoJson is a simple JavaScript object, not a layer, so you can't call methods on it.
If you're adding custom data to a map, create a new L.mapbox.featureLayer rather than using map.featureLayer
If you're calling .setGeoJSON() you do not have to wait for the .on('ready' event.