Recentering Oracle APEX Maps

Anton NielsenAnton Nielsen
2 min read

If you have worked with Oracle APEX Map regions you have likely found that under Map Attributes > Initial Position and Zoom > Type you can set “how” you want the map to initially render. By “how” I mean what location in the world you want it to go to and what zoom level you want it to be at. If you have spent any time at all working with maps you may think this feature is broken. I have come to realize that APEX just really means initial. It doesn’t matter what you do (declaratively) on or to the page, once you have visited the page in an APEX session, that initial position is set. You can refresh the report, reset the page cache in the URL, reset everything you can think of, but after that first (initial) visit to the page, the map is going to keep recentering and zooming on that initial spot.

The sample maps application has a Search and Show page that manages to recenter the map. It uses about 25 lines of javascript (in an after refresh dynamic action) to make it happen:

var lMapRegion   = apex.region("airport-map-region"),
    // important: Use the layer name exactly as specified in the "name" attribute in Page Designer
    lLayerId     = lMapRegion.call("getLayerIdByName", "Airport"),
    lCurrentZoom = lMapRegion.call("getMapCenterAndZoomLevel").zoom,
    lAirportId   = apex.item("P121_ID").getValue(),
    lFeature     = lMapRegion.call("getFeature", lLayerId, lAirportId ),
    lPosition;

if ( lFeature.geometry ) {
    lPosition    = lFeature.geometry.coordinates;

    // close all Info Windows, which might currently be open
    lMapRegion.call( "closeAllInfoWindows" );

    // focus the map to the chosen feature
    lMapRegion.call( "setCenter", lPosition );

    // if the current zoom level is below 8, zoom in. Otherwise do nothing.
    if ( lCurrentZoom < 12 ) {
        lMapRegion.call( "setZoomLevel", 12 );
    }
    setTimeout( function() {lMapRegion.call( "displayPopup", "infoWindow", lLayerId, lAirportId.toString(), false )}, 500 );
}

Unfortunately, those 25 lines of javascript don’t work for polygons (and perhaps other layer types). Fortunately, there is a single line of javascript that works for all types:

apex.region("your_region_static-ic").reset();

With that line of javascript you don’t even need to refresh the region. It will refresh and recenter the region. For more details, check out APEX Instant Tips Episode 154. Many thanks to Marwa for teaching me this tip!

I admit there is a downside to this method. The region will zoom out to a location and then zoom into the location you want. It looks cool the first few times it happens, but gets old after a while. The solution is simple enough that I’m willing to live with it…until I have someone that insists on a different solution.

0
Subscribe to my newsletter

Read articles from Anton Nielsen directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anton Nielsen
Anton Nielsen