14 January 2013

Google Maps Android API v2 - เปลี่ยนภาพ Marker ใน Google Maps

Updated on
รอบนี้ก็ขอต่อจากเรื่อง Marker ของ Google Maps เลยละกัน
คราวนี้ก็จะเป็นการเปลี่ยนภาพ Marker ที่ใช้ปักลงบนแผนที่
สามารถเปลี่ยนสีหรือเปลี่ยนเป็นภาพอะไรก็ได้ตามใจชอบ


สำหรับการติดตั้งเบื้องต้นเพื่อจะใช้งาน API v2 ให้อ่านที่

โดยปกติแล้ว Marker เดิมของ Google Maps จะใช้ภาพนี้



ถ้าผู้ที่หลงเข้ามาอ่านอยากเปลี่ยนภาพ Marker ก็ใช้คำสั่ง icon ได้เลย
GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager()
    .findFragmentById(R.id.map)).getMap();

mMap.addMarker(new MarkerOptions().position(
    new LatLng(13.751, 100.534))
    .icon(BitmapDescriptorFactory.fromAsset("marker_icon.png"))
    .title("Asset"));

โดยที่ marker_icon.png คือไฟล์ภาพที่เจ้าของบล็อกใช้เป็น Marker
ซึ่งทำขึ้นมาเองแล้วเอาไปไว้ในโฟลเดอร์ assets ของโปรเจค



ในกรณีที่ผู้ที่หลงเข้ามาอ่านจะใช้ภาพใน drawable ก็เปลี่ยนมาใช้คำสั่งตามนี้
GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager()
    .findFragmentById(R.id.map)).getMap();

mMap.addMarker(new MarkerOptions().position(
    new LatLng(13.751, 100.535))
    .icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_icon))
    .title("Drawable"));

ส่วนไฟล์ภาพก็เอามาไว้ใน drawable หรือว่าจะแยกตามหน้าจอก็ได้


นอกจาก assets และ drawable ก็จะมี bitmap กับ file ด้วย
แต่เจ้าของบล็อกไม่ลงตัวอย่างนะ เพราะไม่ค่อยได้ใช้
โดยภาพที่ใช้ในบทความนี้จะเป็นภาพ Marker ที่ลองวาดเล่นๆ



ในกรณีที่ไม่อยากเปลี่ยนภาพแต่อยากเปลี่ยนสีจากของเดิม
ก็จะมีสีให้เลือกอยู่ในระดับหนึ่งแล้ว ทั้งหมด 10 สี ดังนี้


เวลาจะเปลี่ยนสี Marker ให้เป็นสีดังกล่าว ก็ให้ใช้คำสั่ง
GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager()
    .findFragmentById(R.id.map)).getMap();
mMap.addMarker(new MarkerOptions().position(
    new LatLng(13.745, 100.534))
    .icon(BitmapDescriptorFactory.defaultMarker(
    BitmapDescriptorFactory.HUE_AZURE)));

ทีนี้ก็มาดูตัวอย่างของบทความนี้กันเลยดีกว่า

Main.java


1. ประกาศ mMap จากคลาส GoogleMap แล้วกำหนดค่าเป็น R.id.map ที่สร้างไว้ใน Layout

2. กำหนดให้แผนที่เลื่อนไปยังพิกัด 13.750, 100.100.53440 แล้วซูมเข้าไปที่ระดับ 16

3. ปัก Marker ที่พิกัด 13.751, 100.534 โดยใช้ภาพจาก assets/marker_icon.png
จากนั้นก็กำหนดข้อความให้กับ Marker ว่า "Asset" เพื่อให้แสดงว่าเป็นภาพจาก assets

4. ปัก Marker ที่พิกัด 13.751, 100.535 โดยใช้ภาพจาก drwable/marker_icon.png
จากนั้นก็กำหนดข้อความให้กับ Marker ว่า "Drawable" เพื่อให้แสดงว่าเป็นภาพจาก drawable

5. ปัก Marker ที่พิกัด 13.745, 100.534 โดยให้ Marker เปลี่ยนเป็นสี Azure


พอลองทดสอบดูก็จะพบว่ามี Marker เรียงอยู่ตามที่กำหนดไว้เลย






สำหรับพิกัดบนแผนที่ ผู้ที่หลงเข้ามาอ่านสามารถใช้ Coordinate Finder
ในการช่วยหาพิกัดได้นะ เปิดแอพขึ้นมาแล้วจิ้มเลือกที่ที่ต้องการเลย
สามารถดาวน์โหลดได้จาก Coordinate Finder [Play Store]




Main.java
package app.akexorcist.googlemapsv2markericon;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
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 android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Window;

public class Main extends FragmentActivity {    
    public void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
                
        GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();

        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(13.750, 100.53440), 16));    

        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.751, 100.534))
                .icon(BitmapDescriptorFactory
                        .fromAsset("marker_icon.png"))
                .title("Asset"));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.751, 100.535))
                .icon(BitmapDescriptorFactory
                        .fromResource(R.drawable.marker_icon))
                .title("Drawable"));
        
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.745, 100.534))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_AZURE)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.746, 100.534))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_BLUE)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.747, 100.534))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_CYAN)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.748, 100.534))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_GREEN)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.749, 100.534))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_MAGENTA)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.745, 100.535))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_ORANGE)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.746, 100.535))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_RED)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.747, 100.535))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_ROSE)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.748, 100.535))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_VIOLET)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.749, 100.535))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_YELLOW)));
    }
}

main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"  >

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment"/>
    
</RelativeLayout>

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="app.akexorcist.googlemapsv2markericon"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="8" />
    
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name=
        "com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
      <uses-permission android:name=
        "app.akexorcist.googlemapsv2markericon.permission.MAPS_RECEIVE"/>
      
    <permission 
        android:name=
                "app.akexorcist.googlemapsv2markericon.permission.MAPS_RECEIVE"
        android:protectionLevel="signature"/>
    
    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="app.akexorcist.googlemapsv2markericon.Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <meta-data
           android:name="com.google.android.maps.v2.API_KEY"
           android:value="your_api_key"/>
    </application>
</manifest>


สำหรับผู้ที่หลงเข้ามาอ่านคนใดที่ต้องการไฟล์ตัวย่าง
สามารถดาวน์โหลดได้จาก Google Maps V2 Marker Icon

เมื่อดาวน์โหลดตัวอย่างไป Import แล้วให้ตรวจสอบตามนี้
• ใส่ API Key ที่ไปขอจาก Google API ลงใน AndroidManifest.xml
• เลือก Library ของ google-play-services_lib ให้ตรงกับเครื่อง

อาจจะมีปัญหาพอสมควรสำหรับผู้ที่ดาวน์โหลดไปทดสอบ
เพราะว่าการใช้ Google Maps นี้มีการขอ API Key และ Library
ดังนั้นจึงควรตรวจสอบให้แน่ใจว่าได้กำหนดไว้ถูกต้องแล้ว 
และก็อย่าลืมว่าทดสอบบน AVD หรือ Emulator ไม่ได้นะ
เพราะต้องมี Play Store ซึ่ง AVD ไม่มี ทำให้แอป Force Close