日本語版の記事はこちら (Japanese version is here)
Recently, I had a request in a project: “I want to specify an area intuitively by rotating and transforming shapes on Google Maps, just like in PowerPoint.”
In the standard Google Maps JavaScript API, drawing a Rectangle is supported, but it is designed to always align parallel to the North-South and East-West axes. Because of this, it was difficult to achieve operations like “rotating diagonally” using only standard features.
To overcome this, I created a custom editor component that allows completely free transformation and rotation by utilizing spherical geometry calculations (well, it’s really just combining vector operations with the API). I’ll summarize the implementation points here as a memorandum.
Live Demo
🎮 How to Use
- Draw: Click a button like “Add Usual” and drag your mouse on the map to draw a rectangle.
- Select/Move: Click an already drawn area to enter edit mode, and drag the entire area to move it.
- Transform/Rotate: In edit mode, drag the circular anchors at the four corners to resize, and drag the double-circle handle at the top to rotate.
- Delete/Switch: Use “Remove” to delete the selected area, and “Prev”/”Next” to switch the target editing area.
- Save/Restore: You can export or import the layout data in JSON format from the text area at the bottom.
The Wall of Standard APIs and Implementation Points
To realize this editor, special considerations unique to “coordinates on a sphere” like latitude and longitude were necessary.
1. Using Polygon to Define Shapes
The standard Rectangle class does not support rotation. Therefore, I pseudo-represented a “rotatable rectangle” by calculating the coordinates of the four vertices each time and drawing them using the Polygon class instead.
2. Vector Operations and Spherical Geometry
To maintain the shape properly on the spherical Earth, I combined methods like spherical.computeOffset, which calculates vertices using the heading and distance from the center coordinate. I also prepared a custom vector operation class (math.js) to translate the mouse behavior during rotation handling and resizing into accurate coordinates.
3. Adopting Modern Technologies
This time, I built the component using Vanilla JS (ES Modules) and adopted the latest AdvancedMarkerElement for the operation markers.
Note: To use AdvancedMarkerElement, you must specify a mapId when initializing the map.
How to Use (Published on GitHub)
I have published this component on GitHub under the MIT license so that it can be easily copied and used in other projects.
GitHub – hiroyukashi/google-maps-area-editor
import { AreaEditor, AreaType } from './AreaEditor.js';
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 35.681236, lng: 139.767125 },
zoom: 18,
mapId: 'DEMO_MAP_ID',
isFractionalZoomEnabled: false
});
const editor = await AreaEditor.create(map, {
types: [new AreaType("usual", "#00bbdd")]
});
editor.setAreaType(editor.types[0]);
Note: Because it uses ES Modules, it will not work if you open index.html directly locally. Please check it via a local server like VS Code’s Live Server.
Conclusion
Shape manipulation, which looks simple at first glance, was actually quite a challenging implementation because it involves a lot of geometry calculations to make it work seamlessly on a map. I hope this helps developers who are struggling with similar requests. Please feel free to customize and use it!
(Bonus)
I worked hard on refining the code and building the demo… so I let an AI write this article for me (with just a few minor tweaks). They really praise you embarrassingly well, don’t they?