Android Open Source - android_maplib Vector Layer






From Project

Back to project page android_maplib.

License

The source code is released under:

GNU General Public License

If you think the Android project android_maplib listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Project:  NextGIS Mobile/*from  w  w  w.ja  v  a  2 s.c  o m*/
 * Purpose:  Mobile GIS for Android.
 * Author:   Dmitry Baryshnikov (aka Bishop), bishop.dev@gmail.com
 * *****************************************************************************
 * Copyright (c) 2012-2015. NextGIS, info@nextgis.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.nextgis.maplib.map;


import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.util.Log;
import android.util.Pair;
import com.nextgis.maplib.R;
import com.nextgis.maplib.api.IJSONStore;
import com.nextgis.maplib.datasource.Geo;
import com.nextgis.maplib.datasource.GeoEnvelope;
import com.nextgis.maplib.datasource.GeoGeometry;
import com.nextgis.maplib.display.SimpleFeatureRenderer;
import com.nextgis.maplib.display.SimpleLineStyle;
import com.nextgis.maplib.display.SimpleMarkerStyle;
import com.nextgis.maplib.util.Feature;
import com.nextgis.maplib.util.VectorCacheItem;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import static com.nextgis.maplib.util.Constants.*;
import static com.nextgis.maplib.util.GeoConstants.*;

public class VectorLayer extends Layer
{
    protected boolean mIsInitialized;
    protected int mGeometryType;
    protected List<VectorCacheItem> mVectorCacheItems;

    protected static final String JSON_GEOMETRY_TYPE_KEY   = "geometry_type";
    protected static final String JSON_IS_INITIALIZED_KEY   = "is_inited";

    public VectorLayer(
            Context context,
            File path)
    {
        super(context, path);

        mIsInitialized = false;
        mGeometryType = GTNone;
    }

    public String createFromGeoJSON(JSONObject geoJSONObject)
    {
        try {
            //check crs
            boolean isWGS84 = true; //if no crs tag - WGS84 CRS
            if (geoJSONObject.has(GEOJSON_CRS)) {
                JSONObject crsJSONObject = geoJSONObject.getJSONObject(GEOJSON_CRS);
                //the link is unsupported yet.
                if (!crsJSONObject.getString(GEOJSON_TYPE).equals(GEOJSON_NAME)) {
                    return  mContext.getString(R.string.error_crs_unsuported);
                }
                JSONObject crsPropertiesJSONObject =
                        crsJSONObject.getJSONObject(GEOJSON_PROPERTIES);
                String crsName = crsPropertiesJSONObject.getString(GEOJSON_NAME);
                if (crsName.equals("urn:ogc:def:crs:OGC:1.3:CRS84")) { // WGS84
                    isWGS84 = true;
                } else if (crsName.equals("urn:ogc:def:crs:EPSG::3857")
                           || crsName.equals("EPSG:3857")) { //Web Mercator
                    isWGS84 = false;
                } else {
                    return mContext.getString(R.string.error_crs_unsuported);
                }
            }

            //load contents to memory and reproject if needed
            JSONArray geoJSONFeatures = geoJSONObject.getJSONArray(GEOJSON_TYPE_FEATURES);
            if (0 == geoJSONFeatures.length()) {
                return mContext.getString(R.string.error_empty_dataset);
            }

            List<Feature> features = new ArrayList<>();
            List<Pair<String, Integer>> fields = new ArrayList<>();

            int geometryType = GTNone;
            for (int i = 0; i < geoJSONFeatures.length(); i++) {
                JSONObject jsonFeature = geoJSONFeatures.getJSONObject(i);
                //get geometry
                JSONObject jsonGeometry = jsonFeature.getJSONObject(GEOJSON_GEOMETRY);
                GeoGeometry geometry = GeoGeometry.fromJson(jsonGeometry);
                if (geometryType == GTNone) {
                    geometryType = geometry.getType();
                } else if (!Geo.isGeometryTypeSame(geometryType, geometry.getType())) {
                    //skip different geometry type
                    continue;
                }

                //reproject if needed
                if (isWGS84) {
                    geometry.setCRS(CRS_WGS84);
                    geometry.project(CRS_WEB_MERCATOR);
                } else {
                    geometry.setCRS(CRS_WEB_MERCATOR);
                }

                int nId = i;
                if(jsonFeature.has(GEOJSON_ID))
                    nId = jsonFeature.getInt(GEOJSON_ID);
                Feature feature = new Feature(nId, fields); // ID == i
                feature.setGeometry(geometry);

                //normalize attributes
                JSONObject jsonAttributes = jsonFeature.getJSONObject(GEOJSON_PROPERTIES);
                Iterator<String> iter = jsonAttributes.keys();
                while (iter.hasNext()) {
                    String key = iter.next();
                    Object value = jsonAttributes.get(key);
                    int nType = NOT_FOUND;
//check type
                    if (value instanceof Integer || value instanceof Long) {
                        nType = FTInteger;
                    } else if (value instanceof Double || value instanceof Float) {
                        nType = FTReal;
                    } else if (value instanceof Date) {
                        nType = FTDateTime;
                    } else if (value instanceof String) {
                        nType = FTString;
                    } else if (value instanceof JSONObject) {
                        nType = NOT_FOUND;
//the some list - need to check it type FTIntegerList, FTRealList, FTStringList
                    }

                    if(nType != NOT_FOUND) {
                        int fieldIndex = NOT_FOUND;
                        for (int j = 0; j < fields.size(); j++) {
                            if (fields.get(j).first.equals(key)) {
                                fieldIndex = j;
                            }
                        }
                        if (fieldIndex == NOT_FOUND) { //add new field
                            Pair<String, Integer> fieldKey = Pair.create(key, nType);
                            fieldIndex = fields.size();
                            fields.add(fieldKey);
                        }
                        feature.setFieldValue(fieldIndex, value);
                    }
                }
                features.add(feature);
            }

            String tableCreate = "CREATE TABLE IF NOT EXISTS " + mPath.getName() + " ( " + //table name is the same as the folder of the layer
                                 "_ID INTEGER PRIMARY KEY, " +
                                 "GEOM BLOB";
            for(int i = 0; i < fields.size(); ++i)
            {
                Pair<String, Integer> field = fields.get(i);

                tableCreate += ", " + field.first + " ";
                switch (field.second)
                {
                    case FTString:
                        tableCreate += "TEXT";
                        break;
                    case FTInteger:
                        tableCreate += "INTEGER";
                        break;
                    case FTReal:
                        tableCreate += "REAL";
                        break;
                    case FTDateTime:
                        tableCreate += "TIMESTAMP";
                        break;
                }
            }
            tableCreate += " );";

            GeoEnvelope extents = new GeoEnvelope();
            for (Feature feature : features) {
                //update bbox
                extents.merge(feature.getGeometry().getEnvelope());
            }

            //1. create table and populate with values
            MapContentProviderHelper map = (MapContentProviderHelper) MapBase.getInstance();
            SQLiteDatabase db = map.getDatabase(true);
            db.execSQL(tableCreate);
            for(Feature feature : features) {
                ContentValues values = new ContentValues();
                values.put("_ID", feature.getId());
                try {
                    values.put("GEOM", feature.getGeometry().toBlob());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                for(int i = 0; i < fields.size(); ++i){
                    if(!feature.isValuePresent(i))
                        continue;
                    switch (fields.get(i).second)
                    {
                        case FTString:
                            values.put(fields.get(i).first, feature.getFieldValueAsString(i));
                            break;
                        case FTInteger:
                            values.put(fields.get(i).first, (int)feature.getFieldValue(i));
                            break;
                        case FTReal:
                            values.put(fields.get(i).first, (double)feature.getFieldValue(i));
                            break;
                        case FTDateTime:
                            values.put(fields.get(i).first, feature.getFieldValueAsString(i));
                            break;
                    }
                }
                db.insert(mPath.getName(), "", values);
            }

            //2. save the layer properties to config.json
            mGeometryType = geometryType;
            mExtents = extents;
            mIsInitialized = true;
            setDefaultRenderer();

            save();

            //3. fill the geometry and labels array
            mVectorCacheItems = new ArrayList<>();
            for(Feature feature : features){
                mVectorCacheItems.add(new VectorCacheItem(feature.getGeometry(), feature.getId()));
            }


            if(null != mParent){ //notify the load is over
                LayerGroup layerGroup = (LayerGroup)mParent;
                layerGroup.onLayerChanged(this);
            }

            return "";
        } catch (JSONException e) {
            e.printStackTrace();
            return e.getLocalizedMessage();
        }
    }


    protected void setDefaultRenderer()
    {
        switch (mGeometryType)
        {
            case GTPoint:
            case GTMultiPoint:
                mRenderer = new SimpleFeatureRenderer(this, new SimpleMarkerStyle(Color.RED, Color.BLACK, 6, SimpleMarkerStyle.MarkerStyleCircle));
                break;
            case GTLineString:
            case GTMultiLineString:
                mRenderer = new SimpleFeatureRenderer(this, new SimpleLineStyle(Color.GREEN));
                break;
            case GTPolygon:
            case GTMultiPolygon:
            default:
                mRenderer = null;
        }
    }


    protected void reportError(String error)
    {
        Log.w(TAG, error);
    }

    @Override
    public JSONObject toJSON()
            throws JSONException
    {
        JSONObject rootConfig = super.toJSON();
        rootConfig.put(JSON_GEOMETRY_TYPE_KEY, mGeometryType);
        rootConfig.put(JSON_IS_INITIALIZED_KEY, mIsInitialized);
        if (null != mRenderer && mRenderer instanceof IJSONStore) {
            IJSONStore jsonStore = (IJSONStore) mRenderer;
            rootConfig.put(JSON_RENDERERPROPS_KEY, jsonStore.toJSON());
        }
        return rootConfig;
    }


    @Override
    public void fromJSON(JSONObject jsonObject)
            throws JSONException
    {
        super.fromJSON(jsonObject);
        mGeometryType = jsonObject.getInt(JSON_GEOMETRY_TYPE_KEY);
        mIsInitialized = jsonObject.getBoolean(JSON_IS_INITIALIZED_KEY);
        if (jsonObject.has(JSON_RENDERERPROPS_KEY)) {
            setDefaultRenderer();

            if (null != mRenderer && mRenderer instanceof IJSONStore) {
                IJSONStore jsonStore = (IJSONStore) mRenderer;
                jsonStore.fromJSON(jsonObject.getJSONObject(JSON_RENDERERPROPS_KEY));
            }
        }

        if(mIsInitialized)
        {
            mExtents = new GeoEnvelope();

            //load vector cache
            MapContentProviderHelper map = (MapContentProviderHelper) MapBase.getInstance();
            SQLiteDatabase db = map.getDatabase(false);
            String[] columns = new String[]{"_ID", "GEOM"};
            Cursor cursor = db.query(mPath.getName(), columns, null, null, null, null, null);
            if(null != cursor && cursor.moveToFirst()) {
                mVectorCacheItems = new ArrayList<>();
                do{
                    try {
                        GeoGeometry geoGeometry = GeoGeometry.fromBlob(cursor.getBlob(1));
                        int nId = cursor.getInt(0);
                        mExtents.merge(geoGeometry.getEnvelope());
                        mVectorCacheItems.add(new VectorCacheItem(geoGeometry, nId));
                    } catch (IOException | ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                while (cursor.moveToNext());
            }
        }
    }


    @Override
    public boolean delete()
    {
        //drop table
        MapContentProviderHelper map = (MapContentProviderHelper) MapBase.getInstance();
        SQLiteDatabase db = map.getDatabase(true);
        String tableDrop = "DROP TABLE IF EXISTS " + mPath.getName();
        db.execSQL(tableDrop);

        return super.delete();
    }


    public List<VectorCacheItem> getVectorCache()
    {
        return mVectorCacheItems;
    }

    @Override
    public boolean isValid()
    {
        return mIsInitialized;
    }
}




Java Source Code List

com.nextgis.maplib.ApplicationTest.java
com.nextgis.maplib.api.GpsEventListener.java
com.nextgis.maplib.api.IGISApplication.java
com.nextgis.maplib.api.IJSONStore.java
com.nextgis.maplib.api.ILayerView.java
com.nextgis.maplib.api.ILayer.java
com.nextgis.maplib.api.IMapView.java
com.nextgis.maplib.api.INGWLayer.java
com.nextgis.maplib.api.IRenderer.java
com.nextgis.maplib.api.MapEventListener.java
com.nextgis.maplib.datasource.DatabaseHelper.java
com.nextgis.maplib.datasource.GeoEnvelope.java
com.nextgis.maplib.datasource.GeoGeometryCollection.java
com.nextgis.maplib.datasource.GeoGeometry.java
com.nextgis.maplib.datasource.GeoLineString.java
com.nextgis.maplib.datasource.GeoLinearRing.java
com.nextgis.maplib.datasource.GeoMultiLineString.java
com.nextgis.maplib.datasource.GeoMultiPoint.java
com.nextgis.maplib.datasource.GeoMultiPolygon.java
com.nextgis.maplib.datasource.GeoPoint.java
com.nextgis.maplib.datasource.GeoPolygon.java
com.nextgis.maplib.datasource.Geo.java
com.nextgis.maplib.datasource.NGWLayerContentProvider.java
com.nextgis.maplib.datasource.TileItem.java
com.nextgis.maplib.datasource.ngw.Connection.java
com.nextgis.maplib.datasource.ngw.Connections.java
com.nextgis.maplib.datasource.ngw.INGWResource.java
com.nextgis.maplib.datasource.ngw.LayerWithStyles.java
com.nextgis.maplib.datasource.ngw.ResourceGroup.java
com.nextgis.maplib.datasource.ngw.Resource.java
com.nextgis.maplib.display.GISDisplay.java
com.nextgis.maplib.display.Renderer.java
com.nextgis.maplib.display.SimpleFeatureRenderer.java
com.nextgis.maplib.display.SimpleLineStyle.java
com.nextgis.maplib.display.SimpleMarkerStyle.java
com.nextgis.maplib.display.Style.java
com.nextgis.maplib.display.TMSRenderer.java
com.nextgis.maplib.location.GpsEventSource.java
com.nextgis.maplib.map.LayerFactory.java
com.nextgis.maplib.map.LayerGroup.java
com.nextgis.maplib.map.Layer.java
com.nextgis.maplib.map.MapBase.java
com.nextgis.maplib.map.MapContentProviderHelper.java
com.nextgis.maplib.map.MapDrawable.java
com.nextgis.maplib.map.MapEventSource.java
com.nextgis.maplib.map.NGWRasterLayer.java
com.nextgis.maplib.map.NGWVectorLayer.java
com.nextgis.maplib.map.RemoteTMSLayer.java
com.nextgis.maplib.map.TMSLayer.java
com.nextgis.maplib.map.VectorLayer.java
com.nextgis.maplib.util.Constants.java
com.nextgis.maplib.util.DatabaseContext.java
com.nextgis.maplib.util.Feature.java
com.nextgis.maplib.util.FileUtil.java
com.nextgis.maplib.util.GeoConstants.java
com.nextgis.maplib.util.NetworkUtil.java
com.nextgis.maplib.util.SettingsConstants.java
com.nextgis.maplib.util.VectorCacheItem.java