GeoJSON ใหญ่เกินไป - จะทำอย่างไรดี?


20

ฉันใช้leaflet.jsเพื่ออนุญาตให้ผู้ใช้เว็บเลือกภูมิภาค ภูมิภาคที่ถูกต้องคือสหรัฐฯ, แคนาดา, แคนาดาและประเทศโลก (ยกเว้นสหรัฐอเมริกาและแคนาดา) ฉันสร้าง shapefile ด้วยตัวเองโดยใช้ Qgis และบันทึกเป็น geojson ฉันทำให้รูปเรขาคณิตง่ายขึ้นเท่าที่จะทำได้

shapefile ที่ได้คือ 400kb แต่ geojson มีขนาดเกินเมกะไบต์ มันใหญ่กว่าที่ฉันต้องการ ฉันต้องลดค่าใช้จ่ายของเครือข่ายที่เกี่ยวข้องในการถ่ายโอนข้อมูลนี้

วิธีที่ถูกต้องในการทำเช่นนี้คืออะไร? ตัวเลือกที่ฉันสามารถจินตนาการได้คือ:

  1. ให้บริการไฟล์ geojson gzipped, แกะออกจากไคลเอนต์
  2. แยก Shapefile บนไคลเอนต์เพื่อ geojson
  3. สร้างไทล์ของฉันเองจาก shapefile และให้บริการเหล่านั้น

หากใครสามารถบอกฉันได้ว่าตัวเลือกใดดีที่สุด (หรือไม่มีข้อใดข้างต้น) ฉันจะขอบคุณมัน


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

1
ตรวจสอบให้แน่ใจว่า GeoJSON ไม่ได้พิมพ์ออกมาสวยแล้วการแยกพื้นที่สีขาวที่ไม่จำเป็นออกทั้งหมดจะช่วยทำให้ไฟล์เล็กลง - ไม่จำเป็นต้องมีจำนวนมาก แต่ก็ช่วยได้ทั้งหมด!
CHenderson

คำตอบ:


14

Mapshaper.orgเป็นเครื่องมือออนไลน์ฟรีที่ช่วยให้คุณอัปโหลดไฟล์ geojson แสดงเป็นแผนที่จากนั้นเลือก alogrithims ทำให้เข้าใจง่ายหนึ่งในสามซึ่งคุณสามารถปรับความแข็งแรงด้วยแถบเลื่อน

มันอัปเดตแผนที่และไฮไลต์เป็นสีแดงทุกสถานที่ที่มีการสูญเสียความสมบูรณ์เช่นทับซ้อนระหว่างสองภูมิภาค มีปุ่ม 'แก้ไข' ที่โดยปกติ (แต่ไม่เสมอไป) แก้ไขปัญหาดังกล่าว

คุณสามารถค้นหาระดับของการทำให้เข้าใจง่ายที่ยอมรับได้และส่งออกไฟล์ geojson แบบใหม่ที่ง่ายขึ้น

เห็นได้ชัดว่าสิ่งนี้ขึ้นอยู่กับระดับของรายละเอียดที่คุณต้องการ แต่ผลลัพธ์นั้นน่าประทับใจ ตัวอย่างเช่นนี่คือแผนที่ของสกอตแลนด์จากไฟล์ geojson 40mb:

ป้อนคำอธิบายรูปภาพที่นี่

แอปพลิเคชั่น 99% ลดขนาดไฟล์ลงเหลือ 441 kb โดยไม่ทับซ้อนและสูญเสียรายละเอียดที่มองไม่เห็นในระดับการซูมนี้:

ป้อนคำอธิบายรูปภาพที่นี่

แอปพลิเคชัน 99.95% (ลดลงถึง 29kb) แสดงประเภทของการทำให้เรียบง่ายของเส้นทางที่ใช้ (และยังคงจัดการเพื่อหลีกเลี่ยงการทับซ้อนกันและเหมาะอย่างยิ่งสำหรับการใช้งานเช่น chloropleth ระดับชาติ):

ป้อนคำอธิบายรูปภาพที่นี่


ฉันใช้เครื่องมือนี้ตลอดเวลา มันยอดเยี่ยมมาก!
Mike Furlender

1
คุณเป็นผู้ช่วยชีวิต !!
Khizar

13

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

หากคุณมั่นใจว่าคุณได้ทำทุกอย่างเท่าที่จะทำได้ข้างต้นแล้วผลไม้แขวนที่ต่ำที่สุดของตัวเลือกของคุณคือ

  1. ให้บริการไฟล์ geojson gzipped, แกะออกจากไคลเอนต์

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

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


6

ฉันสงสัยว่าคุณสามารถใช้ประโยชน์จากการบีบอัดที่พบในคำตอบนี้ที่พูดคุยเกี่ยวกับการบีบอัด GeoJSON กับ topojson

ฉันไม่รู้ว่าแผ่นพับจะยังสามารถอ่าน GeoJSON ได้ไหม - ลองทำ =)

เพิ่มเติมเกี่ยวกับ topojson: https://github.com/mbostock/topojson/


Leaflet.GeoJSON ไม่ได้ทำการแยกวิเคราะห์ข้อมูลอาร์คดังนั้นวิธีการนี้จะไม่สามารถทำได้
smcphill

Leaflet ไม่สามารถทำได้ แต่คุณสามารถใช้ topojson บนฝั่งไคลเอ็นต์เพื่อทำมันตัวอย่างของ topojson บน leafletแม้ว่าตัวอย่างนั้นจะเกิดขึ้นเมื่อใช้ d3 เพื่อสร้างการแสดงผล
Calvin

1
ฉันมีไฟล์ geoJson ขนาด 27mb ไปที่ mapshaper.org และหลังจากลดความซับซ้อน (1.0%) และการส่งออก topojson มันกลายเป็น 122kb หลังจากนั้นเพิ่มโค้ดใบปลิว topoJson จากgithub.com/shramov/leaflet-plugins/blob/master/layer/vector/ ...... ไปยังแอปของฉันและทำสิ่งต่อไปนี้: ใหม่ L.TOPOJSON ("myExported.topojson") toGeoJson ()
StackUnder

3

ฉันเห็นด้วยกับ @Kelso ด้านบนในการทำให้รูปทรงเรขาคณิตของคุณง่ายขึ้น

หากคุณไม่สามารถเข้าถึงเซิร์ฟเวอร์ของคุณเพื่อยุบข้อมูลด้วย gzip ได้อย่างง่ายดายคุณสามารถดูไลบรารี่MessagePackเพื่อทำให้อนุกรม geoJSON ของคุณเป็นข้อมูลไบนารี่(ฉันเชื่อว่ามันเป็นการนำBSON สเป็คไปใช้ เก็บข้อมูล แต่ผมอาจจะผิด) มีไลบรารี่ในPythonและjavascript (ในหมู่อื่น ๆ ) ที่คุณสามารถใช้ในการซีเรียลไลซ์ / กำจัดข้อมูล


2
MessagePack ไม่เกี่ยวข้องกับ BSON (จริง ๆ แล้วมันจะดีกว่าในหลาย ๆ กรณีตามstackoverflow.com/questions/6355497/ …. ข้อมูลที่น่าสนใจเพิ่มเติมเกี่ยวกับ messagepack และ geojson เฉพาะสามารถดูได้ที่nelsonslog.wordpress.com/2012/06/22/checking -out-msgpack .
Kelso

ขอบคุณสำหรับ @Kelso - อัปเดตคำตอบ และบทความที่ดีเช่นกัน!
om_henners

1

ฉันอยากจะแนะนำเพียงแค่สร้างอาเรย์ของวัตถุ Leaflet Polygon ฉันเห็นด้วยกับ GeoJSON ว่าใหญ่เกินไป ชื่อคีย์ของวัตถุนั้นมีความหมายมาก แต่อาจยาวเกินไปโดยไม่จำเป็น ฉันทำสิ่งนี้:

objects = [];
objects.push( new L.polygon([[1,1],[1,2],[3,4]],options );
objects.push( new L.polygon([[4,7],[8,27],[35,66]],options );
objects.push( new L.polygon([[3,5],[56,24],[13,49]],options );
objects.push( new L.polygon([[13,7],[7,68],[23,9]],options );
layerGroup = L.layerGroup(objects).addTo(map);

มันตรงไปตรงมา มันเบากว่า GeoJSON มากเช่นนี้:

{ "type": "FeatureCollection",
  "features": [
    { "type": "Feature",
      "geometry": {"type": "Polygon",
      "coordinates": [1,1],[1,2],[3,4]},
      },

    //etc...

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

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