Mat.B
Mat.B

Reputation: 376

Is there a way to rotate a dash-leaflet dl.Rectangle() through a callback?

I'm building an python dash-leaflet app where the user can click on a map to place a rectangle through a callback, and I would like to add a second callback (bond to a slider) to rotate it around its center according to North (eg. rotate it by 20° to the East).

To place the rectangle in a callback I use:

mapOne.append(dl.Rectangle(fillOpacity=0.5, weight=0.7, color='#888',
        bounds=[[click_lat_lng[0]+xbox1, click_lat_lng[1]+ybox1],
                        [click_lat_lng[0]+xbox2, click_lat_lng[1]+ybox2]]
             ))

I thought about a sort of inverse Haversine function to get the new "rotated" xbox1 and xbox2, but the dl.Rectangle() seem to be always aligned with axes.

Any thought on the best way to achieve this?

Upvotes: 0

Views: 240

Answers (1)

Mat.B
Mat.B

Reputation: 376

Well, I never figured out a ay to do it "out of the box" with dash-leaflet in python (though it seems fairly easy with leaflet and some built-in functions in js).

I ended up using a dl.polygon() instead, using :

  • the center of my rectangle defined by click_lat_lng[0] and click_lat_lng[1],

  • The dimensions of my rectangle defined in meters, together with a simple rotation matrix to define the actual "rotated" x and y of the rectangle corners,

  • Finally translating this to lat / lon values with the help of the following function (taken from here) :

def translate_latlong(lat,long,lat_translation_meters,long_translation_meters):
    ''' method to move any lat,long point by provided meters in lat and long direction.
    params :
        lat,long: lattitude and longitude in degrees as decimal values, e.g. 37.43609517497065, -122.17226450150885
        lat_translation_meters: movement of point in meters in lattitude direction.
                                positive value: up move, negative value: down move
        long_translation_meters: movement of point in meters in longitude direction.
                                positive value: left move, negative value: right move
        '''
    earth_radius = 6378.137

    #Calculate top, which is lat_translation_meters above
    m_lat = (1 / ((2 * math.pi / 360) * earth_radius)) / 1000;  
    lat_new = lat + (lat_translation_meters * m_lat)

    #Calculate right, which is long_translation_meters right
    m_long = (1 / ((2 * math.pi / 360) * earth_radius)) / 1000;  # 1 meter in degree
    long_new = long + (long_translation_meters * m_long) / math.cos(lat * (math.pi / 180));
    
    return lat_new,long_new

Upvotes: 0

Related Questions