more speed ups
This commit is contained in:
+18
-18
@@ -68,6 +68,7 @@ import struct
|
|||||||
import array
|
import array
|
||||||
import argparse
|
import argparse
|
||||||
from typing import IO
|
from typing import IO
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
class Nimrod:
|
class Nimrod:
|
||||||
@@ -89,7 +90,7 @@ class Nimrod:
|
|||||||
x_pixel_size (float): Size of pixel in x-direction
|
x_pixel_size (float): Size of pixel in x-direction
|
||||||
x_right (float): Right easting coordinate
|
x_right (float): Right easting coordinate
|
||||||
y_bottom (float): Bottom northing coordinate
|
y_bottom (float): Bottom northing coordinate
|
||||||
data (array.array): Raster data array
|
data (np.ndarray): Raster data array
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class RecordLenError(Exception):
|
class RecordLenError(Exception):
|
||||||
@@ -253,11 +254,16 @@ class Nimrod:
|
|||||||
array_size = self.ncols * self.nrows
|
array_size = self.ncols * self.nrows
|
||||||
check_record_len(infile, array_size * 2, "data start")
|
check_record_len(infile, array_size * 2, "data start")
|
||||||
|
|
||||||
self.data = array.array("h")
|
|
||||||
try:
|
try:
|
||||||
data = infile.read(array_size * 2)
|
# Read data as big-endian 16-bit integers
|
||||||
self.data.frombytes(data)
|
# numpy.frombuffer is efficient for reading from bytes
|
||||||
self.data.byteswap()
|
data_bytes = infile.read(array_size * 2)
|
||||||
|
self.data = np.frombuffer(data_bytes, dtype='>h').astype(np.int16)
|
||||||
|
|
||||||
|
# Reshape to (nrows, ncols) for easier 2D manipulation
|
||||||
|
# Note: NIMROD data is row-major (C-style), starting from top-left
|
||||||
|
self.data = self.data.reshape((self.nrows, self.ncols))
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
infile.close()
|
infile.close()
|
||||||
raise Nimrod.PayloadReadError
|
raise Nimrod.PayloadReadError
|
||||||
@@ -383,16 +389,12 @@ class Nimrod:
|
|||||||
yMinPixelId = int((self.y_top - ymax) / self.y_pixel_size + 0.5)
|
yMinPixelId = int((self.y_top - ymax) / self.y_pixel_size + 0.5)
|
||||||
yMaxPixelId = int((self.y_top - ymin) / self.y_pixel_size + 0.5)
|
yMaxPixelId = int((self.y_top - ymin) / self.y_pixel_size + 0.5)
|
||||||
|
|
||||||
bbox_data = []
|
# Use numpy slicing to extract the sub-array
|
||||||
for i in range(yMinPixelId, yMaxPixelId + 1):
|
# Note: y indices correspond to rows, x indices to columns
|
||||||
bbox_data.extend(
|
# Slicing is [start:end], so we need +1 for the end index
|
||||||
self.data[
|
self.data = self.data[yMinPixelId : yMaxPixelId + 1, xMinPixelId : xMaxPixelId + 1]
|
||||||
i * self.ncols + xMinPixelId : i * self.ncols + xMaxPixelId + 1
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Update object where necessary
|
# Update object where necessary
|
||||||
self.data = bbox_data
|
|
||||||
self.x_right = self.x_left + xMaxPixelId * self.x_pixel_size
|
self.x_right = self.x_left + xMaxPixelId * self.x_pixel_size
|
||||||
self.x_left += xMinPixelId * self.x_pixel_size
|
self.x_left += xMinPixelId * self.x_pixel_size
|
||||||
self.ncols = xMaxPixelId - xMinPixelId + 1
|
self.ncols = xMaxPixelId - xMinPixelId + 1
|
||||||
@@ -431,11 +433,9 @@ class Nimrod:
|
|||||||
outfile.write("cellsize %.1f\n" % self.y_pixel_size)
|
outfile.write("cellsize %.1f\n" % self.y_pixel_size)
|
||||||
outfile.write("nodata_value %.1f\n" % self.hdr_element[38])
|
outfile.write("nodata_value %.1f\n" % self.hdr_element[38])
|
||||||
|
|
||||||
# Write raster data to output file
|
# Write raster data to output file using numpy.savetxt
|
||||||
for i in range(self.nrows):
|
# This is significantly faster than iterating in Python
|
||||||
for j in range(self.ncols - 1):
|
np.savetxt(outfile, self.data, fmt='%d', delimiter=' ')
|
||||||
outfile.write("%d " % self.data[i * self.ncols + j])
|
|
||||||
outfile.write("%d\n" % self.data[i * self.ncols + self.ncols - 1])
|
|
||||||
outfile.close()
|
outfile.close()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user