Snippets

Piotr Szrajber Smart M.App - custom data table command zoomToFeature with pointmap layer and without svg widgets

Created by Piotr Szrajber last modified
//# sourceURL=customization.js
const KEY_PROPERTY = "GEO_ID", // change to your geometry ID
    BUFFER_SIZE = 10000,
    BUFFER_UNIT = "meters"// 'miles', 'feet', 'kilometers', 'meters', or 'degrees';

let GLOBALS = {},
    TIMEOUTS = {};

// wait for the pointmap layer, store reference to it and apply customizations
waitFor("pointmap", function(widget) {
    let geochart = widget.chart;
    GLOBALS.geochart = geochart;
    // do other changes with the choropleth
    overwriteClickBehavior(geochart);
});

// wait for the table and apply customizations
waitFor("table", function (widget) {
    let table = widget.chart;
    reformatTable(table);
});

// waits until the widget of particular type is on stage
// this is simplified and it should be used just once for particular chartType
// @param {String} chartType - "choropleth", "pointmap", "table", "row", "bar", "pie", etc.
// @param {Function} callback callback function
// @param {Object} callback.widget first widget of particular type
// @return {void}
function waitFor(chartType, callback) {
    gsp.bi.stage.findWidgets({
        descriptors: [{
            chartM: {
                chart: chartType
            }
        }]
    }, function(widgets) {
        if (!widgets || !widgets[0]) {
            TIMEOUTS[chartType] = setTimeout(function() {
                waitFor(chartType, callback);
            }, 500);
        } else {
            clearTimeout(TIMEOUTS[chartType]);
            callback(widgets[0]);
        }
    });
}

// zoom to bounding box with (transforming coordinates)
function zoomToBBox(bbox, callback, errback) {
    var bottomLeftCorner = {
            x: bbox[0],
            y: bbox[1]
        },
        topRightCorner = {
            x: bbox[2],
            y: bbox[3]
        };
    // transform the points to current CRS
    gsp.crs.transform({
        points: [bottomLeftCorner, topRightCorner],
        sourceCrsId: "EPSG:4326",
        targetCrsId: gsp.crs.getCurrent()
    }, function(transformationResult) {
        // get BBOX in form minx, miny, maxx, maxy
        var points = transformationResult.points,
            bbox = [points[0].x, points[0].y, points[1].x, points[1].y];
        gsp.map.zoom({
            bbox: bbox
        });
    });
}

// zoom to feature from GLOBALS.geochart.geoJson() with particular ID
function zoomToFeature(featureId) {
    if (!GLOBALS.geochart) return;

    let feature = GLOBALS.geochart.geoJson().features.find(function(f) {
        return f.properties[KEY_PROPERTY] === featureId;
    });
    if (!feature) {
        gsp.ui.info("This row has no associated geometry");
        return;
    }

    gsp.bi.stage.requireLibraries(function(gvc) {
        let geom = feature.geometry.type === "Point" ? gvc.turf.buffer(feature.geometry, BUFFER_SIZE, BUFFER_UNIT) : feature.geometry;
        let bbox = gvc.turf.bbox(geom);
        zoomToBBox(bbox, function () {
            gsp.ui.info(`Successfully centered on [${bbox.join(",")}]`);
        }, function () {
            gsp.ui.info("Could not zoom on this feature");
        });
    });
}

// add "zoom to feature" tool
function reformatTable(chart) {
    let columns = chart.columns();
    chart.columns(columns.concat([{
        label: "Tools",
        format: function(d) {
            let featureId = d[KEY_PROPERTY];
            if (!window.zoomToFeature) {
                window.zoomToFeature = zoomToFeature;
            }
            if (isNaN(featureId)) {
                return `<a href="#" onClick=window.zoomToFeature("${featureId}")>ZOOM</a>`;
            }
            return `<a href="#" onClick=window.zoomToFeature(${featureId})>ZOOM</a>`;
        }
    }]));
    // redraw the chart so that the changes may be applied
    chart.redraw();
}

// disable filter on click
function overwriteClickBehavior(geochart) {
    geochart.willDoMouseEvent(function(feature, event) {
        if (event.type == "click") {
            console.log("feature was clicked");
        }
    });
}

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.