It seems to be a common problem among users who use Naver API.
For the same reason, there is a case where someone contacted the Naver Developer Forum and received a solution from Naver.
In summary, Draw markers dynamically only in the area you are looking at, so you can refer to the link for more information.
I wrote it as concisely as possible with the intention of just understanding the feeling.
This is an example of taking 40,000 virtual markers at 1-kilometer intervals and dynamically displaying markers within a 3-kilometer radius of the viewing position.
I wrote it based on the Naver Cloud Platform API recommended by Naver.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
android:name="com.naver.maps.map.MapFragment" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package com.learn.navercloudapis;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import com.naver.maps.geometry.LatLng;
import com.naver.maps.map.CameraPosition;
import com.naver.maps.map.CameraUpdate;
import com.naver.maps.map.MapFragment;
import com.naver.maps.map.NaverMap;
import com.naver.maps.map.OnMapReadyCallback;
import com.naver.maps.map.overlay.Marker;
import java.util.Vector;
public class MainActivity extends FragmentActivity implements OnMapReadyCallback {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
MapFragment mapFragment = (MapFragment)fm.findFragmentById(R.id.map);
if (mapFragment == null) {
mapFragment = MapFragment.newInstance();
fm.beginTransaction().add(R.id.map, mapFragment).commit();
}
mapFragment.getMapAsync(this);
}
@UiThread
@Override
public void onMapReady(@NonNull final NaverMap naverMap) {
// Set camera initial position
LatLng initialPosition = new LatLng(37.506855, 127.066242);
CameraUpdate cameraUpdate = CameraUpdate.scrollTo(initialPosition);
naverMap.moveCamera(cameraUpdate);
// Defining the markers' positions (approximately 10,000 in the east, west, north, south, and south directions at intervals of 1 km, total)
markersPosition = new Vector<LatLng>();
for (int x = 0; x < 100; ++x) {
for (int y = 0; y < 100; ++y) {
markersPosition.add(new LatLng(
initialPosition.latitude - (REFERANCE_LAT * x),
initialPosition.longitude + (REFERANCE_LNG * y)
));
markersPosition.add(new LatLng(
initialPosition.latitude + (REFERANCE_LAT * x),
initialPosition.longitude - (REFERANCE_LNG * y)
));
markersPosition.add(new LatLng(
initialPosition.latitude + (REFERANCE_LAT * x),
initialPosition.longitude + (REFERANCE_LNG * y)
));
markersPosition.add(new LatLng(
initialPosition.latitude - (REFERANCE_LAT * x),
initialPosition.longitude - (REFERANCE_LNG * y)
));
}
}
// Events called when the camera is moved
naverMap.addOnCameraChangeListener(new NaverMap.OnCameraChangeListener() {
@Override
public void onCameraChange(int reason, boolean animated) {
freeActiveMarkers();
// Only those within the visible distance of the defined marker positions are created
LatLng currentPosition = getCurrentPosition(naverMap);
for (LatLng markerPosition: markersPosition) {
if (!withinSightMarker(currentPosition, markerPosition))
continue;
Marker marker = new Marker();
marker.setPosition(markerPosition);
marker.setMap(naverMap);
activeMarkers.add(marker);
}
}
});
}
// Declare variables to store marker information
private Vector<LatLng> markersPosition;
private Vector<Marker> activeMarkers;
// Where is the camera currently looking at?
public LatLng getCurrentPosition(NaverMap naverMap) {
CameraPosition cameraPosition = naverMap.getCameraPosition();
return new LatLng(cameraPosition.target.latitude, cameraPosition.target.longitude);
}
// Ensure that the position of the selected marker is within the viewing distance (within a 3 km radius of the position the camera is looking at)
public final static double REFERANCE_LAT = 1 / 109.958489129649955;
public final static double REFERANCE_LNG = 1 / 88.74;
public final static double REFERANCE_LAT_X3 = 3 / 109.958489129649955;
public final static double REFERANCE_LNG_X3 = 3 / 88.74;
public boolean withinSightMarker(LatLng currentPosition, LatLng markerPosition) {
boolean withinSightMarkerLat = Math.abs(currentPosition.latitude - markerPosition.latitude) <= REFERANCE_LAT_X3;
boolean withinSightMarkerLng = Math.abs(currentPosition.longitude - markerPosition.longitude) <= REFERANCE_LNG_X3;
return withinSightMarkerLat && withinSightMarkerLng;
}
// Markers displayed on the map Delete from the map
private void freeActiveMarkers() {
if (activeMarkers == null) {
activeMarkers = new Vector<Marker>();
return;
}
for (Marker activeMarker: activeMarkers) {
activeMarker.setMap(null);
}
activeMarkers = new Vector<Marker>();
}
}
Based on the Galaxy Note 10, it has been confirmed that there is no hesitation.
In addition, as you can see by reading the code carefully, turns the loop 40,000 times to find the marker within the visible distance whenever a camera movement event occurs.
It is necessary to reduce the number of loops through optimization tasks such as using specific algorithms.
I thought this would be enough for you to solve, so I left it as part of it.
Also, I don't usually use Java a lot, so the code may not fit some Conventions.
Please understand this part generously.
© 2024 OneMinuteCode. All rights reserved.