An IDLffShape object contains geometry, connectivity and attributes for graphics primitives within an ESRI Shapefile.
Methods
Overview of ESRI Shapefiles
An ESRI Shapefile stores nontopological geometry and attribute information for the spatial features in a data set.
A Shapefile consists of a main file (.shp), an index file (.shx), a dBASE table (.dbf), and possibly additional files such as a map projection. For example, the Shapefile “states” would have the following files:
- states.shp
- states.shx
- states.dbf
Major Elements of a Shapefile
A Shapefile consists of the following elements that you can access through the IDLffShape class:
Entities
The geometry for a feature is stored as a shape comprising a set of vector coordinates (referred to as ‘entities’). The (non-null) entities in a Shapefile must all be of the same type. The following are the possible types for entities in a Shapefile:
Shape Type |
Type Code |
Point |
1 |
PolyLine |
3 |
Polygon |
5 |
MultiPoint |
8 |
PointZ |
11 |
PolyLineZ |
13 |
PolygonZ |
15 |
MultiPointZ |
18 |
PointM |
21 |
PolyLineM |
23 |
PolygonM |
25 |
MultiPointM |
28 |
MultiPatch |
31 |
When retrieving entities using the IDLffShape::GetEntity method, an {IDL_SHAPE_ENTITY} structure is returned. This structure has the following fields:
Field |
Data Type |
Description |
SHAPE_TYPE |
Long integer |
The entity type.
|
ISHAPE |
Long integer |
A read-only field containing the index of the specific entity within the shape object. This value is set automatically when the shape file is written.
|
BOUNDS |
Eight-element, double-precision array
|
This eight element array contains the following information:
Index 0: X minimum value
Index 1: Y minimum value
Index 2: Z minimum value (if Z is supported by type)
Index 3: Measure minimum value (if measure is supported by entity type)
Index4: X maximum value
Index5: Y maximum value
Index6: Z maximum value (if Z is supported by the entity type)
Index7: Measure maximum value (if measure is supported by entity type)
If the entity is a point type, the values contained in the bounds array are also the values of the entity.
|
N_VERTICES |
Long integer |
The number of vertices in the entity. If this value is one and the entity is a POINT type (POINT, POINTM, POINTZ), the vertices pointer will be set to NULL and the entity value will be maintained in the BOUNDS field.
|
VERTICES |
Pointer to Vertices array
|
An IDL pointer that contains the vertices of the entity. This pointer contains a double array that has one of the following formats:
[2, N]: If Z data is not present
[3, N]: If Z data is present
where N is the number of vertices. These array formats can be passed to the polygon and polyline objects of IDL Object Graphics.
This pointer will be null if the entity is a point type, with the values maintained in the BOUNDS array.
|
MEASURE |
Pointer to Measure array
|
If the entity has a measure value (this is dependent on the entity type), this IDL pointer will contain a vector array of measure values. The length of this vector is N_VERTICES.
This pointer will be null if the entity is of type POINTM, with the values contained in the BOUNDS array.
|
N_PARTS |
Long integer |
If the values of the entity are separated into parts, the break points are enumerated in the parts array. This field lists the number of parts in this entity. If this value is 0, the entity is one part and the PARTS pointer will be NULL.
|
PARTS |
Pointer to Parts array
|
An IDL pointer that contains an array of indices into the vertex/measure arrays. These values represent the start of each part of the entity. The index range of each entity part is defined by the following:
Start = Parts[I]
End = Parts[I+1]-1 or the end of the array
|
PART_TYPES |
Pointer to part types
|
This IDL pointer is only valid for entities of type MultiPatch and defines the type of the particular part. If the entity type is not MultiPatch, part types are assumed to be type RING (SHPP_RING).
This pointer is NULL if the entity is not type MultiPatch.
|
ATTRIBUTES |
Pointer to Attribute array
|
If the attributes for an entity were requested, this field contains an IDL pointer that contains a structure of attributes for the entity. For more information on this structure, see Attributes.
|
Attributes
The Shapefile format provides the ability to associate information describing each entity within the file. These attributes consist of a set of named data elements. The set of attributes is the same for every entity in the Shapefile, with each entity having its own set of attribute values.
An attribute consist of two components:
The name consists of a 10 character string that is used to identify the data value. The data value is not limited to any specific format.
The two components that form an attribute are accessed differently using the shape class. To get the attribute names for a file, you can use the ATTRIBUTE_NAMES keyword to IDLffShape::GetProperty.
To get the attribute values, you can either call the IDLffShape::GetAttributes method or the use the ATTRIBUTES keyword on IDLffShape::GetEntity. The attribute values are returned as an anonymous IDL structure of the form:
{
ATTRIBUTE_0 : value,
ATTRIBUTE_1 : value,
ATTRIBUTE_2 : value,
...
}
Examples
Accessing Shapefiles
The following example shows how to access data in a Shapefile. This example sets up a map to display parts of a Shapefile, opens a Shapefile, reads the entities from the Shapefile, and then plots only the state of Colorado:
file = filepath('states.shp', subdir=['examples', 'data'])
myshape = IDLffShape(file)
myshape->GetProperty, ATTRIBUTE_NAMES=names, N_ENTITIES=num_ent
print, names
m = map('Orthographic', center_longitude=-120, center_latitude=30, $
fill_color='light blue')
m1 = mapcontinents(fill_color='light yellow')
for x=0l, (num_ent-1) do begin
attr = myshape->GetAttributes(x)
if (attr.attribute_1 eq 'Colorado') then begin
ent = myshape->GetEntity(x)
p = polygon(*ent.vertices, fill_color='green', /data)
endif
endfor
myshape = 0
IDL prints:
AREA STATE_NAME STATE_FIPS SUB_REGION STATE_ABBR POP1990 POP1996
Creating New Shapefiles
To create a Shapefile, you need to create a new Shapefile object, define the entity and attributes definitions, and then add your data to the file. For example, the following program creates a new Shapefile (cities.shp), defines the entity type to be “Point”, defines 2 attributes (CITY and STATE), and then adds an entity to the new file:
mynewshape = IDLffShape('cities.shp', ENTITY_TYPE=1)
mynewshape->AddAttribute, 'CITY', 7, 25
mynewshape->AddAttribute, 'STATE', 7, 25
entNew = {IDL_SHAPE_ENTITY}
entNew.SHAPE_TYPE = 1
entNew.BOUNDS = [-104.87270, 39.768040, 0, 0, -104.87270, 39.768040, 0, 0]
mynewshape->PutEntity, entNew
attrNew = {attribute_0: 'Denver', attribute_1: 'Colorado'}
mynewshape->SetAttributes, 0, attrNew
mynewshape = 0
Updating Existing Shapefiles
You can modify existing Shapefiles with the following:
- Adding new entities and attribute values
- Modifying existing attributes
Note: You cannot modify existing entities.
For example, the following program adds an entity and attributes for the city of Boulder to the cities.shp file created in the previous example:
myshape = IDLffShape('cities.shp', /update)
entNew = {IDL_SHAPE_ENTITY}
entNew.SHAPE_TYPE = 1
entNew.BOUNDS = [-105.25100, 40.026878, 0, 0, -105.25100, 40.026878, 0, 0]
myshape->PutEntity, entNew
attrNew = {attribute_0: 'Boulder', attribute_1: 'Colorado'}
myshape->GetProperty, N_ENTITIES=num_entities
myshape->SetAttributes, num_entities - 1, attrNew
myshape = 0
Graphing our Updated Shapefile
The following program graphs the cities.shp file that was created and updated in the previous examples:
m = map('Orthographic', limit = [35, -110, 42, -101], fill_color='light blue')
m.mapgrid.hide = 1
m1 = mapcontinents(fill_color='light yellow', /usa)
file = filepath('states.shp', subdir=['examples', 'data'])
myshape = IDLffShape(file)
myshape->GetProperty, N_ENTITIES=num_ent
ent = myshape->GetEntity(30)
p = polygon(*ent.vertices, fill_color='green', /data)
m1 = mapcontinents(color='blue', thick=2, /rivers, /hires)
myshape = 0
myshape = IDLffShape('cities.shp')
myshape->GetProperty, N_ENTITIES=num_ent
for x=0, (num_ent-1) do begin
ent = myshape->GetEntity(x)
attr = myshape->GetAttributes(x)
sym = SYMBOL( ent.bounds[0], ent.bounds[1], 'star', /data, $
/sym_filled, sym_color='red', sym_size = 2.5, label_font_size=14, $
label_string=attr.attribute_0)
endfor
myshape = 0
IDLffShape
The IDLffShape function method initializes a Shapefile object and creates a new Shapefile file or opens an existing file.
Syntax
Result = IDLffShape([, Filename] [, DBF_ONLY=value] [, ENTITY_TYPE=value] [, /UPDATE])
Return Value
An object reference to the newly-created object.
Arguments
Filename
A scalar string containing the full path and filename of a Shapefile (.shp) to open. If this file exists, it is opened. If the file does not exist, a new Shapefile object is constructed. You do not need to use IDLffShape::Open to open an existing file when specifying this argument.
Note: The .shp, .shx, and .dbx files must exist in the same directory for you to be able to open and access the file unless the UPDATE keyword is set.
Note: The value specified by the Filename argument is used to initialize the value of the FILENAME property of the IDLffShape object.
Keywords
DBF_ONLY
A non-zero, positive integer value indicating whether the underlying dBASE table (.dbf) component of the shapefile is opened while all other entity related files are left closed. The following two values are accepted for this property:
- 1 - Open an existing .dbf file,
- Greater than 1 - Create a new .dbf file
Note: The UPDATE keyword is required to open the .dbf file for updating.
ENTITY_TYPE
Set this property to an integer representing the entity type for a new Shapefile. Use this setting only when creating a new Shapefile. See the Entities table above for possible values.
UPDATE
Set this keyword to open an existing file for both reading and writing. The default is read-only. If the file does not exist then this keyword is ignored and a new file is created and opened for writing.
IDLffShape::AddAttribute
The IDLffShape::AddAttribute method creates an attribute definition for a Shapefile. You must call AddAttribute before setting the actual attribute data. For more information on attributes, see Attributes.
Note: You can only define new attributes for Shapefiles that do not have any existing values in any attributes.
Syntax
Obj.AddAttribute, Name[, Type, Width ] [, /DATE] [, /LOGICAL] [, PRECISION=integer]
Arguments
Name
Set to a string that contains the attribute name. Name values are limited to 10 characters. Names longer than 10 characters will be truncated.
Type
Set to the IDL type code that corresponds to the data type that will be stored in the attribute. The valid types are:
Code |
Type |
3 |
Longword Integer
|
5 |
Double-precision floating point
|
7 |
String |
This argument is ignored if the DATE or LOGICAL keyword is set.
Width
Set to an integer giving the width in characters for the data value. The possible values are:
Type |
Definition |
Integer |
The number of digits of the largest number. Note: Since the values are returned as 32-bit integers, the largest useable values are –2147483648 and 2147483647, which gives a maximum width of 11. If you anticipate using integers outside of this range you should store them as type Double instead.
|
Double |
The total number of digits, including the decimal point and the number of positions after the decimal point (see the PRECISION keyword).
|
String |
The maximum length of the string that can be stored. Strings longer than this will be truncated.
|
This argument is ignored if the DATE or LOGICAL keyword is set.
Note: You should ensure that the Width and PRECISION are large enough to store your largest value. Attribute values that are larger than the width will be quietly truncated.
Keywords
DATE
Set this keyword to create an attribute with type "date". Inside the shapefile, date values are stored as integers of length 8, and should have the form YYYYMMDD (for example: 20240924). If this keyword is set then the Type and Width arguments are ignored.
Note: When writing attribute values with SetAttributes, you should only use numbers of the form YYYYMMDD. Incorrect numbers will still be stored (up to 8 characters) but may be misinterpreted by applications that try to read the attributes.
LOGICAL
Set this keyword to create an attribute with type "logical". Inside the shapefile, logical values are stored as single characters with the value "T" (true) or "F" (false). If this keyword is set then the Type and Width arguments are ignored.
Note: When writing attribute values with SetAttributes, you should only use the strings "T" or "F". Other values will be ignored and set to missing. When reading logical values, if a logical value is missing, it will be returned as a "?" character.
PRECISION
Set this keyword to the number of positions to be included after the decimal point. The default is 8. This keyword is only valid for double-precision fields, and is ignored for other types.
IDLffShape::Cleanup
The IDLffShape::Cleanup procedure method performs all cleanup on a Shapefile object. If the Shapefile being accessed by the object is open and the file has been modified, the new information is written to the file if one of the following conditions is met:
- The file was opened with write permissions using the UPDATE keyword to the IDLffShape::Open method
- It is a newly created file that has not been written previously.
Tip: Instead of calling Obj_Destroy, you can also delete the last reference to the object. IDL's automatic garbage collection will then automatically call cleanup and close the file.
Syntax
Obj.Cleanup
or
OBJ_DESTROY, Obj
Arguments
None
Keywords
None
IDLffShape::Close
The IDLffShape::Close procedure method closes a Shapefile. If the file has been modified, it is also written to the disk if it is a newly-create file, or if the file was opened with write permissions using the UPDATE keyword.
If the file was not opened with write permissions (UPDATE=0), then the file is closed and any changes are discarded.
Tip: In most cases you do not need to directly call the Close method. Destroying the Shapefile object (either with Obj_Destroy or through garbage collection) will automatically call the Close method.
Syntax
Obj.Close
Arguments
None
Keywords
None
IDLffShape::GetAttributes
The IDLffShape::GetAttributes function method retrieves the attribute values (or the attribute structure) from a Shapefile.
Syntax
Result = Obj.GetAttributes([Index] [, /ALL] [, /ATTRIBUTE_STRUCTURE] )
Return Value
Returns an anonymous structure array. For more information on the structure, see Attributes.
Arguments
Index
A scalar or array of longs specifying the entities for which you want to retrieve the attributes, with 0 being the first entity in the Shapefile.
Note: If you do not specify Index and the ALL keyword is not set, the attributes for the first entity (0) are returned.
Keywords
ALL
Set this keyword to return an array of anonymous structures containing the attributes for all entities. If set, the Index argument is ignored.
ATTRIBUTE_STRUCTURE
Set this keyword to return an empty attribute structure that can then be filled in and passed to IDLffShape::SetAttributes.
IDLffShape::GetEntity
The IDLffShape::GetEntity function method returns the entities you specify from a Shapefile.
Syntax
Result = Obj.GetEntity([Index] [, /ALL] [, /ATTRIBUTES])
Return Value
Returns one or more {IDL_SHAPE_ENTITY} structures. For more information on the structure, see Entities.
Note: Since entities cannot be modified in a Shapefile, an entity is read directly from the Shapefile each time you use the IDLffShape::GetEntity method even if you have already read that entity. Modifying the data within the returned structure has no effect on the file.
Arguments
Index
A scalar or array of integers specifying the entities to retrieve (the first entity is 0). If the ALL keyword is set, this argument is ignored. If you do not specify any entities and /ALL is not set, the first entity (0) is returned.
Keywords
ALL
Set this keyword to retrieve all entities. If this keyword is set, the Index argument is ignored.
ATTRIBUTES
Set this keyword to include the attribute values within the entity structure. If not set, the ATTRIBUTES tag in the entity structure will be a null pointer.
IDLffShape::GetProperty
The IDLffShape::GetProperty method returns the Shapefile object property values.
Syntax
Obj.GetProperty [, PROPERTY=variable]
Arguments
None
Keywords
ATTRIBUTE_INFO
A array of IDL_SHAPE_ATTRIBUTE structures containing the attribute information for each attribute. The structures have the following fields:
Field |
Description |
NAME |
A string that contains the attribute name
|
TYPE |
The IDL type code, either 3 (Long Integer), 5 (Double), or 7 (String)
|
WIDTH |
The width of the attribute in characters
|
PRECISION |
The precision of the attribute (only valid for Double)
|
The file must be open to obtain this information.
Note: The TYPE field is the IDL type code. Attributes with Shapefile type String or Logical will both be IDL type string (7); attributes with Shapefile type Integer or Date will both be IDL type long integer (3). To retrieve the Shapefile types use the ATTRIBUTES_TYPES property.
ATTRIBUTE_NAMES
A string array containing the names of each attribute.
ATTRIBUTE_TYPES
An integer array containing the Shapefile types of each attribute. Possible values are:
Value |
Attribute Type |
0 |
String |
1 |
Integer number |
2 |
Double-precision number
|
3 |
Logical |
4 |
Date |
Note: These are the internal Shapefile types, not the IDL type code. Since type Logical is returned as IDL type string, while Date is returned as IDL type long integer, you should always use the ATTRIBUTE_TYPES property to get the actual type.
ENTITY_TYPE
If retrieving this property, its value is an integer representing the type code for the entities contained in the Shapefile object. If the value is unknown, this method returns -1. For more information on entity type codes, see Entities.
If setting this property, its value is an integer representing the entity type of a new Shapefile. Use this setting only when creating a new Shapefile. For more information on entity types, see Entities.
FILENAME
A string representing the fully qualified path name of the Shapefile in the current Shapefile object.
Note: FILENAME can only be set via an argument to IDLffShape.
IS_OPEN
An integer value representing information about the status of a Shapefile. The following values can be returned:
0 |
File is not open
|
1 |
File is open in read-only mode
|
3 |
File is open in update mode
|
N_ATTRIBUTES
A longword integer representing the number of attributes associated with a Shapefile object. If the number of attributes is unknown, this property returns 0.
N_ENTITIES
A longword integer representing the number of entities contained in Shapefile object. If the number of entities is unknown, this property returns 0.
N_RECORDS
A longword integer representing the number of records in the dBASE table (.dbf) component of the Shapefile. In a normal operating mode, this process is accomplished by getting the number of entities. However, in DBF_ONLY mode, no entity file exits.
UPDATE
A Boolean value indicating whether the file opened for writing. The file is opened for writing if this property is set to true. The default is read-only.
IDLffShape::Open
The IDLffShape::Open function method opens a specified Shapefile.
Tip: In almost all cases you should not need to call the Open method. Instead, you should simply call the IDLffShape function with the appropriate arguments and keywords.
Syntax
Result = Obj.Open( ‘Filename’ [, /DBF_ONLY] [, ENTITY_TYPE=’value’] [, /UPDATE] )
Return Value
Returns 1 if the file can be read successfully. If not able to open the file, it returns 0.
Arguments
See IDLffShape for allowed arguments.
Keywords
See IDLffShape for allowed keywords.
IDLffShape::PutEntity
The IDLffShape::PutEntity procedure method inserts an entity into the Shapefile. The entity must be in the proper structure. For more information on the structure, see Entities.
Note: The shape type of the new entity must be the same as the type defined for the Shapefile. If the shape type was never defined (for example by setting ENTITY_TYPE on creation), the first call to PutEntity will automatically set the shape type from the entity data.
Note: Only new entities can be inserted into a Shapefile. Existing entities cannot be updated.
Syntax
Obj.PutEntity, Data
Arguments
Data
A scalar or an array of {IDL_SHAPE_ENTITY} structures. Entities are always added at the end, with no gaps.
Keywords
None
IDLffShape::SetAttributes
The IDLffShape::SetAttributes method sets the attribute values for a specified entity or entities.
Syntax
Obj.SetAttributes, EntityIndex, AttributeNum, Value
or
Obj.SetAttributes, EntityIndex, AttributeStruct
Arguments
EntityIndex
A scalar or array of integers specifying the entity (or entities) for which you want to set the attributes. If Index is a scalar, then it specifies the starting entity at which to start writing the attributes as given by the Value or AttributeStruct. If Index is an array with the same number of elements as Value or AttributeStruct, then Index specifies the entity indices.
Note: When writing new attributes, the attributes must be written in order for the entities, starting at entity 0, with no gaps. When overwriting existing attributes, the attributes may be written in any order of the entities.
AttributeNum
A scalar integer giving the attribute number of the value that you want to set. This value should be in the range 0 to N–1, where N is the number of attributes for this shapefile.
Value
If AttributeNum is present, then Value is the value (or array of values) of the field within the attribute. If the value is not of the correct type for that attribute, the type conversion is attempted.
Tip: Using AttributeNum and Value, all the values for a particular attribute can be set for a list of entities.
AttributeStruct
A structure (or array of structures) whose fields match the fields in the attribute table. If AttributeStruct is an array, the entities specified in Index, up to the size of AttributeStruct, are set.
The type of this Attribute structure must match the type that is generated internally for Attribute table. To get a copy of this structure, either get the attribute set for an entity or get the definition using the ATTRIBUTE_STRUCTURE keyword of the IDLffShape::GetAttributes method.
Tip: Using AttributeStruct, all the attribute values for a list of entities can be set.
Keywords
None
Version History
5.4 |
Introduced |
5.6 |
Added N_RECORDS, DBF_ONLY properties
|
9.1 |
Added support for DATE and LOGICAL attribute types; added ATTRIBUTE_TYPES property; removed docs for DestroyEntity (not needed with garbage collection).
|