- package com.example.nemophila;
-
- import androidx.activity.result.ActivityResultLauncher;
- import androidx.activity.result.contract.ActivityResultContracts;
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
- import androidx.core.app.ActivityCompat;
- import androidx.core.content.ContextCompat;
- import androidx.core.content.res.ResourcesCompat;
- import androidx.fragment.app.DialogFragment;
- import androidx.fragment.app.Fragment;
- import androidx.lifecycle.Observer;
- import androidx.lifecycle.ViewModelProvider;
-
- import android.Manifest;
- import android.annotation.SuppressLint;
- import android.content.Intent;
- import android.content.pm.PackageManager;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.drawable.BitmapDrawable;
- import android.graphics.drawable.Drawable;
- import android.location.Location;
- import android.location.LocationListener;
- import android.location.LocationManager;
- import android.os.Bundle;
- import android.provider.Settings;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ImageButton;
- import android.widget.TextView;
- import android.widget.Toast;
-
- import com.example.nemophila.databinding.ActivityMainBinding;
- import com.example.nemophila.entities.Post;
- import com.example.nemophila.entities.Shop;
- import com.example.nemophila.viewmodels.FriendViewModel;
- 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.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;
- import com.google.android.gms.maps.model.CameraPosition;
- import com.google.android.gms.maps.model.GroundOverlay;
- import com.google.android.gms.maps.model.GroundOverlayOptions;
- import com.google.android.gms.maps.model.LatLng;
- import com.google.android.gms.maps.model.LatLngBounds;
- import com.google.android.gms.maps.model.Marker;
- import com.google.android.gms.maps.model.MarkerOptions;
- import com.google.common.collect.Maps;
-
- import java.util.ArrayList;
- import java.util.Map;
-
- public class MapsFragment extends Fragment implements LocationListener {
- ShopsViewModel shopsViewModel;
- FriendViewModel friendViewModel;
- PostsViewModel postsViewModel;
-
- Nemophila nemophila;
- private GoogleMap mMap;
- private ActivityMainBinding binding;
- private LatLng currentLatlng = null;
- private LatLng initialLatlng;
- private LatLng shopLatlng;
- // private LatLng testLatlng;
- // private LatLng testLatlng2;
- private LatLng tapLatlng;
- // private CameraPosition nowCamera;
- // private LatLng nowLatlng;
- private Marker currentMarker;
- private BitmapDescriptor bd;
- private boolean isLongClick;
-
-
- LocationManager locationManager;
-
- private OnMapReadyCallback callback = new OnMapReadyCallback() {
-
- @Override
- public void onMapReady(GoogleMap googleMap) {
-
- nemophila = (Nemophila) getActivity().getApplication();
- mMap = googleMap;
-
- //ViewModelへのアクセス
- shopsViewModel = new ViewModelProvider(getActivity()).get(ShopsViewModel.class);
- friendViewModel = new ViewModelProvider(getActivity()).get(FriendViewModel.class);
- postsViewModel = new ViewModelProvider(getActivity()).get(PostsViewModel.class);
-
-
- //フレンドの更新が入った時の処理(LiveDataへの購読)
- friendViewModel.getFriends(nemophila.getUid());
- friendViewModel.getFriendsLiveData().observe(getActivity(), friends -> {
- Toast.makeText(getActivity(),
- String.format("フレンドの更新を確認しました。"),
- Toast.LENGTH_SHORT)
- .show();
- //nemophilaにセットしておく
- nemophila.setFriends(friends);
- });
-
-
-
- // 店情報の更新が入った時の処理(LiveDataへの購読)
- shopsViewModel.getShopsLiveData().observe(getActivity(), shops -> {
- Toast.makeText(getActivity(),
- String.format("表示していない店を確認しました。ピンを立てます"),
- Toast.LENGTH_SHORT)
- .show();
-
- for (Shop shop : shops) {
- //受け取ったshopsにfriendsの投稿が含まれているかを確認,受け取ったshopsに対してMarkerが立っているかを確認
-
- //observeの中にobserveはうまくいかなかった
- // postsViewModel.loadShopPost(shop.getSid());
- // postsViewModel.getShopPostLiveData().observe(getActivity(), new Observer <ArrayList<Post>>() {
- // @Override
- // public void onChanged(ArrayList<Post> posts) {
- // ArrayList<String> ids = postsViewModel.getUserIds();
- //
- // for(int i = 0; i < ids.size(); i++) {
- // ArrayList<String> fids = nemophila.getFriendIds();
- // for(int j = 0; j < fids.size(); j++) {
- // if( ( ids.get(i).equals(fids.get(j)) || ids.get(i).equals(nemophila.getUid()) ) && shopsViewModel.getMarker(shop) == null ){
- // //各shopに対応するMarkerがなければMarkerを立てる
- // shopLatlng = new LatLng(shop.getLatitude(), shop.getLongitude());
- // System.out.println(shopLatlng);
- // Marker createMaker = mMap.addMarker(new MarkerOptions().position(shopLatlng).title(""));
- // //マーカーに店情報を持たせる
- // createMaker.setTag(shop);
- // //ShopToMarkerに紐づけ
- // shopsViewModel.setShopAndMarker(shop, createMaker);
- // }
- // }
- // }
- // }
- // });
-
- if ( shopsViewModel.getMarker(shop) == null) { //フレンド以外の投稿のピンも立てたい場合
- //if( && shopsViewModel.getMarker(shop) == null) {
-
- //各shopに対応するMarkerがなければMarkerを立てる
- shopLatlng = new LatLng(shop.getLatitude(), shop.getLongitude());
- System.out.println(shopLatlng);
- Marker createMaker = mMap.addMarker(new MarkerOptions().position(shopLatlng).title(""));
- //マーカーに店情報を持たせる
- createMaker.setTag(shop);
- //ShopToMarkerに紐づけ
- shopsViewModel.setShopAndMarker(shop, createMaker);
- }
- }
- });
-
- // 長押しを認識した後の処理(LiveDataへの購読)
- shopsViewModel.getNearShopsLiveData().observe(getActivity(), shops -> {
- Toast.makeText(getActivity(),
- String.format("近辺の店を確認しました。ダイアログを表示します"),
- Toast.LENGTH_SHORT)
- .show();
-
- //長押し時は周辺のピンを全て取得し、ダイアログに表示する
- DialogFragment dialogFragment = new MapsDialogFragment(shops);
- dialogFragment.show(getActivity().getSupportFragmentManager(),"mapsdialog");
- });
-
- //初期画面の座標(現在地をロードするまで表示)
- //initialLatlng = new LatLng(39,138);
- initialLatlng = new LatLng(nemophila.getCameraLatitude(), nemophila.getCameraLongitude());
- //初期画面に移動
- mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(initialLatlng, nemophila.getZoom()));
-
-
- //画面が動いたとき
- mMap.setOnCameraIdleListener(() -> {
- //カメラの座標とZOOM倍率を保存
- //nowCamera = mMap.getCameraPosition();
- nemophila.setCameraLatitude(mMap.getCameraPosition().target.latitude);
- nemophila.setCameraLongitude(mMap.getCameraPosition().target.longitude);
- nemophila.setZoom(mMap.getCameraPosition().zoom);
- //Shopの描画範囲を指定
- 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();
- });
-
-
- //長押し時に店を作成し、その座標にピンを立てる
- //長押し時にその座標を保存し、投稿画面に移り、Shop作成完了時にはピンを立て、Shop画面に移行
- mMap.setOnMapLongClickListener(longpushLocation -> {
- //長押しされた位置の緯度経度を取得
- //LatLng newlocation = new LatLng(longpushLocation.latitude, longpushLocation.longitude);
-
- //長押し座標を画面中心にしておく
- //zoomMap(longpushLocation.latitude, longpushLocation.longitude);
- //Nemophilaに座標を保存
- nemophila.setCurrentLatitude(longpushLocation.latitude);
- nemophila.setCurrentLongitude(longpushLocation.longitude);
- //長押しした場合は今からShopを作成するので、CurrentShopをnullで登録しておく
- nemophila.setCurrentShop(null);
-
- //長押しでダイアログを表示
- //テスト用
- //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);
- });
-
- // ピンをクリックした場合
- mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
- @Override
- public boolean onMarkerClick(Marker marker) {
- //店の詳細と投稿一覧を表示
- //ここでshopActivityを呼び出す
-
- //下からクリックしたことを通知
- //Toast.makeText(getActivity(), "ピンクリック", Toast.LENGTH_SHORT).show();
-
- //現在地マーカーをクリックしたときのみ例外
- if(marker.getTag() == null) {
- //以下の処理をストップ
- return false;
- }
-
- //選んだ店をsetする
- nemophila.setCurrentShop((Shop) marker.getTag());
- System.out.println(nemophila.getCurrentShop().getName());
-
- //ShopActivity画面に遷移
- Intent intent = new Intent(getActivity(), ShopActivity.class);
- startActivity(intent);
-
- return false;
- }
- });
- }
- };
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater,
- @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
-
-
- return inflater.inflate(R.layout.fragment_maps, container, false);
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- //binding = ActivityMainBinding.inflate(getLayoutInflater());
- //getActivity().setContentView(binding.getRoot());
-
- if (ActivityCompat.checkSelfPermission(
- getContext(),
- Manifest.permission.ACCESS_FINE_LOCATION)
- != PackageManager.PERMISSION_GRANTED) {
-
- requestPermissionLauncher.launch(
- Manifest.permission.ACCESS_FINE_LOCATION);
- }
- else{
- locationStart();
- }
-
- // // Obtain the SupportMapFragment and get notified when the map is ready to be used.
- // SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
- // .findFragmentById(R.id.map);
- // assert mapFragment != null;
- // mapFragment.getMapAsync(this);
-
- SupportMapFragment mapFragment =
- (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
- if (mapFragment != null) {
- mapFragment.getMapAsync(callback);
- }
-
- //現在地アイコン用の準備
- Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_current);
- Bitmap afterBitmap = Bitmap.createScaledBitmap(bitmap, 100, 100, true);
- bd = BitmapDescriptorFactory.fromBitmap(afterBitmap);
- }
-
-
- private void zoomMap(double latitude, double longitude) {
- // 表示する東西南北の緯度経度を設定
- double south = latitude * (1 - 0.00005);
- double west = longitude * (1 - 0.00005);
- double north = latitude * (1 + 0.00005);
- double east = longitude * (1 + 0.00005);
-
- LatLng latlng = new LatLng(latitude, longitude);
-
- // LatLngBounds (LatLng southwest, LatLng northeast)
- //左下、右上
- LatLngBounds bounds = LatLngBounds.builder()
- .include(new LatLng(south, west))
- .include(new LatLng(north, east))
- .build();
-
- int width = getResources().getDisplayMetrics().widthPixels;
- int height = getResources().getDisplayMetrics().heightPixels;
-
- // static CameraUpdate.newLatLngBounds(LatLngBounds bounds, int width, int height, int padding)
- mMap.moveCamera(CameraUpdateFactory.
- newLatLngBounds(bounds, width, height, 0));
-
- //ズーム処理
- mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, nemophila.getZoom()));
- }
-
- //現在地の表示
- private void setIcon(double latitude, double longitude) {
- //現在地をLatLng型で取得
- LatLng current_location = new LatLng(latitude, longitude);
-
- //初回現在地取得時
- if (currentMarker == null) {
- currentMarker=mMap.addMarker(new MarkerOptions().position(current_location).title("現在地").icon(bd));
- } else {
- //2回目移行
- currentMarker.setPosition(current_location);
- }
- }
-
-
- private final ActivityResultLauncher<String>
- requestPermissionLauncher = registerForActivityResult(
- new ActivityResultContracts.RequestPermission(),
- isGranted -> {
- if (isGranted) {
- locationStart();
- }
- else {
- Toast toast = Toast.makeText(getActivity(),
- "これ以上なにもできません", Toast.LENGTH_SHORT);
- toast.show();
- }
- });
-
- //現在地の取得
- @SuppressLint("MissingPermission")
- private void locationStart(){
- Log.d("debug","locationStart()");
-
- // LocationManager インスタンス生成
- locationManager =
- (LocationManager) getContext().getSystemService(getContext().LOCATION_SERVICE);
-
- if (locationManager != null && locationManager.isProviderEnabled(
- LocationManager.GPS_PROVIDER)) {
-
- Log.d("debug", "location manager Enabled");
- } else {
- // GPSを設定するように促す
- Intent settingsIntent =
- new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
- startActivity(settingsIntent);
- Log.d("debug", "not gpsEnable, startActivity");
- }
-
- if (ContextCompat.checkSelfPermission(getContext(),
- Manifest.permission.ACCESS_FINE_LOCATION) !=
- PackageManager.PERMISSION_GRANTED) {
- ActivityCompat.requestPermissions(getActivity(),
- new String[]{Manifest.permission.ACCESS_FINE_LOCATION,}, 1000);
-
- Log.d("debug", "checkSelfPermission false");
- return;
- }
-
- locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
- 1000, 50, this);
-
- }
-
- @Override
- public void onLocationChanged(Location location) {
- //初期画面は現在地を中心にするため...
- 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 -> {
- 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());
- }
-
- @Override
- public void onProviderEnabled(String provider) {
-
- }
-
- @Override
- public void onProviderDisabled(String provider) {
-
- }
-
- }