reprojectWKB = {
function reprojectWKB(wkb, sourceProj, targetProj) {
var wkbCopy = new Uint8Array(wkb);
var dataView = new DataView(wkbCopy.buffer);
var byteOrder = 0;
var geometryType = dataView.getUint32(1, byteOrder === 0);
var geometryFunctions = {
1: reprojectPoint,
2: reprojectLineString,
3: reprojectPolygon,
4: reprojectMultiPoint,
5: reprojectMultiLineString,
6: reprojectMultiPolygon
};
if (geometryFunctions.hasOwnProperty(geometryType)) {
geometryFunctions[geometryType](
dataView,
byteOrder,
sourceProj,
targetProj
);
} else {
// Throw an error and return null
throw new Error("Unsupported geometry type: " + geometryType);
return null;
}
// Return the reprojected WKB
return wkbCopy;
}
// A helper function that reprojects a point coordinate pair from a DataView
// Input: a DataView, a byte order (0 for little endian, 1 for big endian),
// a source projection object, and a target projection object
// Output: none (the data view is modified in place)
function reprojectPoint(dataView, byteOrder, sourceProj, targetProj) {
// A point has one coordinate pair starting from index 5
// Read the x and y coordinates as double values from the data view
var x = dataView.getFloat64(5, byteOrder === 0);
var y = dataView.getFloat64(13, byteOrder === 0);
// Reproject the coordinates using proj4
var reprojected = proj4(sourceProj, targetProj, [x, y]);
// Write the reprojected coordinates back to the data view
dataView.setFloat64(5, reprojected[0], byteOrder === 0);
dataView.setFloat64(13, reprojected[1], byteOrder === 0);
}
// A helper function that reprojects a linestring coordinate pairs from a DataView
// Input: a DataView, a byte order (0 for little endian, 1 for big endian),
// a source projection object, and a target projection object
// Output: none (the data view is modified in place)
function reprojectLineString(dataView, byteOrder, sourceProj, targetProj) {
// A linestring has a number of points starting from index 9
var numPoints = dataView.getUint32(5, byteOrder === 0);
for (var i = 0; i < numPoints; i++) {
// Each point has one coordinate pair starting from index 9 + i * 16
// Read the x and y coordinates as double values from the data view
var x = dataView.getFloat64(9 + i * 16, byteOrder === 0);
var y = dataView.getFloat64(17 + i * 16, byteOrder === 0);
// Reproject the coordinates using proj4
var reprojected = proj4(sourceProj, targetProj, [x, y]);
// Write the reprojected coordinates back to the data view
dataView.setFloat64(9 + i * 16, reprojected[0], byteOrder === 0);
dataView.setFloat64(17 + i * 16, reprojected[1], byteOrder === 0);
}
}
// A helper function that reprojects a polygon coordinate pairs from a DataView
// Input: a DataView, a byte order (0 for little endian, 1 for big endian),
// a source projection object, and a target projection object
// Output: none (the data view is modified in place)
function reprojectPolygon(dataView, byteOrder, sourceProj, targetProj) {
// A polygon has a number of rings starting from index 9
var numRings = dataView.getUint32(5, byteOrder === 0);
var offset = 9;
for (var i = 0; i < numRings; i++) {
// Each ring has a number of points starting from offset + 4
var numPoints = dataView.getUint32(offset, byteOrder === 0);
for (var j = 0; j < numPoints; j++) {
// Each point has one coordinate pair starting from offset + 4 + j * 16
// Read the x and y coordinates as double values from the data view
var x = dataView.getFloat64(offset + 4 + j * 16, byteOrder === 0);
var y = dataView.getFloat64(offset + 12 + j * 16, byteOrder === 0);
// Reproject the coordinates using proj4
var reprojected = proj4(sourceProj, targetProj, [x, y]);
// Write the reprojected coordinates back to the data view
dataView.setFloat64(
offset + 4 + j * 16,
reprojected[0],
byteOrder === 0
);
dataView.setFloat64(
offset + 12 + j * 16,
reprojected[1],
byteOrder === 0
);
}
// Update the offset to the next ring
offset += 4 + numPoints * 16;
}
}
// A helper function that reprojects a multipoint coordinate pairs from a DataView
// Input: a DataView, a byte order (0 for little endian, 1 for big endian),
// a source projection object, and a target projection object
// Output: none (the data view is modified in place)
function reprojectMultiPoint(dataView, byteOrder, sourceProj, targetProj) {
// A multipoint has a number of points starting from index 9
var numPoints = dataView.getUint32(5, byteOrder === 0);
for (var i = 0; i < numPoints; i++) {
// Each point has one coordinate pair starting from index 13 + i * 21
// Read the x and y coordinates as double values from the data view
var x = dataView.getFloat64(13 + i * 21, byteOrder === 0);
var y = dataView.getFloat64(21 + i * 21, byteOrder === 0);
// Reproject the coordinates using proj4
var reprojected = proj4(sourceProj, targetProj, [x, y]);
// Write the reprojected coordinates back to the data view
dataView.setFloat64(13 + i * 21, reprojected[0], byteOrder === 0);
dataView.setFloat64(21 + i * 21, reprojected[1], byteOrder === 0);
}
}
// A helper function that reprojects a multilinestring coordinate pairs from a DataView
// Input: a DataView, a byte order (0 for little endian, 1 for big endian),
// a source projection object, and a target projection object
// Output: none (the data view is modified in place)
function reprojectMultiLineString(
dataView,
byteOrder,
sourceProj,
targetProj
) {
// A multilinestring has a number of linestrings starting from index 9
var numLineStrings = dataView.getUint32(5, byteOrder === 0);
var offset = 9;
for (var i = 0; i < numLineStrings; i++) {
// Each linestring has a number of points starting from offset + 9
var numPoints = dataView.getUint32(offset + 5, byteOrder === 0);
for (var j = 0; j < numPoints; j++) {
// Each point has one coordinate pair starting from offset + 9 + j * 16
// Read the x and y coordinates as double values from the data view
var x = dataView.getFloat64(offset + 9 + j * 16, byteOrder === 0);
var y = dataView.getFloat64(offset + 17 + j * 16, byteOrder === 0);
// Reproject the coordinates using proj4
var reprojected = proj4(sourceProj, targetProj, [x, y]);
// Write the reprojected coordinates back to the data view
dataView.setFloat64(
offset + 9 + j * 16,
reprojected[0],
byteOrder === 0
);
dataView.setFloat64(
offset + 17 + j * 16,
reprojected[1],
byteOrder === 0
);
}
// Update the offset to the next linestring
offset += 9 + numPoints * 16;
}
}
// A helper function that reprojects a multipolygon coordinate pairs from a DataView
// Input: a DataView, a byte order (0 for little endian, 1 for big endian),
// a source projection object, and a target projection object
// Output: none (the data view is modified in place)
function reprojectMultiPolygon(dataView, byteOrder, sourceProj, targetProj) {
// A multipolygon has a number of polygons starting from index 9
var numPolygons = dataView.getUint32(5, byteOrder === 0);
var offset = 9;
for (var i = 0; i < numPolygons; i++) {
// Each polygon has a number of rings starting from offset + 9
var numRings = dataView.getUint32(offset + 5, byteOrder === 0);
for (var j = 0; j < numRings; j++) {
// Each ring has a number of points starting from offset + 13
var numPoints = dataView.getUint32(offset + 9, byteOrder === 0);
for (var k = 0; k < numPoints; k++) {
// Each point has one coordinate pair starting from offset + 13 + k * 16
// Read the x and y coordinates as double values from the data view
var x = dataView.getFloat64(offset + 13 + k * 16, byteOrder === 0);
var y = dataView.getFloat64(offset + 21 + k * 16, byteOrder === 0);
// Reproject the coordinates using proj4
var reprojected = proj4(sourceProj, targetProj, [x, y]);
// Write the reprojected coordinates back to the data view
dataView.setFloat64(
offset + 13 + k * 16,
reprojected[0],
byteOrder === 0
);
dataView.setFloat64(
offset + 21 + k * 16,
reprojected[1],
byteOrder === 0
);
}
// Update the offset to the next ring
offset += 13 + numPoints * 16;
}
// Update the offset to the next polygon
offset += 9 + numRings * 4;
}
}
return reprojectWKB;
}