If you use maps in your applications, it’s possible you’ll sooner or later need to add a drawing objects’ functionality to these maps. There are several ways to do this. In this article, I’ll show you how MapLibre and OpenLayers libraries differ and how to use them in your projects.
MapLibre GL JS – what is it and how to use it
MapLibre GL JS is an open-source library that you can use to show maps on a page. It was conceived as a fork of the mapbox-gl-js project (MapLibre GL JS v1 is compatible with Mapbox GL JS v1). It’s based on the TypeScript programming language and uses GPU-accelerated vector tile rendering, which means it offers good performance (it can display maps quite quickly).
MapLibre GL JS is the library used by Map Region, the default map component offered by Oracle APEX.
Drawing with MapLibre
To draw an object on the Map region in the APEX application, we must go through several steps. Let’s look at them in more detail.
1. Adding the library
First, we need to paste the following URL into the File URLs field in the Page Attributes settings, in the JavaScript section.
https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.2.0/mapbox-gl-draw.js
We will also need to paste the URL below into the File URLs field in the Page Attributes of the CSS section.
https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.2.0/mapbox-gl-draw.css
2. Creating the Map region
The next step is creating a map region to which we will add the functionality of drawing objects. Paste the map_id value into the Static ID field of the Advanced section.
3. Creating a dynamic action
Now we need to create a dynamic action that will allow us to add the feature drawing functionality to our map. To do this, right-click on the previously created Map region in Page Designer (Tree view). In the Event field, select an option: Map Initialized [Map]. In the Region field, select the previously created Map region. Then create an Execute JavaScript Code action. In the Settings section, in the Code field, paste the following code:
//Get MapLibre GL JS map object var map = apex.region('map_id').getMapObject(); //Add Draw plug-in. var draw = new MapboxDraw({ displayControlsDefault: false, controls: { point: true, line_string: true, polygon: true, trash: true } }); //Add Control to map map.addControl(draw, 'top-left'); //Fix Mapbox - MapLibre issue $('.mapboxgl-ctrl-group.mapboxgl-ctrl').addClass('maplibregl-ctrl maplibregl-ctrl-group');
As you can see on the screenshots below, new icons showed up in the upper left corner of our map region. You can use these to draw objects on the map.
We can also easily draw objects on the map.
Of course, you can easily check the coordinates of the drawn object. You do this by using the following code in the dynamic action. You will see results in a browser console:
map.on('draw.create', function(e) { console.log(JSON.stringify(e.features[0].geometry)); });
And that’s about it. Now, let’s look at the OpenLayers example.
OpenLayers – what is it and how to use it
OpenLayers is a powerful open-source library which is a good alternative to MapLibre GL JS. It’s based on JavaScript, and it’s being developed under the 2-clause BSD License, otherwise known as FreeBSD. You can use it to create dynamic maps on any page, with vector data and markers loaded from pretty much any source.
Drawing with OpenLayers
We will use OpenLayers to implement the functionality for drawing objects on the map – similar to the one we’ve added using MapLibre. However, this case is a bit more complicated because we will not use the APEX Map region offered by Oracle. Instead, we will create our entire map using the OpenLayers library.
To create a map and add object drawing functionality to it with OpenLayers in Oracle APEX, we need to go through the following steps.
1. Adding the library
Paste the following URL into the File URLs field in the Page Attributes settings, in the JavaScript section.
https://cdn.jsdelivr.net/npm/ol@v7.1.0/dist/ol.js
Also, add the URL below in the File URLs field in the Page Attributes of the CSS section.
https://cdn.jsdelivr.net/npm/ol@v7.1.0/ol.css
2. Creating Static Content
The next step is creating Static Content in which we will “embed” our map. In the Source section, in the HTML Code field, add the following:
<div id="map_id" class="map"></div>.
This will be the div for our map.
3. Adding the CSS
In the Inline field in the Page Attributes of the CSS section, you can add CSS that will improve the display of your map, e.g.:
.map {height: 500px; width: 100%;}
4. Creating a new dynamic action
Now we need to add a dynamic action that will allow us to create our map. To do this, right-click on the previously created Static Content in Page Designer (Tree view). In the Event field, select the Page Load option. Then create an Execute JavaScript Code action. In the Settings section, in the Code field, paste the following code:
//Create Raster Source const sourceRaster = new ol.source.OSM(); //Create new layer - Open Street Maps const raster = new ol.layer.Tile({ source: sourceRaster }); //Create Vector Source const source = new ol.source.Vector({wrapX: false}); //Create new layer - Vector Source const vector = new ol.layer.Vector ({ source: source, }); //Create map const map = new ol.Map({ //set layer(s) layers: [raster, vector], //set container target: 'map_id', //set view view: new ol.View({ center: ol.proj.fromLonLat([12.48, 41.85]), zoom: 8 }) }); //Add Interaction (Draw object functionality) var draw = new ol.interaction.Draw({ source: source, type: 'Polygon', //you can use 'Point' or 'LineString' }); map.addInteraction(draw);
The map should now look like the one you see below.
You can also easily draw objects with your mouse cursor.
You can also easily retrieve the coordinates of drawn objects using the following code:
var geojson = new ol.format.GeoJSON().writeFeatures(vector.getSource().getFeatures(), { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' });
Conclusion
As you can see, drawing objects on maps in Oracle APEX isn’t terribly complicated and there are several good tools you can use for this purpose. The implementation of this functionality with the help of MapLibre and OpenLayers is very similar.
It’s worth noting that in the first case, we are modifying the native APEX component. Map region is not only drawing objects but also displaying different layers, creating clusters, measuring the distance between points, or getting the location from the browser. And we get these functionalities out-of-the-box. I wrote more about it in my recent introduction to maps in Oracle APEX.
However, the Map region is a relatively new element. In older versions of APEX, we had to do without it, which is why we looked for external libraries. This is where OpenLayers comes in. It allows you to easily create a map, draw objects and download coordinates. In addition, you can find many examples of GIS functionality on the OpenLayers website, and you can easily add them to your APEX application.
So which solution is better? There is no clear answer. It depends mainly on the version of APEX you’re currently using, and also on the functionalities you want to implement. However, I can say one thing. I like the direction APEX is going when it comes to maps. We already have a Map region, Geocoded Address item, and some cool features that make our APEX apps better and better.
If you have any questions, you can always e-mail me at lcieslik@pretius.com. Also, check out the other APEX-related posts on the Pretius blog: