في مقال سابق ، تحدثت بإيجاز عن قدرات kepler.gl ، أداة المصادر المفتوحة الجديدة لتصور وتحليل مجموعات البيانات الجغرافية الكبيرة.

الشكل 1. خيارات الخرائط التي تم إنشاؤها باستخدام kepler.gl (بواسطة Uber)
يتيح لك تطبيق الويب هذا إنشاء خريطة تفاعلية غنية بالمعلومات ، والأهم من ذلك ، تستند إلى مجموعات عشوائية من البيانات الجغرافية في غضون دقائق. ومع ذلك ، السؤال الذي يطرح نفسه ما يجب القيام به بعد ذلك؟ كيفية مشاركة النتائج مع الزملاء أو الأصدقاء أو العملاء؟
قارن البدائل
كل "سحر" kepler.gl يحدث على العميل ، لذلك يقدم التطبيق طريقتين فقط لمشاركة نتائجك مع الآخرين:
- حفظ التصور كصورة ثابتة (مع فقد القدرة على التفاعل مع الخريطة)
- تصدير التكوين والبيانات التي تم إنشاؤها كملفات وإرسالها إلى جميع الأطراف المعنية مع تعليمات حول تنزيل البيانات المستلمة إلى kepler.gl لعرض الخريطة التي تم إنشاؤها
لحسن الحظ ، فإن kepler.gl ليس فقط أداة ويب ، ولكنه أيضًا مكون رد فعل ، يمكنك من خلاله إنشاء موقع تجريبي بسرعة مع تصوراتك أو دمجها في تطبيق ويب موجود.
ملاحظة غالبًا ما تتطلب معالجة البيانات وتجميعها بسرعة ، kepler.gl الكثير من الموارد. لذلك ، يجب أن تكون حذرًا بشكل خاص عند دمجه في تطبيقات مخصصة للجوال.
ستسمح حالة استخدام kepler.gl هذه بما يلي:
- لا يعقد عملية عرض التصور (فقط أرسل رابطًا إلى تطبيقك)
- لا تمنح حق الوصول إلى مجموعات البيانات الأصلية في شكل صريح (كما هو مطلوب في الحالة الأساسية 2)
- تقييد التنسيقات التي يمكن للمستخدم الوصول إليها للتفاعل مع المرئيات (على سبيل المثال ، منع الضبط الذاتي للمرشحات أو طرق عرض البيانات)
- حفظ جميع التنسيقات المطلوبة للتفاعل مع البطاقة (تلميح ، تكبير / تصغير ، تبديل وضع الخريطة ، إلخ.)
سيتطلب آخر الخيارات المدروسة جهودًا إضافية من جانب منشئ التصور الجغرافي ولن تكون قادرًا على الاستغناء عن البرمجة. ومع ذلك ، كما سترى قريبًا ، ليس من الصعب تنفيذه بنفس الطريقة.
إنشاء تطبيق تجريبي
حان الوقت للانتقال من النظرية إلى الممارسة. من أجل تقديمك إلى الخطوات الأساسية لدمج kepler.gl في التعليمات البرمجية الخاصة بك ، قمت بعمل تطبيق تجريبي صغير.
إنه يتيح للمستخدم رؤية معلومات حول مواقف السيارات المدفوعة في موسكو بأحد وضعين - عام أو مجمّع. في الوقت نفسه ، يجعل التطبيق من الممكن فقط عرض التصورات التي أنشأناها ، والتبديل بينها والعمل مع الخريطة في وضع القراءة فقط. كل كود المصدر والنسخة الحية متاحة على جيثب .

الشكل 2. شكلان لعرض الخريطة المقدمة من قبل التطبيق التجريبي
لإنشاء هذا العرض التوضيحي ، استخدمت قالب المشروع الخاص بي. ومع ذلك ، إذا قررت اللعب مع kepler.gl بنفسك ، ولكنك لا تزال لا تملك أي تفضيلات شخصية ، فإنني أوصي باستخدام تطبيق create-response-app ، مما سيقلل بشكل كبير من الوقت اللازم لإنشاء الأساس لتطبيقك المستقبلي.
أضف kepler.gl إلى المشروع
Kepler.gl هو مكون تفاعل يستخدم Redux لتخزين حالته وإدارتها. لإضافتها إلى المشروع ، ما عليك سوى تثبيت حزمة npm المناسبة:
npm install --save kepler.gl
تتضمن حزمة npm:
- مجموعة من مكونات ومصانع واجهة المستخدم التي تسمح بإعادة تعريفها بمكوناتها الخاصة
- طرق محددة مسبقًا لإضافة / تغيير البيانات المستخدمة وكيفية عرضها
- Redux المخفض الضروري لعملهم
تكوين تخزين Redux لـ kepler.gl
يستخدم Kepler.gl Redux لإدارة حالته في عملية إنشاء الخرائط وتحديثها. لذلك ، قبل استخدام مكون KeplerGl ، نحتاج إلى إضافة المخفض المناسب إلى مخفض التطبيق.
import { combineReducers } from 'redux'; import keplerGlReducer from 'kepler.gl/reducers'; import appReducer from './appReducer'; const reducers = combineReducers({ keplerGl: mapReducer, app: appReducer, }); export default reducers;
من المهم أن تتذكر أنه بشكل افتراضي ، سيوفر مكون KeplerGl للمستخدم جميع الخيارات المتاحة للتحرير الذاتي وتنزيل وتحديث وتصفية البيانات. للحد من مجموعة الإجراءات المسموح بها للمستخدم ، تحتاج إلى نقل معلومات حول وضع الخريطة (للقراءة أو التحرير) وعناصر تحكم الخريطة المتاحة في معلمات الحالة الأولية:
const mapReducer = keplerGlReducer .initialState({ uiState: { readOnly: true, mapControls: { visibleLayers: { show: false }, toggle3d: { show: false }, splitMap: { show: true }, mapLegend: { show: true, active: false } } } });
سنحتاج أيضًا إلى تثبيت رد فعل كف ، والذي يستخدمه kepler.gl للتحكم في الآثار الجانبية وإضافة مهمة الوسيطة من حزمة npm إلى مستودع Redux لتطبيقه:
import {createStore, applyMiddleware, compose} from 'redux'; import {taskMiddleware} from 'react-palm'; import reducers from './reducers'; const initialState = { }; const middlewares = [ taskMiddleware ]; const enhancers = [applyMiddleware(...middlewares)]; export default createStore( reducers, initialState, compose(...enhancers) );
ملاحظة يعمل فريق Uber Engineering حاليًا بنشاط على إصدار جديد من kepler.gl والذي لن يعتمد على رد فعل كف اليد.
بشكل افتراضي ، يتوقع kepler.gl أن يكون كائن الحالة الخاص به موجودًا في المستوى الأعلى من حالة التطبيق بالكامل ويمكن الوصول إليه بواسطة اسم keplerGl. إذا اختلف تكوين مستودع Redux عن المستوى المتوقع ، فعندئذٍ بالنسبة للتشغيل الصحيح لمكون React المقابل ، يكفي تحديد موقع حالته في التسلسل الهرمي باستخدام خاصية getState.
قم بتضمين مكون تفاعل KeplerGl
لتقديم سريع للخرائط مع عدد كبير من العناصر المعروضة (حتى ملايين النقاط الجغرافية!) يستخدم Kepler.gl desk.gl - إطار عمل WebGL لتصور البيانات ، و MapBox - منصة جغرافية مفتوحة المصدر ، والتي توفر واجهة برمجة تطبيقات مريحة وإمكانيات واسعة لتخصيص الخرائط التي تم إنشاؤها . لذلك ، إحدى المعلمات المطلوبة التي تم تمريرها إلى مكون KeplerGl هي رمز API للوصول إلى خدمة MapBox.
للحصول على رمز مميز ، تحتاج إلى التسجيل على الموقع www.mapbox.com . يوفر MapBox خيارًا من عدة خطط تعريفية مختلفة ، ولكن بالنسبة للتطبيقات الصغيرة ، ستكون النسخة المجانية التي تحتوي على 50000 مشاهدة في الشهر كافية.
بعد إنشاء حساب ، تحتاج إلى الانتقال إلى قسم الرموز المميزة وإنشاء مفتاح عام للوصول إلى الخدمة.
قم بتعيين الرمز المستلم إلى متغير البيئة المناسب:
export MapboxAccessToken=<your_mapBox_token>
يمكنك الآن الانتقال إلى إنشاء مكون رد فعل لعرض معلومات حول مواقف السيارات المدفوعة. في حالتنا ، سيكون مجرد غلاف فوق مكون KeplerGl ، والذي يأخذ أبعاد الخريطة كمعلمات:
import React from 'react'; import KeplerGl from 'kepler.gl'; const mapboxAccessToken = process.env.MapboxAccessToken; const ParkingMap = (props) => ( <KeplerGl id="parking_map" mapboxApiAccessToken={mapboxAccessToken} width={ props.width } height={ props.height } /> ); export default ParkingMap;
إضافة ParkingMap إلى التطبيق. في هذه المرحلة ، بدلاً من معلومات وقوف السيارات ، يتم عرض الخريطة ببساطة دون أي معلومات ، لأننا لم ننقل البيانات حتى الآن على أساسها تصوراتنا.
تنزيل البيانات وتكوينات الخريطة
لعرض بياناتك على الخريطة ، تحتاج إلى نقل مجموعة البيانات إلى KeplerGl التي سيتم على أساسها إنشاء الخريطة ، والتكوين المطلوب للتصور النهائي. يمكن القيام بذلك باستخدام إحدى الطريقتين - addDataToMap أو updateVisData.
لا تتيح لك الطريقة الأولى تنزيل مجموعة البيانات الضرورية فقط وتعيين / تحديث تكوين المثيل المقابل لمكون KeplerGl ، بما في ذلك إعدادات التصور (visState) والخريطة (mapState) ، بالإضافة إلى نمط الخريطة المستخدمة (mapStyle).
يقبل AddDataToMap كائنًا يحتوي على المعلومات التالية كمعلمة للطريقة:
ملاحظة البيانات من كائن التكوين لها الأسبقية دائمًا على الإعدادات التي تم تمريرها في كائن الخيارات.
تسمح طريقة updateVisData بتحديث مجموعات البيانات المستخدمة فقط دون تغيير تكوين المكون المستخدم بالكامل. كمعلمة ، تأخذ ، مثل الطريقة الأولى ، كائنًا يحتوي على معلومات حول مجموعة جديدة أو مجموعات بيانات جديدة ومعلمة "خيارات" لتحديث بعض إعدادات عرض الخريطة.
تهيئة الخريطة
وبالتالي ، من أجل تحميل البيانات الأولية ، نحتاج إلى طريقة addDataToMap. في التطبيق التجريبي الذي يتم إنشاؤه ، يتم تحميل قاعدة بيانات مواقف السيارات المدفوعة في موسكو عندما يتم الوصول إلى التطبيق لأول مرة عن طريق طلب منفصل. يجب تحضير بيانات المصدر الناتجة للتحميل إلى KeplerGl. لهذا ، في معظم الحالات ، يكفي واحد من المعالجات المحددة مسبقًا التي تنقل بيانات csv / json إلى تنسيق البيانات المدعوم بواسطة kepler.gl.
export function loadParkingData(mapMode) { return (dispatch) => { dispatch( requestParkingData() ); fetch(demoDataUrl) .then(response => response.text()) .then(source => { dispatch( getParkingData() ); const data = Processors.processCsvData(source); const config = getMapConfig(mapMode); const datasets = [{ info, data }]; dispatch( wrapTo('parking_map', addDataToMap({ datasets, config }) )); }); }; }
التبديل بين الأوضاع
للتبديل بين أوضاع عرض الخريطة ، نحتاج إلى تحديد وظيفة إجراء أخرى. نظرًا لأنه في الإصدار الحالي من KeplerGl لا توجد طريقة سهلة لتغيير تكوين الخريطة فقط دون التأثير على البيانات ، فإن طريقة addDataToMap ستكون أيضًا الطريقة الأكثر ملاءمة للتبديل بين الأوضاع:
export function toggleMapMode(mode) { return (dispatch, getState) => { const config = getMapConfig( mode ); const datasets = getDatasets(getState()); dispatch( wrapTo('parking_map', addDataToMap({ datasets, config }) )); dispatch( setMapMode(mode) ); }; }
معلمة مجموعة البيانات مطلوبة ، لذلك ، في كل مرة نبدل فيها وضع عرض الخريطة ، سنعيد إرسال مجموعة البيانات الأصلية التي تم تحميلها عند بدء تشغيل التطبيق. سيتم تحديث معلومات تكوين البطاقة في كل مرة. في هذه المقالة ، لن أتطرق بالتفصيل إلى كيفية تنفيذ طرق المساعدة getMapConfig و getDatasets ، والتي يمكن التعرف عليها من خلال GitHub.
ملاحظة حاليا ، KeplerGl API محدودة للغاية ومصممة للحالات الأساسية (إضافة وتحديث البيانات). في الوقت نفسه ، يقر المطورون أنفسهم بأن الإصدار الحالي لا يوفر طريقة فعالة لتحديث التكوينات فقط أو لتحديث البيانات في الوقت الفعلي. ومع ذلك ، لا تنس أن المشروع قيد التطوير النشط وهناك أمل في التوسع المبكر لوظائفه.
تخصيص عناصر الخريطة
لا يحتوي KeplerGl فقط على حاوية ذات رؤية جغرافية ، ولكن أيضًا عناصر تحكم الخريطة ، ونص أداة ، ولوحة جانبية لإدارة البيانات المعروضة ، ومربع حوار لتحميل البيانات بتنسيق csv أو json أو geojson ، إلخ. في الوقت نفسه ، يمكن بسهولة استبدال كل مكون من المكونات المدرجة بإصداره الخاص باستخدام نظام حقن التبعية.
من أجل استبدال المكون الأساسي بنسخته المخصصة ، يكفي:
- استيراد مصنع المكونات الافتراضية
- تحديد مصنع جديد يقوم بإرجاع مكون مخصص
- تضمين مصنع جديد باستخدام طريقة injectComponents
في التطبيق التجريبي الذي نقوم بإنشائه ، لا نريد منح المستخدم الفرصة لتكوين وضع العرض بشكل مستقل ، أو تصفية البيانات الموجودة أو تحميل بيانات جديدة.
نظريًا ، يكفي هذا للإشارة إلى أن مكون KeplerGl في وضع القراءة فقط ، والذي ظهر فقط في الإصدار 0.0.27. ومع ذلك ، حتى في هذا الإصدار ، لا تزال جميع عناصر التحكم معروضة للمستخدم في اللحظات القليلة الأولى قبل تحميل الخريطة ، ثم اختباء فقط. لتجنب ذلك ، يمكننا صراحةً استبدال المكونات غير المرغوب فيها بمكون فارغ باستخدام طريقة injectComponents:
import React from 'react'; import { injectComponents, ModalContainerFactory, SidePanelFactory, } from 'kepler.gl/components';
بشكل ملائم ، لا يسمح لك KeplerGl فقط باستبدال المكونات الأساسية بأخرى مخصصة ، ولكن بمساعدة طريقة withState تسمح لك بإضافة إجراءات إضافية ومعلمات الحالة للمكونات الجديدة.
كيفية استخدام بطاقات متعددة في وقت واحد
إذا كنت تخطط لاستخدام العديد من مكونات KeplerGL المختلفة داخل نفس التطبيق ، فيجب تعيين كل منها في المعلمات بمعرف فريد ، ضروري لإضافة / تحديث البيانات وتكوينات كل بطاقة:
const wrapToParking = wrapTo(' parking_map'); dispatch( wrapToParking( addDataToMap({ datasets, config }) ));
البديل هو استخدام وظيفة الاتصال من Redux والدالة forwardTo من kepler.gl. في هذه الحالة ، من السهل على وظيفة المرسل المقابلة تحديد معرف البطاقة المقابلة:
import KeplerGl from 'kepler.gl'; import { forwardTo, toggleFullScreen } from 'kepler.gl/actions'; import {connect} from 'react-redux'; const MapContainer = props => ( <div> <button onClick=() => props.keplerGlDispatch(toggleFullScreen())/> <KeplerGl id="foo" /> </div> ) const mapStateToProps = state => state const mapDispatchToProps = (dispatch, props) => ({ dispatch, keplerGlDispatch: forwardTo('foo', dispatch) });
الخلاصة
يسمح لك KeplerGl بإضافة خرائط تفاعلية ملونة إلى تطبيق الويب القائم على التفاعل. بفضل استخدام إطار عمل مكون desk.gl ، يمكنه بسهولة عرض ملايين النقاط الجغرافية بتنسيق مناسب لعرضها وتحليلها.
إن الإمكانيات الواسعة لتخصيص التصورات التي تم إنشاؤها ليس فقط ، ولكن أيضًا أنماط الخريطة ، بالإضافة إلى تنسيقات تفاعل المستخدم ، تجعل KeplerGl أداة جذابة للغاية لإنشاء تصورات معقدة ولوحات رسم الخرائط.
ومع ذلك ، يقتصر فقط على سيناريوهات API الأساسية ومعالجة البيانات على العميل ، فضلاً عن استخدام MapBox دون القدرة على تحديد مصدر خريطة آخر ، وتقليل عدد المشاريع التي يمكن استخدام هذه الأداة من أجلها.
ولكن لا تنس أن المشروع لا يزال اليوم صغيرًا جدًا وهو في مرحلة نشطة من التطوير ، لذا قد يصبح الكثير من هذه العيوب غير ذي صلة في المستقبل القريب.
روابط مفيدة
- كود تجريبي كامل
- مقالة تمهيدية عن Kepler.Gl عن Habr
- مستودع Kepler.gl على جيثب
- التوثيق الرسمي ل kepler.gl
- دروس Kepler.gl على Vis.Academy [ar]