How to Recreate a MapCircle on Location Change in HarmonyOS Wearable Devices
Requirement Description
In HarmonyOS wearable devices, when drawing a MapCircle on a map, the application must handle dynamic location changes. Specifically, if the device location changes, the MapCircle should be recreated at the new location to reflect the updated position accurately. The previous MapCircle instance should be removed or invalidated before drawing the new one to avoid overlapping or outdated visual representation.
The system should ensure:
- Real-time updates of the
MapCirclewhenever the device location changes. - Smooth removal of the previous
MapCircleto maintain map clarity. - Efficient resource management to prevent performance degradation due to frequent redraws.
- Compatibility with both GNSS-based and alternative location sources (e.g., Wi-Fi, paired smartphone).
This requirement ensures that the geospatial representation on the map always accurately reflects the user’s current location, enhancing usability and situational awareness.
Background Knowledge
In HarmonyOS, developers can use MapKit to draw and manage map elements, including MapCircle. A MapCircle represents a circular area on the map, which can be used for geofencing, highlighting regions, or visualizing proximity.
Using MapKit, it is possible to not only draw a MapCircle but also remove or update it dynamically. When the device location changes, the previous MapCircle can be removed and a new one can be drawn at the updated location, ensuring that the visual representation on the map always corresponds to the user’s current position.
Additionally, LocationKit provides real-time location updates from various sources such as GNSS, Wi-Fi, or a paired smartphone. By combining MapKit and LocationKit, developers can implement dynamic map behavior where MapCircle elements are continuously synchronized with the device’s location, providing accurate and up-to-date geospatial feedback to the user.
This approach is essential for applications that rely on location-aware interactions, such as wearable geofencing, navigation, or context-based alerts.
Implementation Steps
-
Initialize Map Options and Controller
- Retrieve map parameters from the router and store them in
mapOptions. - Initialize the map controller and event manager through
MapKit. - Enable location display and user controls on the map.
- Retrieve map parameters from the router and store them in
-
Draw Initial MapCircle
- Create initial
MapCircleusing themapOptionscenter coordinates. - Set properties such as
radius,fillColor,strokeColor,strokeWidth,clickable,visible, andzIndex. - Add the circle to the map using
mapController.addCircle().
- Create initial
-
Set Up Location Change Callback
- Register a callback with
geoLocationManagerthat triggers whenever the device location changes. - Update the
currentLocationstate with the new location. - Call
centerMapOnLocation(location)to animate the map camera to the new location. - Call
updateCirclePosition(location)to recreate theMapCircleat the updated position.
- Register a callback with
-
Center Map on Device Location
- Define a camera position with
latitude,longitude,zoom,tilt, andbearing. - Use
mapController.animateCamera()to smoothly move the map to the updated location.
- Define a camera position with
-
Remove and Redraw MapCircle on Location Change
- In
updateCirclePosition(location), first check if a previousMapCircleexists. - Remove the previous circle using
this.mapCircle.remove(). - Create a new
MapCirclewith the updated location coordinates. - Set the visual properties (
radius,fillColor,strokeColor, etc.) for the new circle. - Add the new circle to the map and update the
mapCirclereference.
- In
-
Start Continuous Location Updates
- Call
geoLocationManager.on('locationChange', locationRequest, locationChangeCallback)to receive ongoing location updates. - Ensure location updates are accurately reflected in real-time on the map.
- Call
-
Clean Up on Component Disappear
- When the component is about to disappear, unregister the location change callback using
geoLocationManager.off(). - This prevents memory leaks and unnecessary background location updates.
- When the component is about to disappear, unregister the location change callback using
-
Render Map Component
- Use the
MapComponentwithin aStacklayout. - Pass the
mapOptionsand thecallbackto initialize the map correctly. - Ensure the map occupies full width and height.
- Use the
Code Snippet / Configuration
1. Imports
import { MapComponent, mapCommon, map } from '@kit.MapKit';
import { AsyncCallback} from '@kit.BasicServicesKit';
import { router } from '@kit.ArkUI';
import { geoLocationManager } from '@kit.LocationKit';
Explanation:
-
MapKitis used for map rendering and map elements likeMapCircle. -
AsyncCallbackhandles asynchronous map initialization events. -
routerretrieves page parameters. -
geoLocationManagerprovides real-time location updates.
2. Component State & Variables
private mapOptions: mapCommon.MapOptions | null = null;
private callback?: AsyncCallback<map.MapComponentController>;
private mapController?: map.MapComponentController;
private mapEventManager?: map.MapEventManager;
@State currentLocation: geoLocationManager.Location | null = null;
private locationRequest: geoLocationManager.LocationRequest = {
priority: geoLocationManager.LocationRequestPriority.ACCURACY,
timeInterval: 0,
distanceInterval: 0,
maxAccuracy: 0
};
private locationChangeCallback?: (location: geoLocationManager.Location) => void;
private mapCircle?: map.MapCircle;
Explanation:
-
mapOptionsstores initial map parameters. -
mapControllerandmapEventManagerhandle map operations and events. -
currentLocationholds the device's current position. -
locationRequestdefines location update parameters. -
mapCirclerepresents the circle drawn on the map.
3. Component Lifecycle: aboutToAppear
aboutToAppear(): void {
const params = router.getParams() as mapCommon.MapOptions
if(params) {
this.mapOptions = params
}
this.locationChangeCallback = (location: geoLocationManager.Location) => {
this.currentLocation = location;
this.centerMapOnLocation(location);
this.updateCirclePosition(location);
};
this.callback = async (err, mapController) => {
if (!err) {
this.mapController = mapController;
this.mapEventManager = this.mapController.getEventManager();
this.mapController.setMyLocationEnabled(true);
this.mapController.setMyLocationControlsEnabled(true);
let mapCircleOptions: mapCommon.MapCircleOptions = {
center: {
latitude: this.mapOptions!.position.target.latitude,
longitude: this.mapOptions!.position.target.longitude
},
radius: 100,
clickable: true,
fillColor: 0xFFFFC100,
strokeColor: 0xFFFF0000,
strokeWidth: 10,
visible: true,
zIndex: 5
}
this.mapCircle = await this.mapController.addCircle(mapCircleOptions);
this.startLocationUpdates();
let callback = () => {
if (this.currentLocation) {
this.centerMapOnLocation(this.currentLocation);
}
}
this.mapEventManager.on("mapLoad", callback);
} else {
console.error(`Failed to initialize the map. Code: ${err.code}; message: ${err.message}`);
}
};
}
Explanation:
- Before the component appears, map parameters are retrieved.
-
locationChangeCallbackupdates the camera and recreates theMapCirclewhenever the device location changes. - Initial
MapCircleis drawn and location updates are started. - This step is critical for MapCircle recreation and dynamic updates.
4. Center Map on Location
private centerMapOnLocation(location: geoLocationManager.Location) {
if (this.mapController) {
const cameraPosition: mapCommon.CameraPosition = {
target: {
latitude: location.latitude,
longitude: location.longitude,
},
zoom: 15,
tilt: 0,
bearing: 0
};
let cameraUpdate = map.newCameraPosition(cameraPosition);
this.mapController.animateCamera(cameraUpdate, 1000);
}
}
Explanation:
- Moves the map camera to focus on the device's current location.
- Ensures the
MapCircleremains visible in the correct area.
5. Recreation of MapCircle
private async updateCirclePosition(location: geoLocationManager.Location) {
if(this.mapController) {
if (this.mapCircle) {
this.mapCircle.remove();
}
let mapCircleOptions: mapCommon.MapCircleOptions = {
center: {
latitude: location.latitude,
longitude: location.longitude
},
radius: 100,
clickable: true,
fillColor: 0xFFFFC100,
strokeColor: 0xFFFF0000,
strokeWidth: 10,
visible: true,
zIndex: 15
}
this.mapCircle = await this.mapController.addCircle(mapCircleOptions);
}
}
Explanation:
-
Critical part: This method recreates the
MapCircleevery time the device location changes. - The previous circle is removed to prevent overlapping or outdated visuals.
- A new circle is drawn at the updated location, ensuring the map always reflects the current position accurately.
6. Start Location Updates
private startLocationUpdates() {
try {
geoLocationManager.on('locationChange', this.locationRequest, this.locationChangeCallback!);
} catch (error) {
console.error('Location updates error:', error);
}
}
Explanation:
- Subscribes to real-time location updates.
- Ensures
updateCirclePositionis called whenever the device moves.
7. Cleanup on Component Disappear
aboutToDisappear(): void {
if (this.locationChangeCallback) {
geoLocationManager.off('locationChange', this.locationChangeCallback);
}
}
Explanation:
- Unsubscribes from location updates when the component is closed.
- Prevents memory leaks and unnecessary background location processing.
8. Build Map Component
build() {
Stack() {
MapComponent({ mapOptions: this.mapOptions!, mapCallback: this.callback }).width('100%').height('100%');
}.height('100%')
}
Explanation:
- Renders the map component in a full-screen stack layout.
Test Results
Here you can find the related screenshots belong to demo below;
Limitations or Considerations
- The technologies and APIs used in this implementation only work on real HarmonyOS wearable devices. Emulators may not provide accurate location updates.
- Frequent recreation of
MapCirclecan lead to performance overhead, especially if the location changes rapidly. Optimization may be needed to avoid UI lag. - The
MapCirclerelies on location accuracy provided bygeoLocationManager. If the device location is inaccurate, the circle may not be positioned correctly. - Network conditions or GPS availability can affect real-time updates; offline or low-signal environments may result in delayed or skipped updates.
- Customization of
MapCircle(e.g., radius, colors, z-index) must be handled carefully to maintain visual consistency when recreating circles repeatedly.
Related Documents or Links
https://developer.huawei.com/consumer/en/doc/harmonyos-guides/map-kit-guide
https://developer.huawei.com/consumer/en/doc/harmonyos-guides/map-circle
https://developer.huawei.com/consumer/en/doc/harmonyos-guides/location-guidelines


Top comments (0)