User Symbols & Images
Two ways to overlay application data (vessel positions, tracks, rendezvous points, event markers) on a loaded chart.
When to use which
Section titled “When to use which”| API group | Use case | Rotation | Scaling |
|---|---|---|---|
| UserImage | one-off PNG markers | × | × |
| Usersymbol | reusable symbol library | ✓ | ✓ |
| Userobj | persistent symbol layer | ✓ | ✓ |
1. UserImage: quick PNG markers
Section titled “1. UserImage: quick PNG markers”The simplest case. Draw a PNG at a specific lat/lon.
// At init - create the image handle onceint markerHandle = hencUserImageNew("assets/ship-marker.png");if (markerHandle < 0) { fprintf(stderr, "marker image load failed\n");}
// Per frame - when the vessel movesvoid onTick(int view, double shipLon, double shipLat) { hencRender(view); hencUserImageDrawAtMapPos(view, markerHandle, shipLon, shipLat); hencSwapBuffer(view);}
// At shutdownhencUserImageDelete(markerHandle);2. Usersymbol: rotatable vessel icons
Section titled “2. Usersymbol: rotatable vessel icons”When you need to display many vessels each with their own heading.
// 1. Init the symbol store (once)hencUsersymbolInit();
// 2. Register an image as a named symbolint shipSymbolId = hencUsersymbolAddNewImage( "SHIP_ICON", "assets/ship-icon.png", 32, 32 // base size (px));
// 3. Add a symbol instance to the map - lat/lon, rotation (deg), scalehencUsersymbolAddToMap( view, shipSymbolId, 129.42, 35.10, 45.0, // heading (deg clockwise from north) 1.0 // scale);
// 4. Symbols are rendered automatically per framehencRender(view);hencSwapBuffer(view);
// 5. Cleanup at shutdownhencUsersymbolClear();3. Userobj: persistent track layer
Section titled “3. Userobj: persistent track layer”Bundle symbols as a “user object layer” for batch show/hide/delete.
int trackObjId = -1;
void onPositionUpdate(int view, double lon, double lat) { if (trackObjId < 0) { trackObjId = hencUserobjAdd(view, "TRACK_VESSEL_001"); }
// Append point/symbol to this object (see API reference for details)}
// At shutdown or on user "clear track"hencUserobjDel(view, trackObjId);Common pitfalls
Section titled “Common pitfalls”- Image invisible: PNG is not 32-bit RGBA, or path is wrong relative to the working dir. Try an absolute path.
- Heading goes the wrong way: heading is clockwise (N→E→S→W) in degrees, matching navigation convention.
- Symbol scale is wrong at high/low zoom: tweak
hencSetSymbolScaleorhencSetAutoScaleToZoom.
Related API
Section titled “Related API”- Image: hencUserImageNew / hencUserImageDrawAtMapPos / hencUserImageDelete
- Symbol: hencUsersymbolInit / hencUsersymbolAddNewImage / hencUsersymbolAddToMap
- Object layer: hencUserobjAdd / hencUserobjDel / hencUserobjGet
- Scaling: hencSetSymbolScale / hencSetAutoScaleToZoom