เอกสาร / พื้นฐาน / เส้นประกอบ

เส้นประกอบ

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

POINTS
GeoPoint[]
STROKE
color · width
GEODESIC
true / false
EVENT
onClick
แพลตฟอร์ม

01 · สถานะของเส้นประกอบ

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

PolylinePageViewModel.kt · Jetpack Compose
val polylineState =
    PolylineState(
        points = routePoints,
        strokeColor = Color.Red,
        strokeWidth = 4.dp,
        geodesic = true,
        onClick = { event -> viewModel.onPolylineClick(event) },
    )

// แค่วางไว้ในแผนที่
Polyline(polylineState)

// การเปลี่ยนรูปทรงคือการเขียน points ใหม่เท่านั้น
polylineState.points = nextPoints
คุณสมบัติ
คำอธิบาย
points
ลำดับพิกัดที่ประกอบเป็นเส้น หากเปลี่ยนแปลง รูปร่างจะเปลี่ยนไป
strokeColor
สีของเส้น สามารถระบุความโปร่งแสงได้
strokeWidth
ความหนาของเส้น ระบุในหน่วยตรรกะของแพลตฟอร์ม และจะมีความหนาเท่ากันไม่ว่าความละเอียดของอุปกรณ์จะเป็นอย่างไร
geodesic
ไม่ว่าจะเชื่อมต่อด้วยเส้นทางวงกลมใหญ่ (geodetic) หรือไม่ ค่าเริ่มต้นคือ false
zIndex
ลำดับชั้น กำหนดความสัมพันธ์ด้านหน้า/ด้านหลังกับการวางซ้อนอื่นๆ
extra
ข้อมูลเพิ่มเติมตามต้องการ สามารถรับได้เมื่อแตะ
onClick
ตัวจัดการการแตะ รับสถานะของเส้นและพิกัดที่แตะ

02 · เส้นตรงและเส้นทางวงกลมใหญ่

หาก geodesic เป็น true สองจุดจะเชื่อมต่อด้วยเส้นทางที่สั้นที่สุดบนโลก (เส้นทางวงกลมใหญ่) เส้นทางการบินระยะไกล ฯลฯ จะไม่เป็นเส้นตรงแต่เป็นส่วนโค้ง เมื่อเป็น false จะเป็นเส้นตรงบนการฉายแผนที่ คุณสามารถวาดทั้งสองแบบเคียงข้างกันเพื่อเปรียบเทียบได้โดยใช้ลำดับพิกัดเดียวกัน

geodesic = false
เส้นตรงบนภาพฉายเมอร์เคเตอร์ ระยะใกล้แทบไม่ต่างกัน แต่ระยะไกลจะเบี่ยงจากเส้นทางสั้นที่สุดจริง
geodesic = true
เส้นทางสั้นที่สุดตามความโค้งของโลก วาดเป็นส่วนโค้งที่โป่งไปทางขั้วโลก
วาดสองเส้นด้วยพิกัดเดียวกัน
Polyline(polylineState) // geodesic = true (เส้นโค้ง)
Polyline(
    polylineState.copy(
        id = "${polylineState.id}-straight",
        geodesic = false,
        strokeColor = Color.Blue,
    ),
)

03 · ดูเหมือนกันในทุกผู้ให้บริการ

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

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

GEODESIC

ส่งค่าโค้งเดียวกันให้กับเอ็นจิ้นที่ไม่สามารถวาดเส้นโค้งได้

สำหรับเอ็นจิ้นที่ไม่สามารถวาดเส้นทางวงกลมใหญ่โดยตรงได้ ให้แปลงเส้นเป็นลำดับพิกัดย่อยๆ ก่อนส่งผ่าน ผลลัพธ์คือเส้นโค้งเดียวกันจะแสดงบนทุกเอ็นจิ้น

ANTIMERIDIAN

เส้นที่ข้ามเส้นแบ่งวันสากล

สำหรับเส้นที่ข้ามเส้นเมริเดียน 180 องศา หากส่งค่าไปโดยตรง บางเอ็นจิ้นจะข้ามโลกในทิศทางตรงข้าม การส่งค่าโดยแบ่งเส้นที่เขตแดนจะทำให้ทุกเอ็นจิ้นเดินทางผ่านด้านที่สั้นที่สุด

STROKE WIDTH

ปรับความหนาให้มีมาตรฐานเดียวกัน

ความหนาของเส้นระบุในหน่วยตรรกะของแพลตฟอร์ม เนื่องจากความหนาแน่นของพิกเซลของอุปกรณ์และความแตกต่างของหน่วยในแต่ละเอ็นจิ้นจะถูกแปลงภายใน ความหนาที่มองเห็นจริงบนอุปกรณ์จึงตรงกัน

HIT TEST

การตรวจจับการแตะก็เป็นแบบร่วมกัน

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

ภาพ · เมื่อข้ามเส้นแบ่งเขตวันสากล
180°
ส่งค่าดิบ ๆ บางเอนจินจะลากเส้นอ้อมโลกไปอีกทาง
180°
ผ่าน MapConductor ระบบจะตัดเส้นที่ลองจิจูด 180 องศา ทุกเอนจินจึงลากไปทางที่สั้นที่สุด
วิดีโอตัวอย่าง · โค้ดเดียวกันที่เขียนด้วย SwiftUI ใน Google Maps และ MapLibre

04 · การแตะ

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

event.state

สถานะของเส้นที่แตะเอง สามารถดึงข้อมูลจากสีและ extra ได้

event.clicked

พิกัดบนเส้น ไม่ใช่ตำแหน่งนิ้ว แต่เป็นจุดที่ใกล้เส้นที่สุด

ขอบเขตการยอมรับ

ตรวจจับโดยมีช่วงพักตามขนาดนิ้ว จะถูกแปลงเป็นเมตรตามการซูม

PolylineClickPageViewModel.kt
// วางมาร์กเกอร์ที่ตำแหน่งที่แตะ
fun onPolylineClick(event: PolylineEvent) {
    markers = markers + MarkerState(
        position = event.clicked,
        animation = MarkerAnimation.Drop,
        icon = DefaultMarkerIcon(fillColor = event.state.strokeColor),
    )
}

ส่วนของเส้นที่อยู่นอกช่วงที่มองเห็นจะถูกแยกออกจากการตรวจจับ ดังนั้นแม้จะวางเส้นทางยาวๆ หลายเส้น การตอบสนองก็จะไม่ช้าลง หากมีหลายเส้นทับซ้อนกัน จะเลือกเส้นที่ใกล้ที่สุด

หน้าที่เกี่ยวข้อง