12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301 |
- package com.tsi.navi.activity;
- import android.Manifest;
- import android.annotation.SuppressLint;
- import android.content.BroadcastReceiver;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.content.ServiceConnection;
- import android.content.res.Configuration;
- import android.graphics.PointF;
- import android.graphics.Rect;
- import android.location.Location;
- import android.os.Build;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.util.Log;
- import android.view.MenuInflater;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.WindowManager;
- import android.widget.ImageView;
- import android.widget.PopupMenu;
- import android.widget.TextView;
- import android.widget.Toast;
- import androidx.annotation.NonNull;
- import androidx.annotation.RequiresApi;
- import androidx.annotation.UiThread;
- import androidx.appcompat.app.AppCompatActivity;
- import androidx.core.app.ActivityCompat;
- import androidx.fragment.app.FragmentManager;
- import androidx.fragment.app.FragmentTransaction;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.naver.maps.geometry.LatLng;
- import com.naver.maps.geometry.LatLngBounds;
- import com.naver.maps.map.CameraPosition;
- import com.naver.maps.map.CameraUpdate;
- import com.naver.maps.map.CameraUpdateParams;
- import com.naver.maps.map.LocationTrackingMode;
- import com.naver.maps.map.MapFragment;
- import com.naver.maps.map.NaverMap;
- import com.naver.maps.map.NaverMapOptions;
- import com.naver.maps.map.NaverMapSdk;
- import com.naver.maps.map.OnMapReadyCallback;
- import com.naver.maps.map.overlay.Align;
- import com.naver.maps.map.overlay.InfoWindow;
- import com.naver.maps.map.overlay.Marker;
- import com.naver.maps.map.overlay.OverlayImage;
- import com.naver.maps.map.util.FusedLocationSource;
- import com.tsi.navi.R;
- import com.tsi.navi.TsiNaviApplication;
- import com.tsi.navi.activity.dialog.AppInformationDialog;
- import com.tsi.navi.activity.dialog.IDialogClickListener;
- import com.tsi.navi.activity.dialog.MapSettingDialog;
- import com.tsi.navi.activity.dialog.NodeCrossDialog;
- import com.tsi.navi.activity.fragment.AreaCrossFragment;
- import com.tsi.navi.activity.fragment.DirectionNaviSignalFragment;
- import com.tsi.navi.activity.fragment.DirectionSignalFragment;
- import com.tsi.navi.activity.fragment.UserSignalFragment;
- import com.tsi.navi.activity.model.NodeCrossItem;
- import com.tsi.navi.database.DbQuery;
- import com.tsi.navi.databinding.ActivityMainBinding;
- import com.tsi.navi.dto.CpuNodeStatusDTO;
- import com.tsi.navi.preferences.PrefManager;
- import com.tsi.navi.util.BackPressedForFinish;
- import com.tsi.navi.util.BoundaryUtils;
- import com.tsi.navi.util.CameraInfo;
- import com.tsi.navi.util.TsiUtils;
- import com.tsi.navi.vo.NodeVo;
- import com.tsi.navi.vo.TsiGpsTrackingVo;
- import com.tsi.navi.websocket.NaviWebsocketClientService;
- import org.jetbrains.annotations.NotNull;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.Vector;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.atomic.AtomicBoolean;
- @RequiresApi(api = Build.VERSION_CODES.R)
- public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
- private static final String TAG = MainActivity.class.getSimpleName();
- private Context context;
- private BackPressedForFinish backPressedForFinish = null;
- private ActivityMainBinding binding = null;
- private NaverMap naverMap = null;
- private static final int LOCATION_PERMISSION_REQUEST_CODE = 1000;
- private final String[] permissions = {
- Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.ACCESS_COARSE_LOCATION
- };
- private FusedLocationSource locationSource;
- private boolean dispAllSignal = false;
- private boolean isTrackingMode = false;
- private boolean isDebugMode = false;
- private boolean dispCvibSignal = false;
- private double trackingZoom;
- private float currSpeed = 0;
- private float lastBearing = -1, currBearing = -1;
- private float moveDist = 0;
- private CameraInfo cameraInfo;
- private BoundaryUtils mapUtils;
- private float carX = 0;
- private float carY = 0;
- private double tilt = 45;
- private float trackingDistance = 5;
- private float driveDistance = 8;
- private TsiGpsTrackingVo gpsTracking;
- private Location lastLocation = null;
- private final float[] resultDistance = {-999, -999, -999};
- private String deviceId;
- private DbQuery dbQuery;
- private int overlayResourceId;
- private CameraUpdateParams cameraUpdateParams;
- private float width, height;
- private NodeVo selectedNode = null;
- private InfoWindow infoWindow;
- private Vector<Marker> activeMarkers;
- private ConcurrentHashMap<Long, NodeVo> activeNodes;
- //private TsiApiService tsiApiService;
- private FragmentManager fragmentManager;
- private DirectionSignalFragment directionSignalFragment;
- private DirectionNaviSignalFragment directionNaviSignalFragment;
- private UserSignalFragment userSignalFragment;
- private AreaCrossFragment areaCrossFragment;
- private String lastTopics;
- private NaviWebsocketClientService naviClientService;
- private final AtomicBoolean moveByGps = new AtomicBoolean(false);
- private final ServiceConnection serviceConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
- //private NaviWebsocketClient naviClient;
- NaviWebsocketClientService.NaviWebsocketClientBinder naviClientBinder = (NaviWebsocketClientService.NaviWebsocketClientBinder) iBinder;
- naviClientService = naviClientBinder.getService();
- //naviClient = naviClientService.getNaviWebsocketClient();
- Toast.makeText(context, "서버 통신 시작", Toast.LENGTH_SHORT).show();
- }
- @Override
- public void onServiceDisconnected(ComponentName componentName) {
- Toast.makeText(context, "서버 통신 연결 종료", Toast.LENGTH_SHORT).show();
- }
- };
- private class NaviWebsocketMessageListener extends BroadcastReceiver {
- ObjectMapper mapper = new ObjectMapper();
- @Override
- public void onReceive(Context context, Intent intent) {
- String message = intent.getStringExtra("message");
- try {
- if (message.contains("offline")) {
- List<String> requests = TsiUtils.split(message, ":");
- if (requests.size() == 2) {
- NodeVo node = TsiNaviApplication.getNodeMap().get(Long.parseLong(requests.get(0)));
- if (node != null) {
- Toast.makeText(context, node.getName() + " 는(은) 통신 OffLine 입니다.", Toast.LENGTH_SHORT).show();
- }
- }
- }
- else {
- CpuNodeStatusDTO status = this.mapper.readValue(message, CpuNodeStatusDTO.class);
- if (directionNaviSignalFragment.isVisible() && directionNaviSignalFragment.getNodeId() == status.getA()) {
- directionNaviSignalFragment.updateSignal(status);
- }
- if (directionSignalFragment.isVisible() && directionSignalFragment.getNodeId() == status.getA()) {
- directionSignalFragment.updateSignal(status);
- }
- if (userSignalFragment.isVisible() && userSignalFragment.getNodeId() == status.getA()) {
- userSignalFragment.updateSignal(status, 10);
- }
- }
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- }
- }
- }
- private void requestTopicMessage(String topic) {
- try {
- this.naviClientService.sendMsg("topics:" + topic);
- this.lastTopics = topic;
- if (topic.equalsIgnoreCase("x")) {
- this.lastTopics = ""; // 교차로 신호정보 요청 취소
- setSelectedNode(null);
- setRequestNode(null);
- if (this.userSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().hide(this.userSignalFragment).commit();
- }
- if (this.directionNaviSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().hide(this.directionNaviSignalFragment).commit();
- }
- if (this.directionSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().hide(this.directionSignalFragment).commit();
- }
- }
- } catch (Exception e) {
- Log.e(TAG, "Request topic error: " + e.getMessage());
- }
- }
- private class NaviWebsocketEventListener extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String event = intent.getStringExtra("event");
- //Log.e(TAG, "onEvent: " + event);
- if (event.equalsIgnoreCase("open")) {
- naviClientService.sendMsg("group:" + deviceId); // group id send
- if (!lastTopics.equals("")) {
- requestTopicMessage(lastTopics);
- }
- //Toast.makeText(context, "서버 통신 연결", Toast.LENGTH_SHORT).show();
- } else if (event.equalsIgnoreCase("close")) {
- Toast.makeText(context, "서버와 연결이 종료되었습니다.", Toast.LENGTH_SHORT).show();
- } else if (event.equalsIgnoreCase("error")) {
- Toast.makeText(context, "서버와 연결 중 오류가 발생했습니다.", Toast.LENGTH_SHORT).show();
- }
- }
- }
- private static class InfoWindowAdapter extends InfoWindow.ViewAdapter {
- @NonNull
- private final Context context;
- private View rootView;
- private ImageView icon;
- private TextView text;
- private InfoWindowAdapter(@NonNull Context context) {
- this.context = context;
- }
- @NonNull
- @Override
- public View getView(@NonNull InfoWindow infoWindow) {
- if (rootView == null) {
- rootView = View.inflate(context, R.layout.marker_info_window, null);
- icon = rootView.findViewById(R.id.icon);
- text = rootView.findViewById(R.id.text);
- }
- if (infoWindow.getMarker() != null) {
- icon.setImageResource(R.drawable.ic_place_black_24dp);
- text.setText((String) infoWindow.getMarker().getTag());
- } else {
- icon.setImageResource(R.drawable.ic_app);
- text.setText(context.getString(
- R.string.format_coord, infoWindow.getPosition().latitude, infoWindow.getPosition().longitude));
- }
- return rootView;
- }
- }
- @SuppressLint("NonConstantResourceId")
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- this.binding = ActivityMainBinding.inflate(getLayoutInflater());
- setContentView(this.binding.getRoot());
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // 화면 꺼짐 방지
- this.context = MainActivity.this;
- this.deviceId = PrefManager.getDeviceId(this);
- this.dispAllSignal = PrefManager.getDispAreaCross(this);
- this.dispCvibSignal = PrefManager.getDispCvibSignal(this);
- TsiNaviApplication.getMapConfig().loadConfig(this);
- //this.tsiApiService = ApiUtils.getApiService(PrefManager.getApiUrl(this));
- this.trackingZoom = TsiNaviApplication.getMapConfig().getTrackingZoom();
- this.tilt = TsiNaviApplication.getMapConfig().getRunTilt();
- this.trackingDistance = TsiNaviApplication.getMapConfig().getRunTrackingDistance();
- this.driveDistance = TsiNaviApplication.getMapConfig().getRunDriveDistance();
- this.isTrackingMode = false;
- this.cameraInfo = new CameraInfo(this);
- this.mapUtils = new BoundaryUtils(this);
- this.gpsTracking = new TsiGpsTrackingVo();
- this.backPressedForFinish = new BackPressedForFinish(this); // BackPressedForFinish 객체를 생성한다.
- //setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
- MainActivityUtils.initDatabase(this);
- this.dbQuery = new DbQuery(this);
- this.dbQuery.createDatabase();
- this.dbQuery.open();
- // 지도사용권한
- this.locationSource = new FusedLocationSource(this, LOCATION_PERMISSION_REQUEST_CODE);
- this.binding.tvLog.setText(" ");
- this.binding.tvLog.setVisibility(View.INVISIBLE);
- this.binding.tvSpeed.setText(" ");
- this.fragmentManager = getSupportFragmentManager();
- FragmentTransaction transaction = this.fragmentManager.beginTransaction();
- this.areaCrossFragment = new AreaCrossFragment();
- this.directionSignalFragment = new DirectionSignalFragment();
- this.directionNaviSignalFragment = new DirectionNaviSignalFragment();
- this.userSignalFragment = new UserSignalFragment();
- transaction.add(R.id.frame_area_cross, areaCrossFragment, "AreaCross");
- transaction.add(R.id.frame_direction_signal, this.directionSignalFragment, "DirectionSignal");
- transaction.add(R.id.frame_direction_navi_signal, this.directionNaviSignalFragment, "DirectionNaviSignal");
- transaction.add(R.id.frame_user_signal, this.userSignalFragment, "UserSignal");
- transaction.hide(areaCrossFragment);
- transaction.hide(this.directionSignalFragment);
- transaction.hide(this.directionNaviSignalFragment);
- transaction.hide(this.userSignalFragment);
- transaction.commit();
- /*this.areaCrossFragment.setOnItemClickListener(item -> {
- if (item != null) {
- requestNodeSignal(item.getNodeId(), true);
- }
- });
- */
- // Naver 지도객체 생성
- FragmentManager fragmentManager = getSupportFragmentManager();
- MapFragment mapFragment = (MapFragment)fragmentManager.findFragmentById(R.id.map);
- if (mapFragment == null) {
- mapFragment = MapFragment.newInstance(new NaverMapOptions());
- fragmentManager.beginTransaction().add(R.id.map, mapFragment).commit();
- }
- mapFragment.getMapAsync(this);
- startNaviWebsocketClientService();
- this.binding.fabSetCurrent.setVisibility(View.INVISIBLE);
- this.binding.fabSetCurrent.setOnClickListener(v -> {
- setTrackingMode(true);
- });
- this.binding.fabMenu.setOnClickListener(v -> {
- PopupMenu popup = new PopupMenu(MainActivity.this, v);
- final MenuInflater inflater = popup.getMenuInflater();
- inflater.inflate(R.menu.bottom_menu, popup.getMenu());
- MenuItem itemDispCross = popup.getMenu().findItem(R.id.menu_disp_cross);
- if (itemDispCross != null) {
- if (this.dispAllSignal) {
- itemDispCross.setIcon(R.drawable.ic_check_yes);
- }
- else {
- itemDispCross.setIcon(R.drawable.ic_check_no);
- }
- }
- MenuItem itemDebugMode = popup.getMenu().findItem(R.id.menu_debug_mode);
- if (itemDebugMode != null) {
- if (this.isDebugMode) {
- itemDebugMode.setIcon(R.drawable.ic_check_yes);
- }
- else {
- itemDebugMode.setIcon(R.drawable.ic_check_no);
- }
- }
- MenuItem itemDispCvib = popup.getMenu().findItem(R.id.menu_disp_cvib);
- if (itemDispCvib != null) {
- if (this.dispCvibSignal) {
- itemDispCvib.setIcon(R.drawable.ic_check_yes);
- }
- else {
- itemDispCvib.setIcon(R.drawable.ic_check_no);
- }
- }
- binding.fabMenu.setImageResource(R.drawable.ic_action_close);
- popup.setOnMenuItemClickListener(item -> {
- switch (item.getItemId()){
- case R.id.menu_cross:
- NodeCrossDialog nodeCrossDialog = new NodeCrossDialog(MainActivity.this,
- new IDialogClickListener() {
- @Override
- public void onPositiveClick() {
- }
- @Override
- public void onNegativeClick() {
- }
- });
- nodeCrossDialog.setOnDismissListener(d -> {
- NodeCrossItem nodeItem = nodeCrossDialog.getSelectedNode();
- if (nodeItem != null) {
- // 교차로 선택 다이얼로그에서 교차로 선택했음
- NodeVo node = TsiNaviApplication.getNodeMap().get(nodeItem.getId());
- if (node != null) {
- naverMap.moveCamera(CameraUpdate.scrollTo(node.getLatLng()));
- setSelectedNode(node);
- setTrackingMode(false);
- requestSelectedNode();
- }
- }
- });
- nodeCrossDialog.setCanceledOnTouchOutside(true); //다이얼로그 밖에 터치했을 때 다이얼로그가 꺼짐.
- nodeCrossDialog.setCancelable(true); //다이얼로그 취소 가능. ( back 버튼 )
- nodeCrossDialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
- nodeCrossDialog.show();
- break;
- case R.id.menu_map_settings:
- MapSettingDialog mapSettingDialog = new MapSettingDialog(MainActivity.this,
- new IDialogClickListener() {
- @Override
- public void onPositiveClick() {
- // 설정값을 레퍼런스에 저장
- TsiNaviApplication.getMapConfig().saveConfig(MainActivity.this);
- mapUtils.loadConfig();
- trackingZoom = TsiNaviApplication.getMapConfig().getTrackingZoom();
- }
- @Override
- public void onNegativeClick() {
- // 레퍼런스를 다시읽어 설정값 초기화
- TsiNaviApplication.getMapConfig().loadConfig(MainActivity.this);
- }
- }, naverMap, mapUtils);
- mapSettingDialog.setCanceledOnTouchOutside(true); //다이얼로그 밖에 터치했을 때 다이얼로그가 꺼짐.
- mapSettingDialog.setCancelable(true); //다이얼로그 취소 가능. ( back 버튼 )
- mapSettingDialog.setOnDismissListener(d -> {
- // 맵 설정정보 셋팅
- MainActivityUtils.setupMap(naverMap, trackingZoom);
- /* if (TsiNaviApplication.getMapConfig().isNightMode()) {
- this.overlayResourceId = (this.overlayResourceId == R.drawable.ic_navi_car_on) ? R.drawable.ic_navi_car_night_on : R.drawable.ic_navi_car_night_off;
- }
- else {
- this.overlayResourceId = (this.overlayResourceId == R.drawable.ic_navi_car_night_on) ? R.drawable.ic_navi_car_on : R.drawable.ic_navi_car_off;
- }
- this.naverMap.getLocationOverlay().setIcon(OverlayImage.fromResource(this.overlayResourceId));
- */ });
- mapSettingDialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
- mapSettingDialog.show();
- break;
- case R.id.menu_map_cache_delete:
- NaverMapSdk.getInstance(MainActivity.this).flushCache(new NaverMapSdk.CacheFlushCallback() {
- @Override
- public void onCacheFlushed() {
- Toast.makeText(MainActivity.this, "지도캐시초기화 완료.", Toast.LENGTH_SHORT).show();
- }
- });
- break;
- case R.id.menu_app_info:
- AppInformationDialog appInformationDialog = new AppInformationDialog(MainActivity.this, new IDialogClickListener() {
- @Override
- public void onPositiveClick() { }
- @Override
- public void onNegativeClick() { }
- });
- appInformationDialog.setCanceledOnTouchOutside(true); //다이얼로그 밖에 터치했을 때 다이얼로그가 꺼짐.
- appInformationDialog.setCancelable(true); //다이얼로그 취소 가능. ( back 버튼 )
- appInformationDialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
- appInformationDialog.show();
- break;
- case R.id.menu_disp_cross:
- this.dispAllSignal = !this.dispAllSignal;
- PrefManager.setDispAreaCross(this.context, this.dispAllSignal);
- if (!this.isTrackingMode) {
- if (this.dispAllSignal) {
- if (this.selectedNode != null) {
- if (!this.directionNaviSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().show(this.directionNaviSignalFragment).commit();
- this.directionNaviSignalFragment.setNodeCross(this.selectedNode, 10);
- }
- if (this.dispCvibSignal && !this.directionSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().show(this.directionSignalFragment).commit();
- this.directionSignalFragment.setNodeCross(this.selectedNode, 10);
- }
- }
- }
- else {
- if (this.directionNaviSignalFragment.isVisible()) {
- //this.fragmentManager.beginTransaction().hide(this.directionNaviSignalFragment).commit();
- this.directionNaviSignalFragment.setNodeCross(null, 10);
- }
- if (this.directionSignalFragment.isVisible()) {
- //this.fragmentManager.beginTransaction().hide(this.directionSignalFragment).commit();
- this.directionSignalFragment.setNodeCross(null, 10);
- }
- }
- }
- break;
- case R.id.menu_disp_cvib:
- this.dispCvibSignal = !this.dispCvibSignal;
- PrefManager.setDispAreaCross(this.context, this.dispCvibSignal);
- if (this.dispCvibSignal && this.directionNaviSignalFragment.isVisible() && !this.directionSignalFragment.isVisible()) {
- this.directionSignalFragment.setNodeCross(this.directionNaviSignalFragment.getNode(), this.directionNaviSignalFragment.getDirection());
- this.fragmentManager.beginTransaction().show(this.directionSignalFragment).commit();
- }
- if (!this.dispCvibSignal && this.directionSignalFragment.isVisible()) {
- this.directionSignalFragment.setNodeCross(this.directionNaviSignalFragment.getNode(), this.directionNaviSignalFragment.getDirection());
- this.fragmentManager.beginTransaction().hide(this.directionSignalFragment).commit();
- }
- break;
- case R.id.menu_debug_mode:
- this.isDebugMode = !this.isDebugMode;
- mapUtils.setDebugMode(this.isDebugMode);
- mapUtils.drawBounds(null);
- if (!this.isDebugMode) {
- if (this.gpsTracking.getRequestNode() != null) {
- requestTopicMessage("x");
- this.directionNaviSignalFragment.setNodeCross(null, 10);
- this.directionSignalFragment.setNodeCross(null, 10);
- }
- if (this.directionSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().hide(this.directionSignalFragment).commit();
- }
- if (this.directionNaviSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().hide(this.directionNaviSignalFragment).commit();
- }
- }
- break;
- default:
- Log.e(TAG, "뭐가 클릭된거야?");
- return false;
- }
- return true;
- });
- // show icons on popup menu
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- popup.setForceShowIcon(true);
- }
- popup.setOnDismissListener(menu -> {
- binding.fabMenu.setImageResource(R.drawable.ic_action_menu);
- });
- popup.show();
- });
- }
- @Override
- protected void onSaveInstanceState(@NonNull Bundle outState) {
- //https://developer.android.com/training/location/request-updates?hl=ko
- /*outState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY,
- requestingLocationUpdates);
- // ...*/
- super.onSaveInstanceState(outState);
- }
- private void startNaviWebsocketClientService() {
- this.lastTopics = "";
- // start service
- Intent intent = new Intent(this.context, NaviWebsocketClientService.class);
- startService(intent);
- // bind service
- Intent bindIntent = new Intent(this.context, NaviWebsocketClientService.class);
- bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE);
- // register receiver
- NaviWebsocketMessageListener naviClientMessageListener = new NaviWebsocketMessageListener();
- IntentFilter messageFilter = new IntentFilter("com.websocket.content");
- registerReceiver(naviClientMessageListener, messageFilter);
- NaviWebsocketEventListener naviClientEventListener = new NaviWebsocketEventListener();
- IntentFilter eventFilter = new IntentFilter("com.websocket.event");
- registerReceiver(naviClientEventListener, eventFilter);
- }
- //권한 받아오기
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (this.locationSource.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
- if (!this.locationSource.isActivated()) {
- // 권한 거부됨
- this.naverMap.setLocationTrackingMode(LocationTrackingMode.None);
- }
- else {
- this.naverMap.setLocationTrackingMode(LocationTrackingMode.Follow);
- }
- return;
- }
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- }
- @SuppressLint("SetTextI18n")
- @UiThread
- @Override
- public void onMapReady(@NonNull @NotNull NaverMap naverMap) {
- this.naverMap = naverMap;
- this.cameraUpdateParams = new CameraUpdateParams();
- this.mapUtils.setup(this.naverMap);
- // 네이버 맵에 locationSource 를 설정하면 위치 추적 기능을 사용 할 수 있다
- this.naverMap.setLocationSource(this.locationSource);
- ActivityCompat.requestPermissions(this, this.permissions, LOCATION_PERMISSION_REQUEST_CODE);
- setMapContentPadding();
- MainActivityUtils.initMap(this.naverMap);
- //TABS6(2560*1600). S105G(3040*1440)
- this.overlayResourceId = R.drawable.ic_car_red;//R.drawable.ic_navi_car_on;//TsiNaviApplication.getMapConfig().isNightMode() ? R.drawable.ic_navi_car_night_on : R.drawable.ic_navi_car_on;
- MainActivityUtils.initMapOverlay(this.naverMap, this.overlayResourceId, (1440 >= Math.min(this.width, this.height)));
- MainActivityUtils.setupMap(this.naverMap, this.trackingZoom);
- initNodeMarker();
- setTrackingMode(true);
- // 도로교통공단 서울지부로 위치 이동(최초 기본 위치)
- //LatLng initialPosition = new LatLng(37.465913939690815, 127.04432631214559);
- /*CameraUpdate cameraUpdate = CameraUpdate.scrollTo(initialPosition);
- this.naverMap.moveCamera(cameraUpdate);*/
- /*CameraPosition initialCameraPosition = new CameraPosition(
- initialPosition, // 위치 지정
- this.trackingZoom, // 줌 레벨
- this.tilt, // 기울임 각도
- 45 // 방향
- );
- this.naverMap.setCameraPosition(initialCameraPosition);*/
- // 카메라의 움직임이 끝나 대기 상태가 되면 카메라 대기 이벤트가 발생합니다.
- // 카메라가 애니메이션 없이 움직일 때. 단, 사용자가 제스처로 지도를 움직이는 경우
- // 제스처가 완전히 끝날 때까지(ACTION_UP이 발생할 때까지)는 연속적인 이동으로 간주되어 이벤트가 발생하지 않습니다.
- // 카메라 애니메이션이 완료될 때. 단, 카메라 애니메이션이 진행 중일 때 새로운 애니메이션이 발생하거나,
- // 기존 카메라 이동의 finishCallback() 또는 cancelCallback()으로 지정된 콜백 내에서 카메라 이동이 일어날 경우
- // 연속적인 이동으로 간주되어 이벤트가 발생하지 않습니다. NaverMap.cancelTransitions()가 호출되어 카메라 애니메이션이 명시적으로 취소될 때.
- this.naverMap.addOnCameraIdleListener(() -> {
- if (!this.cameraInfo.equals(this.naverMap.getCameraPosition())) {
- this.mapUtils.initMap();
- this.mapUtils.drawBounds(this.naverMap.getCameraPosition().target);
- }
- updateNodeMarker();
- });
- this.naverMap.addOnLocationChangeListener(location -> {
- //TODO Log.e(TAG, "LocationChangeListener");
- /*LatLng coord = new LatLng(location);
- LocationOverlay locationOverlay = map.getLocationOverlay();
- locationOverlay.setVisible(true);
- locationOverlay.setPosition(coord);
- locationOverlay.setBearing(location.getBearing());
- map.moveCamera(CameraUpdate.scrollTo(coord));*/
- this.moveByGps.set(false);
- this.currSpeed = location.hasSpeed() ? location.getSpeed() * 3.6F : 0.0F; // 속도 meter/sec ==> km/sec
- this.currBearing = location.hasBearing() ? location.getBearing() : -1; // 베어링
- this.moveDist = this.lastLocation == null ? 0 : this.lastLocation.distanceTo(location);
- this.lastLocation = location;
- this.binding.tvSpeed.setText(String.valueOf((int)this.currSpeed));
- // 속도값이 없거나 이동거리가 기준 이하이면 GPS 수신하지 않은것으로 처리한다.
- if (this.currSpeed <= 1 || this.moveDist <= 2) {
- this.naverMap.getLocationOverlay().setBearing(this.lastBearing);
- /*int disableResourceId = TsiNaviApplication.getMapConfig().isNightMode() ? R.drawable.ic_navi_car_night_off : R.drawable.ic_navi_car_off;
- if (overlayResourceId != disableResourceId) {
- this.naverMap.getLocationOverlay().setIcon(OverlayImage.fromResource(disableResourceId));
- overlayResourceId = disableResourceId;
- }*/
- //updateBounds(location);
- return;
- }
- /*int enabledResourceId = TsiNaviApplication.getMapConfig().isNightMode() ? R.drawable.ic_navi_car_night_on : R.drawable.ic_navi_car_on;
- if (overlayResourceId != enabledResourceId) {
- this.naverMap.getLocationOverlay().setIcon(OverlayImage.fromResource(enabledResourceId));
- overlayResourceId = enabledResourceId;
- }*/
- if (this.currBearing >= 0) {
- this.lastBearing = this.currBearing;
- }
- // GPS 이동한 것으로 판단.
- this.moveByGps.set(true);
- if (this.isTrackingMode) {
- CameraPosition gpsPosition = new CameraPosition(
- new LatLng(location.getLatitude(), location.getLongitude()), // 위치 지정
- this.trackingZoom, // 줌 레벨
- this.tilt, // 기울임 각도
- this.lastBearing // 방향
- );
- this.naverMap.setCameraPosition(gpsPosition);
- }
- });
- this.naverMap.addOnCameraChangeListener((reason, animated) -> {
- switch(reason) {
- case CameraUpdate.REASON_DEVELOPER: //REASON_DEVELOPER: 0, 개발자가 API를 호출해 카메라가 움직였음을 나타냅니다. 기본값입니다.
- break;
- case CameraUpdate.REASON_LOCATION: //REASON_LOCATION: -3, 위치 트래킹 기능으로 인해 카메라가 움직였음을 나타냅니다.
- break;
- case CameraUpdate.REASON_GESTURE: //REASON_GESTURE: -1, 사용자의 제스처로 인해 카메라가 움직였음을 나타냅니다. // == CameraUpdate.DEFAULT_ANIMATION_DURATION
- case CameraUpdate.REASON_CONTROL: //REASON_CONTROL: -2, 사용자의 버튼 선택으로 인해 카메라가 움직였음을 나타냅니다.
- setTrackingMode(false);
- break;
- }
- });
- this.naverMap.setOnMapClickListener((point, coord) -> {
- if (this.infoWindow != null && this.infoWindow.isVisible()) {
- //마커클릭후에 지도클릭 이벤트가 먹기 때문에 여기서 처리하면 안된다.(마커클릭후에 true 리턴하면 된다)
- this.infoWindow.close();
- }
- });
- }
- private void updateBounds(Location location) {
- //if (location == null) return;
- if (location != null) {
- this.mapUtils.drawBounds(new LatLng(location.getLatitude(), location.getLongitude()));
- }
- else {
- this.mapUtils.drawBounds(this.naverMap.getCameraPosition().target);
- }
- }
- // 지도상에 표시되고있는 마커들 지도에서 삭제
- private void freeActiveMarkers() {
- if (this.activeMarkers == null) {
- this.activeMarkers = new Vector<>();
- return;
- }
- //TODO Log.e(TAG, "freeActiveMarkers: " + this.activeMarkers.size());
- for (Marker activeMarker: this.activeMarkers) {
- activeMarker.setMap(null);
- }
- this.activeMarkers = new Vector<>();
- }
- @SuppressLint("SetTextI18n")
- private void updateNodeMarkerInDrive(boolean trackingMode) {
- boolean isMovingByGps = this.moveByGps.getAndSet(false);
- //TODO Log.e(TAG, "updateNodeMarkerInDrive: " + trackingMode + ", " + isMovingByGps);
- //if (!trackingMode || !isMovingByGps) {
- if (!trackingMode && !this.isDebugMode) {
- //TODO Log.e(TAG, "isMovingByGps == false");
- return;
- }
- /*if (this.naverMap.getCameraPosition().zoom != this.trackingZoom) {
- if (this.directionSignalFragment.isVisible()) {
- requestTopicMessage("x");
- this.fragmentManager.beginTransaction().hide(this.directionSignalFragment).commit();
- }
- if (this.areaCrossFragment.isVisible()) {
- this.fragmentManager.beginTransaction().hide(this.areaCrossFragment).commit();
- }
- Log.e(TAG, "updateNodeMarkerInDrive: zoom: " + this.naverMap.getCameraPosition().zoom + ", " + this.trackingZoom);
- return;
- }*/
- LatLngBounds carBounds = this.mapUtils.getCarBounds();
- PointF carPos = this.mapUtils.getCarPosition();
- //LatLng[] latLngBounds = this.mapUtils.getLatLngBounds();
- //LatLng carLatLng = this.naverMap.getLocationOverlay().getPosition(); // 현재 차량위치
- LatLng carLatLng = this.naverMap.getCameraPosition().target; // 현재 차량위치
- //int signalDirectionCode = TsiNaviApplication.getDirection().getSignalDirectionCode(this.lastBearing == 0 ? this.naverMap.getCameraPosition().bearing : this.lastBearing);
- int signalDirectionCode = TsiNaviApplication.getDirection().getSignalDirectionCode(this.naverMap.getCameraPosition().bearing);
- if (signalDirectionCode == 0) {
- //TODO Log.e(TAG, "Direction Error: " + signalDirectionCode);
- return;
- }
- if (this.gpsTracking.getSignalDirCode() != signalDirectionCode) {
- //TODO Log.e(TAG, "Bearing different: " + this.gpsTracking.getSignalDirCode() + ", " + signalDirectionCode);
- this.gpsTracking.setSignalDirCode(signalDirectionCode);
- return;
- }
- this.gpsTracking.setSignalDirCode(signalDirectionCode);
- int calDirectionCode;
- //TODO String sLog = "--Dir: " + String.format("%3d", (int)this.lastBearing) + ", " + signalDirectionCode + ", " + String.format("%3d", (int)this.naverMap.getCameraPosition().bearing);
- // 진출입 노드에 대한 계산
- double calBearing;
- double calDistance;
- double nearDistance = Float.MAX_VALUE;
- double crossDistance = Float.MAX_VALUE;
- NodeVo inCrossNode = null;
- NodeVo targetNode = null;
- NodeVo nearNode = null;
- Set<Long> inCrossNodeSet= new HashSet<>();
- //TODO Log.e(TAG, "Boundary nodes: " + this.activeNodes.size() + " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
- boolean crossPassOffSignal = false;
- for (Map.Entry<Long, NodeVo> obj : this.activeNodes.entrySet()) {
- NodeVo node = obj.getValue();
- PointF posNode = this.naverMap.getProjection().toScreenLocation(node.getLatLng());
- Location.distanceBetween(carLatLng.latitude, carLatLng.longitude, node.getLatLng().latitude, node.getLatLng().longitude, this.resultDistance);
- calDistance = this.resultDistance[0];
- calBearing = (this.resultDistance[1] < 0) ? (360 + this.resultDistance[1]) : this.resultDistance[1];
- calDirectionCode = TsiNaviApplication.getDirection().getSignalDirectionCode(calBearing);
- //TODO Log.e(TAG, "calDirectionCode: " + calDirectionCode + ", " + node.getName());
- if (carBounds.contains(node.getLatLng())) {
- // 노드 통과 영역에 포함
- //TODO sLog += "\n-C: " + String.format("%3d, %d, %3d m, %s, %s", (int)calBearing, calDirectionCode, (int)calDistance, node.getDirCode(), node.getName());
- if (calDistance < crossDistance) {
- inCrossNode = node;
- crossDistance = calDistance;
- //TODO sLog += "--Near";
- }
- //TODO if (!node.isReal()) sLog += "--Dummy";
- if (this.gpsTracking.getRequestNode() != null) {
- if (this.gpsTracking.getRequestNode().getNodeId() == node.getNodeId()) {
- if (posNode.y > carPos.y) {
- // 요청 신호정보가 존재하고 지금 요청 신호등을 지났으면 신호 정보 요청 취소
- crossPassOffSignal = true;
- requestTopicMessage("x");
- this.gpsTracking.setRequestNode(null);
- }
- }
- else {
- // 검지영역이 좁아서 검지역역내에 교차로가 2개 이상 검지되고 있는 경우
- // 이전 요청 교차로가 현재 교차로가 아니면 요청을 취소한다.
- requestTopicMessage("x");
- this.gpsTracking.setRequestNode(null);
- }
- }
- }
- if (this.mapUtils.contains((node.getLatLng()))) {
- // 진행방향 바운더리 영역내에 포함됨
- //TODO sLog += "\n-N: " + String.format("%3d, %d, %3d m, %s, %s", (int)calBearing, calDirectionCode, (int)calDistance, node.getDirCode(), node.getName());
- if (node.getInDirMap().contains(calDirectionCode)) {
- //TODO sLog += "--Match";
- if (node.getInDirMap().contains(calDirectionCode) && calDistance < nearDistance) {
- nearNode = node;
- nearDistance = calDistance;
- //TODO sLog += "--Near";
- }
- }
- //TODO if (!node.isReal()) sLog += "--Dummy";
- }
- }
- if (inCrossNode != null) {
- // 노드를 통과 중이면 처리하는게 없다. 노드를 통과한 후에 처리하도록 한다.
- this.gpsTracking.setInCrossNode(inCrossNode);
- if (crossPassOffSignal) {
- // 요청 신호 정보 교차로를 지나서 요청 신호를 취소한 경우
- // ====> 이부분 주석 처리하면 교차로 통과할 동안 신호정보 요청을 보내지 않는다.
- /*
- if (nearNode != null && nearNode.isReal()) {
- if (this.gpsTracking.getRequestNode() == null) {
- requestNodeSignal(nearNode.getNodeId(), signalDirectionCode);
- this.gpsTracking.setRequestNode(nearNode);
- }
- }
- */
- }
- }
- else {
- // 노드를 통과하는 것이 아니라 도로를 주행 중인 상태
- if (this.gpsTracking.getInCrossNode() != null) {
- // 노드를 빠져 나온 상태. 시작 노드 정보로 설정한다.
- this.gpsTracking.setStartNode(inCrossNode);
- // 노드를 빠져 나올때 근접 노드정보가 있을 경우와 없을 경우에 따라 처리
- if (nearNode != null) {
- if (nearNode.isReal()) {
- if (this.gpsTracking.getRequestNode() == null || this.gpsTracking.getRequestNode().getNodeId() != nearNode.getId()) {
- requestNodeSignal(nearNode.getNodeId(), signalDirectionCode);
- this.gpsTracking.setRequestNode(nearNode);
- }
- }
- else {
- this.gpsTracking.setEndNode(nearNode);
- }
- }
- else {
- if (this.gpsTracking.getRequestNode() != null) {
- // 더이상 요청할 노드가 진행 방향에 존재하지 않는다.
- requestTopicMessage("x");
- this.gpsTracking.setRequestNode(null);
- }
- }
- }
- else {
- // 도로 주행
- if (nearNode != null) {
- // 진행방향에 표출할 노드가 존재하면
- if (nearNode.isReal()) {
- if (this.gpsTracking.getRequestNode() == null || this.gpsTracking.getRequestNode().getNodeId() != nearNode.getId()) {
- requestNodeSignal(nearNode.getNodeId(), signalDirectionCode);
- this.gpsTracking.setRequestNode(nearNode);
- }
- }
- }
- else {
- // 진행방향에 노드가 존재하지 않음.
- if (this.gpsTracking.getRequestNode() != null) {
- requestTopicMessage("x");
- this.gpsTracking.setRequestNode(null);
- }
- }
- }
- this.gpsTracking.setInCrossNode(null);
- }
- if (this.gpsTracking.getRequestNode() != null) {
- if (this.activeNodes.get(this.gpsTracking.getRequestNode().getNodeId()) == null) {
- // 요청 중인데 영역내에 없으면 취소 시킨다.
- requestTopicMessage("x");
- this.gpsTracking.setRequestNode(null);
- }
- }
- //TODO this.binding.tvLog.setText(sLog);
- //TODO Log.e(TAG, sLog);
- }
- private void updateNodeMarker() {
- //Log.e(TAG, "updateNodeMarker: zoom: " + this.naverMap.getCameraPosition().zoom);
- updateBounds(null);
- int signalDirectionCode = TsiNaviApplication.getDirection().getSignalDirectionCode(this.naverMap.getCameraPosition().bearing);
- int runDirectionCode = TsiNaviApplication.getDirection().getSignal2RunDirection(signalDirectionCode);
- //TODO String sLog = "Bearing: " + (int)this.naverMap.getCameraPosition().bearing + ", " + signalDirectionCode + ", " + runDirectionCode + ", zoom:" + (int)this.naverMap.getCameraPosition().zoom;
- //TODO this.binding.tvLog.setText(sLog);
- Marker infoMarker = null;
- if (this.infoWindow != null) {
- infoMarker = this.infoWindow.getMarker();
- }
- freeActiveMarkers(); // 메모리 관리를 위해 여기서 삭제해 준다.
- if (this.naverMap.getCameraPosition().zoom < 13) {
- /*if (this.isTrackingMode && this.directionSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().hide(this.directionSignalFragment).commit();
- }*/
- if (infoMarker != null) {
- this.infoWindow.close();
- }
- return;
- }
- LatLngBounds bounds = this.naverMap.getCoveringBounds();
- //LatLngBounds bounds = this.naverMap.getContentBounds();
- ConcurrentHashMap<Long, NodeVo> activeNodes = new ConcurrentHashMap<>();
- Vector<Marker> activeMarkers = new Vector<>();
- List<Long> nodes = MainActivityUtils.getBoundsNodes(this.dbQuery, bounds);
- if (nodes != null) {
- //TODO Log.e(TAG, "Bounds nodes: " + nodes.size() + " EA.");
- if (nodes.size() <= 300) {
- for (Long obj : nodes) {
- try {
- NodeVo node = TsiNaviApplication.getNodeMap().get(obj);
- if (node != null) {
- activeMarkers.add(node.getMarker());
- activeNodes.put(node.getNodeId(), node);
- }
- } catch (Exception e) {
- Log.e(TAG, "updateNodeMarker: " + e.getMessage());
- }
- }
- }
- }
- this.activeMarkers = activeMarkers;
- for (Marker activeMarker: this.activeMarkers) {
- if (!activeMarker.getTag().equals("x")) {
- activeMarker.setMap(this.naverMap);
- }
- }
- if (infoMarker != null) {
- this.infoWindow.open(infoMarker, Align.TopLeft);
- }
- if (this.isTrackingMode) {
- // 트래킹(드라이빙) 모드이고 조건을 만족할 경우
- this.activeNodes = activeNodes;
- updateNodeMarkerInDrive(true);
- }
- else {
- // 사용자 움직임인 경우 바운더리 계산해서 영역을 다시 찾은 다음 영역에 속한
- // 교차로 정보를 다시 조회해서 처리해야함
- this.activeNodes = activeNodes;
- updateNodeMarkerInDrive(false);
- }
- }
- private void requestNodeSignal(long nodeId, int directionCode) {
- if (!this.isTrackingMode) {
- //return;
- }
- NodeVo node = TsiNaviApplication.getNodeMap().get(nodeId);
- //if (node == null) return;
- setRequestNode(node);
- this.userSignalFragment.setNodeCross(null);
- this.directionNaviSignalFragment.setNodeCross(node, directionCode);
- this.directionSignalFragment.setNodeCross(node, directionCode);
- requestTopicMessage(String.valueOf(nodeId));
- if (this.dispCvibSignal && !this.directionSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().show(this.directionSignalFragment).commit();
- }
- if (!this.directionNaviSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().show(this.directionNaviSignalFragment).commit();
- }
- if (userSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().hide(this.userSignalFragment).commit();
- }
- }
- private void setSelectedNode(NodeVo node) {
- this.gpsTracking.setRequestNode(null);
- if (this.selectedNode != null) {
- // 이전 선택한 아이콘은 기본 아이콘으로 변경
- this.selectedNode.marker.setIcon(OverlayImage.fromResource(R.drawable.ic_cross_normal));
- }
- if (this.infoWindow != null && this.infoWindow.isVisible()) {
- // 이전 인포 윈도우 닫음
- this.infoWindow.close();
- }
- this.selectedNode = node;
- if (this.selectedNode != null) {
- // 선택한 아이콘은 선택 아이콘으로 변경
- this.selectedNode.marker.setIcon(OverlayImage.fromResource(R.drawable.ic_cross_select));
- // 선택한 아이콘의 인포 윈도우 오픈
- this.infoWindow.open(this.selectedNode.marker, Align.TopLeft);
- }
- }
- private void setRequestNode(NodeVo node) {
- this.selectedNode = null;
- if (this.gpsTracking.getRequestNode() != null) {
- // 이전 선택한 아이콘은 기본 아이콘으로 변경
- this.gpsTracking.getRequestNode().marker.setIcon(OverlayImage.fromResource(R.drawable.ic_cross_normal));
- }
- if (this.infoWindow != null && this.infoWindow.isVisible()) {
- // 이전 인포 윈도우 닫음
- this.infoWindow.close();
- }
- this.gpsTracking.setRequestNode(node) ;
- if (this.gpsTracking.getRequestNode() != null) {
- // 선택한 아이콘은 선택 아이콘으로 변경
- this.gpsTracking.getRequestNode().marker.setIcon(OverlayImage.fromResource(R.drawable.ic_cross_select));
- // 선택한 아이콘의 인포 윈도우 오픈
- this.infoWindow.open(this.gpsTracking.getRequestNode().marker, Align.TopLeft);
- }
- }
- private void setTrackingMode(boolean trackingMode) {
- if (!this.isTrackingMode && trackingMode) {
- requestTopicMessage("x");
- this.moveByGps.set(true);
- }
- if (this.isTrackingMode && !trackingMode) {
- this.gpsTracking.init();
- }
- this.isTrackingMode = trackingMode;
- if (trackingMode) {
- if (this.naverMap.getLocationTrackingMode() != LocationTrackingMode.Follow) {
- this.naverMap.setLocationTrackingMode(LocationTrackingMode.Follow); // Tracking Mode 설정
- //binding.tvLog.setText("Follow");
- /*this.cameraUpdateParams//.scrollTo(this.cameraPosition.target)
- .zoomTo(this.trackingZoom)
- .rotateTo(this.lastBearing).tiltTo(this.tilt);
- this.naverMap.moveCamera(CameraUpdate.withParams(this.cameraUpdateParams));*/
- }
- this.cameraUpdateParams//.scrollTo(this.cameraPosition.target)
- .zoomTo(this.trackingZoom)
- .rotateTo(this.lastBearing).tiltTo(this.tilt);
- this.naverMap.moveCamera(CameraUpdate.withParams(this.cameraUpdateParams));
- if (this.naverMap.getUiSettings().isZoomControlEnabled()) {
- this.naverMap.getUiSettings().setZoomControlEnabled(false);
- }
- if (this.binding.tvSpeed.getVisibility() == View.INVISIBLE) {
- this.binding.tvSpeed.setVisibility(View.VISIBLE);
- }
- if (this.lastLocation != null) {
- CameraPosition initialCameraPosition = new CameraPosition(
- new LatLng(this.lastLocation.getLatitude(), this.lastLocation.getLongitude()), // 위치 지정
- this.trackingZoom, // 줌 레벨
- this.tilt, // 기울임 각도
- this.lastBearing // 방향
- );
- this.naverMap.setCameraPosition(initialCameraPosition);
- }
- if (View.VISIBLE == this.binding.fabSetCurrent.getVisibility()) {
- this.binding.fabSetCurrent.setVisibility(View.INVISIBLE);
- }
- if (this.infoWindow != null && this.infoWindow.isVisible()) {
- //마커클릭후에 지도클릭 이벤트가 먹기 때문에 여기서 처리하면 안된다.
- this.infoWindow.close();
- }
- }
- else {
- if (this.naverMap.getLocationTrackingMode() != LocationTrackingMode.NoFollow) {
- this.naverMap.setLocationTrackingMode(LocationTrackingMode.NoFollow);
- this.cameraUpdateParams//.scrollTo(this.cameraPosition.target)
- .zoomTo(this.trackingZoom)
- .rotateTo(0).tiltTo(this.tilt);
- this.naverMap.moveCamera(CameraUpdate.withParams(this.cameraUpdateParams));
- }
- if (!this.naverMap.getUiSettings().isZoomControlEnabled()) {
- this.naverMap.getUiSettings().setZoomControlEnabled(true);
- }
- if (this.binding.tvSpeed.getVisibility() == View.VISIBLE) {
- this.binding.tvSpeed.setVisibility(View.INVISIBLE);
- }
- if (View.VISIBLE != this.binding.fabSetCurrent.getVisibility()) {
- this.binding.fabSetCurrent.setVisibility(View.VISIBLE);
- }
- if (!this.userSignalFragment.isVisible()) {
- if (this.selectedNode != null) this.fragmentManager.beginTransaction().show(this.userSignalFragment).commit();
- }
- if (this.dispAllSignal) {
- if (!this.directionNaviSignalFragment.isVisible()) {
- //TODO Log.e(TAG, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX: " + this.selectedNode);
- if (this.selectedNode != null) this.fragmentManager.beginTransaction().show(this.directionNaviSignalFragment).commit();
- }
- if (this.dispCvibSignal && !this.directionSignalFragment.isVisible()) {
- //TODO Log.e(TAG, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX: " + this.selectedNode);
- if (this.selectedNode != null) this.fragmentManager.beginTransaction().show(this.directionSignalFragment).commit();
- }
- }
- else {
- if (this.directionNaviSignalFragment.isVisible()) {
- //this.fragmentManager.beginTransaction().hide(this.directionNaviSignalFragment).commit();
- }
- if (this.directionSignalFragment.isVisible()) {
- //this.fragmentManager.beginTransaction().hide(this.directionSignalFragment).commit();
- }
- }
- }
- }
- private void requestSelectedNode() {
- if (this.selectedNode != null) {
- this.naverMap.moveCamera(CameraUpdate.scrollTo(this.selectedNode.getLatLng()));
- this.userSignalFragment.setNodeCross(this.selectedNode);
- this.directionNaviSignalFragment.setNodeCross(this.selectedNode, 10);
- this.directionSignalFragment.setNodeCross(this.selectedNode, 10);
- requestTopicMessage(String.valueOf(this.selectedNode.getNodeId()));
- }
- }
- private void initNodeMarker() {
- // 인포 윈도우 생성
- this.infoWindow = new InfoWindow();
- this.infoWindow.setAnchor(new PointF(0, 1));
- this.infoWindow.setOffsetX(getResources().getDimensionPixelSize(R.dimen.marker_info_window_offset_x));
- this.infoWindow.setOffsetY(getResources().getDimensionPixelSize(R.dimen.marker_info_window_offset_y));
- this.infoWindow.setAdapter(new InfoWindowAdapter(this));
- this.infoWindow.setOnClickListener(overlay -> {
- if (this.selectedNode != null) {
- if (!this.isTrackingMode) {
- setTrackingMode(false);
- requestSelectedNode();
- }
- }
- else {
- this.infoWindow.close();
- }
- return true;
- });
- // 교차로 마커 생성
- for (Map.Entry<Long, NodeVo> obj : TsiNaviApplication.getNodeMap().entrySet()) {
- NodeVo node = obj.getValue();
- //node.marker = MainActivityUtils.createNodeMarker(this.naverMap, node, R.drawable.ic_cross_normal, R.drawable.ic_node_small);
- node.marker = MainActivityUtils.createNodeMarker(null, node, R.drawable.ic_cross_normal, R.drawable.ic_node_small);
- if (node.isReal()) {
- node.marker.setOnClickListener(overlay -> {
- setSelectedNode(node);
- return true; // false 리턴하면 마커클릭 후에 지도 클릭 이벤트가 동시에 발생한다.
- });
- }
- }
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (this.locationSource.isActivated()) {
- this.locationSource.deactivate();
- }
- if (this.naviClientService.getNaviWebsocketClient().isOpen()) {
- this.naviClientService.getNaviWebsocketClient().close();
- }
- this.dbQuery.close();
- }
- @Override
- public void onBackPressed() {
- if (this.userSignalFragment.isVisible() ||
- ( !this.isTrackingMode && this.directionSignalFragment.isVisible() || !this.isTrackingMode && this.directionSignalFragment.isVisible() )
- ) {
- requestTopicMessage("x");
- return;
- }
- /*if (this.directionSignalFragment.isVisible()) {
- this.fragmentManager.beginTransaction().hide(this.directionSignalFragment).commit();
- setTrackingMode(true);
- requestTopicMessage("x");
- return;
- }*/
- this.backPressedForFinish.onBackPressed(true);
- }
- @Override
- public void onConfigurationChanged(@NonNull Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- /*if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
- Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
- } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
- Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
- }*/
- setMapContentPadding();
- }
- private void setMapContentPadding() {
- WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
- Rect rc = wm.getCurrentWindowMetrics().getBounds();
- float lWidth = rc.width();
- float lHeight = rc.height();
- /*@SuppressLint("WrongViewCast") FrameLayout frameMap = (FrameLayout) this.binding.getRoot().findViewById(R.id.map);
- if (frameMap != null) {
- this.width = frameMap.getWidth();
- this.height = frameMap.getHeight();
- Log.e(TAG, "width: " + this.width + ", height: " + this.height);
- }*/
- //TODO Log.e(TAG, "RECT: " + rc.width() + ", " + rc.height());
- float lCarX = lWidth / 2;
- float lCarY = (lHeight / 3) * 2;
- if (this.naverMap != null) {
- int padding = (int) (lHeight / 2);
- //TODO Log.e(TAG, "Rect: " + rc.toString());
- //TODO Log.e(TAG, "Padding: " + padding);
- this.naverMap.setContentPadding(0, 0, 0, -padding);
- //this.naverMap.setContentPadding(100, 100, 100, 100);
- lCarX = (float)(this.naverMap.getContentWidth() / 2);
- lCarY = (float)(this.naverMap.getContentHeight() / 2);
- if (this.isTrackingMode) {
- if (this.lastLocation != null) {
- CameraPosition gpsPosition = new CameraPosition(
- new LatLng(this.lastLocation.getLatitude(), this.lastLocation.getLongitude()), // 위치 지정
- this.trackingZoom, // 줌 레벨
- this.tilt, // 기울임 각도
- this.lastBearing // 방향
- );
- this.naverMap.setCameraPosition(gpsPosition);
- }
- }
- else {
- naverMap.moveCamera(CameraUpdate.scrollTo(this.naverMap.getCameraPosition().target));
- }
- }
- this.width = lWidth;
- this.height = lHeight;
- this.carX = lCarX;
- this.carY = lCarY;
- this.moveByGps.set(true);
- }
- }
|