onPress/onLongPress `position` is in device pixels on Android, points on iOS

Author: ivan-kolesovCreated Sep 12, 2026Updated Sep 12, 2026

Summary

Map events that carry a position (onPress, onLongPress, onPanDrag, onPoiClick, marker presses) report it in device pixels on Android and in UIKit points on iOS. Anything an app positions from that value — a context menu, a tooltip, a custom callout — therefore lands PixelRatio.get() times too far right and down on Android. On a 420 dpi device that is 2.625x, which is usually far enough to leave the screen.

docs/mapview.md documents these props as { coordinate: LatLng, position: Point } without stating a unit, so there is nothing that says which platform is right — but the two disagree, and the library itself is not consistent either: MapModule.pointForCoordinate() divides by the display density before resolving its promise, so the two ways of getting a frame point out of the same map answer in different units.

Version

react-native-maps 1.27.2, also present on master (1.29.0) and on beta.

Steps to reproduce

  1. Render a MapView with provider={PROVIDER_GOOGLE} on an Android device whose density is not 1.
  2. In onLongPress, store nativeEvent.position and absolutely position a small view at that {x, y}.
  3. Long-press somewhere near the middle of the map.

Expected: the view appears under the finger, as it does on iOS. Actual: it appears at position * density — down and to the right, usually clamped at the edge of the screen.

Cause

MapView.makeClickEventData() puts projection.toScreenLocation(point) into the event as is:

java
Projection projection = map.getProjection();
Point screenPoint = projection.toScreenLocation(point);

WritableMap position = new WritableNativeMap();
position.putDouble("x", screenPoint.x);
position.putDouble("y", screenPoint.y);

toScreenLocation() answers in device pixels. MapModule.pointForCoordinate(), a few files over, divides the very same call by getResources().getDisplayMetrics().density. On iOS the same events carry locationInView: results, which are already points.

Suggested fix

Divide by the display density in makeClickEventData(), the way pointForCoordinate() already does. PR follows.

Source: react-native-maps/react-native-maps