blog.itcode.devblog.itcode.dev

A Guide for Developers Traveling Through OpenLayers - 10. Creating an Open Street Map (OSM) Map

OSM is a world map that map professionals from around the world autonomously manage. In other words, it's easiest to think of it as open source for the mapping field. Contributors from each country manage the map, and each country's territory is displayed in that country's language. It has the advantage of being applicable without issue to services targeting the entire world. However, based in Korea, the quality of the map isn't all that great. OpenLayers provides OSM by default at the library level. In other words, you can put a world map up on the web with just a few lines of simple code, without any special API calls or configuration. This chapter covers the very basic method of putting up OSM on the web using OpenLayers6.

A Guide for Developers Traveling Through OpenLayers - 10. Creating an Open Street Map (OSM) Map

OSM is a world map that map professionals from around the world autonomously manage. In other words, it's easiest to think of it as open source for the mapping field. Contributors from each country manage the map, and each country's territory is displayed in that country's language. It has the advantage of being applicable without issue to services targeting the entire world. However, based in Korea, the quality of the map isn't all that great. OpenLayers provides OSM by default at the library level. In other words, you can put a world map up on the web with just a few lines of simple code, without any special API calls or configuration. This chapter covers the very basic method of putting up OSM on the web using OpenLayers6.
RWB0104
@RWBwritten at 2022-03-14 19:53:00
A Guide for Developers Traveling Through OpenLayers

시리즈 모아보기

A Guide for Developers Traveling Through OpenLayers

10 / 23

OSM is a world map that map professionals from around the world autonomously manage. In other words, it's easiest to think of it as open source for the mapping field. Contributors from each country manage the map, and each country's territory is displayed in that country's language. It has the advantage of being applicable without issue to services targeting the entire world. However, based in Korea, the quality of the map isn't all that great.

OpenLayers provides OSM by default at the library level. In other words, you can put a world map up on the web with just a few lines of simple code, without any special API calls or configuration.

This chapter covers the very basic method of putting up OSM on the web using OpenLayers6.




We mentioned this before, but just in case, let's go over the structure of OpenLayers once more.

  • Feature: Elements such as points, lines, and polygons (vector layer only)
  • Source: The data source of a layer. Similar to a collection of Features. (SHP, GeoJSON, etc.)
  • Layer: A dataset defined based on a data source (vector, image)
  • View: Information about how the user currently views the map
  • Interaction: Interactive elements of the map (zoom in/out buttons, etc.)
  • Overlay: Elements to display on the map

Since this chapter only needs OSM alone, the elements required are as follows.

  • Source: The source of OSM
  • Layer: The OSM layer defined by the OSM source
  • View: View information

The remaining elements are not used, or use default values.



Let's create an OSM Source object that manages OSM data.

TYPESCRIPT

import OSM from 'ol/source/OSM';

// Default
const source = new OSM();

// Applying options
const source = new OSM({ attributions: '<p>Developed by <a href="https://itcode.dev" target="_blank">RWB</a></p>', cacheSize: 0 });
NameTypeDefaultDescription
attributionsol/source/Source-AttributionLike | undefinedAttribution text (bottom-right of map)
cacheSizenumber | undefinedTile cache size
crossOriginstring | nullanonymousCORS attribute
imageSmoothingbooleantrueDeprecated attribute. Whether to use interpolation
interpolatebooleantrueWhether to use interpolation
maxZoomnumber19Maximum zoom level. No data is shown beyond the specified zoom level
opaquebooleantrueWhether it is opaque
reprojectionErrorThresholdnumber0.5Maximum reprojection error in pixels (0 ~ 1)
tileLoadFunctionol/Tile-LoadFunction | undefinedURL load function
transitionnumber250Rendering output animation duration
urlstringhttps://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.pngURL pattern. Values in curly braces are automatically assigned by OL
wrapXbooleantrueWhether to wrap horizontally
zDirectionol/array-NearestDirectionFunction | number0Whether to use a higher or lower tile when the zoom level is a real number (e.g. 12.552)

An OSM Source can be created via OSM. It takes an options object as a parameter.

For other options and methods you can use, check ol/source/OSM.



Create a Layer object to hold the OSM Source. This Layer will display the OSM map through the assigned OSM Source.

TYPESCRIPT

import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';

const source = new OSM({ attributions: '<p>Developed by <a href="https://itcode.dev" target="_blank">RWB</a></p>', cacheSize: 0 });

const layer = new TileLayer({
	source: source,
	properties: { name: 'base-osm' },
	zIndex: 1,
	preload: Infinity
});
NameTypeDefaultDescription
classNamestringol-layerClass name
opacitynumber1Opacity (0 ~ 1)
visiblebooleantrueWhether visible
extentol/extent-Extent | undefinedThe rendering extent of the layer. Data is not displayed beyond this range
zIndexnumber | undefinedPriority (higher is shown on top)
minResolutionnumber | undefinedMinimum display resolution
maxResolutionnumber | undefinedMaximum display resolution
minZoomnumber | undefinedMinimum display zoom level
maxZoomnumber | undefinedMaximum display zoom level
preloadnumber0Preload low-resolution tiles up to the specified level (0 means unused)
sourceol/source/Tile-TileSource | undefinedThe layer's source
mapol/PluggableMap-PluggableMap | undefinedUse this layer as an overlay in the specified Map object
useInterimTilesOnErrorbooleantrueWhether to use interim tiles on error
propertiesobject | undefinedArbitrary attributes. Can be manipulated with get(), set()

You can create a tile layer via the TileLayer object.

The source option is required; if this option is left empty, nothing appears on the layer, making the layer meaningless.

properties allows you to specify arbitrary attributes of the layer. Assigning a unique identifier to the layer as above helps with managing the layer, since it becomes troublesome to extract a layer from the Map object without a unique identifier.

For other options and methods you can use, check ol/layer/Tile.

Why a tile map of all things?
For base maps, in order to serve them quickly, the map is pre-cut by zoom level and managed as static images. Because of this, it is far more advantageous in terms of management and efficiency to cut the map into fixed-sized pieces and manage them, rather than managing it as a single monolithic image. If you were to keep that large map as a single uncut piece, the image size would be far beyond what a browser could handle.

In fact, the author once did map tiling at a previous job, and the size for levels 1 through 14 amounts to terabytes. That's why it's more advantageous to break it up finely and call only the range the current user is looking at.



Create a View object that will declare the map's viewing information.

TYPESCRIPT

import View from 'ol/View';

const view = new View({
	projection: 'EPSG:3857',
	center: [ 14135490.777017945, 4518386.883679577 ],
	zoom: 17
});

[ 14135490.777017945, 4518386.883679577 ] is the coordinates of Seoul City Hall expressed in EPSG:3857.

NameTypeDefaultDescription
centerol/coordinate-Coordinate | undefinedThe center of the map
constrainRotationboolean | numbertrueWhether rotation is constrained. If a number, indicates the number of allowed rotation steps (if 0: 90, 180, 270, 360)
enableRotationbooleantrueWhether rotation is enabled
extentol/extent-Extent | undefinedThe map's viewing extent. Cannot go outside the specified range
constrainOnlyCenterbooleanfalseIf true, the extent restriction applies only to the View's center, not to the whole extent
smoothExtentConstraintbooleantrueWhether the View can slightly exceed the extent range
maxResolutionnumber | undefinedMaximum viewing resolution. Cannot zoom in beyond the specified resolution.
minResolutionnumber | undefinedMinimum viewing resolution. Cannot zoom out beyond the specified resolution.
maxZoomnumber28Maximum viewing zoom level. Cannot zoom in beyond the specified zoom level.
minZoomnumber0Minimum viewing zoom level. Cannot zoom out beyond the specified zoom level.
multiWorldbooleanfalseWhether multiple worlds are used
constrainResolutionbooleanfalseWhether only integer zoom levels are allowed
smoothResolutionConstraintbooleantrueWhether to use loose zoom in/out rules
showFullExtentbooleanfalseWhether to display the entire configured extent
projectionol/proj-ProjectionLikeEPSG:3857Coordinate system
resolutionnumber | undefinedInitial resolution
resolutionsArray<number> | undefinedList of available resolutions (descending order). max/minResolution, max/minZoom, zoomFactor options are ignored
rotationnumber0Default rotation value
zoomnumber | undefinedDefault zoom level
zoomFactornumber2Zoom factor
paddingArray<number>[ 0, 0, 0, 0 ]Padding

You can declare the map's viewing information through the View object.

For the smoothResolutionConstraint option, for example, let's assume the map's size is width: 120px, height: 80px. With the default value false, the map can zoom in up to 80px at most.

However, if true, the map can zoom in up to 120px at most. In other words, this specifies whether the zoom criterion of the map is based on the shortest length or the longest length.



Create the Map object that assembles all the information to build a map.

TYPESCRIPT

import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';

const source = new OSM({ attributions: '<p>Developed by <a href="https://itcode.dev" target="_blank">RWB</a></p>', cacheSize: 0 });

const layer = new TileLayer({
	source: source,
	properties: { name: 'base-osm' },
	zIndex: 1,
	preload: Infinity
});

const view = new View({
	projection: 'EPSG:3857',
	center: [ 14135490.777017945, 4518386.883679577 ],
	zoom: 17
});

const map = new Map({
	layers: [ layer ],
	target: 'map',
	view: view
});
NameTypeDefaultDescription
controlsol/Collection-Collection<ol/control/Control-Control> | Array<ol/control/Control-Control> | undefinedol/control/defaultsThe map's control object
pixelRationumberwindow.devicePixelRatioDevice pixel ratio
interactionsol/Collection-Collection<ol/interaction/Interaction-Interaction> | Array<ol/interaction/Interaction-Interaction> | undefined
keyboardEventTargetHTMLElement | Document | string | undefinedTarget element for keyboard events
layersArray<ol/layer/Base-BaseLayer> | ol/Collection-Collection<ol/layer/Base-BaseLayer> | ol/layer/Group-LayerGroup | undefinedList of layers. The later in the array, the higher the priority
maxTilesLoadingnumber16Maximum number of tiles that can load simultaneously
moveTolerancenumber1Minimum pixels the mouse must move to be recognized as a map move event
overlaysol/Collection-Collection<ol/Overlay-Overlay> | Array<ol/Overlay-Overlay> | undefinedThe map's overlay object
targetHTMLElement | string | undefinedThe DOM or DOM id where the map is displayed
viewol/View-View | Promise<ol/View-View> | undefinedThe map's view object

Assign the objects declared so far to the Map object. The declared map is displayed in the DOM specified in target.

target: map means the map is displayed in the DOM whose id is map. It doesn't have to be an id — you can also assign an HTMLElement.




You can check an example implementing this at OpenLayers6 Sandbox - OSM.

Since this is simply a page displaying an OSM map, there's not much to interact with besides viewing the map.

It would also be good to compare OSM's appearance with maps serviced domestically in Korea.

Limited to Korea, many places are missing building information, and the display of public transportation is also quite lacking. This is why it has no merit as a domestic-only service.

# GIS# OpenLayers
ship
blog.itcode.dev

Notes from the π-th Alpaca

7.0.1
Developed by RWB since 2021.057th upgraded at 2026.08