read method
Read a geometry from the ByteBuffer. The buffer's position, byteOrder, and limit are set to that which is needed. The record has been read as well as the shape type integer. The handler need not worry about reading unused information as the ShapefileReader will correctly adjust the buffer position after this call.
@param buffer The ByteBuffer to read from. @return A geometry object.
Implementation
@override
dynamic read(LByteBuffer buffer, ShapeType? type, bool flatGeometry) {
if (type == ShapeType.NULL) {
return createNull();
}
int dimensions =
((shapeType == ShapeType.ARCZ || shapeType == ShapeType.ARCM) &&
!flatGeometry)
? 3
: 2;
// read bounding box (not needed)
buffer.position = buffer.position + 4 * 8;
int numParts = buffer.getInt32();
int numPoints = buffer.getInt32(); // total number of points
List<int> partOffsets = List.filled(numParts, 0);
// points = new Coordinate[numPoints];
for (int i = 0; i < numParts; i++) {
partOffsets[i] = buffer.getInt32();
}
// read the first two coordinates and start building the coordinate
// sequences
List<CoordinateSequence> lines = []; //List(numParts);
int finish, start = 0;
int length = 0;
bool clonePoint = false;
// final DoubleBuffer doubleBuffer = buffer.asDoubleBuffer();
for (int part = 0; part < numParts; part++) {
start = partOffsets[part];
if (part == (numParts - 1)) {
finish = numPoints;
} else {
finish = partOffsets[part + 1];
}
length = finish - start;
int xyLength = length;
if (length == 1) {
length = 2;
clonePoint = true;
} else {
clonePoint = false;
}
CoordinateSequence cs;
int measure = flatGeometry ? 0 : 1;
if (shapeType == ShapeType.ARCM) {
cs = Shapeutils.createCSMeas(
geometryFactory.getCoordinateSequenceFactory(),
length,
dimensions + measure,
measure);
} else if (shapeType == ShapeType.ARCZ) {
cs = Shapeutils.createCSMeas(
geometryFactory.getCoordinateSequenceFactory(),
length,
dimensions + measure,
measure);
} else {
cs = Shapeutils.createCS(
geometryFactory.getCoordinateSequenceFactory(), length, dimensions);
}
// List<double> xy = new double[xyLength * 2];
// doubleBuffer.get(xy);
List<double> xy = List.filled(xyLength * 2, 0.0);
for (var i = 0; i < xy.length; i++) {
xy[i] = buffer.getDouble64();
}
for (int i = 0; i < xyLength; i++) {
cs.setOrdinate(i, CoordinateSequence.X, xy[i * 2]);
cs.setOrdinate(i, CoordinateSequence.Y, xy[i * 2 + 1]);
}
if (clonePoint) {
cs.setOrdinate(
1, CoordinateSequence.X, cs.getOrdinate(0, CoordinateSequence.X));
cs.setOrdinate(
1, CoordinateSequence.Y, cs.getOrdinate(0, CoordinateSequence.Y));
}
lines.add(cs);
// lines[part] = cs;
}
// if we have another coordinate, read and add to the coordinate
// sequences
if (shapeType == ShapeType.ARCZ && !flatGeometry) {
// z min, max
// buffer.position(buffer.position() + 2 * 8);
// doubleBuffer.position(doubleBuffer.position() + 2);
buffer.position = buffer.position + 2 * 8;
for (int part = 0; part < numParts; part++) {
start = partOffsets[part];
if (part == (numParts - 1)) {
finish = numPoints;
} else {
finish = partOffsets[part + 1];
}
length = finish - start;
if (length == 1) {
length = 2;
clonePoint = true;
} else {
clonePoint = false;
}
// List<double> z = new double[length];
// doubleBuffer.get(z);
List<double> z = List.filled(length, 0.0);
for (var i = 0; i < z.length; i++) {
z[i] = buffer.getDouble64();
}
for (int i = 0; i < length; i++) {
lines[part].setOrdinate(i, CoordinateSequence.Z, z[i]);
}
}
}
if ((shapeType == ShapeType.ARCZ || shapeType == ShapeType.ARCM) &&
!flatGeometry) {
// M min, max
// buffer.position(buffer.position() + 2 * 8);
// doubleBuffer.position(doubleBuffer.position() + 2);
buffer.position = buffer.position + 2 * 8;
for (int part = 0; part < numParts; part++) {
start = partOffsets[part];
if (part == (numParts - 1)) {
finish = numPoints;
} else {
finish = partOffsets[part + 1];
}
length = finish - start;
if (length == 1) {
length = 2;
clonePoint = true;
} else {
clonePoint = false;
}
// List<double> m = new double[length];
// doubleBuffer.get(m);
List<double> m = List.filled(length, 0.0);
for (var i = 0; i < m.length; i++) {
m[i] = buffer.getDouble64();
}
for (int i = 0; i < length; i++) {
lines[part].setOrdinate(i, CoordinateSequence.M, m[i]);
}
}
}
// Prepare line strings and return the multilinestring
List<LineString> lineStrings = []; // List(numParts);
for (int part = 0; part < numParts; part++) {
lineStrings.add(geometryFactory.createLineStringSeq(lines[part]));
// lineStrings[part] = geometryFactory.createLineStringSeq(lines[part]);
}
return geometryFactory.createMultiLineString(lineStrings);
}