Select Shapefile Data to Read
The shaperead function provides you with a
powerful method, called a selector, to select only the data fields
and items you want to import from shapefiles.
A selector is a cell array with two or more elements. The first element is a handle to
a predicate function (a function with a single output argument of type
logical). Each remaining element is a character vector indicating
the name of an attribute.
For a given feature, shaperead supplies the values of the
attributes listed to the predicate function to help determine whether to include the
feature in its output. The feature is excluded if the predicate returns
false. The converse is not necessarily true: a feature for which
the predicate returns true may be excluded for other reasons when the
selector is used in combination with the bounding box or record number options.
The following examples are arranged in order of increasing sophistication. Although
they use MATLAB® function handles, anonymous functions, and nested functions, you do not
need to be familiar with these features to use the selectors for
shaperead.
Example 1: Predicate Function in Separate File
Define the predicate function in a separate file. (Prior to Release 14, this was the only option available.) Create a file named
roadfilter.m, with the following contents:function result = roadfilter(roadclass,roadlength) mininumClass = 4; minimumLength = 200; result = (roadclass >= mininumClass) && ... (roadlength >= minimumLength); endYou can then call
shapereadlike this:roadselector = {@roadfilter, 'CLASS', 'LENGTH'} roadselector = @roadfilter 'CLASS' 'LENGTH' s = shaperead('concord_roads.shp', 'Selector', roadselector) s = 115x1 struct array with fields: Geometry BoundingBox X Y STREETNAME RT_NUMBER CLASS ADMIN_TYPE LENGTHor, in a slightly more compact fashion, like this:
s = shaperead('concord_roads.shp',... 'Selector', {@roadfilter, 'CLASS', 'LENGTH'}) s = 115x1 struct array with fields: Geometry BoundingBox X Y STREETNAME RT_NUMBER CLASS ADMIN_TYPE LENGTHPrior to Version 7 of the Mapping Toolbox™ software, putting the selector in a file or local function of its own was the only way to work with a selector.
Note that if the call to
shapereadtook place within a function, thenroadfiltercould be defined in a local function thereof rather than in a file of its own.
Example 2: Predicate as Function Handle
As a simple variation on the previous example, you could assign a function handle,
roadfilterfcn, and use it in the selector:
roadfilterfcn = @roadfilter
s = shaperead('concord_roads.shp',...
'Selector', {roadfilterfcn, 'CLASS', 'LENGTH'})
roadfilterfcn =
@roadfilter
s =
115x1 struct array with fields:
Geometry
BoundingBox
X
Y
STREETNAME
RT_NUMBER
CLASS
ADMIN_TYPE
LENGTHExample 3: Predicate as Anonymous Function
Having to define predicate functions in files of their own, or even as local functions, may sometimes be awkward. Anonymous functions allow the predicate function to be defined right where it is needed. For example:
roadfilterfcn = ...
@(roadclass, roadlength) (roadclass >= 4) && ...
(roadlength >= 200)
roadfilterfcn =
@(roadclass, roadlength) (roadclass >= 4) ...
&& (roadlength >= 200)
s = shaperead('concord_roads.shp','Selector', ...
{roadfilterfcn, 'CLASS', 'LENGTH'})
s =
115x1 struct array with fields:
Geometry
BoundingBox
X
Y
STREETNAME
RT_NUMBER
CLASS
ADMIN_TYPE
LENGTHExample 4: Predicate (Anonymous Function) Defined Within Cell Array
There is actually no need to introduce a function handle variable when defining the predicate as an anonymous function. Instead, you can place the whole expression within the selector cell array itself, resulting in somewhat more compact code. This pattern is used in many examples throughout the Mapping Toolbox documentation and function help.
s = shaperead('concord_roads.shp', 'Selector', ...
{@(roadclass, roadlength)...
(roadclass >= 4) && (roadlength >= 200),...
'CLASS', 'LENGTH'})
s =
115x1 struct array with fields:
Geometry
BoundingBox
X
Y
STREETNAME
RT_NUMBER
CLASS
ADMIN_TYPE
LENGTHExample 5: Parametrizing the Selector; Predicate as Nested Function
In the previous patterns, the predicate involves two hard-coded parameters (called
minimumClass and minimumLength in
roadfilter.m), as well as the roadclass
and roadlength input variables. If you use any of these patterns
in a program, you need to decide on minimum cut-off values for
roadclass and roadlength at the time you
write the program. But suppose that you wanted to wait and decide on parameters like
minimumClass and minimumLength at run
time?
Fortunately, nested functions provide the additional power that you need to do
this; they allow you to utilize workspace variables in as parameters, rather than
requiring that the parameters be hard-coded as constants within the predicate
function. In the following example, the workspace variables
minimumClass and minimumLength could have
been assigned through a variety of computations whose results were unknown until
run-time, yet their values can be made available within the predicate as long as it
is defined as a nested function. In this example the nested function is wrapped in a
file called constructroadselector.m, which returns a complete
selector: a handle to the predicate (named nestedroadfilter) and
the two attribute names:
function roadselector = ...
constructroadselector(minimumClass, minimumLength)
roadselector = {@nestedroadfilter, 'CLASS', 'LENGTH'};
function result = nestedroadfilter(roadclass, roadlength)
result = (roadclass >= minimumClass) && ...
(roadlength >= minimumLength);
end
endThe following four lines show how to use constructroadselector:
minimumClass = 4; % Could be run-time dependent
minimumLength = 200; % Could be run-time dependent
roadselector = constructroadselector(...
minimumClass, minimumLength);
s = shaperead('concord_roads.shp', 'Selector', roadselector)
s =
115x1 struct array with fields:
Geometry
BoundingBox
X
Y
STREETNAME
RT_NUMBER
CLASS
ADMIN_TYPE
LENGTH