Mapbox - Update data-driven styling in session - mapbox

There are several tutorials on data-driven styling on Mapbox's site, but none of them address how to update an existing data-driven style (created in Mapbox Studio) in-session. For example, say I want to create a choropleth of US states, colored by area. User then selects 'color by population' and the color of the states update accordingly.
I've found some resources that would allow one to achieve this by adding the geojson of all the states and then doing map.addLayer, however the geojson I'm working with (census tracts) is too massive to add to the front-end, so I needed to change the data-driven styling of an existing layer (or find a similar work-around). The data has to be a persisted tileset from mapbox studio, with user updating the data coloration based on geojson properties.
Any ideas or examples would be much appreciated.

Updating data-driven styling at run-time is straightforward. You simply call map.setPaintProperty.
I usually implement this with one function that generates the property value. Something like this:
function fillColorByPopulation(min, max) {
return {
property: 'pop',
stops: [
[min, 'red'],
[max, 'blue']
],
type: 'exponential'
}
}
function updateStyle(prop) {
if (prop === 'population') {
map.setPaintStyle('regions', 'fill-color', fillColorByPopulation(data.minpopulation, data.maxpopulation));
} else {
map.setPaintStyle('regions', 'fill-color', 'transparent');
}
}
I generally don't create any data-driven styles within Mapbox Studio. It's simpler to create them all in Javascript.

Related

Ag Grid Autocomplete in edit cell

I need to implement Autocomplete feature in ag grid cell on the table. Is ag provides any options for that. I am just seeing select with options. But my need is to edit the cell and while start typing the values has to display below based the character.
Like you I could not find this feature. I decided to write an Angular component for this purpose and share it.
It has the ability to filter by starting to type, as well as clicking the selection by mouse. Keyboard arrow up and down navigation is also included.
It's a simple component and should be quite straightforward to edit to your likings, or take the code and implement in JS or a different framework if you are not using Angular. I am having some unfortunate cosmetic issues (primarily on the last column of the grid), which I hopefully can solve soon and then will update the repository.
https://github.com/superman-lopez/ag-grid-auto-complete
Edit:
Since my original post, a new project has started and this is not limited to Angular projects:
https://github.com/avallete/ag-grid-autocomplete-editor
You can use a jQuery autocomplete as part of the cell editor. You have to do it in the afterGuiAttached function of the custom editor so it won't run until after your input has been created.
// function to act as a class
function YourCustomEditor () {}
// gets called once before the renderer is used
YourCustomEditor.prototype.init = function(params) {
this.eInput = document.createElement('input');
this.eInput.setAttribute('class', 'inputClass');
this.eInput.setAttribute('type', 'text');
}
};
YourCustomEditor.prototype.afterGuiAttached = function() {
$('.inputClass').autocomplete({
source: function(request, response) {
// Do your autocomplete filtering here
},
datatype: 'json',
select: function(event, ui) {
// Do Stuff on select
}
});
this.eInput.focus();
};

How to get the feature geojson from the result of queryRenderedFeatures on a layer whose source is a vector tile in mapbox gl js?

I have a layer called "Searched LayerX" having a vector tile source. I am having a simple requirement of highlighting a feature inside this "Searched LayerX" at runtime.
I was thinking of using the result of queryRenderedFeatures on "Searched LayerX" with the filter of unique ID of this particular feature and using this feature's geojson as a separate source to the new layer which I will be adding as "Selected LayerX".
var features = mapBox.queryRenderedFeatures({layers:['Searched LayerX'], filter : ["==",'gid','7818_2_CA']})
var selectedFeature = features[0];
Resultant feature set does not provide any geojson which I can use to create a new geojson source.
So my question is, how do I use the result as a different source to my "Selected LayerX"?
You can use the method described in the first link below - but understand that the returned feature is not the same as the source GeoJSON feature - it is the vector tile representation of that feature at that zoom level, which means it might be highly simplified.
https://gis.stackexchange.com/questions/186533/highlight-feature-with-click-in-mapbox-gl
Another method is to add another layer with the same source, and use the filter function for the highlight as shown in the two links below -
http://www.mapbox.com.s3-website-us-east-1.amazonaws.com/mapbox-gl-js/example/query-similar-features/
highlighting polyline features in mapbox-gl.js
Try this post, I have added the code which will let you have the features using querySourceFeatures() https://stackoverflow.com/a/66308173/9185662

Change 'prefer canvas' setting per leaflet map

I'm using Leaflet (v 0.7.7). It expects setting L_PREFER_CANVAS as a script tag, which is global. I wish to create 2 maps on same page, one with L_PREFER_CANVAS flag ON and once with OFF. How can I do that ?
1) I've tried setting window.L_PREFER_CANVAS before the map creation.
2) I've tried creating my layers with extended classes like this
var MyCircle = L.Circle.extend({
statics: {
CANVAS: true,
SVG: false
}
});
then using 'new MyCircle' instead of 'L.circle'.
Neither of the two methods have the desired effect, even though the map is rendered successfully
I'm looking into leaflet code but i'm not very comfortable with its inner workings yet, due to lack of js sorcery know-how i believe
Edit: A thing that partly works is cloning the entire leaflet source under a new object (M.* instead of L.), and keep my desired flag enabled for it. But its clumsy and breaks with plugins which add their functionality to L. classes. Thereby requiring more duplication to fix, which i'm trying to avoid
Would recommend you look into migrating onto Leaflet 1.0, where preferCanvas is now a traditional option inside the map constructor...Among many other significant improvements.
http://leafletjs.com/reference-1.0.0.html#map-prefercanvas

Loading geoJson with simplestyle into leaflet

Is there any way to load a GeoJson file with "simplestyle" (for example, created with geojsonio) directly into Leaflet, so it could use the color, stroke and other properties?
It seems that it is supported in the mapbox, but what about leaflet itself?
Thanks,
Alex
This isn't supported out-of-the-box by Leaflet but you could write your own logic using the pointToLayer function of L.GeoJSON:
Function that will be used for creating layers for GeoJSON points (if not specified, simple markers will be created)
http://leafletjs.com/reference.html#geojson-pointtolayer
new L.GeoJSON(collection, {
pointToLayer: function (feature, latlng) {
// Return a custom marker
}
});
In that function you have access to each feature's properties so you can return a custom marker based on them. Hope that helps, also found the following gist on github which shows a implementation which might do what you are looking for:
https://gist.github.com/tmcw/3861338

How do I use OSM custom tags in Mapbox style

Here's a brief description of what I'd like to do (and I'm very, very new to this but seem to have hit a wall):
Display a map of color-coded buildings based on a custom tag (miamioh_lds).
What I've tried: in Mapbox Studio Classic starting with the Emerald style (coordinates 84.7286, 39.5033)
#building [miamioh_lds="uitcp"] {
polygon-fill: #f61313;
}
I would expect Hoyt Hall to be red, but it is not, even if I remove all other #building CartoCSS statements.
I would like the building filled, which is why I'm using tags and fill instead of using a data source, which seems to be focused at adding markers. I'm using Mapbox because my goal is to bring the map into Tableau (which I'll use to add a marker off dynamic data, which is why I need a fill, not a marker here).
Can I use custom tags in CartoCSS? If so, what am I doing wrong?
Thanks!