คุณสามารถเพิ่มรูปภาพบนแผนที่เป็นเลเยอร์ไทล์ได้ ชั้นไทล์จะวางซ้อนบนชิ้นส่วนแผนที่ที่ระดับการซูมหนึ่งๆ เมื่อคุณมีชิ้นส่วนแผนที่เพียงพอแล้ว ก็จะสามารถเสริมข้อมูลแผนที่ของ Google สำหรับทั้งแผนที่ในระดับการซูมต่างๆ
บทนำ
เลเยอร์ชิ้นส่วนแผนที่ (บางครั้งเรียกว่าการวางซ้อนของชิ้นส่วนแผนที่) ช่วยให้คุณวางซ้อนรูปภาพบนชิ้นส่วนแผนที่ฐานของ Google ได้ วิธีนี้เป็นวิธีที่ยอดเยี่ยมในการเพิ่มข้อมูล เช่น จุดที่น่าสนใจหรือข้อมูลการจราจร และภาพในพื้นที่ลงในแอป เมื่อใช้ร่วมกับkGMSTypeNone
ประเภทแผนที่ เลเยอร์ไทล์จะช่วยให้คุณแทนที่ข้อมูลแผนที่ฐานของ Google ด้วยข้อมูลของคุณเองได้อย่างมีประสิทธิภาพ
เลเยอร์ไทล์มีประโยชน์เมื่อคุณต้องการเพิ่มภาพจำนวนมากลงในแผนที่ ซึ่งมักจะครอบคลุมพื้นที่ทางภูมิศาสตร์ขนาดใหญ่ ในทางตรงกันข้าม การวางซ้อนภาพพื้นดินจะมีประโยชน์เมื่อคุณต้องการแก้ไขรูปภาพเดียวที่จุดหนึ่งๆ ในแผนที่
พิกัดแผนที่ย่อย
Maps API จะแบ่งภาพในแต่ละระดับการซูมออกเป็นชุดไทล์แผนที่สี่เหลี่ยมจัตุรัส ซึ่งจัดเรียงเป็นตารางกริดตามลำดับ เมื่อแผนที่เลื่อนไปยังตำแหน่งใหม่หรือระดับการซูมใหม่ Maps API จะกำหนดว่าต้องใช้ชิ้นส่วนแผนที่ใด และแปลข้อมูลนั้นให้เป็นชุดชิ้นส่วนแผนที่ที่จะดึงข้อมูล
สำหรับการใช้การฉาย Mercator ของ Google ไทล์ที่มีพิกัด (0,0) จะอยู่ที่มุมตะวันตกเฉียงเหนือของแผนที่เสมอ โดยค่า x
จะเพิ่มขึ้นจากตะวันตกไปตะวันออก และค่า y
จะเพิ่มขึ้นจากเหนือไปใต้
ระบบจะจัดทําดัชนีไทล์โดยใช้พิกัด x,y
จากต้นทางนั้น ตัวอย่างเช่น เมื่อซูมระดับ 2 ซึ่งโลกถูกแบ่งออกเป็น 16 ไทล์ แต่ละไทล์จะอ้างอิงได้ด้วยคู่ x,y
ที่ไม่ซ้ำกัน ดังนี้
แต่ละชิ้นส่วนแผนที่เป็นรูปสี่เหลี่ยมจัตุรัสขนาด 256x256 จุด เมื่อซูมระดับ 0 ระบบจะแสดงผลทั้งโลกในไทล์เดียว ระดับการซูมแต่ละระดับจะเพิ่มการขยายภาพเป็น 2 เท่า ดังนั้น เมื่อซูมระดับ 1 แผนที่จะแสดงผลเป็นตารางกริด 2x2 หรือตารางกริด 4x4 เมื่อซูมระดับ 2, ตารางกริด 8x8 เมื่อซูมระดับ 3 และอื่นๆ หากกำลังสร้างรูปภาพสำหรับเลเยอร์ไทล์ คุณจะต้องสร้างรูปภาพจุด 256x256 ใหม่สำหรับแต่ละไทล์ในระดับการซูมแต่ละระดับที่คุณต้องการรองรับ
เพิ่มเลเยอร์ชิ้นส่วนแผนที่
- สร้างออบเจ็กต์
GMSURLTileLayer
หรือคลาสย่อยที่กำหนดเองของGMSTileLayer
หรือGMSSyncTileLayer
- แก้ไขพร็อพเพอร์ตี้
zIndex
(ไม่บังคับ) เพื่อปรับตำแหน่งของพร็อพเพอร์ตี้นั้นๆ สัมพันธ์กับเลเยอร์ไทล์อื่นๆ - กำหนดออบเจ็กต์
GMSTileLayer
ให้กับแผนที่โดยการตั้งค่าพร็อพเพอร์ตี้map
Maps SDK สำหรับ iOS มีคลาส 3 คลาสที่สามารถใช้เพื่อติดตั้งใช้งานเลเยอร์ไทล์ สำหรับแต่ละคลาส คุณจะต้องกำหนดวิธีดึงข้อมูลไทล์แผนที่ที่ถูกต้องสำหรับชุดพิกัด {x,y,zoom}
หนึ่งๆ ตัวเลือกที่ใช้ได้มีดังนี้
- คลาสย่อย
GMSSyncTileLayer
ซึ่งให้บริการtileForX:y:zoom
ที่แสดงผลอินสแตนซ์UIImage
- คลาสย่อย
GMSTileLayer
ซึ่งให้บริการการใช้งานเมธอดrequestTileForX:y:zoom
แบบแอซิงโครนัสซึ่งจะเรียกกลับพร้อมรูปภาพไทล์ในภายหลัง - ใช้คลาสที่มีอยู่
GMSURLTileLayer
เพื่อดึงข้อมูลไทล์โดยอัตโนมัติจาก URL โดยระบุบล็อกGMSTileURLConstructor
GMSURLTileLayer
เป็นคลาสที่เฉพาะเจาะจงซึ่งไม่สามารถสร้างคลาสย่อยได้
ในกรณีที่เป็นคลาสย่อยของ GMSSyncTileLayer
หรือ GMSTileLayer
การให้ผลลัพธ์ของชิ้นส่วนแผนที่ nil
จะบอก Maps SDK สำหรับ iOS ว่าขณะนี้ไม่มีข้อมูล แต่อาจพร้อมใช้งานในอนาคต หรือแสดงผล kGMSTileLayerNoTile
เพื่อระบุว่าไม่มีการ์ดที่ตำแหน่งนี้
สำหรับ GMSURLTileLayer
การคืนค่า nil
จาก GMSTileURLConstructor
จะบ่งบอกว่าไม่มีการ์ดในตำแหน่งนี้
ใช้ GMSURLTileLayer เพื่อดึงข้อมูลไทล์จาก URL
GMSURLTileLayer
ไม่จำเป็นต้องมีคลาสย่อย แต่คุณจะต้องติดตั้งใช้งานบล็อก GMSTileURLConstructor
โค้ดด้านล่างแสดงวิธีใช้ GMSURLTileLayer
เพื่อแสดงผังชั้นของอาคารหลายชั้น
Swift
let floor = 1 // Implement GMSTileURLConstructor // Returns a Tile based on the x,y,zoom coordinates, and the requested floor let urls: GMSTileURLConstructor = { (x, y, zoom) in let url = "https://www.example.com/floorplans/L\(floor)_\(zoom)_\(x)_\(y).png" return URL(string: url) } // Create the GMSTileLayer let layer = GMSURLTileLayer(urlConstructor: urls) // Display on the map at a specific zIndex layer.zIndex = 100 layer.map = mapView
Objective-C
NSInteger floor = 1; // Create the GMSTileLayer GMSURLTileLayer *layer = [GMSURLTileLayer tileLayerWithURLConstructor:^NSURL * _Nullable(NSUInteger x, NSUInteger y, NSUInteger zoom) { NSString *url = [NSString stringWithFormat:@"https://www.example.com/floorplans/L%ld_%lu_%lu_%lu.png", (long)floor, (unsigned long)zoom, (unsigned long)x, (unsigned long)y]; return [NSURL URLWithString:url]; }]; // Display on the map at a specific zIndex layer.zIndex = 100; layer.map = mapView;
สร้างคลาสย่อย GMSSyncTileLayer เพื่อแสดงไทล์เป็น UIImage
GMSSyncTileLayer
และ GMSTileLayer
เป็นคลาสนามธรรมที่ออกแบบมาเพื่อรับคลาสย่อย คุณสามารถใช้คลาสเหล่านี้เพื่อแสดงการ์ดเป็น UIImage
ได้ ตัวอย่างด้านล่างแสดงวิธีแสดงผลรูปภาพที่กําหนดเองบนชิ้นส่วนแผนที่บางส่วนด้วยการแยกคลาสย่อยของ GMSSyncTileLayer
Swift
class TestTileLayer: GMSSyncTileLayer { override func tileFor(x: UInt, y: UInt, zoom: UInt) -> UIImage? { // On every odd tile, render an image. if (x % 2 == 1) { return UIImage(named: "australia") } else { return kGMSTileLayerNoTile } } }
Objective-C
@interface TestTileLayer : GMSSyncTileLayer @end @implementation TestTileLayer - (UIImage *)tileForX:(NSUInteger)x y:(NSUInteger)y zoom:(NSUInteger)zoom { // On every odd tile, render an image. if (x % 2 == 1) { return [UIImage imageNamed:@"australia"]; } else { return kGMSTileLayerNoTile; } } @end
หากต้องการเพิ่มเลเยอร์ลงในแผนที่ ให้สร้างอินสแตนซ์ของออบเจ็กต์และตั้งค่าพร็อพเพอร์ตี้แผนที่
Swift
let layer = TestTileLayer() layer.map = mapView
Objective-C
GMSTileLayer *layer = [[TestTileLayer alloc] init]; layer.map = mapView;
ไทล์ High DPI สำหรับอุปกรณ์ Retina
คุณใช้รูปภาพที่มี DPI สูงกับ GMSSyncTileLayer
หรือ GMSURLTileLayer
ได้โดยตั้งค่า tileSize
เป็น 512
พร็อพเพอร์ตี้ tileSize
ระบุจํานวนพิกเซลที่ภาพไทล์ที่แสดงจะแสดงเป็นค่าเริ่มต้น ซึ่งมีค่าเริ่มต้นเป็น 256 ซึ่งเป็นขนาดของไทล์ Google Maps ในอุปกรณ์ที่ไม่ใช่ Retina
หากแสดงไทล์ DPI ปกติในอุปกรณ์ DPI สูง คุณสามารถปรับขนาดรูปภาพให้ใหญ่ขึ้นได้โดยตั้งค่า tileSize
เป็น 512 โปรดทราบว่าการขยายขนาดรูปภาพอาจทำให้คุณภาพรูปภาพลดลง โดยเฉพาะอย่างยิ่งเส้นหรือข้อความเล็กๆ เพื่อผลลัพธ์ที่ดีที่สุด ให้จับคู่tileSize
และ DPI ของรูปภาพกับจอแสดงผล แผนที่ที่แสดงในอุปกรณ์ Retina จะดูดีที่สุดเมื่อแสดงรูปภาพที่มี DPI สูงโดยมี tileSize
เป็น 512 ส่วนแผนที่ที่แสดงในอุปกรณ์ที่ไม่ใช่ Retina จะดูดีเมื่อแสดงรูปภาพปกติและ tileSize
เริ่มต้นคือ 256
การล้างการ์ดที่ล้าสมัย
หากไทล์ที่เลเยอร์ระบุ "ล้าสมัย" คุณควรเรียกใช้เมธอด clearTileCache
ในเลเยอร์เพื่อบังคับให้รีเฟรช ซึ่งจะทําให้ระบบโหลดการ์ดทั้งหมดในเลเยอร์นี้อีกครั้ง
Swift
layer.clearTileCache()
Objective-C
[layer clearTileCache];