การวางซ้อนของชิ้นส่วนแผนที่

เลือกแพลตฟอร์ม: Android iOS JavaScript

การวางซ้อนของชิ้นส่วนแผนที่ ซึ่งบางครั้งเรียกว่าเลเยอร์ของชิ้นส่วน คือคอลเล็กชันรูปภาพที่แสดงที่ด้านบนของชิ้นส่วนแผนที่ฐาน

ตัวอย่างโค้ด

ที่เก็บ ApiDemos ใน GitHub มีตัวอย่างที่สาธิตฟีเจอร์การวางซ้อนแบบไทล์ ดังนี้

  • TileOverlayDemoActivity - Java: ฟีเจอร์การวางซ้อนของชิ้นส่วนแผนที่ใน Java
  • TileCoordinateDemoActivity - Java: ระบบพิกัดที่ใช้สำหรับการวางซ้อนของชิ้นส่วนแผนที่ใน Java
  • TileOverlayDemoActivity - Kotlin: ฟีเจอร์การวางซ้อนของชิ้นส่วนแผนที่ใน Kotlin
  • TileCoordinateDemoActivity - Kotlin: ระบบพิกัดที่ใช้สำหรับการวางซ้อนของชิ้นส่วนแผนที่ใน Kotlin

เกริ่นนำ

TileOverlay กำหนดชุดรูปภาพที่เพิ่มที่ด้านบนของชิ้นส่วนแผนที่ฐาน

คุณต้องระบุไทล์สําหรับการซูมแต่ละระดับที่ต้องการรองรับ หากมีชิ้นส่วนข้อมูลเพียงพอสำหรับการซูมหลายระดับ คุณจะเพิ่มข้อมูลแผนที่ของ Google สําหรับแผนที่ทั้งหมดได้

การวางซ้อนของชิ้นส่วนแผนที่มีประโยชน์เมื่อคุณต้องการเพิ่มภาพขนาดใหญ่ลงในแผนที่ ซึ่งโดยปกติจะครอบคลุมพื้นที่ทางภูมิศาสตร์ขนาดใหญ่ ในทางกลับกัน การวางซ้อนพื้นจะมีประโยชน์เมื่อคุณต้องการแก้ไขภาพเดียวที่บริเวณใดบริเวณหนึ่งบนแผนที่

คุณยังใช้การวางซ้อนของชิ้นส่วนแบบโปร่งใสเพื่อเพิ่มฟีเจอร์เพิ่มเติมลงในแผนที่ได้ด้วย โดยตั้งค่าปัจจัยความโปร่งใสในการซ้อนทับของชิ้นส่วนแผนที่หรือใส่ภาพชิ้นส่วนแบบโปร่งใส

พิกัดแผนที่ย่อยและระดับการซูม

Google Maps API แยกภาพในแต่ละระดับการซูมออกเป็นชุดชิ้นส่วนแผนที่สี่เหลี่ยมจัตุรัสที่จัดเรียงไว้ในตารางกริด เมื่อแผนที่ย้ายไปที่ตำแหน่งใหม่หรือไปที่ระดับการซูมใหม่ Maps API จะกำหนดว่าต้องใช้ชิ้นส่วนใดและแปลข้อมูลนั้นเป็นชุดชิ้นส่วนที่จะดึง

ชิ้นส่วนที่มีพิกัด (0,0) จะอยู่ที่มุมตะวันตกเฉียงเหนือของแผนที่เสมอ โดยค่า x เพิ่มขึ้นจากทิศตะวันตกถึงทิศตะวันออก และค่า y เพิ่มขึ้นจากทิศเหนือไปยังทิศใต้ ระบบจะจัดทำดัชนีการ์ดโดยใช้พิกัด x,y จากต้นทางนั้น

เมื่อซูมถึงระดับ 0 ภาพโลกทั้งใบจะแสดงในไทล์เดียว ระดับการซูมแต่ละระดับจะเพิ่มการขยายขึ้น 2 เท่า ดังนั้น ที่ระดับการซูม 1 แผนที่จะแสดงผลเป็นตารางขนาด 2x2 ของชิ้นส่วนแผนที่ ที่ระดับการซูม 2 จะเป็นตารางกริดขนาด 4x4 ที่ระดับการซูม 3 จะเป็นตารางกริดขนาด 8x8 เป็นต้น

ตัวอย่างเช่น ที่ระดับการซูม 2 โลกจะแบ่งออกเป็น 16 ชิ้นส่วน ไทล์แต่ละรายการจะอ้างอิงได้ด้วยชุดค่าผสมของ x, y และการซูมที่ไม่ซ้ำกัน ดังนี้

แผนที่โลกแบ่งออกเป็น 4 แถวและ 4 คอลัมน์

เมื่อสร้างรูปภาพสำหรับเลเยอร์ของไทล์ คุณจะต้องสร้างรูปภาพสำหรับ การ์ดแต่ละใบที่การซูมแต่ละระดับที่คุณต้องการรองรับ Google Maps กำหนดเป้าหมายเป็น 256 dp (พิกเซลที่ไม่ขึ้นอยู่กับอุปกรณ์) เมื่อแสดงชิ้นส่วน สำหรับอุปกรณ์ความละเอียดสูง ขอแนะนำให้คุณแสดงผลไทล์ dpi สูง (512x512 พิกเซล) ดูข้อมูลเกี่ยวกับการรองรับหน้าจอขนาดและความหนาแน่นต่างๆ ได้ในเอกสารประกอบสำหรับนักพัฒนาซอฟต์แวร์ Android

หมายเหตุ: ระดับการซูมที่กล้องรองรับจะขึ้นอยู่กับหลายปัจจัย และไม่เกี่ยวข้องกับระดับการซูมที่การ์ดของคุณรองรับ

  1. GoogleMap.getMaxZoomLevel() จะแสดงผลระดับการซูมสูงสุดที่มีอยู่ในตำแหน่งปัจจุบันของกล้อง โดยคำนึงถึงประเภทแผนที่ที่ใช้อยู่ในปัจจุบัน เช่น แผนที่ดาวเทียมหรือภูมิประเทศอาจมีระดับการซูมสูงสุดต่ำกว่าชิ้นส่วนแผนที่ฐาน
  2. GoogleMap.getMinZoomLevel() จะแสดงผลระดับการซูมขั้นต่ำซึ่งเป็นค่าเดียวกันในทุกตำแหน่ง (ต่างจากระดับการซูมสูงสุด) แต่อาจแตกต่างกันไปในแต่ละอุปกรณ์และขนาดแผนที่

เพิ่มการวางซ้อนของชิ้นส่วนแผนที่

วิธีที่ง่ายและพบบ่อยที่สุดในการสร้างการวางซ้อนของชิ้นส่วนแผนที่คือการระบุ URL ที่ชี้ไปยังภาพย่อยที่เกี่ยวข้อง UrlTileProvider เป็นการใช้งานบางส่วนของ TileProvider ที่มอบชิ้นส่วนรูปภาพตาม URL รูปภาพทั้งหมดต้องมีขนาดเท่ากันสำหรับคลาสนี้

คุณจะต้องใช้ UrlTileProvider.getTileUrl() ซึ่งยอมรับพิกัดของชิ้นส่วน (x, y, ซูม) และแสดงผล URL ที่ชี้ไปยังรูปภาพที่จะใช้สำหรับไทล์ เมธอดควรแสดงค่า Null หากไม่มีไทล์สําหรับ x, y และการซูมที่ระบุ URL อาจชี้ไปยังทรัพยากรบนเว็บ เนื้อหา Android หรือไฟล์ในดิสก์ในเครื่อง

ตั้งค่าคลังภาพไทล์ของคุณบนเซิร์ฟเวอร์ ซึ่งกำหนดสำหรับพิกัด x,y และระดับการซูมทั้งหมดที่คุณต้องการรองรับ จากนั้นเพิ่มการวางซ้อนของชิ้นส่วนแผนที่โดยทำดังนี้

  1. กำหนด UrlTileProvider เพื่อใส่ภาพย่อย
  2. ลบล้าง getTileUrl() เพื่อสร้าง URL สำหรับรูปภาพชิ้นส่วนแต่ละรูป
  3. ระบุออบเจ็กต์ TileOverlayOptions ที่มีตัวเลือกที่เกี่ยวข้องดังนี้
    • fadeIn: บูลีน ระบุว่าการ์ดควรจางเข้ามาหรือไม่ ค่าเริ่มต้นคือ true คุณอาจพบว่าการ ปิดการค่อยๆ เปลี่ยนเมื่อสลับระหว่างการวางซ้อนชิ้นส่วนแบบเรียงชิดกันอย่างรวดเร็ว หากต้องการทราบข้อมูลเกี่ยวกับความสัมพันธ์ระหว่างความโปร่งใสและการเฟดอิน โปรดดูส่วนความโปร่งใสด้านล่าง
    • tileProvider: TileProvider ที่ใช้สำหรับการวางซ้อนนี้
    • transparency: ลอย ตั้งค่าปัจจัยด้านความโปร่งใสสำหรับรูปภาพย่อย ค่าต้องอยู่ในช่วง [0.0f, 1.0f] โดย 0.0f หมายถึงทึบแสงเต็มที่ (ค่าเริ่มต้น) และ 1.0f หมายถึงโปร่งแสงทั้งหมด ดูส่วนเกี่ยวกับความโปร่งใสด้านล่างเพื่อดูตัวอย่างโค้ดและความสัมพันธ์ระหว่างความโปร่งใสและการจางลง
    • visible: บูลีน ระบุการเปิดเผยการวางซ้อนของชิ้นส่วนแผนที่ การวางซ้อนของชิ้นส่วนแผนที่ที่มองไม่เห็น (ค่า false) ไม่ได้วาดบนแผนที่ แต่จะรักษาพร็อพเพอร์ตี้อื่นๆ ทั้งหมดไว้ ค่าเริ่มต้นคือ true
    • zIndex: กำหนดลำดับการวาดการวางซ้อนของชิ้นส่วนภาพโดยสัมพันธ์กับการวางซ้อนอื่นๆ ซึ่งรวมถึงการวางซ้อนพื้น วงกลม เส้นประกอบ และรูปหลายเหลี่ยม โฆษณาซ้อนทับที่มีดัชนีลำดับ Z สูงกว่าจะแสดงทับบนโฆษณาที่มีดัชนีลำดับ Z ต่ำกว่า ลำดับของโฆษณาซ้อนทับที่มีดัชนี z เดียวกันจะเป็นแบบอิสระ ดัชนีลำดับ Z เริ่มต้นคือ 0 โปรดทราบว่า เครื่องหมายจะ แสดงเหนือการวางซ้อนอื่นๆ เสมอ โดยไม่คำนึงถึงดัชนี z ของ การวางซ้อนอื่นๆ
  4. เรียก GoogleMap.addTileOverlay() เพื่อเพิ่มการวางซ้อนลงใน แผนที่

Kotlin



private lateinit var map: GoogleMap

var tileProvider: TileProvider = object : UrlTileProvider(256, 256) {
    override fun getTileUrl(x: Int, y: Int, zoom: Int): URL? {

        /* Define the URL pattern for the tile images */
        val url = "http://my.image.server/images/$zoom/$x/$y.png"
        return if (!checkTileExists(x, y, zoom)) {
            null
        } else try {
            URL(url)
        } catch (e: MalformedURLException) {
            throw AssertionError(e)
        }
    }

    /*
     * Check that the tile server supports the requested x, y and zoom.
     * Complete this stub according to the tile range you support.
     * If you support a limited range of tiles at different zoom levels, then you
     * need to define the supported x, y range at each zoom level.
     */
    private fun checkTileExists(x: Int, y: Int, zoom: Int): Boolean {
        val minZoom = 12
        val maxZoom = 16
        return zoom in minZoom..maxZoom
    }
}

val tileOverlay = map.addTileOverlay(
    TileOverlayOptions()
        .tileProvider(tileProvider)
)

      

Java


private GoogleMap map;

TileProvider tileProvider = new UrlTileProvider(256, 256) {

    @Override
    public URL getTileUrl(int x, int y, int zoom) {

        /* Define the URL pattern for the tile images */
        String s = String.format("http://my.image.server/images/%d/%d/%d.png", zoom, x, y);

        if (!checkTileExists(x, y, zoom)) {
            return null;
        }

        try {
            return new URL(s);
        } catch (MalformedURLException e) {
            throw new AssertionError(e);
        }
    }

    /*
     * Check that the tile server supports the requested x, y and zoom.
     * Complete this stub according to the tile range you support.
     * If you support a limited range of tiles at different zoom levels, then you
     * need to define the supported x, y range at each zoom level.
     */
    private boolean checkTileExists(int x, int y, int zoom) {
        int minZoom = 12;
        int maxZoom = 16;

        return (zoom >= minZoom && zoom <= maxZoom);
    }
};

TileOverlay tileOverlay = map.addTileOverlay(new TileOverlayOptions()
    .tileProvider(tileProvider));

      

หากต้องการดูตัวอย่างการทำงานของ UrlTileProvider โปรดดู TileOverlayDemoActivity ในโค้ดตัวอย่างที่มาพร้อมกับ SDK บริการ Google Play

ตั้งค่าความโปร่งใสสำหรับการวางซ้อนแบบเรียงชิดกัน

การวางชิ้นส่วนแบบโปร่งใสซ้อนทับบนแผนที่อาจเป็นประโยชน์ต่อผู้ใช้ เพื่อให้ผู้ใช้ดูแผนที่ฐานด้านล่างแผนที่ที่วางซ้อนอยู่ได้ ซึ่งทำได้โดยการระบุการ์ดโปร่งใสของคุณเองหรือโดยการตั้งค่าปัจจัยความโปร่งใสในการซ้อนทับของชิ้นส่วนแผนที่ แบบเป็นโปรแกรม

ตัวอย่างโค้ดต่อไปนี้จะสลับความโปร่งใสของการวางซ้อนชิ้นส่วนระหว่าง 0.5f ถึง 0.0f

Kotlin



private var tileOverlayTransparent: TileOverlay? = null

override fun onMapReady(map: GoogleMap) {
    tileOverlayTransparent = map.addTileOverlay(
        TileOverlayOptions()
            .tileProvider(object : UrlTileProvider(256, 256) {
                // ...
            })
            .transparency(0.5f)
    )
}

// Switch between 0.0f and 0.5f transparency.
fun toggleTileOverlayTransparency() {
    tileOverlayTransparent?.let {
        it.transparency = 0.5f - it.transparency
    }
}

      

Java


private TileOverlay tileOverlayTransparent;

@Override
public void onMapReady(GoogleMap map) {
    tileOverlayTransparent = map.addTileOverlay(new TileOverlayOptions()
        .tileProvider(new UrlTileProvider(256, 256) {
            // ...
        })
        .transparency(0.5f));
}

// Switch between 0.0f and 0.5f transparency.
public void toggleTileOverlayTransparency() {
    if (tileOverlayTransparent != null) {
        tileOverlayTransparent.setTransparency(0.5f - tileOverlayTransparent.getTransparency());
    }
}

      

ระบบจะใช้ความโปร่งใสเป็นตัวคูณแชแนลอัลฟ่าสำหรับรูปภาพไทล์ หากต้องการกำหนดความโปร่งใสของการวางซ้อนแบบเรียงชิดกัน ให้ระบุออบเจ็กต์ TileOverlayOptions ที่มี transparency ในช่วง [0.0f, 1.0f] ดังที่แสดงในตัวอย่างข้างต้น ค่า 0.0f หมายความว่าการวางซ้อนของชิ้นส่วนภาพทึบแสงมากที่สุด ส่วน 1.0f หมายความว่าการวางซ้อนนั้นโปร่งใสทั้งหมด ค่าเริ่มต้นคือ 0.0f (ทึบ)

คุณเข้าถึงความโปร่งใสของการวางซ้อนของการ์ดได้โดยเรียกใช้ TileOverlay.getTransparency() และคุณสามารถเปลี่ยนการตั้งค่านี้ได้โดยเรียกใช้ TileOverlay.setTransparency()

ความโปร่งใส ภาพเคลื่อนไหว และการเฟดเข้า

จะไม่มีภาพเคลื่อนไหวเมื่อเปลี่ยนความโปร่งใส ตัวเลือกความโปร่งใสจะทำงานควบคู่ไปกับตัวเลือก fadeIn

การเฟดอินจะแสดงภาพเคลื่อนไหวแบบโปร่งใสเมื่อมีการโหลดการ์ด หากคุณกำหนดค่าความโปร่งใส ชิ้นส่วนจะค่อยๆ เปลี่ยนจากโปร่งใสที่สุดกลายเป็นค่าความโปร่งใสที่กำหนดไว้ หากคุณเปลี่ยนความโปร่งใสในระหว่างการเฟดอิน ภาพเคลื่อนไหวจะเข้าสู่ความโปร่งใสเป้าหมายใหม่ต่อไป

นำการวางซ้อนของชิ้นส่วนแผนที่ออก

คุณนำการวางซ้อนของชิ้นส่วนออกได้โดยใช้เมธอด TileOverlay.remove()

Kotlin



tileOverlay?.remove()

      

Java


tileOverlay.remove();

      

ล้างการ์ดที่ไม่มีอัปเดต

หากการ์ดที่มาจากการวางซ้อน "ไม่มีอัปเดต" คุณเรียกใช้ clearTileCache() เพื่อบังคับให้รีเฟรชได้ การดำเนินการนี้จะทำให้มีการโหลดชิ้นส่วนทั้งหมดในการวางซ้อนนี้ซ้ำ ตัวอย่างเช่น หากการ์ดที่มาจากการเปลี่ยนแปลง TileProvider คุณต้องเรียกใช้ clearTileCache() ในภายหลังเพื่อไม่ให้การ์ดก่อนหน้าแสดงผลอีกต่อไป

Kotlin



tileOverlay?.clearTileCache()

      

Java


tileOverlay.clearTileCache();