The polygon footprint data in the ISIS cube file hirise40.cal.map.cub is stored as ASCII text in WKT (Well-Known Text) format, not as binary data.
The example cube file hirise40.cal.map.cub was created from the following HiRISE data processing pipeline:
- Source Data:
ESP_039983_1390_RED4_0.IMG(raw HiRISE image data) - Import to ISIS: Used
hi2isisto convert the IMG file to ISIS cube format - Calibration: Applied radiometric calibration using
hical - Map Projection: Applied default map projection using
cam2map - Footprint Generation: Generated the spatial footprint using
footprintinit
The resulting cube file (hirise40.cal.map.cub) contains the calibrated, map-projected image data along with the polygon footprint stored in the PVL label and as attached binary data.
The polygon footprint location is stored in the PVL (Planetary Data System Label) header of the .cub file. The extraction script automatically parses the PVL label to find:
- Object Name: Polygon
- Name: Footprint
- StartByte: Location in the file (parsed from PVL)
- Bytes: Size of the footprint data (parsed from PVL)
Indexing Note: PVL uses 1-based indexing (first byte is position 1), while Python's f.seek() uses 0-based indexing (first byte is position 0). The script automatically converts PVL StartByte values to 0-based by subtracting 1 before using f.seek().
The polygon data is stored as a plain ASCII text string in WKT (Well-Known Text) format:
MULTIPOLYGON (((30.107598435886608 -40.35696177712009, 30.108625875765043 -40.356868167155994, ...)))
WKT Format Notes:
MULTIPOLYGONis a valid WKT geometry type (OGC standard) used to represent collections of polygons- This particular footprint is stored as a MULTIPOLYGON containing a single polygon, which is valid WKT
- The structure has three levels of parentheses: outer (MULTIPOLYGON), middle (polygon), inner (coordinate ring)
Indexing Conversion: When PVL reports StartByte = 225143647, this means the 225143647th byte (1-based). To read from Python using f.seek(), we convert to 0-based indexing: f.seek(225143647 - 1), which correctly positions us at the start of the MULTIPOLYGON string.
- Coordinates are stored as longitude latitude pairs (not latitude longitude)
- Each coordinate pair is separated by commas
- Coordinates are floating-point numbers with high precision (~15 decimal places)
- The polygon is closed (first and last coordinates are identical)
- Total coordinate pairs: 420
- Coordinate range:
- Longitude: ~30.107° to ~30.138° (East)
- Latitude: ~-40.357° to ~-40.526° (South)
- Projection: Sinusoidal (based on cube file metadata)
The polygon can be extracted and converted to either GML (Geography Markup Language) or GeoPackage format using the extract_isis_footprint.py script. The script uses geopandas exporters for both formats, ensuring compatibility with GIS software.
The GML format is created using geopandas.GeoDataFrame.to_file() with driver="GML":
- GML 3.2 namespace
- Proper geometry encoding for Polygon/MultiPolygon
- Coordinates stored as space-separated "lon lat" pairs
- Compatible with OGC GML standards
The GeoPackage format is created using geopandas.GeoDataFrame.to_file() with driver="GPKG":
- SQLite-based format (OGC GeoPackage standard)
- Single polygon feature in a named layer (default: "footprint")
- Configurable CRS (default: EPSG:4326)
- Compatible with QGIS, ArcGIS, and other GIS software
The script automatically parses the PVL label to find the footprint location - no manual byte offsets needed:
# Extract to GML (default) - automatically finds footprint location
python3 extract_isis_footprint.py --format gml
# Extract to GeoPackage - automatically finds footprint location
python3 extract_isis_footprint.py --format gpkg
# Extract to both formats
python3 extract_isis_footprint.py --format both
# Custom options
python3 extract_isis_footprint.py --format gpkg --output my_footprint.gpkg \
--layer-name "hirise_footprint" --crs "EPSG:4326"
# Override PVL parsing with manual byte offsets (if needed)
python3 extract_isis_footprint.py --format gml --start-byte 225143647 --num-bytes 16318Required Libraries: The script requires pvl, geopandas, and shapely. Install with:
pip install pvl geopandas shapelyThe extraction process works as follows:
- Parse PVL Label: The script reads the PVL label from the beginning of the
.cubfile using thepvllibrary - Find Footprint Location: Searches for an object with
Object = PolygonandName = Footprintto extractStartByteandBytesvalues- Uses direct search through
label.get("Object", [])first - Falls back to recursive search through the entire PVL structure if needed
- Uses direct search through
- Convert Indexing: Converts PVL 1-based
StartByteto Python 0-based indexing by subtracting 1 - Read WKT Data: Seeks to the calculated position and reads the specified number of bytes
- Parse WKT: Uses
shapely.wkt.loads()to parse the WKT text into geometric objects- Handles both
POLYGONandMULTIPOLYGONformats - Extracts all polygons if MULTIPOLYGON contains multiple polygons
- Handles both
- Export: Uses
geopandas.GeoDataFrame.to_file()to export to GML or GeoPackage format- GML:
gdf.to_file(output_file, driver="GML") - GeoPackage:
gdf.to_file(output_file, driver="GPKG", layer=layer_name)
- GML:
Key Implementation Details:
- PVL parsing handles different label structures (dict, list, nested objects)
- Recursive search ensures footprint is found even in complex PVL hierarchies
- Indexing conversion is automatic and transparent to the user
- WKT parsing uses Shapely for robustness and standards compliance
- Export uses geopandas exporters for compatibility and maintainability