mapbox gl setFilter by feature property that is an array - mapbox

I have a feature property that is an array of ids:
feature.properties.ownerTypeIds: [1,2,3]
I have a form. In it it has a multi-select for Owner Types that produces an array: [1,2]
What is the mapbox gl latest version expression to compare a feature's array to an array of values? Match doesn't appear to support a feature property that is an array.
If ANY id in the feature's array is also in the selected choices array, I want it set to true. So that when it gets combined with many other filters inside an "all", it will work. The all works with many other filters, I just need help with the ownerTypeIds array scenario presented here.
Any value the user selects, is it inside the feature's ownerTypeIds array?
I'd appreciate any help. The mapbox expressions documentation doesn't appear to support feature properties that are an array. I hope I'm wrong in that assessment!
Appreciate you!
Thanks,
Donnie

From mapbox support ...
Hi Donnie,
Thanks for contacting Mapbox Support.
You are correct; only simple types are supported in Feature's properties.
With that said, you cannot compare the two lists at runtime using the style spec.
For your information, there is a publicly tracked issue here.
https://github.com/mapbox/mapbox-gl-js/issues/2434
One workaround would be to create a new property that computes whether an element in one array also exists in another array and sets a true/false value.
Then that boolean value can be used to compare in your filters.
Let me know if you still have any questions
Regards,

Related

mapbox gl setFilter filter by indexOf, contains, or substring

I want to use setFilter expression to filter by substring for a given feature property inside a tileset. Note: I do NOT want to have to load an array of features external to the tileset, I want it to use setFilter only, not getFeatures functions and no looping. If user begins typing, "smith .." it would filter out features as they typed using setFilter only.
I only see "==" or "match" but neither do case insensitive substring filtering, such as indexOf, contains, Like, etc. Something like ['contains', feature.prop, 'smi'] then ['contains', feature.prop, 'smith'], for example.
I see the example on mapbox examples, for filtering as you type, but I want to only use setFilter. It doesn't look like it supports what I want to do, but I thought I'd ask anyway. It is a waste of client-side resources to have to populate any local array of features from the tileset. It defeats the purpose of putting the data inside a tileset to begin with.
Any standard expression for parsing a feature property by a partial string, not an exact match?
As you have noticed, Mapbox-GL expressions don't support substrings or regexes. So I think the only workaround is along the lines you mentioned: getting a list of attribute values and using that as an autocomplete.
There are two ways to get that list of attribute values that don't require making separate, arguably redundant, queries.
Use the values within the TileJSON. Depending how the TileJSON is generated, it often contains a list of the most common values for each attribute (up to 1000 or so, I think).
Use querySourceFeatures() to fetch all features within the current viewport, then filter down to find the values of the attribute you care about. This won't help if the user wants to filter towards something which is currently outside the viewport.
Now mapbox support to filter for tyle layer for sub string from string
expression code is
['in', {filter-substring-value}, ['string', ['get', {mapbox-property-field-string}]]]

scala for mapbox vector tiles - getting an 'id' field into the Features written to vector tiles

I'm writing MapBox vector tiles using geotrellis vectorpipe.
see here for the basic flow: https://geotrellis.github.io/vectorpipe/usage.html
Typically GeoJson Features can have an id field, so that Features can be rolled up into FeatureCollections. I need to make use of this field, but vectorpipe doesn't (natively) have this capability.
This is the Feature type used, and you can see it only has space for 1) a Geometry and 2) a data object D (which ends up populating properties in the output). There is no spot for an id.
https://geotrellis.github.io/scaladocs/latest/index.html#geotrellis.vector.Feature
Upstream there's a method called writeFeatureJsonWithID() that does let you inject an id field into a Feature when writing GeoJson.
https://github.com/locationtech/geotrellis/blob/master/vector/src/main/scala/geotrellis/vector/io/json/FeatureFormats.scala#L41-L49
My question is this:
I have worked through the vectorpipe code (https://github.com/geotrellis/vectorpipe), and I can't figure out if/where the data ever exists as GeoJson in a way where I can override and inject the id, maybe using the writeFeatureJsonWithID() or something I write explicitly. A lot of conversions are implicit, but it also may never explicitly sit as json.
Any ideas for how to get an id field in the final GeoJson written to vector tiles?
EDIT
Right now I think the trick is going to be finding a way to override .unfeature() method here:
https://github.com/locationtech/geotrellis/blob/master/vectortile/src/main/scala/geotrellis/vectortile/Layer.scala
The problem is that the internal.vector_tile.Tile is private, so I can construct it without forking the project.
Ended up having to fork geotrellis, hard-code a metadata => id function in Layer.unfeature() and compile locally to include in my project. Not ideal, but it works fine.
Also opened an issue here: https://github.com/locationtech/geotrellis/issues/2884

Most efficient way to change the value of a specific tag in a DICOM file using GDCM

I have a need to go through a set of DICOM files and modify certain tags to be current with the data maintained in the database of an external system. I am looking to use GDCM. I am new to GDCM. A search through stack overflow posts demonstrates that the anonymizer class can be used to change tag values.
Generating a simple CT DICOM image using GDCM
My question is if this is the best use of the GDCM API or if there is a better approach for changing the values of individual tags such as patient name or accession number. I am unfamiliar with all of the API options but have a link to the API documentation. It looks like the DataElement SetValue member could be used, but it doesn't appear that there is a valid constructor for doing this in the Value class. Any assistance would appreciated. This is my current approach:
Anonymizer anon = new Anonymizer();
anon.SetFile(myFile);
anon.Replace(new Tag(0x0010, 0x0010), "BUGS^BUNNY");
Quite late, but maybe it would be still useful. You have not mention if you write in C++ or C#, but I assume the latter, as you do not use pointers. Generally, your approach is correct (unless you use System.IO.File instead of gdcm.File). The value (second parameter of Replace function) has to be a plain string so no special constructor is needed. You should probably start with doxygen documentation of gdcm, and there is especially one complete example. It is in C++, but there should be no problems with translation.
There are two different ways to pad dicom tags:
Anonymizer
gdcm::Anonymizer anon;
anon.SetFile(file);
anon.Replace(gdcm::Tag(0x0002, 0x0013), "Implementation Version Name");
//Implementation Version Name
DatsElement
gdcm::Attribute<0x0018, 0x0088> ss;
ss.SetValue(10.0);
ds.Insert(ss.GetAsDataElement());

Simulink & Masks: Dynamic access to parameters "evaluate" and "tunable"

First of all, matlab version is 2011b, so I cannot use Simulink.MaskParameters class.
I have one simulink mask and some parameters inside. I need to determine in my function for each parameter if it is "evaluable" or "tunable".
Those two things are two checkboxes in the mask parameters dialog which you can select for any parameter.
For "tunable", there's the MaskTunableValues property. For "enable", there's the "MaskEnables" property.
Do you know if there's a way to programmatically access the same property but for "evaluate" ?
Thanks
#Phil Goddard's answer shows you how to find the parameter. To complete the answer, the actual parameter is MaskVariables. Evaluate flag is embedded into the MaskVariables string. It is not straightforward to modify this. For example for two parameters MaskVariables string contains something like this:
"a=#1;b=&2;"
In this string the # sign indicates evaluation. Based on that, parameter a is evaluated and parameter b is not. If you want to change the evaluate flag, you need to set this string for MaskVariables parameter exactly how it was except for # or & signs.
For more information see R2011b documentation for mask parameters at https://www.mathworks.com/help/releases/R2011b/toolbox/simulink/slref/f23-18517.html. Towards the bottom of the page there is more detail about MaskVariables parameter.
You're using too old a release for most people to be able to give you an exact solution, however, I'm sure (from memory) that this parameter is available.
If you click on the mask to select the block, then go to the MATLAB command line and type
get_param(gcb,'ObjectParameters')
you'll get a list of all the block properties. (You may already know that since you're aware of MaskTunableValues and MaskEnables.) Near the bottom of that list are all of the properties related to the mask.
Now manually look at each/all of those properties, e.g.
get_param(gcb,'MaskTunableValues')
and you'll find that one of them is a structure that contains the information that you're looking for. (You may need to dig down into the structure to find the specific info.)
Answer for versions > 2011b (tested on 2014b):
Ok found it, actually the matlab documentation is REALLY unclear regarding the Simulink.MaskParameter class and here is how it works:
First, get the Mask class from your block:
mask = Simulink.Mask.get(gcb)
The Mask class is a structure containing all mask parameters:
parameters = mask.Parameters(:)
parameters is a (array of) Simulink.MaskParameter object which will contains all the necessary properties, including Evaluate.

Kendo MVVM: How to bind a function to a Template inside a Template?

I prepared a simple dojo here: http://dojo.telerik.com/iQERE
Scenario:
I have an array within another array and I wanted to render it with a kendo template in a sort of table/grid.
First array's items are the rows and inner array's items are the columns.
I googled and found this technique: template inside template
The problems are:
1) How can I bind values for the nested array's items?
I tried data-bind="value:subval" but it doesn't work.
I think because using that technique the 'real data' of this template is the outer array, not the inner one!
Tried data-bind="value: item.subval" - leaded to nothing.
So finally I tried data-bind="value: subList[#:index#].subval" and it works. But I ask myself: Is this correct?
2) How can I bind the value to a function in the nested template? (famous kendo mvvm calculated fields).
I hoped I could bind all the input to a unique function who takes the 'caller' value and do something (multiply for another model field for example).
But I can't get rid who called the function... my "e" argument is the whole data!!
After some experiments I tried this way: http://dojo.telerik.com/OpOja and first time works... but it seems the function doesn't trigger when the value1 of the model change (wich I would expect in a normal mvvm behavior), maybe because I declared the function inside the dataSource. (it's not an observable object itself?)
I hope I explained well my problem!
Well.. It seems is not possible. Response from a Telerik ticket:
I am afraid, that the Kendo MVVM framework would not allow you to achieve the desired two-way binding for in the discussed scenario. The reason for that is the fact, that in the ​$.each() in the template would be executed only once and will not be reevaluated in the viewModel changes.
In addition, in case you need to configure a hierarchical DataSource for an MVVM model, I would suggest you to follow this example. You will notice, that similarly to your implementation, it includes a field which is calculated as a function from another field. It however, will not allow you the desired two-way binding too. So the update of the value1 field would not trigger again the above mentioned function.