@@ -370,14 +370,6 @@ def validate(cls, v):
370
370
def _is_simple (self , epsg : EPSG ) -> bool :
371
371
return epsg == EPSG .SIMPLEPIXEL
372
372
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
-
381
373
def _get_ranges (self , bounds : np .ndarray ):
382
374
"""helper function to get the range between bounds.
383
375
@@ -386,34 +378,97 @@ def _get_ranges(self, bounds: np.ndarray):
386
378
y_range = np .max (bounds [:, 1 ]) - np .min (bounds [:, 1 ])
387
379
return (x_range , y_range )
388
380
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
+
389
400
def geo_and_pixel (self ,
390
401
src_epsg ,
391
402
pixel_bounds : TiledBounds ,
392
403
geo_bounds : TiledBounds ,
393
404
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
+
395
427
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
397
445
398
446
#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 :
415
464
416
465
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
+
417
472
return (x * (local_x_range ) / (global_x_range ),
418
473
y * (local_y_range ) / (global_y_range ))
419
474
0 commit comments