Performance on changing colour of big geojson by using data-driven (comparing to using setPaintProperty) - mapbox-gl-js

I have been rendering a FeatureCollection of polygons into the Map (in one GeoJSONLayer). The size of each polygon is big (5mb, 10mb). With user interactions, the colours of polygons would be re-calculated & changed constantly. We are using data-driven method and keeping the data in properties of each feature. So GeoJSONLayer has to call .setData(geojson) everytime the data and colours changed (they are kept in properties).
I find above approach is lead to performance issue since the size of geojsons is big and calling .setData() is expensive.
I'm thinking of separating the geojson source and the data, style, colouring and calling direct function (setPaintProperty) whenever colours changed would be better than.
Someone told me that .setData and .setPaintProperty would do the same thing, both 2 will trigger re-rendering whole polygons.
Kindly need help to advice on this matter
Thanks a lot!

If I understand you correctly, you're asking which of these two is faster:
map.setData(mylayer, mygeojson)
map.setPaintProperty(mylayer, 'fill-color', ...mydatadrivenproperty)
I haven't tested, but I'd assume the second is faster, because the first one has to:
Parse the GeoJSON
Convert it to vector tiles
Repaint
whereas the second just has to parse the property repaint. Try them both out to see.
You may also consider a third way, which is to have a second layer which is a highlight, which you update by calling map.setFilter(mylayer, ...).

Related

MapBox. A highlight effect by hover event on table. SetData takes 2s for updating source with 6000 features

I'm trying to implement a highlight effect by hover effect on the table's row. I've got the data table related to Mapbox's point features. I update the map point's styles by my rxjs state (every change in the state calls styles updating on my map). For small features count, it works well, but it takes 2 seconds for updating styles on the map with 6000 points. Directly setData execution takes 150-200 ms, but rendering takes 1-3 seconds. How can I improve the performance of the Mapbox for my task? As I wrote, I have 6000 points on the map, and when I hover the cursor over a row in the table I want to change the style for2 points. Change of style implemented by changing the feature's layer (might that be the matter?).
Thanks for any ideas.
the github issue.
setFeatureState is the most efficient way to update the styling of a small number of features on a map with many features.
It does have certain limitations: it only works on layers with feature IDs, and not all styling can be controlled through feature state (notably, layout properties such as icon-image cannot).
Documentation here: https://docs.mapbox.com/mapbox-gl-js/api/#map#setfeaturestate
I found more productive way to highlight any resource. I just use another data-source for selected / highlighted resources and one or few style layers. You only need to put selected resources to another data-source and draw them according selected style. That don't affective to common data sources, and don't need to recompute resources states, just draw selected resource above based resources.

How to control what markers are displayed by mapbox-gl-js

I am loading a bunch of geojson points. I can see that I am loading about 40 points but which ones get displayed on my map seems random and somehow connected to the zoom level. Below you can see that only 2 points of ~40 are displayed.
What criteria does mapbox-gl-js use to decide what to display?
Is there a way to control what points are being displayed? (All of them? Some based on an attribute?)
This is likely occurring because you are using the default text-allow-overlap value of false. The text-allow-overlap documentation reads
If true, the text will be visible even if it collides with other previously drawn symbols.
Because your symbols overlap each other, some are hidden. You can disable this behavior by setting text-allow-overlap to true.
You might find marker clustering to be useful.

Leaflet.js display of a non-geo map (gdal2tiles.py) – I need a concrete example

I'm displaying a map that's been tiled (-p raster) using gdal2tiles.py. The X-coordinate is about [0..-1160]. The Y-coordinate, for some reason, is [-700,0]. Zoom-levels 0-5.
I simply cannot get a plausible display to work. Sometimes, if I zoom-out to level-zero, I see the map way down at the bottom of the display ... not centered. Nothing at all appears at other levels.
I am also seeing the display "bounce back and forth" between about a 3-o'clock and a 6-o'clock position. (Only, once again, at zoom-level zero.)
I am at my wit's end. Please give guidance. Complete examples. Anything ...
Well, I found my answer:
If you're going to be using several layers in your Leaflet map, add them in the constructor-call, using the layers parameter.
If you try to do things with the layers before joining them all together, or with the map with no layers added, "strange and default things will happen." (For example, although I requested the Simple CRS when constructing things (separately...), the net-effect was to actually try to use a different one. Therefore, "do what the author expected." Specify all the layers at once, to the Map constructor. Then, customize them as you need to. Make very sure that they all know about each other from the very start of things.

Data structure for page layout like CSS floats

Suppose I have my own markup language that allows me to consume an array of TextElements and ImageElements. Each of these can have properties like "float: left/right/none" and "clear: none/left/right/both". Additionally, non-floated elements can flow around floated elements. Basically, all like CSS float layout.
For example:
Elem1 Elem2
Elem3
Elem4 Elem5 _Elem6
What's the best data structure to use to store these elements while I'm laying them out? I need something which makes it easy to answer questions like:
Is there enough space to fit Element2 left or right of Element1?
What's the page coordinates of Element1, origin and size?
I'll basically store a structure like:
{ Element, Origin(x, y), Size(w, h) }
for each already-laid-out element in this data structure.
There are things like RTrees, QuadTrees and such, but I want something simple to abstractly represent the layout of rectangles on a page for use in my layout algorithm.
NOTE: I am not doing this in HTML, it is for layout of elements in an iOS App, and I cannot use iOS 6 constraints since I need to support earlier iOS versions.
Thanks!
I believe that a binary heap could be made to work for what you want. Wikipedia explains binary heaps quite well.
The binary heap has two properties that make it nice for what you want:
It is a complete tree, which resembles structurally a laid-out page of elements.
The nodes are ordered such that each node is greater (or less, depending on which you want) than its children. In your case, "greater" means "placed further left and towards the top".
You have a list of elements that, in the absence of floats, would be laid out sequentially, wrapping lines as necessary. Thus, building a heap in the absence of floats would simply add nodes to the tree in the order they are received.
Floats complicate this, because they are placed higher than the nodes that preceded them (or lower than those that follow them in the case of right floats). Fortunately, building a heap allows for this by bubbling new nodes up to their proper place. So, as long as you can define a function that orders a floated element with respect to its peers, this can work.
It's that if that I'm not sure about, and unfortunately, I don't have enough time right now to explore the idea more completely.
Anyway, presuming you have a correct heap, repeatedly removing the topmost element should enumerate the nodes in the order they should be placed on the page.
I think CHDataStructures has a binary heap, but I can't verify that since the server where the documentation is kept seems to be offline at the time of posting.
Good luck and I hope this is helpful.

D3.js pie chart labels for slices not tweening

When I click on the various hyperlinks to tween my chart: while the pie's slices are tweening but I cannot figure out how to bring along each slice's label.
A mostly working JSfiddle is here: http://jsfiddle.net/lukateake/MX7JC/
Thanks in advance for any insights you can provide me. I promise to update the fiddle with whatever solution we discover as I imagine this effect is of interest to a great many D3'ers.
The main issue here is in your updateChart function - while you rebound the data to arcs, you did not do so for sliceLabel: (second line added)
arcs.data(donut(data.pct)); // recompute angles, rebind data
sliceLabel.data(donut(data.pct));
One other small thing - your slice label text selection seems a little bit strange:
var sliceLabel = label_group.selectAll("text.value")
but you are creating no text with class = "value"; this doesn't really end up affecting much, but might cause problems in other implementations - selectAll("text") or selectAll("text.arcLabel") might be more appropriate here.
updated fiddle at http://jsfiddle.net/MX7JC/9/