[GIS] Open source library to display offline shapefiles in Android

androidlibraryofflineshapefilesoftware-recommendations

I am involved in developing a Android application that needs to be able to make use of Esri Shapefiles. Hardware used will be 7" Android rugged tablets running Android 4.2 or later. It is an offline application, the shapefiles gets loaded onto the device’s SD Card. The application would show a map with shapes representing different premises that needs to be audited. The user would then click on a shape representing the premises and I need to get the data for to the clicked shape to identify which premises is being audited. I also need to make sure that the user’s current position falls within the boundaries of the shape. The user will only pan and zoom on the map. Map needs to be centred on the users current position and the current position needs to be indicated. Audit data is synced via Wi-Fi once the user is back at the office as mobile carrier coverage is poor in some of the areas.

Please recommend a free/open source library with which this can be accomplished.

Best Answer

In the end we went with: https://developers.arcgis.com/android Here is sample code to get you started...

private Boolean setBaseLayer() {

    File myShapeFilePath = null;
    try {

        if (MyApplication.mPathMaps == null || MyApplication.mPathMaps.length() < 1) {
            File rootDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),
                    getApplication().getApplicationInfo().packageName);

            File tmpDir = new File(rootDir, "maps");
            MyApplication.mPathMaps = tmpDir.getAbsolutePath();
        }

        myShapeFilePath = new File(MyApplication.mPathMaps, BASE_LAYER_PATH);
        if (!myShapeFilePath.exists()) {
            displayFatalErrorMsg("Could not locate base map at:\n" + myShapeFilePath.getAbsolutePath());
            return false;
        }

        ShapefileFeatureTable shapefileFeatureTable =
                new ShapefileFeatureTable(myShapeFilePath.toString());
        FeatureLayer featureLayer = new FeatureLayer(shapefileFeatureTable);

        if (MyUVRvalues.getInstance().getBaseLayerColor().isEmpty()) {
            displayFatalErrorMsg("Failed to get config value for 'GIS_BASE_LAYER'");
            return false;
        }

        // int color = Color.argb(255, 84, 110, 122); // a = transparency 0 - 255
        int color = Color.parseColor(MyUVRvalues.getInstance().getBaseLayerColor());
        SimpleFillSymbol simpleFillSymbol = new SimpleFillSymbol(color, SimpleFillSymbol.STYLE.SOLID);
        SimpleRenderer simpleRenderer = new SimpleRenderer(simpleFillSymbol);

        featureLayer.setRenderer(simpleRenderer);
        featureLayer.setVisible(true);

        mMapView.addLayer(featureLayer);

    } catch (FileNotFoundException e) {
        displayFatalErrorMsg("setBaseLayer() Failed, could not locate base map at:\n" + myShapeFilePath.getAbsolutePath()
                + "\n" + e.toString());
        return false;
    }
    return true;
}

private Boolean setFeatureLayer(Boolean visible) {
    File myShapeFilePath = null;
    try {

        myShapeFilePath = new File(MyApplication.mPathMaps, FEATURE_LAYER_PATH);
        if (!myShapeFilePath.exists()) {
            displayFatalErrorMsg("Could not locate feature map at:\n" + myShapeFilePath.getAbsolutePath());
            return false;
        }

        ShapefileFeatureTable shapefileFeatureTable = new ShapefileFeatureTable(myShapeFilePath.toString());
        mFeatureLayer = new FeatureLayer(shapefileFeatureTable);

        mFeatureLayer.setRenderer(getUniqueValueRenderer());
        mFeatureLayer.setSelectionColorWidth(7); // integer in DP(density independent pixels).
        mFeatureLayer.setSelectionColor(Color.YELLOW);

        mFeatureLayer.setVisible(visible); //Only show when zoomed in

        mMapView.addLayer(mFeatureLayer);

    } catch (FileNotFoundException e) {
        displayFatalErrorMsg("Could not locate feature map at:\n" + myShapeFilePath.getAbsolutePath());
        return false;
    } catch (Exception e) {
        displayFatalErrorMsg("setFeatureLayer() caused exception:\n" + e.toString());
        return false;
    }
    return true;
}

private UniqueValueRenderer getUniqueValueRenderer() throws Exception {
    // UniqueValueRenderer used to assign unique values to feature
    UniqueValueRenderer uniqueValueRenderer = new UniqueValueRenderer();

    // setting the field for the unique values
    uniqueValueRenderer.setField1(MyUVRvalues.getInstance().getFieldName());

    // Rendering Type which is used to fill the region
    SimpleFillSymbol defaultsymbol =
            new SimpleFillSymbol(Color.parseColor(MyUVRvalues.getInstance().getDefaultColor()));
    uniqueValueRenderer.setDefaultSymbol(defaultsymbol);

    for (UVRFields field : MyUVRvalues.getInstance().getUVRFields()) {
        UniqueValue uv = new UniqueValue();

        String[] uniqueAttribute = {field.getValue()};
        uv.setValue(uniqueAttribute);

        // The symbol definition for each region
        uv.setSymbol(new SimpleFillSymbol(Color.parseColor(field.getColor())));

        uniqueValueRenderer.addUniqueValue(uv);
    }

    return uniqueValueRenderer;

}