เนื่องจาก "ตอนนี้" เราไม่สามารถวาดอะไรลงไปใน MKMapView ได้โดยตรง ดังนั้นหากต้องการวาดอะไรลงไป จึงจำเป็นต้องใช้วิธีอ้อมๆเล็กน้อย
หลักการก็คือ วาง UIView ซ้อนลงไปเป็น subview ของ MKMapView และวาดเส้นต่างๆลงไปบน UIView ที่วางลงไปนั้นแทน และหากต้องการวาดเส้น โดยอิงกับจุด latitude, longitude จริงบนแผนที่ด้วยแล้ว เจะใช้ method ของ MKMapView ที่ชื่อ convertCoordinate:toPointToView: ซึ่งผลที่ได้ก็คือเป็นการแปลงจุด latitude และ longitude ในแผนที่ให้กลายมาเป็นจุด x, y จริงบนหน้าจอ
อีกจุดหนึ่งที่ต้องให้ความสนใจก็คือ เมื่อมีการขยับ หรือมีการเปลี่ยนแปลงการแสดงผลบน MKMapView ก็จะให้ UIView ที่วางทับอยู่วาดรูปใหม่อีกครั้ง เนื่องจาก latitude, longitude ที่แสดงบนหน้าจอ ไม่ใช่ x, y เดิมที่เคยวาดไปก่อนที่ MKMapView จะถูกขยับอีกแล้ว และแน่นอน พระเอกของเราคือ MKMapViewDelegate
และเมื่อเรารู้แล้วว่าจุดที่เราต้องการวาดคือ x, y ไหนบนหน้าจอ การวาดอะไรลงไปก็ไม่ยาก
ตัวอย่างขั้นตอนหลักๆมีดังนี้
เริ่มแรกจะมี Array ของ CLLocation ที่บรรจุ latitude และ longitude ไว้พร้อมใช้งาน (ทำจริงๆอาจเก็บไว้ในลักษณะอื่นๆก็ได้แล้วแต่สะดวก)
จุดสำคัญคือจุดที่เราจะสั่งวาดเส้นลงไปบน UIView โดยเราจะใช้วิธี override method ชื่อ drawRect: ของ UIView ให้วาดเส้นลงไปตามจุดที่ต้องการ ดังนี้
อีก 2 delegate method ของ MKMapViewDelegate ที่พลาดไม่ได้ก็คือ
mapView:regionWillChangeAnimated:
mapView:regionDidChangeAnimated:
หากแผนที่เปลี่ยน region ใหม่ หรือกำลังจะถูกย่อ/ขยาย เลื่อนแผนที่ ให้ซ่อน UIView ออกไปก่อน
เมื่อหยุดการกระทำกับแผนที่ไปแล้ว ให้แสดง UIView พร้อมทั้งบอกให้วาดเส้นใหม่ตามจุดต่างๆอีกครั้ง
จากตัวอย่าง พบว่ามีการสั่งให้วาดเส้นตามจุดต่างๆใหม่ทุกครั้งที่มีการเปลี่ยน region ขยับ เลื่อน หรือย่อ ขยายแผนที่ทุกครั้งไป :(
หากเราปักหมุดลงไปด้วย แล้วลากเส้นเชื่อมตามลำดับ จะได้หน้าตาออกมาลักษณะนี้
ที่มา: Drawing polyines or routes on a MKMapView (Using Map Kit on the iPhone)
ต้นฉบับ source code Created by Craig
ตัวอย่างโปรเจ็คสามารถดาวน์โหลดได้จากที่นี่
Related Link from Roti
หลักการก็คือ วาง UIView ซ้อนลงไปเป็น subview ของ MKMapView และวาดเส้นต่างๆลงไปบน UIView ที่วางลงไปนั้นแทน และหากต้องการวาดเส้น โดยอิงกับจุด latitude, longitude จริงบนแผนที่ด้วยแล้ว เจะใช้ method ของ MKMapView ที่ชื่อ convertCoordinate:toPointToView: ซึ่งผลที่ได้ก็คือเป็นการแปลงจุด latitude และ longitude ในแผนที่ให้กลายมาเป็นจุด x, y จริงบนหน้าจอ
อีกจุดหนึ่งที่ต้องให้ความสนใจก็คือ เมื่อมีการขยับ หรือมีการเปลี่ยนแปลงการแสดงผลบน MKMapView ก็จะให้ UIView ที่วางทับอยู่วาดรูปใหม่อีกครั้ง เนื่องจาก latitude, longitude ที่แสดงบนหน้าจอ ไม่ใช่ x, y เดิมที่เคยวาดไปก่อนที่ MKMapView จะถูกขยับอีกแล้ว และแน่นอน พระเอกของเราคือ MKMapViewDelegate
และเมื่อเรารู้แล้วว่าจุดที่เราต้องการวาดคือ x, y ไหนบนหน้าจอ การวาดอะไรลงไปก็ไม่ยาก
ตัวอย่างขั้นตอนหลักๆมีดังนี้
เริ่มแรกจะมี Array ของ CLLocation ที่บรรจุ latitude และ longitude ไว้พร้อมใช้งาน (ทำจริงๆอาจเก็บไว้ในลักษณะอื่นๆก็ได้แล้วแต่สะดวก)
จุดสำคัญคือจุดที่เราจะสั่งวาดเส้นลงไปบน UIView โดยเราจะใช้วิธี override method ชื่อ drawRect: ของ UIView ให้วาดเส้นลงไปตามจุดที่ต้องการ ดังนี้
- (void)drawRect:(CGRect)rect{
/* สั่งให้วาดเส้นหากมีจุดที่ต้องวาด และวาดเมื่อ UIView นี้ไม่ได้ถูก hidden อยู่เท่านั้น */
if(!self.hidden && nil != self.points && self.points.count > 0){
CGContextRef context = UIGraphicsGetCurrentContext();
if(nil == self.lineColor)
self.lineColor = [UIColor blueColor];
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
CGContextSetLineWidth(context, 2.0);
//วนรอบอ่าน coordinate ทุกๆอันใน list เพื่อแปลงเป็นจุด x, y บนหน้าจอ และวาดต่อจุดกันไปเรื่อยๆ
for(int idx = 0; idx < self.points.count; idx++){
CLLocation* location = [self.points objectAtIndex:idx];
//แปลง coordinate ที่เก็บไว้ใน list ให้กลายเป็นตำแหน่ง x, y บนหน้าจอ
CGPoint point = [self.map convertCoordinate:location.coordinate toPointToView:self];
if(idx == 0){
CGContextMoveToPoint(context, point.x, point.y);
}else{
CGContextAddLineToPoint(context, point.x, point.y);
}
}
CGContextStrokePath(context);
} // end if
} //end drawRect:
อีก 2 delegate method ของ MKMapViewDelegate ที่พลาดไม่ได้ก็คือ
mapView:regionWillChangeAnimated:
mapView:regionDidChangeAnimated:
หากแผนที่เปลี่ยน region ใหม่ หรือกำลังจะถูกย่อ/ขยาย เลื่อนแผนที่ ให้ซ่อน UIView ออกไปก่อน
- (void)mapView:(MKMapView *)mapView
regionWillChangeAnimated:(BOOL)animated{
self.hidden = YES;
}
เมื่อหยุดการกระทำกับแผนที่ไปแล้ว ให้แสดง UIView พร้อมทั้งบอกให้วาดเส้นใหม่ตามจุดต่างๆอีกครั้ง
- (void)mapView:(MKMapView *)mapView
regionDidChangeAnimated:(BOOL)animated{
self.hidden = NO;
[self setNeedsDisplay];
}
จากตัวอย่าง พบว่ามีการสั่งให้วาดเส้นตามจุดต่างๆใหม่ทุกครั้งที่มีการเปลี่ยน region ขยับ เลื่อน หรือย่อ ขยายแผนที่ทุกครั้งไป :(
หากเราปักหมุดลงไปด้วย แล้วลากเส้นเชื่อมตามลำดับ จะได้หน้าตาออกมาลักษณะนี้
ที่มา: Drawing polyines or routes on a MKMapView (Using Map Kit on the iPhone)
ต้นฉบับ source code Created by Craig
ตัวอย่างโปรเจ็คสามารถดาวน์โหลดได้จากที่นี่
Related Link from Roti


