preface

In the previous article, how to create maps and draw point positions in Leaflet, cesium and Mapbox was explained in detail. In the development of webGis, when there is a need to render a region, a river or a path, in addition to the traditional release of GIS layers, we can also directly use data to draw lines and surface elements on the client. Building on the previous article, this article will talk about how to draw line elements and surface elements in these three maps.

Through this article, we can learn the following:

  • Line elements are drawn in leaflet, cesium and mapBox in different ways
  • Surface elements are drawn in leaflet, Cesium and mapBox in different ways

The code in this article has been submitted to Github. Welcome star.

The code address

Preview the address

Linear elements

Leaflet, Cesium and Mapbox differ slightly in data management modes, but they are basically similar in rendering modes. The first is to draw directly on the map through the collection of longitude and latitude, which is relatively common, and the other is to draw through the standard geoJson data format. The next step is to explain how to draw lines for the three maps.

leaflet

Common data

Refer to the simulation data for the stationList1.json file that appears in the instance code

const layer = {
    polylineLeaflet: null
}

/** * Build the set of latitude and longitude */
async function buildLeafletLineData() {
    const dataJson: any[] = await import('stationList1.json');
    const data: any = [];
    // The simulated data is processed as a collection of longitude and latitude
    for (let i = 0; i < dataJson.length; i++) {
        // Leaflet the first part is the dimension and the second part is the longitude
        const latitude = parseFloat(dataJson[i].latitude);
        const longitude = parseFloat(dataJson[i].longitude);
        data.push([latitude, longitude]);
    }
    return { data, position: data[3]}; }/** * Render the leaflet line elements */
async function renderEntityLineLeaflet() {
    // Set the latitude and longitude according to the data module
    const { data, position } = await buildLeafletLineData();
    // Create an instance of Polyline and append the layer to the map
    layer.polylineLeaflet = new Polyline(data, { color: 'red' })
        .addTo((window as any).leafletMap);
    LeafletMap (window as any). LeafletMap (window as any
    (window as any).leafletMap.setView(position, 11);
}
Copy the code

New Polyline() is used to create the line element, where the first attribute is the latitude and longitude set, and the second parameter type is described in PolylineOptions in Index. d.ts leaflet, mainly including the following attributes:

export interface PathOptions extendsInteractiveLayerOptions { stroke? :boolean; color? :string; weight? :number; opacity? :number; lineCap? : LineCapShape; lineJoin? : LineJoinShape; dashArray? :string | number[]; dashOffset? :string; fill? :boolean; fillColor? :string; fillOpacity? :number; fillRule? : FillRule; renderer? : Renderer; className? :string; smoothFactor? :number; noClip? :boolean;
}
Copy the code

The properties are very easy to understand, line width, fill, color, fill color, transparency, and so on.

geoJson

You can draw your own geoJson online against the GeoJsasonline. json file that appears in the instance code.

const layer = {
    polylineLeafletGeoJson: null
}

/** * Load geoJson line data */
async function renderGeoLineLeaflet() {
    const dataJson1: any = require('geoJsonline.json');
    layer.polylineLeafletGeoJson = geoJSON(dataJson1, {
        style: {
            color: 'red'
        }
    })
        .addTo((window as any).leafletMap);
    (window as any).leafletMap.flyTo([
        30.276858411864904.120.16433715820311,].11);
}
Copy the code

The geoJSON method is called, and the first parameter is the standard geoJSON data. The second element configuration information, such as line color, width, and so on, is the same as the previous PathOptions properties.

cesium

Any element in cesium can be created as an entity, so the first way to draw a line element is to create it as an entity, and the other is to create it by loading geoJson data.

Ordinary entities

Refer to the simulation data for the stationList1.json file that appears in the instance code

async function renderEntityLineCesium() {
    const positionList: number[] = [];
    // Through the simulation data tease out the collection of longitude and latitude longitude, dimension, longitude, dimension
    const dataJson: any[] = await import('stationList1.json');
    for (let i = 0; i < dataJson.length; i++) {
        const latitude = parseFloat(dataJson[i].latitude);
        const longitude = parseFloat(dataJson[i].longitude);
        positionList.push(longitude);
        positionList.push(latitude);
    }
    // When creating an entity, you need to pay attention to the data requirements of positions
    const drawEntity: Entity = new Entity({
        polyline: {
            // Generate a C3 array from the given array of latitude and longitude collections and return it
            positions: Cartesian3.fromDegreesArray(positionList),
            width: 2.material: Color.BLUE,  // Line material
            // material: new PolylineDashMaterialProperty({
            // color: Color.RED,
            // }),
            // depthFailMaterial: new PolylineDashMaterialProperty({
            // color: Color.YELLOW,
            // }),
            // followSurface: false, // cancel bending
            // clampToGround: true

        },
        label: {
            text: 'the line'./ / text
            show: true.// Display by default
            font: '12pt Source Han Sans CN'.// Font style
            fillColor: Color.GOLD,        // Font color
            backgroundColor: Color.AQUA,    // The background color
            //showBackground:true, // whether to display the background color
            style: LabelStyle.FILL,        / / label style
            outlineWidth: 1.verticalOrigin: VerticalOrigin.CENTER,// Vertical position
            horizontalOrigin: HorizontalOrigin.LEFT,// Horizontal position
            pixelOffset: new Cartesian2(5.0)            / / migration}});// Add the created line entities to the cesium entity collection
    (window as any).cesiumMap.entities.add(drawEntity);
    // The map is mapped to the line entity by flyTo
    (window as any).cesiumMap.flyTo(drawEntity);
    // Cache the entity temporarily so that it can be removed later
    (cesiumLayer as any).drawEntityCesium = drawEntity;
    return drawEntity;
}
Copy the code

Draw lines by means of physical elements of the new Entity () operation, mainly through the polyline configuration items, its type is PolylineGraphics | PolylineGraphics. ConstructorOptions, including configuration item is more, It is recommended to read the cesium type declaration documentation directly.

export namespace PolylineGraphics {
    typeConstructorOptions = { show? : Property |boolean; positions? : Property | Cartesian3[]; width? : Property |number; granularity? : Property |number; material? : MaterialProperty | Color; depthFailMaterial? : MaterialProperty | Color; arcType? : Property | ArcType; clampToGround? : Property |boolean; shadows? : Property | ShadowMode; distanceDisplayCondition? : Property | DistanceDisplayCondition; classificationType? : Property | ClassificationType; zIndex? : Property |number;
    };
}
Copy the code

geoJson

It is also very simple for Cesium to draw line elements with geoJson. The following code example can be used to draw geoJson online for the geoJsasonline. json file.

async function renderGeoLineCesium() {
        / / load geoJosn
        const geoJson: any = require('geoJsonline.json');
        // Cesium provides the geojsondatasource. load method for loading standard geoJosn data
        const geoJsonResource = await GeoJsonDataSource.load(geoJson);
        // Add the geoJosn data resource to the map
        cesiumLayer.geoJsonLineCesium = await (window as any).cesiumMap.dataSources.add(geoJsonResource);
        // Get the entities contained in geoJosn
        const entities = geoJsonResource.entities.values;
        // Refactor each entity
        for (let i = 0; i < entities.length; i++) {
            const entity = entities[i];
            entity.billboard = undefined;
            // The following code is the style of the refactoring line element
            (entity as any).nameID  = `${i}-test-line`;
            (entity as any).polyline.width = 2;
            (entity as any).polyline.material = new PolylineDashMaterialProperty({
                color: Color.RED,
            });
        }
        // Map flight location to entity
        (window as any).cesiumMap.flyTo(entities[0]);
}
Copy the code

mapbox

async function renderGeoLineMapBox() {
      / / load geoJosn
      const geoJson: any = import('geoJsonline.json')
      // Mapbox adds a geoJosn resource to the mapbox. You need to specify an ID for the resource, so that you can specify or remove the resource when you draw other layers
      (window as any).mapboxMap.addSource('test-line-mapbox', {"type": "geojson"."data": geoJson
      });
      // Add a layer and specify the data source as the newly loaded resource
      (window as any).mapboxMap.addLayer({
          "id": "test-line-mapbox"./ / layer id
          "type": "line".// Layer type
          "source": 'test-line-mapbox'.// Resource ID
          "layout": {                  // Some common layout configurations
              "line-cap": "round".//"line-json": "round"
          },
          "paint": {                   // Line elements style color, width, transparency, etc
              "line-color": "red"."line-width": 6."line-opacity": 0.5}});// Map to the line element (center is simply the first point of the line element)
      (window as any).mapboxMap.flyTo({
          center: geoJson.features[0].geometry.coordinates[0].zoom: 9.speed: 0.6.curve: 1.easing(t: any) {
              returnt; }}); }Copy the code

To draw line elements in mapBox, first add data to the map by addSource method, and then draw layers by addLayer method. Some specific configuration items are not listed in detail here, and you can directly view the type declaration document if necessary.

Surface elements

We have explained how to draw lines in the three maps. The drawing of surface elements is basically the same as the drawing of lines except for a few configuration items.

leaflet

The drawing of Leaflet surface elements is basically the same as that of line elements, which can be drawn either by instantiating the corresponding Api or by loading geoJson.

Common data

Refer to the simulation data for the stationList1.json file that appears in the instance code

const layer = {
    polygonLeaflet: null
}

/** * Build the set of latitude and longitude */
async function buildLeafletPolygonData() {
    const dataJson: any[] = await import('stationList1.json');
    const data: any = [];
    // The simulated data is processed as a collection of longitude and latitude
    for (let i = 0; i < dataJson.length; i++) {
        // Leaflet the first part is the dimension and the second part is the longitude
        const latitude = parseFloat(dataJson[i].latitude);
        const longitude = parseFloat(dataJson[i].longitude);
        data.push([latitude, longitude]);
    }
    return { data, position: data[3]}; }/** * Render the Leaflet surface elements */
async function renderEntityPolygonLeaflet() {
    // Set the latitude and longitude according to the data module
    const { data, position } = await buildLeafletPolygonData();
    // Create an instance of Polygon and append the layer to the map
    layer.polygonLeaflet = new Polygon(data, { color: '#000eff'.fillColor: '#0000ed'.weight: 1 })
        .addTo((window as any).leafletMap);
    LeafletMap (window as any). LeafletMap (window as any
    (window as any).leafletMap.setView(position, 11);
}
Copy the code

New Polygon() is used to create a line element. The first attribute is a collection of longitude and latitude. The second parameter type is described in PolylineOptions in Index. d.ts in Leaflet (the configuration items for lines and planes are the same).

export interface PathOptions extendsInteractiveLayerOptions { stroke? :boolean; color? :string; weight? :number; opacity? :number; lineCap? : LineCapShape; lineJoin? : LineJoinShape; dashArray? :string | number[]; dashOffset? :string; fill? :boolean; fillColor? :string; fillOpacity? :number; fillRule? : FillRule; renderer? : Renderer; className? :string; smoothFactor? :number; noClip? :boolean;
}
Copy the code

geoJson

You can draw your own geoJson online against the Mockpolygon. json file that appears in the instance code.

const layer = {
    polygonLeafletGeoJson: null
}

/** * Load the geoJson surface element */
async function renderGeoPolygonLeaflet() {
    const dataJson1: any = await import('mockPolygon.json')
    layer.polygonLeafletGeoJson = geoJSON(dataJson1, {
        style: {
            color: 'red'
        }
    })
        .addTo((window as any).leafletMap);
    (window as any).leafletMap.flyTo([
        30.276858411864904.120.16433715820311,].11);
}
Copy the code

The geoJSON method is called, and the first parameter is the standard geoJSON data. The second element configuration information, such as line color, transparency, and so on, is the same as the previous PathOptions properties.

cesium

Ordinary entities

Refer to the simulation data for the stationList1.json file that appears in the instance code

async function renderEntityPolygonCesium() {
    const positionList: number[] = [];
    // Through the simulation data tease out the collection of longitude and latitude longitude, dimension, longitude, dimension
    const dataJson: any[] = await import('stationList1.json');
    for (let i = 0; i < dataJson.length; i++) {
        const latitude = parseFloat(dataJson[i].latitude);
        const longitude = parseFloat(dataJson[i].longitude);
        positionList.push(longitude);
        positionList.push(latitude);
    }
    // When creating an entity, you need to pay attention to the data requirements of positions
    const drawEntity: Entity = new Entity({
        name: 'Plane data'.polygon: {
            // @ts-ignore
            hierarchy: Cartesian3.fromDegreesArray(positionList),
            outline: false.perPositionHeight: true.// Allow the triangle to use the height of the point
            material: Color.RED.withAlpha(0.4)},label: {
            text: 'Solid Plane data'./ / text
            show: true.// Display by default
            font: '12pt Source Han Sans CN'.// Font style
            fillColor: Color.GOLD,        // Font color
            backgroundColor: Color.AQUA,    // The background color
            //showBackground:true, // whether to display the background color
            style: LabelStyle.FILL,        / / label style
            outlineWidth: 1.verticalOrigin: VerticalOrigin.CENTER,// Vertical position
            horizontalOrigin: HorizontalOrigin.LEFT,// Horizontal position
            pixelOffset: new Cartesian2(5.0)            / / migration}});// Add the created line entities to the cesium entity collection
    (window as any).cesiumMap.entities.add(drawEntity);
    // The map is mapped to the line entity by flyTo
    (window as any).cesiumMap.flyTo(drawEntity);
    // Cache the entity temporarily so that it can be removed later
    (cesiumLayer as any).drawEntityCesium = drawEntity;
    return drawEntity;
}
Copy the code

Draw lines by means of physical elements of the new Entity () operation, mainly through the polygon configuration items, its type is PolygonGraphics | PolygonGraphics. ConstructorOptions, including configuration item is more, It is recommended to read the cesium type declaration documentation directly. The cesium type documentation is very thoughtful, and almost every property is described in detail.

export namespace PolygonGraphics {
    typeConstructorOptions = { show? : Property |boolean; hierarchy? : Property | PolygonHierarchy; height? : Property |number; heightReference? : Property | HeightReference; extrudedHeight? : Property |number; extrudedHeightReference? : Property | HeightReference; stRotation? : Property |number; granularity? : Property |number; fill? : Property |boolean; material? : MaterialProperty | Color; outline? : Property |boolean; outlineColor? : Property | Color; outlineWidth? : Property |number; perPositionHeight? : Property |boolean; closeTop? :boolean | boolean; closeBottom? :boolean | boolean; arcType? : Property | ArcType; shadows? : Property | ShadowMode; distanceDisplayCondition? : Property | DistanceDisplayCondition; classificationType? : Property | ClassificationType; zIndex? : ConstantProperty |number;
    };
}
Copy the code

geoJson

Cesium is also very simple to draw the line element with geoJson, and can draw geoJson online for the mockpolygon. json file that appears in the example code as follows:

const cesiumLayer = {
    geoJsonCoverCesium: null
}
async function renderGeoPolygonCesium() {
        / / load geoJosn
        const geoJson: any = require('mockPolygon.json');
        // Cesium provides the geojsondatasource. load method for loading standard geoJosn data
        const geoJsonResource = await GeoJsonDataSource.load(geoJson);
        // Add the geoJosn data resource to the map
        cesiumLayer.geoJsonCoverCesium = await (window as any).cesiumMap.dataSources.add(geoJsonResource);
        // Get all the entities in the geoJson face
        const entities = geoJsonResource.entities.values;
        for (let i = 0; i < entities.length; i++) {
            const entity = entities[i];
            entity.billboard = undefined;
            (entity as any).nameID  = `${i}-test-polygon`;
            (entity as any).polygon.perPositionHeight = true; // Allow the triangle to use the height of the point
            (entity as any).polygon.material = Color.RED.withAlpha(0.4);
        }
        (window as any).cesiumMap.flyTo(entities[0]);
}
Copy the code

mapbox

async function renderGeoPolygonMapBox() {
      / / load geoJosn
      const geoJson: any = import('mockPolygon.json')
      // Mapbox adds a geoJosn resource to the mapbox. You need to specify an ID for the resource, so that you can specify or remove the resource when you draw other layers
      (window as any).mapboxMap.addSource('test-polygon-mapbox', {"type": "geojson"."data": geoJson
      });
      (window as any).mapboxMap.addLayer({
          "id": "test-polygon-mapbox"."type": "fill"."source": 'test-polygon-mapbox'.'layout': {},
          'paint': {
              'fill-color': 'red'.'fill-opacity': 0.8}});// Map to the line element (center is simply the first point of the line element)
      (window as any).mapboxMap.flyTo({
          center: geoJson.features[0].geometry.coordinates[0].zoom: 9.speed: 0.6.curve: 1.easing(t: any) {
              returnt; }}); }Copy the code

The process of drawing surface elements in mapBox is the same as that of drawing line elements. First, add data to the map by addSource method, and then draw the layer by addLayer method. When you need to remove the relevant layer, you can directly call removeLayer. You can also call setLayoutProperty(layerName, ‘visibility’, ‘None ‘) if the layer is only temporarily hidden.

The last

This article briefly explains how to draw lines and surfaces in different ways in the three maps. The author is a non-professional GIS professional born, if there are professional problems in the article, you are welcome to correct.

How to realize WebGIS data visualization in front-end development (I) — map creation and point rendering

The code address

Preview the address