티스토리 뷰

Android Google Map Polyline

  • Google Map 라이브러리를 사용하여 지도 관련 프로젝트를 진행하고 있습니다.
    • GPS를 통해 걸음을 체크하는 서비스  
  • 걸음 시작 버튼을 누른 후부터 특정 주기로 GPS를 기록하여 이동한 거리를 선으로 그려주는 기능을 구현하고 싶었다. 

구현방법

  • Google Map 라이브러리에서 제공하는 Polyline이라는 기능을 통해서 지도 상에 line을 그릴수 있습니다.
  • 걸음시작 버튼을 누른 순간부터 GPS 정보가 업데이트 됨에 따라서 선을 그려주는 방식입니다.
  • GPS 정보는 onLocationChanged 라는 메소드가 호출될 때마다 업데이트가 되며 이때 이전 위치, 현재 위치를 선으로 그러줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
public class MainActivity extends AppCompatActivity
        implements
        NavigationView.OnNavigationItemSelectedListener,
        OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        ActivityCompat.OnRequestPermissionsResultCallback,
        LocationListener {
 
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;
 
    private GoogleMap mMap;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;
    private Location mCurrentLocation;
    private FusedLocationProviderApi mFusedLocationProviderApi;
    private boolean mPermissionDenied;
    private LocationManager locationManager;
    private Marker mCurrentMarker;
    private LatLng startLatLng = new LatLng(00);        //polyline 시작점 
    private LatLng endLatLng = new LatLng(00);        //polyline 끝점
    private boolean walkState = false;                    //걸음 상태
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
 
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {               
                changeWalkState();        //걸음 상태 변경
            }
        });
 
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
 
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
        }
        createLocationRequest();
    }
 
    private void changeWalkState(){
        if(!walkState) {
            Toast.makeText(getApplicationContext(), "걸음 시작", Toast.LENGTH_SHORT).show();
            walkState = true;
            startLatLng = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());        //현재 위치를 시작점으로 설정
        }else{
            Toast.makeText(getApplicationContext(), "걸음 종료", Toast.LENGTH_SHORT).show();
            walkState = false;
        }
    }
 
    private void drawPath(){        //polyline을 그려주는 메소드
        PolylineOptions options = new PolylineOptions().add(startLatLng).add(endLatLng).width(15).color(Color.BLACK).geodesic(true);
        polylines.add(mMap.addPolyline(options));
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(startLatLng, 18));
    }
    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }
 
    @Override
    protected void onStop() {
        super.onStop();
        mGoogleApiClient.disconnect();
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
 
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        return super.onOptionsItemSelected(item);
    }
 
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
    }
 
    @Override
    public void onConnected(@Nullable Bundle bundle) {
        enableMyLocation();
    }
 
    @Override
    public void onConnectionSuspended(int i) {
 
    }
 
    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
 
    }
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        if (requestCode != LOCATION_PERMISSION_REQUEST_CODE) {
            return;
        }
 
        if (PermissionUtils.isPermissionGranted(permissions, grantResults,
                Manifest.permission.ACCESS_FINE_LOCATION)) {
            // Enable the my location layer if the permission has been granted.
            enableMyLocation();
        } else {
            // Display the missing permission error dialog when the fragments resume.
            mPermissionDenied = true;
        }
    }
    @Override
    public void onLocationChanged(Location location) {
        double latitude = location.getLatitude(), longtitude = location.getLongitude();
 
        if (mCurrentMarker != null) mCurrentMarker.remove();
        mCurrentLocation = location;
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(new LatLng(latitude, longtitude));
        mCurrentMarker =  mMap.addMarker(markerOptions);
 
 
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude()), 18));
        if(walkState){                        //걸음 시작 버튼이 눌렸을 때
                endLatLng = new LatLng(latitude, longtitude);        //현재 위치를 끝점으로 설정
                drawPath();                                            //polyline 그리기
                startLatLng = new LatLng(latitude, longtitude);        //시작점을 끝점으로 다시 설정
        }
    }
 
    private void enableMyLocation() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            // Permission to access the location is missing.
            PermissionUtils.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
                    Manifest.permission.ACCESS_FINE_LOCATION, true);
        } else if (mMap != null) {
            mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            // Start location updates.
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, this);
 
            if (mCurrentLocation != null) {
                Log.i("Location""Latitude: " + mCurrentLocation.getLatitude()
                        + ", Longitude: " + mCurrentLocation.getLongitude());
            }
        }
    }
    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10000);
        mLocationRequest.setFastestInterval(5000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }
}
 
cs

 

 

반응형
댓글