Skip to content

Commit 83aebf1

Browse files
committed
updates to projections
1 parent 1c85c46 commit 83aebf1

File tree

1 file changed

+81
-26
lines changed

1 file changed

+81
-26
lines changed

labelbox/data/annotation_types/data/tiled_image.py

Lines changed: 81 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -370,14 +370,6 @@ def validate(cls, v):
370370
def _is_simple(self, epsg: EPSG) -> bool:
371371
return epsg == EPSG.SIMPLEPIXEL
372372

373-
def geo_and_geo(self, src_epsg: EPSG, tgt_epsg: EPSG) -> None:
374-
if self._is_simple(src_epsg) or self._is_simple(tgt_epsg):
375-
raise Exception(
376-
f"Cannot be used for Simple transformations. Found {src_epsg} and {tgt_epsg}"
377-
)
378-
self.transform_function = Transformer.from_crs(src_epsg.value,
379-
tgt_epsg.value).transform
380-
381373
def _get_ranges(self, bounds: np.ndarray):
382374
"""helper function to get the range between bounds.
383375
@@ -386,34 +378,97 @@ def _get_ranges(self, bounds: np.ndarray):
386378
y_range = np.max(bounds[:, 1]) - np.min(bounds[:, 1])
387379
return (x_range, y_range)
388380

381+
def _min_max_x_y(self, bounds: np.ndarray):
382+
"""returns the min x, max x, min y, max y of a numpy array
383+
"""
384+
return np.min(bounds[:, 0]), np.max(bounds[:, 0]), np.min(
385+
bounds[:, 1]), np.max(bounds[:, 1])
386+
387+
def geo_and_geo(self, src_epsg: EPSG, tgt_epsg: EPSG) -> None:
388+
"""method to change from one projection to another projection.
389+
390+
supports EPSG transformations not Simple.
391+
"""
392+
if self._is_simple(src_epsg) or self._is_simple(tgt_epsg):
393+
raise Exception(
394+
f"Cannot be used for Simple transformations. Found {src_epsg} and {tgt_epsg}"
395+
)
396+
self.transform_function = Transformer.from_crs(src_epsg.value,
397+
tgt_epsg.value,
398+
always_xy=True).transform
399+
389400
def geo_and_pixel(self,
390401
src_epsg,
391402
pixel_bounds: TiledBounds,
392403
geo_bounds: TiledBounds,
393404
zoom=0):
394-
#TODO: pixel to geo
405+
"""method to change from one projection to simple projection"""
406+
407+
pixel_bounds = pixel_bounds.bounds
408+
geo_bounds_epsg = geo_bounds.epsg
409+
geo_bounds = geo_bounds.bounds
410+
411+
#TODO: think about renaming local/global?
412+
#local = pixel
413+
#global = geo
414+
local_bounds = np.array([(point.x, point.y) for point in pixel_bounds],
415+
dtype=np.int)
416+
#convert geo bounds to pixel bounds. assumes geo bounds are in wgs84/EPS4326 per leaflet
417+
global_bounds = np.array([
418+
PygeoPoint.from_latitude_longitude(latitude=point.y,
419+
longitude=point.x).pixels(zoom)
420+
for point in geo_bounds
421+
])
422+
423+
#get the range of pixels for both sets of bounds to use as a multiplification factor
424+
local_x_range, local_y_range = self._get_ranges(local_bounds)
425+
global_x_range, global_y_range = self._get_ranges(global_bounds)
426+
395427
if src_epsg == EPSG.SIMPLEPIXEL:
396-
pass
428+
429+
def transform(x: int, y: int):
430+
scaled_xy = (x * (global_x_range) / (local_x_range),
431+
y * (global_y_range) / (local_y_range))
432+
433+
minx, _, miny, _ = self._min_max_x_y(global_bounds)
434+
x, y = map(lambda i, j: i + j, scaled_xy, (minx, miny))
435+
436+
point = PygeoPoint.from_pixel(pixel_x=x, pixel_y=y,
437+
zoom=zoom).latitude_longitude
438+
#convert to the desired epsg
439+
return Transformer.from_crs(EPSG.EPSG4326.value,
440+
geo_bounds_epsg.value,
441+
always_xy=True).transform(
442+
point[1], point[0])
443+
444+
self.transform_function = transform
397445

398446
#geo to pixel - converts a point in geo coords to pixel coords
399-
else:
400-
pixel_bounds = pixel_bounds.bounds
401-
geo_bounds = geo_bounds.bounds
402-
403-
local_bounds = np.array(
404-
[(point.x, point.y) for point in pixel_bounds], dtype=np.int)
405-
#convert geo bounds to pixel bounds. assumes geo bounds are in wgs84/EPS4326 per leaflet
406-
global_bounds = np.array([
407-
PygeoPoint.from_latitude_longitude(
408-
latitude=point.y, longitude=point.x).pixels(zoom)
409-
for point in geo_bounds
410-
])
411-
412-
#get the range of pixels for both sets of bounds to use as a multiplification factor
413-
global_x_range, global_y_range = self._get_ranges(global_bounds)
414-
local_x_range, local_y_range = self._get_ranges(local_bounds)
447+
#handles 4326 from lat,lng
448+
elif src_epsg == EPSG.EPSG4326:
449+
450+
def transform(x: int, y: int):
451+
point_in_px = PygeoPoint.from_latitude_longitude(
452+
latitude=y, longitude=x).pixels(zoom)
453+
454+
minx, _, miny, _ = self._min_max_x_y(global_bounds)
455+
x, y = map(lambda i, j: i - j, point_in_px, (minx, miny))
456+
457+
return (x * (local_x_range) / (global_x_range),
458+
y * (local_y_range) / (global_y_range))
459+
460+
self.transform_function = transform
461+
462+
#handles 3857 from meters
463+
elif src_epsg == EPSG.EPSG3857:
415464

416465
def transform(x: int, y: int):
466+
point_in_px = PygeoPoint.from_meters(meter_y=y,
467+
meter_x=x).pixels(zoom)
468+
469+
minx, _, miny, _ = self._min_max_x_y(global_bounds)
470+
x, y = map(lambda i, j: i - j, point_in_px, (minx, miny))
471+
417472
return (x * (local_x_range) / (global_x_range),
418473
y * (local_y_range) / (global_y_range))
419474

0 commit comments

Comments
 (0)