Viscosity's Blog

How to Draw a Polygon in APEX

Written by Luis Flores | May 17, 2023 4:08:23 PM

APEX has a Maps region introduced in APEX 4.2. It has received several upgrades over the years with APEX upgrades. Now on 22.2, we have a lot of functionality and many ways to use the Maps region. In this post, we will look at how you can enable drawing and saving a polygon from the Maps region.

 

This functionality does not come out of the box. Therefore, we must look at the JavaScript used in the back end and how it works.

 

MapLibre

APEX uses MapLibre (an open-source fork of Mapbox made in 2021) in the back end as their Map rendering engine. Because of it, we can use JavaScript to modify the APEX Map. Since Maplibre was born from a fork of Mapbox, there is some functionality from Mapbox API we can leverage, like this draw library (Please check the license section on the GitHub repo to review its fair usability). The last step in drawing the polygon is to use the mapbox-gl-draw library available on GitHub.

 

From there, we need to look at the documentation in docs > api.md.

 

APEX

We will create a dummy app and a page with a Maps region in APEX.

  1. We need to import the JS for the new functionality. We are going to do that from the Mapbox API. Put this URL on the file URLs for JavaScript on the APEX page. https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.0/mapbox-gl-draw.js
  2. Let’s create the functions we will to use; we need to define the draw variable as constant before creating our functions.
    1. Get Polygon

      function getPolygon(e) {

         const data = draw.getAll();

         var json_polygon = JSON.stringify(data.features[0].geometry)

         apex.item( "P10_DRAWING_GEOJSON" ).setValue (json_polygon);

         console.log(json_polygon);

      }

    2. Delete Draw

      function deleteDraw(){

         draw.deleteAll();

         apex.item( "P10_DRAWING_GEOJSON" ).setValue ("");

      }

  3. We will create a page item to store the geoJSON for the drawing.
  4. Add this JavaScript code to run on a dynamic action when the Map has been initialized. The getPolygon function will save the geocode in the variable.

    map = apex.region( "tract-map" ).getMapObject();

     

    draw = new MapboxDraw({

    displayControlsDefault: false,

    });

     

    map.addControl(draw);

    map.on('draw.create', getPolygon);

    map.on('draw.delete', getPolygon);

    map.on('draw.update', getPolygon);


  5. We will create APEX buttons to control when we start drawing, save the drawing, or delete it.
    1. Draw Button
      1. Dynamic action with JavaScript to set the canvas in draw mode.
      2. You can add the hide and show button depending on the state here.

        draw.changeMode('draw_polygon');

    2. Delete Draw
      1. Dynamic action with JavaScript to delete the draw from the previous JS.

        deleteDraw();

    3. Save the Draw
      1. Submit the page to save the item.

        update polygon

        set POLYGON = sdo_util.from_geojson(:P10_DRAWING_GEOJSON)

        where id = :P10_ID;

 

At the end, you are going to have something like this:


 

This is one of the ways we can leverage all the utilities from APEX. Once we know how some of the utilities from APEX work, we can start customizing them to our needs. APEX is very flexible and can adapt. We need to do some research and testing, and ultimately, we will get the desired result.