shapekit 0.3.2
shapekit: ^0.3.2 copied to clipboard
Read and write ESRI Shapefiles and GeoPackage feature data in Dart, with streaming, typed geometries, and DBF attribute support.
shapekit #
A comprehensive Dart library for reading and writing ESRI Shapefiles, with GeoPackage support for feature data workflows.
Features #
- ✅ Complete Shapefile Support - Read and write
.shp,.shx,.dbf, and.prjfiles - ✅ 12 Geometry Types - Point, PointM, PointZ, Polyline, PolylineM, PolylineZ, Polygon, PolygonM, PolygonZ, MultiPoint, MultiPointM, MultiPointZ
- ✅ GeoPackage Support - Read feature tables, inspect metadata, stream typed features, and write feature data
- ✅ Streaming Shapefile Reads - Read large shapefiles incrementally with
ShapefileStreamReader - ✅ Attribute Support - Full dBASE III+ (
.dbf) file support for feature attributes - ✅ Projection Support - Read projection information from
.prjfiles - ✅ Korean Text Support - CP949 encoding for Korean text in attributes
- ✅ UTF-8 Support - Modern UTF-8 encoding support
- ✅ Type-Safe - Strongly typed geometry classes with immutable data structures
- ✅ Clean Architecture - Well-organized codebase following clean architecture principles
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
shapekit: ^0.3.2
Then run:
dart pub get
Quick Start #
Reading a Shapefile #
import 'package:shapekit/shapekit.dart';
void main() {
final shapefile = Shapefile();
try {
shapefile.read('path/to/file.shp');
print('Loaded ${shapefile.records.length} records');
// Access geometry
for (final record in shapefile.records) {
if (record is Point) {
print('Point: ${record.x}, ${record.y}');
} else if (record is Polyline) {
print('Polyline with ${record.numPoints} points');
} else if (record is Polygon) {
print('Polygon with ${record.numParts} parts');
}
}
// Access attributes (if .dbf file exists)
for (int i = 0; i < shapefile.attributeRecords.length; i++) {
print('Record $i attributes: ${shapefile.attributeRecords[i]}');
}
// Access projection EPSG code (if .prj file exists)
if (shapefile.epsgCode != null) {
print('Projection EPSG: ${shapefile.epsgCode}');
}
} on ShapefileException catch (e) {
print('Error reading shapefile: ${e.message}');
}
}
Writing a Shapefile #
import 'package:shapekit/shapekit.dart';
void main() {
final shapefile = Shapefile();
// Create point records
final records = [
Point(126.9780, 37.5665), // Seoul
Point(129.0756, 35.1796), // Busan
];
// Create attribute fields
final fields = [
DbaseField.fieldC('NAME', 50),
DbaseField.fieldN('POPULATION', 10),
];
// Create attribute records
final attributes = [
['Seoul', 9776000],
['Busan', 3413000],
];
// Write shapefile
shapefile.writeComplete(
'cities.shp',
ShapeType.shapePOINT,
records,
minX: 126.9780,
minY: 35.1796,
maxX: 129.0756,
maxY: 37.5665,
attributeFields: fields,
attributeRecords: attributes,
);
print('Shapefile created successfully!');
}
Reading a GeoPackage #
import 'package:shapekit/shapekit.dart';
Future<void> main() async {
final gpkg = GpkgReader.open('path/to/file.gpkg');
try {
final tables = gpkg.listFeatureTables();
print('Feature tables: $tables');
await for (final batch in gpkg.queryFeatures(
table: tables.first,
bounds: const Envelope(-180, -90, 180, 90),
loadAttributes: true,
)) {
for (final feature in batch.features) {
print('${feature.fid}: ${feature.geometry.type}');
}
}
} finally {
gpkg.close();
}
}
Streaming a Shapefile #
import 'package:shapekit/shapekit.dart';
Future<void> main() async {
final reader = ShapefileStreamReader.open('path/to/file.shp', isUtf8: true);
await for (final feature in reader.features()) {
print('Feature ${feature.index}: ${feature.geometry.type}');
}
}
Supported Geometry Types #
| Geometry Type | Class | Description |
|---|---|---|
| Point | Point |
Single point (X, Y) |
| PointM | PointM |
Point with measure value (X, Y, M) |
| PointZ | PointZ |
Point with Z and M values (X, Y, Z, M) |
| Polyline | Polyline |
Line or multi-line (parts, points) |
| PolylineM | PolylineM |
Polyline with optional M values |
| PolylineZ | PolylineZ |
Polyline with Z and optional M values |
| Polygon | Polygon |
Polygon or multi-polygon (parts, points) |
| PolygonM | PolygonM |
Polygon with optional M values |
| PolygonZ | PolygonZ |
Polygon with Z and optional M values |
| MultiPoint | MultiPoint |
Collection of points |
| MultiPointM | MultiPointM |
MultiPoint with optional M values |
| MultiPointZ | MultiPointZ |
MultiPoint with Z and optional M values |
| MultiPatch | MultiPatch |
3D surface ❌ not yet implemented |
Text Encoding #
The library supports multiple text encodings for attribute data:
// UTF-8 encoding (default, recommended)
final shapefile = Shapefile(isUtf8: true);
// CP949 encoding (for Korean legacy data)
final shapefile = Shapefile(isCp949: true);
// ASCII encoding (when both flags are false)
final shapefile = Shapefile();
Attribute Field Types #
When working with dBASE attributes, use these field types:
// Character field (text)
DbaseField.fieldC('NAME', 50) // name, max length
// Date field
DbaseField.fieldD('DATE') // name only
// Logical field (boolean)
DbaseField.fieldL('ACTIVE') // name only
// Numeric field (integer)
DbaseField.fieldN('COUNT', 10) // name, total digits
// Numeric field (floating point)
DbaseField.fieldNF('AREA', 20, 8) // name, total digits, decimal places
Limitations #
- No MultiPatch support - MultiPatch geometry type is not yet implemented
- No coordinate transformation - The library reads projection information but does not transform coordinates
- Synchronous I/O - File operations are synchronous (blocking)
Error Handling #
The library uses typed exceptions for error handling:
try {
final shapefile = Shapefile();
shapefile.read('data.shp');
} on FileNotFoundException catch (e) {
print('File not found: ${e.path}');
} on InvalidHeaderException catch (e) {
print('Invalid shapefile header: ${e.message}');
} on CorruptedDataException catch (e) {
print('Corrupted data: ${e.details}');
} on ShapefileException catch (e) {
print('Shapefile error: $e');
}
Exception Types:
FileNotFoundException- File not found or cannot be accessedInvalidHeaderException- Invalid file headerInvalidFormatException- Invalid file formatCorruptedDataException- Corrupted record dataUnsupportedTypeException- Unsupported geometry typeShapefileIOException- File I/O errorGpkgException- GeoPackage read/write/query error
Support #
If you find this library helpful, consider supporting its development! ☕️
Your support helps me:
- 🐛 Fix bugs faster
- ✨ Add new features and projections
- 📚 Improve documentation
- 🚀 Build more GIS tools for the community
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
References #
Acknowledgments #
This library is based on the shapefile-kr repository by @michael-kim-korea.