Грегори Старр
Это обсуждение касается нашего использования листовок по сравнению с другими технологиями и того, как мы можем использовать холст HTML5 для повышения производительности на наших картах, получения возможности использовать обнаружение устройств и лучше планировать наши структуры данных из нашего API. Мы также можем использовать это как возможность для создания сценариев, которые помогут формировать более оптимизированные структуры данных, а также определить, где создавать швы, чтобы помочь нам лучше визуализировать наши данные для наших клиентов.
Что такое Canvas и WebGL?
Холст
Элемент HTML ‹canvas› используется для рисования графики на лету с помощью сценариев (обычно JavaScript). Элемент ‹canvas› — это только контейнер для графики. Вы должны использовать сценарий, чтобы на самом деле нарисовать графику. Canvas имеет несколько методов рисования контуров, прямоугольников, кругов, текста и добавления изображений.
Подробнее: здесь
WebGL
На самом базовом уровне WebGL (или библиотека веб-графики) представляет собой библиотеку изображений, которая позволяет создавать интерактивную трехмерную графику в режиме реального времени, используя другую часть «мозга» вашего компьютера. Это означает, что вы можете создавать расширенные трехмерные визуальные эффекты, которые запускаются в веб-браузере без необходимости загрузки пользователем каких-либо плагинов. Технология работает поверх холста и доступна через отдельный API. Привлекательность здесь в том, что мы можем перенести рендеринг в GL на основе устройства во время выполнения. Если клиент может, то мы передаем рендеринг в webGL, в противном случае мы остаемся в холсте. Просто, верно?
Что касается поддержки браузера? Как утверждает Википедия, WebGL широко поддерживается в современных браузерах. Однако его доступность зависит от других факторов, таких как поддерживающий его графический процессор. Официальный сайт WebGL предлагает простую тестовую страницу: [13]. Более подробная информация (например, какой рендерер использует браузер и какие расширения доступны) представлена на сторонних веб-сайтах: [14][15].
Подробнее: здесь
Что такое GeoJSON-VT и почему?
Прямо со страницы git:
«Высокоэффективная библиотека JavaScript для нарезки данных GeoJSON на векторные фрагменты на лету, в первую очередь предназначенная для обеспечения рендеринга и взаимодействия с большими наборами геопространственных данных на стороне браузера (без сервера).
Создан для поддержки GeoJSON в Mapbox GL JS, но может быть полезен в других платформах визуализации, таких как Leaflet и d3, а также в серверных приложениях Node.js.
Результирующие плитки соответствуют JSON-эквиваленту спецификации векторной плитки. Чтобы ускорить рендеринг данных и взаимодействие, плитки упрощаются, сохраняя минимальный уровень детализации, соответствующий каждому уровню масштабирования (упрощение фигур, отфильтровывание крошечных полигонов и ломаных линий)».
Листовка против MapBox
Итак, просто чтобы прояснить некоторую путаницу в отношении того, что есть что:
«Mapbox.js — это плагин Leaflet. Он расширяет функциональные возможности Leaflet дополнительным кодом для интеграции со службами Mapbox и вашими данными в Mapbox.
Файл Mapbox.js по умолчанию включает копию Leaflet, прикрепленную к определенной стабильной версии. ”
Визуализация данных клиента Leaf
Наша цель здесь — получить производительный рендеринг из картографического клиента независимо от используемого устройства. Исторически сложилось так, что мы хотели бы подойти к нашему приложению в первую очередь с точки зрения мобильных устройств, чтобы легче находить и решать наиболее очевидные проблемы.
Визуализация наших данных в производительной, независимой от устройства манере потребует от нас более разумного мышления о том, как мы доставляем данные, которые необходимо визуализировать. Нам также нужно быть умнее в том, как мы отображаем эти данные.
В настоящее время мы делаем наивные запросы на основе устройств, получаем неоднозначные данные сокета, а затем пытаемся отобразить все это прямо сейчас. Понятно, откуда берутся проблемы с производительностью.
Я хотел бы предложить лучший способ. Я думаю, мы можем разработать «сценарии», которые управляют несколькими типами запросов на данные. Эти данные структурированы (GeoJSON) таким образом, что их можно визуализировать для удовлетворения наших потребностей в визуализации за один проход. Введите GeoJSON-VT.
Во-первых, конечно, вам нужен набор данных GeoJSON. Предполагая, что вы это сделаете, вы можете продолжить что-то вроде следующего:
if(this.props.geojson.features){ // Generate the tileset. This is for the entire world BTW // It gets generated only once. So make sure you have your dataset complete. // Otherwise you will need to re-generate it when you update your data const tileIndex = geojsonvt(this.props.geojson, this.geoVectorTileOptions); // Create your canvas layer this.canvasLayer = L.tileLayer.canvas(); // The drawTile property is a callback that you set to a function that will get // called everytime we need to draw a new tile (zooming, new tile entering the viewport, etc) this.canvasLayer.drawTile = (canvas, tilePoint, zoom) => { drawVectorTile(canvas, tilePoint, zoom, tileIndex); }; // Add the layer to leaflet if(!this.map.hasLayer(this.canvasLayer)){ this.map.addLayer(this.canvasLayer); } }
Вот функция, которая вызывается каждый раз, когда холсту требуется отрисовать данные тайла (масштабирование или каждый раз, когда новый тайл карты входит в окно просмотра).
export function drawVectorTile (canvas, tilePoint, zoom, tileIndex) { // Use the performance API to start gathering drawing perf metrics const begin = performance.now(); const params ={zoom:zoom,tilePoint:tilePoint, canvas:canvas} params.tilePoint.z = params.zoom; const bounds = params.bounds; const ratio = 1; const pad = 0; // get a reference to the 2d canvas context to draw with // In a web gl implementation you would need to reference the 'experimental-webgl' // or 'experimental-webgl2' contexts. const ctx = canvas.getContext('2d'); ctx.globalCompositeOperation = 'source-over'; // grab a tile from the geojson-vt lib based on the params // sent in from the leaf draw event. Based on tile and zoom // If there is something to draw geojson-vt pass it into this tile const tile = tileIndex.getTile(params.tilePoint.z, params.tilePoint.x, params.tilePoint.y); // Only continue if we have a tile to draw... if (!tile) { console.log('tile empty'); return; } // Clear the canvas for a new drawing ctx.clearRect(0, 0, params.canvas.width, params.canvas.height); // Get the tile features from the new tile that was generated from geojson-vt const features = tile.features; // Define the path styles ctx.lineWidth = 3; // Enter the feature loop and draw based on features... for (let i = 0; i < features.length; i++) { const feature = features[i], type = feature.type; // Set the line style to draw ctx.strokeStyle = 'red'; //`hsla(${(Math.random() * 360)}, 100%, 50%, 1)`; //'red' ctx.beginPath(); // Begin looping through geometry for (let j = 0; j < feature.geometry.length; j++) { const geom = feature.geometry[j]; // handle drawing a circles if (type === 1) { ctx.arc(geom[0] * ratio + pad, geom[1] * ratio + pad, 2, 0, 2 * Math.PI, false); continue; } // more looping for (let k = 0; k < geom.length; k++) { // calculate positioning based on geojson extent settings, these are defaults I'm using const p = geom[k]; const extent = 4096; const x = p[0] / extent * 256; const y = p[1] / extent * 256; // Store position as we will need to do collision testing later for mouse interaction. // By default interacting with cnvas does not happen out of the box // we will need to set that up down the line if we need to work with the location trails geom.x = x; geom.y = y; // Perform the move commands for each point of a stoke if (k) ctx.lineTo(x + pad, y + pad); else ctx.moveTo(x + pad, y + pad); } } // If we encounter a shape, fill it if (type === 3 || type === 1) ctx.fill('evenodd'); // finally draw the strokes ctx.stroke(); } // I like to use the performance API for perf metrics var end = performance.now(); // Log out the perf console.log("Call to DrawTile took " + (end - begin) + " milliseconds.") }
Нравится эта статья? Нажмите на маленькое зеленое сердечко ниже и покажите свою любовь Agrarian Labs!