fix(select): support circle resize on globe and web-mercator projections#846
fix(select): support circle resize on globe and web-mercator projections#846Remenby31 wants to merge 2 commits intoJamesLMilner:mainfrom
Conversation
b28ae6a to
837a606
Compare
Circle features were distorted into ovals when resized because the select mode used generic bbox-based coordinate scaling. On globe projection, resizing threw an error entirely. This fix detects circle features (via the `radiusKilometers` property) and regenerates the circle from its center + new radius instead of scaling individual coordinates. The center is captured once at drag start to prevent centroid drift during progressive updates. Works for both `globe` (geodesic circle) and `web-mercator` projections. Closes JamesLMilner#436
837a606 to
8e4fc98
Compare
|
Thanks for this, I appreciate your thought and input here on the topic and your interest more broadly in the project. I am just on my phone and I need to write this up on the issue but I've wanted to avoid mode specific logic in TerraDrawSelectMode as it is a powerful property that the mode is agnostic to what it is interacting with (I.e. it doesn't know about other modes you may or may not be using). I'll provide more detailed response at a later date when I have more free time to dig into this more thoroughly. Just speaking off the cuff, I feel like we might be able to fix globe projection resizing to respect geodesic resizing for circles without knowledge of circle mode. Another option might be to allow custom functions that allow people to modify the geometry/properties as they wish. Again though I'll think about this all when I get a moment! |
Problem
Circle features created with
TerraDrawCircleModeare distorted into ovals when resized viaTerraDrawSelectModewithresizable: "center".This happens because the resize behavior (
DragCoordinateResizeBehavior) treats circles as generic polygons and applies bbox-based coordinate scaling. Since a circle is a polygon with 64 evenly-spaced vertices, scaling X and Y independently — especially in Web Mercator where latitude distortion is non-linear — deforms the circle into an ellipse.On globe projection, resizing throws an error entirely:
This is tracked in #436.
Solution
When a resizable feature is detected as a circle (has
properties.mode === "circle"andproperties.radiusKilometers), bypass the generic bbox scaling and instead:circleResizeCentercircle()(globe) orcircleWebMercator()(web-mercator) functions with the new radiusradiusKilometersproperty on the feature to keep it in syncThe center is captured once at drag start rather than recomputed each frame to prevent centroid drift — the arithmetic mean of polygon vertices is not exactly the geodesic center, and progressive recomputation causes the circle to slowly migrate.
Changes
packages/terra-draw/src/modes/select/select.mode.ts— 1 file, ~100 lines addedcircleResizeCenter: Position | nullfield toTerraDrawSelectModeonDragStart: capture center when starting a circle resizeonDrag: detect circles and callresizeCircle()instead of bbox scaling — for both globe and web-mercator projectionsonDragEnd: reset stored centerresizeCircle()that regenerates the geodesic/web-mercator circle from center + haversine distance to cursorTesting
Tested manually with MapLibre GL JS v5.21 + globe projection:
radiusKilometersproperty updates correctly