OpenLayers profile

OpenLayers (OpenLayers.org/) is a high performance, rich JavaScript library designed to help you develop Web map applications. It can meet almost any map development needs.

It has the following characteristics:

  1. Support for any XYZ tile resource, as well as OGC’s WMTS specification tile service and ArcGIS specification tile service
  2. Supports vector slicing, including PBF, GeoJSON, and TopoJSON formats
  3. Support vector layers for rendering GeoJSON, TopoJSON, KML, GML and other vector data formats
  4. Support GIS network service specifications such as WMS and WFS formulated by OGC
  5. Supports running on mobile devices
  6. You can style the map control using CSS
  7. In OpenLayers everything is an object

Unlike Leaflet, another popular map library, openLayers is completely developed in an object-oriented way and has almost all the functions required for map development built in, while Leaflet core library only provides basic functions and other functions are extended through third-party plug-ins. In terms of use, Leaflet is easier to get started, while OpenLayers is more difficult to get started. Therefore, it is recommended to use Leaflet for business predictability and simplicity.

OpenLayers is powerful, but cumbersome to use because everything is object, combined with ugly documentation, can be extremely unfriendly to new users, which is the original purpose of this series of articles, to help new users use OpenLayers based on actual business development scenarios.

This is the first article in a series on map instantiation, basic elements of operation, and will be updated from time to time.

This paper is based on OpenLayers V6 +, and the code is based on Vue.

The installation

npm i ol
Copy the code

Instantiated map

To display a basic map you first need to provide a container, set the width and height, then introduce OpenLayers and add a map layer. The map service can use the built-in open source map OSM, or use other online tile services, such as: Baidu, Scott, map world, bing, Google, etc., the specific service address to baidu, this article USES the gold service, details may refer to: www.jianshu.com/p/e34f85029… .

<div class="ol-map" ref="olMap"></div>
Copy the code
import Map from 'ol/Map'
import View from 'ol/View'
import { Tile as TileLayer } from 'ol/layer'
import {XYZ, OSM} from 'ol/source'
import { fromLonLat } from 'ol/proj'

// The fromLonLat method converts coordinates from longitude/latitude to other projections

// Use the built-in OSM
//const tileLayer = new TileLayer({
// source: new OSM()
/ /})
// Use Autonavi
const tileLayer = new TileLayer({
    source: new XYZ({
        url: 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'})})let map = new Map({
    layers: [tileLayer],
    view: new View({
        center: fromLonLat([120.771441.30.756433]),// Map center
        zoom: 15.// Scale level
        minZoom: 0.// Minimum scale level
        maxZoom: 18.// Maximum scale level
        constrainResolution: true// Since there are non-integer zoom levels, set this parameter to true to automatically zoom to the nearest integer level after each zoom. This must be set, as the map will be burned if the zoom is not at the integer level
    }),
    target: this.$refs.olMap/ / DOM container
})
Copy the code

This will display a basic map:

You can drag and scale, but you can’t rotate. If you want to support rotation, you need to add a rotation interaction:

import {
  defaults as defaultInteractions,
  DragRotateAndZoom,
} from 'ol/interaction'

let map = new Map({
    // ...
    interactions: defaultInteractions().extend([new DragRotateAndZoom()])
})
Copy the code

This allows you to rotate the map with the mouse while holding down the Shift key.

OpenLayers has many controls built in out of the box.

import { defaults, FullScreen, MousePosition, ScaleLine } from 'ol/control'

let map = new Map({
    // ...
    controls: defaults().extend([
        new FullScreen(), / / full screen
        new MousePosition(), // Displays the latitude and longitude of the current mouse position
        new ScaleLine()// Display the scale])})Copy the code

The map also has a number of events, and you can listen for the events you need to do the corresponding operation, using the following:

map.on('moveend'.e= > {
    // console.log(' map move ', e)
})
map.on('rendercomplete'.() = > {
    // console.log(' render done ')
})
map.on('click'.e= > {
    // console.log(' map click ', e)
})
Copy the code

So much for displaying maps, let’s look at some common usage scenarios.

Display elements

Displaying custom elements on a map is arguably the most basic and common requirement. If you want to display a complex structure or style of elements, you can use overlays, which display DOM elements on a map and move them along with the map.

import Overlay from 'ol/Overlay'

// You can add any content or attributes or styles to an element. You can also bind an event to an element
let el = document.createElement('div')
let marker = new Overlay({
    element: el,// The element to display
    position: fromLonLat([longitude, latitude], 'EPSG:4326'),// The location of the map projection
    offset: [-17, -17].// The pixel offset displayed by the element
    autoPan: true.// Automatically move the map to full display elements
})
// Add to map
map.addOverlay(marker)
// Delete from the map
map.removeOverlay(marker)
Copy the code

If you need to use the vector object Feature to display a small icon, polygon, line, etc., see how to display an image icon first:

import Feature from 'ol/Feature'
import Point from 'ol/geom/Point'
import { Vector as VectorLayer } from 'ol/layer'
import { Vector as VectorSource } from 'ol/source'
import { Style, Icon } from 'ol/style'

// Instantiate elements
let feature = new Feature({
    geometry: new Point([120.12636255813723.30.313142215804806])// Select point geometry for geographical geometry
})
// If you need to attach some custom data to the element
feature.set('data', data)
// Set the style to display an image icon
feature.setStyle([
    new Style({
        image: new Icon({
          anchor: [0.5.1].// Display the location
          size: [18.28]./ / size
          src: require('.. /.. /assets/images/mouse_location_ing.png')/ / picture url})})])/ / vector source
let source = new VectorSource({
    features: [feature]
})
// Add feature ([feature]); // Add feature ([feature]);
// Delete feature: source.clear()

// Vector layers
let vector = new VectorLayer({
    source: source
})
// Styles can be set on a single feature or on a vector layer
/* let vector = new VectorLayer({source: source, style: new style ({image: new Icon({anchor: [0.5, 1]),// [18, 28],// dimensions SRC: require('.. /.. / assets/images/mouse_location_ing. PNG ') / / picture url})})}) * /
map.addLayer(vector)
Copy the code

Add an icon element to the map. If you want to add multiple features, instantiate multiple features. The effect is as follows:

Sometimes you need to support the ability to drag an element to change its position, which requires interactive Translate support:

import {Translate} from 'ol/interaction'
// ...

// ...
let translate = new Translate({
    layers: [vector]
})
map.addInteraction(translate)
// You can listen for the start and end of the drag event. The latitude and longitude after the drag can be obtained from e
translate.on('translateend'.(e) = > {
    console.log(e)
})
translate.on('translatestart'.(e) = > {
    console.log(e)
})
Copy the code

In addition to showing it directly on the map, you can also add it yourself by adding an element at the point of mouse click, using the Draw interaction:

import { Draw } from 'ol/interaction'

let draw = new Draw({
    source: source,
    type: 'Point'.style: new Style({
        image: new Icon({
          anchor: [0.5.1].// Display the location
          size: [18.28]./ / size
          src: require('.. /.. /assets/images/mouse_location_ing.png')/ / picture url})})})// Listen for completion events
draw.on('drawend'.(e) = > {
    console.log(e)
    // Remove the interaction if only one needs to be placed, otherwise keep adding it
    map.removeInteraction(draw)
    
})
map.addInteraction(draw)
Copy the code

In fact, tooltip is basically a DOM element. Overlay is used to Overlay a DOM element. In this case, Overlay is used to Overlay a DOM element.

<! -- You can style elements -->
<div class="ol-popup" ref="olPopup">{{olPopupText}}</div>
Copy the code
import Overlay from 'ol/Overlay'

/ / create the Overlayer
this.tooltipOverlay = new Overlay({
    element: this.$refs.olPopup,
    positioning: 'bottom-center'.// Set the relative position to the position attribute
    offset: [0, -30].// The positioning is solid
    autoPan: true
})
map.addOverlay(this.tooltipOverlay)

// Bind the mouse movement event to the map, detect whether the mouse location has a feature, and display tooltip if it is the target feature
map.on('pointermove'.(e) = > {
    this.olPopupText = ' '
    map.forEachFeatureAtPixel(e.pixel, (f, layer) = > {
        if(layer ! = =this.vectorLayer || ! f.get('data')) {
            return false
        }
        this.olPopupText = f.get('data')
        this.tooltipOverlay.setPosition(f.getGeometry().getCoordinates())
    })
})
Copy the code

This will display tooltip when you mouse over it:

Now let’s see how to Draw polygons, using the same Draw interaction as before:

import { Draw } from 'ol/interaction'

let source = new VectorSource()
let vector = new VectorLayer({
    source: source
})
map.addLayer(vector)
let draw = new Draw({
    source: source,
    type: 'Circle'
})
map.addInteraction(draw)
Copy the code

To do this, instantiate a Draw object and set type to Circle:

Next look at squares and rectangles and modify them on top of the example above:

import { createRegularPolygon, createBox } from 'ol/interaction/Draw'

// The createRegularPolygon method executes and returns a geometryFunction that creates the square
// The createBox method returns a rectangle created by geometryFunction

let draw = new Draw({
    source: source,
    type: 'Circle'.// Yes, Circle
    geometryFunction: createBox()
})
Copy the code

Other types of just setting the corresponding type, such as drawing for irregular POLYGON POLYGON, specific type can view the document: openlayers.org/en/latest/a… .

In the actual usage scenario, there will be situations where the existing polygons need to be modified, so the Modify interaction is needed:

import { Modify } from 'ol/interaction'

let modify = new Modify({
    source
})
map.addInteraction(modify)
Copy the code

Now you can drag the end points of the polygon to make changes.

You can use the default styles to manipulate and display the geometry. If you need a custom style, you can use the style configuration to change it. So much for basic use of elements.

Gets the scope of the current region of the map

For performance reasons, if is displayed on the map elements it is best to display only the elements of the currently displayed area, to display the data from the back-end to request, you can put in the area of the current sent to the back end, back end only return data in this area, you will need to get the current range:

// Obtain the latitude and longitude of four points in the current map area
let range = map.getView().calculateExtent(map.getSize())
let state = {
    minLon: range[0].minLat: range[1].maxLon: range[2].maxLat: range[3].zoomLevel: map.getView().getZoom()// The current scale level, which can be used to determine whether to aggregate elements for display
}
Copy the code

farewell

Because I just started, so there may be some wrong place or some better way to achieve, welcome to point out.