| |
---|
| | import android.graphics.drawable.Drawable; |
---|
| | import android.location.Location; |
---|
| | import android.location.LocationListener; |
---|
| | import android.location.LocationManager; |
---|
| | import android.os.AsyncTask; |
---|
| | import android.os.Bundle; |
---|
| | import android.provider.Settings; |
---|
| | import android.util.Log; |
---|
| | import android.view.LayoutInflater; |
---|
| |
---|
| | import android.widget.ImageButton; |
---|
| | import android.widget.TextView; |
---|
| | import android.widget.Toast; |
---|
| | |
---|
| | import android.content.Context; |
---|
| | import android.location.Address; |
---|
| | import android.location.Geocoder; |
---|
| | import android.text.TextUtils; |
---|
| | import java.io.IOException; |
---|
| | import java.util.List; |
---|
| | import java.util.Locale; |
---|
| | |
---|
| | import com.example.nemophila.databinding.ActivityMainBinding; |
---|
| | import com.example.nemophila.entities.AccountNameJson; |
---|
| | import com.example.nemophila.entities.Post; |
---|
| | import com.example.nemophila.entities.Shop; |
---|
| |
---|
| | import com.example.nemophila.viewmodels.PostsViewModel; |
---|
| | import com.example.nemophila.viewmodels.ShopsViewModel; |
---|
| | import com.google.android.gms.maps.CameraUpdateFactory; |
---|
| | import com.google.android.gms.maps.GoogleMap; |
---|
| | import com.google.maps.*; |
---|
| | import com.google.maps.model.GeocodingResult; |
---|
| | import com.google.android.gms.maps.OnMapReadyCallback; |
---|
| | import com.google.android.gms.maps.SupportMapFragment; |
---|
| | import com.google.android.gms.maps.model.BitmapDescriptor; |
---|
| | import com.google.android.gms.maps.model.BitmapDescriptorFactory; |
---|
| |
---|
| | PostsViewModel postsViewModel; |
---|
| | |
---|
| | Nemophila nemophila; |
---|
| | private GoogleMap mMap; |
---|
| | private GeoApiContext geoApiContext; |
---|
| | private ActivityMainBinding binding; |
---|
| | private LatLng currentLatlng = null; |
---|
| | private LatLng initialLatlng; |
---|
| | private LatLng shopLatlng; |
---|
| |
---|
| | } |
---|
| | }); |
---|
| | |
---|
| | |
---|
| | |
---|
| | // 店情報の更新が入った時の処理(LiveDataへの購読) |
---|
| | shopsViewModel.getShopsLiveData().observe(getActivity(), shops -> { |
---|
| | Toast.makeText(getActivity(), |
---|
| | String.format("表示していない店を確認しました。ピンを立てます"), |
---|
| | Toast.LENGTH_SHORT) |
---|
| | .show(); |
---|
| | for (Shop shop : shops) { |
---|
| | if ( shopsViewModel.getMarker(shop) == null) { //フレンド以外の投稿のピンも立てたい場合 |
---|
| | //各shopに対応するMarkerがなければMarkerを立てる |
---|
| | shopLatlng = new LatLng(shop.getLatitude(), shop.getLongitude()); |
---|
| | System.out.println(shopLatlng); |
---|
| | Marker createMarker = mMap.addMarker(new MarkerOptions().position(shopLatlng).title("")); |
---|
| | //マーカーに店情報を持たせる |
---|
| | createMarker.setTag(shop); |
---|
| | |
---|
| | //ShopToMarkerに紐づけ |
---|
| | shopsViewModel.setShopAndMarker(shop, createMarker); |
---|
| | System.out.println(friendsData); |
---|
| | |
---|
| | ArrayList<String> userIdSet = (ArrayList<String>)shop.getUserIdSet().clone(); |
---|
| | friendsData.add(nemophila.getUid()); |
---|
| | userIdSet.retainAll(friendsData); |
---|
| | |
---|
| | //自分とそのフレンド以外の投稿は確認しない |
---|
| | if( userIdSet.size() > 0) { |
---|
| | //場合分け |
---|
| | //フィルターを一切かけていないとき |
---|
| | if(nemophila.getSelectGenres().isEmpty() && nemophila.getSelectFriends().isEmpty()){ |
---|
| | createMarker.setVisible(true); |
---|
| | for (Shop shop : shops) { |
---|
| | if (shopsViewModel.getMarker(shop) == null) { //フレンド以外の投稿のピンも立てたい場合 |
---|
| | //各shopに対応するMarkerがなければMarkerを立てる |
---|
| | shopLatlng = new LatLng(shop.getLatitude(), shop.getLongitude()); |
---|
| | System.out.println(shopLatlng); |
---|
| | Marker createMarker = mMap.addMarker(new MarkerOptions().position(shopLatlng).title("")); |
---|
| | //マーカーに店情報を持たせる |
---|
| | createMarker.setTag(shop); |
---|
| | |
---|
| | //ShopToMarkerに紐づけ |
---|
| | shopsViewModel.setShopAndMarker(shop, createMarker); |
---|
| | System.out.println(friendsData); |
---|
| | |
---|
| | ArrayList<String> userIdSet = (ArrayList<String>) shop.getUserIdSet().clone(); |
---|
| | friendsData.add(nemophila.getUid()); |
---|
| | userIdSet.retainAll(friendsData); |
---|
| | |
---|
| | //自分とそのフレンド以外の投稿は確認しない |
---|
| | if (userIdSet.size() > 0) { |
---|
| | //場合分け |
---|
| | //フィルターを一切かけていないとき |
---|
| | if (nemophila.getSelectGenres().isEmpty() && nemophila.getSelectFriends().isEmpty()) { |
---|
| | createMarker.setVisible(true); |
---|
| | } |
---|
| | //ジャンルのみフィルターをかけているとき |
---|
| | else if (nemophila.getSelectFriends().isEmpty()) { |
---|
| | for (String genre : nemophila.getSelectGenres()) { |
---|
| | if (shop.getGenreSet().contains(genre)) { |
---|
| | createMarker.setVisible(true); |
---|
| | break; |
---|
| | } else { |
---|
| | createMarker.setVisible(false); |
---|
| | } |
---|
| | } |
---|
| | //ジャンルのみフィルターをかけているとき |
---|
| | else if(nemophila.getSelectFriends().isEmpty()) { |
---|
| | for(String genre : nemophila.getSelectGenres()) { |
---|
| | if(shop.getGenreSet().contains(genre)) { |
---|
| | } |
---|
| | //フレンドのみフィルターをかけているとき |
---|
| | else if (nemophila.getSelectGenres().isEmpty()) { |
---|
| | for (String friendId : nemophila.getSelectFriends()) { |
---|
| | if (shop.getUserIdSet().contains(friendId)) { |
---|
| | createMarker.setVisible(true); |
---|
| | break; |
---|
| | } else { |
---|
| | createMarker.setVisible(false); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | //どちらもフィルターをかけているとき |
---|
| | else { |
---|
| | for (String genre : nemophila.getSelectGenres()) { |
---|
| | for (String friendId : nemophila.getSelectFriends()) { |
---|
| | if (shop.getGenreSet().contains(genre) && shop.getUserIdSet().contains(friendId)) { |
---|
| | createMarker.setVisible(true); |
---|
| | break; |
---|
| | } else { |
---|
| | createMarker.setVisible(false); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | //フレンドのみフィルターをかけているとき |
---|
| | else if(nemophila.getSelectGenres().isEmpty()) { |
---|
| | for(String friendId : nemophila.getSelectFriends()) { |
---|
| | if(shop.getUserIdSet().contains(friendId)) { |
---|
| | createMarker.setVisible(true); |
---|
| | break; |
---|
| | } else { |
---|
| | createMarker.setVisible(false); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | //どちらもフィルターをかけているとき |
---|
| | else { |
---|
| | for(String genre : nemophila.getSelectGenres()) { |
---|
| | for(String friendId : nemophila.getSelectFriends()) { |
---|
| | if (shop.getGenreSet().contains(genre) && shop.getUserIdSet().contains(friendId)) { |
---|
| | createMarker.setVisible(true); |
---|
| | break; |
---|
| | } else { |
---|
| | createMarker.setVisible(false); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | } else { |
---|
| | createMarker.setVisible(false); |
---|
| | } |
---|
| | } else { |
---|
| | createMarker.setVisible(false); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | }); |
---|
| | |
---|
| | // 長押しを認識した後の処理(LiveDataへの購読) |
---|
| | shopsViewModel.getNearShopsLiveData().observe(getActivity(), shops -> { |
---|
| |
---|
| | String.format("近辺の店を確認しました。ダイアログを表示します"), |
---|
| | Toast.LENGTH_SHORT) |
---|
| | .show(); |
---|
| | |
---|
| | //長押し時は周辺のピンを全て取得し、ダイアログに表示する |
---|
| | DialogFragment dialogFragment = new MapsDialogFragment(shops); |
---|
| | dialogFragment.show(getActivity().getSupportFragmentManager(),"mapsdialog"); |
---|
| | //長押し時は周辺のピンを全て取得し、ダイアログに表示する |
---|
| | DialogFragment dialogFragment = new MapsDialogFragment(shops); |
---|
| | dialogFragment.show(getActivity().getSupportFragmentManager(), "mapsdialog"); |
---|
| | }); |
---|
| | |
---|
| | //初期画面の座標(現在地をロードするまで表示) |
---|
| | //initialLatlng = new LatLng(39,138); |
---|
| |
---|
| | shopsViewModel.setViewArea(nemophila.getCameraLongitude() + 1, nemophila.getCameraLatitude() + 1, nemophila.getCameraLongitude() - 1, nemophila.getCameraLatitude() - 1); |
---|
| | }); |
---|
| | |
---|
| | |
---|
| | // test用 座標を確認するため |
---|
| | // タップした時のリスナーをセット |
---|
| | mMap.setOnMapClickListener(tapLocation -> { |
---|
| | // map(ピン以外)をtapされた位置の緯度経度 |
---|
| | tapLatlng = new LatLng(tapLocation.latitude, tapLocation.longitude); |
---|
| | Toast.makeText(getActivity(), |
---|
| | String.format("%s", tapLatlng), |
---|
| | Toast.LENGTH_SHORT) |
---|
| | .show(); |
---|
| | }); |
---|
| | // test用 座標を確認するため |
---|
| | // タップした時のリスナーをセット |
---|
| | mMap.setOnMapClickListener(tapLocation -> { |
---|
| | // map(ピン以外)をtapされた位置の緯度経度 |
---|
| | tapLatlng = new LatLng(tapLocation.latitude, tapLocation.longitude); |
---|
| | Toast.makeText(getActivity(), |
---|
| | String.format("%s", tapLatlng), |
---|
| | Toast.LENGTH_SHORT) |
---|
| | .show(); |
---|
| | }); |
---|
| | |
---|
| | |
---|
| | //長押し時に店を作成し、その座標にピンを立てる |
---|
| | //長押し時にその座標を保存し、投稿画面に移り、Shop作成完了時にはピンを立て、Shop画面に移行 |
---|
| |
---|
| | //長押しでダイアログを表示 |
---|
| | //テスト用 |
---|
| | //shopsViewModel.longClickViewArea(longpushLocation.longitude+1, longpushLocation.latitude+1, longpushLocation.longitude-1, longpushLocation.latitude-1); |
---|
| | //本番環境は↓の範囲で |
---|
| | shopsViewModel.longClickViewArea(longpushLocation.longitude+0.001, longpushLocation.latitude+0.001, longpushLocation.longitude-0.001, longpushLocation.latitude-0.001); |
---|
| | shopsViewModel.longClickViewArea(longpushLocation.longitude + 0.001, longpushLocation.latitude + 0.001, longpushLocation.longitude - 0.001, longpushLocation.latitude - 0.001); |
---|
| | }); |
---|
| | |
---|
| | // ピンをクリックした場合 |
---|
| | mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { |
---|
| | @Override |
---|
| | public boolean onMarkerClick(Marker marker) { |
---|
| | //現在地マーカーをクリックしたときのみ例外 |
---|
| | if(marker.getTag() == null) { |
---|
| | if (marker.getTag() == null) { |
---|
| | //以下の処理をストップ |
---|
| | return false; |
---|
| | } |
---|
| | |
---|
| |
---|
| | != PackageManager.PERMISSION_GRANTED) { |
---|
| | |
---|
| | requestPermissionLauncher.launch( |
---|
| | Manifest.permission.ACCESS_FINE_LOCATION); |
---|
| | } |
---|
| | else{ |
---|
| | } else { |
---|
| | locationStart(); |
---|
| | } |
---|
| | |
---|
| | ((MapsActivity) getContext()).setMapsFragment(this); |
---|
| |
---|
| | bd = BitmapDescriptorFactory.fromBitmap(afterBitmap); |
---|
| | } |
---|
| | |
---|
| | |
---|
| | private void zoomMap(double latitude, double longitude) { |
---|
| | public void zoomMap(double latitude, double longitude) { |
---|
| | // 表示する東西南北の緯度経度を設定 |
---|
| | double south = latitude * (1 - 0.00005); |
---|
| | double west = longitude * (1 - 0.00005); |
---|
| | double north = latitude * (1 + 0.00005); |
---|
| |
---|
| | LatLng current_location = new LatLng(latitude, longitude); |
---|
| | |
---|
| | //初回現在地取得時 |
---|
| | if (currentMarker == null) { |
---|
| | currentMarker=mMap.addMarker(new MarkerOptions().position(current_location).title("現在地").icon(bd)); |
---|
| | currentMarker = mMap.addMarker(new MarkerOptions().position(current_location).title("現在地").icon(bd)); |
---|
| | } else { |
---|
| | //2回目移行 |
---|
| | currentMarker.setPosition(current_location); |
---|
| | } |
---|
| |
---|
| | new ActivityResultContracts.RequestPermission(), |
---|
| | isGranted -> { |
---|
| | if (isGranted) { |
---|
| | locationStart(); |
---|
| | } |
---|
| | else { |
---|
| | } else { |
---|
| | Toast toast = Toast.makeText(getActivity(), |
---|
| | "これ以上なにもできません", Toast.LENGTH_SHORT); |
---|
| | toast.show(); |
---|
| | } |
---|
| | }); |
---|
| | |
---|
| | //現在地の取得 |
---|
| | @SuppressLint("MissingPermission") |
---|
| | private void locationStart(){ |
---|
| | Log.d("debug","locationStart()"); |
---|
| | private void locationStart() { |
---|
| | Log.d("debug", "locationStart()"); |
---|
| | |
---|
| | // LocationManager インスタンス生成 |
---|
| | locationManager = |
---|
| | (LocationManager) getContext().getSystemService(getContext().LOCATION_SERVICE); |
---|
| |
---|
| | |
---|
| | @Override |
---|
| | public void onLocationChanged(Location location) { |
---|
| | //初期画面は現在地を中心にするため... |
---|
| | if (currentLatlng == null){ |
---|
| | if (currentLatlng == null) { |
---|
| | //↓現在地ロード後画面中心を現在地にする場合 |
---|
| | //zoomMap(location.getLatitude(), location.getLongitude()); |
---|
| | //ロード画面の終了 |
---|
| | //getView().findViewById(R.id.LL_Load).setVisibility(View.GONE); |
---|
| |
---|
| | //現在地ボタンを表示 |
---|
| | getView().findViewById(R.id.currentButton).setVisibility(View.VISIBLE); |
---|
| | ImageButton button1 = getView().findViewById(R.id.currentButton); |
---|
| | |
---|
| | button1.setOnClickListener( v -> { |
---|
| | button1.setOnClickListener(v -> { |
---|
| | Log.d("debug", "currentbutton, 現在地にカメラを移動"); |
---|
| | System.out.println(shopsViewModel.getShopsLiveData().getValue()); |
---|
| | //現在地にカメラを移動 |
---|
| | zoomMap(currentLatlng.latitude, currentLatlng.longitude); |
---|
| |
---|
| | //LatLng型で受け取っておく |
---|
| | currentLatlng = new LatLng(location.getLatitude(), location.getLongitude()); |
---|
| | |
---|
| | //現在地アイコンを表示.このsetIcon内にzoomMap処理もあるので注意 |
---|
| | setIcon(location.getLatitude(),location.getLongitude()); |
---|
| | setIcon(location.getLatitude(), location.getLongitude()); |
---|
| | } |
---|
| | |
---|
| | //住所・施設名などから緯度経度を検索するメソッド |
---|
| | public void SeachLocation(String seachText) { |
---|
| | // Geocoderを使用して緯度経度を取得し移動 |
---|
| | LatLng latLng = getLatLngFromAddress(seachText); |
---|
| | if (latLng != null) { |
---|
| | System.out.println("-------検索地点の座標取得完了!--------"); |
---|
| | System.out.println("緯度: " + latLng.latitude + "\n経度: " + latLng.longitude); |
---|
| | System.out.println("-----------------------------------"); |
---|
| | |
---|
| | Toast.makeText(getActivity(), |
---|
| | String.format("該当の地点に移動します"), |
---|
| | Toast.LENGTH_SHORT) |
---|
| | .show(); |
---|
| | nemophila.setZoom(18f); |
---|
| | zoomMap(latLng.latitude, latLng.longitude); |
---|
| | } else { |
---|
| | //緯度経度取得ミス |
---|
| | System.out.println("-------検索地点の座標取得失敗--------"); |
---|
| | Toast.makeText(getActivity(), |
---|
| | String.format("該当の地点が見つかりませんでした"), |
---|
| | Toast.LENGTH_SHORT) |
---|
| | .show(); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | // 住所から緯度経度を取得するメソッド |
---|
| | private LatLng getLatLngFromAddress(String address) { |
---|
| | Geocoder geocoder = new Geocoder(requireContext(), Locale.getDefault()); |
---|
| | try { |
---|
| | List<Address> addresses = geocoder.getFromLocationName(address, 1); |
---|
| | if (addresses != null && !addresses.isEmpty()) { |
---|
| | Address firstAddress = addresses.get(0); |
---|
| | double latitude = firstAddress.getLatitude(); |
---|
| | double longitude = firstAddress.getLongitude(); |
---|
| | return new LatLng(latitude, longitude); |
---|
| | } |
---|
| | } catch (IOException e) { |
---|
| | e.printStackTrace(); |
---|
| | } |
---|
| | return null; |
---|
| | } |
---|
| | |
---|
| | @Override |
---|
| | public void onProviderEnabled(String provider) { |
---|
| |
---|
| | |
おねがい
住所・地名・施設名などで検索を行い、画面の地図を移動させられるようにしました
ea018ef
intomaster
fromsearch_location
on 5 Oct 2023search_location
branch on 5 Oct 2023