การแสดงชุดข้อมูลขนาดใหญ่ด้วย Leaflet


35

เมื่อใช้ Leaflet ในการมองเห็นชุดข้อมูลขนาดใหญ่ (GeoJSON ที่มีคุณสมบัติ 10,000 จุด) ไม่น่าแปลกใจที่เบราว์เซอร์ล่มหรือหยุดทำงาน ตัวอย่างย่อย 1,000 ฟีเจอร์จากชุดข้อมูลเดียวกันนั้นทำงานได้อย่างไร้ที่ติ น่าเสียดายที่ฉันไม่สามารถแชร์ชุดข้อมูลให้ผู้อื่นลองได้

ไม่มีใครมีวิธีแก้ปัญหาที่ดีกว่าสำหรับการแสดงชุดข้อมูลขนาดใหญ่เช่นนี้หรือไม่? (เป้าหมายสูงสุดคือการปรับขนาดให้ถึง 2 ล้านฟีเจอร์) ฉันยินดีที่จะพิจารณากรอบการสร้างภาพออฟไลน์ในกรณีที่เบราว์เซอร์ที่ใช้แทนเช่นPolymapsหรือd3.jsเป็นต้นถือว่าไม่สามารถใช้งานได้

แก้ไข:ลืมพูดถึงผู้ใช้จะต้องสามารถกรองชุดข้อมูลตามคุณลักษณะ ดังนั้นเมื่อไม่ใช้คุณลักษณะNคุณสมบัติเฉพาะการจับคู่n <= Nอาจต้องแสดงผลแบบไดนามิก


3
การสนทนาที่คล้ายกัน: gis.stackexchange.com/questions/4096/ gis.stackexchange.com/questions/14882 gis.stackexchange.com/questions/6954
julien

การโพสต์ลิงก์ซ้ำ เพื่อให้ทำงานได้gis.stackexchange.com/questions/4096/…gis.stackexchange.com/questions/14882/… gis.stackexchange.com/questions/6954/ ?
raphael

คำตอบ:


23

ฉันเป็นผู้เขียนแผ่นพับ มีปลั๊กอินที่น่ากลัวสำหรับการจัดกลุ่มนี้เป็นLeaflet.markercluster มันรวดเร็วและมีประสิทธิภาพ (ดูตัวอย่างเครื่องหมายขนาด 50k) ดูและทำงานได้อย่างราบรื่นด้วยภาพเคลื่อนไหวที่ดีและมีตัวเลือกมากมายเพื่อให้เหมาะกับความต้องการของคุณ


3
ยังPruneClusterดูมีแนวโน้ม
TLama

1
ฉันต้องการขยายคำถามเดิม ฉันต้องทำอะไรเช่นนี้: matall.in/posts/deep-insights-visualizing-1m-flight-routes ฉันจะจัดกลุ่มพา ธ ของเครื่องหมายได้อย่างไร
guilhermecgs

16

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

เท่าที่ฉันรู้ไม่มีวิธีการอื่นที่รวดเร็วสำหรับการทำสิ่งนี้นอกเหนือจากการมีเซิร์ฟเวอร์ WFS ที่รวดเร็วมากซึ่งค่อนข้างยากที่จะรักษา / ขยายขนาดให้กับผู้ชมจำนวนมาก

การเปิดเผยข้อมูล: ทำงานMapBoxเขียนไม่น้อยของโค้ด แต่ TileMill เป็นฟรี / โอเพนซอร์สและอื่น ๆ


1
ฉันลืมที่จะพูดถึงผู้ใช้ควรจะสามารถกรองชุดข้อมูลตามคุณลักษณะและแสดงเฉพาะระเบียนที่ตรงกัน สมมุติว่าจาก 10,000 รายการมีเพียง 500 รายการที่อาจจำเป็นสำหรับกรณีที่กำหนด ฉันสามารถทำสิ่งนี้กับ TileMill ได้ (หรือจะทำอย่างไร)
Imad

3
Nope คุณอาจต้องการลองCartoDBแต่คุณควรรู้ว่าการทำสิ่งต่าง ๆ เป็นแบบไดนามิกและการทำสิ่งต่าง ๆ เป็นสิ่งที่ตรงกันข้ามกับเป้าหมาย
tmcw

1
ลิงค์แผนที่สำมะโนประชากรเสียชีวิต!
drho

ลิงก์ทั้งหมดเป็น daed
LeeGee

9

คุณดูที่ leaflet clusterer หรือไม่? โพสต์บล็อกของผู้เขียนอธิบายไว้ ที่นี่

อีกตัวเลือกที่คุ้มค่าดูอาจจะใช้ใบร่วมกับระบบสารสนเทศภูมิศาสตร์เมฆ ลองดูที่การสาธิตนี้เพื่อดูว่ามันจัดการกับรูปทรงเรขาคณิตจำนวนมากได้อย่างรวดเร็ว ที่น่าประทับใจมาก. ฉันไม่มีส่วนเกี่ยวข้องกับ GISCloud


7

คุณไม่ควรแสดงคะแนนเป็นล้าน ๆ คะแนนบนแผนที่ ไม่เพียงเพราะปัญหาประสิทธิภาพการทำงานที่สำคัญ แต่ยังมาจากมุมมองของผู้ใช้เพราะสำหรับพวกเขาแล้วแน่นอนที่สุดจะเป็นการยากที่จะตีความข้อมูลนี้ ใช้วิธีการรวมข้อมูล (การรวมกลุ่มการรวมกับพื้นที่รูปหลายเหลี่ยม ฯลฯ ) รวมกับประเภทการแสดงผลที่ระดับการซูมที่แตกต่างกัน (เช่นแสดงข้อมูลจุด "ดิบ" เฉพาะในระดับการซูมที่สูงมากและใช้ข้อมูลรวมที่อื่น) ตัวอย่างจะเป็นเว็บไซต์อสังหาริมทรัพย์เช่นzillow.com


8
คุณไม่ควรพูดว่า "คุณไม่ควรทำ" ชาวบ้านและนักท่องเที่ยวเป็นตัวอย่างที่ดีของความเข้าใจอย่างลึกซึ้งว่าการให้คะแนนเป็นล้าน (หรือพันล้านในกรณีนี้) เป็นภาพ
Joseph Sheedy

1
เห็นด้วย w / @velotron เช่นหกล้านจุดแสดงผลได้อย่างสวยงามและรวดเร็ว: mapbox.com/blog/supercluster
Max von Hippel

1
ใช่ แต่ในกรณีนี้จุดเหล่านั้นจะถูกจัดกลุ่มเช่นกัน (ขึ้นอยู่กับระดับการซูม) ทำให้ง่ายต่อการตีความและทำความเข้าใจข้อมูล
chriserik

2
@chriserik ถูกต้องดังนั้นคำตอบที่ถูกต้องคือ "คุณควรใช้การจัดกลุ่มหรือแผนที่ความร้อนหากคุณมีหลาย ๆ จุดและนี่คือวิธีการทำเช่นนั้น ... "
Max von Hippel

3
ประเด็นของฉันคือพล็อตที่ไม่กระจัดกระจายหลายล้านจุดสามารถให้ข้อมูลเชิงลึกได้
โจเซฟ Sheedy

0

ฉันขอแนะนำให้คุณลดจำนวนฟีเจอร์ของจุดที่แสดงผล: สายตามนุษย์จะไม่สามารถเห็น 10,000 คะแนนไม่พูดถึง 2,000,000

สิ่งที่คุณสามารถลองได้คือการขอชุดข้อมูลจากเซิร์ฟเวอร์ที่กำหนดเองแบบไดนามิก (ซึ่งคุณต้องตั้งค่า) เช่น

    map = ...
    map.on('moveend', function(e) {
        getGeoJson(e);
    });
    map.on('zoomend', function(e) {
        getGeoJson(e);
    });
    map.setView([2,3], 2);

    function getGeoJson(event) {
        // todo determine current viewport
        $http.get('someGeoJsonDataProvider.someLanguage?currentView=[lat0,lon0,lat1,lon1]').then(function (resp) {
            // todo clear layers
            // new layer
            map.addLayer(
                L.geoJson(resp.data)
            );
        });
    }

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

ข้อเสีย: การตั้งค่าเซิร์ฟเวอร์ (คุณควรค้นหาไลบรารีสำหรับการกรองจุดทางภูมิศาสตร์) และการเรนเดอร์ที่ช้ากว่า (หลังจากการซูมหรือลากทุกครั้งจะต้องมีการร้องขอเซิร์ฟเวอร์)


-5

ฉันมีทางออกในการทำแผนที่ 50 ถึง 100 ล้านเรคคอร์ดคุณต้องใช้โซลูชันฝั่งเซิร์ฟเวอร์ในการทำกริดและไดนามิก คุณไม่สามารถตอบกลับบน API ของแผนที่เว็บ (Google หรืออื่น ๆ ) เพื่อทำการเรนเดอร์ฝั่งไคลเอ็นต์ ....

[http://96.231.36.9:8080/rbgis/google_map.html เหมือนเดิม 1] ลองลิงค์ด้านบนและดูว่า


2
โปรดขยายคำตอบของคุณดังนั้นจะเป็นประโยชน์แม้ว่าเซิร์ฟเวอร์ของคุณจะไม่สามารถเข้าถึงได้
lynxlynxlynx

ใช่นั่นเป็นเรื่องน่าขัน เนื่องจากลิงค์ฝั่งเซิร์ฟเวอร์ของคุณใช้งานไม่ได้
Max von Hippel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.