Reputation: 376
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
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