background

A large number of customer projects in the B-side market have strong demand for geographic information visualization, and the security business scenarios of party, government, military and enterprise customers served by Qiancin Group are no exception. Map visualization has become a mandatory option for customer business. From 2015 to now, customers’ requirements for map visualization have also been upgraded from plain static 2D maps to cool dynamic 3D maps. Due to the singular essence group service customer group particularity, requirements such as: map data source must be in conformity with national standard and support services complete offline deployment, submit the source code review, construction model customization, etc., let we have to choose from research, and then build map visualization products meet strange essence group customer needs. After more than 5 years of iterative development in customer business scenarios, we have also gained a lot of valuable experience and results, today we choose to open the part of the sorting into a series of articles to share with colleagues, hoping to help people in need, but also welcome you, experts at any time to correct.

Sharing plan

  1. This article, “Creating cool 3D Map Visualization products for B-side Clients”, will introduce the content related to map engine architecture, including engine architecture layers, related implementation technologies and some effects, etc.
  2. Data Sources and Storage Computing will cover tile pyramids, GeoJSON, using WebWorker and WebAssembly to speed up data computation, using IndexDB for persistent caching, and LRU for in-memory caching.
  3. Map Interaction and Attitude Control will reveal the translation and rotation of the map camera, windowing range tile rendering and sky boundary optimization.
  4. Text Rendering will discuss various text rendering schemes and practices such as text collision detection.
  5. Architectural Rendering will share some of the issues we encountered when doing dynamic architectural rendering, such as Geometry generation, merging, Shader animation, and pickup.
  6. “Map building modeling and output” is an artistic share. In addition to the simple architectural forms in vector data, when the need for a detailed architectural model, the designer comes into play. This article will describe the designer’s modeling and usage process.
  7. Geographic Data Visualization introduces the classification of data visualization charts, applicable scenarios and difficulties in services.
  8. “Cool Effects and Principles revealed” is the last chapter, will share a variety of cool effects shader code implementation.

Next, let’s start our first article: Building cool 3D Map Visualizations for B-side Clients.

Create cool 3D map visualization products for B-side clients

A 3D map visualization of Chianchrell

Since 2015, Ciancirel map visualization engine has evolved from simple GeoJSON map to dynamic tile 3D map based on Unity 3D and WebGL after several iterations.

Rere Map engine iteration timeline

In the process of iterative evolution, the specifications of constrains visual design and use were gradually born, as well as the iterative patterns summarized and innovated from the competing products, which have become the cornerstone of the current map engine. Along the way, new tools and platforms have been created to help users use them, such as theme editors, data style editors, and data services, which make up the entire map product family.

Family of map visualization products

The 3D map visualization engine is at the heart of the whole product. According to the open source 3D map visualization library source reading comprehension, and with the implementation of the process of continuous optimization and adjustment, the final landing structure is as follows:

3D map visualization engine architecture

Next we will go through the core architecture of 3D maps layer by layer.

Data access layer

Responsible for raw data resource management of map layer and visual layer. Considering the confidentiality and transmission speed of data, the vector data adopts the form of binary data. The tile cutting rules, data format and byte number are agreed on the front and back ends, and the front end is decoded. For visual layers, the main function of this layer is to place data into the visual layer for further processing by the next layer.

Frustum = getCameraFrustum(camera) bounds = getBoundsOfIntersection (frustum, mapPlane) tileIds = getTileIds(bounds) for (i = 0; i < tileIds.length; i++) { tileData = indexDBInstance.get(tileIds[i]) if (tileData) { processTileData(tileData) } else { fetch(tileIds[i]) .then(res => res.arrayBuffer()) .then(arrayBuffer => { tileData = parser(arrayBuffer) indexDBInstance.set(tileIds[i], tileData) processData(tileData) }) .catch(e => { // do something }) } }Copy the code

Data processing layer

Responsible for further processing of raw data input by data access layer. For map layer vector tile data, the data processing layer is based on the given vector binary tile data format standard to parse out the point, line, surface, text and other information contained in it, and use a series of techniques, such as LRU, IndexedDB and so on to cache. Speed up data parsing with WebWorker and WebAssembly to improve performance; For the visualization layer, the data processing layer verifies the correctness of the input data and merges the rendering styles.

Comparison of data before and after parsing

WebAssembly vs. JS parsing rate

Data model layer

Responsible for modeling the input data of the data input layer, and output points, lines, planes, text and so on to the rendering layer. The data model layer maps the latitude and longitude coordinates to the Mercator projection coordinates in the WebGL world, and performs meshwork on the face data. In order to improve performance, some surfaces are merged and further abstracted into buildings, pavement, water, etc. Within the visualization layer, the data model layer is also responsible for modeling the data in order to analyze it, such as aggregating and binning the data.

// Use VectorLayer to render kmeans aggregation data for (I =0; i < inputData.length; i++) { inputData[i].coord = lnglat2WebMercator(inputData[i].lnglat) } kmeansData = kmeans(inputData) Vectorlayer.setdata (kmeansData) // Use vectorLayer to render dbScan point aggregation data vectorLayer.setData(dbscanData)Copy the code

Rendering layer

Responsible for the data model layer input points, lines, planes, text and other data to draw, the final output results are vertices, lines, grid. The map layer renders the building, road surface, water surface and other data input by the data model layer into the base map according to the given map style description file. After the visualization layer abstracts points, lines, planes, text, etc., it describes the style of the Feature in the GeoJSON Feature, and input it into the visualization layer to render most of the visualization layers. For layers such as Heatmap, further processing is needed in the render layer.

PointFeatures = [] for (I = 0; i < geojson.features.length; i++) { feature = geojson.features[i] switch feature.type: { case 'LineString': featureMesh = new LineString(feature, layerStyle) break case 'MultiLineString': featureMesh = new MultiLineString(feature, layerStyle) break case 'Polygon': featureMesh = new Polygon(feature, layerStyle) break case 'MultiPolygon': featureMesh = new MultiPolygon(feature, layerStyle) break case 'Point': Pointfeature.push (feature)} if (featureMesh) {scene.add(featureMesh)}} If (pointfeature.length) {featureMesh = new Point(pointFeatures, layerStyle) scene.add(featureMesh)}Copy the code

Interaction layer

Responsible for processing user equipment input and map operation. In 3D maps and visual layers, the user has to perform operations such as translation, rotation, zooming, and graphic pickup. These operations are based on the user’s devices, such as click, wheel, mousemove, etc. These basic operations also need to be differentiated and merged. Further abstract into the map drag, zoom and other events, and then set and merge the parameters of the map, to achieve the purpose of control map attitude; There are two types of pick up for graphics elements: CPU pick up and GPU pick up. The two types of pick up have different application scenarios.

Dom.on (eventName, function(... The args) {map. Emit (eventName,... The args)}) map. On (eventName, function (... Args) {layer. forEach(function(layer) {layer.emit(eventName, eventName... args) }) }) layer.on(eventName, function() { // do something })Copy the code

GPU pickup principle

Obj3d = new Mesh(geometry, material({color: id})) scene.add(obj3d) renderer.render(scene, camera, renderTarget) renderer.readRenderTargetPixels(renderTarget, x, y, 1, 1, pixelBuffer) If (pixelBuffer[3] === 255) {pickingId = unpackId(pixelBuffer)}Copy the code

Business logic layer

Responsible for processing user business goals. The business logic layer is mainly a callback function. After the user sets the animation or carries out the operation such as picking through the interaction layer, the user needs to set the effect on the user’s business data through the callback function.

layer = new VectorLayer() layer.setData(pointsData) layer.on('click', SetStyle ({stroke: {color: '#FF0000', opacity: #FF0000); }}) // do something}})Copy the code

A time line

The timeline is a clock that runs through each layer. In order to unify the time of all elements in the instance, it is convenient to use the time attribute to animate the processing of each layer.

This article is over, the next will involve more technical details and principle analysis. Look forward to the next issue of Data Sources and Storage Computing.