地図を表示させるアプリを作ろう!Android studio を使って地図に吹き出しのピンを立てる方法

Android

本日は、Android Studioを使って地図に吹き出しのピンを立てる方法について説明します。

なお、地図の作り方はこちらの記事を参照してください。

地図を作る準備ができたら、ピンを立てる方法について紹介したいと思います。

地図にピンを立てる

地図にピンを立てる方法はいろとありますが、前回ビットマップ画像を作成してそこにピンを立てる方法について紹介しました。これはこれでカスタマイズ性があって良いですが、多くなると重くなったりするなど面倒なことが起こります。

詳しくは上のリンクをご覧ください

IconGeneratorを使用する

ここで、便利なライブラリーを使います。それがIconGeneratorです。それでは、使い方を見てゆきましょう。

まずは、Gradleに以下のコードを書きます。現時点ではまだ、このコードで良いと思うのですが最新のものを書き込んだ方が無難です。

    implementation 'com.google.maps.android:android-maps-utils:2.2.3'

上のコードをコピペして貼り付けても大丈夫です。

続いて、コードを貼り付けたら一旦シンクさせます。

続いてValuesというフォルダを開いてstyle.xmlのリソースファイルを作成します。

こんな感じですね。

そして、作成したXMLファイルを開き以下の内容を書き込みます。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="iconGenText">
        <item name="android:textSize">10sp</item>
        <item name="android:textColor">#000000</item>
    </style>
</resources>

これは何をやっているのかというと、吹き出しのフォントのレイアウトなどを定義しているのですね。

なので文字サイズを大きくしたいときはtextSizeを大きくします。

続いて、メインアクティブティに戻って

package com.example.map1;

import static android.content.ContentValues.TAG;

import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.Log;

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.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.example.map1.databinding.ActivityMapsBinding;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import com.google.maps.android.ui.IconGenerator;

import java.util.HashMap;
import java.util.Map;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private ActivityMapsBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMapsBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        createNewData();

    }

    public void createNewData(){
        FirebaseFirestore db = FirebaseFirestore.getInstance();

        // Create a new user with a first and last name
        Map<String, Object> user = new HashMap<>();
        user.put("positionX", -20);
        user.put("positionY", 162);
        user.put("title", "OK Google");
        user.put("markerTitle", "Fuck you!");

    // Add a new document with a generated ID
        db.collection("users")
                .add(user)
                .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                    @Override
                    public void onSuccess(DocumentReference documentReference) {
                        Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId());
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.w(TAG, "Error adding document", e);
                    }
                });
        readData(db);
    }
    public void readData(FirebaseFirestore db){
        db.collection("users")
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()) {
                            for (QueryDocumentSnapshot document : task.getResult()) {
                                Log.d(TAG, document.getId() + " => " + document.getData());
                            }
                        } else {
                            Log.w(TAG, "Error getting documents.", task.getException());
                        }
                    }
                });
    }

    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney").icon(getTextMarker("Hello")));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
        setMarkerOnMap(-20,162,"Ok google","Fuck you!");
        setMarkerOnMap(-19,162,"Ok google","Fuck you!");
        setMarkerOnMap(-18,162,"Ok google","Fuck you!");
        setMarkerOnMap(-17,162,"Ok google","Fuck you!");
        setMarkerOnMap(-16,162,"Ok google","Fuck you!");

    }
    public void setMarkerOnMap(int positionX, int positionY,String title, String markerTitle){
        IconGenerator icg = new IconGenerator(this);
        icg.setColor(Color.WHITE); // green background
        icg.setTextAppearance(R.style.iconGenText); // black text
        Bitmap bm = icg.makeIcon(markerTitle);
        // Add a marker in Sydney and move the camera
        LatLng position = new LatLng(positionX, positionY);
        mMap.addMarker(new MarkerOptions().position(position).title(title).icon(BitmapDescriptorFactory.fromBitmap(bm)));
        //mMap.moveCamera(CameraUpdateFactory.newLatLng(position));
    }

}

これを書き込みます。

特に重要なのがsetMarkerOnMapメソッドの

    public void setMarkerOnMap(int positionX, int positionY,String title, String markerTitle){
        IconGenerator icg = new IconGenerator(this);
        icg.setColor(Color.WHITE); // green background
        icg.setTextAppearance(R.style.iconGenText); // black text
        Bitmap bm = icg.makeIcon(markerTitle);
        // Add a marker in Sydney and move the camera
        LatLng position = new LatLng(positionX, positionY);
        mMap.addMarker(new MarkerOptions().position(position).title(title).icon(BitmapDescriptorFactory.fromBitmap(bm)));
        //mMap.moveCamera(CameraUpdateFactory.newLatLng(position));
    }

この部分ですね、positionX、positionYに座標をtitleにクリックしたときに表示される文字列をmarkerTitleには吹き出しマーカーに表示される文字列を渡します。

これはonMapReadyが呼び出された後に必ず行ってください。そうしないとエラーになります。

んで、実際にビルドしてみると

こんな感じで表示されました。

タイトルとURLをコピーしました