Skip to content

Commit 31cbeef

Browse files
committed
fix: map bound ref
1 parent 8cb6eaf commit 31cbeef

File tree

4 files changed

+310
-10
lines changed

4 files changed

+310
-10
lines changed
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
package com.osmdroid;
2+
3+
import android.app.Activity;
4+
5+
import com.facebook.react.bridge.Promise;
6+
import com.facebook.react.bridge.ReactApplicationContext;
7+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
8+
import com.facebook.react.bridge.ReactMethod;
9+
import com.facebook.react.bridge.WritableMap;
10+
import com.facebook.react.bridge.WritableNativeMap;
11+
import com.facebook.react.module.annotations.ReactModule;
12+
import com.facebook.react.uimanager.NativeViewHierarchyManager;
13+
import com.facebook.react.uimanager.UIBlock;
14+
import com.facebook.react.uimanager.UIManagerModule;
15+
16+
17+
import java.io.Closeable;
18+
import java.io.IOException;
19+
20+
import java.util.Map;
21+
import java.util.HashMap;
22+
23+
@ReactModule(name = OsmMapModule.NAME)
24+
public class OsmMapModule extends ReactContextBaseJavaModule {
25+
26+
public static final String NAME = "OsmMapModule";
27+
private static final String SNAPSHOT_RESULT_FILE = "file";
28+
private static final String SNAPSHOT_RESULT_BASE64 = "base64";
29+
private static final String SNAPSHOT_FORMAT_PNG = "png";
30+
private static final String SNAPSHOT_FORMAT_JPG = "jpg";
31+
32+
public OsmMapModule(ReactApplicationContext reactContext) {
33+
super(reactContext);
34+
}
35+
36+
@Override
37+
public String getName() {
38+
return NAME;
39+
}
40+
41+
@Override
42+
public Map<String, Object> getConstants() {
43+
final Map<String, Object> constants = new HashMap<>();
44+
constants.put("legalNotice", "This license information is displayed in Settings > Google > Open Source on any device running Google Play services.");
45+
return constants;
46+
}
47+
48+
public Activity getActivity() {
49+
return getCurrentActivity();
50+
}
51+
52+
public static void closeQuietly(Closeable closeable) {
53+
if (closeable == null) return;
54+
try {
55+
closeable.close();
56+
} catch (IOException ignored) {
57+
}
58+
}
59+
60+
// @ReactMethod
61+
// public void takeSnapshot(final int tag, final ReadableMap options, final Promise promise) {
62+
//
63+
// // Parse and verity options
64+
// final ReactApplicationContext context = getReactApplicationContext();
65+
// final String format = options.hasKey("format") ? options.getString("format") : "png";
66+
// final Bitmap.CompressFormat compressFormat =
67+
// format.equals(SNAPSHOT_FORMAT_PNG) ? Bitmap.CompressFormat.PNG :
68+
// format.equals(SNAPSHOT_FORMAT_JPG) ? Bitmap.CompressFormat.JPEG : null;
69+
// final double quality = options.hasKey("quality") ? options.getDouble("quality") : 1.0;
70+
// final DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
71+
// final Integer width =
72+
// options.hasKey("width") ? (int) (displayMetrics.density * options.getDouble("width")) : 0;
73+
// final Integer height =
74+
// options.hasKey("height") ? (int) (displayMetrics.density * options.getDouble("height")) : 0;
75+
// final String result = options.hasKey("result") ? options.getString("result") : "file";
76+
//
77+
// // Add UI-block so we can get a valid reference to the map-view
78+
// UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class);
79+
// uiManager.addUIBlock(new UIBlock() {
80+
// public void execute(NativeViewHierarchyManager nvhm) {
81+
// OsmMapView view = (OsmMapView) nvhm.resolveView(tag);
82+
// if (view == null) {
83+
// promise.reject("AirMapView not found");
84+
// return;
85+
// }
86+
// if (view.map == null) {
87+
// promise.reject("AirMapView.map is not valid");
88+
// return;
89+
// }
90+
// view.map.snapshot(new GoogleMap.SnapshotReadyCallback() {
91+
// public void onSnapshotReady(@Nullable Bitmap snapshot) {
92+
//
93+
// // Convert image to requested width/height if necessary
94+
// if (snapshot == null) {
95+
// promise.reject("Failed to generate bitmap, snapshot = null");
96+
// return;
97+
// }
98+
// if ((width != 0) && (height != 0) &&
99+
// (width != snapshot.getWidth() || height != snapshot.getHeight())) {
100+
// snapshot = Bitmap.createScaledBitmap(snapshot, width, height, true);
101+
// }
102+
//
103+
// // Save the snapshot to disk
104+
// if (result.equals(SNAPSHOT_RESULT_FILE)) {
105+
// File tempFile;
106+
// FileOutputStream outputStream;
107+
// try {
108+
// tempFile =
109+
// File.createTempFile("AirMapSnapshot", "." + format, context.getCacheDir());
110+
// outputStream = new FileOutputStream(tempFile);
111+
// } catch (Exception e) {
112+
// promise.reject(e);
113+
// return;
114+
// }
115+
// snapshot.compress(compressFormat, (int) (100.0 * quality), outputStream);
116+
// closeQuietly(outputStream);
117+
// String uri = Uri.fromFile(tempFile).toString();
118+
// promise.resolve(uri);
119+
// } else if (result.equals(SNAPSHOT_RESULT_BASE64)) {
120+
// ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
121+
// snapshot.compress(compressFormat, (int) (100.0 * quality), outputStream);
122+
// closeQuietly(outputStream);
123+
// byte[] bytes = outputStream.toByteArray();
124+
// String data = Base64.encodeToString(bytes, Base64.NO_WRAP);
125+
// promise.resolve(data);
126+
// }
127+
// }
128+
// });
129+
// }
130+
// });
131+
// }
132+
133+
// @ReactMethod
134+
// public void getCamera(final int tag, final Promise promise) {
135+
// final ReactApplicationContext context = getReactApplicationContext();
136+
//
137+
// UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class);
138+
// uiManager.addUIBlock(new UIBlock()
139+
// {
140+
// @Override
141+
// public void execute(NativeViewHierarchyManager nvhm)
142+
// {
143+
// OsmMapView view = (OsmMapView) nvhm.resolveView(tag);
144+
// if (view == null) {
145+
// promise.reject("AirMapView not found");
146+
// return;
147+
// }
148+
//
149+
//
150+
// CameraPosition position = view.map.getCameraPosition();
151+
//
152+
// WritableMap centerJson = new WritableNativeMap();
153+
// centerJson.putDouble("latitude", position.target.latitude);
154+
// centerJson.putDouble("longitude", position.target.longitude);
155+
//
156+
// WritableMap cameraJson = new WritableNativeMap();
157+
// cameraJson.putMap("center", centerJson);
158+
// cameraJson.putDouble("heading", (double)position.bearing);
159+
// cameraJson.putDouble("zoom", (double)position.zoom);
160+
// cameraJson.putDouble("pitch", (double)position.tilt);
161+
//
162+
// promise.resolve(cameraJson);
163+
// }
164+
// });
165+
// }
166+
167+
// @ReactMethod
168+
// public void pointForCoordinate(final int tag, ReadableMap coordinate, final Promise promise) {
169+
// final ReactApplicationContext context = getReactApplicationContext();
170+
// final double density = (double) context.getResources().getDisplayMetrics().density;
171+
//
172+
// final LatLng coord = new LatLng(
173+
// coordinate.hasKey("latitude") ? coordinate.getDouble("latitude") : 0.0,
174+
// coordinate.hasKey("longitude") ? coordinate.getDouble("longitude") : 0.0
175+
// );
176+
//
177+
// UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class);
178+
// uiManager.addUIBlock(new UIBlock()
179+
// {
180+
// @Override
181+
// public void execute(NativeViewHierarchyManager nvhm)
182+
// {
183+
// AirMapView view = (AirMapView) nvhm.resolveView(tag);
184+
// if (view == null) {
185+
// promise.reject("AirMapView not found");
186+
// return;
187+
// }
188+
// if (view.map == null) {
189+
// promise.reject("AirMapView.map is not valid");
190+
// return;
191+
// }
192+
//
193+
// Point pt = view.map.getProjection().toScreenLocation(coord);
194+
//
195+
// WritableMap ptJson = new WritableNativeMap();
196+
// ptJson.putDouble("x", (double)pt.x / density);
197+
// ptJson.putDouble("y", (double)pt.y / density);
198+
//
199+
// promise.resolve(ptJson);
200+
// }
201+
// });
202+
// }
203+
204+
// @ReactMethod
205+
// public void coordinateForPoint(final int tag, ReadableMap point, final Promise promise) {
206+
// final ReactApplicationContext context = getReactApplicationContext();
207+
// final double density = (double) context.getResources().getDisplayMetrics().density;
208+
//
209+
// final Point pt = new Point(
210+
// point.hasKey("x") ? (int)(point.getDouble("x") * density) : 0,
211+
// point.hasKey("y") ? (int)(point.getDouble("y") * density) : 0
212+
// );
213+
//
214+
// UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class);
215+
// uiManager.addUIBlock(new UIBlock()
216+
// {
217+
// @Override
218+
// public void execute(NativeViewHierarchyManager nvhm)
219+
// {
220+
// AirMapView view = (AirMapView) nvhm.resolveView(tag);
221+
// if (view == null)
222+
// {
223+
// promise.reject("AirMapView not found");
224+
// return;
225+
// }
226+
// if (view.map == null)
227+
// {
228+
// promise.reject("AirMapView.map is not valid");
229+
// return;
230+
// }
231+
//
232+
// LatLng coord = view.map.getProjection().fromScreenLocation(pt);
233+
//
234+
// WritableMap coordJson = new WritableNativeMap();
235+
// coordJson.putDouble("latitude", coord.latitude);
236+
// coordJson.putDouble("longitude", coord.longitude);
237+
//
238+
// promise.resolve(coordJson);
239+
// }
240+
// });
241+
// }
242+
243+
@ReactMethod
244+
public void getMapBoundaries(final int tag, final Promise promise) {
245+
final ReactApplicationContext context = getReactApplicationContext();
246+
247+
UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class);
248+
uiManager.addUIBlock(new UIBlock()
249+
{
250+
@Override
251+
public void execute(NativeViewHierarchyManager nvhm)
252+
{
253+
OsmMapView view = (OsmMapView) nvhm.resolveView(tag);
254+
if (view == null) {
255+
promise.reject("AirMapView not found");
256+
return;
257+
}
258+
259+
double[][] boundaries = view.getMapBoundaries();
260+
261+
WritableMap coordinates = new WritableNativeMap();
262+
WritableMap northEastHash = new WritableNativeMap();
263+
WritableMap southWestHash = new WritableNativeMap();
264+
265+
northEastHash.putDouble("longitude", boundaries[0][0]);
266+
northEastHash.putDouble("latitude", boundaries[0][1]);
267+
southWestHash.putDouble("longitude", boundaries[1][0]);
268+
southWestHash.putDouble("latitude", boundaries[1][1]);
269+
270+
coordinates.putMap("northEast", northEastHash);
271+
coordinates.putMap("southWest", southWestHash);
272+
273+
promise.resolve(coordinates);
274+
}
275+
});
276+
}
277+
}

android/src/main/java/com/osmdroid/OsmMapView.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,16 @@ public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePad
516516
}
517517
}
518518

519+
public double[][] getMapBoundaries() {
520+
OsmMapView mapView = OsmMapView.this;
521+
BoundingBox bounds = mapView.getBoundingBox();
522+
523+
return new double[][] {
524+
{bounds.getLonEast(), bounds.getLatNorth()},
525+
{bounds.getLonWest(), bounds.getLatSouth()}
526+
};
527+
}
528+
519529
@Override
520530
public boolean dispatchTouchEvent(MotionEvent ev) {
521531
scaleDetector.onTouchEvent(ev);

example/src/App.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,24 @@ export default function App() {
2020
};
2121
const toner =
2222
'https://api.maptiler.com/maps/toner-v2/{z}/{x}/{y}.png?key=j46yoHMlBMQRgTY3lCMk';
23+
const mapRef = React.useRef<MapView>();
2324

2425
return (
25-
<MapView
26-
onRegionChange={(region) => {
27-
console.log('🚀 ~ file: App.tsx:88 ~ App ~ region', region);
26+
<MapView.Animated
27+
ref={mapRef}
28+
onMapReady={async () => {
29+
// const mapBoundaries = await mapRef.current?.getMapBoundaries();
30+
// console.log(
31+
// '🚀 ~ file: App.tsx:30 ~ onMapReady={ ~ mapBoundaries',
32+
// mapBoundaries
33+
// );
34+
}}
35+
onRegionChangeComplete={async () => {
36+
// const mapBoundaries = await mapRef.current?.getMapBoundaries();
37+
// console.log(
38+
// '🚀 ~ file: App.tsx:30 ~ onMapReady={ ~ mapBoundaries',
39+
// mapBoundaries
40+
// );
2841
}}
2942
style={styles.container}
3043
initialRegion={initialRegion}
@@ -86,7 +99,7 @@ export default function App() {
8699
radius={40}
87100
/>
88101
<UrlTile shouldReplaceMapContent={true} urlTemplate={toner} />
89-
</MapView>
102+
</MapView.Animated>
90103
);
91104
}
92105

src/MapView.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ class MapView extends React.Component<MapViewProps> {
736736

737737
getCamera(): Promise<Camera> {
738738
if (Platform.OS === 'android') {
739-
return NativeModules.AirMapModule.getCamera(this._getHandle());
739+
return NativeModules.OsmMapModule.getCamera(this._getHandle());
740740
} else if (Platform.OS === 'ios') {
741741
return this._runCommand('getCamera', []);
742742
}
@@ -815,7 +815,7 @@ class MapView extends React.Component<MapViewProps> {
815815
*/
816816
async getMapBoundaries(): Promise<BoundingBox> {
817817
if (Platform.OS === 'android') {
818-
return await NativeModules.AirMapModule.getMapBoundaries(
818+
return await NativeModules.OsmMapModule.getMapBoundaries(
819819
this._getHandle()
820820
);
821821
} else if (Platform.OS === 'ios') {
@@ -869,7 +869,7 @@ class MapView extends React.Component<MapViewProps> {
869869

870870
// Call native function
871871
if (Platform.OS === 'android') {
872-
return NativeModules.AirMapModule.takeSnapshot(this._getHandle(), config);
872+
return NativeModules.OsmMapModule.takeSnapshot(this._getHandle(), config);
873873
} else if (Platform.OS === 'ios') {
874874
return new Promise((resolve, reject) => {
875875
this._runCommand('takeSnapshot', [
@@ -903,7 +903,7 @@ class MapView extends React.Component<MapViewProps> {
903903
*/
904904
addressForCoordinate(coordinate: LatLng): Promise<Address> {
905905
if (Platform.OS === 'android') {
906-
return NativeModules.AirMapModule.getAddressFromCoordinates(
906+
return NativeModules.OsmMapModule.getAddressFromCoordinates(
907907
this._getHandle(),
908908
coordinate
909909
);
@@ -924,7 +924,7 @@ class MapView extends React.Component<MapViewProps> {
924924
*/
925925
pointForCoordinate(coordinate: LatLng): Promise<Point> {
926926
if (Platform.OS === 'android') {
927-
return NativeModules.AirMapModule.pointForCoordinate(
927+
return NativeModules.OsmMapModule.pointForCoordinate(
928928
this._getHandle(),
929929
coordinate
930930
);
@@ -945,7 +945,7 @@ class MapView extends React.Component<MapViewProps> {
945945
*/
946946
coordinateForPoint(point: Point): Promise<LatLng> {
947947
if (Platform.OS === 'android') {
948-
return NativeModules.AirMapModule.coordinateForPoint(
948+
return NativeModules.OsmMapModule.coordinateForPoint(
949949
this._getHandle(),
950950
point
951951
);

0 commit comments

Comments
 (0)